dm_rpc Module

Abstraction layer for Remote Procedure Calls (RPCs) over HTTP, using libcurl.

To send an observation to an HTTP-RPC API on localhost:

character(len=:), allocatable :: url
integer                       :: rc
type(observ_type)             :: observ
type(rpc_request_type)        :: request
type(rpc_response_type)       :: response

rc = dm_rpc_init()
call dm_error_out(rc, fatal=.true.)

url = dm_rpc_url('localhost', port=80, endpoint=RPC_ROUTE_OBSERV)
rc  = dm_rpc_post(request, response, observ, url)

call dm_error_out(rc)
call dm_rpc_shutdown()

The URL returned by dm_rpc_url() will equal http://localhost:80/api/v1/observ in this case.

The procedure dm_rpc_init() has to be called once per process, and only if neither the MQTT nor the mail backend is initialised already.


Uses

  • module~~dm_rpc~~UsesGraph module~dm_rpc dm_rpc curl curl module~dm_rpc->curl iso_c_binding iso_c_binding module~dm_rpc->iso_c_binding module~dm_error dm_error module~dm_rpc->module~dm_error module~dm_http dm_http module~dm_rpc->module~dm_http module~dm_kind dm_kind module~dm_rpc->module~dm_kind module~dm_mime dm_mime module~dm_rpc->module~dm_mime module~dm_util dm_util module~dm_rpc->module~dm_util module~dm_version dm_version module~dm_rpc->module~dm_version module~dm_z dm_z module~dm_rpc->module~dm_z module~dm_error->module~dm_kind module~dm_ascii dm_ascii module~dm_error->module~dm_ascii iso_fortran_env iso_fortran_env module~dm_kind->iso_fortran_env module~dm_util->module~dm_error module~dm_util->module~dm_kind module~dm_z->module~dm_error module~dm_z->module~dm_kind module~dm_nml dm_nml module~dm_z->module~dm_nml module~dm_zlib dm_zlib module~dm_z->module~dm_zlib module~dm_zstd dm_zstd module~dm_z->module~dm_zstd module~dm_nml->module~dm_error module~dm_nml->module~dm_kind module~dm_zlib->module~dm_error module~dm_zlib->module~dm_kind zlib zlib module~dm_zlib->zlib module~dm_zstd->iso_c_binding module~dm_zstd->module~dm_error module~dm_zstd->module~dm_kind zstd zstd module~dm_zstd->zstd

Used by

  • module~~dm_rpc~~UsedByGraph module~dm_rpc dm_rpc module~dmpack dmpack module~dmpack->module~dm_rpc

Variables

Type Visibility Attributes Name Initial
character(len=*), public, parameter :: RPC_BASE = '/api/v1'

Base path of dmapi service.

character(len=*), public, parameter :: RPC_USER_AGENT = 'DMPACK '//DM_VERSION_STRING

Default user agent of RPC client.

character(len=*), public, parameter :: RPC_ROUTE_BEAT = '/beat'

Resolves to /api/v1/beat.

character(len=*), public, parameter :: RPC_ROUTE_LOG = '/log'

Resolves to /api/v1/log.

character(len=*), public, parameter :: RPC_ROUTE_OBSERV = '/observ'

Resolves to /api/v1/observ.

character(len=*), public, parameter :: RPC_ROUTE_NODE = '/node'

Resolves to /api/v1/node.

character(len=*), public, parameter :: RPC_ROUTE_SENSOR = '/sensor'

Resolves to /api/v1/sensor.

character(len=*), public, parameter :: RPC_ROUTE_TARGET = '/target'

Resolves to /api/v1/target.

integer, public, parameter :: RPC_AUTH_NONE = 0

No authentication.

integer, public, parameter :: RPC_AUTH_BASIC = 1

HTTP Basic Auth.

integer, public, parameter :: RPC_METHOD_GET = 0

HTTP GET method.

