Merge branch 'master' of github.com:jamesagnew/hapi-fhir

This commit is contained in:
James 2016-12-04 21:09:48 -05:00
commit fd26f074e5
13 changed files with 2935 additions and 204 deletions

View File

@ -244,6 +244,9 @@ public abstract class BaseParser implements IParser {
continue;
}
theContained.addContained(resource);
if (resource.getIdElement().isLocal() && existingIdToContainedResource != null) {
existingIdToContainedResource.remove(resource.getIdElement().getValue());
}
} else {
continue;
}

View File

@ -287,7 +287,17 @@ public abstract class RestfulClientFactory implements IRestfulClientFactory {
}
@SuppressWarnings("rawtypes")
Class implementingClass = myContext.getResourceDefinition(capabilityStatementResourceName).getImplementingClass();
Class implementingClass;
try {
implementingClass = myContext.getResourceDefinition(capabilityStatementResourceName).getImplementingClass();
} catch (DataFormatException e) {
if (!myContext.getVersion().getVersion().isOlderThan(FhirVersionEnum.DSTU3)) {
capabilityStatementResourceName = "Conformance";
implementingClass = myContext.getResourceDefinition(capabilityStatementResourceName).getImplementingClass();
} else {
throw e;
}
}
try {
conformance = (IBaseResource) client.fetchConformance().ofType(implementingClass).execute();
} catch (FhirClientConnectionException e) {

View File

@ -2209,10 +2209,14 @@ public class SearchBuilder {
for (ResourceLink resourceLink : results) {
if (theReverseMode) {
Long pid = resourceLink.getSourceResourcePid();
pidsToInclude.add(pid);
if (pid != null) {
pidsToInclude.add(pid);
}
} else {
Long pid = resourceLink.getTargetResourcePid();
pidsToInclude.add(pid);
if (pid != null) {
pidsToInclude.add(pid);
}
}
}
}

View File

@ -22,91 +22,40 @@ import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.nio.charset.StandardCharsets;
import java.util.*;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.RandomStringUtils;
import org.hamcrest.Matchers;
import org.hamcrest.core.StringContains;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import ca.uhn.fhir.jpa.dao.BaseHapiFhirDao;
import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao;
import ca.uhn.fhir.jpa.dao.FhirResourceDaoDstu2;
import ca.uhn.fhir.jpa.dao.SearchParameterMap;
import ca.uhn.fhir.jpa.dao.*;
import ca.uhn.fhir.jpa.dao.dstu3.FhirResourceDaoDstu3Test;
import ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamString;
import ca.uhn.fhir.jpa.entity.TagTypeEnum;
import ca.uhn.fhir.model.api.IQueryParameterType;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.api.Include;
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
import ca.uhn.fhir.model.api.Tag;
import ca.uhn.fhir.model.api.TagList;
import ca.uhn.fhir.model.api.*;
import ca.uhn.fhir.model.base.composite.BaseCodingDt;
import ca.uhn.fhir.model.dstu.valueset.QuantityCompararatorEnum;
import ca.uhn.fhir.model.dstu2.composite.CodeableConceptDt;
import ca.uhn.fhir.model.dstu2.composite.CodingDt;
import ca.uhn.fhir.model.dstu2.composite.IdentifierDt;
import ca.uhn.fhir.model.dstu2.composite.MetaDt;
import ca.uhn.fhir.model.dstu2.composite.PeriodDt;
import ca.uhn.fhir.model.dstu2.composite.QuantityDt;
import ca.uhn.fhir.model.dstu2.composite.ResourceReferenceDt;
import ca.uhn.fhir.model.dstu2.resource.BaseResource;
import ca.uhn.fhir.model.dstu2.composite.*;
import ca.uhn.fhir.model.dstu2.resource.*;
import ca.uhn.fhir.model.dstu2.resource.Bundle;
import ca.uhn.fhir.model.dstu2.resource.ConceptMap;
import ca.uhn.fhir.model.dstu2.resource.Device;
import ca.uhn.fhir.model.dstu2.resource.DiagnosticReport;
import ca.uhn.fhir.model.dstu2.resource.Encounter;
import ca.uhn.fhir.model.dstu2.resource.Observation;
import ca.uhn.fhir.model.dstu2.resource.OperationOutcome;
import ca.uhn.fhir.model.dstu2.resource.Organization;
import ca.uhn.fhir.model.dstu2.resource.Patient;
import ca.uhn.fhir.model.dstu2.resource.Questionnaire;
import ca.uhn.fhir.model.dstu2.valueset.AdministrativeGenderEnum;
import ca.uhn.fhir.model.dstu2.valueset.BundleTypeEnum;
import ca.uhn.fhir.model.dstu2.valueset.HTTPVerbEnum;
import ca.uhn.fhir.model.dstu2.valueset.IssueSeverityEnum;
import ca.uhn.fhir.model.dstu2.valueset.IssueTypeEnum;
import ca.uhn.fhir.model.dstu2.valueset.QuantityComparatorEnum;
import ca.uhn.fhir.model.primitive.CodeDt;
import ca.uhn.fhir.model.primitive.DateDt;
import ca.uhn.fhir.model.primitive.DateTimeDt;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.model.primitive.InstantDt;
import ca.uhn.fhir.model.primitive.StringDt;
import ca.uhn.fhir.model.primitive.UriDt;
import ca.uhn.fhir.model.dstu2.valueset.*;
import ca.uhn.fhir.model.primitive.*;
import ca.uhn.fhir.model.valueset.BundleEntrySearchModeEnum;
import ca.uhn.fhir.model.valueset.BundleEntryTransactionMethodEnum;
import ca.uhn.fhir.rest.api.MethodOutcome;
import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
import ca.uhn.fhir.rest.api.SortOrderEnum;
import ca.uhn.fhir.rest.api.SortSpec;
import ca.uhn.fhir.rest.param.DateParam;
import ca.uhn.fhir.rest.param.DateRangeParam;
import ca.uhn.fhir.rest.param.QuantityParam;
import ca.uhn.fhir.rest.param.ReferenceParam;
import ca.uhn.fhir.rest.param.StringParam;
import ca.uhn.fhir.rest.param.TokenOrListParam;
import ca.uhn.fhir.rest.param.TokenParam;
import ca.uhn.fhir.rest.api.*;
import ca.uhn.fhir.rest.param.*;
import ca.uhn.fhir.rest.server.Constants;
import ca.uhn.fhir.rest.server.EncodingEnum;
import ca.uhn.fhir.rest.server.IBundleProvider;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException;
import ca.uhn.fhir.rest.server.exceptions.ResourceGoneException;
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
import ca.uhn.fhir.rest.server.exceptions.ResourceVersionConflictException;
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
import ca.uhn.fhir.rest.server.exceptions.*;
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor.ActionRequestDetails;
import ca.uhn.fhir.util.TestUtil;
@ -130,6 +79,31 @@ public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
}
}
@After
public final void after() {
myDaoConfig.setAllowExternalReferences(new DaoConfig().isAllowExternalReferences());
}
@Test
public void testValidateAgainstDstu2Profile() throws Exception {
myDaoConfig.setAllowExternalReferences(true);
String stream = IOUtils.toString(getClass().getResourceAsStream("/binu_testpatient_structuredefinition_dstu2.xml"), StandardCharsets.UTF_8);
StructureDefinition sd = myFhirCtx.newXmlParser().parseResource(StructureDefinition.class, stream);
myStructureDefinitionDao.create(sd, mySrd);
String rawResource = IOUtils.toString(getClass().getResourceAsStream("/binu_testpatient_resource.json"), StandardCharsets.UTF_8);
try {
myValueSetDao.validate(null, null, rawResource, EncodingEnum.JSON, ValidationModeEnum.UPDATE, null, mySrd);
fail();
} catch (PreconditionFailedException e) {
ourLog.info(myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(e.getOperationOutcome()));
}
}
@Test
public void testCreateBundleAllowsDocumentAndCollection() {
String methodName = "testCreateBundleAllowsDocumentAndCollection";

View File

@ -29,13 +29,7 @@ import java.net.Socket;
import java.net.SocketTimeoutException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import java.util.*;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
@ -43,79 +37,31 @@ import org.apache.commons.lang3.Validate;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPatch;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.methods.*;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.message.BasicNameValuePair;
import org.hl7.fhir.dstu3.model.AuditEvent;
import org.hl7.fhir.dstu3.model.BaseResource;
import org.hl7.fhir.dstu3.model.Basic;
import org.hl7.fhir.dstu3.model.Bundle;
import org.hl7.fhir.dstu3.model.Bundle.BundleEntryComponent;
import org.hl7.fhir.dstu3.model.Bundle.BundleLinkComponent;
import org.hl7.fhir.dstu3.model.Bundle.BundleType;
import org.hl7.fhir.dstu3.model.Bundle.HTTPVerb;
import org.hl7.fhir.dstu3.model.Bundle.SearchEntryMode;
import org.hl7.fhir.dstu3.model.CodeSystem;
import org.hl7.fhir.dstu3.model.CodeType;
import org.hl7.fhir.dstu3.model.Coding;
import org.hl7.fhir.dstu3.model.Condition;
import org.hl7.fhir.dstu3.model.DateTimeType;
import org.hl7.fhir.dstu3.model.DateType;
import org.hl7.fhir.dstu3.model.Device;
import org.hl7.fhir.dstu3.model.DiagnosticRequest;
import org.hl7.fhir.dstu3.model.DocumentManifest;
import org.hl7.fhir.dstu3.model.DocumentReference;
import org.hl7.fhir.dstu3.model.Encounter;
import org.hl7.fhir.dstu3.model.*;
import org.hl7.fhir.dstu3.model.Bundle.*;
import org.hl7.fhir.dstu3.model.Encounter.EncounterLocationComponent;
import org.hl7.fhir.dstu3.model.Encounter.EncounterStatus;
import org.hl7.fhir.dstu3.model.Enumerations.AdministrativeGender;
import org.hl7.fhir.dstu3.model.Extension;
import org.hl7.fhir.dstu3.model.IdType;
import org.hl7.fhir.dstu3.model.ImagingStudy;
import org.hl7.fhir.dstu3.model.InstantType;
import org.hl7.fhir.dstu3.model.IntegerType;
import org.hl7.fhir.dstu3.model.Location;
import org.hl7.fhir.dstu3.model.Medication;
import org.hl7.fhir.dstu3.model.MedicationAdministration;
import org.hl7.fhir.dstu3.model.MedicationRequest;
import org.hl7.fhir.dstu3.model.Meta;
import org.hl7.fhir.dstu3.model.Narrative.NarrativeStatus;
import org.hl7.fhir.dstu3.model.Observation;
import org.hl7.fhir.dstu3.model.Observation.ObservationStatus;
import org.hl7.fhir.dstu3.model.OperationOutcome;
import org.hl7.fhir.dstu3.model.Organization;
import org.hl7.fhir.dstu3.model.Parameters;
import org.hl7.fhir.dstu3.model.Patient;
import org.hl7.fhir.dstu3.model.Period;
import org.hl7.fhir.dstu3.model.Practitioner;
import org.hl7.fhir.dstu3.model.Quantity;
import org.hl7.fhir.dstu3.model.Questionnaire;
import org.hl7.fhir.dstu3.model.Questionnaire.QuestionnaireItemType;
import org.hl7.fhir.dstu3.model.QuestionnaireResponse;
import org.hl7.fhir.dstu3.model.Reference;
import org.hl7.fhir.dstu3.model.StringType;
import org.hl7.fhir.dstu3.model.StructureDefinition;
import org.hl7.fhir.dstu3.model.Subscription;
import org.hl7.fhir.dstu3.model.Subscription.SubscriptionChannelType;
import org.hl7.fhir.dstu3.model.Subscription.SubscriptionStatus;
import org.hl7.fhir.dstu3.model.TemporalPrecisionEnum;
import org.hl7.fhir.dstu3.model.UnsignedIntType;
import org.hl7.fhir.dstu3.model.ValueSet;
import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Ignore;
import org.junit.Test;
import com.google.common.collect.Lists;
import ca.uhn.fhir.jpa.dao.DaoConfig;
import ca.uhn.fhir.model.primitive.InstantDt;
import ca.uhn.fhir.model.primitive.UriDt;
import ca.uhn.fhir.parser.IParser;
@ -124,11 +70,7 @@ import ca.uhn.fhir.rest.api.MethodOutcome;
import ca.uhn.fhir.rest.api.SummaryEnum;
import ca.uhn.fhir.rest.client.IGenericClient;
import ca.uhn.fhir.rest.gclient.StringClientParam;
import ca.uhn.fhir.rest.param.DateRangeParam;
import ca.uhn.fhir.rest.param.ParamPrefixEnum;
import ca.uhn.fhir.rest.param.StringAndListParam;
import ca.uhn.fhir.rest.param.StringOrListParam;
import ca.uhn.fhir.rest.param.StringParam;
import ca.uhn.fhir.rest.param.*;
import ca.uhn.fhir.rest.server.Constants;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException;
@ -148,6 +90,29 @@ public class ResourceProviderDstu3Test extends BaseResourceProviderDstu3Test {
myDaoConfig.setAllowMultipleDelete(true);
}
@Override
@After
public void after() throws Exception {
super.after();
myDaoConfig.setAllowMultipleDelete(new DaoConfig().isAllowMultipleDelete());
myDaoConfig.setAllowExternalReferences(new DaoConfig().isAllowExternalReferences());
}
@Test
public void testIncludeWithExternalReferences() {
myDaoConfig.setAllowExternalReferences(true);
Patient p = new Patient();
p.getManagingOrganization().setReference("http://example.com/Organization/123");
ourClient.create().resource(p).execute();
Bundle b = ourClient.search().forResource("Patient").include(Patient.INCLUDE_ORGANIZATION).returnBundle(Bundle.class).execute();
assertEquals(1, b.getEntry().size());
}
private void checkParamMissing(String paramName) throws IOException, ClientProtocolException {
HttpGet get = new HttpGet(ourServerBase + "/Observation?" + paramName + ":missing=false");
CloseableHttpResponse resp = ourHttpClient.execute(get);

View File

@ -0,0 +1,40 @@
{
"resourceType": "Patient",
"id": "67.20068.14731",
"meta": {
"versionId": "1",
"lastUpdated": "2016-11-30T02:18:24.929-05:00",
"profile": [
"http://example.org/fhir/StructureDefinition/DutchPatient"
]
},
"text": {
"status": "generated",
"div": "<div xmlns=\"http://www.w3.org/1999/xhtml\"><div class=\"hapiHeaderText\"> GHASIYA <b>AL WAHEIBI </b></div><table class=\"hapiPropertyTable\"><tbody><tr><td>Identifier</td><td>14731</td></tr><tr><td>Address</td><td></td></tr><tr><td>Date of birth</td><td><span>01 January 1981</span></td></tr></tbody></table></div>"
},
"identifier": [{
"value": "14731",
"period": {
"start": "2005-03-15"
}
}],
"active": false,
"name": [{
"family": [
"AL WAHEIBI"
],
"given": [
"GHASIYA"
]
}],
"gender": "female",
"birthDate": "1981-01-01",
"deceasedBoolean": true,
"address": {
"use": "home"
},
"placeOfBirth": {
"url": "http://hl7.org/fhir/StructureDefinition/birthPlace",
"valueString": "Narakal"
}
}

View File

@ -11,14 +11,10 @@ import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.StringReader;
import java.io.*;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.nio.charset.StandardCharsets;
import java.util.*;
import org.apache.commons.io.IOUtils;
import org.hamcrest.core.IsNot;
@ -84,7 +80,7 @@ public class JsonParserTest {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(JsonParserTest.class);
private void parseAndEncode(String name) throws IOException {
String msg = IOUtils.toString(XmlParser.class.getResourceAsStream(name));
String msg = IOUtils.toString(XmlParser.class.getResourceAsStream(name), StandardCharsets.UTF_8);
// ourLog.info(msg);
msg = msg.replace("\"div\": \"<div>", "\"div\":\"<div xmlns=\\\"http://www.w3.org/1999/xhtml\\\">");
@ -107,6 +103,7 @@ public class JsonParserTest {
assertEquals(exp, act);
}
@Test
public void testDecimalPrecisionPreserved() {
String number = "52.3779939997090374535378485873776474764643249869328698436986235758587";

View File

@ -0,0 +1,75 @@
package ca.uhn.fhir.rest.client;
import static org.junit.Assert.fail;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.util.List;
import java.util.Map;
import org.junit.AfterClass;
import org.junit.Test;
import org.mockito.Mockito;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.FhirVersionEnum;
import ca.uhn.fhir.model.dstu2.resource.Conformance;
import ca.uhn.fhir.parser.DataFormatException;
import ca.uhn.fhir.rest.api.RequestTypeEnum;
import ca.uhn.fhir.rest.client.apache.ApacheRestfulClientFactory;
import ca.uhn.fhir.rest.client.api.IHttpClient;
import ca.uhn.fhir.rest.client.api.IHttpRequest;
import ca.uhn.fhir.rest.client.api.IHttpResponse;
import ca.uhn.fhir.rest.server.EncodingEnum;
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
import ca.uhn.fhir.util.TestUtil;
public class RestfulClientFactoryDstu2Test {
private static FhirContext ourCtx = FhirContext.forDstu2();
/**
* See #518
*/
@SuppressWarnings({ "unchecked", "cast" })
@Test
public void testMissingCapabilityStatementDstu2() throws Exception {
FhirContext ctx = mock(FhirContext.class);
IRestfulClientFactory restfulClientFactory = mock(IRestfulClientFactory.class);
IHttpClient httpClient = mock(IHttpClient.class);
when(ctx.getResourceDefinition(Mockito.eq("CapabilityStatement"))).thenThrow(new DataFormatException());
when(ctx.getResourceDefinition(Mockito.eq("Conformance"))).thenReturn(ourCtx.getResourceDefinition("Conformance"));
when(ctx.getResourceDefinition(Conformance.class)).thenReturn(ourCtx.getResourceDefinition("Conformance"));
when(ctx.getVersion()).thenReturn(FhirVersionEnum.DSTU2.getVersionImplementation());
when(ctx.getRestfulClientFactory()).thenReturn(restfulClientFactory);
when(restfulClientFactory.getHttpClient(any(StringBuilder.class), (Map<String, List<String>>)any(Map.class), any(String.class), any(RequestTypeEnum.class), any(List.class))).thenReturn(httpClient);
IHttpRequest httpRequest = mock(IHttpRequest.class);
when(httpClient.createGetRequest(any(FhirContext.class), any(EncodingEnum.class))).thenReturn(httpRequest);
IHttpResponse httpResponse = mock(IHttpResponse.class);
when(httpRequest.execute()).thenReturn(httpResponse);
when(httpResponse.getStatus()).thenReturn(404);
ApacheRestfulClientFactory cf = new ApacheRestfulClientFactory(ctx);
IHttpClient client = mock(IHttpClient.class);
BaseClient baseClient = mock(BaseClient.class);
try {
cf.validateServerBase("http://localhost:9999", client, baseClient);
fail();
} catch (ResourceNotFoundException e) {
// ok
}
}
@AfterClass
public static void afterClassClearContext() {
TestUtil.clearAllStaticFieldsForUnitTest();
}
}

View File

@ -1,5 +1,6 @@
package ca.uhn.fhir.parser;
import static org.apache.commons.lang3.StringUtils.countMatches;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.empty;
@ -17,7 +18,9 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.util.*;
@ -36,6 +39,7 @@ import org.hl7.fhir.dstu3.model.Enumeration;
import org.hl7.fhir.dstu3.model.Enumerations.AdministrativeGender;
import org.hl7.fhir.dstu3.model.Identifier.IdentifierUse;
import org.hl7.fhir.dstu3.model.Observation.ObservationStatus;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
import org.junit.*;
import org.mockito.ArgumentCaptor;
@ -66,6 +70,32 @@ public class JsonParserDstu3Test {
ourCtx.setNarrativeGenerator(null);
}
/**
* See #276
*/
@Test
public void testDoubleEncodingContainedResources() throws Exception {
Patient patient = new Patient();
patient.setId("#patient-1");
patient.setActive(true);
Coverage coverage = new Coverage();
coverage.setId("#coverage-1");
coverage.getBeneficiary().setResource(patient);
Claim resource = new Claim();
resource.getContained().add(patient);
resource.getContained().add(coverage);
resource.getPatient().setReference("#patient-1");
resource.addCoverage().getCoverage().setReference("#coverage-1");
IParser p = ourCtx.newJsonParser().setPrettyPrint(true);
String encoded = p.encodeResourceToString(resource);
ourLog.info(encoded);
assertEquals(3, countMatches(encoded, "resourceType"));
}
/**
* #480
*/
@ -77,15 +107,15 @@ public class JsonParserDstu3Test {
qr.getItemFirstRep().setLinkIdElement(new StringType());
qr.getItemFirstRep().addItem().setLinkIdElement(new StringType(""));
qr.getItemFirstRep().addItem().setLinkIdElement(new StringType("LINKID"));
String encoded = ourCtx.newJsonParser().encodeResourceToString(qr);
ourLog.info(encoded);
assertThat(encoded, stringContainsInOrder("123"));
assertThat(encoded, not(stringContainsInOrder("\"\"")));
assertThat(encoded, not(stringContainsInOrder("null")));
}
/**
* #480
*/
@ -93,7 +123,7 @@ public class JsonParserDstu3Test {
public void testParseEmptyValue() {
String input = "{\"resourceType\":\"QuestionnaireResponse\",\"id\":\"123\",\"authored\":\"\",\"item\":[{\"item\":[{\"linkId\":\"\"}]}]}";
QuestionnaireResponse qr = ourCtx.newJsonParser().parseResource(QuestionnaireResponse.class, input);
assertEquals("QuestionnaireResponse/123", qr.getIdElement().getValue());
assertEquals(null, qr.getAuthored());
assertEquals(null, qr.getAuthoredElement().getValue());
@ -108,7 +138,7 @@ public class JsonParserDstu3Test {
@Test
public void testUnexpectedElementsWithUnderscoreAtStartOfName() throws Exception {
String input = IOUtils.toString(JsonParserDstu3Test.class.getResourceAsStream("/bug477.json"), StandardCharsets.UTF_8);
IParserErrorHandler errorHandler = mock(IParserErrorHandler.class);
// Do it once without the custom error handler just for the logging
@ -117,23 +147,22 @@ public class JsonParserDstu3Test {
p = ourCtx.newJsonParser();
p.setParserErrorHandler(errorHandler);
Patient parsed = p.parseResource(Patient.class, input);
assertEquals("1", parsed.getIdElement().getIdPart());
ArgumentCaptor<String> elementName = ArgumentCaptor.forClass(String.class);
ArgumentCaptor<ValueType> expected = ArgumentCaptor.forClass(ValueType.class);
ArgumentCaptor<ValueType> actual = ArgumentCaptor.forClass(ValueType.class);
verify(errorHandler, atLeastOnce()).incorrectJsonType(Mockito.any(IParseLocation.class),elementName.capture(), expected.capture(), actual.capture());
verify(errorHandler, atLeastOnce()).incorrectJsonType(Mockito.any(IParseLocation.class),Mockito.eq("_id"), Mockito.eq(ValueType.OBJECT), Mockito.eq(ValueType.SCALAR));
verify(errorHandler, atLeastOnce()).incorrectJsonType(Mockito.any(IParseLocation.class),Mockito.eq("__v"), Mockito.eq(ValueType.OBJECT), Mockito.eq(ValueType.SCALAR));
verify(errorHandler, atLeastOnce()).incorrectJsonType(Mockito.any(IParseLocation.class),Mockito.eq("_status"), Mockito.eq(ValueType.OBJECT), Mockito.eq(ValueType.SCALAR));
verify(errorHandler, atLeastOnce()).incorrectJsonType(Mockito.any(IParseLocation.class), elementName.capture(), expected.capture(), actual.capture());
verify(errorHandler, atLeastOnce()).incorrectJsonType(Mockito.any(IParseLocation.class), Mockito.eq("_id"), Mockito.eq(ValueType.OBJECT), Mockito.eq(ValueType.SCALAR));
verify(errorHandler, atLeastOnce()).incorrectJsonType(Mockito.any(IParseLocation.class), Mockito.eq("__v"), Mockito.eq(ValueType.OBJECT), Mockito.eq(ValueType.SCALAR));
verify(errorHandler, atLeastOnce()).incorrectJsonType(Mockito.any(IParseLocation.class), Mockito.eq("_status"), Mockito.eq(ValueType.OBJECT), Mockito.eq(ValueType.SCALAR));
assertEquals("_id", elementName.getAllValues().get(0));
assertEquals(ValueType.OBJECT, expected.getAllValues().get(0));
assertEquals(ValueType.SCALAR, actual.getAllValues().get(0));
}
@Test
public void testEncodeAndParseExtensions() throws Exception {
@ -221,7 +250,6 @@ public class JsonParserDstu3Test {
}
@Test
public void testEncodeAndParseMetaProfileAndTags() {
Patient p = new Patient();
@ -300,7 +328,6 @@ public class JsonParserDstu3Test {
assertEquals("sec_label2", tagList.get(1).getDisplay());
}
/**
* See #336
*/
@ -355,7 +382,6 @@ public class JsonParserDstu3Test {
}
@Test
public void testEncodeAndParseSecurityLabels() {
Patient p = new Patient();
@ -415,7 +441,7 @@ public class JsonParserDstu3Test {
assertEquals("DISPLAY2", label.getDisplay());
assertEquals("VERSION2", label.getVersion());
}
@Test
public void testEncodeBundleNewBundleNoText() {
@ -434,8 +460,6 @@ public class JsonParserDstu3Test {
}
/**
* See #326
*/
@ -481,7 +505,7 @@ public class JsonParserDstu3Test {
String actual = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(p);
assertThat(actual, not(containsString("78ef6f64c2f2")));
}
@Test
public void testEncodeEmptyBinary() {
String output = ourCtx.newJsonParser().encodeResourceToString(new Binary());
@ -503,8 +527,7 @@ public class JsonParserDstu3Test {
String encoded = ourCtx.newJsonParser().encodeResourceToString(p);
assertThat(encoded, not(containsString("tag")));
}
/**
* #158
*/
@ -697,14 +720,14 @@ public class JsonParserDstu3Test {
@Test
public void testEncodeHistoryEncodeVersionsAtPath1() {
ourCtx = FhirContext.forDstu3();
assertNull(ourCtx.newJsonParser().getStripVersionsFromReferences());
Patient p = new Patient();
p.setManagingOrganization(new Reference("http://foo.com/Organization/2/_history/1"));
IParser parser = ourCtx.newJsonParser();
parser.setDontStripVersionsFromReferencesAtPaths("Patient.managingOrganization");
String enc = parser.setPrettyPrint(true).encodeResourceToString(p);
ourLog.info(enc);
@ -714,15 +737,15 @@ public class JsonParserDstu3Test {
@Test
public void testEncodeHistoryEncodeVersionsAtPath2() {
ourCtx = FhirContext.forDstu3();
assertNull(ourCtx.newJsonParser().getStripVersionsFromReferences());
assertTrue(ourCtx.getParserOptions().isStripVersionsFromReferences());
Patient p = new Patient();
p.setManagingOrganization(new Reference("http://foo.com/Organization/2/_history/1"));
IParser parser = ourCtx.newJsonParser();
parser.setDontStripVersionsFromReferencesAtPaths("AuditEvent.entity.reference");
String enc = parser.setPrettyPrint(true).encodeResourceToString(p);
ourLog.info(enc);
@ -732,30 +755,30 @@ public class JsonParserDstu3Test {
@Test
public void testEncodeHistoryEncodeVersionsAtPath3() {
ourCtx = FhirContext.forDstu3();
assertNull(ourCtx.newJsonParser().getStripVersionsFromReferences());
AuditEvent auditEvent = new AuditEvent();
auditEvent.addEntity().setReference(new Reference("http://foo.com/Organization/2/_history/1"));
IParser parser = ourCtx.newJsonParser();
parser.setDontStripVersionsFromReferencesAtPaths("AuditEvent.entity.reference");
String enc = parser.setPrettyPrint(true).encodeResourceToString(auditEvent);
ourLog.info(enc);
assertThat(enc, containsString("\"reference\": \"http://foo.com/Organization/2/_history/1\""));
parser.setDontStripVersionsFromReferencesAtPaths(new ArrayList<String>());
enc = parser.setPrettyPrint(true).encodeResourceToString(auditEvent);
ourLog.info(enc);
assertThat(enc, containsString("\"reference\": \"http://foo.com/Organization/2\""));
parser.setDontStripVersionsFromReferencesAtPaths((String[])null);
parser.setDontStripVersionsFromReferencesAtPaths((String[]) null);
enc = parser.setPrettyPrint(true).encodeResourceToString(auditEvent);
ourLog.info(enc);
assertThat(enc, containsString("\"reference\": \"http://foo.com/Organization/2\""));
parser.setDontStripVersionsFromReferencesAtPaths((List<String>)null);
parser.setDontStripVersionsFromReferencesAtPaths((List<String>) null);
enc = parser.setPrettyPrint(true).encodeResourceToString(auditEvent);
ourLog.info(enc);
assertThat(enc, containsString("\"reference\": \"http://foo.com/Organization/2\""));
@ -764,21 +787,21 @@ public class JsonParserDstu3Test {
@Test
public void testEncodeHistoryEncodeVersionsAtPathUsingOptions() {
ourCtx = FhirContext.forDstu3();
assertNull(ourCtx.newJsonParser().getStripVersionsFromReferences());
assertTrue(ourCtx.getParserOptions().isStripVersionsFromReferences());
assertThat(ourCtx.getParserOptions().getDontStripVersionsFromReferencesAtPaths(), empty());
Patient p = new Patient();
p.setManagingOrganization(new Reference("http://foo.com/Organization/2/_history/1"));
IParser parser = ourCtx.newJsonParser();
ourCtx.getParserOptions().setDontStripVersionsFromReferencesAtPaths("Patient.managingOrganization");
String enc = parser.setPrettyPrint(true).encodeResourceToString(p);
ourLog.info(enc);
assertThat(enc, containsString("\"reference\": \"http://foo.com/Organization/2/_history/1\""));
ourCtx.getParserOptions().setDontStripVersionsFromReferencesAtPaths(Arrays.asList("Patient.managingOrganization"));
enc = parser.setPrettyPrint(true).encodeResourceToString(p);
ourLog.info(enc);
@ -793,17 +816,17 @@ public class JsonParserDstu3Test {
@Test
public void testEncodeHistoryStripVersionsFromReferences() {
ourCtx = FhirContext.forDstu3();
assertNull(ourCtx.newJsonParser().getStripVersionsFromReferences());
Patient p = new Patient();
p.setManagingOrganization(new Reference("http://foo.com/Organization/2/_history/1"));
IParser parser = ourCtx.newJsonParser();
String enc = parser.setPrettyPrint(true).encodeResourceToString(p);
ourLog.info(enc);
assertThat(enc, containsString("\"reference\": \"http://foo.com/Organization/2\""));
parser.setStripVersionsFromReferences(false);
enc = parser.setPrettyPrint(true).encodeResourceToString(p);
ourLog.info(enc);
@ -815,17 +838,17 @@ public class JsonParserDstu3Test {
@Test
public void testEncodeHistoryStripVersionsFromReferencesFromContext() {
ourCtx = FhirContext.forDstu3();
assertTrue(ourCtx.getParserOptions().isStripVersionsFromReferences());
Patient p = new Patient();
p.setManagingOrganization(new Reference("http://foo.com/Organization/2/_history/1"));
IParser parser = ourCtx.newJsonParser();
String enc = parser.setPrettyPrint(true).encodeResourceToString(p);
ourLog.info(enc);
assertThat(enc, containsString("\"reference\": \"http://foo.com/Organization/2\""));
ourCtx.getParserOptions().setStripVersionsFromReferences(false);
enc = parser.setPrettyPrint(true).encodeResourceToString(p);
ourLog.info(enc);
@ -1015,7 +1038,7 @@ public class JsonParserDstu3Test {
assertEquals("home", ref.getValue().toCode());
}
@Test
public void testEncodeWithDontEncodeElements() throws Exception {
Patient patient = new Patient();
@ -1645,7 +1668,7 @@ public class JsonParserDstu3Test {
} catch (DataFormatException e) {
assertEquals("Resource is missing required element 'url' in parent element 'extension'", e.getMessage());
}
}
/**
@ -1675,7 +1698,7 @@ public class JsonParserDstu3Test {
} catch (DataFormatException e) {
assertEquals("Resource is missing required element 'url' in parent element 'modifierExtension'", e.getMessage());
}
}
@Test
@ -1744,15 +1767,14 @@ public class JsonParserDstu3Test {
@Test
public void testParseMissingArray() throws IOException {
// RelatedPerson.name is 0..* but this file has it as a 0..1 (no array around the object)
// We're lenient so we accept it. Maybe this could change, or be a warning in future though
String input = IOUtils.toString(JsonParserDstu3Test.class.getResourceAsStream("/missing_array.json"), StandardCharsets.UTF_8);
RelatedPerson rp = ourCtx.newJsonParser().parseResource(RelatedPerson.class, input);
assertEquals(1, rp.getName().size());
assertEquals("Doe", rp.getName().get(0).getFamilyAsSingleString());
}
/**
@ -1763,7 +1785,7 @@ public class JsonParserDstu3Test {
String input = "{\"resourceType\":\"Basic\",\"id\":\"1\",\"text\":{\"status\":\"generated\",\"div\":\"<div/>\"}}";
Basic basic = ourCtx.newJsonParser().parseResource(Basic.class, input);
assertEquals(null, basic.getText().getDivAsString());
input = "{\"resourceType\":\"Basic\",\"id\":\"1\",\"text\":{\"status\":\"generated\",\"div\":\"<div></div>\"}}";
basic = ourCtx.newJsonParser().parseResource(Basic.class, input);
assertEquals(null, basic.getText().getDivAsString());
@ -1938,7 +1960,7 @@ public class JsonParserDstu3Test {
@Test
public void testValidateCustomStructure() throws Exception {
FooMessageHeader.FooMessageSourceComponent source = new FooMessageHeader.FooMessageSourceComponent();
source.getMessageHeaderApplicationId().setValue("APPID");
source.setName("NAME");
@ -1952,9 +1974,9 @@ public class JsonParserDstu3Test {
FhirValidator val = ourCtx.newValidator();
val.setValidateAgainstStandardSchema(true);
val.setValidateAgainstStandardSchematron(true);
ValidationResult result = val.validateWithResult(header);
ourLog.info(ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(result.toOperationOutcome()));
assertTrue(result.isSuccessful());
}

View File

@ -0,0 +1,76 @@
package ca.uhn.fhir.rest.client;
import static org.junit.Assert.fail;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.util.List;
import java.util.Map;
import org.hl7.fhir.dstu3.model.Conformance;
import org.junit.AfterClass;
import org.junit.Test;
import org.mockito.Mockito;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.FhirVersionEnum;
import ca.uhn.fhir.parser.DataFormatException;
import ca.uhn.fhir.rest.api.RequestTypeEnum;
import ca.uhn.fhir.rest.client.apache.ApacheRestfulClientFactory;
import ca.uhn.fhir.rest.client.api.IHttpClient;
import ca.uhn.fhir.rest.client.api.IHttpRequest;
import ca.uhn.fhir.rest.client.api.IHttpResponse;
import ca.uhn.fhir.rest.server.EncodingEnum;
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
import ca.uhn.fhir.util.TestUtil;
@SuppressWarnings("deprecation")
public class RestfulClientFactoryTest {
private static FhirContext ourCtx = FhirContext.forDstu3();
/**
* See #518
*/
@SuppressWarnings({ "unchecked", "cast" })
@Test
public void testMissingCapabilityStatement() throws Exception {
FhirContext ctx = mock(FhirContext.class);
IRestfulClientFactory restfulClientFactory = mock(IRestfulClientFactory.class);
IHttpClient httpClient = mock(IHttpClient.class);
when(ctx.getResourceDefinition(Mockito.eq("CapabilityStatement"))).thenThrow(new DataFormatException());
when(ctx.getResourceDefinition(Mockito.eq("Conformance"))).thenReturn(ourCtx.getResourceDefinition("Conformance"));
when(ctx.getResourceDefinition(Conformance.class)).thenReturn(ourCtx.getResourceDefinition("Conformance"));
when(ctx.getVersion()).thenReturn(FhirVersionEnum.DSTU3.getVersionImplementation());
when(ctx.getRestfulClientFactory()).thenReturn(restfulClientFactory);
when(restfulClientFactory.getHttpClient(any(StringBuilder.class), (Map<String, List<String>>)any(Map.class), any(String.class), any(RequestTypeEnum.class), any(List.class))).thenReturn(httpClient);
IHttpRequest httpRequest = mock(IHttpRequest.class);
when(httpClient.createGetRequest(any(FhirContext.class), any(EncodingEnum.class))).thenReturn(httpRequest);
IHttpResponse httpResponse = mock(IHttpResponse.class);
when(httpRequest.execute()).thenReturn(httpResponse);
when(httpResponse.getStatus()).thenReturn(404);
ApacheRestfulClientFactory cf = new ApacheRestfulClientFactory(ctx);
IHttpClient client = mock(IHttpClient.class);
BaseClient baseClient = mock(BaseClient.class);
try {
cf.validateServerBase("http://localhost:9999", client, baseClient);
fail();
} catch (ResourceNotFoundException e) {
// ok
}
}
@AfterClass
public static void afterClassClearContext() {
TestUtil.clearAllStaticFieldsForUnitTest();
}
}

View File

@ -274,6 +274,11 @@
<id>vadi2</id>
<name>Vadim Peretokin</name>
</developer>
<developer>
<id>lawley</id>
<name>Michael Lawley</name>
<organization>CSIRO</organization>
</developer>
</developers>
<licenses>
@ -307,7 +312,7 @@
<maven_source_plugin_version>2.4</maven_source_plugin_version>
<phloc_schematron_version>2.7.1</phloc_schematron_version>
<phloc_commons_version>4.4.5</phloc_commons_version>
<spring_version>4.3.1.RELEASE</spring_version>
<spring_version>4.3.4.RELEASE</spring_version>
<thymeleaf-version>3.0.1.RELEASE</thymeleaf-version>
<xmlunit_version>1.6</xmlunit_version>

View File

@ -7,7 +7,16 @@
</properties>
<body>
<release version="2.2" date="TBD">
<action type="fix">
<action type="add">
Bump the version of a few dependencies to the
latest versions (dependent HAPI modules listed in brackets):
<![CDATA[
<ul>
<li>spring (JPA): 4.3.1 -&gt; 4.3.4</li>
</ul>
]]>
</action>
<action type="fix">
Fix issue in AuthorizationIntetceptor where
transactions are blocked even when they
should not be
@ -46,6 +55,26 @@
or log a warning depending on the configured
error handler.
</action>
<action type="fix" issue="276">
Fix issue when serializing resources that have
contained resources which are referred to
from multiple places. Sometimes when serializing
these resources the contained resource section
would contain duplicates. Thanks to Hugo Soares
and Stefan Evinance for reporting and providing
a test case!
</action>
<action type="add" issue="518">
Allow client to gracefully handle running in DSTU3 mode
but with a structures JAR that does not contain a
CapabilityStatement resource. Thanks to Michael Lawley
for the pull request!
</action>
<action type="fix">
Fix a crash in JPA server when searching using an _include if _include targets are
external references (and therefore can't be loaded
by the server). Thanks to Hannes Ulrich for reporting!
</action>
</release>
<release version="2.1" date="2016-11-11">
<action type="add">