{"id":7481,"library":"oslo-messaging","title":"Oslo Messaging","description":"Oslo Messaging is a foundational library providing an API for inter-process communication (IPC) for OpenStack services. It supports both Remote Procedure Call (RPC) and notification patterns over various message queue backends like RabbitMQ, Kafka, and ZeroMQ. It's currently at version 17.3.0 and follows the OpenStack release cadence, typically receiving updates roughly every six months.","status":"active","version":"17.3.0","language":"en","source_language":"en","source_url":"https://opendev.org/openstack/oslo.messaging","tags":["OpenStack","messaging","RPC","AMQP","Kafka","ZeroMQ","IPC"],"install":[{"cmd":"pip install oslo-messaging","lang":"bash","label":"Basic installation"},{"cmd":"pip install oslo-messaging[rabbit] # for RabbitMQ\npip install oslo-messaging[kafka] # for Kafka\npip install oslo-messaging[zeromq] # for ZeroMQ","lang":"bash","label":"Install with specific backend"}],"dependencies":[{"reason":"Highly recommended for production configuration via a central config file.","package":"oslo.config","optional":true},{"reason":"Required for RabbitMQ backend (installed via `[rabbit]`).","package":"amqp","optional":true},{"reason":"Required for Kafka backend (installed via `[kafka]`).","package":"kafka-python","optional":true},{"reason":"Required for ZeroMQ backend (installed via `[zeromq]`).","package":"pyzmq","optional":true}],"imports":[{"symbol":"get_transport","correct":"from oslo_messaging import get_transport"},{"symbol":"Target","correct":"from oslo_messaging import Target"},{"symbol":"RPCClient","correct":"from oslo_messaging import RPCClient"},{"symbol":"get_rpc_server","correct":"from oslo_messaging import get_rpc_server"},{"symbol":"Notifier","correct":"from oslo_messaging import Notifier"}],"quickstart":{"code":"import os\nfrom oslo_config import cfg\nfrom oslo_messaging import get_transport, RPCClient, Target, get_rpc_server, Notifier\n\n# NOTE: This example requires a running message queue (e.g., RabbitMQ)\n# and appropriate backend packages (e.g., `pip install oslo-messaging[rabbit]`)\n\n# 1. Configure the transport (using oslo_config for simplicity)\n#    In a real application, this would load from a config file.\nCONF = cfg.CONF\nCONF.set_default('transport_url', os.environ.get('OSLO_MESSAGING_TRANSPORT_URL', 'rabbit://guest:guest@localhost:5672/'))\n\ntry:\n    transport = get_transport(CONF)\nexcept Exception as e:\n    print(f\"Error getting transport: {e}. Make sure your message queue is running and transport_url is correct.\")\n    exit(1)\n\n# --- RPC Example ---\n\n# RPC Server Handler\nclass MyHandler(object):\n    def say_hello(self, ctxt, name):\n        print(f\"[Server] Received 'say_hello' for: {name} (context: {ctxt})\")\n        return f\"Hello, {name}!\"\n\n    def add_numbers(self, ctxt, a, b):\n        print(f\"[Server] Received 'add_numbers' for: {a}, {b} (context: {ctxt})\")\n        return a + b\n\n# Define a target for the RPC server and client\nrpc_target = Target(topic='my_service_topic', server='my_host')\n\n# RPC Server setup (typically in a separate process/thread)\nrpc_server = get_rpc_server(transport, rpc_target, [MyHandler()])\n# In a real app, you'd start this in a loop or dedicated process\n# rpc_server.start()\n# rpc_server.wait()\nprint(\"[RPC Server] Handler registered for topic 'my_service_topic'. (Not started for this quickstart)\")\n\n# RPC Client setup\nrpc_client = RPCClient(transport, rpc_target)\n\n# Make an RPC call\ntry:\n    # Simulate a context object\n    context = {'user_id': 'test_user', 'tenant_id': 'test_tenant'}\n\n    result_hello = rpc_client.call(context, 'say_hello', name='World')\n    print(f\"[RPC Client] Result of 'say_hello': {result_hello}\")\n\n    result_add = rpc_client.call(context, 'add_numbers', a=5, b=3)\n    print(f\"[RPC Client] Result of 'add_numbers': {result_add}\")\n\n    # Cast (fire and forget)\n    rpc_client.cast(context, 'say_hello', name='Async User')\n    print(\"[RPC Client] Sent 'say_hello' cast for 'Async User'\")\n\nexcept Exception as e:\n    print(f\"[RPC Client] Error making RPC call: {e}. Ensure a server is running and message queue is accessible.\")\n\n# --- Notification Example ---\n\nnotifier = Notifier(transport, topic='my_notifications_topic')\n\n# Publish a notification\nnotification_payload = {'event_type': 'resource_created', 'resource_id': 'xyz-123'}\nnotifier.info(context, 'resource.create.start', notification_payload)\nprint(f\"[Notifier] Sent 'info' notification: {notification_payload}\")\n\n# Clean up transport resources\ntransport.cleanup()\n","lang":"python","description":"This quickstart demonstrates the core components of oslo-messaging: setting up a transport, defining an RPC target, creating an RPC client, and using a notifier. It showcases both RPC (Remote Procedure Call) with `call` and `cast` methods, and simple notifications. For actual execution, ensure a message queue (like RabbitMQ) is running and the appropriate `oslo-messaging` backend is installed (e.g., `pip install oslo-messaging[rabbit]`). The `OSLO_MESSAGING_TRANSPORT_URL` environment variable can be used to configure the message queue connection string."},"warnings":[{"fix":"Install the necessary backend using pip extras: `pip install oslo-messaging[rabbit]` or `pip install oslo-messaging[kafka]`.","message":"oslo-messaging requires a specific message queue backend to be installed separately (e.g., `amqp` for RabbitMQ, `kafka-python` for Kafka). Installing just `oslo-messaging` will lead to 'No backend found' errors.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Use `oslo_config.cfg.CONF` to load `transport_url` and other messaging options, as shown in the quickstart. Ensure `CONF.set_default` or configuration file options are properly set.","message":"Configuration of transport URLs and other settings is primarily handled by `oslo_config`. While direct keyword arguments can be passed to `get_transport` for simple cases, production-grade applications should integrate `oslo_config` for robust and flexible configuration management.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Upgrade to `oslo-messaging` version 7.0.0 or higher and ensure `amqp` (for RabbitMQ) or another supported backend is installed. Avoid `qpid` for new deployments.","message":"Prior to version 7.0.0, `oslo.messaging` supported older `qpid` client libraries. This support was removed, and updates required migrating to `amqp>=2.0` for RabbitMQ or switching backends.","severity":"breaking","affected_versions":"< 7.0.0"},{"fix":"Always provide a context dictionary as the first argument to `RPCClient.call()`, `RPCClient.cast()`, `Notifier.info()`, etc., even if it's an empty dictionary initially.","message":"The OpenStack ecosystem relies on a 'context' object (e.g., a dictionary containing user_id, tenant_id, etc.) being passed with every RPC call or notification. Forgetting to pass this context can lead to missing audit information or authorization failures in downstream services.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-16T00:00:00.000Z","next_check":"2026-07-15T00:00:00.000Z","problems":[{"fix":"Install the specific backend using pip extras: `pip install oslo-messaging[rabbit]` or `pip install oslo-messaging[kafka]`.","cause":"The required message queue backend library (e.g., `amqp` for RabbitMQ) is not installed.","error":"oslo_messaging.exceptions.No                  BackendFound: No backend found for transport URL: rabbit://guest:guest@localhost:5672/"},{"fix":"Use the `Notifier` class for sending notifications: `notifier = Notifier(transport, topic='mytopic')`, then `notifier.info(context, 'event.type', payload)`.","cause":"Attempting to use notification methods (like `notify`, `info`) on an `RPCClient` instance. These methods belong to the `Notifier` class.","error":"AttributeError: 'RPCClient' object has no attribute 'notify'"},{"fix":"Instantiate `Notifier` directly: `notifier = Notifier(transport, topic='mytopic')`.","cause":"The `get_notifier` function was removed or never existed; `Notifier` is instantiated directly.","error":"ImportError: cannot import name 'get_notifier' from 'oslo_messaging'"},{"fix":"Verify the username and password in your `transport_url` (e.g., `rabbit://user:pass@host:port/`) or ensure the RabbitMQ user has appropriate access.","cause":"The credentials provided in the `transport_url` are incorrect or the RabbitMQ user does not exist/has incorrect permissions.","error":"amqp.exceptions.ConnectionForced: Connection.forbid-method: no auth mechanism found"}]}