Service clients

Integration with HeartAI services is provided for both user applications and service clients. A general end-user will typically engage with HeartAI services through an application approach, such as a web application that may be accessed with a browser. Advanced integration is also possible by interfacing through a service client. HeartAI service endpoints support REST interface endpoints for both HTTP and WebSocket protocol connections.

The following examples show a service client implementation to interface with the HeartAI service for the SA Virtual Care Service. This client may interact with the service to access data in real-time, with middleware support for data processing, data quality assessment, terminology codification, and dynamic audit and adjudication.

Services: SA Virtual Care Service

The examples in this document show service client functionality for the HeartAI service implementation of the SA Virtual Care Service (SAVCS). Further information about HeartAI support for SAVCS may be found with the following documentation:

Client configuration

The following configuration snippet shows how the SAVCS service client may be configured. This functionality includes:

  • Whether the client is interfacing with a local deployment of the service or a remote deployment of the service.
  • Whether the client interfacing with a development or production deployment of the service.
  • The host machine name of a local deployment.
  • The host machine name of a remote deployment.
## Client configuration
localMode <- TRUE
devMode <- TRUE
localDomain <- "localhost"
SAHDomain <- "apps.aro.sah.heartai.net"
if (!localMode) {
  protocol <- "https://"
  protocolWS <- "wss://"
  serviceHost <- paste0("svcs.srv.", ifelse(devMode, "dev.", "prod."), SAHDomain)
  keycloakHost <- paste0("keycloak.", SAHDomain)
} else {
  protocol <- "http://"
  protocolWS <- "ws://"
  serviceHost <- paste0(localDomain, ":14000")
  analyticsHost <- paste0(localDomain, ":7900")
  keycloakHost <- paste0(localDomain, ":9990")
}

Client external dependencies

The following external dependencies are required for this particular R client for the SAVCS service. For other clients, whether in R or another language, the dependency requirements may vary. In this case, the dependencies are as follows:

External dependency Description
tidyverse General extension to the R language developed by the tidyverse team. Provides additional functionality especially supporting data processing and data science capabilities.
httr HTTP web client for R. Supports interfacing with general HTTP service endpoints and processing the content to and from these endpoints.
websocket WebSocket web client for R. Supports interfacing with general WebSocket service endpoints and processing the content to and from these endpoints.
## External dependencies
library(tidyverse)
library(httr)
library(websocket)
library(jsonlite)

Client source dependencies

The following source dependencies provide the primary service endpoint functionalities of the client.

Client service endpoint functionalities

Some examples of specific functionalities may be found at the end of this document:

Source working directory

Ensure that the R script is configured to use the source directory location when dependencies are referred to by their filesystem path.

## Source dependencies
list.files(file.path('./functions'), full.names = TRUE, pattern = '') %>%
  walk(source)

list.files(file.path('../../../core/client/r/functions'), full.names = TRUE, pattern = '') %>%
  walk(source)

Client service ping

Clients can confirm basic service interface functionality by requesting to the service ping endpoints. The service will respond with a variety of ping types:

Client ping function Service endpoint functionality
pingService Ping over HTTP GET that returns a unique identifier and information about the service request.
pingServiceByPOST Ping over HTTP POST that returns the body of the request as the message of the ping response.
pingServiceByWebSocketCount WebSocket connection that increments a count from zero.
pingServiceByWebSocketEcho WebSocket connection that echoes requests over the connection.

The following shows SAVCS client functionalities to interface with corresponding service ping endpoints:

## Ping endpoints
r <- pingService("/savcs/api/ping")
r
content(r)

r <- pingServiceByPOST("/savcs/api/ping")
r
content(r)

ws <- pingServiceByWebSocketCount("/savcs/api/ping_ws_count")
ws$connect()
ws$close()

ws <- pingServiceByWebSocketEcho("/savcs/api/ping_ws_echo")
ws$connect()
ws$send("ping")
ws$send("pong")
ws$close()

Client authentication

Typically service endpoints are secured with identity-based access control mechanisms. In order to access the protected resource of such endpoints, the user of the client is required to perform the OAuth 2.0 Client Credentials Grant, which will provide the user will an OAuth 2.0 access token.

Platform: Identity and Access Management

Further information about HeartAI identity and access management may be found with the following documentation:

The following figure shows the typical authentication flow for acquiring an OAuth 2.0 access token:

heartai-direct-service-request.svg

The following shows SAVCS client functionalities to authenticate with a corresponding HeartAI Keycloak instance:

## Authentication: Examine Keycloak public certificates
r <- keycloakPublicCerts()
r
content(r)

## Authentication: Perform OAuth 2.0 Client Credentials Grant
r <-
  if (localMode) {
    keycloakClientCredentialsGrant("heartai-savcs-srv-dev")
  } else {
    keycloakClientCredentialsGrant("heartai-savcs-srv-dev", "USERNAME", "PASSWORD")
  }
r
content(r)

ACCESS_TOKEN <-
  content(r) %>%
    .["access_token"]

authBearer <-
  c(Authorization = paste0("Bearer ", ACCESS_TOKEN))

authBearerFail <-
  c(Authorization = paste0("Bearer ", "NOT_A_VALID_ACCESS_TOKEN"))

Client interfaces for service endpoints

The following shows SAVCS client functionalities to interface with corresponding service endpoints:

## Service endpoints
getSAVCSSim(n = 1000, authBearer = authBearer) %>%
  .$data %>% View()

getSAVCSData(10000, authBearer = authBearer) %>%
  .$data %>% View()

getSAVCSDataAudits(10000, authBearer = authBearer) %>%
  .$data %>% View()

Example: SAVCS sim data

The following example shows the function declaration to request to the SAVCS data simulation endpoint:

getSAVCSSim <-
  function(seed = 12345, n = 10, authBearer) {
    GET(
      url = paste0(
        protocol,
        serviceHost,
        "/savcs/api/sim/data_match/",
        seed, "/",
        n),
      encode = "json",
      add_headers(.headers = authBearer)) %>%
      content(.,
              as = "text",
              encoding = "UTF-8") %>%
      fromJSON(flatten = TRUE)
  }

Example: SAVCS real-time data

The following example shows the function declaration to request to the SAVCS real-time data endpoint:

getSAVCSData <-
  function(n = 10, authBearer) {
    GET(
      url = paste0(
        protocol,
        serviceHost,
        "/savcs/api/data/",
        n),
      encode = "json",
      add_headers(.headers = authBearer)) %>%
      content(.,
              as = "text",
              encoding = "UTF-8") %>%
      jsonlite::fromJSON(flatten = TRUE)
  }