logoutSuccessUrl not working in Spring Boot - security

I have a simple Gradle Spring Boot (v 1.3.3) WebMVC application I'm running from the command line via "Gradle bootrun". I am also including Spring Security and am overriding some default security configuration by including a java security config class. My build file is
buildscript {
ext {
springBootVersion = '1.3.3.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'spring-boot'
jar {
baseName = 'readinglist'
version = '0.0.1-SNAPSHOT'
}
sourceCompatibility = 1.8
targetCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
compile('org.springframework.boot:spring-boot-starter-data-jpa')
compile('org.springframework.boot:spring-boot-starter-thymeleaf')
compile('org.springframework.boot:spring-boot-starter-web')
compile("org.springframework.boot:spring-boot-starter-security")
runtime('com.h2database:h2')
testCompile('org.springframework.boot:spring-boot-starter-test')
}
eclipse {
classpath {
containers.remove('org.eclipse.jdt.launching.JRE_CONTAINER')
containers 'org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8'
}
}
task wrapper(type: Wrapper) {
gradleVersion = '2.9'
}
My security configuration class is
package readinglist;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
#Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private ReaderRepository readerRepository;
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/readingList").access("hasRole('READER')")
.antMatchers("/**").permitAll()
.and()
.formLogin()
.loginPage("/login")
.failureUrl("/login?error=true")
.and()
.logout()
.logoutSuccessUrl("/"); // Added .and()....logoutSuccessURL()
}
#Override
protected void configure(
AuthenticationManagerBuilder auth) throws Exception {
auth
.userDetailsService(new UserDetailsService() {
#Override
public UserDetails loadUserByUsername(String username)
throws UsernameNotFoundException {
UserDetails userDetails = readerRepository.findOne(username);
if (userDetails != null) {
return userDetails;
}
throw new UsernameNotFoundException("User '" + username + "' not found.");
}
});
}
}
I also have a home controller that maps the URL "/" to the view home.html
When I run the application and go to localhost:8080/ I get the home page.
When I try to access the URL "/readingList", I get the custom login page. If I enter incorrect credentials, I return to the login page for another try. If I enter valid credentials I get the readingList page. So far so good. The problem is with the logoutSuccessURL("/"). When I go to the URL "/logout" this should log me out and take me back to "/", but instead I get the following error showing in the browser:
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Thu Mar 03 19:31:24 PST 2016
There was an unexpected error (type=Not Found, status=404).
No message available
I turned on debug for security and when I hit my logout link I get the following:
2016-03-03 19:48:45.033 DEBUG 22401 --- [io-8080-exec-10] o.s.web.servlet.DispatcherServlet : DispatcherServlet with name 'dispatcherServlet' processing GET request for [/error]
2016-03-03 19:48:45.033 DEBUG 22401 --- [io-8080-exec-10] s.w.s.m.m.a.RequestMappingHandlerMapping : Looking up handler method for path /error
2016-03-03 19:48:45.036 DEBUG 22401 --- [io-8080-exec-10] s.w.s.m.m.a.RequestMappingHandlerMapping : Returning handler method [public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)]
2016-03-03 19:48:45.036 DEBUG 22401 --- [io-8080-exec-10] o.s.web.servlet.DispatcherServlet : Last-Modified value for [/error] is: -1
2016-03-03 19:48:45.046 DEBUG 22401 --- [io-8080-exec-10] o.s.w.s.v.ContentNegotiatingViewResolver : Requested media types are [text/html, text/html;q=0.8] based on Accept header types and producible media types [text/html])
2016-03-03 19:48:45.047 DEBUG 22401 --- [io-8080-exec-10] o.s.w.s.v.ContentNegotiatingViewResolver : Returning [org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration$SpelView#7ae1a0fb] based on requested media type 'text/html'
2016-03-03 19:48:45.047 DEBUG 22401 --- [io-8080-exec-10] o.s.web.servlet.DispatcherServlet : Rendering view [org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration$SpelView#7ae1a0fb] in DispatcherServlet with name 'dispatcherServlet'
2016-03-03 19:48:45.055 DEBUG 22401 --- [io-8080-exec-10] o.s.web.servlet.DispatcherServlet : Successfully completed request
I'm not sure why DispatcherServlet is trying to lookup "/error". I am also not being logged out since if I try to go to the URL "/readingList" again, I am not prompted for credentials.
I did a little more testing by loggin in, then going to the URL "/logout" manually. I got the following in my log:
2016-03-04 16:39:31.170 DEBUG 24395 --- [nio-8080-exec-6] o.s.security.web.FilterChainProxy : /logout reached end of additional filter chain; proceeding with original chain
2016-03-04 16:39:31.170 DEBUG 24395 --- [nio-8080-exec-6] o.s.web.servlet.DispatcherServlet : DispatcherServlet with name 'dispatcherServlet' processing GET request for [/logout]
2016-03-04 16:39:31.170 DEBUG 24395 --- [nio-8080-exec-6] s.w.s.m.m.a.RequestMappingHandlerMapping : Looking up handler method for path /logout
2016-03-04 16:39:31.171 DEBUG 24395 --- [nio-8080-exec-6] s.w.s.m.m.a.RequestMappingHandlerMapping : Did not find handler method for [/logout]
2016-03-04 16:39:31.171 DEBUG 24395 --- [nio-8080-exec-6] o.s.w.s.handler.SimpleUrlHandlerMapping : Matching patterns for request [/logout] are [/**]
2016-03-04 16:39:31.171 DEBUG 24395 --- [nio-8080-exec-6] o.s.w.s.handler.SimpleUrlHandlerMapping : URI Template variables for request [/logout] are {}
2016-03-04 16:39:31.172 DEBU G 24395 --- [nio-8080-exec-6] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapping [/logout] to HandlerExecutionChain with handler [ResourceHttpRequestHandler [locations=[ServletContext resource [/], class path resource [META-INF/resources/], class path resource [resources/], class path resource [static/], class path resource [public/]], resolvers=[org.springframework.web.servlet.resource.PathResourceResolver#e146f93]]] and 1 interceptor
2016-03-04 16:39:31.172 DEBUG 24395 --- [nio-8080-exec-6] o.s.web.servlet.DispatcherServlet : Last-Modified value for [/logout] is: -1
2016-03-04 16:39:31.172 DEBUG 24395 --- [nio-8080-exec-6] o.s.web.servlet.DispatcherServlet : Null ModelAndView returned to DispatcherServlet with name 'dispatcherServlet': assuming HandlerAdapter completed request handling
2016-03-04 16:39:31.173 DEBUG 24395 --- [nio-8080-exec-6] o.s.web.servlet.DispatcherServlet : Successfully completed request
2016-03-04 16:39:31.173 DEBUG 24395 --- [nio-8080-exec-6] o.s.s.w.a.ExceptionTranslationFilter : Chain processed normally
2016-03-04 16:39:31.173 DEBUG 24395 --- [nio-8080-exec-6] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
2016-03-04 16:39:31.196 DEBUG 24395 --- [nio-8080-exec-6] o.s.web.servlet.DispatcherServlet : DispatcherServlet with name 'dispatcherServlet' processing GET request for [/error]
....
It seems like the "/logout" URL is not working which I don't undertand. I though the default logout URL is "/logout".

I found a solution in a similar project here, http://spr.com/part-5-integrating-spring-security-with-spring-boot-web/. In my security config I changed
.logout()
.logoutSuccessUrl("/")
.and()
...
to
.logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessUrl("/")
.and()
...
I'm not sure if this is the "preferred" solution, and I don't know why the call to logoutRequestMatcher(...) is needed. I have other (non-Spring-Boot) Spring Security projects that don't use the call to logoutRequestMatcher(...), and the .logout(...).logoutSuccessUrl(...) call works just fine.

.and()
.logout()
.invalidateHttpSession(true)
.logoutUrl("/logout")
.permitAll();
i prefer this solution because it wipe the session data so you can't access anymore try it yousrself to make sure open the developer tools in the browser and see the session !!

Related

Multitenancy is not working in my JHIpster application

I have followed some links to create multi-tenancy in my JHipster application,but its not working.
https://docs.jboss.org/hibernate/orm/current/userguide/html_single/Hibernate_User_Guide.html#multitenacy
https://www.baeldung.com/hibernate-5-multitenancy
https://github.com/jgasmi/jhipster-mt/
I did following:
Added following in my application-dev.yml:
datasource:
type: com.zaxxer.hikari.HikariDataSource
url: jdbc:mysql://localhost:3306/myApp?useUnicode=true&characterEncoding=utf8&useSSL=false&useLegacyDatetimeCode=false&serverTimezone=UTC&createDatabaseIfNotExist=true
username: root
password: root
serverName: localhost
hikari:
poolName: Hikari
auto-commit: false
data-source-properties:
cachePrepStmts: true
prepStmtCacheSize: 250
prepStmtCacheSqlLimit: 2048
useServerPrepStmts: true
jpa:
database-platform: org.hibernate.dialect.MySQL5InnoDBDialect
database: MYSQL
show-sql: true
properties:
hibernate.id.new_generator_mappings: true
hibernate.cache.use_query_cache: false
hibernate.generate_statistics: true
hibernate.cache.use_minimal_puts: true
hibernate.cache.hazelcast.use_lite_member: true
hibernate.tenant_identifier_resolver : com.mycompany.myapp.multitenancy.TenantIdentifierResolver
hibernate.multi_tenant_connection_provider : com.mycompany.myapp.multitenancy.SchemaMultiTenantConnectionProviderImpl
hibernate.multiTenancy : SCHEMA
My TenantIdentifierResolver class:
public class TenantIdentifierResolver implements CurrentTenantIdentifierResolver {
#Override
public String resolveCurrentTenantIdentifier() {
return "myapp2";
}
#Override
public boolean validateExistingCurrentSessions() {
return true;
}
}
And my class SchemaMultiTenantConnectionProviderImpl looks as follows:
public class SchemaMultiTenantConnectionProviderImpl implements MultiTenantConnectionProvider, ServiceRegistryAwareService
{
private final Logger log = LoggerFactory.getLogger(SchemaMultiTenantConnectionProviderImpl.class);
DataSource dataSource;
#Override
public Connection getAnyConnection() throws SQLException {
return this.dataSource.getConnection();
}
#Override
public void releaseAnyConnection(Connection connection) throws SQLException {
try {
connection.createStatement().execute("USE myapp2;");
}
catch (SQLException e) {
throw new HibernateException("Could not alter JDBC connection to specified schema [public]", e);
}
connection.close();
}
#Override
public Connection getConnection(String tenantIdentifier) throws SQLException {
log.warn("Get Connection for Tenatd is:"+tenantIdentifier);
final Connection connection = getAnyConnection();
/*
* try { connection.setCatalog(tenantIdentifier); //
* connection.createStatement().execute("USE " + tenantIdentifier + ";"); //
* connection.setCatalog(tenantIdentifier); //
* connection.setSchema(tenantIdentifier); } catch (SQLException e) { throw new
* HibernateException("Could not alter JDBC connection to specified schema [" +
* tenantIdentifier + "]", e); }
*/
return connection;
}
#Override
public void releaseConnection(String tenantIdentifier, Connection connection) throws SQLException {
// try {
// connection.createStatement().execute("USE "+tenantIdentifier+";");
// }
// catch (SQLException e) {
// throw new HibernateException("Could not alter JDBC connection to specified schema [public]", e);
// }
connection.close();
}
#Override
public boolean supportsAggressiveRelease() {
return false;
}
#Override
public boolean isUnwrappableAs(Class unwrapType) {
return false;
}
#Override
public <T> T unwrap(Class<T> unwrapType) {
return null;
}
#Override
public void injectServices(ServiceRegistryImplementor serviceRegistry) {
Map lSettings = serviceRegistry.getService(ConfigurationService.class).getSettings();
DataSource localDs = (DataSource) lSettings.get("hibernate.connection.datasource");
dataSource = localDs;
}
}
I am just trying to see first that it should work, and then I can change it to be based on tenant logic, schema tenancy logic or database tenancy logic.
When I run the application following is the logs:
D:\java-project\jhipsterptest-eclipse-workspace\sample\multitennnacy>mvnw -e
[INFO] Error stacktraces are turned on.
[INFO] Scanning for projects...
[INFO]
[INFO] --------------------------< com.myapp:my-app >--------------------------
[INFO] Building My App 0.0.1-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] >>> spring-boot-maven-plugin:2.4.7:run (default-cli) > test-compile # my-app >>>
[INFO]
[INFO] --- maven-resources-plugin:3.2.0:copy-resources (default-resources) # my-app ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Using 'UTF-8' encoding to copy filtered properties files.
[INFO] Copying 4 resources
[INFO] Copying 19 resources
[INFO]
[INFO] --- maven-resources-plugin:3.2.0:resources (default-resources) # my-app ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Using 'UTF-8' encoding to copy filtered properties files.
[INFO] Copying 4 resources
[INFO] Copying 19 resources
[INFO]
[INFO] --- maven-enforcer-plugin:3.0.0-M3:enforce (enforce-versions) # my-app ---
[INFO]
[INFO] --- maven-enforcer-plugin:3.0.0-M3:enforce (enforce-dependencyConvergence) # my-app ---
[WARNING]
Dependency convergence error for net.java.dev.jna:jna:5.2.0 paths to dependency are:
+-com.myapp:my-app:0.0.1-SNAPSHOT
+-org.testcontainers:mysql:1.15.3
+-org.testcontainers:jdbc:1.15.3
+-org.testcontainers:database-commons:1.15.3
+-org.testcontainers:testcontainers:1.15.3
+-org.rnorth.visible-assertions:visible-assertions:2.1.2
+-net.java.dev.jna:jna:5.2.0
and
+-com.myapp:my-app:0.0.1-SNAPSHOT
+-org.testcontainers:mysql:1.15.3
+-org.testcontainers:jdbc:1.15.3
+-org.testcontainers:database-commons:1.15.3
+-org.testcontainers:testcontainers:1.15.3
+-com.github.docker-java:docker-java-transport-zerodep:3.2.8
+-net.java.dev.jna:jna:5.8.0
[WARNING]
Dependency convergence error for org.wildfly.common:wildfly-common:1.5.2.Final paths to dependency are:
+-com.myapp:my-app:0.0.1-SNAPSHOT
+-org.springframework.boot:spring-boot-starter-undertow:2.4.7
+-io.undertow:undertow-core:2.2.8.Final
+-org.jboss.xnio:xnio-api:3.8.0.Final
+-org.wildfly.common:wildfly-common:1.5.2.Final
and
+-com.myapp:my-app:0.0.1-SNAPSHOT
+-org.springframework.boot:spring-boot-starter-undertow:2.4.7
+-io.undertow:undertow-core:2.2.8.Final
+-org.jboss.xnio:xnio-api:3.8.0.Final
+-org.wildfly.client:wildfly-client-config:1.0.1.Final
+-org.wildfly.common:wildfly-common:1.2.0.Final
[WARNING]
Dependency convergence error for org.apiguardian:apiguardian-api:1.1.0 paths to dependency are:
+-com.myapp:my-app:0.0.1-SNAPSHOT
+-org.springframework.boot:spring-boot-starter-test:2.4.7
+-org.junit.jupiter:junit-jupiter:5.7.2
+-org.junit.jupiter:junit-jupiter-api:5.7.2
+-org.apiguardian:apiguardian-api:1.1.0
and
+-com.myapp:my-app:0.0.1-SNAPSHOT
+-org.springframework.boot:spring-boot-starter-test:2.4.7
+-org.junit.jupiter:junit-jupiter:5.7.2
+-org.junit.jupiter:junit-jupiter-api:5.7.2
+-org.junit.platform:junit-platform-commons:1.7.2
+-org.apiguardian:apiguardian-api:1.1.0
and
+-com.myapp:my-app:0.0.1-SNAPSHOT
+-org.springframework.boot:spring-boot-starter-test:2.4.7
+-org.junit.jupiter:junit-jupiter:5.7.2
+-org.junit.jupiter:junit-jupiter-params:5.7.2
+-org.apiguardian:apiguardian-api:1.1.0
and
+-com.myapp:my-app:0.0.1-SNAPSHOT
+-org.springframework.boot:spring-boot-starter-test:2.4.7
+-org.junit.jupiter:junit-jupiter:5.7.2
+-org.junit.jupiter:junit-jupiter-engine:5.7.2
+-org.apiguardian:apiguardian-api:1.1.0
and
+-com.myapp:my-app:0.0.1-SNAPSHOT
+-com.tngtech.archunit:archunit-junit5-engine:0.19.0
+-com.tngtech.archunit:archunit-junit5-engine-api:0.19.0
+-org.junit.platform:junit-platform-engine:1.7.2
+-org.apiguardian:apiguardian-api:1.1.0
and
+-com.myapp:my-app:0.0.1-SNAPSHOT
+-org.zalando:problem-spring-web:0.26.2
+-org.zalando:problem-violations:0.26.2
+-org.apiguardian:apiguardian-api:1.1.0
and
+-com.myapp:my-app:0.0.1-SNAPSHOT
+-org.zalando:problem-spring-web:0.26.2
+-org.zalando:problem-spring-common:0.26.2
+-org.apiguardian:apiguardian-api:1.1.0
and
+-com.myapp:my-app:0.0.1-SNAPSHOT
+-org.zalando:problem-spring-web:0.26.2
+-org.apiguardian:apiguardian-api:1.1.0
and
+-com.myapp:my-app:0.0.1-SNAPSHOT
+-org.zalando:problem-spring-web:0.26.2
+-org.zalando:faux-pas:0.8.0
+-org.apiguardian:apiguardian-api:1.0.0
[WARNING] Rule 0: org.apache.maven.plugins.enforcer.DependencyConvergence failed with message:
Failed while enforcing releasability. See above detailed error message.
[INFO]
[INFO] --- jacoco-maven-plugin:0.8.7:prepare-agent (pre-unit-tests) # my-app ---
[INFO] argLine set to -javaagent:C:\\Users\\sachin\\.m2\\repository\\org\\jacoco\\org.jacoco.agent\\0.8.7\\org.jacoco.agent-0.8.7-runtime.jar=destfile=D:\\java-project\\jhipsterptest-eclipse-workspace\\sample\\multitennnacy\\target\\jacoco.exec -Djava.security.egd=file:/dev/./urandom -Xmx256m
[INFO]
[INFO] --- properties-maven-plugin:1.0.0:read-project-properties (default) # my-app ---
[INFO]
[INFO] --- checksum-maven-plugin:1.10:files (default) # my-app ---
[INFO]
[INFO] --- maven-antrun-plugin:3.0.0:run (eval-frontend-checksum) # my-app ---
[INFO] Executing tasks
[INFO] [copy] Copying 1 file to D:\java-project\jhipsterptest-eclipse-workspace\sample\multitennnacy\target
[INFO] Executed tasks
[INFO]
[INFO] --- frontend-maven-plugin:1.12.0:install-node-and-npm (install-node-and-npm) # my-app ---
[INFO] Node v14.17.1 is already installed.
[INFO] NPM 7.18.1 is already installed.
[INFO]
[INFO] --- frontend-maven-plugin:1.12.0:npm (npm install) # my-app ---
[INFO] Skipping execution.
[INFO]
[INFO] --- frontend-maven-plugin:1.12.0:npm (webapp build dev) # my-app ---
[INFO] Skipping execution.
[INFO]
[INFO] --- maven-compiler-plugin:3.8.1:compile (default-compile) # my-app ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 81 source files to D:\java-project\jhipsterptest-eclipse-workspace\sample\multitennnacy\target\classes
[INFO] /D:/java-project/jhipsterptest-eclipse-workspace/sample/multitennnacy/src/main/java/com/mycompany/myapp/multitenancy/ConnectionProviderFactory.java: D:\java-project\jhipsterptest-eclipse-workspace\sample\multitennnacy\src\main\java\com\mycompany\myapp\multitenancy\ConnectionProviderFactory.java uses unchecked or unsafe operations.
[INFO] /D:/java-project/jhipsterptest-eclipse-workspace/sample/multitennnacy/src/main/java/com/mycompany/myapp/multitenancy/ConnectionProviderFactory.java: Recompile with -Xlint:unchecked for details.
[INFO]
[INFO] --- maven-resources-plugin:3.2.0:testResources (default-testResources) # my-app ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Using 'UTF-8' encoding to copy filtered properties files.
[INFO] Copying 5 resources
[INFO]
[INFO] --- maven-compiler-plugin:3.8.1:testCompile (default-testCompile) # my-app ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 29 source files to D:\java-project\jhipsterptest-eclipse-workspace\sample\multitennnacy\target\test-classes
[INFO] /D:/java-project/jhipsterptest-eclipse-workspace/sample/multitennnacy/src/test/java/com/myapp/service/MailServiceIT.java: D:\java-project\jhipsterptest-eclipse-workspace\sample\multitennnacy\src\test\java\com\myapp\service\MailServiceIT.java uses or overrides a deprecated API.
[INFO] /D:/java-project/jhipsterptest-eclipse-workspace/sample/multitennnacy/src/test/java/com/myapp/service/MailServiceIT.java: Recompile with -Xlint:deprecation for details.
[INFO]
[INFO] <<< spring-boot-maven-plugin:2.4.7:run (default-cli) < test-compile # my-app <<<
[INFO]
[INFO]
[INFO] --- spring-boot-maven-plugin:2.4.7:run (default-cli) # my-app ---
[INFO] Attaching agents: []
??? ??? ??? ????????? ???????? ??????? ????????? ????????? ????????
??? ??? ??? ????????? ????????? ???????? ????????? ????????? ?????????
??? ????????? ??? ????????? ??????? ??? ??????? ?????????
??? ??? ????????? ??? ???????? ??????? ??? ??????? ????????
????????? ??? ??? ????????? ??? ???????? ??? ????????? ??? ????
??????? ??? ??? ????????? ??? ??????? ??? ????????? ??? ???
:: JHipster ? :: Running Spring Boot 2.4.7 ::
:: https://www.jhipster.tech ::
2021-07-14 10:46:05.956 DEBUG 24976 --- [kground-preinit] org.jboss.logging : Logging Provider: org.jboss.logging.Log4j2LoggerProvider
2021-07-14 10:46:05.988 INFO 24976 --- [ restartedMain] com.myapp.MyApp : Starting MyApp using Java 11.0.11 on SACHIN-MSI with PID 24976 (D:\java-project\jhipsterptest-eclipse-workspace\sample\multitennnacy\target\classes started by sachin in D:\java-project\jhipsterptest-eclipse-workspace\sample\multitennnacy)
2021-07-14 10:46:05.989 DEBUG 24976 --- [ restartedMain] com.myapp.MyApp : Running with Spring Boot v2.4.7, Spring v5.3.8
2021-07-14 10:46:05.989 INFO 24976 --- [ restartedMain] com.myapp.MyApp : The following profiles are active: dev,api-docs
2021-07-14 10:46:09.018 DEBUG 24976 --- [ restartedMain] i.m.c.u.i.logging.InternalLoggerFactory : Using SLF4J as the default logging framework
2021-07-14 10:46:09.217 DEBUG 24976 --- [ restartedMain] com.myapp.config.WebConfigurer : Registering CORS filter
2021-07-14 10:46:09.283 INFO 24976 --- [ restartedMain] com.myapp.config.WebConfigurer : Web application configuration, using profiles: dev
2021-07-14 10:46:09.283 INFO 24976 --- [ restartedMain] com.myapp.config.WebConfigurer : Web application fully configured
2021-07-14 10:46:09.570 DEBUG 24976 --- [ restartedMain] c.ehcache.core.Ehcache-usersByLogin : Initialize successful.
2021-07-14 10:46:09.592 DEBUG 24976 --- [ restartedMain] c.ehcache.core.Ehcache-usersByEmail : Initialize successful.
2021-07-14 10:46:09.595 DEBUG 24976 --- [ restartedMain] c.e.core.Ehcache-com.myapp.domain.User : Initialize successful.
2021-07-14 10:46:09.599 DEBUG 24976 --- [ restartedMain] c.e.c.E.myapp.domain.Authority : Initialize successful.
2021-07-14 10:46:09.602 DEBUG 24976 --- [ restartedMain] c.e.c.E.myapp.domain.User.authorities : Initialize successful.
2021-07-14 10:46:09.605 DEBUG 24976 --- [ restartedMain] c.e.c.Ehcache-com.myapp.domain.Tenant : Initialize successful.
2021-07-14 10:46:09.608 DEBUG 24976 --- [ restartedMain] c.e.c.Ehcache-com.myapp.domain.DbType : Initialize successful.
2021-07-14 10:46:09.622 DEBUG 24976 --- [ restartedMain] com.myapp.config.AsyncConfiguration : Creating Async Task Executor
2021-07-14 10:46:09.692 DEBUG 24976 --- [ restartedMain] com.myapp.config.LiquibaseConfiguration : Configuring Liquibase
2021-07-14 10:46:09.829 WARN 24976 --- [ my-app-task-1] t.j.c.liquibase.AsyncSpringLiquibase : Starting Liquibase asynchronously, your database might not be ready at startup!
2021-07-14 10:46:11.299 DEBUG 24976 --- [ restartedMain] com.myapp.security.jwt.TokenProvider : Using a Base64-encoded JWT secret key
2021-07-14 10:46:12.920 DEBUG 24976 --- [ restartedMain] t.j.c.apidoc.SpringfoxAutoConfiguration : Starting OpenAPI docs
2021-07-14 10:46:12.927 DEBUG 24976 --- [ restartedMain] t.j.c.apidoc.SpringfoxAutoConfiguration : Started OpenAPI docs in 5 ms
2021-07-14 10:46:13.623 INFO 24976 --- [ restartedMain] org.jboss.threads : JBoss Threads version 3.1.0.Final
2021-07-14 10:46:14.116 INFO 24976 --- [ restartedMain] com.myapp.MyApp : Started MyApp in 8.783 seconds (JVM running for 9.535)
2021-07-14 10:46:14.124 INFO 24976 --- [ restartedMain] com.myapp.MyApp :
----------------------------------------------------------
Application 'myApp' is running! Access URLs:
Local: http://localhost:8080/
External: http://192.168.43.1:8080/
Profile(s): [dev, api-docs]
----------------------------------------------------------
There are no error logs, but browser shows this.
Seems like I am missing something small, but not ablw to find it out.

