Notes on IBM FHIR server

Russell Bateman
June 2020

Relevant links

Cloning the project from GitHub

Most of what follows is my experience in real time. I did this work in a separate rather than under my usual user area.

russ@gondolin ~ $ cd /home2/FHIR
russ@gondolin /home2 $ git clone https://github.com/IBM/FHIR.git
Cloning into 'FHIR'...
remote: Enumerating objects: 161, done.
remote: Counting objects: 100% (161/161), done.
remote: Compressing objects: 100% (119/119), done.
remote: Total 271151 (delta 47), reused 87 (delta 10), pack-reused 270990
Receiving objects: 100% (271151/271151), 374.17 MiB | 2.53 MiB/s, done.
Resolving deltas: 100% (211871/211871), done.
Checking connectivity... done.
Checking out files: 100% (21257/21257), done.
russ@gondolin ~ $ cd FHIR

Setting up the project in IntelliJ IDEA

At this point, I launched IntelliJ IDEA on the project and began fixing configuration to compile everything, which did not work. Besides lots of pointless IDEA configuration that didn't make a lot of difference, I created this root pom.xml. I was careful to avoid modifications to anything under the myriad submodules.

See appendices for the root-level pom.xml.

Building from the command line

I began to use this page to help figure out how to build: IBM FHIR Server on the Raspberry Pi 4. It had the answer of the third line below, but not the second line. The third line errors out unless fhir-examples has been built. Here's my experience:

