Skip to content

Commit b6043f3

Browse files
authored
Merge pull request #3683 from IBM/robin-citus-1
Citus distribution support and async/remote indexing
2 parents 2df79da + 59e3c24 commit b6043f3

321 files changed

Lines changed: 20448 additions & 2180 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

build/docker/deploySchemaAndTenant.sh

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ while [ "$not_ready" == "true" ]
2121
do
2222
EXIT_CODE="-1"
2323
java -jar schema/fhir-persistence-schema-*-cli.jar \
24-
--prop-file db2.properties --schema-name FHIRDATA --create-schemas | tee -a ${TMP_FILE}
24+
--db-type db2 --prop-file db2.properties --schema-name FHIRDATA --create-schemas | tee -a ${TMP_FILE}
2525
EXIT_CODE="${PIPESTATUS[0]}"
2626
LOG_OUT=`cat ${TMP_FILE}`
2727
if [[ "$EXIT_CODE" == "0" ]]
@@ -54,18 +54,18 @@ then
5454
fi
5555

5656
java -jar schema/fhir-persistence-schema-*-cli.jar \
57-
--prop-file db2.properties --schema-name FHIRDATA --update-schema --pool-size 2
57+
--db-type db2 --prop-file db2.properties --schema-name FHIRDATA --update-schema --pool-size 2
5858

5959
java -jar schema/fhir-persistence-schema-*-cli.jar \
60-
--prop-file db2.properties --schema-name FHIRDATA --grant-to FHIRSERVER --pool-size 2
60+
--db-type db2 --prop-file db2.properties --schema-name FHIRDATA --grant-to FHIRSERVER --pool-size 2
6161

6262
java -jar schema/fhir-persistence-schema-*-cli.jar \
63-
--prop-file db2.properties --schema-name FHIRDATA --allocate-tenant default --pool-size 2
63+
--db-type db2 --prop-file db2.properties --schema-name FHIRDATA --allocate-tenant default --pool-size 2
6464

6565
# The regex in the following command will output the capture group between "key=" and "]"
6666
# With GNU grep, the following would work as well: grep -oP 'key=\K\S+(?=])'
6767
tenantKey=$(java -jar schema/fhir-persistence-schema-*-cli.jar \
68-
--prop-file db2.properties --schema-name FHIRDATA --add-tenant-key default 2>&1 \
68+
--db-type db2 --prop-file db2.properties --schema-name FHIRDATA --add-tenant-key default 2>&1 \
6969
| grep "key=" | sed -e 's/.*key\=\(.*\)\].*/\1/')
7070

7171
# Creating a backup file is the easiest way to make in-place sed portable across OSX and Linux

build/docker/updateSchema.sh

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,17 @@ cd ${DIR}
1313
# For #1366 the migration hits deadlock issues if run in parallel, so
1414
# to avoid this, serialize the steps using --pool-size 1
1515
java -jar schema/fhir-persistence-schema-*-cli.jar \
16-
--prop-file db2.properties --schema-name FHIRDATA --update-schema \
16+
--db-type db2 --prop-file db2.properties --schema-name FHIRDATA --update-schema \
1717
--pool-size 1
1818

1919
# Rerun grants to cover any new tables added by the above migration step
2020
java -jar schema/fhir-persistence-schema-*-cli.jar \
21-
--prop-file db2.properties --schema-name FHIRDATA --grant-to FHIRSERVER --pool-size 2
21+
--db-type db2 --prop-file db2.properties --schema-name FHIRDATA --grant-to FHIRSERVER --pool-size 2
2222

2323
# And make sure that the new tables have partitions for existing tenants
2424
java -jar schema/fhir-persistence-schema-*-cli.jar \
25-
--prop-file db2.properties --refresh-tenants
25+
--db-type db2 --prop-file db2.properties --refresh-tenants
2626

2727
java -jar schema/fhir-persistence-schema-*-cli.jar \
28-
--prop-file db2.properties --schema-name FHIRDATA --grant-to FHIRSERVER \
28+
--db-type db2 --prop-file db2.properties --schema-name FHIRDATA --grant-to FHIRSERVER \
2929
--pool-size 20

