Exemplo n.º 1
0
def main():
    '''Main entry function for the script.'''
    try:
        init_args(detectors)

        data = Data()

        for input_name, input in inputs.items():
            t = dbg_time(f'INPUT: {input_name}')
            input(data)
            log.dbg(f'INPUT: Done in {t}s')

        input_post_process.post_process(data)

        for detector_name in args.license_detectors:
            func = detectors[detector_name]
            optional = detector_name in args.optional_license_detectors
            t = dbg_time(f'DETECTOR: {detector_name}')
            func(data, optional)
            log.dbg(f'DETECTOR: Done in {t}s')

        output_pre_process.pre_process(data)

        for generator_name, generator in generators.items():
            output_file = args.__dict__[f'output_{generator_name}']
            if output_file is not None:
                t = dbg_time(f'GENERATOR: {generator_name}')
                output_template.generate(data, output_file, Path(__file__).parent / generator)
                log.dbg(f'GENERATOR: Done in {t}s')
    except SbomException as e:
        log.die(str(e), exit_code=1)
Exemplo n.º 2
0
 def get_next_timestep(self):
     curr_time = float(self.data[1].split(',')[0])
     prev_time = float(self.data[2].split(',')[0])
     data = Data(self.getY(), self.getH(), self.getStd(), curr_time,
                 prev_time)
     self.__truncate()
     return data
Exemplo n.º 3
0
    def GD(self, request, context):
        job_type = request.data_handling_type
        starter_node = Data(request.node_key, request.node_address)
        data = Data(request.data_key, request.data_value)

        cur_key = self.node_table.cur_node.key
        successor_key = self.node_table.finger_table.entries[n.successor].key

        # 만약 get 한 값이 들어왔을 때
        if job_type == d.get_result:

            # 값이 없으면 not found를 출력하게끔 한 뒤
            if data.value == "":
                data.value = "not found"

            # 실제 get 한 값들을 보여줌
            logging.info(
                f"request key:{data.key[:10]}'s value is {data.value}, stored in {starter_node.value}"
            )

        # 만약 자신의 data table에 접근해야 하는 값이라면
        elif cur_key <= data.key < successor_key or successor_key < cur_key <= data.key or data.key < successor_key < cur_key:
            if job_type == d.get:
                self.get(starter_node, data)
            if job_type == d.set:
                self.data_table.set(data)
                logging.info(
                    f"request key:{data.key[:10]}'s value is set to {data.value}, stored in {self.node_table.cur_node.value}"
                )
            if job_type == d.delete:
                self.data_table.delete(data.key)
                logging.info(
                    f"request key:{data.key[:10]} is deleted from {self.node_table.cur_node.value}"
                )
        else:
            # 살아있는 가장 가까운 노드를 찾음
            nearest_node = self.node_table.find_nearest_alive_node(data.key)

            # 그 노드에게 이 정보를 보낸 뒤 종료
            threading.Thread(
                target=data_request,
                args=(
                    starter_node,
                    nearest_node,  # Finger Table 구현되면 수정 필요
                    data,
                    job_type)).start()
        return chord_pb2.HealthReply(pong=0)
Exemplo n.º 4
0
def remove_duplicates(data: Data):
    '''Remove duplicated entries in data.files list.'''
    def is_not_visited(file: FileInfo):
        if file.file_path in visited:
            return False
        visited.add(file.file_path)
        return True

    visited = set()
    data.files = list(filter(is_not_visited, data.files))
Exemplo n.º 5
0
    def get(self, starter_node: Data, req_data: Data):
        try:
            value = self.data_table.get(req_data.key).value
        except ValueError:
            value = ""

        threading.Thread(
            target=data_request,
            args=(
                self.node_table.cur_node,
                starter_node,  # Finger Table 구현되면 수정 필요
                Data(req_data.key, value),
                d.get_result)).start()
