Merge branch 'master' into 5873-support-effective-data-reqs

This commit is contained in:
Brenin Rhodes 2024-04-30 19:57:36 -06:00
commit cdce4f4806
9 changed files with 99 additions and 4 deletions

View File

@ -0,0 +1,5 @@
---
type: fix
issue: 5874
jira: SMILE-8149
title: "Fixed a bug where 'List' would be incorrectly shown as 'ListResource' in the error response for a GET for an invalid resource."

View File

@ -0,0 +1,6 @@
---
type: fix
issue: 4556
title: "The CSS file used by the OpenApiInterceptor to serve up the Swagger UI
component inadvertently blocked the authorization button evem when it was
wanted. This has been fixed. Thanks Jesse Bonzo for the contribution!"

View File

@ -0,0 +1,5 @@
---
type: fix
issue: 5877
title: "Previously, updating a tokenParam with a value greater than 200 characters would raise a SQLException.
This issue has been fixed."

View File

@ -36,6 +36,7 @@ import jakarta.persistence.Index;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.PrePersist;
import jakarta.persistence.PreUpdate;
import jakarta.persistence.SequenceGenerator;
import jakarta.persistence.Table;
import org.apache.commons.lang3.StringUtils;
@ -429,6 +430,7 @@ public class ResourceIndexedSearchParamToken extends BaseResourceIndexedSearchPa
* We don't truncate earlier in the flow because the index hashes MUST be calculated on the full string.
*/
@PrePersist
@PreUpdate
public void truncateFieldsForDB() {
mySystem = StringUtils.truncate(mySystem, MAX_LENGTH);
myValue = StringUtils.truncate(myValue, MAX_LENGTH);

View File

@ -54,7 +54,6 @@ 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.util.ClasspathUtil;
import com.google.common.base.Charsets;
import com.google.common.collect.Lists;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.RandomStringUtils;
@ -83,6 +82,7 @@ import org.hl7.fhir.r4.model.CompartmentDefinition;
import org.hl7.fhir.r4.model.ConceptMap;
import org.hl7.fhir.r4.model.Condition;
import org.hl7.fhir.r4.model.Consent;
import org.hl7.fhir.r4.model.ContactPoint;
import org.hl7.fhir.r4.model.DateTimeType;
import org.hl7.fhir.r4.model.DateType;
import org.hl7.fhir.r4.model.Device;
@ -157,9 +157,11 @@ import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.Matchers.hasItem;
import static org.hamcrest.Matchers.hasItems;
import static org.hamcrest.Matchers.hasLength;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.matchesPattern;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.startsWith;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
@ -247,6 +249,42 @@ public class FhirResourceDaoR4Test extends BaseJpaR4Test {
return retVal;
}
@Test
public void testUpdateResource_whenTokenPropertyAssignedTooLargeValue_willTruncateLargeValueOnUpdate(){
// given
final String modifiedEmailPrefix = "modified";
final String originalEmail = RandomStringUtils.randomAlphanumeric(ResourceIndexedSearchParamToken.MAX_LENGTH) + "@acme.corp";
final String modifiedEmail = modifiedEmailPrefix + originalEmail;
// when
Patient pt1 = new Patient();
pt1.setActive(true);
pt1.addName().setFamily("FAM");
pt1.addTelecom().setSystem(ContactPoint.ContactPointSystem.EMAIL).setValue(originalEmail);
myPatientDao.create(pt1).getId().toUnqualifiedVersionless();
pt1.getTelecomFirstRep().setValue(modifiedEmail);
IIdType id1 = myPatientDao.update(pt1).getId().toUnqualifiedVersionless();
// then
runInTransaction(() -> {
List<String> paramValues = myResourceIndexedSearchParamTokenDao
.findAll()
.stream()
.filter(t -> defaultString(t.getSystem()).equals("email"))
.map(t -> t.getValue())
.collect(Collectors.toList());
assertThat(paramValues, hasSize(2));
for (String tokenValue : paramValues) {
assertThat(tokenValue, startsWith(modifiedEmailPrefix));
assertThat(tokenValue, hasLength(ResourceIndexedSearchParamToken.MAX_LENGTH));
}
});
}
@Test
public void testDeletedResourcesAreReindexed() {

View File

@ -141,6 +141,10 @@ body
}
/* Disable the servers dropdown, which is useless here */
.swagger-ui .scheme-container {
display: none;
.swagger-ui .scheme-container .servers-title {
display: none;
}
.swagger-ui .scheme-container .servers {
display: none;
}

View File

@ -1990,7 +1990,8 @@ public class RestfulServer extends HttpServlet implements IRestfulServer<Servlet
/* perform a 'distinct' in case there are multiple concrete IResourceProviders declared for the same FHIR-Resource. (A concrete IResourceProvider for Patient@Read and a separate concrete for Patient@Search for example */
/* perform a 'sort' to provide an easier to read alphabetized list (vs how the different FHIR-resource IResourceProviders happened to be registered */
List<String> knownDistinctAndSortedResourceTypes = myResourceProviders.stream()
.map(t -> t.getResourceType().getSimpleName())
.map(t ->
myFhirContext.getResourceDefinition(t.getResourceType()).getName())
.distinct()
.sorted()
.collect(toList());

View File

@ -10,13 +10,17 @@ import ca.uhn.fhir.rest.annotation.Metadata;
import ca.uhn.fhir.rest.annotation.Operation;
import ca.uhn.fhir.rest.annotation.ResourceParam;
import ca.uhn.fhir.rest.api.MethodOutcome;
import ca.uhn.fhir.rest.api.RequestTypeEnum;
import ca.uhn.fhir.rest.api.server.IFhirVersionServer;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.api.server.SystemRequestDetails;
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
import org.hl7.fhir.instance.model.api.IBaseBundle;
import org.hl7.fhir.instance.model.api.IBaseConformance;
import org.hl7.fhir.instance.model.api.IBaseMetaType;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.r4.model.ListResource;
import org.hl7.fhir.r4.model.Patient;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@ -88,6 +92,20 @@ public class RestfulServerTest {
}
}
@Test
public void exceptionHandling() {
final SystemRequestDetails requestDetails = new SystemRequestDetails();
requestDetails.setRequestType(RequestTypeEnum.GET);
requestDetails.setResourceName("InvalidResourceName");
myRestfulServer.registerProvider(new MyListResourceProvider());
ResourceNotFoundException thrown = assertThrows(
ResourceNotFoundException.class,
() -> myRestfulServer.determineResourceMethod(requestDetails, "1234"),
"Expected request to fail, but it succeeded.");
assertTrue(thrown.getMessage().contains("List"));
assertFalse(thrown.getMessage().contains("ListResource"));
}
//--------- Scaffolding ---------//
private static class MyClassWithoutRestInterface implements Serializable {
@ -141,6 +159,18 @@ public class RestfulServerTest {
}
}
private static class MyListResourceProvider implements IResourceProvider {
@Create
public MethodOutcome create(@ResourceParam IBaseResource theResource) {
return mock(MethodOutcome.class);
}
@Override
public Class<? extends IBaseResource> getResourceType() {
return ListResource.class;
}
}
private static class MyProvider implements IResourceProvider {
@Operation(name = "SHOW_ME_THE_MONEY", typeName = "MyResource")
public IBaseBundle match() {

View File

@ -905,6 +905,10 @@
<id>pano-smals</id>
<name>pano-smals</name>
</developer>
<developer>
<id>jbonzohln</id>
<name>Jesse Bonzo</name>
</developer>
</developers>
<licenses>