1""" This module implements a MongoDB storage back-end adapter. """
5from datetime
import datetime
6from mongoengine
import *
13from databases.mongodb.models.detector
import Detector
14from databases.mongodb.models.detectorWrapper
import DetectorWrapper
15from databases.mongodb.models.condition
import Condition
17from interface
import APIInterface
20__authors__ = [
"Nathan DPenha",
"Juan van der Heijden",
21 "Vladimir Romashov",
"Raha Sadeghi"]
22__copyright__ =
"TU/e ST2019"
24__status__ =
"Prototype"
30 Adapter class for a MongoDB back-end that implements the CDB interface.
33 __db_connection =
None
37 This constructor makes a connection to the MongoDB conditions DB.
39 :param connection_dict: The mongoDB configuration for making the connection
40 to the Conditions Database.
46 Create a connection to a MongoDB server and return the connection handle.
53 db=connection_dict[
'db_name'],
54 username=connection_dict[
'user'],
55 password=connection_dict[
'password'],
56 host=connection_dict[
'host'],
57 port=connection_dict[
'port']
62 Delete the specified database.
64 :param db_name: The name of the DB that needs to be deleted.
70 This method validates if input_string is of string type.
71 If it is not of String type it returns False.
73 :param input_string: value that needs to be tested.
75 if type(input_string) == str:
81 This method validates if input_datetime is of datetime type.
82 If it is not of datetime type it returns False.
84 :param input_datetime: value that needs to be tested.
86 if type(input_datetime) == datetime:
92 This method validates if input_path is a valid path.
93 If it is not of String type it returns False.
95 :param input_path: value that needs to be tested.
97 if type(input_path) == str:
103 This method validates if input_date is a datetime type or string.
104 If yes, it returns True. Otherwise it returns False.
106 :param input_date: It could be String or datetime type.
108 if type(input_date) == datetime
or type(input_date) == str:
114 This method removes spaces at the beginning and at the end of the string and
115 returns the String without spaces.
117 :param input_string: string that will be sanitized.
119 return input_string.strip()
123 This method removes slashes and spaces at the beginning and
124 at the end of the parameter input_path.
126 :param input_path: string that will be sanitized.
129 return input_path.strip(
'/')
133 This method converts a date string to a datetime Object.
135 :param input_date_string: String representing a date
136 Accepted String formats: "Year", "Year-Month", "Year-Month-Day", "Year-Month-Day Hours",
137 "Year-Month-Day Hours-Minutes", "Year-Month-Day Hours-Minutes-Seconds".
138 :throw ValueError: If input_date_string is not as specified.
141 time_stamp_str_format = [
"%Y",
"%Y-%m",
"%Y-%m-%d",
"%Y-%m-%d %H",
"%Y-%m-%d %H:%M",
143 datetime_value =
None
145 for time_stamp_format
in time_stamp_str_format:
147 datetime_value = datetime.strptime(input_date_string, time_stamp_format)
152 if datetime_value
is None:
153 raise ValueError(
"Please pass the correct date input. This date string should "
154 "contain only digits/:/ /-. The minimum length could be 4 digits, "
155 "representing the year. ")
157 return datetime_value
161 Splits the detector_id string using '/' and returns a list of detector names.
162 Otherwise raises an exception if detector_id is not a valid path / id.
164 :param detector_id: path to a detector (e.g. detect_name/subdetector_name/...).
168 return detector_id.split(
'/')
170 raise TypeError(
"The provided detector_id needs to be a valid path")
174 Returns a DetectorWrapper object. Otherwise it raises a
175 ValueError exception if the wrapper_id could not be found.
177 :param wrapper_id: String specifying the ID for the wrapper to be returned.
178 Must be unique. Must not contain a forward slash (i.e. /).
181 raise ValueError(
"Please pass the correct type of the ID for the new detector. "
182 "It must be unique, and it must not contain a forward slash "
189 detector_wrapper = DetectorWrapper.objects().get(name=detector_names[0])
190 return detector_wrapper
193 print (
"The detector wrapper ",
195 " does not exist in the database")
203 Returns a subdetector with name sub_name under the specified parent detector.
205 :param detector: Detector object.
206 :param sub_name: (String) name of the subdetector that should be returned.
209 subdetector = detector.subdetectors.get(name=sub_name)
217 Returns a Detector object identified by detector_id.
218 It raises ValueError if the detector_id could not be found.
220 :param detector_wrapper: DetectorWrapper object that contains a detector tree.
221 :param detector_id: (String) The ID (i.e. path) to the detector that
225 detector = detector_wrapper.detector
228 for i
in range(1, len(detector_names)):
230 path = path +
"/" + detector_names[i]
235 print (
"The detector " +
237 " does not exist in the database")
247 Creates a new DetectorWrapper object and stores it in the DB.
248 Returns this new wrapper or None if a detector with that name
251 :param name: (String) uniquely identifying the wrapper.
253 if not DetectorWrapper.objects(name=name):
261 Removes a detector wrapper and its contents from the database.
263 :param wrapper_id: (String) identifying the wrapper to remove.
269 print (
"The detector '",
271 "' does not exist in the database")
283 detector_wrapper_list = DetectorWrapper.objects.all()
285 for wrapper
in detector_wrapper_list:
286 detector_list.append(str(wrapper.detector.name))
291 raise TypeError(
"Please pass the correct type of input: parent_id, "
292 "parent_id should be of String type")
298 print (
"The detector '",
300 "' does not exist in the database")
309 for subdetector
in detector.subdetectors:
310 detector_list.append(str(path +
"/" + subdetector.name))
316 if detector_id ==
"":
317 raise ValueError(
"Please specify a valid detector id. A detector id cannot be empty.")
320 raise TypeError(
"Please pass the correct type of input: detector_id "
327 raise ValueError(
"The detector '",
329 "' does not exist in the database")
334 raise ValueError(
"The requested detector " + detector_id +
" does not exist.")
337 return loads(detector.to_json())
342 raise TypeError(
"Please pass the correct type of input: name should be String")
345 raise ValueError(
"Please pass the correct value of input: name should not "
346 "be an empty string")
349 raise ValueError(
"The name parameter cannot contain a / ")
355 if parent_id
is None or parent_id
is "":
358 if wrapper
is not None:
361 wrapper.detector = detector
366 print (
"The detector '",name,
"' already exists. Nothing done.")
373 raise TypeError(
"Please pass the correct type of input: parent_id "
382 raise ValueError(
"The detector '",
384 "' does not exist in the database")
389 added_detector.name = name
391 raise ValueError(
"The detector with id '" + parent_id +
"' does not exist")
394 detector.subdetectors.get(name=name)
396 print (
"Detector '",parent_id,
"/",name,
"' already exists. Nothing done.")
399 detector.subdetectors.append(added_detector)
400 detector_wrapper.save()
407 raise TypeError(
"Please pass the correct type of input: detector_id should be String")
409 if detector_id ==
"":
410 raise ValueError(
"Please provide the correct input for detector_id: detector_id "
411 "cannot be an empty String")
419 print (
"The detector '",
421 "' does not exist in the database")
429 if len(detector_names) < 2:
434 print (
"The detector '",
436 "' does not exist in the database")
446 for i
in range(0, len(detector_names) - 1):
447 path = path +
"/" + detector_names[i]
451 subdetectors = detector.subdetectors
454 for i
in range(0, len(subdetectors)):
455 if subdetectors[i].name == detector_names[-1]:
456 detector.subdetectors.pop(i)
463 collected_at=datetime.now(), valid_since=datetime.now(),
464 valid_until=datetime.max):
465 if detector_id ==
"" or name ==
"" or tag ==
"" or values ==
"" or values
is None:
466 raise TypeError(
"Please pass the correct parameters: parameters detector_id, name, "
467 "tag, values should not be empty")
474 raise TypeError(
"Please pass the correct type of input: detector_id, "
475 "tag, and name should be String")
483 "Please pass the correct type of input: valid_since, valid_until and collected_at "
484 "should be either String or datetime object")
488 "Please pass the correct type of input: type should be String")
495 valid_until = valid_until.replace(microsecond=0)
500 valid_since = valid_since.replace(microsecond=0)
505 collected_at = collected_at.replace(microsecond=0)
507 if valid_since > valid_until:
508 raise ValueError(
"Incorrect validity interval")
514 raise ValueError(
"The detector '",
516 "' does not exist in the database")
522 raise ValueError(
"The requested detector '" + detector_id +
"' does not exist.")
526 if condition
is not None:
527 raise ValueError(
"A condition with the same tag '", tag,
"' already exists")
534 condition.name = name
536 condition.values = values
537 condition.type = type
538 condition.collected_at = collected_at
539 condition.valid_until = valid_until
540 condition.valid_since = valid_since
542 detector.conditions.append(condition)
543 detector_wrapper.save()
549 "Please pass the correct type of input: detector_id should be String")
554 raise ValueError(
"The detector '",
556 "' does not exist in the database")
563 print (
"The requested detector '" + detector_id +
"' does not exist.")
570 for condition
in detector.conditions:
572 conditions_list.append(loads(condition.to_json()))
575 return conditions_list
583 raise TypeError(
"Please pass the correct type of input: "
584 "detector_id should be String")
587 raise TypeError(
"Please pass the correct form of input: "
588 "name should be String")
597 raise ValueError(
"The detector '",
599 "' does not exist in the database")
605 raise ValueError(
"The requested detector '" + detector_id +
"' does not exist.")
608 conditions = detector.conditions.filter(name=name)
614 for condition
in conditions:
615 condition_dicts.append(loads(condition.to_json()))
617 return condition_dicts
623 raise TypeError(
"Please pass the correct type of input: "
624 "detector_id should be String")
627 raise TypeError(
"Please pass the correct format of input: "
628 "tag should be String")
637 raise ValueError(
"The detector '",
639 "' does not exist in the database")
645 raise ValueError(
"The requested detector '" + detector_id +
"' does not exist.")
648 conditions = detector.conditions.filter(tag=tag)
654 for condition
in conditions:
655 condition_dicts.append(loads(condition.to_json()))
657 return condition_dicts
663 raise TypeError(
"Please pass the correct type of input: "
664 "detector_id should be String")
669 raise TypeError(
"Please pass the valid input type: name should be String, "
670 "dates could be either datetime or String type.")
679 start_date = start_date.replace(microsecond=0)
683 end_date = end_date.replace(microsecond=0)
686 if end_date
is not None and start_date
is not None:
687 if start_date > end_date:
688 raise ValueError(
"Invalid validity interval")
694 raise ValueError(
"The detector '",
696 "' does not exist in the database")
702 raise ValueError(
"The requested detector '" + detector_id +
"' does not exist.")
705 conditions = detector.conditions.filter(name=name)
709 for condition
in conditions:
711 if condition.valid_since <= start_date <= condition.valid_until:
713 if end_date
is not None:
716 if condition.valid_since <= end_date <= condition.valid_until:
717 result_list.append(condition)
719 result_list.append(condition)
726 for condition
in result_list:
727 condition_dicts.append(loads(condition.to_json()))
729 return condition_dicts
735 raise TypeError(
"Please pass the correct type of input: "
736 "detector_id should be String")
739 raise TypeError(
"Please pass the correct form of input: "
740 "name and tag should be String")
750 raise ValueError(
"The detector '",
752 "' does not exist in the database")
757 raise ValueError(
"The requested detector '" + detector_id +
"' does not exist.")
761 condition = detector.conditions.get(name=name, tag=tag)
766 return loads(condition.to_json())
772 raise TypeError(
"Please pass the correct type of input: "
773 "detector_id should be String")
777 "Please pass the valid input type: name should be String, collected_at could be "
778 "either datetime or String type.")
788 collected_at = collected_at.replace(microsecond=0)
794 raise ValueError(
"The detector '",
796 "' does not exist in the database")
802 raise ValueError(
"The requested detector '" + detector_id +
"' does not exist.")
807 condition = detector.conditions.get(name=name, collected_at=collected_at)
809 return loads(condition.to_json())
815 type=None, valid_since=None, valid_until=None):
818 raise TypeError(
"Please pass the correct type of input: "
819 "detector_id should be String")
827 "Please pass correct form of input: for valid_since and/or valid_until, "
828 "they could be String, datetime or None. Only String is accepted for name, "
836 valid_until = valid_until.replace(microsecond=0)
841 valid_since = valid_since.replace(microsecond=0)
843 if valid_until
is not None and valid_since
is not None:
844 if valid_since > valid_until:
845 raise ValueError(
"Invalid validity interval")
858 raise ValueError(
"The detector '",
860 "' does not exist in the database")
866 raise ValueError(
"The requested detector '" + detector_id +
"' does not exist.")
870 condition = detector.conditions.get(name=name, tag=tag)
872 raise ValueError(
"No condition with this name and tag can be found")
876 condition.type = type
877 if valid_since
is not None:
878 condition.valid_since = valid_since
879 if valid_until
is not None:
880 condition.valid_until = valid_until
882 detector_wrapper.save()
remove_detector(self, detector_id)
Removes a detector from the database.
add_condition(self, detector_id, name, tag, values, type=None, collected_at=datetime.now(), valid_since=datetime.now(), valid_until=datetime.max)
Adds a condition to a detector.
__get_connection(self, connection_dict)
get_condition_by_name_and_tag(self, detector_id, name, tag)
Returns a condition dictionary of a specific condition belonging to a detector, identified by conditi...
get_conditions(self, detector_id)
Returns a list with all condition dictionaries associated with a detector.
get_conditions_by_name_and_validity(self, detector_id, name, start_date, end_date=None)
Returns a list with condition dictionaries associated with a detector that are valid on the specified...
__validate_interval_parameters(self, input_date)
__get_subdetector(self, detector, sub_name)
__split_name(self, detector_id)
__add_wrapper(self, name)
__validate_datetime(self, input_datetime)
__convert_date(self, input_date_string)
__get_wrapper(self, wrapper_id)
__validate_str(self, input_string)
__get_detector(self, detector_wrapper, detector_id)
get_conditions_by_tag(self, detector_id, tag)
Returns a list with condition dictionaries having a specific tag for a given detector.
__validate_path(self, input_path)
get_detector(self, detector_id)
Returns a detector dictionary.
__delete_db(self, db_name)
__init__(self, connection_dict)
__sanitize_str(self, input_string)
get_conditions_by_name(self, detector_id, name)
Returns a list with condition dictionaries having a specific name for a given detector.
update_condition_by_name_and_tag(self, detector_id, name, tag, type=None, valid_since=None, valid_until=None)
Updates the type, valid_since and valid_until values of a specific condition belonging to a detector,...
add_detector(self, name, parent_id=None)
Adds a new detector to the database.
list_detectors(self, parent_id=None)
Returns a list with all the detector names in the database.
__remove_wrapper(self, wrapper_id)
__sanitize_path(self, input_path)
get_condition_by_name_and_collection_date(self, detector_id, name, collected_at)
Returns a condition dictionary of a specific condition belonging to a detector, identified by conditi...
Conditions Database Interface definition.
get_condition_by_name_and_tag(self, detector_id, name, tag)
Returns a condition dictionary of a specific condition belonging to a detector, identified by conditi...