Exemplo n.º 6
0
def request_node_info(node: Data, which_info: int):
    """
    해당 노드에게 그 노드가 가지고 있는 노드들의 정보를 물어봅니다.
    ex) predecessor에게 predecessor가 가지고 있는 finger table의 데이터를 물어봄

    :param node: 노드 정보를 물어볼 노드입니다.
    :param which_info: 해당 노드의 몇 번째 finger table의 정보, 혹은 predecessor인지를 물어봅니다.
                    규격은 utils.py의 class _NodeType를 사용합니다.
    :return: 요청한 노드의 정보가 존재하면 해당 노드의 정보를, param node가 죽었거나 해당 정보가 없으면 False를 return합니다.
    """
    # which_info는 utils.NodeType 의 명세를 따름
    try:
        with grpc.insecure_channel(node.value) as channel:
            stub = chord_pb2_grpc.GetNodeValueStub(channel)
            response = stub.GetNodeVal(
                chord_pb2.NodeDetail(node_address=node.value,
                                     which_node=which_info))
        if response.node_key == "0":
            return False
        return Data(response.node_key, response.node_address)
    except _InactiveRpcError:
        return False
Exemplo n.º 7
0
    def __init__(self, ids, address: str, data_table: TableEntry):
        # generate node table
        super().__init__()
        host, port = address.split(":")

        # 현재 본인의 노드 정보와, predecessor 는 finger table에 없지만 필요하므로 별도로 선언함
        self.cur_node = Data(ids, address)

        # 현재 네트워크에 존재하는 노드 수를 정의
        self.network_node_num = 1  # 현재 존재하는 네트워크 노드 수

        # finger table 정의
        self.finger_table = TableEntry()

        # data table 정의
        self.data_table = data_table

        # stop flag 정의
        self.stop_flag = False

        # finger table update cycle 정의
        self.finger_table_update_cycle = 0

        # 보고서 상, 최초 init은 두 개의 노드가 있는 network이기 때문에, 해당 네트워크를 init해 줌
        if port == "50051":
            self.predecessor = Data("0b03a4d8a7d8f8f4c7afae9aeda7d76b431f4cba", host + ":50054")
            self.finger_table.set("0b03a4d8a7d8f8f4c7afae9aeda7d76b431f4cba", host + ":50054")
            self.finger_table.entries.append(Data(ids, address))
            self.network_node_num += 1
        elif port == "50054":
            self.predecessor = Data("a09b0ce42948043810a1f2cc7e7079aec7582f29", host + ":50051")
            self.finger_table.set("t1", "t2")
            self.finger_table.set("t2", "t1")
            self.finger_table.entries[n.successor].update_info(self.predecessor, 0)
            self.finger_table.entries[n.d_successor].update_info(self.cur_node, 1)
            self.network_node_num += 1
        else:
            self.predecessor = Data(ids, address)
            self.finger_table.set(ids, address)  # 0 - successor
            self.finger_table.entries.append(Data(ids, address))  # 1 - double successor
