@Override public ValueSetExpansionOutcome expandVS(ValueSet vs, boolean cacheOk, boolean heirarchical) { try { if (vs.hasExpansion()) { return new ValueSetExpansionOutcome(vs.copy()); } String cacheFn = null; if (cache != null) { cacheFn = Utilities.path(cache, determineCacheId(vs, heirarchical) + ".json"); if (new File(cacheFn).exists()) return loadFromCache(vs.copy(), cacheFn); } if (cacheOk && vs.hasUrl()) { if (expProfile == null) throw new Exception("No ExpansionProfile provided"); ValueSetExpansionOutcome vse = expansionCache.getExpander().expand(vs, expProfile.setExcludeNested(!heirarchical)); if (vse.getValueset() != null) { if (cache != null) { FileOutputStream s = new FileOutputStream(cacheFn); newJsonParser().compose(new FileOutputStream(cacheFn), vse.getValueset()); s.close(); } } return vse; } else { ValueSetExpansionOutcome res = expandOnServer(vs, cacheFn); if (cacheFn != null) { if (res.getValueset() != null) { saveToCache(res.getValueset(), cacheFn); } else { OperationOutcome oo = new OperationOutcome(); oo.addIssue().getDetails().setText(res.getError()); saveToCache(oo, cacheFn); } } return res; } } catch (NoTerminologyServiceException e) { return new ValueSetExpansionOutcome( e.getMessage() == null ? e.getClass().getName() : e.getMessage(), TerminologyServiceErrorClass.NOSERVICE); } catch (Exception e) { return new ValueSetExpansionOutcome( e.getMessage() == null ? e.getClass().getName() : e.getMessage(), TerminologyServiceErrorClass.UNKNOWN); } }
private Bundle batch(final RequestDetails theRequestDetails, Bundle theRequest) { ourLog.info("Beginning batch with {} resources", theRequest.getEntry().size()); long start = System.currentTimeMillis(); TransactionTemplate txTemplate = new TransactionTemplate(myTxManager); txTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); Bundle resp = new Bundle(); resp.setType(BundleType.BATCHRESPONSE); OperationOutcome ooResp = new OperationOutcome(); resp.addEntry().setResource(ooResp); /* * For batch, we handle each entry as a mini-transaction in its own database transaction so that if one fails, it doesn't prevent others */ for (final BundleEntryComponent nextRequestEntry : theRequest.getEntry()) { TransactionCallback<Bundle> callback = new TransactionCallback<Bundle>() { @Override public Bundle doInTransaction(TransactionStatus theStatus) { Bundle subRequestBundle = new Bundle(); subRequestBundle.setType(BundleType.TRANSACTION); subRequestBundle.addEntry(nextRequestEntry); Bundle subResponseBundle = transaction( (ServletRequestDetails) theRequestDetails, subRequestBundle, "Batch sub-request"); return subResponseBundle; } }; BaseServerResponseException caughtEx; try { Bundle nextResponseBundle = txTemplate.execute(callback); caughtEx = null; BundleEntryComponent subResponseEntry = nextResponseBundle.getEntry().get(0); resp.addEntry(subResponseEntry); /* * If the individual entry didn't have a resource in its response, bring the sub-transaction's OperationOutcome across so the client can see it */ if (subResponseEntry.getResource() == null) { subResponseEntry.setResource(nextResponseBundle.getEntry().get(0).getResource()); } } catch (BaseServerResponseException e) { caughtEx = e; } catch (Throwable t) { ourLog.error("Failure during BATCH sub transaction processing", t); caughtEx = new InternalErrorException(t); } if (caughtEx != null) { BundleEntryComponent nextEntry = resp.addEntry(); OperationOutcome oo = new OperationOutcome(); oo.addIssue().setSeverity(IssueSeverity.ERROR).setDiagnostics(caughtEx.getMessage()); nextEntry.setResource(oo); BundleEntryResponseComponent nextEntryResp = nextEntry.getResponse(); nextEntryResp.setStatus(toStatusString(caughtEx.getStatusCode())); } } long delay = System.currentTimeMillis() - start; ourLog.info("Batch completed in {}ms", new Object[] {delay}); ooResp .addIssue() .setSeverity(IssueSeverity.INFORMATION) .setDiagnostics("Batch completed in " + delay + "ms"); return resp; }