SpringBoot + Spring Security OAuth2 2.0 Resource Server JWT at Startup Expectation is not calling Authorisation Server - spring-boot

Summary :
Testing out Spring Security OAuth2 Resource Server JWT with SpringBoot 2.7.7 which uses Spring Security 5.7.6 to query Authorisation Server at startup.
According to :
https://docs.spring.io/spring-security/reference/5.7/servlet/oauth2/resource-server/jwt.html#_startup_expectations
Startup Expectations
When this property and these dependencies are used, Resource Server
will automatically configure itself to validate JWT-encoded Bearer
Tokens.
It achieves this through a deterministic startup process:
Query the Provider Configuration or Authorization Server Metadata endpoint for the jwks_url property
Query the jwks_url endpoint for supported algorithms
Configure the validation strategy to query jwks_url for valid public keys of the algorithms found
Configure the validation strategy to validate each JWTs iss claim against idp.example.com.
A consequence of this process is that the authorization server must be
up and receiving requests in order for Resource Server to successfully
start up.
If the authorization server is down when Resource Server queries it
(given appropriate timeouts), then startup will fail.
I have the property defined in application.properties AND the dependencies in pom.xml as above.
However, my very small example to try this out does not work ( e.g. The Resource Server does not appear to be querying the Authorisation Server at all at startup, and therefore the Resource Server starts-up successfully.
I was expecting my very small app to fail at startup as per documentation, but it did not ! Went as far as shutting down the Authorisation Server, and the SpringBoot Resources Server app still starts up.
Here's what I did :
1) pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.7</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>org.example</groupId>
<artifactId>oauth2-resource-server</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>oauth2-resource-server</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>11</java.version>
<spring-cloud.version>2021.0.5</spring-cloud.version>
<bootstrap.version>5.2.3</bootstrap.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-jose</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!--dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
</dependency-->
<!--dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency-->
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
<version>${bootstrap.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
2. application.properties
server.port=8081
spring.thymeleaf.cache=false
spring.security.oauth2.resourceserver.jwt.issuer-uri=http://openam.localtest.me:8080/openam/oauth2/realms/subrealm/
spring.security.oauth2.resourceserver.jwt.jwk-set-uri=http://openam.localtest.me:8080/openam/oauth2/realms/subrealm/connect/jwk_uri
3. Configuration class:
package org.example.oauth2resourceserver;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.oauth2.server.resource.OAuth2ResourceServerConfigurer;
import org.springframework.security.oauth2.jwt.JwtDecoder;
import org.springframework.security.oauth2.jwt.NimbusJwtDecoder;
import org.springframework.security.web.SecurityFilterChain;
#Configuration
#EnableWebSecurity
public class OAuth2ResourceServerSecurityConfiguration {
#Value("${spring.security.oauth2.resourceserver.jwt.jwk-set-uri}")
String jwkSetUri;
#Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests((authorize) -> authorize
.antMatchers(HttpMethod.GET, "/**").hasAuthority("SCOPE_message:read")
.antMatchers(HttpMethod.POST, "/**").hasAuthority("SCOPE_message:write")
.anyRequest().authenticated()
)
.oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt);
return http.build();
}
#Bean
JwtDecoder jwtDecoder() {
return NimbusJwtDecoder.withJwkSetUri(this.jwkSetUri).build();
}
}
4. Controller
package org.example.oauth2resourceserver;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
#Controller
public class ExampleMVCController {
#GetMapping("/")
public String main(Model model) {
return "welcome";
}
#GetMapping("/welcome")
public String welcome(Model model) {
return "welcome";
}
}
5. Application
package org.example.oauth2resourceserver;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class Oauth2ResourceServerApplication {
public static void main(String[] args) {
SpringApplication.run(Oauth2ResourceServerApplication.class, args);
}
}
With the Authorisation Server down, output on the console when I run the Resource Server is:
2022-12-28 03:32:38.148 INFO 1377958 --- [ main] o.e.o.Oauth2ResourceServerApplication : Starting Oauth2ResourceServerApplication using Java 11.0.15 on xxxxx-Inspiron-15-7510 with PID 1377958 (/home/xxxxx/projects/oauth2-resource-server/target/classes started by jsalvo in /home/xxxxx/projects/oauth2-resource-server)
2022-12-28 03:32:38.150 INFO 1377958 --- [ main] o.e.o.Oauth2ResourceServerApplication : No active profile set, falling back to 1 default profile: "default"
2022-12-28 03:32:38.561 INFO 1377958 --- [ main] o.s.cloud.context.scope.GenericScope : BeanFactory id=12f14043-de4d-3b01-a8aa-ef038a41274e
2022-12-28 03:32:38.733 INFO 1377958 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8081 (http)
2022-12-28 03:32:38.739 INFO 1377958 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2022-12-28 03:32:38.739 INFO 1377958 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.70]
2022-12-28 03:32:38.819 INFO 1377958 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2022-12-28 03:32:38.820 INFO 1377958 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 634 ms
2022-12-28 03:32:38.931 INFO 1377958 --- [ main] o.s.s.web.DefaultSecurityFilterChain : Will secure any request with [org.springframework.security.web.session.DisableEncodeUrlFilter#748ac6f3, org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter#68f6e55d, org.springframework.security.web.context.SecurityContextPersistenceFilter#2bfaba70, org.springframework.security.web.header.HeaderWriterFilter#5584d9c6, org.springframework.security.web.csrf.CsrfFilter#3bf54172, org.springframework.security.web.authentication.logout.LogoutFilter#58af5076, org.springframework.security.oauth2.server.resource.web.BearerTokenAuthenticationFilter#650c405c, org.springframework.security.web.savedrequest.RequestCacheAwareFilter#9301672, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter#2577a95d, org.springframework.security.web.authentication.AnonymousAuthenticationFilter#6fff46bf, org.springframework.security.web.session.SessionManagementFilter#17e9bc9e, org.springframework.security.web.access.ExceptionTranslationFilter#4da39ca9, org.springframework.security.web.access.intercept.AuthorizationFilter#2954f6ab]
2022-12-28 03:32:39.140 INFO 1377958 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8081 (http) with context path ''
2022-12-28 03:32:39.152 INFO 1377958 --- [ main] o.e.o.Oauth2ResourceServerApplication : Started Oauth2ResourceServerApplication in 1.27 seconds (JVM running for 1.512)
What am I missing ?
What code in Spring Security OAuth2 Resource Server does the call to the Authorisation Server at startup ?
UPDATE 2022-12-28
As suggested by the comments, I have completely removed my OAuth2ResourceServerSecurityConfiguration above. Still no luck.
On looking at the source code for OAuth2ResourceServerJwtConfiguration.JwtDecoderConfiguration :
It appears that you must only specify one of the following properties, but not both:
spring.security.oauth2.resourceserver.jwt.issuer-uri
spring.security.oauth2.resourceserver.jwt.jwk-set-uri
The method at :
JwtDecoderConfiguration.jwtDecoderByIssuerUri() method has an #IssuerUriCondition annotation that dictates a condition where you must only have the spring.security.oauth2.resourceserver.jwt.issuer-uri property defined.
So I commented out the other property ( commented out spring.security.oauth2.resourceserver.jwt.jwk-set-uri from application.properties), but when I debug into that method via IntelliJ, it steps at line 139 below but it does not step / stop at line 141 within the lambda, which is where the code that actually calls the authorisation server, even if I try to Step-In ( F7 ) from line 139:
In short, I am still at a loss. Anyone have any ideas ?

Related

Running SQL scripts on startup with spring boot and h2 memory database

I have a spring-boot application where i'm running a h2 memory database, however I can't seem to run SQL scripts when starting the app. I want to run a script to create a couple of tables.
This script works fine when I run it manually, but I want to run it automatically on startup.
I have understood that the script should be ran automatically when put in the src/main/resources directory, which is also the classpath.
I found this Stackoverflow question which seems to contain all sorts of different answers, however none of them seem to work for me.
This is my pom.xml :
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.3</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>...</groupId>
<artifactId>...</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>...</name>
<description>...</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.3.6</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.193</version>
</dependency>
<!-- Switch back from Spring Boot 2.x standard HikariCP to Tomcat JDBC,
configured later in Heroku (see https://stackoverflow.com/a/49970142/4964553) -->
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<excludes>
<exclude>app/**</exclude>
</excludes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>com.heroku.sdk</groupId>
<artifactId>heroku-maven-plugin</artifactId>
<version>2.0.8</version>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>8</source>
<target>8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
This is how my application.properties looks like :
spring.h2.console.enabled=true
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=admin
spring.datasource.password=admin
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.jpa.hibernate.ddl-auto=none
I tried to configure my application.properties in a couple of ways that were listed:
//Configuration 1
spring.datasource.schema=classpath:data.sql
//Configuration 2
spring.sql.init.schema-locations=classpath:data.sql
//Configuration 3
spring.datasource.data=classpath:data.sql
//Configuration 4
spring.sql.init.data-locations=classpath:data.sql
None of them worked, I also tried to configure a DataSource Bean, which seemed to have done something different, since the logs didn't show h2 memory database starting up before, now the logs show this:
2022-06-25 18:46:25.826 INFO 5303 --- [ restartedMain] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
2022-06-25 18:46:25.840 INFO 5303 --- [ restartedMain] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 8 ms. Found 0 JPA repository interfaces.
2022-06-25 18:46:26.413 INFO 5303 --- [ restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8081 (http)
2022-06-25 18:46:26.419 INFO 5303 --- [ restartedMain] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2022-06-25 18:46:26.419 INFO 5303 --- [ restartedMain] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.56]
2022-06-25 18:46:26.467 INFO 5303 --- [ restartedMain] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2022-06-25 18:46:26.467 INFO 5303 --- [ restartedMain] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1335 ms
2022-06-25 18:46:26.568 INFO 5303 --- [ restartedMain] o.s.b.a.h2.H2ConsoleAutoConfiguration : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
2022-06-25 18:46:26.725 INFO 5303 --- [ restartedMain] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [name: default]
2022-06-25 18:46:26.747 INFO 5303 --- [ restartedMain] org.hibernate.Version : HHH000412: Hibernate ORM core version 5.6.4.Final
2022-06-25 18:46:26.857 INFO 5303 --- [ restartedMain] o.hibernate.annotations.common.Version : HCANN000001: Hibernate Commons Annotations {5.1.2.Final}
2022-06-25 18:46:26.906 INFO 5303 --- [ restartedMain] org.hibernate.dialect.Dialect : HHH000400: Using dialect: org.hibernate.dialect.H2Dialect
2022-06-25 18:46:26.993 INFO 5303 --- [ restartedMain] o.h.e.t.j.p.i.JtaPlatformInitiator : HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
The DataSource Bean :
#Bean
public DriverManagerDataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("org.h2.Driver");
dataSource.setUrl("jdbc:h2:mem:testdb");
dataSource.setUsername("admin");
dataSource.setPassword("admin");
// schema init
Resource initSchema = new ClassPathResource("data.sql");
DatabasePopulator databasePopulator = new ResourceDatabasePopulator(initSchema);
DatabasePopulatorUtils.execute(databasePopulator, dataSource);
return dataSource;
}
What am I missing here? Thanks!
EDIT I fixed the issue:
I found this post on github and it seemed relevant since my hikariPool wasn't starting up, I checked one of the answers where you configure the hikaripool as a bean, like this :
#Bean
public HikariDataSource createHikariConfig() {
HikariConfig hikariConfig = new HikariConfig();
hikariConfig.setDriverClassName("org.h2.Driver");
hikariConfig.setJdbcUrl("jdbc:h2:mem:testdb");
hikariConfig.setUsername("admin");
hikariConfig.setPassword("admin");
return new HikariDataSource(hikariConfig);
}
This made the hikariPool startup and execute the schema.sql script file under my src/main/resources, and now it is working.
You've disabled schema generation with
spring.jpa.hibernate.ddl-auto=none
Set it to create and it should work with the default schema.sql or import.sql
For reference, these are the possible values you can set it to:
none: No action will be performed
create-only: Database creation will be generated
drop: Database dropping will be generated
create: Database dropping will be generated followed by database creation.
create-drop: Drop the schema and recreate it on SessionFactory startup. Additionally, drop the schema on SessionFactory shutdown
validate: Validate the database schema
update: Update the database schema

spring cloud stream kafka consumer clientId anonymous

I am new to kafka with spring cloud stream.the application is in two in one.
the first application is producing to kafka topic (com.ng.vela.even.card_verified) which is very accurate but the second one is give me the following in my console but messages are not being comsumed from the kafka topic.
This is what am getting in my console .
020-06-24 14:36:07.168 INFO 7784 --- [container-0-C-1] o.a.k.c.c.internals.AbstractCoordinator : [Consumer clientId=consumer-anonymous.1bf08674-d2fd-447a-b7d6-ce0c9eb597e9-24, groupId=anonymous.1bf08674-d2fd-447a-b7d6-ce0c9eb597e9] Successfully joined group with generation 1
2020-06-24 14:36:07.170 INFO 7784 --- [container-0-C-1] o.a.k.c.c.internals.ConsumerCoordinator : [Consumer clientId=consumer-anonymous.1bf08674-d2fd-447a-b7d6-ce0c9eb597e9-24, groupId=anonymous.1bf08674-d2fd-447a-b7d6-ce0c9eb597e9] Adding newly assigned partitions: com.ng.vela.even.card_verified-0
2020-06-24 14:36:07.171 INFO 7784 --- [ restartedMain] .ConditionEvaluationDeltaLoggingListener : Condition evaluation unchanged
2020-06-24 14:36:07.171 INFO 7784 --- [container-0-C-1] o.a.k.c.c.internals.ConsumerCoordinator : [Consumer clientId=consumer-anonymous.1bf08674-d2fd-447a-b7d6-ce0c9eb597e9-24, groupId=anonymous.1bf08674-d2fd-447a-b7d6-ce0c9eb597e9] Found no committed offset for partition com.ng.vela.even.card_verified-0
2020-06-24 14:36:07.173 INFO 7784 --- [container-0-C-1] o.a.k.c.c.internals.ConsumerCoordinator : [Consumer clientId=consumer-anonymous.1bf08674-d2fd-447a-b7d6-ce0c9eb597e9-24, groupId=anonymous.1bf08674-d2fd-447a-b7d6-ce0c9eb597e9] Found no committed offset for partition com.ng.vela.even.card_verified-0
2020-06-24 14:36:07.180 INFO 7784 --- [container-0-C-1] o.a.k.c.c.internals.SubscriptionState : [Consumer clientId=consumer-anonymous.1bf08674-d2fd-447a-b7d6-ce0c9eb597e9-24, groupId=anonymous.1bf08674-d2fd-447a-b7d6-ce0c9eb597e9] Resetting offset for partition com.ng.vela.even.card_verified-0 to offset 63.
2020-06-24 14:36:07.183 INFO 7784 --- [container-0-C-1] o.s.c.s.b.k.KafkaMessageChannelBinder$1 : anonymous.1bf08674-d2fd-447a-b7d6-ce0c9eb597e9: partitions assigned: [com.ng.vela.even.card_verified-0]
the java source code is this below cos I am trying to follow the documentation of spring cloud stream :
package com.mint.financial;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.stream.annotation.EnableBinding;
import org.springframework.cloud.stream.annotation.StreamListener;
import org.springframework.cloud.stream.messaging.Processor;
import org.springframework.context.annotation.Bean;
import org.springframework.messaging.handler.annotation.SendTo;
import com.mint.financial.entity.CardSchemeStream;
import com.mint.financial.kafka.consumer.CardSchemeKafkaConsumer;
#SpringBootApplication
#EnableBinding(Processor.class)
public class MintFinancialClientConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(MintFinancialClientConsumerApplication.class, args);
}
#StreamListener(Processor.INPUT)
#SendTo(Processor.OUTPUT)
public String handle(String value) {
System.out.println("Received: " + value);
return value ;
}
#Bean
public CardSchemeStream getCardSchemeStream() {
return new CardSchemeStream() ;
}
#Bean
public ApplicationRunner initializeConnection(){
return args -> {
System.out.println("handler testing for api working also with application runner");
};
}
}
The pom is
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.mint</groupId>
<artifactId>MintFinance</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>MintFinancialClientConsumer</name>
<description>Visa Validation project Consumer for mint financial technology</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb-reactive</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream</artifactId>
<version>3.0.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream-binder-kafka</artifactId>
<version>3.0.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
The application.properties file is
spring.data.mongodb.host=localhost
spring.data.mongodb.port=27017
spring.data.mongodb.repositories.enabled=true
spring.data.mongodb.database=mint
spring.cloud.stream.kafka.binders.broker=9092
spring.cloud.stream.kafka.binder.zkNodes=2181
spring.cloud.stream.input.group.name=test-consumer-group
spring.cloud.stream.bindings.output.destination=com.ng.vela.even.card_verified
spring.cloud.stream.bindings.input.destination=com.ng.vela.even.card_verified
#spring.cloud.stream.bindings.input.destination=first-topic
#spring.cloud.stream.bindings.output.destination=first-topic
spring.cloud.stream.bindings.output.producer.partitionCount=1
spring.cloud.stream.bindings.output.content-type=text/plain
spring.cloud.stream.bindings.output.producer.headerMode=headers
As shown above, every other thing is working including the connection to mongodb
but i cant just consume messages that i have produced to kafka.I am trying to produce and consume from the same topic.
I have even considered using the default consumer group due to the error, but all to no avail.
Again,I changed the replication factor in server.properties file to 3 but yet nothing is working.
I have searched everywhere . please guys i need your help .

HTTP Status 404 – Not Found for basic Spring Boot program

I receive the "HTTP Status 404 – Not Found" even though the Tomcat server seems to have initialized and running in the localhost:8080.
The pom.xml is
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework</groupId>
<artifactId>gs-consuming-rest</artifactId>
<version>0.1.0</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
</parent>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<!--<scope>provided</scope>-->
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
The Controller is
package com.example.demo;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
#RestController
public class HelloController {
#RequestMapping("/")
public String hello(){
return "Hello!";
}
}
The Main Application code is
package com.example.demo;
import java.util.Arrays;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
#SpringBootApplication
public class HelloWorldApplication {
public static void main(String[] args) {
SpringApplication.run(HelloWorldApplication.class, args);
}
}
The console logs :
2019-08-09 19:53:07.161 INFO 13948 --- [ main] com.example.demo.HelloWorldApplication : Starting HelloWorldApplication on DESKTOP-BIMC3QL with PID 13948 (C:\Users\AdharshD\Documents\workspace-sts-3.9.9.RELEASE\HelloWorld\target\classes started by AdharshD in C:\Users\AdharshD\Documents\workspace-sts-3.9.9.RELEASE\HelloWorld)
2019-08-09 19:53:07.164 INFO 13948 --- [ main] com.example.demo.HelloWorldApplication : No active profile set, falling back to default profiles: default
2019-08-09 19:53:07.791 INFO 13948 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2019-08-09 19:53:07.810 INFO 13948 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2019-08-09 19:53:07.810 INFO 13948 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.21]
2019-08-09 19:53:07.891 INFO 13948 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2019-08-09 19:53:07.891 INFO 13948 --- [ main] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 679 ms
2019-08-09 19:53:08.076 INFO 13948 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2019-08-09 19:53:08.079 INFO 13948 --- [ main] com.example.demo.HelloWorldApplication : Started HelloWorldApplication in 1.211 seconds (JVM running for 1.855)
You are missing spring-boot-starter-web artifact. Artifact contains tells spring boot to scan the package (in which main method is present) and all his subpackage for configuration, components and controller. Since this artifact is missing, spring doesn’t register your controller and throws 404-Not found.

How to convert this spring boot sample app so a war file is built that can run in an external Tomcat server

I am trying to figure out how to convert this sample spring boot app so that the war file that gets generated can run in an external Tomcat server: enter link description here
Here is my modiefied pom.xml which does generate the war file:
<?xml version="1.0" encoding="UTF-8"?>
http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
<groupId>org.springframework</groupId>
<artifactId>gs-securing-web</artifactId>
<version>0.1.0</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.3.RELEASE</version>
</parent>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
</dependencies>
<properties>
<java.version>1.8</java.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-releases</id>
<name>Spring Releases</name>
<url>https://repo.spring.io/libs-release</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-releases</id>
<name>Spring Releases</name>
<url>https://repo.spring.io/libs-release</url>
</pluginRepository>
</pluginRepositories>
Here is my new Application class that extends SpringBootServletInitializer:
package hello;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.support.SpringBootServletInitializer;
#SpringBootApplication
public class Application extends SpringBootServletInitializer {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(ApplicationOLD.class);
}
public static void main(String[] args) throws Exception {
SpringApplication.run(ApplicationOLD.class, args);
}
}
In the console, I can see that the app has been started by Tomcat:
2017-07-14 16:53:10.736 INFO 12020 --- [ main] hello.Application : Starting Application v0.1.0 on LAPTOP-I1Q04POH with PID 12020 (C:\apache-tomcat-9.0.0.M22\webapps\gs-securing-web-0.1.0\WEB-INF\classes started by akova in C:\apache-tomcat-9.0.0.M22\bin)
2017-07-14 16:53:10.740 INFO 12020 --- [ main] hello.Application : No active profile set, falling back to default profiles: default
2017-07-14 16:53:11.012 INFO 12020 --- [ main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext#5f4f198c: startup date [Fri Jul 14 16:53:11 EDT 2017]; root of context hierarchy
2017-07-14 16:53:11.209 INFO 12020 --- [ main] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 197 ms
2017-07-14 16:53:11.256 INFO 12020 --- [ main] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'errorPageFilter' to: [/*]
2017-07-14 16:53:11.295 INFO 12020 --- [ main] hello.Application : Started Application in 1.118 seconds (JVM running for 3.925)
But I can't see to access the app when I go to the url in a browser. I get an HTTP 404 error using the url: http://localhost:8080/gs-securing-web-0.1.0/.
What am I missing??? Thanks
As stated in the porject itself, and the tutorial to followed to build this porject, you should use only this URI: http://localhost:8080/ to consume your service.
Use http://localhost:8080/hello and http://localhost:8080/login for the other resouces.
Add this dependency under dependencies section
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>

JSF components are not rendered when running Spring Boot app on Eclipse Tomcat

I have Spring Boot JSF application that runs fine on embedded Tomcat
but when trying to run it on Eclipse Tomcat, the jsf components are not getting rendered, here's my pom file:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework</groupId>
<artifactId>gs-accessing-data-jpa</artifactId>
<version>0.1.0</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.4.RELEASE</version>
</parent>
<packaging>war</packaging>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.sun.faces</groupId>
<artifactId>jsf-api</artifactId>
<version>2.2.14</version>
</dependency>
<dependency>
<groupId>com.sun.faces</groupId>
<artifactId>jsf-impl</artifactId>
<version>2.2.14</version>
</dependency>
<dependency>
<groupId>org.primefaces</groupId>
<artifactId>primefaces</artifactId>
<version>6.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<!--
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
-->
</plugins>
</build>
<repositories>
<repository>
<id>spring-releases</id>
<name>Spring Releases</name>
<url>https://repo.spring.io/libs-release</url>
</repository>
<repository>
<id>org.jboss.repository.releases</id>
<name>JBoss Maven Release Repository</name>
<url>https://repository.jboss.org/nexus/content/repositories/releases</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-releases</id>
<name>Spring Releases</name>
<url>https://repo.spring.io/libs-release</url>
</pluginRepository>
</pluginRepositories>
</project>
The main class:
package hello;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import javax.faces.application.ProjectStage;
import javax.servlet.ServletContainerInitializer;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.HandlesTypes;
import org.apache.catalina.Context;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.config.CustomScopeConfigurer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory;
import org.springframework.boot.context.embedded.tomcat.TomcatContextCustomizer;
import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
import org.springframework.boot.web.servlet.ServletContextInitializer;
import org.springframework.boot.web.support.SpringBootServletInitializer;
import org.springframework.context.annotation.Bean;
import com.sun.faces.config.FacesInitializer;
#SpringBootApplication
public class Application extends SpringBootServletInitializer {
private static final Logger log = LoggerFactory.getLogger(Application.class);
public static void main(String[] args) {
SpringApplication.run(Application.class);
}
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Application.class);
}
#Bean
public ServletContextInitializer servletContextCustomizer() {
return new ServletContextInitializer() {
#Override
public void onStartup(ServletContext sc) throws ServletException {
sc.setInitParameter(ProjectStage.PROJECT_STAGE_PARAM_NAME, ProjectStage.Development.name());
}
};
}
#Bean
public static CustomScopeConfigurer customScopeConfigurer() {
CustomScopeConfigurer configurer = new CustomScopeConfigurer();
configurer.setScopes(Collections.<String, Object>singletonMap(FacesViewScope.NAME, new FacesViewScope()));
return configurer;
}
#Bean
public EmbeddedServletContainerFactory embeddedServletContainerFactory() {
TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory();
tomcat.addContextCustomizers(new TomcatContextCustomizer() {
#Override
public void customize(Context context) {
context.addServletContainerInitializer(new FacesInitializer(),
getServletContainerInitializerHandlesTypes(FacesInitializer.class));
context.addWelcomeFile("index.xhtml");
context.addMimeMapping("eot", "application/vnd.ms-fontobject");
context.addMimeMapping("ttf", "application/x-font-ttf");
context.addMimeMapping("woff", "application/x-font-woff");
}
});
return tomcat;
}
#SuppressWarnings("rawtypes")
private Set<Class<?>> getServletContainerInitializerHandlesTypes(
Class<? extends ServletContainerInitializer> sciClass) {
HandlesTypes annotation = sciClass.getAnnotation(HandlesTypes.class);
if (annotation == null) {
return Collections.emptySet();
}
Class[] classesArray = annotation.value();
Set<Class<?>> classesSet = new HashSet<Class<?>>(classesArray.length);
for (Class clazz : classesArray) {
classesSet.add(clazz);
}
return classesSet;
}
}
Other configuration:
JSF are added to project facets
Maven dependencies are added in deployment assembly
When running the application on server, I don't get any errors in fact I see logs meaning that JSF was started successfully:
2017-01-28 16:04:47.145 INFO 6880 --- [ost-startStop-1] hello.Application : Started Application in 13.522 seconds (JVM running for 19.312)
2017-01-28 16:04:47.231 INFO 6880 --- [ost-startStop-1] j.e.resource.webcontainer.jsf.config : Initializing Mojarra 2.2.14 ( 20161114-2153 unable to get svn info) for context '/spring-hibernate-jsf-web'
2017-01-28 16:04:47.539 INFO 6880 --- [ost-startStop-1] j.e.r.webcontainer.jsf.application : JSF1048: PostConstruct/PreDestroy annotations present. ManagedBeans methods marked with these annotations will have said annotations processed.
2017-01-28 16:04:48.557 INFO 6880 --- [ost-startStop-1] j.e.resource.webcontainer.jsf.config : Monitoring file:/C:/Users/lenovo/workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/spring-hibernate-jsf-web/WEB-INF/faces-config.xml for modifications
2017-01-28 16:04:48.630 INFO 6880 --- [ost-startStop-1] .w.PostConstructApplicationEventListener : Running on PrimeFaces 6.0
2017-01-28 16:04:48.790 INFO 6880 --- [ main] org.apache.coyote.ajp.AjpNioProtocol : Starting ProtocolHandler [ajp-nio-8009]
2017-01-28 16:04:48.799 INFO 6880 --- [ main] org.apache.catalina.startup.Catalina : Server startup in 20021 ms
2017-01-28 16:04:49.463 INFO 6880 --- [nio-8080-exec-2] .a.c.c.C.[.[.[/spring-hibernate-jsf-web] : Initializing Spring FrameworkServlet 'dispatcherServlet'
2017-01-28 16:04:49.463 INFO 6880 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization started
2017-01-28 16:04:49.511 INFO 6880 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization completed in 47 ms
When accessing the xhtml page, there are no errors but the jsf and Primefaces components doesn't get rendered. How can I fix this issue?
I found the issue, it's weird, while running the jar on embeded tomcat i was able to access the xhtml pages without the /faces/ prefix but on eclipse tomcat i have to add /faces/ prefix before the xhtml page in order to work properly.

Resources