예제 #1
0
def self_register_service(config):
    """An example of using the Boston Dynamics API to self register a service using payload auth.

    This function represents code that would run directly on a payload to set itself up. It
    registers a single leaf service without access to a pre-existing credentials.
    """
    # Create an sdk and robot instance.
    sdk = bosdyn.client.create_standard_sdk('SelfRegisterServiceExampleClient')
    robot = sdk.create_robot(config.hostname)

    # Authenticate by using the credentials of a registered & authorized payload.
    robot.authenticate_from_payload_credentials(config.guid, config.secret)

    # Create the directory registration client after getting the user token.
    directory_registration_client = robot.ensure_client(
        DirectoryRegistrationClient.default_service_name)

    # Create a keep_alive to reset and maintain registration of service.
    keep_alive = DirectoryRegistrationKeepAlive(directory_registration_client)
    keep_alive.start(DIRECTORY_NAME, SERVICE_TYPE, AUTHORITY, config.host_ip,
                     config.port)

    # List all services. Success if above test service is shown.
    directory_client = robot.ensure_client(
        DirectoryClient.default_service_name)
    try:
        registered_service = directory_client.get_entry(DIRECTORY_NAME)
    except NonexistentServiceError:
        print('\nSelf-registered service not found. Failure.')
        return False

    print('\nService registration confirmed. Self-registration was a success.')
    return True
예제 #2
0
def liveness_faulting(robot):
    """Force ServiceFaults to be raised indirectly via the directory registration liveness."""
    # Set up robot state client
    robot_state_client = robot.ensure_client(
        RobotStateClient.default_service_name)

    # Set up directory client
    directory_client = robot.ensure_client(
        DirectoryClient.default_service_name)

    # Set up a directory registration client.
    directory_registration_client = robot.ensure_client(
        DirectoryRegistrationClient.default_service_name)

    # Unregister the service if it already exists
    try:
        directory_registration_client.unregister(kServiceName)
        # Wait for a few seconds to give old liveness faults a chance to clear themselves.
        time.sleep(2)
    except:
        pass

    # Use keep alive helper class to maintain liveness with repeated registration/update requests.
    directory_keep_alive = DirectoryRegistrationKeepAlive(
        directory_registration_client,
        rpc_interval_seconds=kKeepAliveIntervalSecs)
    directory_keep_alive.start(kServiceName, kServiceType, kServiceAuthority,
                               kServiceIp, kServicePort, kTimeoutSecs)

    # Verify the service is listed
    services = directory_client.list()
    for service in services:
        if service.name == kServiceName:
            print('Service registration confirmed with liveness timeout == ' +
                  str(service.liveness_timeout_secs))

    # Continually display ServiceFaults. Should not see liveness fault from service_name
    print(
        '\n\n\nHeartbeat thread is active. Should not see liveness fault from '
        + kServiceName + ':')
    watch_service_fault_state(robot_state_client, 8)

    # Stop the service and display ServiceFaults. New liveness fault from service_name should appear.
    print(
        '\n\n\nHeartbeat thread is shutting down. Expect liveness faults from '
        + kServiceName + ':')
    directory_keep_alive.shutdown()
    watch_service_fault_state(robot_state_client, 8)

    # Start a keep alive again, which should re-establish liveness and automatically clear the liveness fault.
    # Unregistering the service will also automatically clear liveness faults.
    print('\n\n\nHeartbeat thread is starting again. Expect ' + kServiceName +
          ' liveness faults to clear')
    directory_keep_alive_2 = DirectoryRegistrationKeepAlive(
        directory_registration_client,
        rpc_interval_seconds=kKeepAliveIntervalSecs)
    directory_keep_alive_2.start(kServiceName, kServiceType, kServiceAuthority,
                                 kServiceIp, kServicePort, kTimeoutSecs)
    watch_service_fault_state(robot_state_client, 4)