Possible issue with Publish subscribe Channel

I have an application that monitors FTP folder for a specific csv file foo.csv, once the file is located it pulls it to my local and generate a new output format bar.csv, the application then will send the new file finalBEY.csv back to the FTP folder and erase it from local.
Now that I have introduced a process using publishSubscribeChannel where it transforms the file to a message then uses jobLaunchingGateway that will read finalBEY.csv using batch and print it to the consol, it is not working since the finalBEY.csv is being deleted from the local forlder after sending it back to FTP, I'm using .channel("nullChannel") on the jobLaunchingGateway within the first subscribe which suppose to hold it until having a reply from the batch and then moves to the next subscribe which will send it to the ftp and remove it from local, but seems it is not the case where it is removing it from local and thus the batch is not finding finalBEY.csv and throws an error that I'm pasting below with the code.
If I remove the advice from the second subscribe it works fine as this will not delete it from local anymore.
Can you please assist on this matter?
public IntegrationFlow localToFtpFlow(Branch myBranch) {
return IntegrationFlows.from(Files.inboundAdapter(new File(myBranch.getBranchCode()))
.filter(new ChainFileListFilter<File>()
.addFilter(new RegexPatternFileListFilter("final" + myBranch.getBranchCode() + ".csv"))
.addFilter(new FileSystemPersistentAcceptOnceFileListFilter(metadataStore(dataSource), "foo"))),//FileSystemPersistentAcceptOnceFileListFilter
e -> e.poller(Pollers.fixedDelay(10_000)))
.enrichHeaders(h ->h.headerExpression("file_originalFile", "new java.io.File('"+ myBranch.getBranchCode() +"/FEFOexport" + myBranch.getBranchCode() + ".csv')",true))
.transform(p -> {
LOG.info("Sending file " + p + " to FTP branch " + myBranch.getBranchCode());
return p;
})
.log()
.transform(m -> {
this.defaultSessionFactoryLocator.addSessionFactory(myBranch.getBranchCode(),createNewFtpSessionFactory(myBranch));
LOG.info("Adding factory to delegation");
return m;
})
.publishSubscribeChannel(s ->
s.subscribe(f ->f.transform(fileMessageToJobRequest())
.handle(jobLaunchingGateway()).channel("nullChannel"))
.subscribe(h -> h.handle(Ftp.outboundAdapter(createNewFtpSessionFactory(myBranch), FileExistsMode.REPLACE)
.useTemporaryFileName(true)
.autoCreateDirectory(false)
.remoteDirectory(myBranch.getFolderPath()), e -> e.advice(expressionAdvice()))))
.get();
}
#Bean
public FileMessageToJobRequest fileMessageToJobRequest(){
FileMessageToJobRequest fileMessageToJobRequest = new FileMessageToJobRequest();
fileMessageToJobRequest.setFileParameterName("file_path");
fileMessageToJobRequest.setJob(orderJob);
return fileMessageToJobRequest;
}
#Bean
public JobLaunchingGateway jobLaunchingGateway() {
SimpleJobLauncher simpleJobLauncher = new SimpleJobLauncher();
simpleJobLauncher.setJobRepository(jobRepository);
simpleJobLauncher.setTaskExecutor(new SyncTaskExecutor());
JobLaunchingGateway jobLaunchingGateway = new JobLaunchingGateway(simpleJobLauncher);
return jobLaunchingGateway;
}
/**
* Creating the advice for routing the payload of the outbound message on different expressions (success, failure)
* #return Advice
*/
#Bean
public Advice expressionAdvice() {
ExpressionEvaluatingRequestHandlerAdvice advice = new ExpressionEvaluatingRequestHandlerAdvice();
advice.setSuccessChannelName("success.input");
advice.setOnSuccessExpressionString("payload.delete() + ' was successful'");
//advice.setOnSuccessExpressionString("inputMessage.headers['file_originalFile'].renameTo(new java.io.File(payload.absolutePath + '.success.to.send'))");
//advice.setFailureChannelName("failure.input");
advice.setOnFailureExpressionString("payload + ' was bad, with reason: ' + #exception.cause.message");
advice.setTrapException(true);
return advice;
}
Here is the error and as you can see the first lines show that it is transferred to FTP and then initiated the batch job while in the subscribe should do the batch first...
INFO 10452 --- [ask-scheduler-2] o.s.integration.ftp.session.FtpSession : File has been successfully renamed from: /ftp/erbranch/EDMS/FEFO/finalBEY.csv.writing to /ftp/erbranch/EDMS/FEFO/finalBEY.csv
Caused by: java.lang.IllegalStateException: Input resource must exist (reader is in 'strict' mode): file [C:\Java Programs\spring4ftpappftp\BEY\finalBEY.csv]
at org.springframework.batch.item.file.FlatFileItemReader.doOpen(FlatFileItemReader.java:251) ~[spring-batch-infrastructure-4.0.1.RELEASE.jar:4.0.1.RELEASE]
at org.springframework.batch.item.support.AbstractItemCountingItemStreamItemReader.open(AbstractItemCountingItemStreamItemReader.java:146) ~[spring-batch-infrastructure-4.0.1.RELEASE.jar:4.0.1.RELEASE]
... 123 common frames omitted
Debugging code:
2019-07-15 10:43:02.838 INFO 4280 --- [ask-scheduler-2] o.s.integration.ftp.session.FtpSession : File has been successfully transferred to: /ftp/erbranch/EDMS/FEFO/finalBEY.csv.writing
2019-07-15 10:43:02.845 INFO 4280 --- [ask-scheduler-2] o.s.integration.ftp.session.FtpSession : File has been successfully renamed from: /ftp/erbranch/EDMS/FEFO/finalBEY.csv.writing to /ftp/erbranch/EDMS/FEFO/finalBEY.csv
2019-07-15 10:43:02.845 DEBUG 4280 --- [ask-scheduler-2] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'integrationEvaluationContext'
2019-07-15 10:43:02.848 DEBUG 4280 --- [ask-scheduler-2] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'success.input'
2019-07-15 10:43:02.849 DEBUG 4280 --- [ask-scheduler-2] o.s.integration.channel.DirectChannel : preSend on channel 'success.input', message: AdviceMessage [payload=true was successful, headers={id=eca55e1d-918e-3334-afce-66f8ab650748, timestamp=1563176582848}, inputMessage=GenericMessage [payload=BEY\finalBEY.csv, headers={file_originalFile=BEY\FEFOexportBEY.csv, id=a2f029b0-2609-1a11-67ef-4f56c7dd0752, file_name=finalBEY.csv, file_relativePath=finalBEY.csv, timestamp=1563176582787}]]
2019-07-15 10:43:02.849 DEBUG 4280 --- [ask-scheduler-2] o.s.i.t.MessageTransformingHandler : success.org.springframework.integration.transformer.MessageTransformingHandler#0 received message: AdviceMessage [payload=true was successful, headers={id=eca55e1d-918e-3334-afce-66f8ab650748, timestamp=1563176582848},
inputMessage=GenericMessage [payload=BEY\finalBEY.csv, headers={file_originalFile=BEY\FEFOexportBEY.csv, id=a2f029b0-2609-1a11-67ef-4f56c7dd0752, file_name=finalBEY.csv, file_relativePath=finalBEY.csv, timestamp=1563176582787}]]
2019-07-15 10:43:02.951 DEBUG 4280 --- [ask-scheduler-2] o.s.b.i.launch.JobLaunchingGateway : jobLaunchingGateway received message: GenericMessage [payload=JobLaunchRequest: orderJob, parameters={file_path=C:\Java Programs\spring4ftpappftp\BEY\finalBEY.csv, dummy=1563176582946}, headers={file_originalFile=BEY\FEFOexportBEY.csv, id=c98ad6cb-cced-c911-1b93-9d054baeb9d0, file_name=finalBEY.csv, file_relativePath=finalBEY.csv, timestamp=1563176582951}]
2019-07-16 08:35:29.442 INFO 10208 --- [nio-8081-exec-3] o.s.i.channel.PublishSubscribeChannel : Channel 'application.FTPOutp' has 1 subscriber(s).
2019-07-16 08:35:29.442 INFO 10208 --- [nio-8081-exec-3] o.s.i.endpoint.EventDrivenConsumer : started 1o.org.springframework.integration.config.ConsumerEndpointFactoryBean#3
2019-07-16 08:35:29.442 INFO 10208 --- [nio-8081-exec-3] o.s.i.endpoint.EventDrivenConsumer : Adding {message-handler} as a subscriber to the '1o.subFlow#1.channel#0' channel
2019-07-16 08:35:29.442 INFO 10208 --- [nio-8081-exec-3] o.s.integration.channel.DirectChannel : Channel 'application.1o.subFlow#1.channel#0' has 1 subscriber(s).
2019-07-16 08:35:29.442 INFO 10208 --- [nio-8081-exec-3] o.s.i.endpoint.EventDrivenConsumer : started 1o.subFlow#1.org.springframework.integration.config.ConsumerEndpointFactoryBean#1
2019-07-16 08:35:29.442 INFO 10208 --- [nio-8081-exec-3] o.s.i.endpoint.EventDrivenConsumer : Adding {bridge} as a subscriber to the 'FTPOutp' channel
2019-07-16 08:35:29.442 INFO 10208 --- [nio-8081-exec-3] o.s.i.channel.PublishSubscribeChannel : Channel 'application.FTPOutp' has 2 subscriber(s).
Since you are using a SyncTaskExecutor the batch job should run on the calling thread and then followed by the FTP adapter.
Use DEBUG logging and follow the message flow to see why that's not happening.

