Skip to content

Commit 4e22e3d

Browse files
awendelin-workMatthewKhouzam
authored andcommitted
Add health endpoint API support
Add a fetch_health method to TspClient to allow a user to fetch the health status of the trace server as described in the TSP. Add command-line option --get-health to the CLI client.
1 parent 29ba74a commit 4e22e3d

File tree

5 files changed

+97
-0
lines changed

5 files changed

+97
-0
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ usage: tsp_cli_client [-h] [--ip IP] [--port PORT]
8181
[--type-id TYPE_ID]
8282
[--config-id CONFIG_ID]
8383
[--params PARAMS]
84+
[--get-health]
8485

8586
CLI client to send Trace Server Protocol commands to a Trace Server.
8687

@@ -134,6 +135,7 @@ optional arguments:
134135
--config-id CONFIG_ID
135136
id of configuration
136137
--params PARAMS comma separated key value pairs (key1=val1,key2=val2)
138+
--get-health Get the health status of the server
137139
```
138140

139141
Examples:
@@ -161,6 +163,7 @@ Examples:
161163
./tsp_cli_client --load-configuration --type-id TYPE_ID --params key1:value1
162164
./tsp_cli_client --update-configuration --type-id TYPE_ID --config-id CONFIG_ID --params key1=value1,key2=value2
163165
./tsp_cli_client --delete-configuration CONFIGURATION_ID --type-id TYPE_ID
166+
./tsp_cli_client --get-health
164167
```
165168

166169
[agc]: https://kislyuk.github.io/argcomplete/#activating-global-completion

test_tsp.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import pytest
3030
import requests
3131

32+
from tsp.health import HealthStatus
3233
from tsp.response import ResponseStatus
3334
from tsp.tsp_client import TspClient
3435

@@ -475,6 +476,13 @@ def test_put_configuration(self, extension):
475476

476477
self.tsp_client.delete_configuration(CONFIG_SOURCE_TYPE, self.name)
477478

479+
def test_fetch_health(self):
480+
"""Expect a successful health response"""
481+
response = self.tsp_client.fetch_health()
482+
assert response.status_code == 200
483+
assert response.model
484+
assert response.model.status == HealthStatus.UP
485+
478486
@staticmethod
479487
def __requested_parameters(response):
480488
parameters = {}

tsp/health.py

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# The MIT License (MIT)
2+
#
3+
# Copyright (C) 2024 - Ericsson
4+
#
5+
# Permission is hereby granted, free of charge, to any person obtaining a copy
6+
# of this software and associated documentation files (the "Software"), to deal
7+
# in the Software without restriction, including without limitation the rights
8+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
# copies of the Software, and to permit persons to whom the Software is
10+
# furnished to do so, subject to the following conditions:
11+
#
12+
# The above copyright notice and this permission notice shall be included in
13+
# all copies or substantial portions of the Software.
14+
#
15+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
# SOFTWARE.
22+
23+
"""Health class file."""
24+
25+
from enum import Enum
26+
27+
STATUS_KEY = "status"
28+
29+
30+
class HealthStatus(Enum):
31+
'''
32+
The server is running and ready to receive requests
33+
'''
34+
UP = "UP"
35+
36+
def __str__(self):
37+
return f"{self.value}"
38+
39+
40+
# pylint: disable=too-few-public-methods
41+
class Health:
42+
'''
43+
Model of server health
44+
'''
45+
46+
def __init__(self, params):
47+
'''
48+
Constructor
49+
'''
50+
51+
# Health status
52+
if STATUS_KEY in params:
53+
self.status = HealthStatus(params.get(STATUS_KEY))
54+
del params[STATUS_KEY]
55+
else:
56+
self.status = None
57+
58+
def to_string(self):
59+
'''
60+
to_string method
61+
'''
62+
return f"Health[status={self.status}]"

tsp/tsp_client.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
from tsp.experiment_set import ExperimentSet
3838
from tsp.experiment import Experiment
3939
from tsp.output_descriptor import OutputDescriptor
40+
from tsp.health import Health
4041

4142
APPLICATION_JSON = 'application/json'
4243

@@ -465,3 +466,18 @@ def delete_configuration(self, type_id, config_id):
465466
else: # pragma: no cover
466467
print("post extension failed: {0}".format(response.status_code))
467468
return TspClientResponse(None, response.status_code, response.text)
469+
470+
def fetch_health(self):
471+
'''
472+
Fetch the health status of the server
473+
:return: :class:`TspClientResponse <Health>` object
474+
:rtype: TspClientResponse
475+
'''
476+
api_url = '{0}health'.format(self.base_url)
477+
response = requests.get(api_url, headers=headers)
478+
if response.status_code == 200:
479+
return TspClientResponse(Health(json.loads(response.content.decode('utf-8'))),
480+
response.status_code, response.text)
481+
else: # pragma: no cover
482+
print("get health failed: {0}".format(response.status_code))
483+
return TspClientResponse(None, response.status_code, response.text)

tsp_cli_client

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,7 @@ if __name__ == "__main__":
222222
parser.add_argument("--type-id", dest="type_id", help="id of configuration source type")
223223
parser.add_argument("--config-id", dest="config_id", help="id of configuration")
224224
parser.add_argument("--params", dest="params", help="semicolon separated key value pairs (key1=val1;key2=val2)")
225+
parser.add_argument("--get-health", dest="get_health", action='store_true', help="Get the health status of the server")
225226

226227
argcomplete.autocomplete(parser)
227228
options = parser.parse_args()
@@ -510,6 +511,13 @@ if __name__ == "__main__":
510511
else:
511512
print("No source typeId provided to delete this configuration")
512513

514+
if options.get_health:
515+
response = tsp_client.fetch_health()
516+
if response.status_code == 200:
517+
print(' {0}'.format(response.model.to_string()))
518+
sys.exit(0)
519+
else:
520+
sys.exit(1)
513521

514522
except requests.exceptions.ConnectionError as e:
515523
print('Unexpected error: {0}'.format(e))

0 commit comments

Comments
 (0)