def test_keep_alive(default_service_entry, default_service_endpoint):
    client, service, server = _setup()
    keepalive = DirectoryRegistrationKeepAlive(client)
    name = default_service_entry.name
    assert name not in service.service_entries
    keepalive.start(name, default_service_entry.type, default_service_entry.authority,
                    default_service_endpoint.host_ip, default_service_endpoint.port)
    assert name in service.service_entries

    with keepalive:
        # Just have some statement inside the "with" context.
        assert service.service_entries[name] == default_service_entry

    # Now that we've exited the "with" block, the internal thread should have ended and the service
    # should be unregistered.
    assert not keepalive.is_alive()
    assert name not in service.service_entries
def test_keep_alive_update(default_service_entry, default_service_endpoint):
    client, service, server = _setup()
    interval_seconds = 0.1
    keepalive = DirectoryRegistrationKeepAlive(client, rpc_interval_seconds=interval_seconds)
    name = default_service_entry.name
    assert name not in service.service_entries

    client.register(default_service_entry.name, default_service_entry.type,
                    default_service_entry.authority, default_service_endpoint.host_ip,
                    default_service_endpoint.port)

    new_authority = default_service_entry.authority + 'woo-hoo'
    keepalive.start(name, default_service_entry.type, new_authority,
                    default_service_endpoint.host_ip, default_service_endpoint.port)
    assert service.service_entries[name].authority == new_authority

    # Make sure the thread is still alive after a few loops.
    time.sleep(interval_seconds * 3)
    assert keepalive.is_alive()
예제 #5
0
def register_with_robot(options):
    """ Registers this worker with the robot's Directory."""
    ip = bosdyn.client.common.get_self_ip(options.hostname)
    print('Detected IP address as: ' + ip)
    kServiceName = "fire-extinguisher-server"
    kServiceTypeName = "bosdyn.api.NetworkComputeBridgeWorker"
    kServiceAuthority = "fire-extinguisher-worker.spot.robot"

    sdk = bosdyn.client.create_standard_sdk("retinanet-server")

    robot = sdk.create_robot(options.hostname)

    # Authenticate robot before being able to use it
    if options.on_spot_core:
        guid, secret = get_guid_and_secret()
        robot.authenticate_from_payload_credentials(guid, secret)
    else:
        robot.authenticate(options.username, options.password)

    directory_client = robot.ensure_client(
        bosdyn.client.directory.DirectoryClient.default_service_name)
    directory_registration_client = robot.ensure_client(
        bosdyn.client.directory_registration.DirectoryRegistrationClient.default_service_name)

    # Create a keep_alive to reset and maintain registration of service.
    keep_alive = DirectoryRegistrationKeepAlive(directory_registration_client)
    keep_alive.start(kServiceName, kServiceTypeName, kServiceAuthority, ip, int(options.port))

    # List all services. Success if above test service is shown.
    try:
        registered_service = directory_client.get_entry(kServiceName)
    except NonexistentServiceError:
        print('\nSelf-registered service not found. Failure.')
        return False

    print('\nService registration confirmed. Self-registration was a success.')
    return True
        service_runner = run_service(options.port, logger=_LOGGER)
        print('{} service running.\nCtrl + C to shutdown.'.format(
            DIRECTORY_NAME))
        service_runner.run_until_interrupt()
        sys.exit('Shutting down {} service'.format(DIRECTORY_NAME))

    # Else if a robot is available, register the service with the robot so that all clients can
    # access it through the robot directory without knowledge of the service IP or port.

    # Setup logging to use either INFO level or DEBUG level.
    setup_logging(options.verbose)

    # Create and authenticate a bosdyn robot object.
    sdk = bosdyn.client.create_standard_sdk("HelloWorldMissionServiceSDK")
    robot = sdk.create_robot(options.hostname)
    robot.authenticate(options.username, options.password)

    # Create a service runner to start and maintain the service on background thread.
    service_runner = run_service(options.port, logger=_LOGGER)

    # Use a keep alive to register the service with the robot directory.
    dir_reg_client = robot.ensure_client(
        DirectoryRegistrationClient.default_service_name)
    keep_alive = DirectoryRegistrationKeepAlive(dir_reg_client, logger=_LOGGER)
    keep_alive.start(DIRECTORY_NAME, SERVICE_TYPE, AUTHORITY, options.host_ip,
                     service_runner.port)

    # Attach the keep alive to the service runner and run until a SIGINT is received.
    with keep_alive:
        service_runner.run_until_interrupt()
