Skip to content

Commit

Permalink
Issue #2155 - Start implementation
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 3b99c2d
Show file tree
Hide file tree
Showing 22 changed files with 504 additions and 81 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 @@ -587,6 +588,7 @@ public Resource insert(Resource resource, List<ExtractedParameterValue> paramete
stmt.setInt(6, resource.getVersionId());
stmt.registerOutParameter(7, Types.BIGINT);
stmt.registerOutParameter(8, Types.BIGINT);
// TODO: Include the "parameters hash" on the call to the stored procedure

stmt.execute();
long latestTime = System.nanoTime();
Expand Down Expand Up @@ -614,11 +616,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 @@ -476,20 +476,22 @@ public long storeResource(String tablePrefix, List<ExtractedParameterValue> para
// 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);
}
}
}

// TODO: Update the "parameters hash" in the LOGICAL_RESOURCES table

// Finally, write a record to RESOURCE_CHANGE_LOG which records each event
// related to resources changes (issue-1955)
String changeType = p_is_deleted ? "D" : v_new_resource ? "C" : "U";
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 3b99c2d

Please sign in to comment.