integer, public, parameter :: RPC_METHOD_POST = 1

HTTP POST method.

integer, public, parameter :: RPC_METHOD_PUT = 2

HTTP PUT method.

logical, public, parameter :: RPC_KEEP_ALIVE = .true.

Enable TCP keep-alive.

integer, public, parameter :: RPC_KEEP_ALIVE_IDLE = 120

TCP keep-alive idle time in seconds.

integer, public, parameter :: RPC_KEEP_ALIVE_INTERVAL = 60

Interval time between TCP keep-alive probes in seconds.


Interfaces

public interface dm_rpc_post

Generic RPC post function.

  • public function dm_rpc_post_type(request, response, type, url, username, password, user_agent, compression) result(rc)

    Sends a single derived type in Namelist format to a given URL, with optional authentication and compression. The URL has to be the API endpoint that accepts HTTP POST requests.

    The dummy argument type may be of derived type beat_type, log_type, node_type, observ_type, sensor_type, or target_type. The function returns E_TYPE on any other type.

    The function returns the following error codes:

    • E_INVALID if compression type is invalid.
    • E_RPC if request failed.
    • E_TYPE if type is unsupported.
    • E_ZLIB if zlib libray call failed.
    • E_ZSTD if zstd libray call failed.

    Arguments

    Type IntentOptional Attributes Name
    type(rpc_request_type), intent(inout) :: request

    RPC request type.

    type(rpc_response_type), intent(out) :: response

    RPC response type.

    class(*), intent(inout) :: type

    Derived type.

    character(len=*), intent(in), optional :: url

    URL of RPC API (may include port).

    character(len=*), intent(in), optional :: username

    HTTP Basic Auth user name.

    character(len=*), intent(in), optional :: password

    HTTP Basic Auth password.

    character(len=*), intent(in), optional :: user_agent

    HTTP User Agent.

    integer, intent(in), optional :: compression

    Deflate or Zstandard compression of payload for POST requests (Z_TYPE_*).

    Return Value integer

  • public function dm_rpc_post_types(requests, responses, types, url, username, password, user_agent, compression, sequential) result(rc)

    Sends multiple derived types concurrently in Namelist format to the given URL, with optional authentication and compression. The URL has to be the API endpoint that accepts HTTP POST requests.

    The dummy argument types may be of derived type beat_type, log_type, node_type, observ_type, sensor_type, or target_type. The function returns E_TYPE on any other type.

    If sequential is .true., the transfer will be sequentially instead of concurrently. The number of requests must match the number of types, or E_CORRUPT is returned.

    The function returns the following error codes:

    • E_ALLOC if memory allocation failed.
    • E_CORRUPT if sizes of requests and types array mismatch.
    • E_INVALID if compression type is invalid.
    • E_RPC if request failed.
    • E_TYPE if type of types is unsupported.
    • E_ZLIB if zlib libray call failed.
    • E_ZSTD if zstd libray call failed.

    Arguments

    Type IntentOptional Attributes Name
    type(rpc_request_type), intent(inout) :: requests(:)

    RPC request type array.

    type(rpc_response_type), intent(out), allocatable :: responses(:)

    RPC response type array.

    class(*), intent(inout) :: types(:)

    Derived type array.

    character(len=*), intent(in), optional :: url

    URL of RPC API (may include port).

    character(len=*), intent(in), optional :: username

    HTTP Basic Auth user name.

    character(len=*), intent(in), optional :: password

    HTTP Basic Auth password.

    character(len=*), intent(in), optional :: user_agent

    HTTP User Agent.

    integer, intent(in), optional :: compression

    Deflate or Zstandard compression of payload for POST requests (Z_TYPE_*).

    logical, intent(in), optional :: sequential

    Sequential instead of concurrent transfer.

    Return Value integer

public interface dm_rpc_request