russ@gondolin /home2/FHIR $ mvn clean install -f fhir-examples/pom.xml
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building fhir-examples 4.2.2-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
.
.
.
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 8.008 s
[INFO] Finished at: 2020-06-16T16:26:19-06:00
[INFO] Final Memory: 23M/526M
[INFO] ------------------------------------------------------------------------
russ@gondolin /home2/FHIR $ mvn install -f fhir-parent/pom.xml
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Build Order:
[INFO]
[INFO] IBM FHIR Server
[INFO] fhir-core
[INFO] fhir-database-utils
[INFO] fhir-config
[INFO] fhir-audit
[INFO] fhir-model
[INFO] fhir-registry
[INFO] fhir-term
[INFO] fhir-profile
[INFO] fhir-path
[INFO] fhir-validation
[INFO] fhir-ig-us-core
[INFO] fhir-ig-carin-bb
.
.
.
WARNING: [ONCE] Not supported in Derby: ALTER TABLE FHIRDATA.OBSERVATION_STR_VALUES ALTER COLUMN ROW_ID SET CACHE 1000
Release 455 FHIR database created successfully.
June 28, 2020 1:19:04 PM com.ibm.fhir.database.utils.model.DatabaseObject applyVersion
INFO: Applying change [v1]: TABLESPACE:FHIR_TS:1
June 28, 2020 1:19:10 PM com.ibm.fhir.database.utils.derby.DerbyMaster shutdown
INFO: Shutting down Derby DB 'target/derby/initial' with: jdbc:derby:target/derby/initial;shutdown=true
June 28, 2020 1:19:11 PM com.ibm.fhir.database.utils.derby.DerbyMaster shutdown
INFO: Database 'target/derby/initial' shutdown.
FHIR database migrated successfully.
.
.
.
Downloaded: https://repo.maven.apache.org/maven2/org/ops4j/pax/url/pax-url-aether/2.6.1/pax-url-aether-2.6.1.jar (3289 KB at 1988.0 KB/sec)
[INFO] Building zip: /media/home2/FHIR/fhir-install/target/fhir-server-distribution.zip
[INFO]
[INFO] --- maven-install-plugin:2.5.2:install (default-install) @ fhir-install ---
[INFO] Installing /media/home2/FHIR/fhir-install/pom.xml to /home/russ/.m2/repository/com/ibm/fhir/fhir-install/4.2.2-SNAPSHOT/fhir-install-4.2.2-SNAPSHOT.pom
[INFO] Installing /media/home2/FHIR/fhir-install/target/fhir-server-distribution.zip to /home/russ/.m2/repository/com/ibm/fhir/fhir-install/4.2.2-SNAPSHOT/fhir-install-4.2.2-SNAPSHOT.zip
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO]
[INFO] IBM FHIR Server .................................... SUCCESS [  1.209 s]
[INFO] fhir-core .......................................... SUCCESS [  1.865 s]
[INFO] fhir-database-utils ................................ SUCCESS [  1.443 s]
[INFO] fhir-config ........................................ SUCCESS [  2.296 s]
[INFO] fhir-audit ......................................... SUCCESS [  1.549 s]
[INFO] fhir-model ......................................... SUCCESS [ 18.995 s]
[INFO] fhir-registry ...................................... SUCCESS [  7.093 s]
[INFO] fhir-term .......................................... SUCCESS [  3.519 s]
[INFO] fhir-profile ....................................... SUCCESS [  0.114 s]
[INFO] fhir-path .......................................... SUCCESS [  7.203 s]
[INFO] fhir-validation .................................... SUCCESS [ 12.516 s]
[INFO] fhir-ig-us-core .................................... SUCCESS [  5.855 s]
[INFO] fhir-ig-carin-bb ................................... SUCCESS [  4.854 s]
[INFO] fhir-ig-mcode ...................................... SUCCESS [  4.524 s]
[INFO] fhir-ig-davinci-pdex-plan-net ...................... SUCCESS [  4.017 s]
[INFO] fhir-search ........................................ SUCCESS [ 12.498 s]
[INFO] fhir-persistence ................................... SUCCESS [  3.600 s]
[INFO] fhir-persistence-proxy ............................. SUCCESS [  3.545 s]
[INFO] fhir-persistence-schema ............................ SUCCESS [11:17 min]
[INFO] fhir-persistence-jdbc .............................. SUCCESS [20:30 min]
[INFO] fhir-provider ...................................... SUCCESS [  3.301 s]
[INFO] fhir-notification .................................. SUCCESS [  0.192 s]
[INFO] fhir-notification-websocket ........................ SUCCESS [  0.193 s]
[INFO] fhir-notification-kafka ............................ SUCCESS [  0.082 s]
[INFO] fhir-notification-nats ............................. SUCCESS [  1.069 s]
[INFO] IBM FHIR Server - REST API Implementation .......... SUCCESS [  2.750 s]
[INFO] fhir-operation-test ................................ SUCCESS [  2.973 s]
[INFO] fhir-operation-validate ............................ SUCCESS [  0.058 s]
[INFO] fhir-operation-document ............................ SUCCESS [  0.054 s]
[INFO] fhir-operation-healthcheck ......................... SUCCESS [  0.069 s]
[INFO] fhir-operation-apply ............................... SUCCESS [  0.084 s]
[INFO] fhir-operation-bulkdata ............................ SUCCESS [  3.995 s]
[INFO] fhir-operation-convert ............................. SUCCESS [  0.048 s]
[INFO] fhir-operation-term ................................ SUCCESS [  0.098 s]
[INFO] fhir-bulkimportexport-webapp ....................... SUCCESS [  7.155 s]
[INFO] fhir-client ........................................ SUCCESS [  2.199 s]
[INFO] fhir-cli ........................................... SUCCESS [  7.810 s]
[INFO] IBM FHIR Server - REST API WebApp .................. SUCCESS [  0.713 s]
[INFO] fhir-server-test ................................... SUCCESS [  1.578 s]
[INFO] fhir-swagger-generator ............................. SUCCESS [  8.999 s]
[INFO] fhir-openapi ....................................... SUCCESS [  0.239 s]
[INFO] fhir-install ....................................... SUCCESS [ 30.872 s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 34:39 min
[INFO] Finished at: 2020-06-16T17:01:12-06:00
[INFO] Final Memory: 132M/1534M
[INFO] ------------------------------------------------------------------------

So, yeah, it takes a really long time. I built it a year later on some new hardware I built (10th generation i7) and it took about 10 fewer minutes.

Where is the zip file spoken of in the article?

russ@gondolin /home2/FHIR $ find . -name '*.zip'
./fhir-cli/target/fhir-cli.zip
./fhir-persistence-proxy/target/fhir-persistence-proxy-distribution.zip
./fhir-install/target/fhir-server-distribution.zip
./fhir-validation/target/fhir-validation-distribution.zip

Note that the warning that the [third] command takes a long time and patience is required is not an idle one. It takes a seriously long time. It's the tests that slog on...

Unpack server from distribution

russ@gondolin /home2/FHIR $ mkdir ./unpack
russ@gondolin /home2/FHIR $ pushd ./unpack
russ@gondolin /home2/FHIR/unpack $ unzip ../fhir-install/target/fhir-server-distribution.zip
Archive:  ../fhir-install/target/fhir-server-distribution.zip
   creating: fhir-server-dist/
   creating: fhir-server-dist/artifacts/
   creating: fhir-server-dist/artifacts/servers/
   creating: fhir-server-dist/artifacts/servers/fhir-server/
   creating: fhir-server-dist/artifacts/servers/fhir-server/docs/
   .
   .
   .
  inflating: fhir-server-dist/artifacts/shared/resources/lib/fhir/gson-2.8.1.jar
  inflating: fhir-server-dist/artifacts/shared/resources/lib/fhir/commons-logging-1.2.jar
  inflating: fhir-server-dist/artifacts/servers/fhir-server/userlib/fhir-ig-mcode-4.2.2-SNAPSHOT.jar
  inflating: fhir-server-dist/artifacts/shared/resources/lib/postgresql/postgresql-42.2.12.jar
russ@gondolin /home2/FHIR/unpack $ ll
total 12
drwxrwxr-x  3 russ russ 4096 Jun 17 08:36 .
drwxrwxr-x 44 russ russ 4096 Jun 17 08:35 ..
drwxr-xr-x  4 russ russ 4096 Jun 16 17:01 fhir-server-dist

Install fhir-server and test its installation

russ@gondolin /home2/FHIR/unpack $ mkdir -p ../runtime/fhir-server
russ@gondolin /home2/FHIR/unpack $ sh ./fhir-server-dist/install.sh ../runtime/fhir-server
Executing ./fhir-server-dist/install.sh to deploy the fhir-server web application...

Deploying fhir-server in location: ../runtime/fhir-server

The Liberty installation directory does not exist; will attempt to create it... done!

Extracting the Liberty runtime... done!

Warning: JAVA_HOME not set; Java 8 or above is required for proper execution.

Creating Liberty server definition for fhir-server...
Server fhir-server created.
done!

Deploying fhir-server assets to server runtime environment... done!


The FHIR Server has been successfully deployed to the
Liberty runtime located at: ../runtime/fhir-server/wlp

The following manual steps must be completed before the server can be started:

1) Make sure that your selected database (e.g. Derby, DB2) is active and
   ready to accept requests.