예제 #7
0
if __name__ == '__main__':
    # Define all arguments used by this service.
    import argparse
    parser = argparse.ArgumentParser()
    bosdyn.client.util.add_base_arguments(parser)
    bosdyn.client.util.add_payload_credentials_arguments(parser)
    bosdyn.client.util.add_service_endpoint_arguments(parser)
    options = parser.parse_args()

    # Setup logging to use either INFO level or DEBUG level.
    setup_logging(options.verbose)

    # Create and authenticate a bosdyn robot object.
    sdk = bosdyn.client.create_standard_sdk("PiksiMetadataPluginServiceSDK")
    robot = sdk.create_robot(options.hostname)
    robot.authenticate_from_payload_credentials(options.guid, options.secret)

    # Create a service runner to start and maintain the service on background thread.
    service_runner = run_service(robot, options.port, logger=_LOGGER)

    # Use a keep alive to register the service with the robot directory.
    dir_reg_client = robot.ensure_client(
        DirectoryRegistrationClient.default_service_name)
    keep_alive = DirectoryRegistrationKeepAlive(dir_reg_client, logger=_LOGGER)
    keep_alive.start(DIRECTORY_NAME, DataAcquisitionPluginService.service_type,
                     AUTHORITY, options.host_ip, service_runner.port)

    # Attach the keep alive to the service runner and run until a SIGINT is received.
    with keep_alive:
        service_runner.run_until_interrupt()
def main(server):
    parser = argparse.ArgumentParser()
    bosdyn.client.util.add_common_arguments(parser)
    parser.add_argument('--my-host',
                        help='Address to register into the directory with')
    parser.add_argument(
        '--directory-host',
        help=
        'Host running the directory service. Omit to skip directory registration'
    )
    parser.add_argument(
        '--port',
        default=0,
        type=int,
        help='Listening port for server. Omit to choose a port at random')
    parser.add_argument('--servicer',
                        default='HelloWorld',
                        help='Type of servicer to launch.')
    options = parser.parse_args()

    sdk = bosdyn.client.create_standard_sdk('run-mission-service')
    sdk.load_app_token(options.app_token)

    level = logging.DEBUG if options.verbose else logging.INFO
    logging.basicConfig(level=level,
                        format='%(message)s (%(filename)s:%(lineno)d)')
    logger = logging.getLogger()

    # Map options.servicer to a function that will build the appropriate instance.
    string_to_servicer = {
        'HelloWorld':
        lambda: HelloWorldServicer(logger),
        'PowerOff':
        lambda: PowerOffServicer(logger, sdk, options.hostname, options.
                                 username, options.password)
    }

    # Build whatever service the user specified.
    servicer = string_to_servicer[options.servicer]()

    # Start the server, talking over an insecure channel.
    remote_service_pb2_grpc.add_RemoteMissionServiceServicer_to_server(
        servicer, server)
    port = server.add_insecure_port('[::]:{}'.format(options.port))
    server.start()
    logger.info('Starting server on port %i', port)

    dir_keepalive = None

    # If a directory host was specified, register with the directory there.
    # This will often be the robot. For example, if this program is running on a payload computer
    # like the Spot CORE, directory_host would be 192.168.50.3.
    # Registering with the directory will be important when running with a robot, but it's useful
    # to skip directory registration when you're just testing your service locally.
    if options.directory_host:
        # Register with the directory.
        robot = sdk.create_robot(options.directory_host)
        robot.authenticate(options.username, options.password)
        dir_reg_client = robot.ensure_client(
            DirectoryRegistrationClient.default_service_name)

        dir_keepalive = DirectoryRegistrationKeepAlive(dir_reg_client,
                                                       logger=logger)
        dir_keepalive.start(SERVICE_NAME_IN_DIRECTORY, SERVICE_TYPE, AUTHORITY,
                            options.my_host, port)

    try:
        # Nothing for this thread to do. The server / servicer pair handles all incoming
        # requests.
        while not _STOP_RUNNING.wait(1):
            pass
    except KeyboardInterrupt:
        logger.info('Cancelled by keyboard interrupt')

    if dir_keepalive:
        dir_keepalive.shutdown()
        dir_keepalive.unregister()

    logger.info('Stopping server.')
    return 0