Generic RPC request function.

  • public function dm_rpc_request_multi(requests, responses, url, method, accept, username, password, user_agent, compression) result(rc)

    Sends multiple HTTP requests by GET, POST, or PUT method, with optional deflate or zstd compression.

    Arguments

    Type IntentOptional Attributes Name
    type(rpc_request_type), intent(inout) :: requests(:)

    RPC request type array.

    type(rpc_response_type), intent(out), allocatable :: responses(:)

    RPC response type array.

    character(len=*), intent(in), optional :: url

    URL of RPC API (may include port).

    integer, intent(in), optional :: method

    RPC_METHOD_GET or RPC_METHOD_POST.

    character(len=*), intent(in), optional :: accept

    HTTP Accept header.

    character(len=*), intent(in), optional :: username

    HTTP Basic Auth user name.

    character(len=*), intent(in), optional :: password

    HTTP Basic Auth password.

    character(len=*), intent(in), optional :: user_agent

    HTTP User Agent.

    integer, intent(in), optional :: compression

    Deflate or Zstandard compression of payload for POST requests (Z_TYPE_*).

    Return Value integer

  • public function dm_rpc_request_single(request, response, url, method, payload, content_type, accept, username, password, user_agent, compression) result(rc)

    Sends single HTTP request by GET, POST, or PUT method, and with optional deflate or zstd compression.

    Arguments

    Type IntentOptional Attributes Name
    type(rpc_request_type), intent(inout) :: request

    RPC request type.

    type(rpc_response_type), intent(out) :: response

    RPC response type.

    character(len=*), intent(in), optional :: url

    URL of RPC API (may include port).

    integer, intent(in), optional :: method

    RPC_METHOD_GET or RPC_METHOD_POST.

    character(len=*), intent(inout), optional :: payload

    Payload data (for POST only).

    character(len=*), intent(in), optional :: content_type

    Payload content type (for POST only).

    character(len=*), intent(in), optional :: accept

    HTTP Accept header.

    character(len=*), intent(in), optional :: username

    HTTP Basic Auth user name.

    character(len=*), intent(in), optional :: password

    HTTP Basic Auth password.

    character(len=*), intent(in), optional :: user_agent

    HTTP User Agent.

    integer, intent(in), optional :: compression

    Deflate or Zstandard compression of payload for POST requests (Z_TYPE_*).

    Return Value integer


Abstract Interfaces

abstract interface

  • public function dm_rpc_callback(ptr, size, nmemb, data) bind(c)

    C-interoperable read/write callback for libcurl.

    Arguments

    Type IntentOptional Attributes Name
    type(c_ptr), intent(in), value :: ptr

    C pointer to a chunk of the response.

    integer(kind=c_size_t), intent(in), value :: size

    Always 1.

    integer(kind=c_size_t), intent(in), value :: nmemb

    Size of the response chunk.

    type(c_ptr), intent(in), value :: data

    C pointer to client data passed by caller.

    Return Value integer(kind=c_size_t)

    Function return value.


Derived Types

type, public ::  rpc_response_type

HTTP-RPC response type.

Components

Type Visibility Attributes Name Initial
integer, public :: code = 0

HTTP response code.

integer, public :: error = E_NONE

DMPACK error code.

integer, public :: error_curl = CURLE_OK

cURL error code.

real(kind=r8), public :: total_time = 0.0_r8

Total transmission time.

character(len=:), public, allocatable :: error_message

cURL error message.

character(len=:), public, allocatable :: content_type

Response payload type (MIME).

character(len=:), public, allocatable :: payload

Response payload.

type, public ::  rpc_request_type

HTTP-RPC request type.

Components

Type Visibility Attributes Name Initial
integer, public :: auth = RPC_AUTH_NONE

HTTP Auth.

integer, public :: method = RPC_METHOD_GET

HTTP method (GET, POST).

integer, public :: compression = Z_TYPE_NONE

Use deflate or zstd compression (Z_TYPE_*).

integer, public :: connect_timeout = 30

