A (Secure) Hello, World (telemedical) application
Prequisites
We strongly recommend following the "Hello, World" example before jumping into "(Secure) Hello, World".
Overview
This example follows the same ideas and principles as in "Hello, World", but here the data is uploaded to and retrieved from the Net4Care server using HTTPS connections.
Building and Starting the server
Before you try this example, you must build Net4Care, which is done as indicated below:
(in the root folder, execute) mvn install
Once the framework is built, start the server:
cd (root)/n4c_osgi/n4c_receiver mvn pax:provision
You can check that the server is running and accepting HTTPS connections by navigating to https://localhost:8443/observation. This should give you an HTTP 403 error
Building and Executing the SecureHelloWorld clients
The next step is to compile the example project:
cd (root)/n4c_example/SecureHelloWorld mvn compile
Next, execute the "SecureHelloUpload" program, which will upload a single observation by typing the command:
mvn -q exec:java -Dexec.mainClass="org.net4care.demo.SecureHelloUpload"
(Windows users: the batch script "upload.bat" contains the above command.)
Output should be something like
Hello Net4Care World with added security: Uploading an observation to server at address: https://localhost:8443/observation (Make sure the Net4Care server is running!) Upload result: true Upload connection result: 200OK
Now, let us retrieve the observations issued for the last 10 minutes:
mvn -q exec:java -Dexec.mainClass="org.net4care.demo.SecureHelloQuery"
(Again, a Windows batch script "query.bat" contains the command.)
This should result in the something like
Hello Net4Care World with added security: Query all observations for last 10 minutes to server at address: https://localhost:8443/observation (Make sure the Net4Care server is running!) The query is: Forwarder.QueryPersonTimeInterval for 251248-4916 in time (1369402285600-1369402885600) === Observations from the last 10 minutes === --- RAW FORMAT - using toString() --- STO: 251248-4916/MyOrgID/Device: Spirometry/MODEL1/Manufac1/1/1/1/1.0/1.0//0/obs=(Spiro: FEV1:2.8 L/FVC:3.5 L(false)) STO: 251248-4916/MyOrgID/Device: Spirometry/MODEL1/Manufac1/1/1/1/1.0/1.0//0/obs=(Spiro: FEV1:2.8 L/FVC:3.5 L(false)) --- OWN FORMAT - using API --- -*-*-*-*-*- At date/time: 24/05/2013 15:38 FVC=3.5L FEV1=2.8L. Answer to question "Feeling well?" : false Comment: I have difficulties in breathing. -*-*-*-*-*- At date/time: 24/05/2013 15:41 FVC=3.5L FEV1=2.8L. Answer to question "Feeling well?" : false Comment: I have difficulties in breathing. End.
Code walkthrough
Since the code is very similar to the "Hello, World" example, we will omit the aspects explained there and focus on the security features introduced in the code.
SecureHelloUpload
As in the "Hello, World" example, the SecureHelloUpload client does three things
- Configure the DataUploader which is responsible for uploading observations to the server
- Define a tele observation with proper information on the patient, devices used, and of course measured values
- Perform the actual upload, testing that it went well
Configure the DataUploader
As both the upload and query application needs to configure the uploader, this is encapsulated in a global function.
// Configure the architecture dataUploader = Shared.setupN4CConfiguration( serverAddress );
The difference between this example and "Hello, World" is that the uploader is configured to support secure connections through the address and port below:
https://localhost:8443/observation
Define a tele observation
Please refer to the "Hello, World" example for more information on how to define a tele observation.
Perform the actual upload
// Upload the observation to the server... FutureResult result = null; try { HttpConnector.trustKeystore(new FileInputStream("../../n4c_osgi/n4c_receiver/resources/keystore")); result = dataUploader.upload(sto, username, password); result.awaitUninterruptibly(); } catch (GeneralSecurityException e) { e.printStackTrace(); } catch (IOException e) { System.err.println("Currently unable to connect to server"); } if ( result == null ) { System.out.println( "Upload returned a null result (was the server running?)." ); } else { System.out.println( "Upload result: "+result.isSuccess() ); System.out.println( "Upload connection result: "+result.result() ); }
Since the upload is performed using an HTTPS connection, it is necessary for the server to use an SSL security certificate. Ideally, you should use a certificate issued by a trusted certification authority. However, and for testing purposes, self-signed certificates can also be used.
Please check "Configuring HTTPS" for information on how to create self-signed SSL certificates.
If you are using a self-signed certificate, you must tell the program that we will be trusting this particular certificate, even though it has not been signed by a trusted certificate authority. In this case, we will use a default self-signed keystore with certificates located in the file '(root)/n4c_osgi/n4c_receiver/resources/keystore'. The code for doing so, is
HttpConnector.trustKeystore(new FileInputStream("../../n4c_osgi/n4c_receiver/resources/keystore"));
The basic upload is done using the upload(sto, username, password)
method of the dataUploader, having the username and password defined as
// Define username and password for authentication String username = "net4care"; String password = "N3t4C@re";
where the username "net4care" is a default, already-existing user with administrator rights.
The method will return a FutureResult
which can be queried for the result of the operation.
SecureHelloQuery
The SecureHelloQuery program does the following:
- Configures the DataUploader
- Defines a query for the last ten minutes of observations on the given person
- Sends the query to the server and
- Processes the returned observations
Configure the DataUploader
This step is identical to the one defined in the SecureHelloUpload program.
Define a query
The query is defined as in the HelloQuery program from the "Hello, World" example
Send the query
In order to send the query, we must specify the keystore that contains the certificate we want to use. This step is done the exact same way as in SecureHelloUpload. The actual query is sent using the query(query, username, password)
method of the dataUploader
instance we have defined earlier. Keep in mind that you have to include the username and password, which are defined as in SecureHelloUpload.
// Send the query to the server. QueryResult res = null; try { HttpConnector.trustKeystore(new FileInputStream("../../n4c_osgi/n4c_receiver/resources/keystore")); res = dataUploader.query(query, username, password); res.awaitUninterruptibly(); } catch (IOException e) { System.out.println("Currently unable to connect to server"); e.printStackTrace(); System.exit(-1); } catch (Net4CareException e) { System.out.println("Encountered a Net4Care exception \n" +"\n Please inspect the console for details"); e.printStackTrace(); System.exit(-1); } catch (GeneralSecurityException e) { e.printStackTrace(); System.exit(-1); }
Process the returned observations
Please refer to HelloUpload from the "Hello, World" example