Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions config/tests/deep-segments-config.data.xml
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@
</rel>
<rel name="detector_configuration" class="DetectorConfig" id="dummy-detector"/>
<rel name="opmon_uri" class="OpMonURI" id="local-opmon-uri"/>
<rel name="resource_manager" class="ResourceManagerConf" id="ResourceManagerConf_test"/>
</obj>


Expand Down
1 change: 1 addition & 0 deletions config/tests/nestedConfig.data.xml
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@
</rel>
<rel name="detector_configuration" class="DetectorConfig" id="dummy-detector"/>
<rel name="opmon_uri" class="OpMonURI" id="local-opmon-uri"/>
<rel name="resource_manager" class="ResourceManagerConf" id="ResourceManagerConf_test"/>
</obj>

<obj class="Session" id="test-nested-config-failure-on-init">
Expand Down
6 changes: 6 additions & 0 deletions config/tests/one-controller-config.data.xml
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,11 @@
<rel name="controller" class="RCApplication" id="controller-0"/>
</obj>

<obj class="ResourceManagerConf" id="ResourceManagerConf_test">
<attr name="address" type="string" val="localhost"/>
<attr name="port" type="u16" val="32009"/>
</obj>

<obj class="Session" id="one-controller-config">
<attr name="data_request_timeout_ms" type="u32" val="1000"/>
<attr name="data_rate_slowdown_factor" type="u32" val="1"/>
Expand All @@ -124,6 +129,7 @@
</rel>
<rel name="detector_configuration" class="DetectorConfig" id="dummy-detector"/>
<rel name="opmon_uri" class="OpMonURI" id="local-opmon-uri"/>
<rel name="resource_manager" class="ResourceManagerConf" id="ResourceManagerConf_test"/>
</obj>


Expand Down
14 changes: 14 additions & 0 deletions request_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import requests

url = "http://127.0.0.1:8000/api/request_resource/"
payload = {
"names": "resource_one",
"owner": "pplesnia",
"session_id": "1234567890",
"session_name": "test_session",
}

# verify=False mimics the -k flag in curl (disables SSL verification)
response = requests.post(url, data=payload, verify=False)
print(f"Status Code: {response.status_code}")
print(response.json())
5 changes: 5 additions & 0 deletions src/drunc/resource_manager/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from drunc.utils.utils import get_logger

# Initialise process manager logger with Rich handler
# This is the tty interface, so its designed to be coloured
get_logger("resource_manager", rich_handler=True)
125 changes: 125 additions & 0 deletions src/drunc/resource_manager/client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
import requests

from drunc.utils.utils import get_logger


class ResourceManagerClient:
"""
Interface for communicating with the Resource Manager service.
"""

def __init__(self, base_url):
"""
Initialize the ResourceManagerClient with the base URL of the Resource Manager service.
"""
self.url = base_url.rstrip("/")
self.log = get_logger("resource_manager.client")

def _send_request(self, endpoint, payload):
"""
Helper method to send a POST request to the Resource Manager and handle responses.

Args:
endpoint (str): The full URL endpoint to send the request to
payload (dict): The data payload to send in the request

Returns:
dict: The JSON response from the server if successful, or None if an error occurred

Raises:
None: Logs errors and returns None instead of raising exceptions for HTTP errors or unexpected issues.
"""
try:
# verify=False is used here for local/self-signed certs (like curl -k)
self.log.debug(f"Sending request to {endpoint} with payload: {payload}")
response = requests.post(endpoint, data=payload, verify=False)

if "application/json" not in response.headers.get("Content-Type", ""):
self.log.error(
"Server returned HTML/Text instead of JSON. Check your URL paths."
)
return None

# Raise an exception for 4xx or 5xx status codes
response.raise_for_status()

# Log the successful response
return response.json()
except (requests.exceptions.ConnectionError, requests.exceptions.Timeout) as e:
self.log.error(f"Failed to connect to Resource Manager at {endpoint}: {e}")
return None
except requests.exceptions.HTTPError:
self.log.warning(f"Request failed with status {response.status_code}")
self.log.debug(f"Response content: {response.text}")
return response.json()
except Exception as e:
self.log.error(f"An unexpected error occurred: {e}")
return None

def query_resources(
self, resources: list[str], owner: str, session_id: str, session_name: str
) -> dict[str]:
"""
Query the Resource Manager for the status of the specified resources.

Args:
resources (list[str]): List of resource names to query
owner (str): The new owner of the resources
session_id (str): The session ID taking the resources
session_name (str): The session name taking the resources

Returns:
dict: A dictionary containing the status of the queried resources
"""
payload = {
"names": ",".join(resources),
"session_id": session_id,
"session_name": session_name,
"user_name": owner,
}
endpoint = f"{self.url}/api/query_resource/"
return self._send_request(endpoint, payload)

def request_resources(
self, resources: list[str], owner: str, session_id: str, session_name: str
) -> dict[str]:
"""
Request resources from the Resource Manager for isolation during the run.

Args:
resources (list[str]): List of resource names to query
owner (str): The new owner of the resources
session_id (str): The session ID taking the resources
session_name (str): The session name taking the resources

Returns:
dict: A dictionary containing the status of the queried resources
"""
payload = {
"names": ",".join(resources),
"user_name": owner,
"session_id": session_id,
"session_name": session_name,
}
endpoint = f"{self.url}/api/request_resource/"

return self._send_request(endpoint, payload)

def release_resources(self, resources: list[str], session_id: str) -> dict[str]:
"""
Release resources from the Resource Manager for other runs to use.

Args:
resources (list[str]): List of resource names to query
session_id (str): The session ID taking the resources

Returns:
dict: A dictionary containing the status of the queried resources
"""
payload = {
"names": ",".join(resources),
"session_id": session_id,
}
endpoint = f"{self.url}/api/release_resource/"

return self._send_request(endpoint, payload)
Loading
Loading