code: def publish(self, message, exchange):
          
          message.validate()
          try:
              yield self._channel.basic_publish(
                  exchange=exchange,
                  routing_key=message._encoded_routing_key,
                  body=message._encoded_body,
                  properties=message._properties,
              )
          except (pika.exceptions.NackError, pika.exceptions.UnroutableError) as e:
              _std_log.error("Message was rejected by the broker (%s)", str(e))
              raise PublishReturned(reason=e)
          except pika.exceptions.ChannelClosed:
              self._channel = yield self._allocate_channel()
              yield self.publish(message, exchange)
          except pika.exceptions.ConnectionClosed as e:
              raise ConnectionException(reason=e)
docs: Publish a :class:`fedora_messaging.message.Message` to an `exchange`_
          on the message broker.
  
          Args:
              message (message.Message): The message to publish.
              exchange (str): The name of the AMQP exchange to publish to
  
          Raises:
              NoFreeChannels: If there are no available channels on this connection.
                  If this occurs, you can either reduce the number of consumers on this
                  connection or create an additional connection.
              PublishReturned: If the broker rejected the message. This can happen if
                  there are resource limits that have been reached (full disk, for example)
                  or if the message will be routed to 0 queues and the exchange is set to
                  reject such messages.
  
          .. _exchange: https://www.rabbitmq.com/tutorials/amqp-concepts.html#exchanges