@Override
  public void bindRequestor(
      String name, MessageChannel requests, MessageChannel replies, Properties properties) {
    if (logger.isInfoEnabled()) {
      logger.info("binding requestor: " + name);
    }
    validateProducerProperties(name, properties, SUPPORTED_REQUESTING_PRODUCER_PROPERTIES);
    Assert.isInstanceOf(SubscribableChannel.class, requests);
    RabbitPropertiesAccessor accessor = new RabbitPropertiesAccessor(properties);
    String queueName = applyRequests(name);
    AmqpOutboundEndpoint queue =
        this.buildOutboundEndpoint(queueName, accessor, this.rabbitTemplate);
    queue.setBeanFactory(this.getBeanFactory());

    String replyQueueName =
        accessor.getPrefix(this.defaultPrefix)
            + name
            + ".replies."
            + this.getIdGenerator().generateId();
    this.doRegisterProducer(name, requests, queue, replyQueueName, accessor);
    Queue replyQueue = new Queue(replyQueueName, false, false, true); // auto-delete
    declareQueueIfNotPresent(replyQueue);
    // register with context so it will be redeclared after a connection failure
    if (!this.autoDeclareContext.containsBean(replyQueueName)) {
      this.autoDeclareContext.getBeanFactory().registerSingleton(replyQueueName, replyQueue);
    }
    this.doRegisterConsumer(name, replies, replyQueue, accessor, false);
  }
 private void configureOutboundHandler(
     AmqpOutboundEndpoint handler, RabbitPropertiesAccessor properties) {
   DefaultAmqpHeaderMapper mapper = new DefaultAmqpHeaderMapper();
   mapper.setRequestHeaderNames(
       properties.getRequestHeaderPattens(this.defaultRequestHeaderPatterns));
   mapper.setReplyHeaderNames(properties.getReplyHeaderPattens(this.defaultReplyHeaderPatterns));
   handler.setHeaderMapper(mapper);
   handler.setDefaultDeliveryMode(properties.getDeliveryMode(this.defaultDefaultDeliveryMode));
   handler.setBeanFactory(this.getBeanFactory());
   handler.afterPropertiesSet();
 }
 @Override
 public void bindPubSubProducer(
     String name, MessageChannel moduleOutputChannel, Properties properties) {
   validateProducerProperties(name, properties, SUPPORTED_PUBSUB_PRODUCER_PROPERTIES);
   RabbitPropertiesAccessor accessor = new RabbitPropertiesAccessor(properties);
   String exchangeName = applyPrefix(accessor.getPrefix(this.defaultPrefix), applyPubSub(name));
   declareExchangeIfNotPresent(new FanoutExchange(exchangeName));
   AmqpOutboundEndpoint fanout = new AmqpOutboundEndpoint(determineRabbitTemplate(accessor));
   fanout.setExchangeName(exchangeName);
   configureOutboundHandler(fanout, accessor);
   doRegisterProducer(name, moduleOutputChannel, fanout, accessor);
 }
  @Override
  public void bindReplier(
      String name, MessageChannel requests, MessageChannel replies, Properties properties) {
    if (logger.isInfoEnabled()) {
      logger.info("binding replier: " + name);
    }
    validateConsumerProperties(name, properties, SUPPORTED_REPLYING_CONSUMER_PROPERTIES);
    RabbitPropertiesAccessor accessor = new RabbitPropertiesAccessor(properties);
    Queue requestQueue =
        new Queue(applyPrefix(accessor.getPrefix(this.defaultPrefix), applyRequests(name)));
    declareQueueIfNotPresent(requestQueue);
    this.doRegisterConsumer(name, requests, requestQueue, accessor, false);

    AmqpOutboundEndpoint replyQueue = new AmqpOutboundEndpoint(rabbitTemplate);
    replyQueue.setExpressionRoutingKey(
        EXPRESSION_PARSER.parseExpression("headers['" + AmqpHeaders.REPLY_TO + "']"));
    configureOutboundHandler(replyQueue, accessor);
    doRegisterProducer(name, replies, replyQueue, accessor);
  }
 private AmqpOutboundEndpoint buildOutboundEndpoint(
     final String name, RabbitPropertiesAccessor properties, RabbitTemplate rabbitTemplate) {
   String queueName = applyPrefix(properties.getPrefix(this.defaultPrefix), name);
   String partitionKeyExtractorClass = properties.getPartitionKeyExtractorClass();
   Expression partitionKeyExpression = properties.getPartitionKeyExpression();
   AmqpOutboundEndpoint queue = new AmqpOutboundEndpoint(rabbitTemplate);
   if (partitionKeyExpression == null && !StringUtils.hasText(partitionKeyExtractorClass)) {
     declareQueueIfNotPresent(new Queue(queueName));
     queue.setRoutingKey(queueName); // uses default exchange
   } else {
     queue.setExpressionRoutingKey(
         EXPRESSION_PARSER.parseExpression(buildPartitionRoutingExpression(queueName)));
     // if the stream is partitioned, create one queue for each target partition
     for (int i = 0; i < properties.getNextModuleCount(); i++) {
       this.rabbitAdmin.declareQueue(new Queue(queueName + "-" + i));
     }
   }
   configureOutboundHandler(queue, properties);
   return queue;
 }