Spring boot - different messages.properties based on request - java

I would like to load a different set of messages_xx.properties based on the HttpServletRequest to differentiate them based on our customers.
In templates and through all the application, we have a #Bean which gives the actual customer based on the path of the request
#Component
public class CompanySelector {
#Autowired
private ICompanyService service;
public String getURLBase(HttpServletRequest request) throws MalformedURLException {
URL requestURL = new URL(request.getRequestURL().toString());
String port = requestURL.getPort() == -1 ? "" : ":" + requestURL.getPort();
return requestURL.getHost() + port;
}
public Company getActualCompany(HttpServletRequest request) throws MalformedURLException{
String url = getURLBase(request);
Company company = service.findByCompanyUrl(url);
if(company != null){
return company;
}
return null;
}
}
Now, we configure the MessageSource in WebConfig which extends WebMvcConfigurerAdapter and we would like to do something like that
#Configuration
#ComponentScan("it.besmart.eshare.web")
public class WebConfig extends WebMvcConfigurerAdapter{
public WebConfig(){
super();
}
#Autowired
CompanySelector companySelector;
#Autowired
HttpServletRequest request;
#Bean
public MessageSource messageSource() {
ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
Company company = null;
try {
company = companySelector.getActualCompany(request);
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (company != null){
messageSource.setBasename("classpath:"+ company.getSlug() + "_messages");
} else {
messageSource.setBasename("classpath:messages");
}
messageSource.setDefaultEncoding("UTF-8");
return messageSource;
}
}
but obviously it doesn't work because we don't have a request during configuration... Is there another way to load the messages file based on the request? Or any other best practice to adopt? Because our other choice would be using only one file per language and using the company.getSlug() at the beginning of each phrase, but we would decuplicate the size of file...

You need to declare every properties files like that:
#Bean
public MessageSource messageSource() {
ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
messageSource.setBasenames("company1_messages", "company2_messages");
messageSource.setDefaultEncoding("UTF-8");
return messageSource;
}
And to get the message:
#Autowired
private MessageSource messageSource;
public String myRequest(Locale locale) {
...
messageSource.getMessage(company.getSlug().".messageKey1", null, locale));
...
}
In company1_messages_fr.properties:
company1.messageKey1=messageCompany1
In company2_messages_fr.properties:
company2.messageKey1=messageCompany2

Related

Upload a xml file in spring integration using HttpRequestHandlingMessagingGateway

