Fix #744 - Long search URLs on Derby shouldn't cause a failure

This commit is contained in:
James Agnew 2017-10-05 13:41:22 -04:00
parent 4d1ab2734f
commit 0ab8a9a0ba
5 changed files with 96 additions and 12 deletions

View File

@ -1259,7 +1259,7 @@ public class SearchBuilder implements ISearchBuilder {
* Check if there is a unique key associated with the set
* of parameters passed in
*/
ourLog.info("Checking for unique index for query: {}", theParams.toNormalizedQueryString(myContext));
ourLog.debug("Checking for unique index for query: {}", theParams.toNormalizedQueryString(myContext));
if (myCallingDao.getConfig().isUniqueIndexesEnabled()) {
if (myParams.getIncludes().isEmpty()) {
if (myParams.getRevIncludes().isEmpty()) {

View File

@ -50,6 +50,7 @@ public class Search implements Serializable {
private static final int FAILURE_MESSAGE_LENGTH = 500;
private static final long serialVersionUID = 1L;
public static final int MAX_SEARCH_QUERY_STRING = 10000;
@Temporal(TemporalType.TIMESTAMP)
@Column(name="CREATED", nullable=false, updatable=false)
@ -100,8 +101,8 @@ public class Search implements Serializable {
private Date mySearchLastReturned;
@Lob()
@Basic(fetch=FetchType.LAZY)
@Column(name="SEARCH_QUERY_STRING", nullable=true, updatable=false)
@Basic(fetch=FetchType.LAZY)
@Column(name="SEARCH_QUERY_STRING", nullable=true, updatable=false, length = MAX_SEARCH_QUERY_STRING)
private String mySearchQueryString;
@Column(name="SEARCH_QUERY_STRING_HASH", nullable=true, updatable=false)
@ -256,7 +257,11 @@ public class Search implements Serializable {
}
public void setSearchQueryString(String theSearchQueryString) {
mySearchQueryString = theSearchQueryString;
if (theSearchQueryString != null && theSearchQueryString.length() > MAX_SEARCH_QUERY_STRING) {
mySearchQueryString = null;
} else {
mySearchQueryString = theSearchQueryString;
}
}
public void setSearchQueryStringHash(Integer theSearchQueryStringHash) {

View File

@ -78,13 +78,6 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
private int mySyncSize = DEFAULT_SYNC_SIZE;
// @Autowired
// private DataSource myDataSource;
// @PostConstruct
// public void start() {
// JpaTransactionManager txManager = (JpaTransactionManager) myManagedTxManager;
// }
/**
* Constructor
*/

View File

@ -44,11 +44,92 @@ public class FhirResourceDaoR4SearchNoFtTest extends BaseJpaR4Test {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirResourceDaoR4SearchNoFtTest.class);
@Before
public void beforeDisableResultReuse() {
public void beforeDidsableCacheReuse() {
myDaoConfig.setReuseCachedSearchResultsForMillis(null);
}
@After
public void afterResetSearchSize() {
myDaoConfig.setReuseCachedSearchResultsForMillis(new DaoConfig().getReuseCachedSearchResultsForMillis());
myDaoConfig.setFetchSizeDefaultMaximum(new DaoConfig().getFetchSizeDefaultMaximum());
}
/**
* See #744
*/
@Test
public void testSearchWithVeryLongUrlShorter() {
myDaoConfig.setReuseCachedSearchResultsForMillis(new DaoConfig().getReuseCachedSearchResultsForMillis());
Patient p = new Patient();
p.addName().setFamily("A1");
myPatientDao.create(p);
assertEquals(0, mySearchEntityDao.count());
SearchParameterMap map = new SearchParameterMap();
StringOrListParam or = new StringOrListParam();
or.addOr(new StringParam("A1"));
or.addOr(new StringParam(StringUtils.leftPad("", 200, 'A')));
or.addOr(new StringParam(StringUtils.leftPad("", 200, 'B')));
or.addOr(new StringParam(StringUtils.leftPad("", 200, 'C')));
map.add(Patient.SP_NAME, or);
IBundleProvider results = myPatientDao.search(map);
assertEquals(1, results.getResources(0, 10).size());
assertEquals(1, mySearchEntityDao.count());
map = new SearchParameterMap();
or = new StringOrListParam();
or.addOr(new StringParam("A1"));
or.addOr(new StringParam(StringUtils.leftPad("", 200, 'A')));
or.addOr(new StringParam(StringUtils.leftPad("", 200, 'B')));
or.addOr(new StringParam(StringUtils.leftPad("", 200, 'C')));
map.add(Patient.SP_NAME, or);
results = myPatientDao.search(map);
assertEquals(1, results.getResources(0, 10).size());
assertEquals(1, mySearchEntityDao.count());
}
/**
* See #744
*/
@Test
public void testSearchWithVeryLongUrlLonger() {
myDaoConfig.setReuseCachedSearchResultsForMillis(new DaoConfig().getReuseCachedSearchResultsForMillis());
Patient p = new Patient();
p.addName().setFamily("A1");
myPatientDao.create(p);
assertEquals(0, mySearchEntityDao.count());
SearchParameterMap map = new SearchParameterMap();
StringOrListParam or = new StringOrListParam();
or.addOr(new StringParam("A1"));
for (int i = 0; i < 50; i++) {
or.addOr(new StringParam(StringUtils.leftPad("", 200, (char)('A' + i))));
}
map.add(Patient.SP_NAME, or);
IBundleProvider results = myPatientDao.search(map);
assertEquals(1, results.getResources(0, 10).size());
assertEquals(1, mySearchEntityDao.count());
map = new SearchParameterMap();
or = new StringOrListParam();
or.addOr(new StringParam("A1"));
or.addOr(new StringParam("A1"));
for (int i = 0; i < 50; i++) {
or.addOr(new StringParam(StringUtils.leftPad("", 200, (char)('A' + i))));
}
map.add(Patient.SP_NAME, or);
results = myPatientDao.search(map);
assertEquals(1, results.getResources(0, 10).size());
// We expect a new one because we don't cache the search URL for very long search URLs
assertEquals(2, mySearchEntityDao.count());
}
/**
* See #441
*/

View File

@ -27,6 +27,11 @@
has been changed to only accept "url".
Thanks to Avinash Shanbhag for reporting!
</action>
<action type="fix" issue="744">
Fix an error in JPA server when using Derby Database, where search queries with
a search URL longer than 255 characters caused a mysterious failure. Thanks to
Chris Schuler and Bryn Rhodes for all of their help in reproducing this issue.
</action>
</release>
<release version="3.0.0" date="2017-09-27">
<action type="add">