2) Modify the server.xml and fhir-server-config.json files located at
   ../runtime/fhir-server/wlp/usr/servers/fhir-server to properly configure the server according
   to your requirements.
   This includes the definition of the ports, the configuration
   of datastore(s), and other associated configuration.

3) The fhir-server application requires Java 8 or above.
   If you do not have one, a copy of the Java 8 SDK can be obtained at https://adoptopenjdk.net.
   Be sure to set the JAVA_HOME environment variable to point to your Java 8 installation
   before starting the server:
       export JAVA_HOME=../runtime/fhir-server/wlp/ibm-java-x86_64-80

4) You can start and stop the server with these commands:
   ../runtime/fhir-server/wlp/bin/server start fhir-server
   ../runtime/fhir-server/wlp/bin/server stop fhir-server
russ@gondolin /home2/FHIR/unpack $ ../runtime/fhir-server/wlp/bin/server status fhir-server
bash: ../runtime/fhir-server/wlp/bin/server: No such file or directory
russ@gondolin /home2/FHIR/unpack $ ll ../runtime/fhir-server/
total 8
drwxrwxr-x 2 russ russ 4096 Jun 17 08:52 .
drwxrwxr-x 3 russ russ 4096 Jun 17 08:52 ..
russ@gondolin /home2/FHIR/unpack $ tree ../runtime/
../runtime/
└── fhir-server
1 directory, 0 files