I am trying to upload a multipart form-data with an attached xml file to integration server.
I am using a HttpRequestHandlingMessagingGateway with a RequestMapping bean.
#Bean("Inbound_GATEWAY_in")
public MessageChannel Inbound_GATEWAY_in() { return new DirectChannel(); }
#Bean
public HttpRequestHandlingMessagingGateway selerixInboundRequest() {
HttpRequestHandlingMessagingGateway gateway =
new HttpRequestHandlingMessagingGateway(true);
gateway.setRequestMapping(selerixMapping());
gateway.setMessageConverters( messageConverter() );
gateway.setMultipartResolver(multipartResolverBean());
gateway.setRequestTimeout(3000); // 3s
gateway.setReplyTimeout(5000); // 5s
gateway.setRequestChannelName("Inbound_GATEWAY_in");
gateway.setReplyChannelName("Outbound_GATEWAY_out");
return gateway;
}
#Bean
public RequestMapping selerixMapping() {
RequestMapping requestMapping = new RequestMapping();
requestMapping.setPathPatterns("/path");
requestMapping.setMethods(HttpMethod.POST);
requestMapping.setConsumes(MediaType.MULTIPART_FORM_DATA_VALUE);
return requestMapping;
}
#Bean
public MultipartResolver multipartResolverBean(){
return new CommonsMultipartResolver();
}
#ServiceActivator(inputChannel = "Inbound_GATEWAY_in")
public Message<?> headerEnrich_Inbound_GATEWAY_in(Message<?> message){
Message<?> outmessage = null;
LOGGER.info("message ", message); // returns blank message
But when I am trying to upload the xml file the message is coming as blank.
How can I find the xml file in the Message<?> or how can I check the Request object ?
Here is a simple test to demonstrate how we can upload the file using Spring Integration:
#SpringJUnitWebConfig
#DirtiesContext
public class FileUploadTests {
#Autowired
private WebApplicationContext wac;
private MockMvc mockMvc;
#BeforeEach
public void setup() {
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
}
#Test
void commonsFileUploadValidation() throws Exception {
MockPart mockPart1 = new MockPart("file", "file.text", "ABC".getBytes(StandardCharsets.UTF_8));
mockPart1.getHeaders().setContentType(MediaType.TEXT_PLAIN);
this.mockMvc.perform(multipart("/path").part(mockPart1))
.andExpect(status().isOk())
.andExpect(content().string("File uploaded: file.text with content: ABC"));
}
#Configuration
#EnableIntegration
public static class ContextConfiguration {
#Bean("Inbound_GATEWAY_in")
public MessageChannel Inbound_GATEWAY_in() {
return new DirectChannel();
}
#Bean
public HttpRequestHandlingMessagingGateway selerixInboundRequest() {
HttpRequestHandlingMessagingGateway gateway = new HttpRequestHandlingMessagingGateway();
RequestMapping requestMapping = new RequestMapping();
requestMapping.setPathPatterns("/path");
gateway.setRequestMapping(requestMapping);
gateway.setRequestChannelName("Inbound_GATEWAY_in");
return gateway;
}
#Bean(name = DispatcherServlet.MULTIPART_RESOLVER_BEAN_NAME)
public MultipartResolver multipartResolver() {
return new StandardServletMultipartResolver();
}
#ServiceActivator(inputChannel = "Inbound_GATEWAY_in")
public String headerEnrich_Inbound_GATEWAY_in(MultiValueMap<String, MultipartFile> payload) throws IOException {
MultipartFile file = payload.getFirst("file");
return "File uploaded: " + file.getOriginalFilename() + " with content: " + new String(file.getBytes());
}
}
}
Note: the CommonsMultipartResolver is deprecated for a while and was removed from latest Spring. Please, be sure that you use the latest versions of the frameworks: https://spring.io/projects/spring-integration#learn
What I did is I created an interface
#Configuration
#MessagingGateway
#EnableIntegration
public interface IntegrationGateway2 {
#Gateway(requestChannel = "Inbound_CHANNEL_in", replyChannel = "Inbound_Channel_reply")
public Message<?> sendAndReceive(Message<?> input);
}
and then created a normal rest controller and fetched the multipart file and then converted to a message.
#RestController
#EnableIntegration
#Configuration
public class SelerixController {
#Bean("Inbound_CHANNEL_in")
public MessageChannel Inbound_Channel_in() {
return new DirectChannel();
}
#Bean("Inbound_Channel_reply")
public MessageChannel Inbound_Channel_reply() {
return new DirectChannel();
}
#Autowired
IntegrationGateway integrationGateway;
#PostMapping("/processFile")
public ResponseEntity<String> fileUpload(#RequestParam String partner, #RequestParam("file") MultipartFile file ) throws IOException {
Message reply = null;
String xmlInputData = "";
if (file != null) {
InputStream is = file.getInputStream();
xmlInputData = new BufferedReader(new InputStreamReader(is))
.lines().collect(Collectors.joining(""));
MapConversionUtility mcu = new MapConversionUtility();
String json = mcu.convertXmlToJSON(xmlInputData);
Map<String, Object> header = new HashMap<String, Object>();
header.put("uuid", UUID.randomUUID().toString());
header.put("REAL_TIME_FLAG", "TRUE"); //QUERY_PARAM
header.put("QUERY_PARAM", partner);
Message<?> request = MessageBuilder
.withPayload(json)
.copyHeaders(header)
.build();
reply = integrationGateway.sendAndReceive( request);
LOGGER.info("getting reply final *************** {}",reply.getPayload());
}
}
}

Spring boot app gives error circular references why?

I have this Configuration class:-
#Configuration
public class AppConfig {
#Autowired
private Environment env;
private List<Weather> weathers = new ArrayList<>();
#Bean
public RestTemplate restTemplate() {
var factory = new SimpleClientHttpRequestFactory();
factory.setConnectTimeout(3000);
factory.setReadTimeout(3000);
return new RestTemplate(factory);
}
#PostConstruct
public void startMonitoring() {
String url = env.getProperty("openWeatherUrl");
String apiKey = env.getProperty("openWeatherApiKey");
try (InputStream resource = app.class.getResourceAsStream("/config.csv")) {
CSVReader reader = new CSVReader(new InputStreamReader(resource));
String[] lineInArray;
while ((lineInArray = reader.readNext()) != null) {
Weather weather = new Weather();
if (!lineInArray[0].contains("city")) {
weather.setCity(lineInArray[0]);
} else {
continue;
}
if (!lineInArray[1].contains("temperaturesLimit")) {
weather.setTemperaturesLimit(Float.parseFloat(lineInArray[2]));
}
if (!lineInArray[2].contains("temperaturesLimit")) {
weather.setFrequency(Integer.parseInt(lineInArray[2]));
}
URI uri = new URI(url + "?q=" + weather.getCity() + "&units=metric&APPID=" + apiKey);
weather.setUri(uri);
weathers.add(weather);
}
} catch (IOException | CsvValidationException | URISyntaxException e) {
System.out.println(e.getMessage());
}
fetchWeatherData();
}
void fetchWeatherData(){
RestTemplate restTemplate = restTemplate();
weathers.forEach(weather -> {
var res = restTemplate.getForEntity(weather.getUri(), Weather.class);
});
}
}
I got error:-
The dependencies of some of the beans in the application context form a cycle:
Action:
Relying upon circular references is discouraged and they are prohibited by default. Update your application to remove the dependency cycle between beans. As a last resort, it may be possible to break the cycle automatically by setting spring.main.allow-circular-references to true.
Why is it circular? How do I fix it?
It's quite simple #PostConstruct in AppConfig relies on the RestTemplate bean but this #Bean is part of AppConfig.
This is due to how #Configuration classes work, they are proxied and a call to public RestTemplate restTemplate() would call the proxied method.
A simple fix would be removing the #Bean annotation from your RestTemplate method, if the RestTemplate is not used in other locations.

Spring Boot 1.5 sessionRegistry().getAllPrincipals() always returns empty list

I inherited a Spring Boot 1.5 project which cannot be migrated up at the moment and need to work on session registry to manage users (ex: list logged users, email users of production updates etc.)
I tried all existing SO solutions I could find, but all of them provide a null result for sessionRegistry().getAllPrincipals(). My security config looks like:
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.httpBasic().disable()
.formLogin().disable()
.headers().frameOptions().sameOrigin()
.and()
.sessionManagement().maximumSessions(1).sessionRegistry(sessionRegistry());
}
#Bean
public SessionRegistry sessionRegistry() {
return new SessionRegistryImpl();
}
#Bean
public ServletListenerRegistrationBean<HttpSessionEventPublisher> httpSessionEventPublisher() {
return new ServletListenerRegistrationBean<>(new HttpSessionEventPublisher());
}
}
My Application config looks like:
#EnableRedisHttpSession(maxInactiveIntervalInSeconds = 3600000)
#EnableDiscoveryClient
#EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class})
#EnableZuulProxy
#EnableFeignClients
#EnableSwagger2
#SpringBootApplication
#RibbonClients({
#RibbonClient(name = "employeeService", configuration = StickySessionEditorRibbonConfiguration.class)
})
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
#Bean
public PreFilter preFilter() {
return new PreFilter();
}
#Bean
public PostFilter postFilter() {
return new PostFilter();
}
#Bean
public CorsFilter corsFilter() {
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
final CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("*");
config.addAllowedHeader("*");
config.addAllowedMethod("OPTIONS");
config.addAllowedMethod("HEAD");
config.addAllowedMethod("GET");
config.addAllowedMethod("PUT");
config.addAllowedMethod("POST");
config.addAllowedMethod("DELETE");
config.addAllowedMethod("PATCH");
source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
}
#Bean
public CookieSerializer cookieSerializer() {
DefaultCookieSerializer serializer = new DefaultCookieSerializer();
serializer.setCookieName("JSESSIONID");
serializer.setCookiePath("/");
serializer.setDomainNamePattern("^.+?\\.(\\w+\\.[a-z]+)$");
serializer.setCookieMaxAge(3600000);
return serializer;
}
}
Relevant code to access the session registry looks like this:
public class TestController extends BaseController {
#Autowired
private SessionRegistry sessionRegistry;
...
public List<User> findAllLoggedInUsers() {
final List<Object> allPrincipals = sessionRegistry.getAllPrincipals();
}
}
Using the actuator/bean endpoint I can see that the SessionRegistry Bean is active.
I am logging in successfully from a couple of browsers but allPrincipals is always size 0 before and after the logins.
Am at a loss why, and any help here is much appreciated.
Based on #M.Deinum 's comment regarding disabled login I want to add that the project uses Zuul Filters (preFilter and PostFilter) as indicated in the application config. We have an account-manager service completely different from this api-gateway service, which authenticates users based on simple login/password.
The logic in preFilter looks like this:
public class PreFilter extends BaseFilter {
#Autowired
SessionRegistry sessionRegistry;
#Autowired
private SessionRepository sessionRepository;
#Override
public String filterType() {
return "pre";
}
#Override
public boolean shouldFilter() {
return true;
}
#Override
public Object run() {
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest req = ctx.getRequest();
HttpSession session = req.getSession();
try {
String uri = req.getRequestURI();
// user assumed is not authenticated
String authToken = null;
//Login code
if (uri.contains("/api/public/authorization/login") && req.getMethod().equals("POST")) {
session.removeAttribute(AUTH_TOKEN_HEADER);
LoginRequest request = createLoginRequest(req);
/* LoginRequest basically contains "userName" and "password" entered by user */
ResponseEntity<MessageWrapper<String>> response = accountManagerFeignClient.authenticate(loginRequest);
authToken = response.getBody().getData();
if (authToken != null) {
session.setAttribute(AUTH_TOKEN_HEADER, authToken);
ctx.setResponseStatusCode(HttpStatus.OK.value());
ctx.setSendZuulResponse(false);
return null;
}
// authToken == null implies the user was not authenticated by accountManager
} else if ("internal or public apis are called, they won't need authentication") {
// user remains unauthenticated, which is fine for public or internal apis
return null;
} else {
// Assume this is a protected API and provide authToken if one exists
authToken = (String) session.getAttribute(AUTH_TOKEN_HEADER);
}
if (authToken == null)
throw new Exception(UNAUTHORIZED + ". Log String: " + logString);
// Validated user will go through here
ctx.addZuulRequestHeader(AUTH_TOKEN_HEADER, authToken);
} catch (Exception ex) {
ctx.setResponseBody(UNAUTHORIZED);
ctx.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value());
ctx.setSendZuulResponse(false);
}
return null;
}
}
The only relevant logic in postFilter (similar to preFilter) disables sessions during logout in this manner:
if (authToken != null) {
session.removeAttribute(AUTH_TOKEN_HEADER);
session.removeAttribute(StickySessionEditorRule.STICKY_ID);
session.removeAttribute(StickySessionWSGRule.STICKY_ID);
ctx.setResponseBody(LOGGED_OUT);
ctx.setResponseStatusCode(HttpStatus.OK.value());
ctx.setSendZuulResponse(false);
}
session.invalidate();
My other time-consuming option would be to use the HTTPSessionBindingListener as shown here . I have not tried that yet.
Finally, if none of the above work, how could I work directly with redis and do a findAll() ? It looks like there is a SessionRepository, but I could not find a documented way of using it.
Thank You.