Connection timeout in seconds.

integer, public :: timeout = 30

Timeout in seconds.

logical, public :: follow_location = .true.

Follow HTTP 3xx redirects.

character(len=:), public, allocatable :: payload

Request payload.

character(len=:), public, allocatable :: content_type

Request payload type (MIME).

character(len=:), public, allocatable :: accept

HTTP Accept header.

character(len=:), public, allocatable :: username

HTTP Basic Auth user name.

character(len=:), public, allocatable :: password

HTTP Basic Auth password.

character(len=:), public, allocatable :: url

Request URL.

character(len=:), public, allocatable :: user_agent

User Agent.

procedure(dm_rpc_callback), public, pointer, nopass :: callback => null()

C-interoperable write callback function.


Functions

public function dm_rpc_version() result(version)

Returns version number of libcurl an linked libreries as allocatable string.

Arguments

None

Return Value character(len=:), allocatable

public function dm_rpc_error(error_curl) result(rc)

Converts cURL easy stack error code to DMPACK error code.

Arguments

Type IntentOptional Attributes Name
integer, intent(in) :: error_curl

cURL easy error code.

Return Value integer

public function dm_rpc_error_message(error_curl) result(message)

Return message associated with given cURL error code as allocatable character string.

Arguments

Type IntentOptional Attributes Name
integer, intent(in) :: error_curl

cURL error code.

Return Value character(len=:), allocatable

Error message.

public function dm_rpc_error_multi(multi_error) result(rc)

Converts cURL multi stack error code to DMPACK error code.

Arguments

Type IntentOptional Attributes Name
integer, intent(in) :: multi_error

cURL multi error code.

Return Value integer

public function dm_rpc_init() result(rc)

Initialises RPC backend. The function returns E_RPC on error.

Arguments

None

Return Value integer

public function dm_rpc_post_type(request, response, type, url, username, password, user_agent, compression) result(rc)

Sends a single derived type in Namelist format to a given URL, with optional authentication and compression. The URL has to be the API endpoint that accepts HTTP POST requests.

Read more…

Arguments

Type IntentOptional Attributes Name
type(rpc_request_type), intent(inout) :: request

RPC request type.

type(rpc_response_type), intent(out) :: response

RPC response type.

class(*), intent(inout) :: type

Derived type.

character(len=*), intent(in), optional :: url

URL of RPC API (may include port).

character(len=*), intent(in), optional :: username

HTTP Basic Auth user name.

character(len=*), intent(in), optional :: password

HTTP Basic Auth password.

character(len=*), intent(in), optional :: user_agent

HTTP User Agent.

integer, intent(in), optional :: compression

Deflate or Zstandard compression of payload for POST requests (Z_TYPE_*).

Return Value integer

public function dm_rpc_post_types(requests, responses, types, url, username, password, user_agent, compression, sequential) result(rc)

Sends multiple derived types concurrently in Namelist format to the given URL, with optional authentication and compression. The URL has to be the API endpoint that accepts HTTP POST requests.

Read more…

Arguments

Type IntentOptional Attributes Name
type(rpc_request_type), intent(inout) :: requests(:)

RPC request type array.

type(rpc_response_type), intent(out), allocatable :: responses(:)

RPC response type array.

class(*), intent(inout) :: types(:)

Derived type array.

character(len=*), intent(in), optional :: url

URL of RPC API (may include port).

character(len=*), intent(in), optional :: username

HTTP Basic Auth user name.

character(len=*), intent(in), optional :: password

HTTP Basic Auth password.

character(len=*), intent(in), optional :: user_agent

HTTP User Agent.

integer, intent(in), optional :: compression

Deflate or Zstandard compression of payload for POST requests (Z_TYPE_*).

logical, intent(in), optional :: sequential

Sequential instead of concurrent transfer.

Return Value integer

public function dm_rpc_request_multi(requests, responses, url, method, accept, username, password, user_agent, compression) result(rc)

