SND@LHC Software
Loading...
Searching...
No Matches
mongodbadapter.py
Go to the documentation of this file.
1""" This module implements a MongoDB storage back-end adapter. """
2import sys
3
4from json import loads
5from datetime import datetime
6from mongoengine import *
7
11
12#evh add databases.mongodb.
13from databases.mongodb.models.detector import Detector
14from databases.mongodb.models.detectorWrapper import DetectorWrapper
15from databases.mongodb.models.condition import Condition
16#from ...interface import APIInterface
17from interface import APIInterface
18
19# Package metadata
20__authors__ = ["Nathan DPenha", "Juan van der Heijden",
21 "Vladimir Romashov", "Raha Sadeghi"]
22__copyright__ = "TU/e ST2019"
23__version__ = "1.0"
24__status__ = "Prototype"
25
26
27#TODO uncomment for python >= 3.8: @final
29 """
30 Adapter class for a MongoDB back-end that implements the CDB interface.
31 """
32 # Holds the connection handle to the database
33 __db_connection = None
34
35 def __init__(self, connection_dict):
36 """
37 This constructor makes a connection to the MongoDB conditions DB.
38
39 :param connection_dict: The mongoDB configuration for making the connection
40 to the Conditions Database.
41 """
42 self.__db_connection = self.__get_connection(connection_dict)
43
44 def __get_connection(self, connection_dict):
45 """
46 Create a connection to a MongoDB server and return the connection handle.
47 """
48 #evh added printout
49 #print ('***********')
50 #print ("db=",connection_dict['db_name']," username=",connection_dict['user']," host=",connection_dict['host'])
51 #print ('***********')
52 return connect(
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']
58 )
59
60 def __delete_db(self, db_name):
61 """
62 Delete the specified database.
63
64 :param db_name: The name of the DB that needs to be deleted.
65 """
66 self.__db_connection.drop_database(db_name)
67
68 def __validate_str(self, input_string):
69 """
70 This method validates if input_string is of string type.
71 If it is not of String type it returns False.
72
73 :param input_string: value that needs to be tested.
74 """
75 if type(input_string) == str:
76 return True
77 return False
78
79 def __validate_datetime(self, input_datetime):
80 """
81 This method validates if input_datetime is of datetime type.
82 If it is not of datetime type it returns False.
83
84 :param input_datetime: value that needs to be tested.
85 """
86 if type(input_datetime) == datetime:
87 return True
88 return False
89
90 def __validate_path(self, input_path):
91 """
92 This method validates if input_path is a valid path.
93 If it is not of String type it returns False.
94
95 :param input_path: value that needs to be tested.
96 """
97 if type(input_path) == str:
98 return True
99 return False
100
101 def __validate_interval_parameters(self, input_date):
102 """
103 This method validates if input_date is a datetime type or string.
104 If yes, it returns True. Otherwise it returns False.
105
106 :param input_date: It could be String or datetime type.
107 """
108 if type(input_date) == datetime or type(input_date) == str:
109 return True
110 return False
111
112 def __sanitize_str(self, input_string):
113 """
114 This method removes spaces at the beginning and at the end of the string and
115 returns the String without spaces.
116
117 :param input_string: string that will be sanitized.
118 """
119 return input_string.strip()
120
121 def __sanitize_path(self, input_path):
122 """
123 This method removes slashes and spaces at the beginning and
124 at the end of the parameter input_path.
125
126 :param input_path: string that will be sanitized.
127 """
128 input_path = self.__sanitize_str(input_path)
129 return input_path.strip('/')
130
131 def __convert_date(self, input_date_string):
132 """
133 This method converts a date string to a datetime Object.
134
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.
139 """
140 # Accepted formats for input_date_string
141 time_stamp_str_format = ["%Y", "%Y-%m", "%Y-%m-%d", "%Y-%m-%d %H", "%Y-%m-%d %H:%M",
142 "%Y-%m-%d %H:%M:%S"]
143 datetime_value = None
144
145 for time_stamp_format in time_stamp_str_format:
146 try:
147 datetime_value = datetime.strptime(input_date_string, time_stamp_format)
148 break
149 except ValueError:
150 pass
151
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. ")
156 else:
157 return datetime_value
158
159 def __split_name(self, detector_id):
160 """
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.
163
164 :param detector_id: path to a detector (e.g. detect_name/subdetector_name/...).
165 """
166 if self.__validate_path(detector_id):
167 detector_id = self.__sanitize_path(detector_id)
168 return detector_id.split('/')
169 else:
170 raise TypeError("The provided detector_id needs to be a valid path")
171
172 def __get_wrapper(self, wrapper_id):
173 """
174 Returns a DetectorWrapper object. Otherwise it raises a
175 ValueError exception if the wrapper_id could not be found.
176
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. /).
179 """
180 if not self.__validate_str(wrapper_id):
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 "
183 "(i.e. /)")
184
185 wrapper_id = self.__sanitize_path(wrapper_id)
186 detector_names = self.__split_name(wrapper_id)
187
188 try:
189 detector_wrapper = DetectorWrapper.objects().get(name=detector_names[0])
190 return detector_wrapper
191 except:
192 #evh
193 print ("The detector wrapper ",
194 detector_names[0],
195 " does not exist in the database")
196 pass
197 #raise ValueError("The detector wrapper ",
198 # detector_names[0],
199 # " does not exist in the database")
200
201 def __get_subdetector(self, detector, sub_name):
202 """
203 Returns a subdetector with name sub_name under the specified parent detector.
204
205 :param detector: Detector object.
206 :param sub_name: (String) name of the subdetector that should be returned.
207 """
208 try:
209 subdetector = detector.subdetectors.get(name=sub_name)
210 except:
211 return None
212
213 return subdetector
214
215 def __get_detector(self, detector_wrapper, detector_id):
216 """
217 Returns a Detector object identified by detector_id.
218 It raises ValueError if the detector_id could not be found.
219
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
222 must be retrieved.
223 """
224 detector_names = self.__split_name(detector_id)
225 detector = detector_wrapper.detector
226 path = ""
227
228 for i in range(1, len(detector_names)):
229 detector = self.__get_subdetector(detector, detector_names[i])
230 path = path + "/" + detector_names[i]
231
232 if detector is None:
233 path = self.__sanitize_path(path)
234 #evh
235 print ("The detector " +
236 path +
237 " does not exist in the database")
238 pass
239 #raise ValueError("The detector " +
240 # path +
241 # " does not exist in the database")
242
243 return detector
244
245 def __add_wrapper(self, name):
246 """
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
249 already exists.
250
251 :param name: (String) uniquely identifying the wrapper.
252 """
253 if not DetectorWrapper.objects(name=name):
254 wrapper = DetectorWrapper()
255 wrapper.name = name
256 wrapper.save()
257 return wrapper
258
259 def __remove_wrapper(self, wrapper_id):
260 """
261 Removes a detector wrapper and its contents from the database.
262
263 :param wrapper_id: (String) identifying the wrapper to remove.
264 """
265 try:
266 wrapper = self.__get_wrapper(wrapper_id)
267 except Exception:
268 #evh
269 print ("The detector '",
270 wrapper_id,
271 "' does not exist in the database")
272 pass
273 #raise ValueError("The detector '",
274 # wrapper_id,
275 # "' does not exist in the database")
276 wrapper.delete()
277
278 # Method signature description can be found in the toplevel interface.py file
279 def list_detectors(self, parent_id=None):
280 detector_list = []
281
282 if not parent_id:
283 detector_wrapper_list = DetectorWrapper.objects.all()
284
285 for wrapper in detector_wrapper_list:
286 detector_list.append(str(wrapper.detector.name))
287
288 # This executes when a particular parent_id is provided.
289 else:
290 if not self.__validate_path(parent_id):
291 raise TypeError("Please pass the correct type of input: parent_id, "
292 "parent_id should be of String type")
293
294 try:
295 wrapper = self.__get_wrapper(parent_id)
296 except Exception:
297 #evh
298 print ("The detector '",
299 parent_id,
300 "' does not exist in the database")
301 pass
302 #raise ValueError("The detector '",
303 # parent_id,
304 # "' does not exist in the database")
305
306 detector = self.__get_detector(wrapper, parent_id)
307 path = self.__sanitize_path(parent_id)
308
309 for subdetector in detector.subdetectors:
310 detector_list.append(str(path + "/" + subdetector.name))
311
312 return detector_list
313
314 # Method signature description can be found in the toplevel interface.py file
315 def get_detector(self, detector_id):
316 if detector_id == "":
317 raise ValueError("Please specify a valid detector id. A detector id cannot be empty.")
318
319 if not self.__validate_str(detector_id):
320 raise TypeError("Please pass the correct type of input: detector_id "
321 "should be String")
322
323 detector_id = self.__sanitize_path(detector_id)
324 try:
325 detector_wrapper = self.__get_wrapper(detector_id)
326 except Exception:
327 raise ValueError("The detector '",
328 detector_id,
329 "' does not exist in the database")
330
331 try:
332 detector = self.__get_detector(detector_wrapper, detector_id)
333 except Exception:
334 raise ValueError("The requested detector " + detector_id + " does not exist.")
335
336 # Convert the internal Detector object to a generic Python dict type
337 return loads(detector.to_json())
338
339 # Method signature description can be found in the toplevel interface.py file
340 def add_detector(self, name, parent_id=None):
341 if not self.__validate_str(name):
342 raise TypeError("Please pass the correct type of input: name should be String")
343 # Detector names cannot be empty string
344 if name == "":
345 raise ValueError("Please pass the correct value of input: name should not "
346 "be an empty string")
347 # If a / is in the name parameter we raise ValueError Exception
348 if '/' in name:
349 raise ValueError("The name parameter cannot contain a / ")
350
351 # Remove any unwanted symbols from the name
352 name = self.__sanitize_str(name)
353
354 # This executes when trying to add a root level detector and wrapper
355 if parent_id is None or parent_id is "":
356 wrapper = self.__add_wrapper(name)
357
358 if wrapper is not None:
359 detector = Detector()
360 detector.name = name
361 wrapper.detector = detector
362 wrapper.save()
363 # If the wrapper already exist throw an error
364 else:
365 # evh. should not crash when detector already exists
366 print ("The detector '",name,"' already exists. Nothing done.")
367 pass
368 #raise ValueError("The detector '" + name + "' already exists")
369
370 # If we add a subdetector
371 else:
372 if not self.__validate_path(parent_id):
373 raise TypeError("Please pass the correct type of input: parent_id "
374 "should be String")
375
376 parent_id = self.__sanitize_path(parent_id)
377 detector_names = self.__split_name(parent_id)
378
379 try:
380 detector_wrapper = self.__get_wrapper(detector_names[0])
381 except Exception:
382 raise ValueError("The detector '",
383 detector_names[0],
384 "' does not exist in the database")
385
386 try:
387 detector = self.__get_detector(detector_wrapper, parent_id)
388 added_detector = Detector()
389 added_detector.name = name
390 except Exception:
391 raise ValueError("The detector with id '" + parent_id + "' does not exist")
392
393 try:
394 detector.subdetectors.get(name=name)
395 #evh added this. should not crash if detector already exists.
396 print ("Detector '",parent_id,"/",name,"' already exists. Nothing done.")
397 pass
398 except:
399 detector.subdetectors.append(added_detector)
400 detector_wrapper.save()
401 return
402 #raise ValueError("Detector '" + parent_id + "/" + name + "' already exist")
403
404 # Method signature description can be found in the toplevel interface.py file
405 def remove_detector(self, detector_id):
406 if not self.__validate_str(detector_id):
407 raise TypeError("Please pass the correct type of input: detector_id should be String")
408
409 if detector_id == "":
410 raise ValueError("Please provide the correct input for detector_id: detector_id "
411 "cannot be an empty String")
412
413 detector_id = self.__sanitize_path(detector_id)
414
415 try:
416 wrapper = self.__get_wrapper(detector_id)
417 except Exception:
418 #evh
419 print ("The detector '",
420 detector_id,
421 "' does not exist in the database")
422 pass
423 #raise ValueError("The detector '",
424 # detector_id,
425 # "' does not exist in the database")
426
427 detector_names = self.__split_name(detector_id)
428 # If we want to remove a root detector
429 if len(detector_names) < 2:
430 try:
431 self.__remove_wrapper(detector_names[0])
432 except Exception:
433 #evh
434 print ("The detector '",
435 detector_names[0],
436 "' does not exist in the database")
437 pass
438 #raise ValueError("The detector '",
439 # detector_names[0],
440 # "' does not exist in the database")
441 return
442
443 # Otherwise, when we remove a subdetector
444 path = ""
445
446 for i in range(0, len(detector_names) - 1):
447 path = path + "/" + detector_names[i]
448
449 path = self.__sanitize_path(path)
450 detector = self.__get_detector(wrapper, path)
451 subdetectors = detector.subdetectors
452
453 # Find the subdetector and remove it from the list
454 for i in range(0, len(subdetectors)):
455 if subdetectors[i].name == detector_names[-1]:
456 detector.subdetectors.pop(i)
457 break
458
459 wrapper.save()
460
461 # Method signature description can be found in the toplevel interface.py file
462 def add_condition(self, detector_id, name, tag, values, type=None,
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")
468
469 if not (
470 self.__validate_path(detector_id)
471 and self.__validate_str(tag)
472 and self.__validate_str(name)
473 ):
474 raise TypeError("Please pass the correct type of input: detector_id, "
475 "tag, and name should be String")
476
477 if not (
478 (self.__validate_interval_parameters(valid_since) or valid_since is None)
479 and (self.__validate_interval_parameters(valid_until) or valid_until is None)
480 and (self.__validate_interval_parameters(collected_at) or collected_at is None)
481 ):
482 raise TypeError(
483 "Please pass the correct type of input: valid_since, valid_until and collected_at "
484 "should be either String or datetime object")
485
486 if not self.__validate_str(type) and type != None:
487 raise TypeError(
488 "Please pass the correct type of input: type should be String")
489
490 # Converting all dates given as a String to a datetime object
491 if self.__validate_str(valid_until):
492 valid_until = self.__convert_date(valid_until)
493 elif self.__validate_datetime(valid_until):
494 # Strip off the microseconds
495 valid_until = valid_until.replace(microsecond=0)
496 if self.__validate_str(valid_since):
497 valid_since = self.__convert_date(valid_since)
498 elif self.__validate_datetime(valid_since):
499 # Strip off the microseconds
500 valid_since = valid_since.replace(microsecond=0)
501 if self.__validate_str(collected_at):
502 collected_at = self.__convert_date(collected_at)
503 elif self.__validate_datetime(collected_at):
504 # Strip off the microseconds
505 collected_at = collected_at.replace(microsecond=0)
506
507 if valid_since > valid_until:
508 raise ValueError("Incorrect validity interval")
509
510 # Get the detector with the specified detector_id
511 try:
512 detector_wrapper = self.__get_wrapper(detector_id)
513 except Exception:
514 raise ValueError("The detector '",
515 detector_id,
516 "' does not exist in the database")
517
518 detector = None
519 try:
520 detector = self.__get_detector(detector_wrapper, detector_id)
521 except Exception:
522 raise ValueError("The requested detector '" + detector_id + "' does not exist.")
523
524 # Check if this condition already exists in the database
525 condition = self.get_condition_by_name_and_tagget_condition_by_name_and_tag(detector_id, name, tag)
526 if condition is not None:
527 raise ValueError("A condition with the same tag '", tag, "' already exists")
528
529 name = self.__sanitize_str(name)
530 tag = self.__sanitize_str(tag)
531
532 # Create a new condition and associate it to the detector
533 condition = Condition()
534 condition.name = name
535 condition.tag = tag
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
541
542 detector.conditions.append(condition)
543 detector_wrapper.save()
544
545 # Method signature description can be found in the toplevel interface.py file
546 def get_conditions(self, detector_id):
547 if not self.__validate_str(detector_id):
548 raise TypeError(
549 "Please pass the correct type of input: detector_id should be String")
550
551 try:
552 detector_wrapper = self.__get_wrapper(detector_id)
553 except Exception:
554 raise ValueError("The detector '",
555 detector_id,
556 "' does not exist in the database")
557
558 detector = None
559 try:
560 detector = self.__get_detector(detector_wrapper, detector_id)
561 except Exception:
562 #evh
563 print ("The requested detector '" + detector_id + "' does not exist.")
564 return None
565 #raise ValueError("The requested detector '" + detector_id + "' does not exist.")
566
567 conditions_list = []
568
569 # Iterate over all conditions in the detector and append to conditions_list
570 for condition in detector.conditions:
571 # Convert the internal Condition object(s) to a generic Python dict type
572 conditions_list.append(loads(condition.to_json()))
573
574 if conditions_list:
575 return conditions_list
576 else:
577 return None
578
579 # Method signature description can be found in the toplevel interface.py file
580 def get_conditions_by_name(self, detector_id, name):
581 # Input validation
582 if not self.__validate_str(detector_id):
583 raise TypeError("Please pass the correct type of input: "
584 "detector_id should be String")
585
586 if not self.__validate_str(name):
587 raise TypeError("Please pass the correct form of input: "
588 "name should be String")
589
590 # Input sanitization
591 name = self.__sanitize_str(name)
592
593 # Get the detector of the specified detector_id
594 try:
595 detector_wrapper = self.__get_wrapper(detector_id)
596 except Exception:
597 raise ValueError("The detector '",
598 detector_id,
599 "' does not exist in the database")
600
601 detector = None
602 try:
603 detector = self.__get_detector(detector_wrapper, detector_id)
604 except Exception:
605 raise ValueError("The requested detector '" + detector_id + "' does not exist.")
606
607 # Query the condition where the 'name' equals the specified name
608 conditions = detector.conditions.filter(name=name)
609 if not conditions:
610 return None
611
612 # Convert the internal Condition object(s) to a generic Python dict type
613 condition_dicts = []
614 for condition in conditions:
615 condition_dicts.append(loads(condition.to_json()))
616
617 return condition_dicts
618
619 # Method signature description can be found in the toplevel interface.py file
620 def get_conditions_by_tag(self, detector_id, tag):
621 # Input validation
622 if not self.__validate_str(detector_id):
623 raise TypeError("Please pass the correct type of input: "
624 "detector_id should be String")
625
626 if not self.__validate_str(tag):
627 raise TypeError("Please pass the correct format of input: "
628 "tag should be String")
629
630 # Input sanitization
631 tag = self.__sanitize_str(tag)
632
633 # Get the detector of the specified detector_id
634 try:
635 detector_wrapper = self.__get_wrapper(detector_id)
636 except Exception:
637 raise ValueError("The detector '",
638 detector_id,
639 "' does not exist in the database")
640
641 detector = None
642 try:
643 detector = self.__get_detector(detector_wrapper, detector_id)
644 except Exception:
645 raise ValueError("The requested detector '" + detector_id + "' does not exist.")
646
647 # Query the condition where the 'tag' equals the specified tag
648 conditions = detector.conditions.filter(tag=tag)
649 if not conditions:
650 return None
651
652 # Convert the internal Condition object(s) to a generic Python dict type
653 condition_dicts = []
654 for condition in conditions:
655 condition_dicts.append(loads(condition.to_json()))
656
657 return condition_dicts
658
659 # Method signature description can be found in the toplevel interface.py file
660 def get_conditions_by_name_and_validity(self, detector_id, name, start_date, end_date=None):
661 # Input validation
662 if not self.__validate_str(detector_id):
663 raise TypeError("Please pass the correct type of input: "
664 "detector_id should be String")
665
666 if not (self.__validate_str(name) and
667 self.__validate_interval_parameters(start_date) and
668 (self.__validate_interval_parameters(end_date) or end_date is None)):
669 raise TypeError("Please pass the valid input type: name should be String, "
670 "dates could be either datetime or String type.")
671
672 # Input sanitization
673 name = self.__sanitize_str(name)
674
675 # Converting all dates given as a String to a datetime object
676 if self.__validate_str(start_date):
677 start_date = self.__convert_date(start_date)
678 elif self.__validate_datetime(start_date):
679 start_date = start_date.replace(microsecond=0) # Strip off the microseconds
680 if self.__validate_str(end_date):
681 end_date = self.__convert_date(end_date)
682 elif self.__validate_datetime(end_date):
683 end_date = end_date.replace(microsecond=0) # Strip off the microseconds
684
685 # Check for a valid interval
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")
689
690 # Get the detector of the specified detector_id
691 try:
692 detector_wrapper = self.__get_wrapper(detector_id)
693 except Exception:
694 raise ValueError("The detector '",
695 detector_id,
696 "' does not exist in the database")
697
698 detector = None
699 try:
700 detector = self.__get_detector(detector_wrapper, detector_id)
701 except Exception:
702 raise ValueError("The requested detector '" + detector_id + "' does not exist.")
703
704 # Query the condition where the 'name' equals the specified name
705 conditions = detector.conditions.filter(name=name)
706
707 # Loop over all conditions and check whether they are valid within the specified range
708 result_list = []
709 for condition in conditions:
710 # Check if start_date is within the condition validation range
711 if condition.valid_since <= start_date <= condition.valid_until:
712 # Check if end_date is set
713 if end_date is not None:
714 # If end_date is specified it should also be within the condition
715 # validation range
716 if condition.valid_since <= end_date <= condition.valid_until:
717 result_list.append(condition)
718 else:
719 result_list.append(condition)
720
721 if not result_list:
722 return None
723
724 # Convert the internal Condition object(s) to a generic Python dict type
725 condition_dicts = []
726 for condition in result_list:
727 condition_dicts.append(loads(condition.to_json()))
728
729 return condition_dicts
730
731 # Method signature description can be found in the toplevel interface.py file
732 def get_condition_by_name_and_tag(self, detector_id, name, tag):
733 # Input validation
734 if not self.__validate_str(detector_id):
735 raise TypeError("Please pass the correct type of input: "
736 "detector_id should be String")
737
738 if not (self.__validate_str(name) and self.__validate_str(tag)):
739 raise TypeError("Please pass the correct form of input: "
740 "name and tag should be String")
741
742 # Input sanitization
743 name = self.__sanitize_str(name)
744 tag = self.__sanitize_str(tag)
745
746 # Get the detector of the specified detector_id
747 try:
748 detector_wrapper = self.__get_wrapper(detector_id)
749 except Exception:
750 raise ValueError("The detector '",
751 detector_id,
752 "' does not exist in the database")
753
754 try:
755 detector = self.__get_detector(detector_wrapper, detector_id)
756 except Exception:
757 raise ValueError("The requested detector '" + detector_id + "' does not exist.")
758
759 # Query the condition where the 'name' and 'tag' equal the specified name and tag
760 try:
761 condition = detector.conditions.get(name=name, tag=tag)
762 except DoesNotExist:
763 return None
764
765 # Convert the internal Condition object to a generic Python dict type
766 return loads(condition.to_json())
767
768 # Method signature description can be found in the toplevel interface.py file
769 def get_condition_by_name_and_collection_date(self, detector_id, name, collected_at):
770 # Input validation
771 if not self.__validate_str(detector_id):
772 raise TypeError("Please pass the correct type of input: "
773 "detector_id should be String")
774
775 if not (self.__validate_str(name) and self.__validate_interval_parameters(collected_at)):
776 raise TypeError(
777 "Please pass the valid input type: name should be String, collected_at could be "
778 "either datetime or String type.")
779
780 # Input sanitization
781 name = self.__sanitize_str(name)
782
783 # Converting all dates given as a String to a datetime object
784 if self.__validate_str(collected_at):
785 collected_at = self.__convert_date(collected_at)
786 elif self.__validate_datetime(collected_at):
787 # Strip off the microseconds
788 collected_at = collected_at.replace(microsecond=0)
789
790 # Get the detector of the specified detector_id
791 try:
792 detector_wrapper = self.__get_wrapper(detector_id)
793 except Exception:
794 raise ValueError("The detector '",
795 detector_id,
796 "' does not exist in the database")
797
798 detector = None
799 try:
800 detector = self.__get_detector(detector_wrapper, detector_id)
801 except Exception:
802 raise ValueError("The requested detector '" + detector_id + "' does not exist.")
803
804 # Query the condition where the 'name' and 'collected_at' equal the specified name and
805 # collection_date
806 try:
807 condition = detector.conditions.get(name=name, collected_at=collected_at)
808 # Convert the internal Condition object to a generic Python dict type
809 return loads(condition.to_json())
810 except DoesNotExist:
811 return None
812
813 # Method signature description can be found in the toplevel interface.py file
814 def update_condition_by_name_and_tag(self, detector_id, name, tag,
815 type=None, valid_since=None, valid_until=None):
816 # Input validation
817 if not self.__validate_str(detector_id):
818 raise TypeError("Please pass the correct type of input: "
819 "detector_id should be String")
820
821 if not ((self.__validate_interval_parameters(valid_since) or valid_since is None) and
822 (self.__validate_interval_parameters(valid_until) or valid_until is None) and
823 (self.__validate_str(type) or type is None) and
824 self.__validate_str(name) and
825 self.__validate_str(tag)):
826 raise TypeError(
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, "
829 "tag and type.")
830
831 # Converting all dates given as a String to a datetime object
832 if self.__validate_str(valid_until):
833 valid_until = self.__convert_date(valid_until)
834 elif self.__validate_datetime(valid_until):
835 # Strip off the microseconds
836 valid_until = valid_until.replace(microsecond=0)
837 if self.__validate_str(valid_since):
838 valid_since = self.__convert_date(valid_since)
839 elif self.__validate_datetime(valid_since):
840 # Strip off the microseconds
841 valid_since = valid_since.replace(microsecond=0)
842
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")
846
847 # Input sanitization
848 name = self.__sanitize_str(name)
849 tag = self.__sanitize_str(tag)
850
851 if self.__validate_str(type):
852 type = self.__sanitize_str(type)
853
854 # Get the detector of the specified detector_id
855 try:
856 detector_wrapper = self.__get_wrapper(detector_id)
857 except Exception:
858 raise ValueError("The detector '",
859 detector_id,
860 "' does not exist in the database")
861
862 detector = None
863 try:
864 detector = self.__get_detector(detector_wrapper, detector_id)
865 except Exception:
866 raise ValueError("The requested detector '" + detector_id + "' does not exist.")
867
868 condition = None
869 try:
870 condition = detector.conditions.get(name=name, tag=tag)
871 except DoesNotExist:
872 raise ValueError("No condition with this name and tag can be found")
873
874 # Only update fields that are not None
875 if type is not None:
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
881
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_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...
get_conditions_by_tag(self, detector_id, tag)
Returns a list with condition dictionaries having a specific tag for a given detector.
get_detector(self, detector_id)
Returns a detector dictionary.
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.
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.
Definition interface.py:24
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...
Definition interface.py:182