diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/BaseParser.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/BaseParser.java index 34781546014..91898e2df9f 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/BaseParser.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/BaseParser.java @@ -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; } diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/RestfulClientFactory.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/RestfulClientFactory.java index d33cacc4f55..62d2b7472e2 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/RestfulClientFactory.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/RestfulClientFactory.java @@ -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) { diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/SearchBuilder.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/SearchBuilder.java index b75b7592bed..a5d621dac90 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/SearchBuilder.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/SearchBuilder.java @@ -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); + } } } } diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu2/FhirResourceDaoDstu2Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu2/FhirResourceDaoDstu2Test.java index 7b870fc56ab..8c6e5211332 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu2/FhirResourceDaoDstu2Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu2/FhirResourceDaoDstu2Test.java @@ -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"; diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/dstu3/ResourceProviderDstu3Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/dstu3/ResourceProviderDstu3Test.java index 2f7552813bc..a5611d6b046 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/dstu3/ResourceProviderDstu3Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/dstu3/ResourceProviderDstu3Test.java @@ -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); diff --git a/hapi-fhir-jpaserver-base/src/test/resources/binu_testpatient_resource.json b/hapi-fhir-jpaserver-base/src/test/resources/binu_testpatient_resource.json new file mode 100644 index 00000000000..c0024ecee3c --- /dev/null +++ b/hapi-fhir-jpaserver-base/src/test/resources/binu_testpatient_resource.json @@ -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": "
GHASIYA AL WAHEIBI
Identifier14731
Address
Date of birth01 January 1981
" + }, + "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" + } +} \ No newline at end of file diff --git a/hapi-fhir-jpaserver-base/src/test/resources/binu_testpatient_structuredefinition_dstu2.xml b/hapi-fhir-jpaserver-base/src/test/resources/binu_testpatient_structuredefinition_dstu2.xml new file mode 100644 index 00000000000..5f3898799c9 --- /dev/null +++ b/hapi-fhir-jpaserver-base/src/test/resources/binu_testpatient_structuredefinition_dstu2.xml @@ -0,0 +1,2531 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/hapi-fhir-structures-dstu/src/test/java/ca/uhn/fhir/parser/JsonParserTest.java b/hapi-fhir-structures-dstu/src/test/java/ca/uhn/fhir/parser/JsonParserTest.java index 4f9219b4e35..14adfbe9bc6 100644 --- a/hapi-fhir-structures-dstu/src/test/java/ca/uhn/fhir/parser/JsonParserTest.java +++ b/hapi-fhir-structures-dstu/src/test/java/ca/uhn/fhir/parser/JsonParserTest.java @@ -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\":\"
"); @@ -107,6 +103,7 @@ public class JsonParserTest { assertEquals(exp, act); } + @Test public void testDecimalPrecisionPreserved() { String number = "52.3779939997090374535378485873776474764643249869328698436986235758587"; diff --git a/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/rest/client/RestfulClientFactoryDstu2Test.java b/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/rest/client/RestfulClientFactoryDstu2Test.java new file mode 100644 index 00000000000..b01941bfa13 --- /dev/null +++ b/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/rest/client/RestfulClientFactoryDstu2Test.java @@ -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>)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(); + } +} diff --git a/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/parser/JsonParserDstu3Test.java b/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/parser/JsonParserDstu3Test.java index e67c190e0df..b70bcf2ce9e 100644 --- a/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/parser/JsonParserDstu3Test.java +++ b/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/parser/JsonParserDstu3Test.java @@ -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 elementName = ArgumentCaptor.forClass(String.class); ArgumentCaptor expected = ArgumentCaptor.forClass(ValueType.class); ArgumentCaptor 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()); 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)null); + parser.setDontStripVersionsFromReferencesAtPaths((List) 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\":\"
\"}}"; Basic basic = ourCtx.newJsonParser().parseResource(Basic.class, input); assertEquals(null, basic.getText().getDivAsString()); - + input = "{\"resourceType\":\"Basic\",\"id\":\"1\",\"text\":{\"status\":\"generated\",\"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()); } diff --git a/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/rest/client/RestfulClientFactoryTest.java b/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/rest/client/RestfulClientFactoryTest.java new file mode 100644 index 00000000000..87e36b7d6c8 --- /dev/null +++ b/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/rest/client/RestfulClientFactoryTest.java @@ -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>)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(); + } +} diff --git a/pom.xml b/pom.xml index 3f7b8f58f2c..2565b52e4a6 100644 --- a/pom.xml +++ b/pom.xml @@ -274,6 +274,11 @@ vadi2 Vadim Peretokin + + lawley + Michael Lawley + CSIRO + @@ -307,7 +312,7 @@ 2.4 2.7.1 4.4.5 - 4.3.1.RELEASE + 4.3.4.RELEASE 3.0.1.RELEASE 1.6 diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 2675db22047..552e3c154b4 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -7,7 +7,16 @@ - + + Bump the version of a few dependencies to the + latest versions (dependent HAPI modules listed in brackets): + +
  • spring (JPA): 4.3.1 -> 4.3.4
  • + + ]]> +
    + 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. + + 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! + + + 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! + + + 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! +