Esempio n. 1
0
 def test_calcuate_connection_for_different_prefix_automata_with_endevent(
         self):
     ws = app.config['WINDOW_SIZE']
     if ws == [1, 2, 3, 4]:
         windowsMemory = ['a', 'b', 'c', 'd', '~!@#$%']
         autos_manual1 = automata.Automata()
         autos_manual1.update_automata(automata.Connection(
             'd', '~!@#$%', 0))
         autos_manual2 = automata.Automata()
         autos_manual2.update_automata(
             automata.Connection('c,d', '~!@#$%', 0))
         autos_manual3 = automata.Automata()
         autos_manual3.update_automata(
             automata.Connection('b,c,d', '~!@#$%', 0))
         autos_manual4 = automata.Automata()
         autos_manual4.update_automata(
             automata.Connection('a,b,c,d', '~!@#$%', 0))
         autos_manuals = {
             1: autos_manual1,
             2: autos_manual2,
             3: autos_manual3,
             4: autos_manual4
         }
         case_thread.calculate_connection_for_different_prefix_automata(
             windowsMemory)
         for ws in app.config['WINDOW_SIZE']:
             self.assertEqual(str(autos_manuals[ws].get_connections()),
                              str(gVars.autos[ws].get_connections()))
             self.assertEqual(str(autos_manuals[ws].get_nodes()),
                              str(gVars.autos[ws].get_nodes()))
 def test_get_probability(self):
     self.assertAlmostEqual(
         self.auto1.get_connection_probability(automata.Connection(
             'A', 'B')), 2 / 3)
     self.assertAlmostEqual(
         self.auto1.get_connection_probability(automata.Connection(
             'A', 'C')), 1 / 3)
     self.assertAlmostEqual(
         self.auto1.get_connection_probability(automata.Connection(
             'C', 'C')), -1)
def calculate_connection_for_different_prefix_automata(windowsMemory):
    """
    Description:
        This function will calculate the connections with different size for the windowsMemory.

    :param windowsMemory: :`list` a list of activities from the same case_id of current event(another event),
                         size is maximum_window_size, and the current event is in the last position of the
                         windowsMemory (i.e. event == windowsMemory[maximum_window_size]).
    """
    for ws in WINDOW_SIZE:
        source_node = ','.join(windowsMemory[MAXIMUN_WINDOW_SIZE -
                                             ws:MAXIMUN_WINDOW_SIZE])
        sink_node = ','.join(windowsMemory[MAXIMUN_WINDOW_SIZE - ws +
                                           1:MAXIMUN_WINDOW_SIZE + 1])
        if CL.lock_list.get((source_node, sink_node)):
            if CL.lock_list.get((source_node, sink_node)).acquire():
                try:
                    if windowsMemory[
                            MAXIMUN_WINDOW_SIZE] == '~!@#$%' and source_node.find(
                                '*') == -1:
                        gVars.autos.get(ws).update_automata(
                            automata.Connection(source_node, '~!@#$%', 0))
                    elif source_node.find('*') == -1:
                        gVars.autos.get(ws).update_automata(
                            automata.Connection(source_node, sink_node, 1))
                    elif source_node.find('*') != -1 and sink_node.find(
                            '*') == -1:
                        gVars.autos.get(ws).update_automata(
                            automata.Connection('NONE', sink_node, 1))
                    CL.lock_list.get((source_node, sink_node)).release()
                except Exception as ec:
                    raise ec
        else:
            lock = threading.RLock()
            CL.lock_list[source_node, sink_node] = lock
            if CL.lock_list.get((source_node, sink_node)).acquire():
                try:
                    if windowsMemory[
                            MAXIMUN_WINDOW_SIZE] == '~!@#$%' and source_node.find(
                                '*') == -1:
                        gVars.autos.get(ws).update_automata(
                            automata.Connection(source_node, '~!@#$%', 0))
                    elif source_node.find('*') == -1:
                        gVars.autos.get(ws).update_automata(
                            automata.Connection(source_node, sink_node, 1))
                    CL.lock_list.get((source_node, sink_node)).release()
                except Exception as ec:
                    raise ec
 def setUp(self):
     self.auto1 = automata.Automata()
     self.auto2 = automata.Automata()
     self.auto1.update_automata(automata.Connection('A', 'B', 1))
     self.auto1.update_automata(automata.Connection('A', 'B', 1))
     self.auto1.update_automata(automata.Connection('A', 'C', 1))
     self.auto1.update_automata(automata.Connection('C', '$', 0))
     self.auto2.update_automata(automata.Connection('A,B', 'B,C', 1))
     self.auto2.update_automata(automata.Connection('B,D', 'D,B', 1))
     self.auto1.set_probability()
     self.auto2.set_probability()
 def create_automata(self):
     auto1 = automata.Automata()
     auto2 = automata.Automata()
     auto3 = automata.Automata()
     auto4 = automata.Automata()
     auto1.update_automata(automata.Connection('A', 'B', 1))
     auto1.update_automata(automata.Connection('A', 'B', 1))
     auto1.update_automata(automata.Connection('A', 'C', 1))
     auto2.update_automata(automata.Connection('A,B', 'B,C', 1))
     auto2.update_automata(automata.Connection('B,D', 'D,B', 1))
     auto3.update_automata(automata.Connection('A,D,D', 'C,D,D', 1))
     auto4.update_automata(automata.Connection('A,B,A,W', 'B,C,S,S', 1))
     auto1.set_probability()
     auto2.set_probability()
     auto3.set_probability()
     auto4.set_probability()
     return {1: auto1, 2: auto2, 3: auto3, 4: auto4}
