class TestGlobalVariables(unittest.TestCase):
    @mock.patch("osd.accountUpdaterService.monitor.Req", mockReq)
    @mock.patch("osd.accountUpdaterService.monitor.Resp", mockResp)
    @mock.patch("osd.accountUpdaterService.monitor.ServiceInfo",
                mockServiceInfo)
    def setUp(self):
        self.global_var = GlobalVariables(logger)
        self.global_var.set_service_id("service_id")

    def test_load_gl_map(self):
        #self.assertTrue(self.global_var.load_gl_map())
        with mock.patch(
                'osd.accountUpdaterService.unitTests.mockReq.connector',
                return_value=None):
            self.assertFalse(self.global_var.load_gl_map())
        with mock.patch(
                'osd.accountUpdaterService.unitTests.mockStatus.get_status_code',
                return_value="Resp.FAILURE"):
            self.assertFalse(self.global_var.load_gl_map())

    def test_load_ownership(self):
        with mock.patch(
                'osd.accountUpdaterService.unitTests.mockReq.connector',
                return_value=None):
            self.global_var.load_ownership()
            self.assertEquals(self.global_var.get_ownershipList(), [])
        with mock.patch(
                'osd.accountUpdaterService.unitTests.mockStatus.get_status_code',
                return_value="Resp.FAILURE"):
            self.global_var.load_ownership()
            self.assertEquals(self.global_var.get_ownershipList(), [])
        self.global_var.load_ownership()
        self.assertEquals(self.global_var.get_ownershipList(), range(1, 513))

    def test_get_account_map(self):
        self.assertEquals(
            [obj.get_id() for obj in self.global_var.get_account_map()],
            acc_id)
        self.assertEquals(
            [obj.get_ip() for obj in self.global_var.get_account_map()],
            acc_ip)
        self.assertEquals(
            [obj.get_port() for obj in self.global_var.get_account_map()],
            acc_port)

    def test_get_container_map(self):
        self.assertEquals(
            [obj.get_id() for obj in self.global_var.get_container_map()],
            cont_id)
        self.assertEquals(
            [obj.get_ip() for obj in self.global_var.get_container_map()],
            cont_ip)
        self.assertEquals(
            [obj.get_port() for obj in self.global_var.get_container_map()],
            cont_port)

    def test_get_acc_updater_map(self):
        self.assertEquals(
            [obj.get_id() for obj in self.global_var.get_acc_updater_map()],
            au_id)
        self.assertEquals(
            [obj.get_ip() for obj in self.global_var.get_acc_updater_map()],
            au_ip)
        self.assertEquals(
            [obj.get_port() for obj in self.global_var.get_acc_updater_map()],
            au_port)

    def test_get_acc_updater_map_version(self):
        self.assertEquals(self.global_var.get_acc_updater_map_version(), "5.0")

    def test_get_global_map_version(self):
        self.assertEquals(self.global_var.get_global_map_version(), "5.0")

    def test_get_service_id(self):
        self.assertEquals(self.global_var.get_service_id(), "service_id")