OAuth2Client return the same token every time

I have the AuthorizationServer. Besides standard functions i have controller who let to create user. After successful user creates the method must to return token for this user. The problem is that the method return valid token only at first call. At next calls - following users will get the first user's token. I tried to set scope(request) for restTemplate - but obtained the error: " Scope 'request' is not active for the current thread"
#Configuration
#EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
#Override
public void configure(ClientDetailsServiceConfigurer configurer) throws Exception {
...
}
#Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
...
}
protected ResourceOwnerPasswordResourceDetails getOwnerPasswordResource(){
ResourceOwnerPasswordResourceDetails resource = new ResourceOwnerPasswordResourceDetails();
List scopes = new ArrayList<String>(3);
scopes.add(SCOPE_READ);
scopes.add(SCOPE_WRITE);
scopes.add(SCOPE_TRUST);
resource.setAccessTokenUri(tokenUrl);
resource.setClientId(CLIENT_ID);
resource.setClientSecret(CLIENT_SECRET_UNCODED);
resource.setGrantType(GRANT_TYPE_PASSWORD);
resource.setScope(scopes);
return resource;
}
}
Here the OAuth2Client:
#EnableOAuth2Client
#Configuration
public class ClientConfig {
#Autowired
AuthorizationServerConfig authorizationServerConfig;
#Bean
//#Scope("request")
public OAuth2RestOperations restTemplate() {
AccessTokenRequest atr = new DefaultAccessTokenRequest();
return new OAuth2RestTemplate(authorizationServerConfig.getOwnerPasswordResource(), new DefaultOAuth2ClientContext(atr));
}
}
And my controller:
#RestController
public class UserRestController {
#Autowired
private OAuth2RestOperations restTemplate;
#PostMapping("/user")
public OAuth2AccessToken createUserCredential(#RequestBody UserCredential user) {
user.validate();
userCredentialService.checkAndSaveUser(user, getClientIp(request));
restTemplate.getOAuth2ClientContext().getAccessTokenRequest().set("username", user.getLogin());
restTemplate.getOAuth2ClientContext().getAccessTokenRequest().set("password", user.getPassword);
return restTemplate.getAccessToken();
}
}
May be exists more correct way to obtain token inside of AuthorizationServer ?
I thought have some special way.. but not found it. And solved problem on following way
#EnableOAuth2Client
#Configuration
public class OAuthClientConfig {
#Autowired
AuthorizationServerConfig authorizationServerConfig;
public OAuth2RestOperations restTemplate() {
AccessTokenRequest atr = new DefaultAccessTokenRequest();
return new OAuth2RestTemplate(authorizationServerConfig.getOwnerPasswordResource(), new DefaultOAuth2ClientContext(atr));
}
}
And my controller:
#RestController
public class UserRestController {
#Autowired
private OAuthClientConfig oAuthClientConfig;
#PostMapping("/user")
public OAuth2AccessToken createUserCredential(#RequestBody UserCredential user) {
user.validate();
userCredentialService.checkAndSaveUser(user, getClientIp(request));
OAuth2RestOperations restTemplate = oAuthClientConfig.restTemplate();
restTemplate.getOAuth2ClientContext().getAccessTokenRequest().set("username", user.getLogin());
restTemplate.getOAuth2ClientContext().getAccessTokenRequest().set("password", user.getPassword);
return restTemplate.getAccessToken();
}
}
May be it will help to someone
I was facing the same issue I found this other way to make it work
#Bean
#Primary
#Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)
public OAuth2RestTemplate oauth2RestTemplate(OAuth2ClientContext context,
OAuth2ProtectedResourceDetails details) {
AccessTokenRequest atr = new DefaultAccessTokenRequest();
OAuth2RestTemplate template = new OAuth2RestTemplate(resource(), new DefaultOAuth2ClientContext(atr));
AccessTokenProvider accessTokenProvider = new AccessTokenProviderChain(Arrays.<AccessTokenProvider>asList(
new AuthorizationCodeAccessTokenProvider(), new ImplicitAccessTokenProvider(),
new ResourceOwnerPasswordAccessTokenProvider(), new ClientCredentialsAccessTokenProvider()));
template.setAccessTokenProvider(accessTokenProvider);
return template;
}
And then I just did the injection
private final OAuth2RestTemplate oauth2RestTemplate;
#GetMapping(path = "/token")
public String token(Credentials credentials) {
oauth2RestTemplate.getOAuth2ClientContext()
.getAccessTokenRequest().add("username", credentials.getEmail());
oauth2RestTemplate.getOAuth2ClientContext()
.getAccessTokenRequest().add("password", credentials.getPass());
final OAuth2AccessToken accessToken = oauth2RestTemplate.getAccessToken();
final String accessTokenAsString = accessToken.getValue();
return accessTokenAsString ;
}

