Merge pull request #1910 from jamesagnew/im_20200605_db_blob_mssql
Im 20200605 db blob mssql
This commit is contained in:
commit
926afd01f2
|
@ -222,6 +222,11 @@ public class DaoConfig {
|
||||||
*/
|
*/
|
||||||
private boolean myLastNEnabled = false;
|
private boolean myLastNEnabled = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 5.1.0
|
||||||
|
*/
|
||||||
|
private boolean myPreloadBlobFromInputStream = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*/
|
*/
|
||||||
|
@ -2083,4 +2088,42 @@ public class DaoConfig {
|
||||||
myMaximumDeleteConflictQueryCount = theMaximumDeleteConflictQueryCount;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@ package ca.uhn.fhir.jpa.binstore;
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import ca.uhn.fhir.jpa.api.config.DaoConfig;
|
||||||
import ca.uhn.fhir.jpa.dao.data.IBinaryStorageEntityDao;
|
import ca.uhn.fhir.jpa.dao.data.IBinaryStorageEntityDao;
|
||||||
import ca.uhn.fhir.jpa.model.entity.BinaryStorageEntity;
|
import ca.uhn.fhir.jpa.model.entity.BinaryStorageEntity;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
|
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
|
||||||
|
@ -55,10 +56,12 @@ public class DatabaseBlobBinaryStorageSvcImpl extends BaseBinaryStorageSvcImpl {
|
||||||
private IBinaryStorageEntityDao myBinaryStorageEntityDao;
|
private IBinaryStorageEntityDao myBinaryStorageEntityDao;
|
||||||
@Autowired
|
@Autowired
|
||||||
private PlatformTransactionManager myPlatformTransactionManager;
|
private PlatformTransactionManager myPlatformTransactionManager;
|
||||||
|
@Autowired
|
||||||
|
private DaoConfig myDaoConfig;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(Transactional.TxType.SUPPORTS)
|
@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();
|
Date publishedDate = new Date();
|
||||||
|
|
||||||
HashingInputStream hashingInputStream = createHashingInputStream(theInputStream);
|
HashingInputStream hashingInputStream = createHashingInputStream(theInputStream);
|
||||||
|
@ -74,7 +77,13 @@ public class DatabaseBlobBinaryStorageSvcImpl extends BaseBinaryStorageSvcImpl {
|
||||||
|
|
||||||
Session session = (Session) myEntityManager.getDelegate();
|
Session session = (Session) myEntityManager.getDelegate();
|
||||||
LobHelper lobHelper = session.getLobHelper();
|
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);
|
entity.setBlob(dataBlob);
|
||||||
|
|
||||||
// Save the entity
|
// Save the entity
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
package ca.uhn.fhir.jpa.binstore;
|
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.dao.r4.BaseJpaR4Test;
|
||||||
import ca.uhn.fhir.jpa.model.entity.BinaryStorageEntity;
|
import ca.uhn.fhir.jpa.model.entity.BinaryStorageEntity;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
|
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
|
||||||
import org.hl7.fhir.r4.model.IdType;
|
import org.hl7.fhir.r4.model.IdType;
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Qualifier;
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
|
@ -32,6 +35,21 @@ public class DatabaseBlobBinaryStorageSvcImplTest extends BaseJpaR4Test {
|
||||||
@Qualifier("databaseBlobBinaryStorageSvc")
|
@Qualifier("databaseBlobBinaryStorageSvc")
|
||||||
private IBinaryStorageSvc mySvc;
|
private IBinaryStorageSvc mySvc;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DaoConfig myDaoConfig;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void backupDaoConfig() {
|
||||||
|
defaultPreloadBlobFromInputStream = myDaoConfig.isPreloadBlobFromInputStream();
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void restoreDaoConfig() {
|
||||||
|
myDaoConfig.setPreloadBlobFromInputStream(defaultPreloadBlobFromInputStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean defaultPreloadBlobFromInputStream;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testStoreAndRetrieve() throws IOException {
|
public void testStoreAndRetrieve() throws IOException {
|
||||||
|
|
||||||
|
@ -78,6 +96,12 @@ public class DatabaseBlobBinaryStorageSvcImplTest extends BaseJpaR4Test {
|
||||||
assertArrayEquals(SOME_BYTES, mySvc.fetchBlob(resourceId, outcome.getBlobId()));
|
assertArrayEquals(SOME_BYTES, mySvc.fetchBlob(resourceId, outcome.getBlobId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testStoreAndRetrieveWithPreload() throws IOException {
|
||||||
|
myDaoConfig.setPreloadBlobFromInputStream(true);
|
||||||
|
testStoreAndRetrieve();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testStoreAndRetrieveWithManualId() throws IOException {
|
public void testStoreAndRetrieveWithManualId() throws IOException {
|
||||||
|
|
Loading…
Reference in New Issue