def create_new_roxcomposer_session(timeout : int = ROXCOMPOSER_TIMEOUT): """ Attempt to start a new log session on the ROXcomposer :param services: list of services that should be watched :param timeout: time after which session expires :return: response with data = session dictionary ('id', 'timeout', 'services') """ # There is no session yet, so start a new one. internal_rox_session = dict() internal_rox_session['timeout'] = timeout content = {'lines': 100, 'timeout': timeout} url = get_rox_connector_url("roxcomposer_log_observer") try: r = requests.put(url, headers=JSON_HEADER, json=content) except requests.exceptions.ConnectionError as err: error_msg = _create_connection_error(str(err)) res = RoxResponse(False, error_msg) res.data = None return res if r.status_code != 200: error_msg = _create_http_status_error(r.status_code, r.text) res = RoxResponse(False, error_msg) res.data = None return res # request successful, create a session dictionary internal_rox_session['id'] = r.json()['sessionid'] res = RoxResponse(True, r.text) res.data = internal_rox_session return res
def watch_services(service_names: list, rox_session: dict = None, timeout: int = SESSION_TIMEOUT) -> RoxResponse: """ Add specified services to given sessions watchlist. :param service_names: List of service names which should be watched. :param rox_session: A dictionary with an ID, a timeout and a set of services which are currently watched. :param timeout: Timeout (in seconds) after which given services are no longer watched. :return: RoxResponse instance documenting if services could be added to watchlist. """ url = get_rox_connector_url("log_observer") if rox_session == {}: # session is empty return create_new_sess(service_names, timeout) else: # Session already exists, so update it. unwatched_services = list( set(service_names) - set(rox_session['services'])) if unwatched_services: # There are services which should be added to watchlist. content = { 'sessionid': rox_session['id'], 'services': unwatched_services } try: r = requests.post(url, headers=JSON_HEADER, json=content) except requests.exceptions.ConnectionError as err: error_msg = _create_connection_error(str(err)) res = RoxResponse(False, error_msg) res.data = rox_session return res # session could be expired, create a new session if r.status_code != 200: error_msg = _create_http_status_error(r.status_code, r.text) res = RoxResponse(False, error_msg) res2 = create_new_sess(service_names, timeout) res2.message = res.message return res2 response = r.json() rox_session['services'] = set(rox_session['services']) for s in response['ok']: rox_session['services'].add( s ) # add the services that could be watched to the session dictionary rox_session['services'] = list(rox_session['services']) res = RoxResponse(True, r.text) res.data = rox_session return res # return the session dictionary else: # All specified services are already watched. return RoxResponse(False, "All services are already watched.")
def post_to_pipeline(pipeline_name: str, message: str) -> RoxResponse: """ Post message to specified pipeline. :param pipeline_name: Pipeline name to which a message should be sent. :param message: Message as string. :return: RoxResponse instance documenting if data could be posted to pipeline. """ url = get_rox_connector_url("post_to_pipeline") content = {'name': pipeline_name, 'data': message} try: r = requests.post(url, data=json.dumps(content), headers=JSON_HEADER) except requests.exceptions.ConnectionError as err: error_msg = _create_connection_error(str(err)) return RoxResponse(False, error_msg) if r.status_code != 200: error_msg = _create_http_status_error(r.status_code, r.text) return RoxResponse(False, error_msg) else: result_msg = "Message {} posted: {}.".format(r.json()['message_id'], message) res = RoxResponse(True, result_msg) res.data = r.json()['message_id'] return res
def create_pipeline(pipe_name: str, service_names: list) -> RoxResponse: """ Create new pipeline with specified services in exactly the given order. :param pipe_name: Name of pipeline. :param service_names: A list of service names. The services are applied in the same order as they appear in this list. :returns: RoxResponse instance documenting if pipeline could be created. """ url = get_rox_connector_url("set_pipeline") content = {'name': pipe_name, 'services': service_names} try: r = requests.post(url, data=json.dumps(content), headers=JSON_HEADER) except requests.exceptions.ConnectionError as err: error_msg = _create_connection_error(str(err)) return RoxResponse(False, error_msg) if r.status_code != 200: error_msg = _create_http_status_error(r.status_code, r.text) return RoxResponse(False, error_msg) else: running_service_names = list(r.json().keys()) running_service_names = [x for x in running_service_names if x not in FORBIDDEN_SERVICES] res = RoxResponse(True) res.data = running_service_names return res
def get_message_history(message_id: str) -> RoxResponse: """ Get history of specified message ID. :param message_id: Message ID. :return: RoxResponse instance with corresponding message history (if available). """ if not message_id: return RoxResponse(False, "No message ID provided.") content = {'message_id': message_id} url = get_rox_connector_url("get_msg_history") try: r = requests.post(url, data=json.dumps(content), headers=JSON_HEADER) except requests.exceptions.ConnectionError as err: error_msg = _create_connection_error(str(err)) return RoxResponse(False, error_msg) if r.status_code != 200: error_msg = _create_http_status_error(r.status_code, r.text) return RoxResponse(False, error_msg) else: history = r.json() res = RoxResponse(True) res.data = history return res
def get_pipelines() -> RoxResponse: """ Get metadata of each available pipeline, i.e. pipeline name, involved services and current status. :returns: oxResponse instance containing a list of tuples mapping each pipeline name to its corresponding JSON data. """ url = get_rox_connector_url("pipelines") try: r = requests.get(url) except requests.exceptions.ConnectionError as err: error_msg = _create_connection_error(str(err)) return RoxResponse(True, error_msg) if r.status_code != 200: error_msg = _create_http_status_error(r.status_code, r.text) return RoxResponse(False, error_msg) else: pipelines = {} for key, value in r.json().items(): pipelines[key] = value res = RoxResponse(True) res.data = pipelines return res
def get_service_logs(rox_session: dict): """ Retrieve the newest log data from the ROXcomposer. :param rox_session: a dictionary containing the information on the current session with the ROXcomposer for instance the session ID, or which services are being watched. :return: RoxResponse with a list of the newest log lines as data, where each line is an element of the list """ if rox_session is None: error_msg = "Trying to get logs, but no session instantiated." return RoxResponse(False, error_msg) url = get_rox_connector_url("log_observer") content = {'sessionid': rox_session['id']} try: r = requests.get(url, headers=JSON_HEADER, json=content) except requests.exceptions.ConnectionError as err: error_msg = _create_connection_error(str(err)) return RoxResponse(False, error_msg) if r.status_code != 200: error_msg = _create_http_status_error(r.status_code, r.text) return RoxResponse(False, error_msg) logs = [] try: logs = [json.loads(logline) for logline in r.json()['loglines']] except json.JSONDecodeError: pass res = RoxResponse(True, r.text) res.data = logs return res
def unwatch_services(service_names: list, rox_session: dict) -> RoxResponse: """ The specified services are removed from the watchlist and logs concerning these services will no longer be sent from the server. :param service_names: a list of service names of services that should no longer be watched :param rox_session: a dictionary containing the information on the current session with the ROXcomposer for instance the session ID, or which services are being watched. :return: RoxResponse with the new or updated session dict as data """ if len(service_names) < 1: return RoxResponse(False, "No services specified.") if rox_session == {}: return RoxResponse(False, "No session specified.") s = list(filter(lambda service: service in rox_session['services'], service_names)) if len(s) == 0: return RoxResponse(False, "The specified services are not being watched.") data = {'sessionid': rox_session['id'], 'services': s} try: r = requests.delete(get_rox_connector_url('log_observer'), headers=JSON_HEADER, json=data) except requests.exceptions.ConnectionError as err: error_msg = _create_connection_error(str(err)) return RoxResponse(False, error_msg) if r.status_code != 200: error_msg = _create_http_status_error(r.status_code, r.text) return RoxResponse(False, error_msg) else: rox_session['services'] = list(set(rox_session['services']).difference(set(s))) res = RoxResponse(True, "Services no longer watched: {}.".format(s)) res.data = rox_session return res
def create_new_sess(services: list, timeout: int = SESSION_TIMEOUT) -> RoxResponse: """ Attempt to start a new log session on the ROXcomposer :param services: list of services that should be watched :param timeout: time after which session expires :return: response with data = session dictionary ('id', 'timeout', 'services') """ # There is no session yet, so start a new one. rox_session = dict() rox_session['services'] = set() rox_session['timeout'] = timeout content = {'lines': 100, 'timeout': timeout, 'services': services} url = get_rox_connector_url("log_observer") try: r = requests.put(url, headers=JSON_HEADER, json=content) except requests.exceptions.ConnectionError as err: error_msg = _create_connection_error(str(err)) res = RoxResponse(False, error_msg) res.data = None return res if r.status_code != 200: error_msg = _create_http_status_error(r.status_code, r.text) res = RoxResponse(False, error_msg) res.data = None return res # request successful, create a session dictionary rox_session['id'] = r.json()['sessionid'] for s in r.json()['ok']: rox_session['services'].add(s) rox_session['services'] = list(rox_session['services']) # convert to list res = RoxResponse(True, r.text) res.data = rox_session return res
def get_running_services() -> RoxResponse: """ Get Names of all currently running services :return: List of service names """ res = get_running_service_jsons() service_names = {} for service in res.data: service_names[service] = service r = RoxResponse(res.success, res.message) r.data = service_names return r
def save_session(file_name: str) -> RoxResponse: """ Save current session to specified file. :param file_name: File name. :return: RoxResponse instance documenting if session could be saved. """ roxsession_path = LOCAL_SETTINGS[SESSION_DIR] # clear all old roxsessions for the_file in os.listdir(roxsession_path): file_path = os.path.join(roxsession_path, the_file) try: if os.path.isfile(file_path): os.unlink(file_path) except Exception as e: print(e) file_path = os.path.join(roxsession_path, file_name) try: fd = open(file_path, 'w') except OSError as err: error_msg = _create_file_error(file_path, str(err)) return RoxResponse(False, error_msg) url = get_rox_connector_url("dump_services_and_pipelines") try: r = requests.get(url) except requests.exceptions.ConnectionError as err: error_msg = _create_connection_error(str(err)) return RoxResponse(False, error_msg) if r.status_code == 200: o = r.json() try: json.dump(o, fd) except Exception as err: error_msg = _create_file_error(file_path, str(err)) return RoxResponse(False, error_msg) finally: fd.close() res = RoxResponse( True, "Wrote session to file {}.\n{}.".format(file_path, r.text)) res.data = {"filepath": file_path, "filename": file_name} return res else: fd.close() error_msg = _create_http_status_error(r.status_code, r.text) return RoxResponse(False, error_msg)
def convert_to_service_json_list(service_name_list: list) -> RoxResponse: """ Convert list of service names to corresponding list of JSON dictionaries. :param service_name_list: List of service names. :return: RoxResponse instance containing a list of corresponding JSON dictionaries. Service names which could not be converted to JSON structure are included as error_data attribute. """ valid_service_jsons = [] invalid_service_names = [] for name in service_name_list: res = convert_to_service_json(name) if res.success: valid_service_jsons.append(res.data) else: invalid_service_names.append(name) res = RoxResponse(True) res.data = valid_service_jsons res.error_data = invalid_service_names return res
def get_running_service_jsons() -> RoxResponse: """ Get JSON data of all currently running services ignoring those specified in FORBIDDEN_SERVICES. :return: RoxResponse instance containing a list of all currently running services. """ url = get_rox_connector_url("services") try: r = requests.get(url) except requests.exceptions.ConnectionError as err: error_msg = _create_connection_error(str(err)) return RoxResponse(False, error_msg) if r.status_code != 200: error_msg = _create_http_status_error(r.status_code, r.text) return RoxResponse(False, error_msg) else: res = RoxResponse(True) res.data = dict((key, value) for (key, value) in r.json().items() if key not in FORBIDDEN_SERVICES) return res
def get_logsession(rox_session: dict): """ Retrieve the information to a specific logsession :param rox_session: contains id of logsession :return: RoxResponse with session information. Contains success = False if no logsession """ url = get_rox_connector_url("get_logsession") content = {'id': rox_session['id']} try: r = requests.post(url, headers=JSON_HEADER, json=content) except requests.exceptions.ConnectionError as err: error_msg = _create_connection_error(str(err)) return RoxResponse(False, error_msg) if r.status_code != 200: error_msg = _create_http_status_error(r.status_code, r.text) return RoxResponse(False, error_msg) if r.json() == {}: return RoxResponse(False, "No session with that ID") res = RoxResponse(True, r.text) res.data = r.json() return res
def get_local_services() -> RoxResponse: """ Get locally stored services and provide them as dictionary mapping service name to its JSON instance. Provide list of invalid services as RoxResponse's error data parameter. :return: RoxResponse instance containing a dictionary mapping each service name to its corresponding JSON instance Provide list of invalid services as error data parameter. """ valid_services = {} invalid_services = [] success = True for f in os.scandir(LOCAL_SETTINGS[SERVICE_DIR]): if f.is_file() and f.name.endswith(".json"): fd = None service_name = None try: fd = open(os.path.join(LOCAL_SETTINGS[SERVICE_DIR], f.name), 'r') service_name = f.name[:-5] service_json = json.load(fd) valid_services[service_name] = service_json except (OSError, json.decoder.JSONDecodeError): success = False if service_name: invalid_services.append(service_name) finally: if fd: fd.close() res = RoxResponse(success) res.data = valid_services res.error_data = invalid_services return res
def check() -> JsonResponse: """ Check function that does not require HTTP request. Check if parameters specified in config.ini file are valid. :return: RoxResponse - Indicate if parameters in config.ini file are valid. """ result = dict() success = True # Check ROXconnector URL. url = rox_request.get_rox_connector_url() res_url = check_rox_connector_url(url) if res_url.success: result["running"] = res_url.success result["ip_set"] = res_url.success result["port_set"] = res_url.success domain = url.strip("http://").strip("https://") if len(domain.split(":")) > 1: port = domain.split(":")[-1] ip = domain.split(":")[0] else: port = domain.split("/")[-1] ip = domain.split("/")[0] result["ip"] = ip result["port"] = port if not res_url.success: res_url.data = result return JsonResponse(res_url.convert_to_json()) response = RoxResponse(success) response.data = result return JsonResponse(response.convert_to_json())
def convert_to_service_json(service_name: str) -> RoxResponse: """ Convert service name to corresponding JSON dictionary. :param service_name: Service name. :return: RoxResponse instance containing corresponding JSON dictionary. """ fd = None name_with_ext = service_name + ".json" try: fd = open(os.path.join(LOCAL_SETTINGS[SERVICE_DIR], name_with_ext)) json_data = json.load(fd) except OSError: error_msg = "Could not open JSON file for service {}.".format( service_name) return RoxResponse(False, error_msg) except json.JSONDecodeError: error_msg = "JSON data for service {} is invalid.".format(service_name) return RoxResponse(False, error_msg) finally: if fd is not None: fd.close() res = RoxResponse(True) res.data = json_data return res