Beispiel #2
0
class HttpListener(BaseHTTPRequestHandler):
    def do_STOP_SERVICE(self):
        """
        Handle COMPLETE ALL REQUEST HTTP request
        """
        self.logger = SimpleLogger(conf=None).get_logger_object()
        self.conf = SimpleLogger(conf=None).get_conf()
        self.msg = GlobalVariables(self.logger)
        all_transfer_event_received = []
        self.logger.info("Account-updater received STOP_SERVICE request")

        complete_all_request_event = self.msg.get_complete_all_event()
        complete_all_request_event.set()
        try:
            while len(all_transfer_event_received) != 4:
                all_transfer_event_received.append(self.msg.get_from_Queue())

            self.logger.info("Completed STOP_SERVICE request")
            self.send_header('Message-Type', typeEnums.BLOCK_NEW_REQUESTS_ACK)
            self.send_header('Ownership-List', self.msg.get_ownershipList())
            self.send_response(HTTP_OK)
            self.end_headers()
            self.wfile.write(self.msg.get_ownershipList())
            return
        except Exception as err:
            self.logger.exception('Exception raised in' \
                ' STOP_SERVICE error :%s' % err)
            self.send_response(HTTP_INTERNAL_SERVER_ERROR)
            self.end_headers()

    def do_ACCEPT_COMPONENT_TRANSFER(self):
        """
        Handle ACCEPT COMPONENT TRANSFER HTTP request
        """
        try:
            self.logger = SimpleLogger(conf=None).get_logger_object()
            self.conf = SimpleLogger(conf=None).get_conf()
            self.msg = GlobalVariables(self.logger)
            self.ll_port = int(self.conf.get('llport', 61014))
            self.logger.info("Account-updater received ACCEPT_COMPONENT_" \
                "TRANSFER request")
            length = int(self.headers['Content-Length'])
            self.logger.debug("Headers:%s" % self.headers)
            #sending intemediate (connection created) acknowledgement
            #to source node
            self.send_response(HTTP_CONTINUE)
            self.end_headers()

            #receiving new ownership list
            pickled_string = self.rfile.read(length)
            add_comp_list = ast.literal_eval(pickled_string)
            self.logger.info("Accepting new component ownership: %s" %
                             add_comp_list)

            #updating global map for new onwership
            thread = threading.Thread(target = self.update_my_ownership, \
                                    args=(add_comp_list,))
            thread.start()

            self.logger.info("Completed ACCEPT_COMPONENTS_TRANSFER request")
            self.send_response(HTTP_OK)
            self.end_headers()
            return
        except Exception as err:
            self.logger.exception('Exception raised in' \
                'ACCEPT_COMPONENTS_TRANSFER error :%s' % err)
            self.send_response(HTTP_INTERNAL_SERVER_ERROR)
            self.end_headers()

    def do_TRANSFER_COMPONENTS(self):
        """
        Handle TRANSFER COMPONENTS HTTP request
        """
        self.logger = SimpleLogger(conf=None).get_logger_object()
        self.conf = SimpleLogger(conf=None).get_conf()
        self.msg = GlobalVariables(self.logger)
        self._request_handler = Req()
        transfer_component_timeout = int(
            self.conf.get('\
            transfer_component_timeout', 600))
        self.ll_port = int(self.conf.get('llport', 61014))
        self.service_id = self.msg.get_service_id()
        self.deleted_comp_list = []
        transfer_component_map = {
        }  #dictionary containing{'(dest_node_obj)':'[comp_list]'}
        #eg: {('169.254.1.12', '61009', 'HN0101_61014_account-updater'):'['1', '2']'}
        self.final_transfer_status_list = [
        ]  #final component status list which will be send to GL
        #[(1, True),(2, False),(3, True)]
        self.final_status = False  #final response to GL
        self.check_transfer_component_map = {
        }  # to check if component transfer completed or failed:
        #{dest_node_obj1:True, dest_node_obj2:"Failed", dest_node_obj3:False}
        all_transfer_event_received = []
        self.protocol_version = "HTTP/1.1"
        self.logger.info("Account-updater received Transfer component request")
        try:
            content_length = int(self.headers['Content-Length'])
            #sending acknowledgement of TRANSFER_COMPONENT to GL
            self.send_response(HTTP_CONTINUE, "Continue\r\n\r\n")

            data = self.rfile.read(content_length)
            message = TransferCompMessage()
            message.de_serialize(data)
            transfer_component_map = message.service_comp_map()
            self.logger.info("Deserialized transfer component map:%s" \
                %transfer_component_map)
        except Exception, ex:
            self.logger.error("Exception: %s" % ex)
            self.send_header('Message-Type', \
                typeEnums.TRANSFER_COMPONENT_RESPONSE)
            self.send_response(HTTP_INTERNAL_SERVER_ERROR)
            self.end_headers()
            return

        #if transfer_component_map is empty then send HTTP_OK to GL
        if not transfer_component_map:
            self.logger.info(
                "Deserialized transfer component map is empty, return HTTP OK!"
            )
            comp_transfer_response = TransferCompResponseMessage(\
                self.final_transfer_status_list, True)
            serialized_body = comp_transfer_response.serialize()

            self.send_header('Message-Type', \
                typeEnums.TRANSFER_COMPONENT_RESPONSE)
            self.send_header('Content-Length', len(serialized_body))
            self.send_response(HTTP_OK)
            self.end_headers()
            self.wfile.write(serialized_body)
            return

        for dest_node_obj, comp_list in transfer_component_map.items():
            for comp in comp_list:
                self.deleted_comp_list.append(comp)
                self.final_transfer_status_list.append((comp, False))
            self.check_transfer_component_map[dest_node_obj] = False
        self.logger.debug("Ownership for components:%s will be removed" %
                          self.deleted_comp_list)
        self.delete_self_ownership()
        transfer_comp_event = self.msg.get_transfer_cmp_event()
        transfer_comp_event.set()

        try:
            #sending accept component request to other nodes
            self.logger.info("Sending accept component request to " \
                "destination nodes")
            for target_service_obj, comp_list in transfer_component_map.items(
            ):
                thread_connecting_node = threading.Thread(target = \
                    self.send_accept_component_request, args = \
                    ("ACCEPT_COMPONENT_TRANSFER", target_service_obj, \
                    comp_list, ))
                thread_connecting_node.setDaemon(True)
                thread_connecting_node.start()

            #Checking if transfer component completed and intermediate
            #response sent or not
            self.logger.info("Checking if transfer component completed")
            thread_check_transfer_status = threading.Thread(target = \
                self.check_component_transfer_completion)
            thread_check_transfer_status.setDaemon(True)
            thread_check_transfer_status.start()
            thread_check_transfer_status.join(transfer_component_timeout)

            # sending final response to GL
            self.logger.info("Sending final response to GL :%s" \
                % self.final_transfer_status_list)
            if self.final_transfer_status_list:
                for comp_status_tuple in self.final_transfer_status_list:
                    if not comp_status_tuple[1]:
                        self.logger.warning("Final transfer component list having failed" \
                            "component:%s, %s" %(comp_status_tuple[0], comp_status_tuple[1]))
                        self.msg.set_ownershipList(self.old_ownership_list)
                        break
                else:
                    self.final_status = True
            comp_transfer_response = TransferCompResponseMessage(\
                self.final_transfer_status_list, self.final_status)
            serialized_body = comp_transfer_response.serialize()

            while len(all_transfer_event_received) != 4:
                all_transfer_event_received.append(self.msg.get_from_Queue())

            self.logger.info("Completed TRANSFER_COMPONENTS request")
            self.send_header('Message-Type', \
                typeEnums.TRANSFER_COMPONENT_RESPONSE)
            self.send_header('Content-Length', len(serialized_body))
            self.send_response(HTTP_OK)
            self.end_headers()
            self.wfile.write(serialized_body)
            transfer_comp_event.clear()
            return
        except Exception as ex:
            self.logger.error("Exception raised: %s" % ex)
            transfer_comp_event.clear()
            self.msg.set_ownershipList(self.old_ownership_list)
            self.logger.error("old_ownership_list:%s" %
                              self.old_ownership_list)
            self.send_header('Message-Type', \
                typeEnums.TRANSFER_COMPONENT_RESPONSE)
            self.send_response(HTTP_INTERNAL_SERVER_ERROR)
            self.end_headers()