Is there a way to quickly wipe the HAPI server's data?

1,358 views
Skip to first unread message

karl....@cms.hhs.gov

unread,
Sep 27, 2016, 1:33:50 PM9/27/16
to HAPI FHIR
All,

Does anyone know of a way to quickly wipe the HAPI server's DB and indexes, without restarting the server? In our test cases, against HAPI v1.4, we're adding about 14K resources: it takes around 12 minutes to insert the data, and another 10 minutes to wipe it. Right now, I'm just using the following routine to wipe the data:

/**
* <strong>Serious Business:</strong> deletes all resources from the FHIR
* server used in tests.
*/
public static void cleanFhirServer() {
// Before disabling this check, please go and update your resume.
if (!FHIR_API.contains("localhost"))
throw new BadCodeMonkeyException("Saving you from a career-changing event.");

IGenericClient fhirClient = createFhirClient();
Conformance conformance = fhirClient.fetchConformance().ofType(Conformance.class).execute();

/*
* This is ugly code, but not worth making more readable. Here's what it
* does: grabs the server's conformance statement, looks at the
* supported resources, and then grabs all of the resource type names
* that support bulk conditional delete operations.
*/
List<String> resourcesToDelete = conformance.getRest().stream()
.filter(r -> r.getMode() == RestfulConformanceMode.SERVER).flatMap(r -> r.getResource().stream())
.filter(r -> r.getConditionalDelete() != null)
.filter(r -> r.getConditionalDelete() == ConditionalDeleteStatus.MULTIPLE).map(r -> r.getType())
.collect(Collectors.toList());

// Loop over each resource that can be deleted, and delete all of them.
/*
* TODO This commented-out version should work, given HAPI 1.4's
* conformance statement, but doesn't. Try again in a later version? The
* not-commented-out version below does work, but is slower.
*/
// for (String resourceTypeName : resourcesToDelete)
// fhirClient.delete().resourceConditionalByUrl(resourceTypeName).execute();
for (String resourceTypeName : resourcesToDelete) {
Bundle results = fhirClient.search().forResource(resourceTypeName).returnBundle(Bundle.class).execute();
while (true) {
for (BundleEntryComponent resourceEntry : results.getEntry())
fhirClient.delete()
.resourceById(resourceTypeName, resourceEntry.getResource().getIdElement().getIdPart())
.execute();

// Get next page of results (if there is one), or exit loop.
if (results.getLink(Bundle.LINK_NEXT) != null)
results = fhirClient.loadPage().next(results).execute();
else
break;
}
}
}


I'm working this sprint on performance tests, and test execution time is one of my main concerns, so I'm hoping there's a faster way to do this.

Thanks!
Karl

James Agnew

unread,
Sep 27, 2016, 1:48:15 PM9/27/16
to karl....@cms.hhs.gov, HAPI FHIR
Hi Karl,

HAPI's own unit tests wipe the database between executions by doing a "roughly direct" call to the DB. It goes through hibernate, but not through HAPI's own persistence stuff. You can see this in the "purgeDatabase" here: https://github.com/jamesagnew/hapi-fhir/blob/master/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/BaseJpaTest.java#L209

That method just goes through and brute-force deletes everything in the database, doing the tables in an order that prevents foreign-key constraints from getting in the way. It needs a copy of the EntityManager and TransactionManager, but you can get both of those from your Spring context if needed.

Note that doing this delete via hibernate also causes Hibernate Search to wipe the associated Lucene indexes. If you're not using Lucene features you could also just wipe the data directly from the database using TRUNCATE TABLE statements. HAPI doesn't do any caching that would be impacted by the database changing under it (other than Lucene).

Ps- Would love to hear about your performance results. We're actively working on performance enhancements these days, so anything you uncover (even just numbers for a given result set and platform) are very useful.

Pps- The following line is glorious :)

if (!FHIR_API.contains("localhost"))
throw new BadCodeMonkeyException("Saving you from a career-changing event.");

Cheers,
James

--
You received this message because you are subscribed to the Google Groups "HAPI FHIR" group.
To unsubscribe from this group and stop receiving emails from it, send an email to hapi-fhir+unsubscribe@googlegroups.com.
To post to this group, send email to hapi...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/hapi-fhir/e59e034f-4f7d-40db-be9f-06c54256fed9%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply all
Reply to author
Forward
0 new messages