Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -138,14 +138,6 @@ public void setRequestUniqueId(String requestUniqueId) {
this.requestUniqueId = requestUniqueId;
}

public String getResourceName() {
return resourceName;
}

public void setResourceName(String resourceName) {
this.resourceName = resourceName;
}

/**
* Generates JSON from this object.
*/
Expand Down Expand Up @@ -191,10 +183,6 @@ public static String generate(Context obj)
generator.write("purpose", obj.getPurpose());
}

if (obj.getResourceName() != null) {
generator.write("resource_name", obj.getResourceName());
}

if (obj.getStartTime() != null) {
generator.write("start_time", obj.getStartTime());
}
Expand Down Expand Up @@ -275,12 +263,6 @@ public static Context parse(InputStream in)
builder.purpose(purpose);
}

t = jsonObject.get("resource_name");
if (t != null) {
String resourceName = jsonObject.getString("resource_name");
builder.resourceName(resourceName);
}

t = jsonObject.get("start_time");
if (t != null) {
String startTime = jsonObject.getString("start_time");
Expand Down Expand Up @@ -387,11 +369,6 @@ public Builder requestUniqueId(String requestUniqueId) {
return this;
}

public Builder resourceName(String resourceName) {
context.setResourceName(resourceName);
return this;
}

public Context build() {
return context;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,10 +124,6 @@ public static String generate(FHIRContext obj)
generator.write("purpose", obj.getPurpose());
}

if (obj.getResourceName() != null) {
generator.write("resource_name", obj.getResourceName());
}

if (obj.getStartTime() != null) {
generator.write("start_time", obj.getStartTime());
}
Expand Down Expand Up @@ -228,12 +224,6 @@ public static FHIRContext parse(InputStream in)
builder.purpose(purpose);
}

t = jsonObject.get("resource_name");
if (t != null) {
String resourceName = jsonObject.getString("resource_name");
builder.resourceName(resourceName);
}

