Skip to content

Commit

Permalink
Issue #2155 - Use hash to determine if search parameters need update
Browse files Browse the repository at this point in the history
Signed-off-by: Troy Biesterfeld <tbieste@us.ibm.com>
  • Loading branch information
tbieste committed Jun 16, 2021
1 parent 0676ad4 commit c970ada
Show file tree
Hide file tree
Showing 23 changed files with 852 additions and 236 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
import java.sql.SQLException;
import java.sql.Timestamp;
import java.time.Instant;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

Expand All @@ -33,6 +32,7 @@
import com.ibm.fhir.persistence.jdbc.dao.impl.ResourceDAOImpl;
import com.ibm.fhir.persistence.jdbc.dto.ExtractedParameterValue;
import com.ibm.fhir.persistence.jdbc.impl.ParameterTransactionDataImpl;
import com.ibm.fhir.persistence.jdbc.util.ExtractedSearchParameters;

/**
* DAO used to contain the logic required to reindex a given resource
Expand Down Expand Up @@ -111,6 +111,7 @@ public ReindexResourceDAO(Connection connection, IDatabaseTranslator translator,
* Getter for the translator currently held by this DAO
* @return
*/
@Override
protected IDatabaseTranslator getTranslator() {
return this.translator;
}
Expand Down Expand Up @@ -169,7 +170,8 @@ protected ResourceIndexRecord getNextResource(SecureRandom random, Instant reind
}
ResultSet rs = stmt.executeQuery();
if (rs.next()) {
result = new ResourceIndexRecord(rs.getLong(1), rs.getInt(2), rs.getString(3), rs.getLong(4));
// TODO: Update this when PARAMETERS_HASH column exists in the DB table
result = new ResourceIndexRecord(rs.getLong(1), rs.getInt(2), rs.getString(3), rs.getLong(4), null);
}
} catch (SQLException x) {
logger.log(Level.SEVERE, select, x);
Expand Down Expand Up @@ -270,7 +272,7 @@ public ResourceIndexRecord getResourceToReindex(Instant reindexTstamp, Integer r
* @param logicalResourceId the logical resource id
* @throws Exception
*/
public void updateParameters(String tablePrefix, List<ExtractedParameterValue> parameters, String logicalId, long logicalResourceId) throws Exception {
public void updateParameters(String tablePrefix, ExtractedSearchParameters parameters, String logicalId, long logicalResourceId) throws Exception {

final String METHODNAME = "updateParameters() for " + tablePrefix + "/" + logicalId;
logger.entering(CLASSNAME, METHODNAME);
Expand All @@ -295,21 +297,25 @@ public void updateParameters(String tablePrefix, List<ExtractedParameterValue> p
deleteFromParameterTable(connection, "str_values", logicalResourceId);
deleteFromParameterTable(connection, "date_values", logicalResourceId);


if (parameters != null && !parameters.isEmpty()) {
if (!parameters.getParameters().isEmpty()) {
JDBCIdentityCache identityCache = new JDBCIdentityCacheImpl(getCache(), this, parameterDao, getResourceReferenceDAO());
// Check if this is multitenant
boolean isMultitenant = this.getFlavor().isMultitenant();
try (ParameterVisitorBatchDAO pvd = new ParameterVisitorBatchDAO(connection, "FHIR_ADMIN", tablePrefix, isMultitenant, logicalResourceId, 100,
identityCache, getResourceReferenceDAO(), getTransactionData())) {
for (ExtractedParameterValue p: parameters) {
for (ExtractedParameterValue p: parameters.getParameters()) {
p.accept(pvd);
}
} catch (SQLException x) {
logger.log(Level.SEVERE, "inserting parameters", x);
throw translator.translate(x);
}
}

// Update the parameters hash
// TODO: Enable this when column exists
//updateParametersHash(connection, logicalResourceId, parameters.getHash());

logger.exiting(CLASSNAME, METHODNAME);
}

Expand All @@ -335,4 +341,27 @@ protected void deleteFromParameterTable(Connection conn, String tableName, long
throw translator.translate(x);
}
}

/**
* Updates the parameters hash in the LOGICAL_RESOURCES table.
* @param conn the connection
* @param logicalResourceId the logical resource ID
* @param hash the parameters hash
* @throws SQLException
*/
protected void updateParametersHash(Connection conn, long logicalResourceId, String hash) throws SQLException {
final String SQL = "UPDATE logical_resources SET parameters_hash = ? WHERE logical_resource_id = ?";
try (PreparedStatement stmt = conn.prepareStatement(SQL)) {
// bind parameters
stmt.setString(1, hash);
stmt.setLong(2, logicalResourceId);
stmt.executeUpdate();
if (logger.isLoggable(Level.FINEST)) {
logger.finest("Update parameters_hash [" + hash + "] for logicalResourceId [" + logicalResourceId + "]");
}
} catch (SQLException x) {
logger.log(Level.SEVERE, SQL, x);
throw translator.translate(x);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@
import com.ibm.fhir.persistence.context.FHIRPersistenceContext;
import com.ibm.fhir.persistence.exception.FHIRPersistenceException;
import com.ibm.fhir.persistence.exception.FHIRPersistenceVersionIdMismatchException;
import com.ibm.fhir.persistence.jdbc.dto.ExtractedParameterValue;
import com.ibm.fhir.persistence.jdbc.dto.Resource;
import com.ibm.fhir.persistence.jdbc.exception.FHIRPersistenceDBConnectException;
import com.ibm.fhir.persistence.jdbc.exception.FHIRPersistenceDataAccessException;
import com.ibm.fhir.persistence.jdbc.util.ExtractedSearchParameters;
import com.ibm.fhir.persistence.jdbc.util.SqlQueryData;

/**
Expand Down Expand Up @@ -224,6 +224,6 @@ List<Resource> search(String sqlSelect)
* @throws FHIRPersistenceVersionIdMismatchException
* @throws FHIRPersistenceException
*/
Resource insert(Resource resource, List<ExtractedParameterValue> parameters, ParameterDAO parameterDao)
Resource insert(Resource resource, ExtractedSearchParameters parameters, ParameterDAO parameterDao)
throws FHIRPersistenceException;
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,15 @@ public class ResourceIndexRecord {
// Deletion flag for the resource. Set when we read the resource
private boolean deleted;

public ResourceIndexRecord(long logicalResourceId, int resourceTypeId, String logicalId, long transactionId) {
// SHA-256 hash of the search parameters
private String parametersHash;

public ResourceIndexRecord(long logicalResourceId, int resourceTypeId, String logicalId, long transactionId, String parametersHash) {
this.logicalResourceId = logicalResourceId;
this.resourceTypeId = resourceTypeId;
this.logicalId = logicalId;
this.transactionId = transactionId;
this.parametersHash = parametersHash;
}

/**
Expand Down Expand Up @@ -92,4 +96,18 @@ public boolean isDeleted() {
public void setDeleted(boolean deleted) {
this.deleted = deleted;
}

/**
* @return the parametersHash
*/
public String getParametersHash() {
return parametersHash;
}

/**
* @param parametersHash the parametersHash to set
*/
public void setParametersHash(String parametersHash) {
this.parametersHash = parametersHash;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
import com.ibm.fhir.persistence.jdbc.exception.FHIRPersistenceDataAccessException;
import com.ibm.fhir.persistence.jdbc.exception.FHIRPersistenceFKVException;
import com.ibm.fhir.persistence.jdbc.impl.ParameterTransactionDataImpl;
import com.ibm.fhir.persistence.jdbc.util.ExtractedSearchParameters;
import com.ibm.fhir.persistence.jdbc.util.ResourceTypesCache;
import com.ibm.fhir.persistence.jdbc.util.ResourceTypesCacheUpdater;
import com.ibm.fhir.persistence.jdbc.util.SqlQueryData;
Expand Down Expand Up @@ -539,9 +540,9 @@ protected Integer getResourceTypeIdFromCaches(String resourceType) {
}

@Override
public Resource insert(Resource resource, List<ExtractedParameterValue> parameters, ParameterDAO parameterDao)
public Resource insert(Resource resource, ExtractedSearchParameters parameters, ParameterDAO parameterDao)
throws FHIRPersistenceException {
final String METHODNAME = "insert(Resource, List<ExtractedParameterValue>";
final String METHODNAME = "insert(Resource, ExtractedSearchParameters";
log.entering(CLASSNAME, METHODNAME);

final Connection connection = getConnection(); // do not close
Expand Down Expand Up @@ -588,6 +589,8 @@ public Resource insert(Resource resource, List<ExtractedParameterValue> paramete
stmt.registerOutParameter(7, Types.BIGINT);
stmt.registerOutParameter(8, Types.BIGINT);

// TODO: Issue #2155: Update the "parameters hash" in the LOGICAL_RESOURCES table

stmt.execute();
long latestTime = System.nanoTime();
double dbCallDuration = (latestTime-dbCallStartTime)/1e6;
Expand All @@ -614,11 +617,11 @@ public Resource insert(Resource resource, List<ExtractedParameterValue> paramete
// Parameter time
// TODO FHIR_ADMIN schema name needs to come from the configuration/context
long paramInsertStartTime = latestTime;
if (parameters != null) {
if (!parameters.getParameters().isEmpty()) {
JDBCIdentityCache identityCache = new JDBCIdentityCacheImpl(cache, this, parameterDao, getResourceReferenceDAO());
try (ParameterVisitorBatchDAO pvd = new ParameterVisitorBatchDAO(connection, "FHIR_ADMIN", resource.getResourceType(), true,
resource.getId(), 100, identityCache, resourceReferenceDAO, this.transactionData)) {
for (ExtractedParameterValue p: parameters) {
for (ExtractedParameterValue p: parameters.getParameters()) {
p.accept(pvd);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
import java.sql.SQLException;
import java.sql.SQLIntegrityConstraintViolationException;
import java.sql.Timestamp;
import java.util.List;
import java.util.UUID;
import java.util.logging.Level;
import java.util.logging.Logger;
Expand All @@ -40,6 +39,7 @@
import com.ibm.fhir.persistence.jdbc.exception.FHIRPersistenceDataAccessException;
import com.ibm.fhir.persistence.jdbc.exception.FHIRPersistenceFKVException;
import com.ibm.fhir.persistence.jdbc.impl.ParameterTransactionDataImpl;
import com.ibm.fhir.persistence.jdbc.util.ExtractedSearchParameters;
import com.ibm.fhir.persistence.jdbc.util.ResourceTypesCache;

/**
Expand Down Expand Up @@ -89,7 +89,7 @@ public DerbyResourceDAO(Connection connection, String schemaName, FHIRDbFlavor f
* @throws FHIRPersistenceVersionIdMismatchException
*/
@Override
public Resource insert(Resource resource, List<ExtractedParameterValue> parameters, ParameterDAO parameterDao)
public Resource insert(Resource resource, ExtractedSearchParameters parameters, ParameterDAO parameterDao)
throws FHIRPersistenceException {
final String METHODNAME = "insert";
logger.entering(CLASSNAME, METHODNAME);
Expand Down Expand Up @@ -198,7 +198,7 @@ public Resource insert(Resource resource, List<ExtractedParameterValue> paramet
* @return the resource_id for the entry we created
* @throws Exception
*/
public long storeResource(String tablePrefix, List<ExtractedParameterValue> parameters, String p_logical_id, InputStream p_payload, Timestamp p_last_updated, boolean p_is_deleted,
public long storeResource(String tablePrefix, ExtractedSearchParameters parameters, String p_logical_id, InputStream p_payload, Timestamp p_last_updated, boolean p_is_deleted,
String p_source_key, Integer p_version, Connection conn, ParameterDAO parameterDao) throws Exception {

final String METHODNAME = "storeResource() for " + tablePrefix + " resource";
Expand Down Expand Up @@ -364,6 +364,8 @@ public long storeResource(String tablePrefix, List<ExtractedParameterValue> para
logger.finest("Created " + tablePrefix + "_logical_resources row: " + v_resource_type + "/" + p_logical_id);
}
}

// TODO: Issue #2155: Update the "parameters hash" in the LOGICAL_RESOURCES table
}
}

Expand Down Expand Up @@ -471,20 +473,22 @@ public long storeResource(String tablePrefix, List<ExtractedParameterValue> para
logger.finest("Updated logical_resources: " + v_resource_type + "/" + p_logical_id);
}
}

// TODO: Issue #2155: Update the "parameters hash" in the LOGICAL_RESOURCES table
}

// To keep things simple for the Derby use-case, we just use a visitor to
// handle inserts of parameters directly in the resource parameter tables.
// Note we don't get any parameters for the resource soft-delete operation
if (parameters != null) {
if (!parameters.getParameters().isEmpty()) {
// Derby doesn't support partitioned multi-tenancy, so we disable it on the DAO:
if (logger.isLoggable(Level.FINEST)) {
logger.finest("Storing parameters for: " + v_resource_type + "/" + p_logical_id);
}
JDBCIdentityCache identityCache = new JDBCIdentityCacheImpl(getCache(), this, parameterDao, getResourceReferenceDAO());
try (ParameterVisitorBatchDAO pvd = new ParameterVisitorBatchDAO(conn, null, tablePrefix, false, v_logical_resource_id, 100,
identityCache, getResourceReferenceDAO(), getTransactionData())) {
for (ExtractedParameterValue p: parameters) {
for (ExtractedParameterValue p: parameters.getParameters()) {
p.accept(pvd);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import java.util.List;

import com.ibm.fhir.persistence.exception.FHIRPersistenceException;
import com.ibm.fhir.persistence.jdbc.util.ParameterHashUtil;

/**
* This class defines the Data Transfer Object representing a row in the X_DATE_VALUES tables.
Expand All @@ -30,10 +31,16 @@ public CompositeParmVal() {
/**
* We know our type, so we can call the correct method on the visitor
*/
@Override
public void accept(ExtractedParameterValueVisitor visitor) throws FHIRPersistenceException {
visitor.visit(this);
}

@Override
public String getHash(ParameterHashUtil parameterHashUtil) {
return parameterHashUtil.getNameValueHash(getHashHeader(), parameterHashUtil.getParametersHash(component));
}

/**
* @return get the list of components in this composite parameter
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import java.sql.Timestamp;

import com.ibm.fhir.persistence.exception.FHIRPersistenceException;
import com.ibm.fhir.persistence.jdbc.util.ParameterHashUtil;

/**
* This class defines the Data Transfer Object representing a row in the X_DATE_VALUES tables.
Expand All @@ -18,9 +19,6 @@ public class DateParmVal extends ExtractedParameterValue {
private Timestamp valueDateStart;
private Timestamp valueDateEnd;

// The SearchParameter base type. If "Resource", then this is a Resource-level attribute
private String base;

public enum TimeType {
YEAR,
YEAR_MONTH,
Expand Down Expand Up @@ -53,13 +51,22 @@ public void setValueDateEnd(Timestamp valueDateEnd) {
/**
* We know our type, so we can call the correct method on the visitor
*/
@Override
public void accept(ExtractedParameterValueVisitor visitor) throws FHIRPersistenceException {
visitor.visit(this);
}

@Override
public String getHash(ParameterHashUtil parameterHashUtil) {
StringBuilder sb = new StringBuilder();
sb.append(valueDateStart);
sb.append("|").append(valueDateEnd);
return parameterHashUtil.getNameValueHash(getHashHeader(), sb.toString());
}

@Override
public String toString() {
return "DateParmVal [resourceType=" + getResourceType() + ", name=" + getName()
+ ", valueDateStart=" + valueDateStart + ", valueDateEnd=" + valueDateEnd + ", base=" + base + "]";
+ ", valueDateStart=" + valueDateStart + ", valueDateEnd=" + valueDateEnd + "]";
}
}
Loading

0 comments on commit c970ada

Please sign in to comment.