Compressing and decompressing Spring RabbitMQ messages with a DirectMessageListenerContainer

I have modified my RabbitMQ from a previous post (spring-rabbit JSON deserialization for ArrayList contents) to now use a DirectMessageListener with MessagePostProcessors to GZip and GUnzip the message payloads.
However, it doesn't appear to be working as the breakpoints are not activated, but also because my RabbitListeners are no longer receiving messages, whereas they did with a SimpleMessageFactoryListenerContainer.
Also, it appears the SimpleMessageListenerContainer(?) is still being used. On a side-note, I am autowiring the DirectMessageListenerContainer so I can dynamically set the queues I used.
spring-rabbit: 2.0.3.RELEASE.
spring-boot: 2.0.1.RELEASE.
RabbitMQ configuration:
#Configuration
#EnableRabbit
public class MessagingConfiguration implements ShutdownListener {
#Autowired
private RabbitListenerEndpointRegistry registry;
#Autowired
private DirectMessageListenerContainer container;
#Bean
public DirectMessageListenerContainer messageListenerContainer(final ConnectionFactory connectionFactory) {
final DirectMessageListenerContainer listenerContainer = new DirectMessageListenerContainer();
listenerContainer.setConnectionFactory(connectionFactory);
listenerContainer.setMessageConverter(jsonConverter()); // i.e.#RabbitListener to use Jackson2JsonMessageConverter
listenerContainer.setAutoStartup(false);
// container.setErrorHandler(errorHandler);
final MessageListenerAdapter messageListener = new MessageListenerAdapter(new Object() {
#SuppressWarnings("unused")
public String handleMessage(final String message) {
return message.toUpperCase();
}
});
messageListener.setBeforeSendReplyPostProcessors(new GZipPostProcessor());
listenerContainer.setMessageListener(messageListener);
listenerContainer.setAfterReceivePostProcessors(new GUnzipPostProcessor());
return listenerContainer;
}
#EventListener(ApplicationDatabaseReadyEvent.class)
public void onApplicationDatabaseReadyEvent() {
log.info("Starting all RabbitMQ Listeners..."); //$NON-NLS-1$
for (final MessageListenerContainer listenerContainer : registry.getListenerContainers()) {
listenerContainer.start();
}
log.info("Register is running: {}", registry.isRunning()); //$NON-NLS-1$
log.info("Started all RabbitMQ Listeners."); //$NON-NLS-1$
}
#Bean
public List<Declarable> bindings() {
final List<Declarable> declarations = new ArrayList<>();
final FanoutExchange exchange = new FanoutExchange("fx", true, false);
final Queue queue = QueueBuilder.durable("orders").build();
declarations.add(exchange);
declarations.add(queue);
declarations.add(BindingBuilder.bind(queue).to(exchange));
List<String> q = new ArrayList<>();
q.add(queue.getName());
container.addQueueNames(q.toArray(new String[queues.size()]));
return declarations;
}
#Bean
public Jackson2JsonMessageConverter jsonConverter() {
final Jackson2JsonMessageConverter converter = new Jackson2JsonMessageConverter();
converter.setClassMapper(classMapper());
return converter;
}
private static DefaultJackson2JavaTypeMapper classMapper() {
final DefaultJackson2JavaTypeMapper classMapper = new DefaultJackson2JavaTypeMapper();
classMapper.setTrustedPackages("*"); //$NON-NLS-1$ //TODO add trusted packages
return classMapper;
}
#ConditionalOnProperty(name = "consumer", havingValue = "true")
#Bean
public ConsumerListener listenerConsumer() {
return new ConsumerListener();
}
#ConditionalOnProperty(name = "producer", havingValue = "true")
#Bean
public ProducerListener listenerProducer() {
return new ProducerListener();
}
#Bean
public RabbitAdmin rabbitAdmin(final CachingConnectionFactory connectionFactory) {
return new RabbitAdmin(connectionFactory);
}
#Bean
public RabbitTemplate rabbitTemplate(final ConnectionFactory connectionFactory) {
final RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
rabbitTemplate.setMessageConverter(jsonConverter()); // convert all sent messages to JSON
rabbitTemplate.setReplyTimeout(TimeUnit.SECONDS.toMillis(3));
rabbitTemplate.setReceiveTimeout(TimeUnit.SECONDS.toMillis(3));
return rabbitTemplate;
}
#Override
public void shutdownCompleted(final ShutdownSignalException arg0) {
}
}
It doesn't work that way, you can't autowire containers for #RabbitListeners; they are not beans; they are created by the container factory and registered in the registry. Instead you have to retrieve them from the registry (by id).
However, since you have autoStartup set to false, it shouldn't be "stealing" messages from your #RabbitListener.
Generally, DEBUG logging should help.

Categories