build/migration/bin/6_current-reindex.sh

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ run_reindex(){
2323
DATE_ISO=$(date +%Y-%m-%dT%H:%M:%SZ)
2424
status=$(curl -k -X POST -o reindex.json -i -w '%{http_code}' -u 'fhiruser:change-password' 'https://localhost:9443/fhir-server/api/v4/$reindex' \
2525
-H 'Content-Type: application/fhir+json' -H 'X-FHIR-TENANT-ID: default' \
26-
-d "{\"resourceType\": \"Parameters\",\"parameter\":[{\"name\":\"resourceCount\",\"valueInteger\":100},{\"name\":\"tstamp\",\"valueString\":\"${DATE_ISO}\"}]}")
26+
-d "{\"resourceType\": \"Parameters\",\"parameter\":[{\"name\":\"resourceCount\",\"valueInteger\":100},{\"name\":\"tstamp\",\"valueString\":\"${DATE_ISO}\"},{\"name\":\"force\",\"valueBoolean\":true}]}")
2727
echo "Status: ${status}"
2828

2929
while [ $status -ne 200 ]
@@ -57,7 +57,7 @@ run_reindex(){
5757
fi
5858
status=$(curl -k -X POST -o reindex.json -i -w '%{http_code}' -u 'fhiruser:change-password' 'https://localhost:9443/fhir-server/api/v4/$reindex' \
5959
-H 'Content-Type: application/fhir+json' -H 'X-FHIR-TENANT-ID: default' \
60-
-d "{\"resourceType\": \"Parameters\",\"parameter\":[{\"name\":\"resourceCount\",\"valueInteger\":100},{\"name\":\"tstamp\",\"valueString\":\"${DATE_ISO}\"}]}")
60+
-d "{\"resourceType\": \"Parameters\",\"parameter\":[{\"name\":\"resourceCount\",\"valueInteger\":100},{\"name\":\"tstamp\",\"valueString\":\"${DATE_ISO}\"},{\"name\":\"force\",\"valueBoolean\":true}]}")
6161
echo "Status: ${status}"
6262
done
6363
fi
@@ -77,4 +77,4 @@ run_reindex "${1}"
7777
popd > /dev/null
7878

7979
# EOF
80-
###############################################################################
80+
###############################################################################

docs/src/pages/guides/FHIRSearchConfiguration.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,7 @@ By default, the operation will select 10 resources and re-extract their search p
217217
|----|----|-----------|
218218
|`tstamp`|string|Reindex only resources not previously reindexed since this timestamp. Format as a date YYYY-MM-DD or time YYYY-MM-DDTHH:MM:SSZ.|
219219
|`resourceCount`|integer|The maximum number of resources to reindex in this call. If this number is too large, the processing time might exceed the transaction timeout and fail.|
220+
|`force`|boolean|Force the parameters to be replaced even if the parameter hash matches. This is only required following a schema migration which changes how the parameters are stored in the database.|
220221

221222
The IBM FHIR Server tracks when a resource was last reindexed and only resources with a reindex_tstamp value less than the given tstamp parameter will be processed. When a resource is reindexed, its reindex_tstamp is set to the given tstamp value. In most cases, using the current date (for example "2020-10-27") is the best option for this value.
222223

