You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
155 lines
5.1 KiB
155 lines
5.1 KiB
import http.client
|
|
import logging
|
|
from experiment.experiment_store import ExperimentStore
|
|
from experiment.history_store import ExperimentHistoryStore
|
|
from rest.proxy import SplunkRestProxyException, SplunkRestException
|
|
|
|
import cexc
|
|
|
|
logger = cexc.get_logger(__name__)
|
|
|
|
|
|
def capture_exception(callback, request, url_parts):
|
|
"""
|
|
execute `callback` with `request` and `path_parts` parameters
|
|
and handles exceptions generated from `callback`
|
|
|
|
Args:
|
|
callback (function): the callback function to execute
|
|
request ([type]): the request object being passed in from rest handler
|
|
path_parts ([type]): the url parts passed in from rest handler
|
|
|
|
Returns:
|
|
dict
|
|
"""
|
|
|
|
try:
|
|
return callback(request, url_parts)
|
|
except (SplunkRestProxyException, SplunkRestException) as e:
|
|
return e.to_http_response()
|
|
except Exception as e:
|
|
logger.exception("exception")
|
|
return SplunkRestProxyException(
|
|
'Cannot complete the request: %s' % str(e),
|
|
logging.ERROR,
|
|
http.client.INTERNAL_SERVER_ERROR,
|
|
).to_http_response()
|
|
|
|
|
|
def get_invalid_path_error(path_parts):
|
|
return SplunkRestProxyException(
|
|
'Invalid request path. path: %s' % str(path_parts),
|
|
logging.ERROR,
|
|
http.client.BAD_REQUEST,
|
|
)
|
|
|
|
|
|
class Experiments(object):
|
|
"""
|
|
A handler for experiments endpoint
|
|
"""
|
|
|
|
experiment_store = ExperimentStore()
|
|
history_store = ExperimentHistoryStore(with_admin_token=True)
|
|
|
|
@classmethod
|
|
def check_experiment_exists(cls, request, url_parts):
|
|
"""
|
|
A util function to check if the experiment with the given id exists, and return the response if it does.
|
|
|
|
Args:
|
|
request: (dict): the request object being passed in from rest handler
|
|
url_parts: ([type]): the url parts passed in from rest handler
|
|
|
|
Returns: (dict) a dict of response from experiment GET request
|
|
|
|
"""
|
|
|
|
experiment_fetch_reply = cls.experiment_store.get(
|
|
request, url_parts, with_raw_reply=True
|
|
)
|
|
if not experiment_fetch_reply['success']:
|
|
raise SplunkRestException(experiment_fetch_reply)
|
|
|
|
return experiment_fetch_reply
|
|
|
|
@classmethod
|
|
def safe_handle_get(cls, request, path_parts):
|
|
path_part_length = len(path_parts)
|
|
url_parts = []
|
|
|
|
# Experiment GET request handling
|
|
if 0 < path_part_length <= 2:
|
|
if path_part_length == 2:
|
|
url_parts.append(path_parts[1])
|
|
return cls.experiment_store.get(request, url_parts)
|
|
|
|
# History GET request handling
|
|
elif path_part_length == 3:
|
|
if path_parts[2] != "history":
|
|
raise get_invalid_path_error(path_parts)
|
|
url_parts.append(path_parts[1])
|
|
cls.check_experiment_exists(request, url_parts)
|
|
return cls.history_store.get(request, url_parts)
|
|
|
|
# Oh noooo we can't do that
|
|
else:
|
|
raise get_invalid_path_error(path_parts)
|
|
|
|
@classmethod
|
|
def safe_handle_post(cls, request, path_parts):
|
|
path_part_length = len(path_parts)
|
|
url_parts = []
|
|
|
|
# Experiment POST request handling
|
|
if path_part_length <= 2:
|
|
if path_part_length == 2:
|
|
url_parts.append(path_parts[1])
|
|
return cls.experiment_store.post(request, url_parts)
|
|
|
|
elif path_part_length == 3:
|
|
# History POST request handling
|
|
if path_parts[2] == "history":
|
|
url_parts.append(path_parts[1])
|
|
cls.check_experiment_exists(request, url_parts)
|
|
return cls.history_store.post(request, url_parts)
|
|
|
|
# clone models POST request handling
|
|
elif path_parts[2] == 'clone_models':
|
|
url_parts.append(path_parts[1])
|
|
experiment_fetch_reply = cls.check_experiment_exists(request, url_parts)
|
|
return cls.experiment_store.clone_experiment_models(
|
|
experiment_fetch_reply, request, url_parts
|
|
)
|
|
|
|
else:
|
|
raise get_invalid_path_error(path_parts)
|
|
|
|
# Welp we don't know this
|
|
else:
|
|
raise get_invalid_path_error(path_parts)
|
|
|
|
@classmethod
|
|
def safe_handle_delete(cls, request, path_parts):
|
|
url_parts = []
|
|
# Experiment DELETE request handling
|
|
if len(path_parts) == 2:
|
|
url_parts.append(path_parts[1])
|
|
# Delete history when we delete the experiment
|
|
cls.history_store.delete(request, url_parts)
|
|
return cls.experiment_store.delete(request, url_parts)
|
|
else:
|
|
raise get_invalid_path_error(path_parts)
|
|
|
|
@classmethod
|
|
def handle_get(cls, request, path_parts):
|
|
return capture_exception(cls.safe_handle_get, request, path_parts)
|
|
|
|
@classmethod
|
|
def handle_post(cls, request, path_parts):
|
|
return capture_exception(cls.safe_handle_post, request, path_parts)
|
|
|
|
@classmethod
|
|
def handle_delete(cls, request, path_parts):
|
|
return capture_exception(cls.safe_handle_delete, request, path_parts)
|