Missed commit for #2471

This commit is contained in:
jamesagnew 2021-03-15 08:52:46 -04:00
parent 3a8881f913
commit 14f12e7dab
3 changed files with 71 additions and 5 deletions

View File

@ -24,7 +24,9 @@ import ca.uhn.fhir.interceptor.api.Hook;
import ca.uhn.fhir.interceptor.api.Interceptor;
import ca.uhn.fhir.interceptor.api.Pointcut;
import ca.uhn.fhir.jpa.api.model.ResourceVersionConflictResolutionStrategy;
import ca.uhn.fhir.jpa.partition.SystemRequestDetails;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import org.apache.commons.lang3.Validate;
import java.util.List;
import java.util.StringTokenizer;
@ -83,4 +85,12 @@ public class UserRequestRetryVersionConflictsInterceptor {
}
/**
* Convenience method to add a retry header to a system request
*/
public static void addRetryHeader(SystemRequestDetails theRequestDetails, int theMaxRetries) {
Validate.inclusiveBetween(1, Integer.MAX_VALUE, theMaxRetries, "Max retries must be > 0");
String value = RETRY + "; " + MAX_RETRIES + "=" + theMaxRetries;
theRequestDetails.addHeader(HEADER_NAME, value);
}
}

View File

@ -33,12 +33,19 @@ import ca.uhn.fhir.rest.server.ElementsSupportEnum;
import ca.uhn.fhir.rest.server.IPagingProvider;
import ca.uhn.fhir.rest.server.IRestfulServerDefaults;
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ImmutableListMultimap;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.ListMultimap;
import com.google.common.collect.Multimap;
import com.google.common.collect.Multimaps;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.nio.charset.Charset;
import java.util.List;
import java.util.Optional;
/**
* A default RequestDetails implementation that can be used for system calls to
@ -51,6 +58,8 @@ public class SystemRequestDetails extends RequestDetails {
super(new MyInterceptorBroadcaster());
}
private ListMultimap<String, String> myHeaders;
public SystemRequestDetails(IInterceptorBroadcaster theInterceptorBroadcaster) {
super(theInterceptorBroadcaster);
}
@ -72,14 +81,31 @@ public class SystemRequestDetails extends RequestDetails {
@Override
public String getHeader(String name) {
return null;
List<String> headers = getHeaders(name);
if (headers.isEmpty()) {
return null;
} else {
return headers.get(0);
}
}
@Override
public List<String> getHeaders(String name) {
return null;
ListMultimap<String, String> headers = myHeaders;
if (headers == null) {
headers = ImmutableListMultimap.of();
}
return headers.get(name);
}
public void addHeader(String theName, String theValue) {
if (myHeaders == null) {
myHeaders = ArrayListMultimap.create();
}
myHeaders.put(theName, theValue);
}
@Override
public Object getAttribute(String theAttributeName) {
return null;

View File

@ -12,14 +12,12 @@ import ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException;
import ca.uhn.fhir.rest.server.exceptions.ResourceVersionConflictException;
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
import ca.uhn.fhir.util.HapiExtensions;
import com.github.dockerjava.api.model.ResourceVersion;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.r4.model.BooleanType;
import org.hl7.fhir.r4.model.Bundle;
import org.hl7.fhir.r4.model.CodeType;
import org.hl7.fhir.r4.model.Enumerations;
import org.hl7.fhir.r4.model.IdType;
import org.hl7.fhir.r4.model.IntegerType;
import org.hl7.fhir.r4.model.Parameters;
import org.hl7.fhir.r4.model.Patient;
import org.hl7.fhir.r4.model.SearchParameter;
@ -140,6 +138,39 @@ public class FhirResourceDaoR4ConcurrentWriteTest extends BaseJpaR4Test {
}
@Test
public void testCreateWithClientAssignedId_SystemRequestContainingRetryDirective() throws InterruptedException, ExecutionException {
myInterceptorRegistry.registerInterceptor(myRetryInterceptor);
SystemRequestDetails requestDetails = new SystemRequestDetails();
UserRequestRetryVersionConflictsInterceptor.addRetryHeader(requestDetails, 10);
List<Future<?>> futures = new ArrayList<>();
for (int i = 0; i < 5; i++) {
Patient p = new Patient();
p.setId("ABC");
p.setActive(true);
p.addIdentifier().setValue("VAL" + i);
Runnable task = () -> {
myPatientDao.update(p, requestDetails);
};
Future<?> future = myExecutor.submit(task);
futures.add(future);
}
// Should not fail
for (Future<?> next : futures) {
next.get();
ourLog.info("Future produced success");
}
// Make sure we saved the object
Patient patient = myPatientDao.read(new IdType("Patient/ABC"));
ourLog.info(myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(patient));
assertEquals(true, patient.getActive());
}
@Test
public void testCreateWithUniqueConstraint() {
SearchParameter sp = new SearchParameter();
@ -424,7 +455,6 @@ public class FhirResourceDaoR4ConcurrentWriteTest extends BaseJpaR4Test {
}
@Test
public void testTransactionWithCreate() {
myInterceptorRegistry.registerInterceptor(myRetryInterceptor);