docs/src/pages/guides/FHIRServerUsersGuide.md

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ permalink: /FHIRServerUsersGuide/
2727
* [4.10 Bulk data operations](#410-bulk-data-operations)
2828
* [4.11 Audit logging service](#411-audit-logging-service)
2929
* [4.12 FHIR REST API](#412-fhir-rest-api)
30+
* [4.13 Remote Index Service](#413-remote-index-service)
3031
- [5 Appendix](#5-appendix)
3132
* [5.1 Configuration properties reference](#51-configuration-properties-reference)
3233
* [5.2 Keystores, truststores, and the FHIR server](#52-keystores-truststores-and-the-fhir-server)
@@ -2070,6 +2071,10 @@ For example, consider a FHIR Server that is listening at https://fhir:9443/fhir-
20702071

20712072
The originalRequestUriHeader is expected to contain the full path of the original request. Values with no scheme (e.g. `https://`) will be handled like relative URLs, but full URL values (including scheme, hostname, optional port, and path) are recommended. Query string values can be included in the header value but will be ignored by the server; the server will use the query string of the actual request to process the request.
20722073

2074+
### 4.13 Remote Index Service
2075+
2076+
To use the experimental remote index service feature, see the instructions documented in the [fhir-remote-index](https://github.com/IBM/FHIR/tree/main/operation/fhir-remote-index/README.md) project.
2077+
20732078
# 5 Appendix
20742079

20752080
## 5.1 Configuration properties reference
@@ -2260,7 +2265,17 @@ This section contains reference information about each of the configuration prop
22602265
|`fhirServer/operations/membermatch/strategy`|string|The key identifying the Member Match strategy|
22612266
|`fhirServer/operations/membermatch/extendedProps`|object|The extended options for the extended member match implementation|
22622267
|`fhirServer/operations/everything/includeTypes`|list|The list of related resource types to include alongside the patient compartment resource types. Instances of these resource types will only be returned when they are referenced from one or more resource instances from the target patient compartment. Example values are like `Location`, `Medication`, `Organization`, and `Practitioner`|
2263-
2268+
|`fhirServer/remoteIndexService/type`|string| The type of service used to send remote index messages. Only `kafka` is currently supported|
2269+
|`fhirServer/remoteIndexService/instanceIdentifier`|string| A UUID or other identifier unique to this cluster of IBM FHIR Servers |
2270+
|`fhirServer/remoteIndexService/kafka/mode`|string| Current operation mode of the service. Specify `ACTIVE` to use the service|
2271+
|`fhirServer/remoteIndexService/kafka/topicName`|string| The Kafka topic name. Typically `FHIR_REMOTE_INDEX` |
2272+
|`fhirServer/remoteIndexService/kafka/connectionProperties/bootstrap.servers`|string| Bootstrap servers for the Kafka service |
2273+
|`fhirServer/remoteIndexService/kafka/connectionProperties/sasl.jaas.config`|string| Kafka service authentication |
2274+
|`fhirServer/remoteIndexService/kafka/connectionProperties/sasl.mechanism`|string| Kafka service authentication|
2275+
|`fhirServer/remoteIndexService/kafka/connectionProperties/security.protocol`|string| Kafka service security |
2276+
|`fhirServer/remoteIndexService/kafka/connectionProperties/ssl.protocol`|string| Kafka service SSL configuration |
2277+
|`fhirServer/remoteIndexService/kafka/connectionProperties/ssl.enabled.protocols`|string| Kafka service SSL configuration |
2278+
|`fhirServer/remoteIndexService/kafka/connectionProperties/ssl.endpoint.identification.algorithm`|string| Kafka service SSL configuration |
22642279

22652280
### 5.1.2 Default property values
22662281
| Property Name | Default value |
@@ -2406,6 +2421,17 @@ This section contains reference information about each of the configuration prop
24062421
|`fhirServer/operations/membermatch/strategy`|default|
24072422
|`fhirServer/operations/membermatch/extendedProps`|empty|
24082423
|`fhirServer/operations/everything/includeTypes`|null|
2424+
|`fhirServer/remoteIndexService/type`|null|
2425+
|`fhirServer/remoteIndexService/instanceIdentifier`|null|
2426+
|`fhirServer/remoteIndexService/kafka/mode`|null|
2427+
|`fhirServer/remoteIndexService/kafka/topicName`|null|
2428+
|`fhirServer/remoteIndexService/kafka/connectionProperties/bootstrap.servers`|null|
2429+
|`fhirServer/remoteIndexService/kafka/connectionProperties/sasl.jaas.config`|null|
2430+
|`fhirServer/remoteIndexService/kafka/connectionProperties/sasl.mechanism`|null|
2431+
|`fhirServer/remoteIndexService/kafka/connectionProperties/security.protocol`|null|
2432+
|`fhirServer/remoteIndexService/kafka/connectionProperties/ssl.protocol`|null|
2433+
|`fhirServer/remoteIndexService/kafka/connectionProperties/ssl.enabled.protocols`|null|
2434+
|`fhirServer/remoteIndexService/kafka/connectionProperties/ssl.endpoint.identification.algorithm`|null|
24092435

24102436
### 5.1.3 Property attributes
24112437
Depending on the context of their use, config properties can be:
@@ -2588,6 +2614,17 @@ Cases where that behavior is not supported are marked below with an `N` in the `
25882614
|`fhirServer/operations/membermatch/strategy`|Y|Y|Y|
25892615
|`fhirServer/operations/membermatch/extendedProps`|Y|Y|Y|
25902616
|`fhirServer/operations/everything/includeTypes`|Y|Y|N|
2617+
|`fhirServer/remoteIndexService/type`|N|N|N|
2618+
|`fhirServer/remoteIndexService/instanceIdentifier`|N|N|N|
2619+
|`fhirServer/remoteIndexService/kafka/mode`|N|N|N|
2620+
|`fhirServer/remoteIndexService/kafka/topicName`|N|N|N|
2621+
|`fhirServer/remoteIndexService/kafka/connectionProperties/bootstrap.servers`|N|N|N|
2622+
|`fhirServer/remoteIndexService/kafka/connectionProperties/sasl.jaas.config`|N|N|N|
2623+
|`fhirServer/remoteIndexService/kafka/connectionProperties/sasl.mechanism`|N|N|N|
2624+
|`fhirServer/remoteIndexService/kafka/connectionProperties/security.protocol`|N|N|N|
2625+
|`fhirServer/remoteIndexService/kafka/connectionProperties/ssl.protocol`|N|N|N|
2626+
|`fhirServer/remoteIndexService/kafka/connectionProperties/ssl.enabled.protocols`|N|N|N|
2627+
|`fhirServer/remoteIndexService/kafka/connectionProperties/ssl.endpoint.identification.algorithm`|N|N|N|
25912628

25922629
## 5.2 Keystores, truststores, and the IBM FHIR server
25932630

fhir-bucket/src/main/java/com/ibm/fhir/bucket/app/Main.java

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,13 @@
5757
import com.ibm.fhir.database.utils.api.IDatabaseAdapter;
5858
import com.ibm.fhir.database.utils.api.IDatabaseTranslator;
5959
import com.ibm.fhir.database.utils.api.ILeaseManagerConfig;
60+
import com.ibm.fhir.database.utils.api.ISchemaAdapter;
6061
import com.ibm.fhir.database.utils.api.ITransaction;
6162
import com.ibm.fhir.database.utils.api.ITransactionProvider;
63+
import com.ibm.fhir.database.utils.api.SchemaApplyContext;
6264
import com.ibm.fhir.database.utils.api.UniqueConstraintViolationException;
6365
import com.ibm.fhir.database.utils.common.JdbcConnectionProvider;
66+
import com.ibm.fhir.database.utils.common.PlainSchemaAdapter;
6467
import com.ibm.fhir.database.utils.db2.Db2Adapter;
6568
import com.ibm.fhir.database.utils.db2.Db2PropertyAdapter;
6669
import com.ibm.fhir.database.utils.db2.Db2Translator;
@@ -147,6 +150,9 @@ public class Main {
147150
// The adapter configured for the type of database we're using
148151
private IDatabaseAdapter adapter;
149152

153+
// The (plain) schema adapter which wraps the database adapter
154+
private ISchemaAdapter schemaAdapter;
155+
150156
// The number of threads to use for the schema creation step
151157
private int createSchemaThreads = 1;
152158

@@ -639,6 +645,7 @@ public void configure() {
639645
setupDerbyRepository();
640646
break;
641647
case POSTGRESQL:
648+
case CITUS:
642649
setupPostgresRepository();
643650
break;
644651
}
@@ -669,6 +676,7 @@ public void setupDerbyRepository() {
669676
this.connectionPool = new PoolConnectionProvider(cp, connectionPoolSize);
670677
this.connectionPool.setCloseOnAnyError();
671678
this.adapter = new DerbyAdapter(connectionPool);
679+
this.schemaAdapter = new PlainSchemaAdapter(adapter);
672680
this.transactionProvider = new SimpleTransactionProvider(connectionPool);
673681
}
674682

@@ -692,6 +700,7 @@ public void setupDb2Repository() {
692700
IConnectionProvider cp = new JdbcConnectionProvider(translator, propertyAdapter);
693701
this.connectionPool = new PoolConnectionProvider(cp, connectionPoolSize);
694702
this.adapter = new Db2Adapter(connectionPool);
703+
this.schemaAdapter = new PlainSchemaAdapter(adapter);
695704
this.transactionProvider = new SimpleTransactionProvider(connectionPool);
696705
}
697706

@@ -715,6 +724,7 @@ public void setupPostgresRepository() {
715724
IConnectionProvider cp = new JdbcConnectionProvider(translator, propertyAdapter);
716725
this.connectionPool = new PoolConnectionProvider(cp, connectionPoolSize);
717726
this.adapter = new PostgresAdapter(connectionPool);
727+
this.schemaAdapter = new PlainSchemaAdapter(adapter);
718728
this.transactionProvider = new SimpleTransactionProvider(connectionPool);
719729
}
720730

@@ -732,7 +742,7 @@ protected VersionHistoryService createVersionHistoryService() {
732742
// Create the version history table if it doesn't yet exist
733743
try (ITransaction tx = transactionProvider.getTransaction()) {
734744
try {
735-
CreateVersionHistory.createTableIfNeeded(schemaName, this.adapter);
745+
CreateVersionHistory.createTableIfNeeded(schemaName, this.schemaAdapter);
736746
} catch (Exception x) {
737747
logger.log(Level.SEVERE, "failed to create version history table", x);
738748
tx.setRollbackOnly();
@@ -761,8 +771,8 @@ public void bootstrapDb() {
761771
try (ITransaction tx = transactionProvider.getTransaction()) {
762772
try {
763773
adapter.createSchema(schemaName);
764-
CreateControl.createTableIfNeeded(schemaName, adapter);
765-
CreateWholeSchemaVersion.createTableIfNeeded(schemaName, adapter);
774+
CreateControl.createTableIfNeeded(schemaName, schemaAdapter);
775+
CreateWholeSchemaVersion.createTableIfNeeded(schemaName, schemaAdapter);
766776
success = true;
767777
} catch (Exception x) {
768778
logger.log(Level.SEVERE, "failed to create schema management tables", x);
@@ -822,7 +832,8 @@ private void buildSchema() {
822832
TaskService taskService = new TaskService();
823833
ExecutorService pool = Executors.newFixedThreadPool(this.createSchemaThreads);
824834
ITaskCollector collector = taskService.makeTaskCollector(pool);
825-
pdm.collect(collector, adapter, this.transactionProvider, vhs);
835+
SchemaApplyContext context = SchemaApplyContext.getDefault();
836+
pdm.collect(collector, schemaAdapter, context, this.transactionProvider, vhs);
826837

827838
// FHIR in the hole!
828839
logger.info("Starting schema updates");
@@ -845,7 +856,7 @@ private void buildSchema() {
845856
try {
846857
Set<String> resourceTypes = ResourceTypeHelper.getR4bResourceTypesFor(FHIRVersionParam.VERSION_43);
847858

848-
if (adapter.getTranslator().getType() == DbType.POSTGRESQL) {
859+
if (adapter.getTranslator().isFamilyPostgreSQL()) {
849860
// Postgres doesn't support batched merges, so we go with a simpler UPSERT
850861
MergeResourceTypesPostgres mrt = new MergeResourceTypesPostgres(schemaName, resourceTypes);
851862
adapter.runStatement(mrt);

fhir-bucket/src/main/java/com/ibm/fhir/bucket/persistence/AddBucketPath.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
import com.ibm.fhir.database.utils.api.IDatabaseSupplier;
1818
import com.ibm.fhir.database.utils.api.IDatabaseTranslator;
1919
import com.ibm.fhir.database.utils.common.DataDefinitionUtil;
20-
import com.ibm.fhir.database.utils.model.DbType;
2120

2221
/**
2322
* DAO to encapsulate all the SQL/DML used to retrieve and persist data
@@ -57,7 +56,7 @@ public Long run(IDatabaseTranslator translator, Connection c) {
5756
// try the old-fashioned way and handle duplicate key
5857
final String bucketPaths = DataDefinitionUtil.getQualifiedName(schemaName, "bucket_paths");
5958
final String dml;
60-
if (translator.getType() == DbType.POSTGRESQL) {
59+
if (translator.isFamilyPostgreSQL()) {
6160
// For POSTGRES, if a statement fails it causes the whole transaction
6261
// to fail, so we need turn this into an UPSERT
6362
dml = "INSERT INTO " + bucketPaths + "(bucket_name, bucket_path) VALUES (?,?) ON CONFLICT(bucket_name, bucket_path) DO NOTHING";

fhir-bucket/src/main/java/com/ibm/fhir/bucket/persistence/AddResourceBundle.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
import com.ibm.fhir.database.utils.api.IDatabaseSupplier;
2121
import com.ibm.fhir.database.utils.api.IDatabaseTranslator;
2222
import com.ibm.fhir.database.utils.common.DataDefinitionUtil;
23-
import com.ibm.fhir.database.utils.model.DbType;
2423

2524
/**
2625
* DAO to encapsulate all the SQL/DML used to retrieve and persist data
@@ -76,7 +75,7 @@ public ResourceBundleData run(IDatabaseTranslator translator, Connection c) {
7675
int version = 1;
7776
final String resourceBundles = DataDefinitionUtil.getQualifiedName(schemaName, "resource_bundles");
7877
final String dml;
79-
if (translator.getType() == DbType.POSTGRESQL) {
78+
if (translator.isFamilyPostgreSQL()) {
8079
// For PostgresSQL, make sure we don't break the current transaction
8180
// if the statement fails...annoying
8281
dml = "INSERT INTO " + resourceBundles + "("

0 commit comments

Comments
 (0)