Sends multiple HTTP requests by GET, POST, or PUT method, with optional deflate or zstd compression.

Arguments

Type IntentOptional Attributes Name
type(rpc_request_type), intent(inout) :: requests(:)

RPC request type array.

type(rpc_response_type), intent(out), allocatable :: responses(:)

RPC response type array.

character(len=*), intent(in), optional :: url

URL of RPC API (may include port).

integer, intent(in), optional :: method

RPC_METHOD_GET or RPC_METHOD_POST.

character(len=*), intent(in), optional :: accept

HTTP Accept header.

character(len=*), intent(in), optional :: username

HTTP Basic Auth user name.

character(len=*), intent(in), optional :: password

HTTP Basic Auth password.

character(len=*), intent(in), optional :: user_agent

HTTP User Agent.

integer, intent(in), optional :: compression

Deflate or Zstandard compression of payload for POST requests (Z_TYPE_*).

Return Value integer

public function dm_rpc_request_single(request, response, url, method, payload, content_type, accept, username, password, user_agent, compression) result(rc)

Sends single HTTP request by GET, POST, or PUT method, and with optional deflate or zstd compression.

Arguments

Type IntentOptional Attributes Name
type(rpc_request_type), intent(inout) :: request

RPC request type.

type(rpc_response_type), intent(out) :: response

RPC response type.

character(len=*), intent(in), optional :: url

URL of RPC API (may include port).

integer, intent(in), optional :: method

RPC_METHOD_GET or RPC_METHOD_POST.

character(len=*), intent(inout), optional :: payload

Payload data (for POST only).

character(len=*), intent(in), optional :: content_type

Payload content type (for POST only).

character(len=*), intent(in), optional :: accept

HTTP Accept header.

character(len=*), intent(in), optional :: username

HTTP Basic Auth user name.

character(len=*), intent(in), optional :: password

HTTP Basic Auth password.

character(len=*), intent(in), optional :: user_agent

HTTP User Agent.

integer, intent(in), optional :: compression

Deflate or Zstandard compression of payload for POST requests (Z_TYPE_*).

Return Value integer

public function dm_rpc_url(host, port, base, endpoint, tls) result(url)

Returns allocatable string of URL to HTTP-RPC API endpoint. Uses the URL API of libcurl to create the URL. The base path and the endpoint must both start with a /.

Read more…

Arguments

Type IntentOptional Attributes Name
character(len=*), intent(in) :: host

IP or FQDN of remote host.

integer, intent(in), optional :: port

API port (up to 5 digits).

character(len=*), intent(in), optional :: base

API base path (for example, /api/v1).

character(len=*), intent(in), optional :: endpoint

API endpoint (for example, /observ).

logical, intent(in), optional :: tls

TLS encryption (HTTPS).

Return Value character(len=:), allocatable

HTTP-RPC API endpoint URL.

public function dm_rpc_write_callback(ptr, sz, nmemb, data) result(n) bind(c))

C-interoperable write callback function for libcurl. Writes the received response chunks to rpc_response_type pointer that has to be passed through C pointer data. Do not call this function directly.

Arguments

Type IntentOptional Attributes Name
type(c_ptr), intent(in), value :: ptr

C pointer to a chunk of the response.

integer(kind=c_size_t), intent(in), value :: sz

Always 1.

integer(kind=c_size_t), intent(in), value :: nmemb

Size of the response chunk.

type(c_ptr), intent(in), value :: data

C pointer to argument passed by caller.

Return Value integer(kind=c_size_t)


Subroutines

public impure elemental subroutine dm_rpc_reset(request)

Auxiliary destructor routine to free allocated request memory. Cleans-up the cURL handles of the request.

Arguments

Type IntentOptional Attributes Name
type(rpc_request_type), intent(inout) :: request

Request type.

public subroutine dm_rpc_shutdown()

Cleans up RPC backend.

Arguments

None