def setUp(self):
        super().setUp()
        self.rc_service = RadioControllerService(SessionManager(self.engine))
        DBInitializer(SessionManager(self.engine)).initialize()

        self.unregistered_state = self.session.query(DBCbsdState).\
            filter(DBCbsdState.name == CbsdStates.UNREGISTERED.value).scalar()
    def setUp(self):
        super().setUp()
        DBInitializer(SessionManager(self.engine)).initialize()

        self.cbsd_states = {
            state.name: state.id
            for state in self.session.query(DBCbsdState).all()
        }
        self.request_types = {
            req_type.name: req_type.id
            for req_type in self.session.query(DBRequestType).all()
        }

        self.rc_service = RadioControllerService(
            SessionManager(self.engine),
            cbsd_states_map=self.cbsd_states,
            request_types_map=self.request_types,
        )
Example #3
0
def run():
    """
    Top-level function for radio controller
    """
    logger.info("Starting grpc server")
    config = get_config()
    scheduler = BackgroundScheduler()
    metricsd_client = get_metricsd_client()
    scheduler.add_job(
        process_metrics,
        args=[metricsd_client, config.SERVICE_HOSTNAME, "radio_controller"],
        trigger=IntervalTrigger(
            seconds=config.METRICS_PROCESSING_INTERVAL_SEC, ),
        max_instances=1,
        name="metrics_processing_job",
    )
    scheduler.start()

    logger.info(f"grpc port is: {config.GRPC_PORT}")
    db_engine = create_engine(
        url=config.SQLALCHEMY_DB_URI,
        encoding=config.SQLALCHEMY_DB_ENCODING,
        echo=config.SQLALCHEMY_ECHO,
        future=config.SQLALCHEMY_FUTURE,
        pool_size=config.SQLALCHEMY_ENGINE_POOL_SIZE,
        max_overflow=config.SQLALCHEMY_ENGINE_MAX_OVERFLOW,
    )
    session_manager = SessionManager(db_engine)
    server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
    add_RadioControllerServicer_to_server(
        RadioControllerService(session_manager=session_manager),
        server,
    )
    add_ActiveModeControllerServicer_to_server(
        ActiveModeControllerService(session_manager=session_manager),
        server,
    )
    add_DPServiceServicer_to_server(
        DPService(
            session_manager=session_manager,
            now_func=datetime.now,
            fluentd_client=FluentdClient(),
        ),
        server,
    )
    server.add_insecure_port(f"[::]:{config.GRPC_PORT}")
    server.start()
    logger.info(f"GRPC Server started on port {config.GRPC_PORT}")

    def handle_sigterm(*_):
        logger.info("Received shutdown signal")
        all_rpcs_done_event = server.stop(30)
        all_rpcs_done_event.wait(30)
        logger.info("Shut down gracefully")

    signal(SIGTERM, handle_sigterm)
    server.wait_for_termination()
Example #4
0
def run():
    """
    Top-level function for radio controller
    """
    logger.info("Starting grpc server")
    config = get_config()
    logger.info(f"grpc port is: {config.GRPC_PORT}")
    db_engine = create_engine(
        url=config.SQLALCHEMY_DB_URI,
        encoding=config.SQLALCHEMY_DB_ENCODING,
        echo=config.SQLALCHEMY_ECHO,
        future=config.SQLALCHEMY_FUTURE,
        pool_size=config.SQLALCHEMY_ENGINE_POOL_SIZE,
        max_overflow=config.SQLALCHEMY_ENGINE_MAX_OVERFLOW,
    )
    session_manager = SessionManager(db_engine)
    server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
    add_RadioControllerServicer_to_server(
        RadioControllerService(session_manager=session_manager),
        server,
    )
    add_ActiveModeControllerServicer_to_server(
        ActiveModeControllerService(session_manager=session_manager),
        server,
    )
    add_DPServiceServicer_to_server(
        DPService(
            session_manager=session_manager,
            now_func=datetime.now,
            fluentd_client=FluentdClient(),
        ),
        server,
    )
    server.add_insecure_port(f"[::]:{config.GRPC_PORT}")
    server.start()
    logger.info(f"GRPC Server started on port {config.GRPC_PORT}")

    def handle_sigterm(*_):
        logger.info("Received shutdown signal")
        all_rpcs_done_event = server.stop(30)
        all_rpcs_done_event.wait(30)
        logger.info("Shut down gracefully")

    signal(SIGTERM, handle_sigterm)
    server.wait_for_termination()