For some reason, runtime was created under unpack instead of in unpack's parent: move the local copy up in place of the parent copy, which is empty.

russ@gondolin /home2/FHIR/unpack $ rm -rf ../runtime
russ@gondolin /home2/FHIR/unpack $ mv runtime/ ..

Now let's look to trial-launching it.

russ@gondolin /home2/FHIR/unpack $ cd ../runtime
russ@gondolin /home2/FHIR/runtime $ ../runtime/fhir-server/wlp/bin/server status fhir-server
Server fhir-server is not running.

Good, it's there, just not running. First, let's reduce the memory footprint just for grins to -Xms1024M and -Xmx1024M.

russ@gondolin /home2/FHIR/runtime $ vim ./fhir-server/wlp/usr/servers/fhir-server/jvm.options

Then we'll launch it.

russ@gondolin /home2/FHIR/runtime $ ./fhir-server/wlp/bin/server start fhir-server
Starting server fhir-server.
Server fhir-server started with process ID 9351.

This article is sorely uncoupled from the source code we have. We will have to improvise the smoke tests. First, verify that the server is running on localhost and accessible via port 9443. This port is presumably chosen by the server though I could not find where that is configured upon a very shallow search.

Check to see if this port is indeed fhir-server and accessible on the port.

russ@gondolin /home2/FHIR/runtime $ netstat -a | grep 9443
tcp6       0      0 [::]:9443               [::]:*                  LISTEN
russ@gondolin /home2/FHIR/runtime $ netstat -tulpn | grep 9443
tcp6       0      0 :::9443                 :::*                    LISTEN      9351/java
russ@gondolin /home2/FHIR/runtime $ pwdx 9351
9351: /media/home2/FHIR/runtime/fhir-server/wlp/usr/servers/fhir-server
russ@gondolin /home2/FHIR/runtime $ telnet localhost 9443
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
exit
Connection closed by foreign host.

Demonstration of using the server

With everything appearing to be in good order, let's try creating a FHIR Patient resource.

russ@gondolin /home2/FHIR/runtime $ curl -k \
-H 'Content-Type: application/json' \
-u 'fhiruser:change-password' 'https://localhost:9443/fhir-server/api/v4/Patient' -d '
{
    "resourceType" : "Patient",
    "active" : true,
    "name" : [ {
        "family" : "Munster",
        "given" : [ "Herman" ]
    } ],
    "gender" : "male"
}
'

All quiet. I should expect a 201 Success with content. Let's try </> RESTED from a browser instead.

The server did not respond with 201 as hoped (or any, cogent error).

(I suspect I'm supposed to fix -u 'fhiruser:change-password', but I don't want to do that now as long as the password is nevertheless good.)

And yet no error reported. It's dead-quiet. I've tried pinging, which doesn't work (despite the port, listening and pid checks above succeeding):

russ@gondolin /home2/FHIR/runtime $ ping localhost
PING localhost (127.0.0.1) 56(84) bytes of data.
64 bytes from localhost (127.0.0.1): icmp_seq=1 ttl=64 time=0.015 ms
^C

