External API
A small, fixed REST API lets a few known external systems retrieve HPA data without going
through the Keycloak login used by the rest of the portal. It runs as its own process, separate
from the portal (server), the extractor, and Introscope EM, so a problem with an external caller
cannot affect any of them.
Three pieces of data are available:
- the list of hosts monitored in an environment by its
HpaInfrastructureagent - SystemEdge machines, Oracle databases and Oracle RAC instances - with their CPU model, CPU count and RAM; - the CPU usage of those hosts over a period;
- the CPU usage of each process running on them over a period - one per HPA agent (JVM) and one per Oracle database or RAC instance.
The metric behind each field is listed in External API metrics.
Licence
The External API requires the EXTERNAL_API module in the HPA licence.
Without it, the External API submenu is hidden, and every call with a valid key is answered with
417 Expectation Failed and the message External API is not included in current HPA licence. The
licence is checked once a minute at most, so a licence replaced from the portal applies within that
delay.
Authentication
Each request must carry an opaque API key as a bearer token:
Authorization: Bearer <key>
Keys are administrator-issued and are not tied to any user account. A key does not expire on its own; it stays valid until it is revoked or the whole API is disabled by the kill switch (see below).
Managing keys
Keys are issued and revoked from the admin-only External API Access page, and the kill switch is on its own External API Kill Switch page. Both are reachable from the External API submenu of the help menu (only shown to administrators), next to External API Swagger, which opens the Swagger UI described below.
- Create a key: a label is entered to identify the consumer (e.g. the external system’s name), and a new key is generated. The raw key is shown once, immediately after creation, and is not retrievable afterward - only its label and usage metadata (creation date, last-used date) remain visible in the list. If a key is lost, it is revoked and a new one is created.
- Revoke a key: an individual key is invalidated; it stops working within a short delay (see below), and the action cannot be undone.
- Kill switch: a single control disables every key at once, regardless of whether each individual key is itself still valid. It is meant as an emergency stop, not day-to-day key management - individual keys are revoked instead for that.
A revoked key, or the kill switch being turned on, does not take effect instantly: the API caches each key’s validity for up to about a minute, so a request made in the seconds right after a revocation may still briefly succeed. This delay is deliberate - it protects the portal from being hit by every request re-checking a key’s validity - and is not configurable from the admin page.
Endpoints
All endpoints are read-only (GET) and require the Authorization header above.
Timestamps are ISO-8601. UTC (2024-01-01T00:00:00Z) is the simplest form; an explicit offset
works too, but its + must be percent-encoded as %2B (2024-01-01T02:00:00%2B02:00), since a
raw + in a URL query is read as a space and fails to parse. A period whose begin is not
strictly before its end is rejected with 400 Bad Request.
A request rejected by the HPA server (period, resolution, unknown host, invalid regular expression) is answered with
400 Bad Request and a JSON error:
{"message": "begin must be strictly before end, got begin=2024-01-02T00:00Z end=2024-01-01T00:00Z", "code": "E09", "detailedMessage": null}
List hosts
GET /external-api/hosts?environment=<environment>[&begin=<begin>&end=<end>]
Returns the machines monitored by the environment’s HpaInfrastructure agent that reported CPU
usage during the period:
- SystemEdge machines first, with
cpu_model,cpu_count(logical CPUs) andram_in_kb, anddb_hostset tofalse, ortruewhen an Oracle database also runs on the machine; - then the other Oracle database hosts, one entry per machine whatever the number of databases and
RAC instances on it, with
ram_in_kbanddb_hostset totrue.
A database host is named by the machine name Oracle reports (its Host Name metric, read live). When
that value is not available, the name falls back to the database host configured in the Oracle
collector, or to <instance>-instance-<rank> for a RAC instance.
Every field is always present, null when its source metric does not exist for that kind of host
(e.g. cpu_model for a database host). Naming rules are detailed in
External API metrics.
begin/end are optional and, when used, must be given together. When omitted, the period is the
last hour. Giving only one of the two is rejected with 400 Bad Request.
{
"hosts": [
{"name": "srv-app-01", "cpu_model": "Intel(R) Xeon(R) CPU E3-1240 v6 @ 3.70GHz", "cpu_count": 8, "ram_in_kb": 65799856, "db_host": false},
{"name": "srv-db-01", "cpu_model": "GenuineIntel, 16 cores", "cpu_count": 32, "ram_in_kb": 131596736, "db_host": true},
{"name": "sd-138994", "cpu_model": null, "cpu_count": null, "ram_in_kb": 65536000, "db_host": true}
]
}
Host CPU
GET /external-api/hosts/cpu?environment=<environment>[&host=<host>]&begin=<begin>&end=<end>&resolution=<resolution>
Returns a CPU usage time series for one host, or for every host returned by List hosts for the
same period when host is omitted:
- SystemEdge machine:
100 - %Idle; - database host (
db_hosttrue): the host CPU utilization measured by Oracle.
host is a name returned by List hosts (case ignored). A host that List hosts does not
return for that environment and period - misspelled, not monitored, or without CPU data during the
period - is rejected with 400 Bad Request and a JSON error naming it, rather than answered with a
grid of null points.
begin, end and resolution are all required. resolution is an ISO-8601 duration giving the
bucket width, a multiple of 15 minutes (PT15M, PT30M, PT1H…). begin and end are rounded
down to the quarter (10:07 becomes 10:00), and the response gives the period evaluated in its own
begin and end. Stored data is 15 minutes per slice once aged, and agents measure on unaligned 15
s windows: a finer analysis of one process goes through a DPS. Each host has exactly one point per bucket across
[begin, end], the average CPU usage over that bucket, weighted by sample count - a fixed grid, not just however many raw samples happened to exist. A bucket with no
data still appears, with cpuPercent set to null, rather than being left out.
A resolution that is not a positive multiple of 15 minutes, or a period shorter than a quarter once
rounded, is rejected with 400 Bad Request. A
period asking for more than 10 000 points per host at the requested resolution is rejected the same
way, rather than served short: the bucket width is honoured literally, so the response would
otherwise stop before end and fold the whole remaining period into its last point. The error names
the number of points requested and the smallest resolution that fits the period.
{
"begin": "2024-01-01T00:00:00Z",
"end": "2024-01-01T00:45:00Z",
"hosts": [
{
"host": "srv-app-01",
"points": [
{"timestamp": "2024-01-01T00:00:00Z", "cpuPercent": 42.7},
{"timestamp": "2024-01-01T00:15:00Z", "cpuPercent": null},
{"timestamp": "2024-01-01T00:30:00Z", "cpuPercent": 38.1}
]
}
]
}
Process CPU
GET /external-api/processes/cpu?environment=<environment>[&host=<host>][&process=<process>]&begin=<begin>&end=<end>&resolution=<resolution>
Returns a CPU usage time series for each process, grouped by host:
- JVM (
typeJVM): one per HPA agent of the environment - servers, engines, risk calculators, scheduled tasks… - named after the agent (e.g.DataServer), measured by the agent. An agent reconnected under a suffixed name (DataServer%1) is merged into its process; - database (
typeDB): one per Oracle database, named after it (e.g.CAL18DS), and one per Oracle RAC instance, named<database>|<instance>(e.g.CAL18DSR|CAL18DSR), measured by Oracle.
Every value is a share of the whole machine, as for Host CPU, used over the whole bucket: a process not running during part of the bucket counts 0 for that part, so a task running 5 minutes at 35 % gives about 2.9 % for an hour. The time the whole environment was not monitored (a monitoring gap) is left out rather than counted as 0. The processes of a host thus add up to about its CPU usage. A database is attached to the host List hosts gives it; a JVM to the host of its agent, under the name List hosts uses for that machine (case and domain ignored), else under the agent host name. Hosts come in the order of List hosts, followed by the other agent hosts; a host without any process during the period is left out.
host and process are optional regular expressions matching the whole name, case ignored (e.g.
process=HpaRisk-Calculator.*). A JVM is matched on the host of its agent, domain ignored; a
database on its List hosts name. A filter matching nothing gives an empty hosts list. An
invalid expression is rejected with 400 Bad Request, as is a +, which cannot travel in the
request: {1,} is used instead. begin, end and resolution follow the rules of Host CPU:
one point per bucket, null for a bucket without data, at most 10 000 points per process.
{
"begin": "2024-01-01T00:00:00Z",
"end": "2024-01-01T00:30:00Z",
"hosts": [
{
"host": "srv-app-01",
"processes": [
{"process": "DataServer", "type": "JVM", "points": [
{"timestamp": "2024-01-01T00:00:00Z", "cpuPercent": 12.0},
{"timestamp": "2024-01-01T00:15:00Z", "cpuPercent": 9.0}
]}
]
},
{
"host": "sd-138994",
"processes": [
{"process": "CAL18DS", "type": "DB", "points": [
{"timestamp": "2024-01-01T00:00:00Z", "cpuPercent": 4.2},
{"timestamp": "2024-01-01T00:15:00Z", "cpuPercent": null}
]}
]
}
]
}
Example
Linux / macOS (bash):
curl -H "Authorization: Bearer <key>" \
"https://<hpa-host>/external-api/hosts?environment=cal18ds"
Windows (PowerShell), curl.exe rather than the curl alias of Invoke-WebRequest:
curl.exe -H "Authorization: Bearer <key>" `
"https://<hpa-host>/external-api/hosts?environment=cal18ds"
Windows (cmd):
curl -H "Authorization: Bearer <key>" ^
"https://<hpa-host>/external-api/hosts?environment=cal18ds"
Interactive documentation
The OpenAPI description of the endpoints is browsable, without API key, with Swagger UI at
https://<hpa-host>/external-api/docs. Its Try it out buttons call the API once a key is
entered with Authorize, and show the matching curl command for bash (Linux, macOS), PowerShell
and cmd (Windows). The raw description is at https://<hpa-host>/external-api/docs/openapi.yaml.
When the HPA server does not answer, a call gets 502 Bad Gateway, or 503 Service Unavailable if
the key or the licence could not be checked: the key may still be valid. An unknown environment is
also answered with 502. A licence without the External API module is answered with 417 (see
Licence).