Создание аутентифицированного ресурса XA из ActiveMQConnectionFactory

У меня есть экземпляр Apache ActiveMQ Artemis (1.3), к которому я пытаюсь подключиться из автономного приложения Spring (4.3.2), над которым сейчас работает моя команда. У него есть Spring JTATransactionManager, использующий Atomikos (4.0.4) UserTransactionManager в качестве поставщика, и во время этих транзакций мне нужно подключиться к нескольким ресурсам, включая вышеупомянутый MQ. Следуя руководствам Artemis и Atomikos, мы настроили ActiveMQConnectionFactory, который затем передается в AtomikosConnectionFactoryBean. Все это происходит в контейнере Spring, но, похоже, это не связано с нашей проблемой.

Все работало хорошо, пока я не попытался добавить аутентификацию в соединение MQ. Можно установить свойства user и password для экземпляра ActiveMQConnectionFactory, однако они, похоже, учитываются только при создании обычного соединения:

@Override
public Connection createConnection() throws JMSException {
  return createConnection(user, password);
}

@Override
public Connection createConnection(final String username, final String password) throws JMSException {
  return createConnectionInternal(username, password, false, ActiveMQConnection.TYPE_GENERIC_CONNECTION);
}

Atomikos вызывает метод createXAConnection() (из интерфейса XAConnectionFactory), который, как я вижу в его реализации, игнорирует учетные данные, если они не переданы явно:

@Override
public XAConnection createXAConnection() throws JMSException {
  return createXAConnection(null, null);
}

@Override
public XAConnection createXAConnection(final String username, final String password) throws JMSException {
  return (XAConnection) createConnectionInternal(username, password, true, ActiveMQConnection.TYPE_GENERIC_CONNECTION);
}

Так работают и некоторые другие методы этого класса, поэтому я предполагаю, что это не ошибка. Если да, то как мне получить аутентифицированный XAConnection? Я не вижу возможности, чтобы Атомикос вызывал перегруженную версию, глядя на ее код.

С уважением, Якуб


person Community    schedule 31.08.2016    source источник


Ответы (1)


В качестве обходного пути мы решили обернуть ActiveMQConnectionFactory в класс, реализующий необходимый интерфейс:

public class ActiveMQConnectionFactoryWrapper implements XAConnectionFactory {

  private final ActiveMQConnectionFactory factory;

  public ActiveMQConnectionFactoryWrapper(ActiveMQConnectionFactory factory) {
    this.factory = factory;
  }

  @Override
  public XAConnection createXAConnection() throws JMSException {
    return factory.createXAConnection(factory.getUser(), factory.getPassword());
  }

  @Override
  public XAConnection createXAConnection(String userName, String password) throws JMSException {
    return factory.createXAConnection(userName, password);
  }

  @Override
  public XAJMSContext createXAContext() {
    return factory.createXAContext(factory.getUser(), factory.getPassword());
  }

  @Override
  public XAJMSContext createXAContext(String userName, String password) {
    return factory.createXAContext(userName, password);
  }
}

При необходимости могут быть реализованы и другие интерфейсы.

person Community    schedule 31.08.2016