class RadioControllerTestCase(LocalDBTestCase):
    def setUp(self):
        super().setUp()
        DBInitializer(SessionManager(self.engine)).initialize()

        self.cbsd_states = {
            state.name: state.id
            for state in self.session.query(DBCbsdState).all()
        }
        self.request_types = {
            req_type.name: req_type.id
            for req_type in self.session.query(DBRequestType).all()
        }

        self.rc_service = RadioControllerService(
            SessionManager(self.engine),
            cbsd_states_map=self.cbsd_states,
            request_types_map=self.request_types,
        )

    @parameterized.expand([
        (
            {
                "registrationRequest": [
                    {
                        "fccId": "foo1",
                        "cbsdSerialNumber": "foo2"
                    },
                    {
                        "fccId": "foo1",
                        "cbsdSerialNumber": "foo2"
                    },
                ],
            },
            [1, 2],
        ),
        (
            {
                "deregistrationRequest": [
                    {
                        "cbsdId": "foo1"
                    },
                    {
                        "cbsdId": "foo1"
                    },
                ],
            },
            [1, 2],
        ),
        (
            {
                "relinquishmentRequest": [
                    {
                        "cbsdId": "foo1"
                    },
                    {
                        "cbsdId": "foo1"
                    },
                ],
            },
            [1, 2],
        ),
        (
            {
                "heartbeatRequest": [
                    {
                        "cbsdId": "foo1"
                    },
                    {
                        "cbsdId": "foo1"
                    },
                ],
            },
            [1, 2],
        ),
        (
            {
                "grantRequest": [
                    {
                        "cbsdId": "foo1"
                    },
                    {
                        "cbsdId": "foo1"
                    },
                ],
            },
            [1, 2],
        ),
        (
            {
                "spectrumInquiryRequest": [
                    {
                        "cbsdId": "foo1"
                    },
                    {
                        "cbsdId": "foo1"
                    },
                ],
            },
            [1, 2],
        ),
    ])
    def test_store_requests_from_map_stores_requests_in_db(
            self, request_map, expected_list):
        # Given

        # When
        self.rc_service._store_requests_from_map_in_db(request_map)
        db_request_ids = self.session.query(DBRequest.id).all()
        db_request_ids = [_id for (_id, ) in db_request_ids]

        # Then
        self.assertListEqual(db_request_ids, expected_list)

    def test_get_or_create_cbsd_doesnt_create_already_existing_entities(self):
        # Given
        payload = {"fccId": "foo1", "cbsdSerialNumber": "foo2"}
        # No cbsds in the db
        # When
        self.rc_service._get_or_create_cbsd(
            self.session,
            "registrationRequest",
            payload,
        )
        self.session.commit()

        cbsd1 = self.session.query(DBCbsd).first()

        self.rc_service._get_or_create_cbsd(
            self.session,
            "registrationRequest",
            payload,
        )
        self.session.commit()
        cbsd2 = self.session.query(DBCbsd).first()

        # Then
        self.assertEqual(cbsd1.id, cbsd2.id)

    @parameterized.expand([
        (0, ),
        (1, ),
        (2, ),
    ])
    def test_channels_not_deleted_when_new_spectrum_inquiry_request_arrives(
            self, number_of_channels):
        # Given
        unregistered = self.cbsd_states[CbsdStates.UNREGISTERED.value]
        cbsd = DBCbsd(id=1,
                      cbsd_id="foo1",
                      state_id=unregistered,
                      desired_state_id=unregistered)

        self._create_channels_for_cbsd(cbsd, number_of_channels)

        cbsd_channels_count_pre_request = len(cbsd.channels)

        self.assertEqual(number_of_channels, cbsd_channels_count_pre_request)

        request_map = {"spectrumInquiryRequest": [{"cbsdId": "foo1"}]}

        # When
        self.rc_service._store_requests_from_map_in_db(request_map)
        self.session.commit()

        cbsd_channels_count_post_request = len(cbsd.channels)

        # Then
        self.assertEqual(number_of_channels, cbsd_channels_count_post_request)

    def _create_channels_for_cbsd(self, cbsd: DBCbsd, number: int):
        channels = [
            DBChannel(
                cbsd=cbsd,
                low_frequency=number,
                high_frequency=number + 1,
                channel_type=f"test_type{number}",
                rule_applied=f"test_rule{number}",
                max_eirp=0.1 + number,
            ) for _ in range(0, number)
        ]
        self.session.add_all(channels)
        self.session.commit()
        return channels