Merge pull request #1910 from jamesagnew/im_20200605_db_blob_mssql

Im 20200605 db blob mssql
This commit is contained in:
IanMMarshall 2020-06-09 13:48:53 -04:00 committed by GitHub
commit 926afd01f2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 78 additions and 2 deletions

View File

@ -222,6 +222,11 @@ public class DaoConfig {
*/
private boolean myLastNEnabled = false;
/**
* @since 5.1.0
*/
private boolean myPreloadBlobFromInputStream = false;
/**
* Constructor
*/
@ -2083,4 +2088,42 @@ public class DaoConfig {
myMaximumDeleteConflictQueryCount = theMaximumDeleteConflictQueryCount;
}
/**
* <p>
* This determines whether $binary-access-write operations should first load the InputStream into memory before persisting the
* contents to the database. This needs to be enabled for MS SQL Server as this DB requires that the blob size be known
* in advance.
* </p>
* <p>
* Note that this setting should be enabled with caution as it can lead to significant demands on memory.
* </p>
* <p>
* The default value for this setting is {@code false}.
* </p>
*
* @since 5.1.0
*/
public boolean isPreloadBlobFromInputStream() {
return myPreloadBlobFromInputStream;
}
/**
* <p>
* This determines whether $binary-access-write operations should first load the InputStream into memory before persisting the
* contents to the database. This needs to be enabled for MS SQL Server as this DB requires that the blob size be known
* in advance.
* </p>
* <p>
* Note that this setting should be enabled with caution as it can lead to significant demands on memory.
* </p>
* <p>
* The default value for this setting is {@code false}.
* </p>
*
* @since 5.1.0
*/
public void setPreloadBlobFromInputStream(Boolean thePreloadBlobFromInputStream) {
myPreloadBlobFromInputStream = thePreloadBlobFromInputStream;
}
}

View File

@ -20,6 +20,7 @@ package ca.uhn.fhir.jpa.binstore;
* #L%
*/
import ca.uhn.fhir.jpa.api.config.DaoConfig;
import ca.uhn.fhir.jpa.dao.data.IBinaryStorageEntityDao;
import ca.uhn.fhir.jpa.model.entity.BinaryStorageEntity;
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
@ -55,10 +56,12 @@ public class DatabaseBlobBinaryStorageSvcImpl extends BaseBinaryStorageSvcImpl {
private IBinaryStorageEntityDao myBinaryStorageEntityDao;
@Autowired
private PlatformTransactionManager myPlatformTransactionManager;
@Autowired
private DaoConfig myDaoConfig;
@Override
@Transactional(Transactional.TxType.SUPPORTS)
public StoredDetails storeBlob(IIdType theResourceId, String theBlobIdOrNull, String theContentType, InputStream theInputStream) {
public StoredDetails storeBlob(IIdType theResourceId, String theBlobIdOrNull, String theContentType, InputStream theInputStream) throws IOException {
Date publishedDate = new Date();
HashingInputStream hashingInputStream = createHashingInputStream(theInputStream);
@ -74,7 +77,13 @@ public class DatabaseBlobBinaryStorageSvcImpl extends BaseBinaryStorageSvcImpl {
Session session = (Session) myEntityManager.getDelegate();
LobHelper lobHelper = session.getLobHelper();
Blob dataBlob = lobHelper.createBlob(countingInputStream, 0);
Blob dataBlob;
if (myDaoConfig.isPreloadBlobFromInputStream()) {
byte[] loadedStream = IOUtils.toByteArray(countingInputStream);
dataBlob = lobHelper.createBlob(loadedStream);
} else {
dataBlob = lobHelper.createBlob(countingInputStream, 0);
}
entity.setBlob(dataBlob);
// Save the entity

View File

@ -1,9 +1,12 @@
package ca.uhn.fhir.jpa.binstore;
import ca.uhn.fhir.jpa.api.config.DaoConfig;
import ca.uhn.fhir.jpa.dao.r4.BaseJpaR4Test;
import ca.uhn.fhir.jpa.model.entity.BinaryStorageEntity;
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
import org.hl7.fhir.r4.model.IdType;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
@ -32,6 +35,21 @@ public class DatabaseBlobBinaryStorageSvcImplTest extends BaseJpaR4Test {
@Qualifier("databaseBlobBinaryStorageSvc")
private IBinaryStorageSvc mySvc;
@Autowired
private DaoConfig myDaoConfig;
@Before
public void backupDaoConfig() {
defaultPreloadBlobFromInputStream = myDaoConfig.isPreloadBlobFromInputStream();
}
@After
public void restoreDaoConfig() {
myDaoConfig.setPreloadBlobFromInputStream(defaultPreloadBlobFromInputStream);
}
boolean defaultPreloadBlobFromInputStream;
@Test
public void testStoreAndRetrieve() throws IOException {
@ -78,6 +96,12 @@ public class DatabaseBlobBinaryStorageSvcImplTest extends BaseJpaR4Test {
assertArrayEquals(SOME_BYTES, mySvc.fetchBlob(resourceId, outcome.getBlobId()));
}
@Test
public void testStoreAndRetrieveWithPreload() throws IOException {
myDaoConfig.setPreloadBlobFromInputStream(true);
testStoreAndRetrieve();
}
@Test
public void testStoreAndRetrieveWithManualId() throws IOException {