def create_source_sink_node(windows_memory, client_uuid, event, thread_id):
    """
    Description:
        This function creates sink node and source node based on prefix sizes and call function to
        check compliance with automata. Let the source node be NONE and sink node be the node,
        if it is the start node.

    :param windows_memory: :`list` a list of activities from the same case_id of current event(another event) with
                         size `maximum_window_size`, and the current event is at the last position of the windowsMemory
    :param client_uuid: :`string` client-id
    :param event: :`dict`={'case_id': `string`, 'activity': `string`}
    :param thread_id: :int, the id of the thread that is running the compliance check

    :return: `json` {
                        'body': other information (Mandatory)
                        'case_id':	case id (Option)
                        'source_node': source node of the current connection, with separator `,` (Option)
                        'sink_node': sink node of the current connection, with separator `,` (Option)
                        'cause': alert cause of the current connection
                                    {M: missing, T: lower than threshold}(Option)
                        'expect': expect connection (Option)
                    }
    """
    response = {}
    func_name = sys._getframe().f_code.co_name
    try:
        for ws in WINDOW_SIZE:
            source_node = ','.join(windows_memory[MAXIMUN_WINDOW_SIZE - ws: MAXIMUN_WINDOW_SIZE])
            sink_node = ','.join(windows_memory[MAXIMUN_WINDOW_SIZE - ws + 1: MAXIMUN_WINDOW_SIZE + 1])
            if source_node.find('*') != -1 and sink_node.find('*') != -1:
                response[str(ws)] = {'body': 'OK'}
                break
            elif source_node.find('*') != -1:
                source_node = 'NONE'

            lock_list = CAL.c_alerts_lock_list.get(client_uuid)
            if (source_node, sink_node) not in lock_list:
                lock = threading.Lock()
                lock_list[source_node, sink_node] = lock
                ServerLogging().log_info(func_name, client_uuid, thread_id, event['case_id'],
                                          event['activity'],
                                          "the lock has been created: " + source_node + " to " + sink_node)

            matches = check_alert(ws, source_node, sink_node, client_uuid, event, thread_id)
            if matches == 2:
                response[str(ws)] = {
                    'case_id': event['case_id'],
                    'source_node': source_node,
                    'sink_node': sink_node,
                    'expect': gVars.autos[ws].get_sink_nodes(source_node),
                    'body': 'M'
                }
                if ALERT_TYPE == 'RETURN_ONE':
                    return response
            elif matches == 1:
                response[str(ws)] = {
                    'case_id': event['case_id'],
                    'source_node': source_node,
                    'sink_node': sink_node,
                    'cause': gVars.autos[ws].get_connection_probability(automata.Connection(source_node, sink_node)),
                    'expect': THRESHOLD,
                    'body': 'T'
                }
            else:
                response[str(ws)] = {'body': 'OK'}
        return response
    except Exception as ec:
        console.error(traceback.format_exc())
        raise ec