asp.net core site behind proxy: Azure B2C signin results in correlation failed

I've got a web app that uses Azure B2C sign in. When I run the site locally, with config set to signin to the Azure B2C tenant, everything works as expected.
I then deploy the site to Azure where I have two webapp siting behind a FrontDoor proxy/load balancing configuration. I have also tried the same using traffic manager.
When I click on the Sign In link, which should redirect me to the Sign In B2C page, instead, I am redirected back to my site and get an error on the webpage: Correlation failed.
Assuming I have two web apps in the frontdoor configuration, called:
mywebapp-eastus
mywebapp-westus
and assuming the public domainname is https://www.mywebapp.com
when i make sign in require, in the response headers of the signin-oidc request, I am seeing this:
set-cookie: ARRAffinity=335ad67894a0a02a521f095924a8d7be4f7829a49d21743b7dd9ec8ce66879d7;Path=/;HttpOnly;Domain=mywebapp-eastus.azurewebsites.net
where mywebapp-eastus is actually an individual web app name. I would have expected to see the public domain here, not the individual web app that I connected to.
As can be seen from this Chrome dev tool screenshot, the signin-oidc then results in an error after the redirect has occurred:
I would expect to see this instead:
ARRAffinity=335ad67894a0a02a521f095924a8d7be4f7829a49d21743b7dd9ec8ce66879d7;Path=/;HttpOnly;Domain=www.mywebapp.com
I don't know if this is the underlying reason for the error.
Here is the code that sets up authentication and cookies:
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.Configure<ApiBehaviorOptions>(options =>
{
options.InvalidModelStateResponseFactory = ctx => new ValidationProblemDetailsResult();
});
services.AddAuthentication(sharedOptions =>
{
sharedOptions.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
sharedOptions.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
sharedOptions.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddAzureAdB2C(options => Configuration.Bind(AppSettings.AzureB2CSettings, options))
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, options =>
{
options.ExpireTimeSpan = TimeSpan.FromMinutes(60);
options.SlidingExpiration = true;
options.Cookie.HttpOnly = false;
options.Cookie.SecurePolicy = CookieSecurePolicy.SameAsRequest;
});
Update
I have added x-forwarded-proto options with no noticeable effect:
var forwardingOptions = new ForwardedHeadersOptions()
{
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
};
forwardingOptions.KnownNetworks.Clear();
forwardingOptions.KnownProxies.Clear();
app.UseForwardedHeaders(forwardingOptions);
I thought i had found a related issue here: x-forwarded-proto-not-working
Any idea how I can resolve this issue? What options can I set so that the public domain is correctly populated into the response headers.
The web app is running asp.netcore 2.2 on linux (web app for containers).
Update 2:
I've added logging to the site. It shows that there's an underlying error: Cookie not found and Correlation failed
Information {Protocol="HTTP/1.1", Method="POST", ContentType="application/x-www-form-urlencoded", ContentLength=722, Scheme="http", Host="webapp-eastus.azurewebsites.net", PathBase="", Path="/signin-oidc", QueryString="", EventId={Id=1}, SourceContext="Microsoft.AspNetCore.Hosting.Internal.WebHost", RequestId="0HLKC8D934664:00000001", RequestPath="/signin-oidc", CorrelationId=null, ConnectionId="0HLKC8D934664"} "Request starting HTTP/1.1 POST http://webapp-eastus.azurewebsites.net/signin-oidc application/x-www-form-urlencoded 722"
Debug {EventId={Id=1}, SourceContext="Microsoft.AspNetCore.HttpsPolicy.HstsMiddleware", RequestId="0HLKC8D934664:00000001", RequestPath="/signin-oidc", CorrelationId=null, ConnectionId="0HLKC8D934664"} The request is insecure. Skipping HSTS header.
Debug {EventId={Id=1}, SourceContext="Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware", RequestId="0HLKC8D934664:00000001", RequestPath="/signin-oidc", CorrelationId=null, ConnectionId="0HLKC8D934664"} "POST" requests are not supported
Debug {EventId={Id=25, Name="RequestBodyStart"}, SourceContext="Microsoft.AspNetCore.Server.Kestrel", RequestId="0HLKC8D934664:00000001", RequestPath="/signin-oidc", CorrelationId=null} Connection id ""0HLKC8D934664"", Request id ""0HLKC8D934664:00000001"": started reading request body.
Debug {EventId={Id=26, Name="RequestBodyDone"}, SourceContext="Microsoft.AspNetCore.Server.Kestrel", RequestId="0HLKC8D934664:00000001", RequestPath="/signin-oidc", CorrelationId=null} Connection id ""0HLKC8D934664"", Request id ""0HLKC8D934664:00000001"": done reading request body.
[40m[1m[33mwarn[39m[22m[49m: Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectHandler[15]
'.AspNetCore.Correlation.OpenIdConnect.2KB8HPHJV3KhB2HCDp3C3b5iPXjcdAQLOrz5-6nGnwY' cookie not found.
Warning {EventId={Id=15}, SourceContext="Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectHandler", RequestId="0HLKC8D934664:00000001", RequestPath="/signin-oidc", CorrelationId=null, ConnectionId="0HLKC8D934664"} '".AspNetCore.Correlation.OpenIdConnect.2KB8HPHJV3KhB2HCDp3C3b5iPXjcdAQLOrz5-6nGnwY"' cookie not found.
Information {EventId={Id=4}, SourceContext="Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectHandler", RequestId="0HLKC8D934664:00000001", RequestPath="/signin-oidc", CorrelationId=null, ConnectionId="0HLKC8D934664"} Error from RemoteAuthentication: "Correlation failed.".
Debug {SourceContext="AppBuilderExtensions", RequestId="0HLKC8D934663:00000001", RequestPath="/", CorrelationId=null, ConnectionId="0HLKC8D934663"} Header: "User-Agent": ["Edge Health Probe"]
Debug {SourceContext="AppBuilderExtensions", RequestId="0HLKC8D934663:00000001", RequestPath="/", CorrelationId=null, ConnectionId="0HLKC8D934663"} Header: "X-Client-IP": ["1.1.1.1"]
Information {ElapsedMilliseconds=12.3269, StatusCode=302, ContentType=null, EventId={Id=2}, SourceContext="Microsoft.AspNetCore.Hosting.Internal.WebHost", RequestId="0HLKC8D934664:00000001", RequestPath="/signin-oidc", CorrelationId=null, ConnectionId="0HLKC8D934664"} "Request finished in 12.3269ms 302 "
Debug {EventId={Id=6, Name="ConnectionReadFin"}, SourceContext="Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets"} Connection id ""0HLKC8D934664"" received FIN.
Debug {EventId={Id=7, Name="ConnectionWriteFin"}, SourceContext="Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets"} Connection id ""0HLKC8D934664"" sending FIN because: ""The client closed the connection.""
Debug {SourceContext="AppBuilderExtensions", RequestId="0HLKC8D934663:00000001", RequestPath="/", CorrelationId=null, ConnectionId="0HLKC8D934663"} Header: "X-Client-Port": ["63761"]
Debug {SourceContext="AppBuilderExtensions", RequestId="0HLKC8D934663:00000001", RequestPath="/", CorrelationId=null, ConnectionId="0HLKC8D934663"} Header: "X-FD-HealthProbe": ["1"]
Debug {SourceContext="AppBuilderExtensions", RequestId="0HLKC8D934663:00000001", RequestPath="/", CorrelationId=null, ConnectionId="0HLKC8D934663"} Header: "X-WAWS-Unencoded-URL": ["/"]
Debug {SourceContext="AppBuilderExtensions", RequestId="0HLKC8D934663:00000001", RequestPath="/", CorrelationId=null, ConnectionId="0HLKC8D934663"} Header: "CLIENT-IP": ["1.1.1.1:63761"]
Debug {SourceContext="AppBuilderExtensions", RequestId="0HLKC8D934663:00000001", RequestPath="/", CorrelationId=null, ConnectionId="0HLKC8D934663"} Header: "X-ARR-LOG-ID": ["5022cb4d-7c63-4a78-ad11-c8474246281d"]
Debug {SourceContext="AppBuilderExtensions", RequestId="0HLKC8D934663:00000001", RequestPath="/", CorrelationId=null, ConnectionId="0HLKC8D934663"} Header: "DISGUISED-HOST": ["webapp-eastus.azurewebsites.net"]
Debug {SourceContext="AppBuilderExtensions", RequestId="0HLKC8D934663:00000001", RequestPath="/", CorrelationId=null, ConnectionId="0HLKC8D934663"} Header: "X-SITE-DEPLOYMENT-ID": ["webapp-eastus"]
Debug {SourceContext="AppBuilderExtensions", RequestId="0HLKC8D934663:00000001", RequestPath="/", CorrelationId=null, ConnectionId="0HLKC8D934663"} Header: "WAS-DEFAULT-HOSTNAME": ["webapp-eastus.azurewebsites.net"]
Debug {SourceContext="AppBuilderExtensions", RequestId="0HLKC8D934663:00000001", RequestPath="/", CorrelationId=null, ConnectionId="0HLKC8D934663"} Header: "X-Original-URL": ["/"]
Debug {EventId={Id=10, Name="ConnectionDisconnect"}, SourceContext="Microsoft.AspNetCore.Server.Kestrel"} Connection id ""0HLKC8D934664"" disconnecting.
Debug {EventId={Id=2, Name="ConnectionStop"}, SourceContext="Microsoft.AspNetCore.Server.Kestrel"} Connection id ""0HLKC8D934664"" stopped.
Just to be clear, I sticky sessions have been activated on the FrontDoor configuration. I also tried stopping one of the web apps during login to see what the effect was. Same behaviour. So, I don't think this is a DataProtection related issue.
Update 3
I think I may have found the underlying issue. I found this error:
AADB2C90006: The redirect URI 'https://webapp-eastus.azurewebsites.net/signin-oidc' provided in the request is not registered for the client id 'zzzzzzz-2121-4158-b0f8-9d164c95000'.
Correlation ID: xxxxxxxxx-xxxxxxxxx-xxxxxxx-xxxxxxx
When I looked for the X-Forwarded * headers in the request, I found they are missing. This is even though I have a block of code that looks like this:
services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardedHeaders =
ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
});
in ConfigureServices, in Startup.cs
In Configure() I have this:
public void Configure(IApplicationBuilder app)
{
app.UseForwardedHeaders();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
app.Use((context, next) =>
{
context.Request.Scheme = "https";
return next();
});
app.UseSession();
app.UseAuthentication();
app.LogAuthenticationRequests(_loggerFactory);
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
The question now is, why would the X-Forwarded-* headers be missing from requests?

Spring Integration Bridge with poller not working as expected for JMS

Using spring-integration 5.0.7 to throttle the bridging of msgs between two JMS queues.
The docs at: https://docs.spring.io/spring-integration/docs/5.0.7.RELEASE/reference/html/messaging-channels-section.html#bridge-namespace
suggest:
<int:bridge input-channel="pollable" output-channel="subscribable">
<int:poller max-messages-per-poll="10" fixed-rate="5000"/>
</int:bridge>
But schema validator complains "no nested poller allowed for subscribable input channel" on bridge elt.
But, if I put the poller on the input-channel-adapter as in:
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns:int="http://www.springframework.org/schema/integration"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:int-jms="http://www.springframework.org/schema/integration/jms"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/integration
http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/jms
http://www.springframework.org/schema/integration/jms/spring-integration-jms.xsd
">
<int:channel id="inChannel" />
<int:channel id="outChannel" />
<int-jms:inbound-channel-adapter id="jmsIn" connection-factory="jmsConnectionFactory" destination-name="_dev.inQueue" channel="inChannel">
<int:poller fixed-delay="5000" max-messages-per-poll="2"/>
</int-jms:inbound-channel-adapter>
<int-jms:outbound-channel-adapter id="jmsOut" connection-factory="jmsConnectionFactory" destination-name="_dev.outQueue" channel="outChannel"/>
<int:bridge input-channel="inChannel" output-channel="outChannel">
</int:bridge>
</beans:beans>
Nothing is ever moved from input to output.
How can I bridge from one JMS queue to another with a rate-limit?
Update:
Turning on logging confirms nothing getting picked up from input channel but otherwise not helpful:
018-08-10 15:36:33.345 DEBUG 112066 --- [ask-scheduler-1] o.s.i.e.SourcePollingChannelAdapter : Received no Message during the poll, returning 'false'
2018-08-10 15:36:38.113 DEBUG 112066 --- [ask-scheduler-2] o.s.integration.jms.DynamicJmsTemplate : Executing callback on JMS Session: ActiveMQSession {id=ID:whitechapel-35247-1533940593148-3:2:1,started=true} java.lang.Object#5c278302
2018-08-10 15:36:38.116 DEBUG 112066 --- [ask-scheduler-2] o.s.i.e.SourcePollingChannelAdapter : Received no Message during the poll, returning 'false'
2018-08-10 15:36:43.115 DEBUG 112066 --- [ask-scheduler-1] o.s.integration.jms.DynamicJmsTemplate : Executing callback on JMS Session: ActiveMQSession {id=ID:whitechapel-35247-1533940593148-3:3:1,started=true} java.lang.Object#1c09a81e
2018-08-10 15:36:43.118 DEBUG 112066 --- [ask-scheduler-1] o.s.i.e.SourcePollingChannelAdapter : Received no Message during the poll, returning 'false'
Here is a Spring Boot app, using Java DSL configuration which is the exact equivalent of what you have in XML (minus the bridge); it works fine.
#SpringBootApplication
public class So51792909Application {
private static final Logger logger = LoggerFactory.getLogger(So51792909Application.class);
public static void main(String[] args) {
SpringApplication.run(So51792909Application.class, args);
}
#Bean
public ApplicationRunner runner(JmsTemplate template) {
return args -> {
for (int i = 0; i < 10; i++) {
template.convertAndSend("foo", "test");
}
};
}
#Bean
public IntegrationFlow flow(ConnectionFactory connectionFactory) {
return IntegrationFlows.from(Jms.inboundAdapter(connectionFactory)
.destination("foo"), e -> e
.poller(Pollers
.fixedDelay(5000)
.maxMessagesPerPoll(2)))
.handle(Jms.outboundAdapter(connectionFactory)
.destination("bar"))
.get();
}
#JmsListener(destination = "bar")
public void listen(String in) {
logger.info(in);
}
}
and
2018-08-10 19:38:52.534 INFO 13408 --- [enerContainer-1] com.example.So51792909Application : test
2018-08-10 19:38:52.543 INFO 13408 --- [enerContainer-1] com.example.So51792909Application : test
2018-08-10 19:38:57.566 INFO 13408 --- [enerContainer-1] com.example.So51792909Application : test
2018-08-10 19:38:57.582 INFO 13408 --- [enerContainer-1] com.example.So51792909Application : test
2018-08-10 19:39:02.608 INFO 13408 --- [enerContainer-1] com.example.So51792909Application : test
2018-08-10 19:39:02.622 INFO 13408 --- [enerContainer-1] com.example.So51792909Application : test
2018-08-10 19:39:07.640 INFO 13408 --- [enerContainer-1] com.example.So51792909Application : test
2018-08-10 19:39:07.653 INFO 13408 --- [enerContainer-1] com.example.So51792909Application : test
2018-08-10 19:39:12.672 INFO 13408 --- [enerContainer-1] com.example.So51792909Application : test
2018-08-10 19:39:12.687 INFO 13408 --- [enerContainer-1] com.example.So51792909Application : test
As you can see, the consumer gets 2 messages every 5 seconds.
Your debug log implies there are no messages in the queue.
EDIT
I figured it out; the XML parser sets the JmsTemplate receiveTimeout to nowait (-1). Since you are not using a caching connection factory, we'll never get a message because the ActiveMQ client returns immediately if there's not already a message present in the client (see this answer). Since there's no caching going on, we get a new consumer on every poll (and do a no-wait receive each time).
The DSL leaves the JmsTemplate's default (Infinite wait - which is actually wrong since it blocks the poller thread indefinitely if there are no messages).
To fix the XML version, adding receive-timeout="1000" fixes it.
However, it's better to use a CachingConnectionFactory to avoid creating a new connection/session/consumer on each poll.
Unfortunately, configurating a CachingConnectionFactory turns off Spring Boot's auto-configuration. This is fixed in Boot 2.1.
I have opened an issue to resolve the inconsistency between the DSL and XML here.
If you stick with the DSL, I would recommend setting the receive timeout to something reasonable, rather than indefinite:
#Bean
public IntegrationFlow flow(ConnectionFactory connectionFactory) {
return IntegrationFlows.from(Jms.inboundAdapter(connectionFactory)
.configureJmsTemplate(t -> t.receiveTimeout(1000))
.destination("foo"), e -> e
.poller(Pollers
.fixedDelay(5000)
.maxMessagesPerPoll(2)))
.handle(Jms.outboundAdapter(connectionFactory)
.destination("bar"))
.get();
}
But, the best solution is to use a CachingConnectionFactory.

Slave configuration for listening to messages in spring batch using spring integration

Can I have a job with just the slaves and no master and listen to a rabbitmq queue? I want to listen to a queue and process the messages in chunk oriented manner using spring batch and spring integration in a spring boot app.
I want to use the chunkProcessorChunkHandler configuration explained in the RemoteChunking example for Spring batch by Michael Minella (https://www.youtube.com/watch?v=30Tdp1mfR0g), but without a master configuration.
Below is my configuration for the job.
#Configuration
#EnableIntegration
public class QueueIntegrationConfiguration {
#Autowired
private CassandraItemWriter cassandraItemWriter;
#Autowired
private VendorProcessor vendorProcessor;
#Autowired
ConnectionFactory connectionFactory;
#Bean
public AmqpInboundChannelAdapter inboundChannelAdapter(
SimpleMessageListenerContainer listenerContainer) {
AmqpInboundChannelAdapter adapter = new AmqpInboundChannelAdapter(listenerContainer);
adapter.setOutputChannel(inboundQueueChannel());
adapter.setAutoStartup(true);
return adapter;
}
#Bean
public SimpleMessageListenerContainer listenerContainer(ConnectionFactory connectionFactory, MessageConverter jsonMessageConverter) {
SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(
connectionFactory);
container.setQueueNames("ProductStore_Partial");
container.setAutoStartup(true);
container.setMessageConverter(jsonMessageConverter);
return container;
}
#Bean
#ServiceActivator(inputChannel = "ProductStore_Partial")
public ChunkProcessorChunkHandler chunkProcessorChunkHandler()
throws Exception {
SimpleChunkProcessor chunkProcessor = new SimpleChunkProcessor(vendorProcessor,
cassandraItemWriter);
chunkProcessor.afterPropertiesSet();
ChunkProcessorChunkHandler<Vendor> chunkHandler = new ChunkProcessorChunkHandler<>();
chunkHandler.setChunkProcessor(chunkProcessor);
chunkHandler.afterPropertiesSet();
return chunkHandler;
}
#Bean
public QueueChannel inboundQueueChannel() {
return new QueueChannel().;
}
}
Below is my Application.java class for spring boot.
#SpringBootApplication
#EnableBatchProcessing
public class BulkImportProductApplication {
public static void main(String[] args) {
SpringApplication app = new SpringApplication(BulkImportProductApplication.class);
app.setWebEnvironment(false);
app.run(args).close();
}
}
From what I understand from spring integration, I have an AmqpInboundChannelAdapter for listening to messages from the queue. A ServiceActivator, an inboundQueueChannel, autowired ItemProcessor and ItemWriter. I am not sure what am I missing here.
The batch job starts, consumes one message from the queue and get a cancelOk and my job terminates without processing the message.
I am also sharing my debug logging if that would help.
2017-12-04 09:58:49.679 INFO 7450 --- [ main] c.a.s.p.b.BulkImportProductApplication : Started BulkImportProductApplication in 9.412 seconds (JVM running for 10.39)
2017-12-04 09:58:49.679 INFO 7450 --- [ main] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext#31c88ec8: startup date [Mon Dec 04 09:58:40 PST 2017]; root of context hierarchy
2017-12-04 09:58:49.679 DEBUG 7450 --- [ main] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'org.springframework.integration.config.IdGeneratorConfigurer#0'
2017-12-04 09:58:49.680 DEBUG 7450 --- [ main] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'inboundChannelAdapter'
2017-12-04 09:58:49.680 DEBUG 7450 --- [ main] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'listenerContainer'
2017-12-04 09:58:49.680 DEBUG 7450 --- [ main] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'integrationHeaderChannelRegistry'
2017-12-04 09:58:49.680 DEBUG 7450 --- [ main] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'org.springframework.amqp.rabbit.config.internalRabbitListenerEndpointRegistry'
2017-12-04 09:58:49.680 DEBUG 7450 --- [ main] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean '_org.springframework.integration.errorLogger'
2017-12-04 09:58:49.680 DEBUG 7450 --- [ main] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'queueIntegrationConfiguration.chunkProcessorChunkHandler.serviceActivator.handler'
2017-12-04 09:58:49.680 DEBUG 7450 --- [ main] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'queueIntegrationConfiguration.chunkProcessorChunkHandler.serviceActivator'
2017-12-04 09:58:49.680 DEBUG 7450 --- [ main] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'lifecycleProcessor'
2017-12-04 09:58:49.680 INFO 7450 --- [ main] o.s.c.support.DefaultLifecycleProcessor : Stopping beans in phase 2147483647
2017-12-04 09:58:49.680 DEBUG 7450 --- [ main] o.s.c.support.DefaultLifecycleProcessor : Asking bean 'inboundChannelAdapter' of type [class org.springframework.integration.amqp.inbound.AmqpInboundChannelAdapter] to stop
2017-12-04 09:58:49.680 DEBUG 7450 --- [ main] o.s.a.r.l.SimpleMessageListenerContainer : Shutting down Rabbit listener container
2017-12-04 09:58:49.814 DEBUG 7450 --- [pool-1-thread-5] o.s.a.r.listener.BlockingQueueConsumer : Storing delivery for Consumer#7c52fc81: tags=[{}], channel=Cached Rabbit Channel: AMQChannel(amqp://admin#xxxx:5672/,2), conn: Proxy#26f1249d Shared Rabbit Connection: SimpleConnection#680bddf5 [delegate=amqp://admin#xxxx:5672/, localPort= 65035], acknowledgeMode=AUTO local queue size=0
2017-12-04 09:58:49.814 DEBUG 7450 --- [enerContainer-1] o.s.a.r.listener.BlockingQueueConsumer : Received message: (Body:'[B#358a5358(byte[618])' MessageProperties [headers={__TypeId__=com.art.service.product.bulkimportproduct.data.model.Vendor}, timestamp=null, messageId=null, userId=null, receivedUserId=null, appId=null, clusterId=null, type=null, correlationId=null, correlationIdString=null, replyTo=null, contentType=json, contentEncoding=UTF-8, contentLength=0, deliveryMode=null, receivedDeliveryMode=NON_PERSISTENT, expiration=null, priority=0, redelivered=false, receivedExchange=ProductStore, receivedRoutingKey=, receivedDelay=null, deliveryTag=2, messageCount=0, consumerTag=amq.ctag-nWGbRxjFiaeTEoZylv6Hrg, consumerQueue=null])
2017-12-04 09:58:49.815 DEBUG 7450 --- [enerContainer-1] s.i.m.AbstractHeaderMapper$HeaderMatcher : headerName=[amqp_receivedDeliveryMode] WILL be mapped, matched pattern=*
2017-12-04 09:58:49.815 DEBUG 7450 --- [enerContainer-1] s.i.m.AbstractHeaderMapper$HeaderMatcher : headerName=[amqp_contentEncoding] WILL be mapped, matched pattern=*
2017-12-04 09:58:49.815 DEBUG 7450 --- [enerContainer-1] s.i.m.AbstractHeaderMapper$HeaderMatcher : headerName=[amqp_receivedExchange] WILL be mapped, matched pattern=*
2017-12-04 09:58:49.815 DEBUG 7450 --- [enerContainer-1] s.i.m.AbstractHeaderMapper$HeaderMatcher : headerName=[amqp_deliveryTag] WILL be mapped, matched pattern=*
2017-12-04 09:58:49.815 DEBUG 7450 --- [enerContainer-1] s.i.m.AbstractHeaderMapper$HeaderMatcher : headerName=[json__TypeId__] WILL be mapped, matched pattern=*
2017-12-04 09:58:49.815 DEBUG 7450 --- [enerContainer-1] s.i.m.AbstractHeaderMapper$HeaderMatcher : headerName=[amqp_redelivered] WILL be mapped, matched pattern=*
2017-12-04 09:58:49.815 DEBUG 7450 --- [enerContainer-1] s.i.m.AbstractHeaderMapper$HeaderMatcher : headerName=[contentType] WILL be mapped, matched pattern=*
2017-12-04 09:58:49.815 DEBUG 7450 --- [enerContainer-1] s.i.m.AbstractHeaderMapper$HeaderMatcher : headerName=[__TypeId__] WILL be mapped, matched pattern=*
2017-12-04 09:58:49.815 DEBUG 7450 --- [enerContainer-1] o.s.integration.channel.QueueChannel : preSend on channel 'inboundQueueChannel', message: GenericMessage [payload=byte[618], headers={amqp_receivedDeliveryMode=NON_PERSISTENT, amqp_contentEncoding=UTF-8, amqp_receivedExchange=ProductStore, amqp_deliveryTag=2, json__TypeId__=com.art.service.product.bulkimportproduct.data.model.Vendor, amqp_redelivered=false, id=a4868670-240f-ddf2-8a8c-ac4b8d234cdd, amqp_consumerTag=amq.ctag-nWGbRxjFiaeTEoZylv6Hrg, contentType=json, __TypeId__=com.art.service.product.bulkimportproduct.data.model.Vendor, timestamp=1512410329815}]
2017-12-04 09:58:49.815 DEBUG 7450 --- [enerContainer-1] o.s.integration.channel.QueueChannel : postSend (sent=true) on channel 'inboundQueueChannel', message: GenericMessage [payload=byte[618], headers={amqp_receivedDeliveryMode=NON_PERSISTENT, amqp_contentEncoding=UTF-8, amqp_receivedExchange=ProductStore, amqp_deliveryTag=2, json__TypeId__=com.art.service.product.bulkimportproduct.data.model.Vendor, amqp_redelivered=false, id=a4868670-240f-ddf2-8a8c-ac4b8d234cdd, amqp_consumerTag=amq.ctag-nWGbRxjFiaeTEoZylv6Hrg, contentType=json, __TypeId__=com.art.service.product.bulkimportproduct.data.model.Vendor, timestamp=1512410329815}]
2017-12-04 09:58:49.853 INFO 7450 --- [ main] o.s.a.r.l.SimpleMessageListenerContainer : Waiting for workers to finish.
2017-12-04 09:58:49.853 DEBUG 7450 --- [pool-1-thread-6] o.s.a.r.listener.BlockingQueueConsumer : Received cancelOk for tag amq.ctag-nWGbRxjFiaeTEoZylv6Hrg (null); Consumer#7c52fc81: tags=[{}], channel=Cached Rabbit Channel: AMQChannel(amqp://admin#xxxx:5672/,2), conn: Proxy#26f1249d Shared Rabbit Connection: SimpleConnection#680bddf5 [delegate=amqp://admin#xxxx:5672/, localPort= 65035], acknowledgeMode=AUTO local queue size=0
2017-12-04 09:58:49.853 DEBUG 7450 --- [enerContainer-1] o.s.a.r.l.SimpleMessageListenerContainer : Cancelling Consumer#7c52fc81: tags=[{}], channel=Cached Rabbit Channel: AMQChannel(amqp://admin#xxxx:5672/,2), conn: Proxy#26f1249d Shared Rabbit Connection: SimpleConnection#680bddf5 [delegate=amqp://admin#xxxx:5672/, localPort= 65035], acknowledgeMode=AUTO local queue size=0
2017-12-04 09:58:49.853 DEBUG 7450 --- [enerContainer-1] o.s.a.r.listener.BlockingQueueConsumer : Closing Rabbit Channel: Cached Rabbit Channel: AMQChannel(amqp://admin#xxxx:5672/,2), conn: Proxy#26f1249d Shared Rabbit Connection: SimpleConnection#680bddf5 [delegate=amqp://admin#xxxx:5672/, localPort= 65035]
2017-12-04 09:58:49.853 DEBUG 7450 --- [enerContainer-1] o.s.a.r.c.CachingConnectionFactory : Closing cached Channel: AMQChannel(amqp://admin#xxxx:5672/,2)
2017-12-04 09:58:50.027 INFO 7450 --- [ main] o.s.a.r.l.SimpleMessageListenerContainer : Successfully waited for workers to finish.
2017-12-04 09:58:50.027 DEBUG 7450 --- [ main] o.s.c.support.DefaultLifecycleProcessor : Bean 'inboundChannelAdapter' completed its stop procedure
What am I missing here? Why is my message getting processed? Please correct me if I'm missing out something here? Also feel free to ask any other configuration that you feel would help analyze the situation here.
EDIT: After removing the code that closes the application context manually( app.run(args).close() ), I was able to receive the messages, but looks like they are lost after a successful retrieve. sharing the debug log for this behavior.
2017-12-04 14:39:11.297 DEBUG 1498 --- [pool-1-thread-5] o.s.a.r.listener.BlockingQueueConsumer : Storing delivery for Consumer#7219ac49: tags=[{amq.ctag-Z8siptJMdxGU6sXdOHkVCA=ProductStore_Partial}], channel=Cached Rabbit Channel: AMQChannel(amqp://admin#xxxx:5672/,2), conn: Proxy#6df20ade Shared Rabbit Connection: SimpleConnection#7ba63fe5 [delegate=amqp://admin#xxxx:5672/, localPort= 51172], acknowledgeMode=AUTO local queue size=0
2017-12-04 14:39:11.297 DEBUG 1498 --- [enerContainer-1] o.s.a.r.listener.BlockingQueueConsumer : Received message: (Body:'[B#347c8f87(byte[624])' MessageProperties [headers={__TypeId__=com.art.service.product.bulkimportproduct.data.model.Vendor}, timestamp=null, messageId=null, userId=null, receivedUserId=null, appId=null, clusterId=null, type=null, correlationId=null, correlationIdString=null, replyTo=null, contentType=json, contentEncoding=UTF-8, contentLength=0, deliveryMode=null, receivedDeliveryMode=NON_PERSISTENT, expiration=null, priority=0, redelivered=false, receivedExchange=ProductStore, receivedRoutingKey=, receivedDelay=null, deliveryTag=2, messageCount=0, consumerTag=amq.ctag-Z8siptJMdxGU6sXdOHkVCA, consumerQueue=ProductStore_Partial])
2017-12-04 14:39:11.297 DEBUG 1498 --- [enerContainer-1] s.i.m.AbstractHeaderMapper$HeaderMatcher : headerName=[amqp_receivedDeliveryMode] WILL be mapped, matched pattern=*
2017-12-04 14:39:11.297 DEBUG 1498 --- [enerContainer-1] s.i.m.AbstractHeaderMapper$HeaderMatcher : headerName=[amqp_contentEncoding] WILL be mapped, matched pattern=*
2017-12-04 14:39:11.297 DEBUG 1498 --- [enerContainer-1] s.i.m.AbstractHeaderMapper$HeaderMatcher : headerName=[amqp_receivedExchange] WILL be mapped, matched pattern=*
2017-12-04 14:39:11.297 DEBUG 1498 --- [enerContainer-1] s.i.m.AbstractHeaderMapper$HeaderMatcher : headerName=[amqp_deliveryTag] WILL be mapped, matched pattern=*
2017-12-04 14:39:11.297 DEBUG 1498 --- [enerContainer-1] s.i.m.AbstractHeaderMapper$HeaderMatcher : headerName=[json__TypeId__] WILL be mapped, matched pattern=*
2017-12-04 14:39:11.297 DEBUG 1498 --- [enerContainer-1] s.i.m.AbstractHeaderMapper$HeaderMatcher : headerName=[amqp_redelivered] WILL be mapped, matched pattern=*
2017-12-04 14:39:11.297 DEBUG 1498 --- [enerContainer-1] s.i.m.AbstractHeaderMapper$HeaderMatcher : headerName=[contentType] WILL be mapped, matched pattern=*
2017-12-04 14:39:11.297 DEBUG 1498 --- [enerContainer-1] s.i.m.AbstractHeaderMapper$HeaderMatcher : headerName=[__TypeId__] WILL be mapped, matched pattern=*
2017-12-04 14:39:11.297 DEBUG 1498 --- [enerContainer-1] o.s.integration.channel.QueueChannel : preSend on channel 'inboundQueueChannel', message: GenericMessage [payload=byte[624], headers={amqp_receivedDeliveryMode=NON_PERSISTENT, amqp_contentEncoding=UTF-8, amqp_receivedExchange=ProductStore, amqp_deliveryTag=2, json__TypeId__=com.art.service.product.bulkimportproduct.data.model.Vendor, amqp_consumerQueue=ProductStore_Partial, amqp_redelivered=false, id=540399a5-62a6-7178-2524-e274bad4ed13, amqp_consumerTag=amq.ctag-Z8siptJMdxGU6sXdOHkVCA, contentType=json, __TypeId__=com.art.service.product.bulkimportproduct.data.model.Vendor, timestamp=1512427151297}]
2017-12-04 14:39:11.297 DEBUG 1498 --- [enerContainer-1] o.s.integration.channel.QueueChannel : postSend (sent=true) on channel 'inboundQueueChannel', message: GenericMessage [payload=byte[624], headers={amqp_receivedDeliveryMode=NON_PERSISTENT, amqp_contentEncoding=UTF-8, amqp_receivedExchange=ProductStore, amqp_deliveryTag=2, json__TypeId__=com.art.service.product.bulkimportproduct.data.model.Vendor, amqp_consumerQueue=ProductStore_Partial, amqp_redelivered=false, id=540399a5-62a6-7178-2524-e274bad4ed13, amqp_consumerTag=amq.ctag-Z8siptJMdxGU6sXdOHkVCA, contentType=json, __TypeId__=com.art.service.product.bulkimportproduct.data.model.Vendor, timestamp=1512427151297}]
2017-12-04 14:39:11.297 DEBUG 1498 --- [enerContainer-1] o.s.a.r.listener.BlockingQueueConsumer : Retrieving delivery for Consumer#7219ac49: tags=[{amq.ctag-Z8siptJMdxGU6sXdOHkVCA=ProductStore_Partial}], channel=Cached Rabbit Channel: AMQChannel(amqp://admin#xxxx:5672/,2), conn: Proxy#6df20ade Shared Rabbit Connection: SimpleConnection#7ba63fe5 [delegate=amqp://admin#xxxx:5672/, localPort= 51172], acknowledgeMode=AUTO local queue size=0
This goes on repeating and new messages are consumed, but the messages are not getting processed and written to the data-store using the itemWriter provided. Now come to think of it, since I have not provided the tasklet/step bean reference anywhere in this code, is that something I am missing out here?
app.run(args).close();
You are explicitly closing the application context, which shuts everything down.
Closing org.springframework.context.annotation.AnnotationConfigApplicationContext.

Resources