t = jsonObject.get("start_time");
if (t != null) {
String startTime = jsonObject.getString("start_time");
Expand Down Expand Up @@ -395,11 +385,6 @@ public FHIRBuilder requestUniqueId(String requestUniqueId) {
return this;
}

public FHIRBuilder resourceName(String resourceName) {
fhirContext.setResourceName(resourceName);
return this;
}

public FHIRContext build() {
return fhirContext;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,6 @@ public void testContextEmptyNull() throws FHIRException, IOException {
assertNull(ctx.getPurpose());
assertNull(ctx.getQueryParameters());
assertNull(ctx.getRequestUniqueId());
assertNull(ctx.getResourceName());
assertNull(ctx.getStartTime());
}

Expand Down Expand Up @@ -175,7 +174,6 @@ public void testContext() throws FHIRException, IOException {
builder.purpose("purpose");
builder.queryParameters("queryParameters");
builder.requestUniqueId("requestUniqueId");
builder.resourceName("test");
builder.startTime("startTime");

Context ctx = builder.build();
Expand Down Expand Up @@ -204,9 +202,6 @@ public void testContext() throws FHIRException, IOException {
assertNotNull(ctx.getRequestUniqueId());
assertEquals(ctx.getRequestUniqueId(), "requestUniqueId");

assertNotNull(ctx.getResourceName());
assertEquals(ctx.getResourceName(), "test");

assertNotNull(ctx.getStartTime());
assertEquals(ctx.getStartTime(), "startTime");

Expand Down Expand Up @@ -236,9 +231,6 @@ public void testContext() throws FHIRException, IOException {
assertNotNull(ctx.getRequestUniqueId());
assertEquals(ctx.getRequestUniqueId(), "requestUniqueId");

assertNotNull(ctx.getResourceName());
assertEquals(ctx.getResourceName(), "test");

assertNotNull(ctx.getStartTime());
assertEquals(ctx.getStartTime(), "startTime");
}
Expand Down Expand Up @@ -349,7 +341,6 @@ public void testFHIRContext() throws IOException, FHIRException {
builder.purpose("purpose");
builder.queryParameters("queryParameters");
builder.requestUniqueId("requestUniqueId");
builder.resourceName("test");
builder.startTime("startTime");

builder.clientCertCn("clientCertCn");
Expand Down Expand Up @@ -386,9 +377,6 @@ public void testFHIRContext() throws IOException, FHIRException {
assertNotNull(fhirCtx.getRequestUniqueId());
assertEquals(fhirCtx.getRequestUniqueId(), "requestUniqueId");

assertNotNull(fhirCtx.getResourceName());
assertEquals(fhirCtx.getResourceName(), "test");

assertNotNull(fhirCtx.getStartTime());
assertEquals(fhirCtx.getStartTime(), "startTime");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,6 @@ public class FHIRConfiguration {
public static final String PROPERTY_AUDIT_SERVICE_CLASS_NAME = "fhirServer/audit/serviceClassName";
public static final String PROPERTY_AUDIT_SERVICE_PROPERTIES = "fhirServer/audit/serviceProperties";
public static final String PROPERTY_AUDIT_PATIENT_ID_EXTURL = "fhirServer/audit/patientIdExtensionUrl";
public static final String PROPERTY_AUDIT_RESOURCE_NAME_EXTURL = "fhirServer/audit/resourceNameExtensionUrl";
public static final String PROPERTY_UPDATE_CREATE_ENABLED = "fhirServer/persistence/common/updateCreateEnabled";

// Notification config properties
public static final String PROPERTY_NOTIFICATION_RESOURCE_TYPES = "fhirServer/notifications/common/includeResourceTypes";
Expand All @@ -59,6 +57,7 @@ public class FHIRConfiguration {
public static final String PROPERTY_KAFKA_CONNECTIONPROPS = "fhirServer/notifications/kafka/connectionProperties";

// Persistence layer properties
public static final String PROPERTY_UPDATE_CREATE_ENABLED = "fhirServer/persistence/common/updateCreateEnabled";
public static final String PROPERTY_PERSISTENCE_FACTORY = "fhirServer/persistence/factoryClassname";
public static final String PROPERTY_DATASOURCES = "fhirServer/persistence/datasources";
public static final String PROPERTY_JDBC_BOOTSTRAP_DB = "fhirServer/persistence/jdbc/bootstrapDb";
Expand Down
25 changes: 16 additions & 9 deletions fhir-persistence-schema/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,28 +58,33 @@ The following sections include common values for `OPTIONS`:
--update-schema
```

## Add a new tenant (e.g. tenant1)

Don't forget to copy the tenant-key secret generated by --allocate-tenant. This key must be added to the datasource configuration to authorize the FHIR server to access this tenant.
## Grant privileges to data access user

```
--prop-file fhir.properties
--schema-name FHIRDATA
--allocate-tenant tenant1
--grant-to FHIRSERVER
```

## Add a new tenant (e.g. default)

## Grant privileges to data access user
Don't forget to copy the tenant-key secret generated by --allocate-tenant. This key must be added to the datasource configuration to authorize the FHIR server to access this tenant.

```
--prop-file fhir.properties
--schema-name FHIRDATA
--grant-to FHIRSERVER
--allocate-tenant default
```

Note: for tenant names other than `default`, the server must determine the tenant id to use for each request.
By default, we get the tenant id from the `X-FHIR-TENANT-ID` header, but to trust this value requires a well-planned approach to security.
Once the server has determined the tenant id for a given request, it uses this to look up the tenantKey and the two are
used in conjunction to create or retrieve data for this tenant.
For more information on multi-tenancy, see section [4.9 Multi-tenancy of the IBM FHIR Server Users Guide](https://ibm.github.io/FHIR/guides/FHIRServerUsersGuide#49-multi-tenancy).

## Configure tenant-key (example)

Edit `wlp/usr/servers/fhir-server/config/tenant1/fhir-server-config.json` and add the tenant-key captured from the add-tenant step above:
Edit `wlp/usr/servers/fhir-server/config/default/fhir-server-config.json` and add the tenant-key captured from the add-tenant step above:

```
"default": {
Expand All @@ -101,12 +106,13 @@ Edit `wlp/usr/servers/fhir-server/config/tenant1/fhir-server-config.json` and ad
}
```


## Test a tenant

```
--prop-file fhir-apikey.properties
--schema-name FHIRDATA
--test-tenant TNT1
--test-tenant default
--tenant-key "<the-base64-tenant-key>"
```

Expand All @@ -118,9 +124,10 @@ Edit `wlp/usr/servers/fhir-server/config/tenant1/fhir-server-config.json` and ad
--update-proc
```

# Alternative: manually apply the schema changes
# Alternative: manually apply the schema

To manually apply the DDL to a Db2 instance:

1. Print the schema to files by executing the SchemaPrinter:
`java -cp ./fhir-database-utils.jar:fhir-persistence-schema.jar com.ibm.fhir.schema.app.SchemaPrinter --to-file`

Expand Down
42 changes: 9 additions & 33 deletions fhir-server/liberty-config/config/default/fhir-server-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,15 @@
"__comment": "Configuration properties common to all persistence layer implementations",
"updateCreateEnabled": true
},
"jdbc": {
"__comment": "Configuration properties for the JDBC persistence implementation",
"bootstrapDb": true,
"__comment": "Use jdbc/fhirProxyDataSource to use the proxy datasource.",
"dataSourceJndiName": "jdbc/fhirProxyDataSource",
"enableCodeSystemsCache": true,
"enableParameterNamesCache": true,
"enableResourceTypesCache": true
},
"datasources": {
"default": {
"type": "derby",
Expand All @@ -88,40 +97,7 @@
"sslTrustStoreLocation": "resources/security/fhirTruststore.jks",
"sslTrustStorePassword": "change-password"
}
},
"audit": {
"type": "derby",
"connectionProperties": {
"databaseName": "derby/auditDB",
"createDatabase": "create"
}
},
"_db2_audit": {
"type": "db2",
"connectionProperties": {
"serverName": "localhost",
"portNumber": 50001,
"user": "db2inst1",
"password": "change-password",
"databaseName": "AUDITDB",
"currentSchema": "AUDIT1",
"driverType": 4,
"sslConnection": true,
"sslTrustStoreLocation": "resources/security/fhirTruststore.jks",
"sslTrustStorePassword": "change-password"
}
}
},
"jdbc": {
"__comment": "Configuration properties for the JDBC persistence implementation, Use jdbc/fhirProxyDataSource to use the proxy datasource.",
"bootstrapDb": true,
"dataSourceJndiName": "jdbc/fhirProxyDataSource",
"enableCodeSystemsCache": true,
"enableParameterNamesCache": true,
"enableResourceTypesCache": true
},
"audit": {
"bootstrapDb": true
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,6 @@

/**
* This class provides convenience methods for FHIR Rest services that need to write FHIR audit log entries.
* @author markd
*
*/
public class RestAuditLogger {

Expand Down Expand Up @@ -462,7 +460,6 @@ private static AuditLogEntry populateAuditLogEntry(AuditLogEntry entry, HttpServ

StringBuffer requestUrl;
String patientIdExtUrl;
String resourceNameExtUrl;
List<String> userList = new ArrayList<>();

// Build a list of possible user names. Pick the first non-null user name to include in the audit log entry.
Expand Down Expand Up @@ -512,8 +509,6 @@ private static AuditLogEntry populateAuditLogEntry(AuditLogEntry entry, HttpServ

patientIdExtUrl = FHIRConfigHelper.getStringProperty(FHIRConfiguration.PROPERTY_AUDIT_PATIENT_ID_EXTURL, null);
entry.setPatientId(FHIRUtil.getExtensionStringValue(resource, patientIdExtUrl));
resourceNameExtUrl = FHIRConfigHelper.getStringProperty(FHIRConfiguration.PROPERTY_AUDIT_RESOURCE_NAME_EXTURL, null);
entry.getContext().setResourceName((FHIRUtil.getExtensionStringValue(resource, resourceNameExtUrl)));
entry.getContext().setRequestUniqueId(FHIRRequestContext.get().getRequestUniqueId());

log.exiting(CLASSNAME, METHODNAME);
Expand Down