def detect(data: Data, optional: bool):
    '''License detection using scancode-toolkit.'''

    if optional:
        filtered = tuple(
            filter(lambda file: len(file.licenses) == 0, data.files))
    else:
        filtered = data.files

    if len(filtered) > 0:
        check_scancode()

    for result, file, _ in concurrent_pool_iter(run_scancode, filtered):
        for i in result['files'][0]['licenses']:

            friendly_id = ''
            if 'spdx_license_key' in i and i['spdx_license_key'] != '':
                friendly_id = i['spdx_license_key']
            elif 'key' in i and i['key'] != '':
                friendly_id = i['key']
            id = friendly_id.upper()
            if id in ('UNKNOWN-SPDX', 'LICENSEREF-SCANCODE-UNKNOWN-SPDX'):
                friendly_id = re.sub(r'SPDX-License-Identifier:',
                                     '',
                                     i['matched_text'],
                                     flags=re.I).strip()
                id = friendly_id.upper()
            if id == '':
                log.wrn(
                    f'Invalid response from scancode-toolkit, file: {file.file_path}'
                )
                continue

            file.licenses.add(id)
            file.detectors.add('scancode-toolkit')

            if not is_spdx_license(id):
                if 'name' in i:
                    name = i['name']
                elif 'short_name' in i:
                    name = i['short_name']
                else:
                    name = None

                if 'spdx_url' in i:
                    url = i['spdx_url']
                elif 'reference_url' in i:
                    url = i['reference_url']
                elif 'scancode_text_url' in i:
                    url = i['scancode_text_url']
                else:
                    url = None

                if id in data.licenses:
                    license = data.licenses[id]
                    if license.is_expr:
                        continue
                else:
                    license = License()
                    data.licenses[id] = license
                    license.id = id
                    license.friendly_id = friendly_id
                if license.name is None:
                    license.name = name
                if license.url is None:
                    license.url = url
                license.detectors.add('scancode-toolkit')
Exemplo n.º 9
0
    def TM(self, request, context):
        logging.debug(f'Toss Message received from {request.node_address}')
        if request.message_type == t.join_node:
            # 만약 join일 시, finger table 에서의 insert 위치를 찾아본다.

            # 1. 본인의 key값보다 크고, successor (finger_table[0]) 의 key 값보다 작은 경우는, 내가 추가한다.
            if self.node_table.cur_node.key < request.node_key < self.node_table.finger_table.entries[n.successor].key or \
                    self.node_table.finger_table.entries[n.successor].key < self.node_table.cur_node.key < request.node_key:
                logging.info(f'Now Adding {request.node_address}...')
                self.notify_new_node_income(
                    new_node=Data(request.node_key, request.node_address))
            # 2. 아닐 경우에는, 노드 테이블을 순회하면서 적절히 보낼 위치를 찾는다.
            # -> 일단 지금은, 바로 successor 에게 넘긴다. (finger table 의 속성을 변경하는 작업이 필요함)
            else:
                logging.info(
                    f'Passing {request.node_address}`s message to {self.node_table.finger_table.entries[n.successor].value}'
                )
                threading.Thread(
                    target=toss_message,
                    args=(Data(request.node_key, request.node_address),
                          self.node_table.finger_table.entries[n.successor],
                          request.message_type)).start()
            return chord_pb2.HealthReply(pong=0)

        # 만약에 메시지 타입이 finger table을 업데이트하는 메시지라면
        if request.message_type == t.finger_table_setting:
            logging.debug(
                f'received finger table update message : {request.node_key}. {request.node_address}, {request.message}'
            )

            # 만약 받은 요청의 node key와 자신의 key가 같다면 (순회를 마쳤다면)
            if request.node_key == self.node_table.cur_node.key:
                logging.debug("finished receiving update message")

                # 현재 네트워크의 노드 수를 갱신해준 후 종료
                self.node_table.node_network_num = request.message
                return chord_pb2.HealthReply(pong=0)

            # 만약 받은 요청의 node_type가 join_node 라면 (새로운 node가 join되었으면)
            if request.node_type == t.join_node:

                # 현재 노드의 네트워크에 존재하는 노드개수 변수를 1 증가시킴
                self.node_table.node_network_num += 1

            # 만약 받은 요청의 node_type가 left_node 라면 (노드가 나간다면)
            if request.node_type == t.left_node:

                # 현재 노드의 네트워크에 존재하는 노드개수 변수를 1 감소시킴
                self.node_table.node_network_num -= 1

                logging.debug(
                    "sending update message complete, pass to successor")
                threading.Thread(
                    target=toss_message,
                    args=(Data(request.node_key, request.node_address),
                          self.node_table.finger_table.entries[n.successor],
                          request.message_type, request.message)).start()
                return chord_pb2.HealthReply(pong=0)

            cur_node_num = int(request.message)
            cur_finger_table_num = math.log2(cur_node_num)

            # 만약 현재 메시지 수가 2의 배수라면 (1 포함)
            if cur_finger_table_num - int(cur_finger_table_num) == 0:

                # 원본에게 finger table을 업데이트하도록 설정
                # 이 요청이 끝나야 계속 가도록 설정
                is_starter_node_alive = notify_node_info(
                    self.node_table.cur_node,
                    Data(request.node_key, request.node_address),
                    int(cur_finger_table_num))
                logging.debug(f"send res : {is_starter_node_alive}")

                # 만약 원본 노드가 응답이 없으면 (연결이 끊겼으면), 메시지를 끊음
                if is_starter_node_alive is False:
                    logging.debug(
                        f"starter node network error, will end toss message here"
                    )
                    return chord_pb2.HealthReply(pong=0)

            # 만약 어떤 사유로 노드 네트워크를 4번 이상 순회했는데도 여전히 돈다면, 네트워크가 끊어짐을 알림
            if cur_node_num > 4 * self.node_table.node_network_num:
                logging.info(
                    "CRITICAL! network is corrupted. end this toss message")
                return chord_pb2.HealthReply(pong=0)

            # 자신이 처리할 일이 끝났으면, 이 요청을 그대로 자신의 successor에게 전송
            logging.debug("sending update message complete, pass to successor")
            threading.Thread(
                target=toss_message,
                args=(Data(request.node_key, request.node_address),
                      self.node_table.finger_table.entries[n.successor],
                      request.message_type, request.message + 1)).start()
            return chord_pb2.HealthReply(pong=0)
