Kod:@RabbitListener w SpringBoot aplikacji
RabbitMQListener:
@Component
public class ServerThroughRabbitMQ implements ServerThroughAMQPBroker {
private static final AtomicLong ID_COUNTER=new AtomicLong();
private final long instanceId=ID_COUNTER.incrementAndGet();
@Autowired
public ServerThroughRabbitMQ(UserService userService,LoginService loginService....){
....
}
@Override
@RabbitListener(queues = "#{registerQueue.name}")
public String registerUserAndLogin(String json) {
.....
}
ServerConfig:
@Configuration
public class ServerConfig {
@Value("${amqp.broker.exchange-name}")
private String exchangeName;
@Value("${amqp.broker.host}")
private String ampqBrokerHost;
@Value("${amqp.broker.quidco.queue.postfix}")
private String quidcoQueuePostfix;
@Value("${amqp.broker.quidco.queue.durability:true}")
private boolean quidcoQueueDurability;
@Value("${amqp.broker.quidco.queue.autodelete:false}")
private boolean quidcoQueueAutodelete;
private String registerAndLoginQuequName;
@PostConstruct
public void init() {
registerAndLoginQuequName = REGISTER_AND_LOGIN_ROUTING_KEY + quidcoQueuePostfix;
public String getRegisterAndLoginQueueName() {
return registerAndLoginQuequName;
}
public String getLoginAndCheckBonusQueueName() {
return loginAndCheckBonusQuequName;
}
@Bean
public ConnectionFactory connectionFactory() {
CachingConnectionFactory connectionFactory = new CachingConnectionFactory(ampqBrokerHost);
return connectionFactory;
}
@Bean
public AmqpAdmin amqpAdmin() {
return new RabbitAdmin(connectionFactory());
}
@Bean
public TopicExchange topic() {
return new TopicExchange(exchangeName);
}
@Bean(name = "registerQueue")
public Queue registerQueue() {
return new Queue(registerAndLoginQuequName, quidcoQueueDurability, false, quidcoQueueAutodelete);
}
@Bean
public Binding bindingRegisterAndLogin() {
return BindingBuilder.bind(registerQueue()).to(topic()).with(REGISTER_AND_LOGIN_ROUTING_KEY);
}
}
TestConfig:
@EnableRabbit
@TestPropertySource("classpath:test.properties")
public class ServerThroughAMQPBrokerRabbitMQIntegrationTestConfig {
private final ExecutorService=Executors.newCachedThreadPool();
private LoginService loginServiceMock=mock(LoginService.class);
private UserService userServiceMock =mock(UserService.class);
@Bean
public ExecutorService executor() {
return executorService;
}
@Bean
public LoginService getLoginServiceMock() {
return loginServiceMock;
}
@Bean
public UserService getUserService() {
return userServiceMock;
}
@Bean
@Autowired
public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory(ConnectionFactory connectionFactory) {
SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
factory.setConnectionFactory(connectionFactory);
factory.setMaxConcurrentConsumers(5);
return factory;
}
@Bean
@Autowired
public RabbitTemplate getRabbitTemplate(ConnectionFactory connectionFactory) {
final RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
return rabbitTemplate;
}
@Bean
public ServerThroughRabbitMQ getServerThroughRabbitMQ() {
return new ServerThroughRabbitMQ(userServiceMock, loginServiceMock,...);
}
}
badania integracji:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes ={ServerConfig.class,ServerThroughAMQPBrokerRabbitMQIntegrationTestConfig.class})
@Category({IntegrationTest.class})
@TestPropertySource("classpath:test.properties")
public class ServerThroughAMQPBrokerRabbitMQIntegrationTest {
final private ObjectMapper jackson = new ObjectMapper();
@Autowired
private ExecutorService executor;
@Autowired
private ServerThroughRabbitMQ serverThroughRabbitMQ;
@Autowired
private RabbitTemplate template;
@Autowired
private TopicExchange exchange;
@Autowired
UserService userService;
@Autowired
LoginService loginService;
@Autowired
private AmqpAdmin amqpAdmin;
@Autowired
private ServerConfig serverConfig;
final String username = "username";
final String email = "[email protected]";
final Integer tcVersion=1;
final int quidcoUserId = 1;
final String jwt = ProcessLauncherForJwtPhpBuilderUnitWithCxtTest.EXPECTED_JWT;
@Before
public void cleanAfterOthersForMyself() {
cleanTestQueues();
}
@After
public void cleanAfterMyselfForOthers() {
cleanTestQueues();
}
private void cleanTestQueues() {
amqpAdmin.purgeQueue(serverConfig.getRegisterAndLoginQueueName(), false);
}
@Test
@Category({SlowTest.class,IntegrationTest.class})
public void testRegistrationAndLogin() throws TimeoutException {
final Waiter waiter = new Waiter();
when(userService.register(anyString(), anyString(), anyString())).thenReturn(...);
when(loginService....()).thenReturn(...);
executor.submit(() -> {
final RegistrationRequest request = new RegistrationRequest(username, email,tcVersion);
final String response;
try {
//@todo: converter to convert RegistrationRequest inside next method to json
response = (String) template.convertSendAndReceive(exchange.getName(), REGISTER_AND_LOGIN_ROUTING_KEY.toString(), jackson.writeValueAsString(request));
waiter.assertThat(response, not(isEmptyString()));
final RegistrationResponse registrationResponse = jackson.readValue(response, RegistrationResponse.class);
waiter.assertThat(...);
waiter.assertThat(...);
} catch (Exception e) {
throw new RuntimeException(e);
}
waiter.resume();
});
waiter.await(5, TimeUnit.SECONDS);
}
}
Kiedy uruchomić ten test separetly, wszystko działa poprawnie, ale kiedy go uruchomić z innych testach szydzili ServerThroughRabbitMQ nie jest używany, więc niektóre buforuje wiosenne zmusić używać starego królika słuchacza.
Próbowałem go debugować i widzę, że poprawny komponent bean jest autowyredowany do testu, ale z jakiegoś powodu stary odbiornik używa (stare pole bean instanceId = 1 nowy szykowany instanceId = 3) i test nie działa (Nie wiem, jak to jest możliwe, więc jeśli w przypadku istniejącego starego komponentu, zakładam, że otrzymam wyjątek autowire).
Próbowałem użyć @DirtiesContext BEFORE_CLASS, ale w obliczu anoter problem (patrz here)
czy masz okazję podzielić się swoją częścią problemu z projektem za pomocą git (byłoby naprawdę przydatne, aby sprawdzić te testy z dodatkowymi eksperymentami)? – Sergii
Czy kiedykolwiek znalazłeś satysfakcjonujące rozwiązanie? – geld0r