def check_alert(window_size, source_node, sink_node, client_uuid, event, thread_id):
    """
        Description:
            This function takes sink_node, source_node and checks if the automata of 'windowsize'
            has any source_node and sink_node that matches tbe source_node, sink_node. If
            there is a match then checks for its probability ,if probability below than threshold (Alert Typ: T) or
            no match found (Alert Typ: M) then it inserts data to Alertlog object and returns an alert messsage.

        :param window_size: :int, the length of the automata node
        :param source_node: :`string` source node combination in fixed size, with separator `,`
        :param sink_node: :`string` sink node combination in fixed size, with separator `,`
        :param client_uuid: :`string` client-id
        :param event: :dict`={'case_id': `string`, 'activity': `string`}
        :param thread_id: :int, the id of the thread that is running the compliance check

        :return: :int: {0: OK, 1: Alert, lower threshold, 2: Alert, no such connection}
    """
    lock_list = CAL.c_alerts_lock_list.get(client_uuid)
    func_name = sys._getframe().f_code.co_name
    ServerLogging().log_info(func_name, client_uuid, thread_id, event['case_id'],
                              event['activity'], "the lock is in the lock_list: " + source_node + " to " + sink_node)
    alert_log = gVars.get_client_alert_logs(client_uuid)[window_size]
    auto = gVars.autos[window_size]
    conn = automata.Connection(source_node, sink_node)
    if auto.contains_connection(conn):
        if auto.get_connection_probability(conn) >= THRESHOLD:
            return 0
        else:
            try:
                if lock_list.get((source_node, sink_node)).acquire():
                    ServerLogging().log_info(func_name, client_uuid, thread_id, event['case_id'],
                                             event['activity'],
                                             "Acquiring lock for alert: " + "(" + source_node + " to " + sink_node + ")")
                    alert_log.update_alert_record(
                        alertlog.AlertRecord (client_uuid, source_node, sink_node, 1, 'T'))
                    ServerLogging().log_info(func_name, client_uuid, thread_id, event['case_id'],
                                              event['activity'], "Alert raised as probability of "
                                                                 "connection between " +
                                              source_node + " and " + sink_node + " is lesser than threshold")
            except Exception as ec:
                ServerLogging().log_info(func_name, client_uuid, thread_id, event['case_id'], event['activity'],
                                          "Exception by check_alert between " + source_node
                                          + " and " + sink_node)
                console.error(traceback.format_exc())
                raise ec
            else:
                lock_list.get((source_node, sink_node)).release()
                ServerLogging().log_info(func_name, client_uuid, thread_id, event['case_id'],
                                         event['activity'],
                                         "Release lock for alert: " + "(" + source_node + " to " + sink_node + ")")
                return 1
    elif source_node == 'NONE' and auto.contains_source_node(sink_node):
        return 0
    else:
        try:
            if lock_list.get((source_node, sink_node)).acquire():
                ServerLogging().log_info(func_name, client_uuid, thread_id, event['case_id'],
                                         event['activity'],
                                         "Acquiring lock for alert: " + "(" + source_node + " to " + sink_node + ")")
                alert_log.update_alert_record(alertlog.AlertRecord(client_uuid, source_node, sink_node, 1, 'M'))
                ServerLogging().log_info(func_name, client_uuid, thread_id, event['case_id'], event['activity'],
                                         "Alert raised as there should not be connection between " + source_node
                                         + " and " + sink_node)
        except Exception:
            ServerLogging().log_info(func_name, client_uuid, thread_id, event['case_id'], event['activity'],
                                      "Exception by check_alert between " + source_node
                                      + " and " + sink_node)
            console.error(traceback.format_exc())
        else:
            lock_list.get((source_node, sink_node)).release()
            ServerLogging().log_info(func_name, client_uuid, thread_id, event['case_id'],
                                     event['activity'],
                                     "Release lock for alert: " + "(" + source_node + " to " + sink_node + ")")
            return 2