Exemplo n.º 10
0
    def command_handler(self, command):
        commands = command.split()

        if commands[0] == 'get':
            key = commands[1]
            try:
                value = self.data_table.get(key)
                logging.info(
                    f"request key:{key[:10]}'s value is {value}, stored in {self.address}"
                )
            except ValueError:
                # 먼저, 해당하는 finger table이 살아있는지, 죽었으면 그 밑에 노드로 계속 보내는 health check 작업이 필요하다.
                nearest_node = self.node_table.find_nearest_alive_node(key)
                data_request(self.node_table.cur_node, nearest_node,
                             Data(key, ""), d.get)

        elif commands[0] == 'set':
            key, value = commands[1].split(":")
            key = generate_hash(key)
            # 만약 자기 자신에 넣어야 하면
            cur_key = self.node_table.cur_node.key
            successor_key = self.node_table.finger_table.entries[
                n.successor].key

            # 만약 자기 자신에 넣을 수 있으면 자기 자신에 넣음
            if cur_key <= key < successor_key or successor_key < cur_key <= key or key < successor_key < cur_key:
                self.data_table.set(key, value)
                logging.info(
                    f"request key:{key[:10]}'s value is set to {value}, stored in {self.address}"
                )
            # 아닐 경우 살아있는 가장 가까운 노드를 찾아서 넣음
            else:
                nearest_node = self.node_table.find_nearest_alive_node(key)
                data_request(self.node_table.cur_node, nearest_node,
                             Data(key, value), d.set)

        elif commands[0] == 'delete':
            key = commands[1]
            try:
                self.data_table.delete(key)
                logging.info(
                    f"request key:{key[:10]} is deleted from {self.address}")
            except ValueError:
                nearest_node = self.node_table.find_nearest_alive_node(key)
                data_request(self.node_table.cur_node, nearest_node,
                             Data(key, ""), d.delete)

        elif commands[0] == 'join':
            toss_message(self.node_table.cur_node, Data("", commands[1]),
                         t.join_node)
            logging.info(f"finishing join node, will update finger table...")
            toss_message(self.node_table.cur_node,
                         self.node_table.finger_table.entries[n.successor],
                         t.finger_table_setting, 1, t.join_node)

        elif commands[0] == 'disjoin':
            self.server.stop(0)  # HealthCheck를 못 받게 모든 서버 종료
            self.node_table.stop_flag = True  # health check 송신 종료
            logging.info(
                'Waiting for other nodes to update their finger tables')
            time.sleep(10)  # 다른 Node들이 FingerTable을 업데이트할때까지 대기
            for entry in self.data_table.entries:
                threading.Thread(target=data_request,
                                 args=(self.node_table.cur_node,
                                       self.node_table.predecessor, entry,
                                       d.set)).start()
            toss_message(self.node_table.cur_node,
                         self.node_table.finger_table.entries[n.successor],
                         t.finger_table_setting, 1, t.left_node)

        elif commands[0] == 'show':  # 노드 테이블 정보 출력하는 기능 추가
            self.node_table.log_nodes()

        elif commands[0] == 'summary':
            self.data_table.summary()

        elif commands[0] == 'ft_update':
            toss_message(self.node_table.cur_node,
                         self.node_table.finger_table.entries[0],
                         t.finger_table_setting, 1)
