Welcome to the Digital Developer Conference Hybrid Cloud - Integrating Healthcare Data in a Serverless World!
Welcome to the Digital Developer Conference Hybrid Cloud - Integrating Healthcare Data in a Serverless World!
In this lab, developers integrate a healthcare data application using IBM FHIR Server with Red Hat OpenShift Serverless to create and respond to a healthcare scenario.
This lab is a companion to the session Integrating Healthcare Data in a Serverless World at Digital Developer Conference - Hybrid Cloud.
The content for this lab can be found at https://ibm.biz/ibm-fhir-server-healthcare-serverless.
Have fun!
At the conclusion of the Conference, please email pbastide@us.ibm.com with questions.
For each lab participant, the lab has two distinct sections - Project and Test.
Each attendee should complete the Prerequisites section.
The lab proctors have previously completed the Appendix: Setup. If you are running outside of the Lab Environment, prior to completing the Project and Test sections, please complete the Appendix: Setup.
Install Docker docker
Log in, or create an account on IBM Cloud
Install the Red Hat OpenShift cli oc
Link to the Install
Install the Knative cli kn
Link to the Install
Optional: Install Maven mvn and Java. You should use Java 11 for this lab. You can download from the AdoptOpenJDK website
Log in to IBM Cloud
Click on your cluster
Click on OpenShift Web Console
Click on the User dropdown in the Upper Right > Copy Login Command
A new tab opens, Click Display Token and Copy the Contents
On a terminal window, paste the contents on the terminal.
oc login --token=sha256~*** \
--server=https://***.us-east.containers.cloud.ibm.com:32689
You see:
Logged into "https://****.us-east.containers.cloud.ibm.com:32689" as "IAM#***" using the token provided.
You have access to 69 projects, the list has been suppressed. You can list all projects with 'oc projects'
Using project "default".
Clone the repository
git clone https://github.com/prb112/healthcare-serverless.git
You see the repository is cloned and unpacked.
Cloning into 'healthcare-serverless'...
remote: Enumerating objects: 10, done.
remote: Counting objects: 100% (10/10), done.
remote: Compressing objects: 100% (7/7), done.
remote: Total 10 (delta 1), reused 6 (delta 1), pack-reused 0
Unpacking objects: 100% (10/10), done.
Change to the healthcare-serverless repository
cd healthcare-serverless
Open with your preferred Integrated Development Environment (IDE), such as Visual Code.
Change directory to the example-fhir-knative
project
cd example-fhir-knative
Once you have the project in the IDE, you are ready to review and build.
Review the src/main/resources/endpoint.properties
a simple properties file. Notice the property points to the IBM FHIR Server - fhirclient.rest.base.url
. If you are using this pattern in production, you can load all these values from a secret.
Review the API, and you’ll see how the API takes Query Parameters first and last name, and runs the Client.
src/main/java/com/ibm/fhir/example/knative/Loader.java
- The Loader API takes two simple HTTP Query Parameters, a first and last name, and submits a FHIR Bundle for the User identified by firstName and lastName.
@Path("/v1/api/loader")
public class Loader {
@GET
@Produces(MediaType.TEXT_PLAIN)
public List<String> loadPatient(
@QueryParam(value="first") String firstName,
@QueryParam(value="last") String lastName) throws Exception {
try {
Client client = new Client();
return client.submitBundle(firstName, lastName);
} catch (Exception e) {
return Arrays.asList(e.toString() + "/" + e);
}
}
}
src/main/java/com/ibm/fhir/example/knative/Report.java
- The Report API calls the Client API.
@Path("/v1/api/report")
public class Report {
@GET
@Produces(MediaType.TEXT_PLAIN)
public String generateReport() throws Exception {
Client client = new Client();
return client.buildReport();
}
}
Review the /src/main/java/com/ibm/fhir/example/Client.java
and you’ll find the dependency fhir-client
is used to call the backend. The backend configuration is loaded from the endpoint.properties, and facilitates the creation and retrieval of FHIR data.
The submitBundle creates a FHIRClient loads an endpoint configuration, and submits a generated bundle to the backend and generates a list of Resources extracted using the fhir-path
module.
public List<String> submitBundle(String firstName, String lastName) throws Exception {
Properties props = generateProperties();
FHIRClient client = FHIRClientFactory.getClient(props);
BundleGenerator generator = new BundleGenerator();
Bundle bundle = generator.sampleData(firstName, lastName);
Entity<Bundle> entity = Entity.entity(bundle, FHIRMediaType.APPLICATION_FHIR_JSON);
Response response = client.getWebTarget().request().post(entity, Response.class);
Bundle responseBundle = response.readEntity(Bundle.class);
LOG.info("The Response is " + responseBundle);
FHIRPathEvaluator evaluator = FHIRPathEvaluator.evaluator();
Collection<FHIRPathNode> result = evaluator.evaluate(responseBundle, "entry.response.location");
// Convert the Path Nodes to the List of Locations
List<String> listOfLocations = new ArrayList<>();
for (FHIRPathNode node : result) {
String loc = node.asElementNode().element().as(com.ibm.fhir.model.type.Uri.class).getValue();
listOfLocations.add(props.getProperty("fhirclient.rest.base.url") + "/" + loc);
}
return listOfLocations;
}
The buildReport also uses the FHIRClient to call the backend using Search Parameters (HTTP Query parameters) and returns a FHIR Bundle in the application/fhir+json
format. The content is extracted, and the total number of Patients with MedicationAdministration resources today are returned. From this basic pattern you can execute even more complicated healtcare queries.
public String buildReport() throws Exception {
FHIRClient client = FHIRClientFactory.getClient(generateProperties());
ZonedDateTime zdt = ZonedDateTime.now();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
String ymd = formatter.format(zdt);
Response response = client.getWebTarget()
.path("/MedicationAdministration")
.queryParam("_include", "MedicationAdministration:patient")
.queryParam("_include", "MedicationAdministration:medication")
.queryParam("_lastUpdated", ymd)
.request(FHIRMediaType.APPLICATION_FHIR_JSON)
.header("X-FHIR-TENANT-ID", "default")
.header("X-FHIR-DSID", "default")
.header("Content-Type", "application/fhir+json")
.get(Response.class);
Bundle responseBundle = response.readEntity(Bundle.class);
LOG.info("The Report Response is " + responseBundle);
StringBuilder builder = new StringBuilder();
// Output the number of MedicationAdministrations
builder.append("Total Number of Medication Administrations Today are: ")
.append(responseBundle.getTotal().getValue());
builder.append("\n");
// Use FHIRPath to Extract the Entry Resource
FHIRPathEvaluator evaluator = FHIRPathEvaluator.evaluator();
Collection<FHIRPathNode> result = evaluator.evaluate(responseBundle, "Bundle.entry.resource");
// Convert the Path Nodes to Patient Names
int idx = 0;
for (FHIRPathNode node : result) {
Resource r = node.asResourceNode().resource();
if (r instanceof Patient) {
Patient patient = node.asResourceNode().resource().as(Patient.class);
String patientName = patient.getName().stream()
.map(name -> name.getGiven()
.stream()
.map(m -> m.getValue())
.collect(Collectors.joining(" "))
+ ","
+ name.getFamily().getValue())
.collect(Collectors.joining(","));
builder.append("[").append(idx++).append("] ");
builder.append(patientName);
builder.append("\n");
}
}
LOG.info("--> " + builder.toString());
return builder.toString();
}
Review the /src/main/java/com/ibm/fhir/example/BundleGenerator.java
and you’ll see the fhir-model
is used to build a set of resources in the HL7 FHIR Standard.
The sampleData method uses the IBM FHIR Server’s fhir-model
to create a Bundle that reflects a conformant set of Resources for the patient. This particular patient has a Medication prescribed for his observed (Observation) Blood Pressure and subsequently administered the medicine (MedicationAdministration).
With the following method, you see how the HL7 FHIR model is wrapped in a set of builders to create an Observation of the Patient’s Blood Pressure reading. A very cool thing here is the .subject(Reference.builder().reference(string("Patient/" + patientId)).build())
which is a relative reference to the Patient. Relative references allow us to retrieve the Patient’s resources in one call.
public Observation buildObservation(String patientId) {
CodeableConcept code = CodeableConcept.builder()
.coding(
Coding.builder()
.code(Code.of("85354-9"))
.system(Uri.of("http://loinc.org"))
.display(string("Blood pressure panel with all children optional"))
.build())
.text(string("Blood pressure systolic & diastolic"))
.build();
Observation observation = Observation.builder()
.status(ObservationStatus.FINAL)
.category(
CodeableConcept.builder()
.coding(
Coding.builder()
.system(Uri.of("http://terminology.hl7.org/CodeSystem/observation-category"))
.code(Code.of("vital-signs"))
.display(string("Vital Signs"))
.build())
.text(string("Vital Signs"))
.build())
.bodySite(
CodeableConcept.builder()
.coding(Coding.builder().code(Code.of("55284-4"))
.system(Uri.of("http://loinc.org")).build())
.text(string("Blood pressure systolic & diastolic")).build())
.code(code)
.subject(Reference.builder().reference(string("Patient/" + patientId)).build())
.component(Component.builder().code(CodeableConcept.builder().coding(Coding.builder().code(Code.of("8480-6"))
.system(Uri.of("http://loinc.org")).build())
.text(string("Systolic blood pressure")).build())
.value(Quantity.builder().value(Decimal.of(124.9)).unit(string("mmHg")).build()).build())
.component(Component.builder().code(CodeableConcept.builder().coding(Coding.builder().code(Code.of("8462-4"))
.system(Uri.of("http://loinc.org")).build())
.text(string("Diastolic blood pressure")).build())
.value(Quantity.builder().value(Decimal.of(93.7)).unit(string("mmHg")).build()).build())
.text(
Narrative.builder()
.div(Xhtml.of("<div xmlns=\"http://www.w3.org/1999/xhtml\">GENERATED</div>"))
.status(NarrativeStatus.GENERATED).build())
.build();
return observation;
}
Build the project resources
If you have Maven installed:
mvn clean install
You should see BUILD SUCCESS
. Note, if you do not, you
[INFO] -------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] -------------------------------------------------
[INFO] Total time: 9.077 s
[INFO] Finished at: 2021-09-07T16:02:16-04:00
[INFO] -------------------------------------------------
If you do not have Maven installed
unzip -qu example-fhir-knative-target.zip
ls -1 target
You’ll see:
classes
fhir-knative-99-SNAPSHOT.jar
generated-sources
generated-test-sources
maven-archiver
maven-status
quarkus-app
quarkus-artifact.properties
test-classes
Build the Docker image
docker build -qf src/main/docker/Dockerfile \
-t example/fhir-knative-jvm:latest .
You’ll see the image built, and named.
sha256:46991973ed52828793cfbab5f16cdd1608576e1f29d9183c6e5d04af9ee41e83
Change to your project, such as my-fhir-project
. If you need to create a project, you can first run oc new-project my-fhir-project
to create a project.
oc project my-fhir-project
You have changed your name space
Now using project "my-fhir-project" on server "https://host.us-east.containers.cloud.ibm.com:9999".
Check the OpenShift Image registry host
oc get route default-route -n openshift-image-registry \
--template='{{.spec.host }}'
You see the hostname printed.
default-route-openshift-image-registry.healthcare-serverless-9999-0000.us-east.containers.appdomain.cloud
Create an image stream
oc create imagestream fhir-knative-jvm
You see a new image stream is created.
imagestream.image.openshift.io/fhir-knative-jvm created
Tag the Image for the Image Registry
docker tag example/fhir-knative-jvm:latest $(oc get route default-route -n openshift-image-registry --template='{{.spec.host }}')/$(oc project --short=true)/fhir-knative-jvm:latest
Login to the Image Registry, and confirm you see Login Succeeded
.
docker login -u `oc whoami` -p `oc whoami --show-token` $(oc get route default-route -n openshift-image-registry --template='{{.spec.host }}')
Push the Image into the OpenShift Image Registry
docker push $(oc get route default-route -n openshift-image-registry --template='{{.spec.host }}')/$(oc project --short=true)/fhir-knative-jvm:latest
You see the image is on the server
The push refers to repository [default-route-openshift-image-registry.0000.us-east.containers.appdomain.cloud/my-fhir-project/fhir-knative-jvm]
5f70bf18a086: Pushed
d23bc788009e: Pushed
8cf05ebe3167: Pushed
e7ed17121dee: Mounted from fhir-serverless/fhir-knative-jvm
785573c4b945: Mounted from fhir-serverless/fhir-knative-jvm
latest: digest: sha256:27e52ab6a53cfc2d74350b230eb0c8693af0875c63c66f117f386cadb08fbf44 size: 1357
If you see unauthorized: authentication required
, please be sure to docker login
in the prior step.
If you see Error from server (NotFound): routes.route.openshift.io "default-route" not found
, be sure to expose your OpenShift Registry with an External Route.
Make the local registry lookup use relative names
oc set image-lookup --all
You see, and now you can use relative names to find your image.
imagestream.image.openshift.io/fhir-knative-jvm image lookup updated
Create the Knative service
kn service create myfhir --force \
--image image-registry.openshift-image-registry.svc:5000/$(oc project --short=true)/fhir-knative-jvm
You see the revision of the Knative application is made available.
Replacing service 'myfhir' in namespace 'my-fhir-project':
0.213s Configuration "myfhir" does not have any ready Revision.
0.623s ...
0.762s Configuration "myfhir" is waiting for a Revision to become ready.
29.217s ...
29.358s Ingress has not yet been reconciled.
29.840s Waiting for load balancer to be ready
30.129s Ready to serve.
Service 'myfhir' replaced to latest revision 'myfhir-00001' is available at URL:
http://myfhir-my-fhir-project.healthcare-serverless-9999-0000.us-east.containers.appdomain.cloud
Check the url endpoint
kn service describe myfhir -o url
You see:
http://fhir-loadero-fhir-serverless.0000.us-east.containers.appdomain.cloud
Call the Serverless project with example first and last names.
curl $(kn service describe myfhir -o url)'/v1/api/loader?last=Smith&first=John'
You see the URLs generated for the new Patient data.
[https://fhirserver.appdomain.cloud/fhir-server/api/v4/Patient/dc7857d3-b5b8-4267-bdc5-14f86848ea7c/_history/1, https://fhirserver.appdomain.cloud/fhir-server/api/v4/Observation/17bc7e604ee-556a98d0-08bf-4026-a3cd-b237cca895ca/_history/1, https://fhirserver.appdomain.cloud/fhir-server/api/v4/Medication/b537a83b-0b06-4b07-8332-9801ca7022b2/_history/1, https://fhirserver.appdomain.cloud/fhir-server/api/v4/MedicationAdministration/17bc7e6052c-a074acff-86db-4ef6-9aac-2195eb7e9118/_history/1]
Copy the URL from the output. e.g. https://fhirserver-dev-fhir-serverless.0000.us-east.containers.appdomain.cloud/fhir-server/api/v4/Patient/dc7857d3-b5b8-4267-bdc5-14f86848ea7c/_history/1
and modify it slightly to extract the UUID so you are able to execute an _id
search. The UUID above is dc7857d3-b5b8-4267-bdc5-14f86848ea7c
.
Confirm the Patient is loaded using IBM FHIR Server’s Search support. Be sure to include the URL in Double Quotes.
curl -k -u fhiruser:change-password \
"https://fhirserver-dev-hir-serverless.healthcare-serverless-.us-east.containers.appdomain.cloud/fhir-server/api/v4/Patient?_id=dc7857d3-b5b8-4267-bdc5-14f86848ea7c&_pretty=true"
You see the FHIR R4 Patient Resource
{
"resourceType": "Bundle",
"id": "30b39c61-3803-4ece-a502-a676975eb1d5",
"type": "searchset",
"total": 1,
"link": [
{
"relation": "self",
"url": "https://fhirserver.appdomain.cloud/fhir-server/api/v4/Patient?_count=10&_id=dc7857d3-b5b8-4267-bdc5-14f86848ea7c&_page=1"
}
],
"entry": [
{
"fullUrl": "https://fhirserver.appdomain.cloud/fhir-server/api/v4/Patient/dc7857d3-b5b8-4267-bdc5-14f86848ea7c",
"resource": {
"resourceType": "Patient",
"id": "dc7857d3-b5b8-4267-bdc5-14f86848ea7c",
"meta": {
"versionId": "1",
"lastUpdated": "2021-09-09T00:12:25.824Z"
},
"text": {
"status": "generated",
"div": "<div xmlns=\"http://www.w3.org/1999/xhtml\">loaded from the datastore</div>"
},
"active": true,
"name": [
{
"family": "John",
"given": [
"Smith"
]
}
],
"birthDate": "2021-09-09",
"multipleBirthInteger": 2,
"generalPractitioner": [
{
"reference": "urn:uuid:c03f629d-16ff-4644-8ed9-fff14f35730d"
}
]
},
"search": {
"mode": "match",
"score": 1
}
}
]
}
You have successfully loaded your IBM FHIR Server with Healthcare Data using a Serverless project.
Call the Serverless project with example first and last names.
curl $(kn service describe myfhir -o url)'/v1/api/report'
You see the report generated by querying the backend FHIR Data.
Total Number of Medication Administrations Today are: 2
[0] John Smith
[1] Johnny Smith
If there is more than one Patient created, you’ll notice your report gets slightly more complicated as it reports on the total Patients that have Medications administered to them.
In this lab, you have built a simple healthcare serverless application using Red Hat OpenShift Serverless to interact with the IBM FHIR Server.
Paul Bastide is reachable at:
Install the IBM Cloud CLI
Install the IBM Cloud CLI Plugins
You should install Container Service for additional control of your containers.
ibmcloud plugin install container-service -f
You see:
Looking up 'container-service' from repository 'IBM Cloud'...
Plug-in 'container-service/kubernetes-service 1.0.312' found in repository 'IBM Cloud'
Attempting to download the binary file...
29.13 MiB / 29.13 MiB [============] 100.00% 3s
30539808 bytes downloaded
Installing binary...
OK
Plug-in 'container-service 1.0.312' was successfully installed. Use 'ibmcloud plugin show container-service' to show its details.
You should install Container Registry to support a custom Registry
ibmcloud plugin install container-registry -f
You see:
Looking up 'container-registry' from repository 'IBM Cloud'...
Plug-in 'container-registry 0.1.543' found in repository 'IBM Cloud'
Attempting to download the binary file...
26.28 MiB / 26.28 MiB [============] 100.00% 2s
27560704 bytes downloaded
Installing binary...
OK
Plug-in 'container-registry 0.1.543' was successfully installed. Use 'ibmcloud plugin show container-registry' to show its details.
You should install Observe Service for additional logging of your containers and cluster.
ibmcloud plugin install observe-service -f
You see:
Looking up 'observe-service' from repository 'IBM Cloud'...
Plug-in 'observe-service 1.0.61' found in repository 'IBM Cloud'
Attempting to download the binary file...
17.70 MiB / 17.70 MiB [============] 100.00% 1s
18561888 bytes downloaded
Installing binary...
OK
Plug-in 'observe-service 1.0.61' was successfully installed. Use 'ibmcloud plugin show observe-service' to show its details.
To support the IBM FHIR Server’s schema, a IBM® Cloud Databases for PostgreSQL database with at least one user with max_connections
and max_prepared_transactions
configured as shown in the below script.
The script is as follows:
ibmcloud resource service-instance-create serverless-db \
databases-for-postgresql standard us-east \
-p '{"service-endpoints": "public-and-private"}'
ibmcloud cdb deployment-configuration \
serverless-db '{"max_connections": 150}'
ibmcloud cdb deployment-configuration \
serverless-db '{"max_prepared_transactions": 150}'
ibmcloud cdb deployment-user-create serverless-db \
fhirserver
The following outlines the steps necessary to setup the IBM FHIR Server Operator.
Log in to IBM Cloud
Click Create Cluster
Select Red Hat OpenShift (The page changes to the OpenShift Version)
Select the OpenShift verison 4.7 stream (4.7.19 as of writing)
Click VPC
Select a COS storage container
Select only one Worker Zone (we don’t need multiple subnets)
Change the cluster name to ibmfhirserverhealthcare
Click Create
… Wait until the Ingress Status is Healthy and there are three nodes deployed and healthy …
Click on OpenShift Web Console
Click on Operators > OperatorHub
Find Red Hat OpenShift Serverless
Click on the Red Hat OpenShift Serverless tile
Click Install
On the Install Operator panel, select Update channel stable
.
Select Installation mode All namespaces on the cluster
.
Select Approval strategy Automatic
Click Install
… The operator is installed …
Wait for Installed Operator - ready for use.
Click View Operator
Switch Project to the knative-serving namespace
Click on Operators > Red Hat OpenShift Serverless
Click Knative Serving > Create Instance
Click Create
Click on the User dropdown in the Upper Right > Copy Login Command
A new tab opens, Click Display Token and Copy the Contents
On a terminal window, paste the contents on the terminal.
oc login --token=sha256~*** \
--server=https://***.us-east.containers.cloud.ibm.com:32689
You see:
Logged into "https://****.us-east.containers.cloud.ibm.com:32689" as "IAM#***" using the token provided.
You have access to 69 projects, the list has been suppressed. You can list all projects with 'oc projects'
Using project "default".
Create a file for the IBM Operator Catalog source with the following content, and save as IBMCatalogSource.yml:
cat << EOF > IBMCatalogSource.yml
apiVersion: operators.coreos.com/v1alpha1
kind: CatalogSource
metadata:
name: ibm-operator-catalog
namespace: openshift-marketplace
spec:
displayName: "IBM Operator Catalog"
publisher: IBM
sourceType: grpc
image: docker.io/ibmcom/ibm-operator-catalog
updateStrategy:
registryPoll:
interval: 45m
EOF
Apply the source by using the following command:
oc apply -f IBMCatalogSource.yml
Upon success, you see:
catalogsource.operators.coreos.com/ibm-operator-catalog created
Click on Operators > OperatorHub
Find IBM FHIR Server
Click on the IBM FHIR Server
tile
Click Install
Select Update channel v1.1
Select A specific namespace on the cluster
Click on Installed Namespace
Click Create Namespace
Enter name fhir-serverless
Click Create
Select Approval strategy automatic
Click Install
... The operator is installed ...
Wait for Installed Operator - ready for use.
Click View Operator
curl -o fhir-server-config.json -L \
https://raw.githubusercontent.com/IBM/FHIR/4.6.1/fhir-server/liberty-config/config/default/fhir-server-config-postgresql.json
If you look at the configuration, you’ll notice it’s a JSON file with lots of name-value pairs which control the behavior of the IBM FHIR Server. The details for each of the features and configurations is detailed on the IBM FHIR Server’s Users Guide.
Create the admin.txt password with a random password value.
cat << EOF > admin.txt
$(openssl rand -hex 20)
EOF
cat << EOF > user.txt
$(openssl rand -hex 20)
EOF
cat << EOF > timeout.txt
240s
EOF
Next, create persistence.json.
Login to the IBM Cloud Console
Find your Postgres service serverless-db
Click Service Credentials
Click New Credentials
Type serverless
Click Add
Expand the serverless
entry
Replace the details in the command below:
cat << EOF > persistence.json
{
"persistence": [
{
"db": {
"type": "postgresql",
"host": "example.appdomain.cloud",
"port": "13999",
"database": "ibmclouddb",
"user": "dbuser",
"password": "password",
"ssl": "true",
"certificate_base64": "<<from connection.certificate.certificate_base64>>"
},
"schema": {
"fhir": "FHIRDATA",
"batch": "FHIR_JBATCH",
"oauth": "FHIR_OAUTH"
},
"grant": "dbuser",
"behavior": "onboard"
}
]
}
cat << EOF > datasource.xml
<server>
<dataSource id="fhirDefaultDefault" jndiName="jdbc/fhir_default_default" type="javax.sql.XADataSource" statementCacheSize="200" syncQueryTimeoutWithTransactionTimeout="true" validationTimeout="30s">
<jdbcDriver javax.sql.XADataSource="org.postgresql.xa.PGXADataSource" libraryRef="sharedLibPostgres"/>
<properties.postgresql
serverName="example.appdomain.cloud"
portNumber="13999"
databaseName="ibmclouddb"
user="fhirserver"
password="change-password"
currentSchema="fhirdata"
/>
<connectionManager maxPoolSize="200" minPoolSize="40"/>
</dataSource>
</server>
echo connection.certificate.certificate_base64>> | base64 -d > db.cert
fhir-serverless-secret
secretoc create secret generic fhir-serverless-secret \
--from-file=IBM_FHIR_SCHEMA_TOOL_INPUT=./persistence.json \
--from-file=IBM_FHIR_SERVER_CONFIG=./fhir-server-config.json \
--from-file=IBM_FHIR_SERVER_DATASOURCE=./datasource.xml \
--from-file=IBM_FHIR_SERVER_ADMIN_PASSWORD=./admin.txt \
--from-file=IBM_FHIR_SERVER_USER_PASSWORD=./user.txt \
--from-file=IBM_FHIR_SERVER_CERT=./db.cert \
--from-file=IBM_FHIR_SERVER_TRANSACTION_TIMEOUT=./timeout.txt \
--namespace=fhir-serverless
Click Create Instance on the IBMFHIRServer
tile.
Enter a name for the instance, and enter the name of the Secret resource containing the IBM FHIR Server configuration, such as fhir-serverless-inst
.
Set License accept to true.
Click Create
Once the pods are UP…
Create a Networking > Routes
Click Create Route
Enter a Name - fhir-server-route
Select Service fhir-serverless-inst
Select Target Port 443 -> 9443
.
Select TLS Termination
Click TLS Termination Type Passthrough
Select Insecure Traffic Redirect
Click Create
You are redirected to the Route details, and you find your location listed:
https://fhir-server-route-fhir-serverless.healthcare-serverless-0000.example.appdomain.cloud
Run a Health Check
curl -k -u fhiruser:yourpassword 'https://fhirserver-dev-fhir-serverless.0000.us-east.containers.appdomain.cloud/fhir-server/api/v4/$healthcheck'
Your IBM FHIR Server instance is up and running on Red Hat OpenShift.
The following references are handy for fellow developers:
The author would like to acknowledge the authors of Digital Developer Conference Hybrid Cloud - Lab Stream and GitHub: IBM/example-bank - Building a data privacy focused mobile back-end who provided insight and a pattern to follow for this Lab.