(This would all be sorted out the second time I would try; see IBM fhir-server Log.

Back to attempting to build the server ourselves...

This is what we're doing above. Our goal is to figure out how to cast this project in IntelliJ IDEA and get it to build there. I'm seeing lots of errors that appear to be artifacts only of how the project is set up. I'm struggling to figure out, in IDEA, how to fix that. Here are some collected links:

fhir-parent (the true project root)
maven-javadoc-plugin, additionalparam:
https://stackoverflow.com/questions/52547306/maven-javadoc-plugin-not-accepting-additionalparam-xdoclintnone-additionalpa

Maybe it's creating the root pom.xml with a modules list.

So, the problem is that I can build it via Maven at the command line with no trouble. What I must do is set it up building in IDEA so that I can modify code and run its debugger. The (sub) modules (or projects) that have errors are:

The root of the bigger project, that creates the FHI server, is fhir-parent and its pom.xml says these are the contributing modules:

fhir-audit
fhir-bulkimportexport-webapp
fhir-cli
fhir-client
fhir-config
fhir-core
fhir-database-utils
fhir-install
fhir-model
fhir-notification
fhir-openapi
fhir-path
fhir-persistence-jdbc
fhir-persistence-proxy
fhir-persistence-schema
fhir-persistence
fhir-profile
fhir-provider
fhir-registry
fhir-search
fhir-server-test
fhir-server-webapp
fhir-server
fhir-swagger-generator
fhir-term
fhir-validation
conformance/fhir-ig-carin-bb
conformance/fhir-ig-davinci-pdex-plan-net
conformance/fhir-ig-mcode
conformance/fhir-ig-us-core
notification/fhir-notification-kafka
notification/fhir-notification-nats
notification/fhir-notification-websocket
operation/fhir-operation-apply
operation/fhir-operation-bulkdata
operation/fhir-operation-convert
operation/fhir-operation-document
operation/fhir-operation-healthcheck
operation/fhir-operation-term
operation/fhir-operation-test
operation/fhir-operation-validate


Appendices

Root-level pom.xml for IBM FHIR project

This doesn't solve all of IntelliJ IDEA's problems; there are still files in a few modules that fail to compile.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
                        http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.windofkeltia.fhir</groupId>
  <artifactId>FHIR</artifactId>
  <version>1.0</version>

  <properties>
    <javac.source>1.8</javac.source>
    <javac.target>1.8</javac.target>
    <hapi-fhir.version>4.2.0</hapi-fhir.version>
    <fhir.version>${hapi-fhir.version}</fhir.version>
    <testng.version>6.8</testng.version>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
    <maven-compiler-plugin.version>3.8.1</maven-compiler-plugin.version>
  </properties>

  <repositories>
    <repository>
      <id>ibm-fhir</id>
      <url>https://dl.bintray.com/ibm-watson-health/ibm-fhir-server-releases</url>
    </repository>
  </repositories>

  <dependencies>
    <dependency>
      <groupId>com.ibm.fhir</groupId>
      <artifactId>fhir-model</artifactId>
      <version>${fhir.version}</version>
    </dependency>
    <dependency>
      <groupId>${project.groupId}</groupId>
      <artifactId>fhir-registry</artifactId>
      <version>${project.version}</version>
    </dependency>
    <dependency>
      <groupId>${project.groupId}</groupId>
      <artifactId>fhir-ig-us-core</artifactId>
      <version>${project.version}</version>
    </dependency>
    <dependency>
      <groupId>${project.groupId}</groupId>
      <artifactId>fhir-validation</artifactId>
      <version>${project.version}</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>${project.groupId}</groupId>
      <artifactId>fhir-validation</artifactId>
      <version>${project.version}</version>
      <scope>test</scope>
      <type>test-jar</type>
    </dependency>
    <dependency>
      <groupId>${project.groupId}</groupId>
      <artifactId>fhir-examples</artifactId>
      <version>${project.version}</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>${project.groupId}</groupId>
      <artifactId>fhir-model</artifactId>
      <version>${project.version}</version>
      <type>test-jar</type>
      <scope>test</scope>
    </dependency>

    <dependency>
      <groupId>org.testng</groupId>
      <artifactId>testng</artifactId>
      <version>${testng.version}</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>${maven-compiler-plugin.version}</version>
        <configuration>
          <source>${javac.source}</source>
          <target>${javac.target}</target>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

Capability statement(s)

russ@tirion /home2/gondolin/dev/ibm-fhir-server/runtime $ ll *.xml
-rw-rw-r-- 1 russ russ 1385647 May 28 16:10 capability-full.xml
-rw-rw-r-- 1 russ russ 1265518 May 28 16:07 capability-normative.xml
-rw-rw-r-- 1 russ russ  159443 May 28 16:08 capability-terminology.xml
russ@tirion /home2/gondolin/dev/ibm-fhir-server/runtime $ wc *.xml
  Lines  Words  Bytes              mode queried
  20078  133730 1385647 capability-full.xml
  20079  133729 1265518 capability-normative.xml
   6376    8554  159443 capability-terminology.xml
  46533  276013 2810608 total

Links relevant to IntelliJ IDEA