Exemplo n.º 11
0
def pre_process(data: Data):
    '''Do pre-processing of data for simpler usage by the output modules.'''
    # Sort files
    data.files.sort(key=lambda f: f.file_path)
    # Convert list of licenses to license expression for each file
    for file in data.files:
        licenses = file.licenses if len(file.licenses) > 0 else ['']
        simple_expr_items = set()
        or_expr_items = set()
        repeated_expr_items = set()
        for license in licenses:
            license = license.upper()
            info = get_spdx_license_expr_info(license)
            if info.valid and not info.is_id_only and len(info.licenses) > 1:
                repeated_expr_items.update(info.licenses)
            if not info.valid or info.or_present:
                or_expr_items.add(license)
            else:
                simple_expr_items.add(license)
        simple_expr_items -= repeated_expr_items
        if len(or_expr_items) > 1 or len(simple_expr_items) > 0:
            or_expr_items = { f'({x})' for x in or_expr_items }
        file.license_expr = ' AND '.join(sorted(simple_expr_items.union(or_expr_items)))
    # Collect all used detectors
    for file in data.files:
        data.detectors.update(file.detectors)
    # Collect all used licenses and license expressions and put them into data.licenses
    used_licenses = dict()
    for file in data.files:
        if file.license_expr in used_licenses:
            continue
        info = get_spdx_license_expr_info(file.license_expr)
        if not info.valid or not info.is_id_only:
            expr = LicenseExpr()
            expr.valid = info.valid
            expr.id = file.license_expr
            expr.friendly_id = info.friendly_expr
            expr.licenses = sorted(info.licenses)
            expr.custom = not info.valid
            for id in expr.licenses:
                if not is_spdx_license(id):
                    expr.custom = True
                    break
            used_licenses[file.license_expr] = expr
        for id in info.licenses:
            if id in used_licenses:
                continue
            elif is_spdx_license(id):
                used_licenses[id] = get_license(id)
            elif id in data.licenses:
                used_licenses[id] = data.licenses[id]
            else:
                lic = get_license(id)
                if lic is None:
                    lic = License()
                    lic.id = id
                    lic.friendly_id = id
                used_licenses[id] = lic
    data.licenses = used_licenses
    # Group files by license id or expression
    for file in data.files:
        if file.license_expr not in data.files_by_license:
            data.files_by_license[file.license_expr] = list()
        data.files_by_license[file.license_expr].append(file)
    # Sort licenses
    def lic_reorder(id: str):
        lic = data.licenses[id]
        lic: 'License|LicenseExpr'
        if id == '':
            return 'A'
        elif lic.is_expr:
            if lic.custom:
                return 'B' + id
            else:
                return 'E' + id
        else:
            if id.startswith('LicenseRef-'):
                return 'D' + id
            elif lic.custom:
                return 'C' + id
            else:
                return 'F' + id
    data.licenses_sorted = sorted(data.licenses.keys(), key=lic_reorder)