def main():
    """Main remote mission service function"""
    parser = argparse.ArgumentParser(
        description=__doc__,
        formatter_class=argparse.ArgumentDefaultsHelpFormatter)
    bosdyn.client.util.add_common_arguments(parser)
    parser.add_argument('--my-host',
                        help='Address to register into the directory with')
    parser.add_argument(
        '--directory-host',
        help=
        'Host running the directory service. Omit to skip directory registration'
    )
    parser.add_argument(
        '--port',
        default=0,
        type=int,
        help='Listening port for server. Omit to choose a port at random')
    parser.add_argument('--theta-client',
                        dest='theta_client',
                        action='store_true',
                        help='Use theta client or direct mode ip settings')
    parser.add_argument('--payload-token',
                        dest='payload_token',
                        action='store_true',
                        help='Use limited-access user token')
    options = parser.parse_args()

    level = logging.DEBUG if options.verbose else logging.INFO
    logging.basicConfig(level=level,
                        format='%(message)s (%(filename)s:%(lineno)d)')
    logger = logging.getLogger()

    sdk = bosdyn.client.create_standard_sdk('run-ricoh-service')
    guid = None
    secret = None
    if options.payload_token:
        guid, secret = get_guid_and_secret()

    server = grpc.server(futures.ThreadPoolExecutor())
    service = RicohThetaServicer(logger, options.theta_client)

    remote_service_pb2_grpc.add_RemoteMissionServiceServicer_to_server(
        service, server)
    port = server.add_insecure_port('[::]:{}'.format(options.port))
    server.start()
    logger.info('Starting server on port %i', port)

    dir_keepalive = None

    if options.directory_host:
        robot = sdk.create_robot(options.directory_host)
        # Check authentication method
        if guid:
            payload_registration_client = robot.ensure_client(
                PayloadRegistrationClient.default_service_name)
            limited_token = payload_registration_client.get_payload_auth_token(
                guid, secret)
            robot.update_user_token(limited_token)
        else:
            robot.authenticate(options.username, options.password)

        # Register with the directory
        dir_reg_client = robot.ensure_client(
            DirectoryRegistrationClient.default_service_name)
        dir_keepalive = DirectoryRegistrationKeepAlive(dir_reg_client,
                                                       logger=logger)
        dir_keepalive.start(DIRECTORY_NAME, SERVICE_TYPE, AUTHORITY,
                            options.my_host, port)

    try:
        while True:
            # Nothing for this thread to do.
            time.sleep(100)
    except KeyboardInterrupt:
        logger.info('Cancelled by keyboard interrupt')

    if dir_keepalive:
        dir_keepalive.shutdown()
        dir_keepalive.unregister()

    logger.info('Stopping server.')
    # Stop with no grace period.
    shutdown_complete = server.stop(None)
    # Wait up to 1 second for a clean shutdown.
    shutdown_complete.wait(1)
    return 0
    if options.on_spot_core:
        guid, secret = get_guid_and_secret()
        robot.authenticate_from_payload_credentials(guid, secret)
    else:
        if not options.guid or not options.secret:
            _LOGGER.error('GUID and secret need to both be specified.')
            exit(1)
        else:
            robot.authenticate_from_payload_credentials(
                options.guid, options.secret)
    robot.sync_with_directory()

    # Create a service runner to start and maintain the service on background thread.
    service_runner = run_service(robot,
                                 options.port,
                                 options.worker_name,
                                 logger=_LOGGER)

    # Set up the directory name.  The name must have the pattern data-acquisition-XXX-plugin.
    directory_name = get_directory_name(options.worker_name)

    # Use a keep alive to register the service with the robot directory.
    dir_reg_client = robot.ensure_client(
        DirectoryRegistrationClient.default_service_name)
    keep_alive = DirectoryRegistrationKeepAlive(dir_reg_client, logger=_LOGGER)
    keep_alive.start(directory_name, DataAcquisitionPluginService.service_type,
                     AUTHORITY, self_ip, service_runner.port)

    # Attach the keep alive to the service runner and run until a SIGINT is received.
    with keep_alive:
        service_runner.run_until_interrupt()