From 795f39d238604681658414d5880d0635454bc86b Mon Sep 17 00:00:00 2001 From: michaelin007 Date: Mon, 5 Feb 2024 06:42:49 +0000 Subject: [PATCH 01/38] https://jira.baeldung.com/browse/BAEL-5235 --- apache-libraries-2/pom.xml | 19 ++++++ .../dynamicrouter/DynamicRouterBean.java | 28 +++++++++ .../dynamicrouter/DynamicRouterRoute.java | 13 ++++ .../DynamicRouterRouteUnitTest.java | 63 +++++++++++++++++++ .../dynamicrouting/DynamicRouteBuilder.java | 4 ++ .../dynamicrouting/DynamicRouterBean.java | 4 ++ .../dynamicrouter/DynamicRouterUnitTest.java | 4 ++ 7 files changed, 135 insertions(+) create mode 100644 apache-libraries-2/src/main/java/com/baeldung/dynamicrouter/DynamicRouterBean.java create mode 100644 apache-libraries-2/src/main/java/com/baeldung/dynamicrouter/DynamicRouterRoute.java create mode 100644 apache-libraries-2/src/test/java/dynamicrouter/DynamicRouterRouteUnitTest.java create mode 100644 messaging-modules/apache-camel/src/main/java/com/baeldung/camel/apache/dynamicrouting/DynamicRouteBuilder.java create mode 100644 messaging-modules/apache-camel/src/main/java/com/baeldung/camel/apache/dynamicrouting/DynamicRouterBean.java create mode 100644 messaging-modules/apache-camel/src/test/java/com/apache/dynamicrouter/DynamicRouterUnitTest.java diff --git a/apache-libraries-2/pom.xml b/apache-libraries-2/pom.xml index d188204208..2e7ef0344c 100644 --- a/apache-libraries-2/pom.xml +++ b/apache-libraries-2/pom.xml @@ -19,10 +19,29 @@ validation-api ${javax.validation.validation-api.version} + + org.apache.camel + camel-core + ${camel.version} + + + + org.apache.camel + camel-test-junit5 + ${camel.version} + test + + + + org.apache.camel + camel-main + ${camel.version} + 2.0.1.Final + 4.3.0 \ No newline at end of file diff --git a/apache-libraries-2/src/main/java/com/baeldung/dynamicrouter/DynamicRouterBean.java b/apache-libraries-2/src/main/java/com/baeldung/dynamicrouter/DynamicRouterBean.java new file mode 100644 index 0000000000..3df861d2b2 --- /dev/null +++ b/apache-libraries-2/src/main/java/com/baeldung/dynamicrouter/DynamicRouterBean.java @@ -0,0 +1,28 @@ +package com.baeldung.dynamicrouter; + +import org.apache.camel.ExchangeProperties; + +import java.util.Map; + +public class DynamicRouterBean { + public String route(String body, @ExchangeProperties Map properties) { + int invoked = 0; + Integer current = (Integer) properties.get("invoked"); + if (current != null) { + invoked = current; + } + invoked++; + properties.put("invoked", invoked); + + if (body.equalsIgnoreCase("mock") && invoked == 1) { + return "mock:dynamicRouter"; + } else if (body.equalsIgnoreCase("direct") && invoked == 1) { + return "mock:directDynamicRouter"; + } else if (body.equalsIgnoreCase("seda") && invoked == 1) { + return "mock:sedaDynamicRouter"; + } else if (body.equalsIgnoreCase("book") && invoked == 1) { + return "mock:bookDynamicRouter"; + } + return null; + } +} diff --git a/apache-libraries-2/src/main/java/com/baeldung/dynamicrouter/DynamicRouterRoute.java b/apache-libraries-2/src/main/java/com/baeldung/dynamicrouter/DynamicRouterRoute.java new file mode 100644 index 0000000000..875263f0b1 --- /dev/null +++ b/apache-libraries-2/src/main/java/com/baeldung/dynamicrouter/DynamicRouterRoute.java @@ -0,0 +1,13 @@ +package com.baeldung.dynamicrouter; + +import org.apache.camel.builder.RouteBuilder; + +public class DynamicRouterRoute extends RouteBuilder { + + @Override + public void configure() { + + from("direct:dynamicRouter").dynamicRouter(method(DynamicRouterBean.class, "route")); + + } +} diff --git a/apache-libraries-2/src/test/java/dynamicrouter/DynamicRouterRouteUnitTest.java b/apache-libraries-2/src/test/java/dynamicrouter/DynamicRouterRouteUnitTest.java new file mode 100644 index 0000000000..fa8cab99a0 --- /dev/null +++ b/apache-libraries-2/src/test/java/dynamicrouter/DynamicRouterRouteUnitTest.java @@ -0,0 +1,63 @@ +package dynamicrouter; + +import com.baeldung.dynamicrouter.DynamicRouterRoute; +import org.apache.camel.RoutesBuilder; +import org.apache.camel.component.mock.MockEndpoint; +import org.apache.camel.test.junit5.CamelTestSupport; +import org.junit.jupiter.api.Test; + +public class DynamicRouterRouteUnitTest extends CamelTestSupport { + + @Override + protected RoutesBuilder createRouteBuilder() { + return new DynamicRouterRoute(); + } + + @Test + void givenDynamicRouter_whenMockEndpointExpectedMessageCountOneAndMockAsMessageBody_thenMessageSentToDynamicRouter() throws InterruptedException { + + MockEndpoint mockDynamicEndpoint = getMockEndpoint("mock:dynamicRouter"); + mockDynamicEndpoint.expectedMessageCount(1); + + template.send("direct:dynamicRouter", exchange -> exchange.getIn() + .setBody("mock")); + context.start(); + MockEndpoint.assertIsSatisfied(context); + } + + @Test + void givenDynamicRouter_whenMockEndpointExpectedMessageCountOneAndDirectAsMessageBody_thenMessageSentToDynamicRouter() throws InterruptedException { + + MockEndpoint mockDynamicEndpoint = context.getEndpoint("mock:directDynamicRouter", MockEndpoint.class); + mockDynamicEndpoint.expectedMessageCount(1); + + template.send("direct:dynamicRouter", exchange -> exchange.getIn() + .setBody("direct")); + + MockEndpoint.assertIsSatisfied(context); + } + + @Test + void givenDynamicRouter_whenMockEndpointExpectedMessageCountOneAndSedaAsMessageBody_thenMessageSentToDynamicRouter() throws InterruptedException { + + MockEndpoint mockDynamicEndpoint = context.getEndpoint("mock:sedaDynamicRouter", MockEndpoint.class); + mockDynamicEndpoint.expectedMessageCount(1); + + template.send("direct:dynamicRouter", exchange -> exchange.getIn() + .setBody("seda")); + + MockEndpoint.assertIsSatisfied(context); + } + + @Test + void givenDynamicRouter_whenMockEndpointExpectedMessageCountOneAndBookAsMessageBody_thenMessageSentToDynamicRouter() throws InterruptedException { + + MockEndpoint mockDynamicEndpoint = getMockEndpoint("mock:bookDynamicRouter"); + mockDynamicEndpoint.expectedMessageCount(1); + + template.send("direct:dynamicRouter", exchange -> exchange.getIn() + .setBody("book")); + MockEndpoint.assertIsSatisfied(context); + } + +} \ No newline at end of file diff --git a/messaging-modules/apache-camel/src/main/java/com/baeldung/camel/apache/dynamicrouting/DynamicRouteBuilder.java b/messaging-modules/apache-camel/src/main/java/com/baeldung/camel/apache/dynamicrouting/DynamicRouteBuilder.java new file mode 100644 index 0000000000..0019a56cae --- /dev/null +++ b/messaging-modules/apache-camel/src/main/java/com/baeldung/camel/apache/dynamicrouting/DynamicRouteBuilder.java @@ -0,0 +1,4 @@ +package com.baeldung.camel.apache.dynamicrouting; + +public class DynamicRouteBuilder { +} diff --git a/messaging-modules/apache-camel/src/main/java/com/baeldung/camel/apache/dynamicrouting/DynamicRouterBean.java b/messaging-modules/apache-camel/src/main/java/com/baeldung/camel/apache/dynamicrouting/DynamicRouterBean.java new file mode 100644 index 0000000000..3128551b0a --- /dev/null +++ b/messaging-modules/apache-camel/src/main/java/com/baeldung/camel/apache/dynamicrouting/DynamicRouterBean.java @@ -0,0 +1,4 @@ +package com.baeldung.camel.apache.dynamicrouting; + +public class DynamicRouterBean { +} diff --git a/messaging-modules/apache-camel/src/test/java/com/apache/dynamicrouter/DynamicRouterUnitTest.java b/messaging-modules/apache-camel/src/test/java/com/apache/dynamicrouter/DynamicRouterUnitTest.java new file mode 100644 index 0000000000..a5a7a2c4fa --- /dev/null +++ b/messaging-modules/apache-camel/src/test/java/com/apache/dynamicrouter/DynamicRouterUnitTest.java @@ -0,0 +1,4 @@ +package com.apache.dynamicrouter; + +public class DynamicRouterUnitTest { +} From f63fbeca4f74d249e2ba34ef6ea79f76be7d6aae Mon Sep 17 00:00:00 2001 From: michaelin007 Date: Mon, 5 Feb 2024 06:45:06 +0000 Subject: [PATCH 02/38] https://jira.baeldung.com/browse/BAEL-5235 --- .../camel/apache/dynamicrouting/DynamicRouteBuilder.java | 4 ---- .../camel/apache/dynamicrouting/DynamicRouterBean.java | 4 ---- .../java/com/apache/dynamicrouter/DynamicRouterUnitTest.java | 4 ---- 3 files changed, 12 deletions(-) delete mode 100644 messaging-modules/apache-camel/src/main/java/com/baeldung/camel/apache/dynamicrouting/DynamicRouteBuilder.java delete mode 100644 messaging-modules/apache-camel/src/main/java/com/baeldung/camel/apache/dynamicrouting/DynamicRouterBean.java delete mode 100644 messaging-modules/apache-camel/src/test/java/com/apache/dynamicrouter/DynamicRouterUnitTest.java diff --git a/messaging-modules/apache-camel/src/main/java/com/baeldung/camel/apache/dynamicrouting/DynamicRouteBuilder.java b/messaging-modules/apache-camel/src/main/java/com/baeldung/camel/apache/dynamicrouting/DynamicRouteBuilder.java deleted file mode 100644 index 0019a56cae..0000000000 --- a/messaging-modules/apache-camel/src/main/java/com/baeldung/camel/apache/dynamicrouting/DynamicRouteBuilder.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.baeldung.camel.apache.dynamicrouting; - -public class DynamicRouteBuilder { -} diff --git a/messaging-modules/apache-camel/src/main/java/com/baeldung/camel/apache/dynamicrouting/DynamicRouterBean.java b/messaging-modules/apache-camel/src/main/java/com/baeldung/camel/apache/dynamicrouting/DynamicRouterBean.java deleted file mode 100644 index 3128551b0a..0000000000 --- a/messaging-modules/apache-camel/src/main/java/com/baeldung/camel/apache/dynamicrouting/DynamicRouterBean.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.baeldung.camel.apache.dynamicrouting; - -public class DynamicRouterBean { -} diff --git a/messaging-modules/apache-camel/src/test/java/com/apache/dynamicrouter/DynamicRouterUnitTest.java b/messaging-modules/apache-camel/src/test/java/com/apache/dynamicrouter/DynamicRouterUnitTest.java deleted file mode 100644 index a5a7a2c4fa..0000000000 --- a/messaging-modules/apache-camel/src/test/java/com/apache/dynamicrouter/DynamicRouterUnitTest.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.apache.dynamicrouter; - -public class DynamicRouterUnitTest { -} From 8af3dd780f4c9fe8782745c39a666d8de5744507 Mon Sep 17 00:00:00 2001 From: michaelin007 Date: Wed, 7 Feb 2024 07:01:48 +0000 Subject: [PATCH 03/38] https://jira.baeldung.com/browse/BAEL-5235 --- .../java/com/baeldung/dynamicrouter/DynamicRouterBean.java | 4 ++-- .../test/java/dynamicrouter/DynamicRouterRouteUnitTest.java | 6 ++---- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/apache-libraries-2/src/main/java/com/baeldung/dynamicrouter/DynamicRouterBean.java b/apache-libraries-2/src/main/java/com/baeldung/dynamicrouter/DynamicRouterBean.java index 3df861d2b2..8bc455353b 100644 --- a/apache-libraries-2/src/main/java/com/baeldung/dynamicrouter/DynamicRouterBean.java +++ b/apache-libraries-2/src/main/java/com/baeldung/dynamicrouter/DynamicRouterBean.java @@ -20,8 +20,8 @@ public class DynamicRouterBean { return "mock:directDynamicRouter"; } else if (body.equalsIgnoreCase("seda") && invoked == 1) { return "mock:sedaDynamicRouter"; - } else if (body.equalsIgnoreCase("book") && invoked == 1) { - return "mock:bookDynamicRouter"; + } else if (body.equalsIgnoreCase("file") && invoked == 1) { + return "mock:fileDynamicRouter"; } return null; } diff --git a/apache-libraries-2/src/test/java/dynamicrouter/DynamicRouterRouteUnitTest.java b/apache-libraries-2/src/test/java/dynamicrouter/DynamicRouterRouteUnitTest.java index fa8cab99a0..6401fa4be2 100644 --- a/apache-libraries-2/src/test/java/dynamicrouter/DynamicRouterRouteUnitTest.java +++ b/apache-libraries-2/src/test/java/dynamicrouter/DynamicRouterRouteUnitTest.java @@ -21,7 +21,6 @@ public class DynamicRouterRouteUnitTest extends CamelTestSupport { template.send("direct:dynamicRouter", exchange -> exchange.getIn() .setBody("mock")); - context.start(); MockEndpoint.assertIsSatisfied(context); } @@ -45,18 +44,17 @@ public class DynamicRouterRouteUnitTest extends CamelTestSupport { template.send("direct:dynamicRouter", exchange -> exchange.getIn() .setBody("seda")); - MockEndpoint.assertIsSatisfied(context); } @Test void givenDynamicRouter_whenMockEndpointExpectedMessageCountOneAndBookAsMessageBody_thenMessageSentToDynamicRouter() throws InterruptedException { - MockEndpoint mockDynamicEndpoint = getMockEndpoint("mock:bookDynamicRouter"); + MockEndpoint mockDynamicEndpoint = getMockEndpoint("mock:fileDynamicRouter"); mockDynamicEndpoint.expectedMessageCount(1); template.send("direct:dynamicRouter", exchange -> exchange.getIn() - .setBody("book")); + .setBody("file")); MockEndpoint.assertIsSatisfied(context); } From 4288f99d1064f0a666a5fb392cdeb8a32a9a3bd2 Mon Sep 17 00:00:00 2001 From: michaelin007 Date: Fri, 9 Feb 2024 08:50:46 +0000 Subject: [PATCH 04/38] https://jira.baeldung.com/browse/BAEL-5235 --- .../dynamicrouter/DynamicRouterBean.java | 29 ++++++++++--------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/apache-libraries-2/src/main/java/com/baeldung/dynamicrouter/DynamicRouterBean.java b/apache-libraries-2/src/main/java/com/baeldung/dynamicrouter/DynamicRouterBean.java index 8bc455353b..a28c3959a4 100644 --- a/apache-libraries-2/src/main/java/com/baeldung/dynamicrouter/DynamicRouterBean.java +++ b/apache-libraries-2/src/main/java/com/baeldung/dynamicrouter/DynamicRouterBean.java @@ -6,22 +6,23 @@ import java.util.Map; public class DynamicRouterBean { public String route(String body, @ExchangeProperties Map properties) { - int invoked = 0; - Integer current = (Integer) properties.get("invoked"); - if (current != null) { - invoked = current; - } - invoked++; + int invoked = (int) properties.getOrDefault("invoked", 0) + 1; + properties.put("invoked", invoked); - if (body.equalsIgnoreCase("mock") && invoked == 1) { - return "mock:dynamicRouter"; - } else if (body.equalsIgnoreCase("direct") && invoked == 1) { - return "mock:directDynamicRouter"; - } else if (body.equalsIgnoreCase("seda") && invoked == 1) { - return "mock:sedaDynamicRouter"; - } else if (body.equalsIgnoreCase("file") && invoked == 1) { - return "mock:fileDynamicRouter"; + if (invoked == 1) { + switch (body.toLowerCase()) { + case "mock": + return "mock:dynamicRouter"; + case "direct": + return "mock:directDynamicRouter"; + case "seda": + return "mock:sedaDynamicRouter"; + case "file": + return "mock:fileDynamicRouter"; + default: + break; + } } return null; } From fabd8328a6c8e12dd0081fe082661cc6bf8bde51 Mon Sep 17 00:00:00 2001 From: h_sharifi Date: Tue, 13 Feb 2024 09:41:45 +0330 Subject: [PATCH 05/38] #BAEL-7484: add main source --- .../SpringMongoConnectionViaBuilderApp.java | 25 +++++ .../SpringMongoConnectionViaClientApp.java | 41 ++++++++ .../SpringMongoConnectionViaFactoryApp.java | 34 +++++++ ...SpringMongoConnectionViaPropertiesApp.java | 15 +++ .../application.properties | 5 + .../MongoConnectionApplicationLiveTest.java | 99 +++++++++++++++++++ 6 files changed, 219 insertions(+) create mode 100644 persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/boot/connection/via/builder/SpringMongoConnectionViaBuilderApp.java create mode 100644 persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/boot/connection/via/client/SpringMongoConnectionViaClientApp.java create mode 100644 persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/boot/connection/via/factory/SpringMongoConnectionViaFactoryApp.java create mode 100644 persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/boot/connection/via/properties/SpringMongoConnectionViaPropertiesApp.java create mode 100644 persistence-modules/spring-boot-persistence-mongodb/src/main/resources/connection.via.properties/application.properties create mode 100644 persistence-modules/spring-boot-persistence-mongodb/src/test/java/com/baeldung/boot/connection/via/MongoConnectionApplicationLiveTest.java diff --git a/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/boot/connection/via/builder/SpringMongoConnectionViaBuilderApp.java b/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/boot/connection/via/builder/SpringMongoConnectionViaBuilderApp.java new file mode 100644 index 0000000000..3ef87fd27d --- /dev/null +++ b/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/boot/connection/via/builder/SpringMongoConnectionViaBuilderApp.java @@ -0,0 +1,25 @@ +package com.baeldung.boot.connection.via.builder; + +import com.mongodb.ConnectionString; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.WebApplicationType; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.mongo.MongoClientSettingsBuilderCustomizer; +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.context.annotation.Bean; + +@SpringBootApplication +public class SpringMongoConnectionViaBuilderApp { + + public static void main(String... args) { + SpringApplicationBuilder app = new SpringApplicationBuilder(SpringMongoConnectionViaBuilderApp.class); + app.web(WebApplicationType.NONE); + app.run(args); + } + + @Bean + public MongoClientSettingsBuilderCustomizer customizer(@Value("${custom.uri}") String uri) { + ConnectionString connection = new ConnectionString(uri); + return settings -> settings.applyConnectionString(connection); + } +} \ No newline at end of file diff --git a/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/boot/connection/via/client/SpringMongoConnectionViaClientApp.java b/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/boot/connection/via/client/SpringMongoConnectionViaClientApp.java new file mode 100644 index 0000000000..9993469a88 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/boot/connection/via/client/SpringMongoConnectionViaClientApp.java @@ -0,0 +1,41 @@ +package com.baeldung.boot.connection.via.client; + +import com.mongodb.client.ListDatabasesIterable; +import com.mongodb.client.MongoClient; +import com.mongodb.client.MongoClients; +import org.bson.Document; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.WebApplicationType; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongoAutoConfiguration; +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.data.mongodb.config.AbstractMongoClientConfiguration; + +@SpringBootApplication(exclude={EmbeddedMongoAutoConfiguration.class}) +public class SpringMongoConnectionViaClientApp extends AbstractMongoClientConfiguration { + + public static void main(String... args) { + SpringApplicationBuilder app = new SpringApplicationBuilder(SpringMongoConnectionViaClientApp.class); + app.web(WebApplicationType.NONE); + app.run(args); + } + + @Value("${spring.data.mongodb.uri}") + private String uri; + + @Value("${spring.data.mongodb.database}") + private String db; + + @Override + public MongoClient mongoClient() { + MongoClient client = MongoClients.create(uri); + ListDatabasesIterable databases = client.listDatabases(); + databases.forEach(System.out::println); + return client; + } + + @Override + protected String getDatabaseName() { + return db; + } +} \ No newline at end of file diff --git a/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/boot/connection/via/factory/SpringMongoConnectionViaFactoryApp.java b/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/boot/connection/via/factory/SpringMongoConnectionViaFactoryApp.java new file mode 100644 index 0000000000..7d04aa3792 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/boot/connection/via/factory/SpringMongoConnectionViaFactoryApp.java @@ -0,0 +1,34 @@ +package com.baeldung.boot.connection.via.factory; + +import com.mongodb.ConnectionString; +import com.mongodb.client.MongoClient; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.WebApplicationType; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.data.mongodb.core.MongoClientFactoryBean; + +@SpringBootApplication +public class SpringMongoConnectionViaFactoryApp { + + public static void main(String... args) { + SpringApplicationBuilder app = new SpringApplicationBuilder(SpringMongoConnectionViaFactoryApp.class); + app.web(WebApplicationType.NONE); + app.run(args); + } + + @Bean + public MongoClientFactoryBean mongo(@Value("${custom.uri}") String uri) throws Exception { + MongoClientFactoryBean mongo = new MongoClientFactoryBean(); + ConnectionString conn = new ConnectionString(uri); + mongo.setConnectionString(conn); + + mongo.setSingleton(false); + + MongoClient client = mongo.getObject(); + client.listDatabaseNames() + .forEach(System.out::println); + return mongo; + } +} \ No newline at end of file diff --git a/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/boot/connection/via/properties/SpringMongoConnectionViaPropertiesApp.java b/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/boot/connection/via/properties/SpringMongoConnectionViaPropertiesApp.java new file mode 100644 index 0000000000..b49149ee6f --- /dev/null +++ b/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/boot/connection/via/properties/SpringMongoConnectionViaPropertiesApp.java @@ -0,0 +1,15 @@ +package com.baeldung.boot.connection.via.properties; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongoAutoConfiguration; +import org.springframework.context.annotation.PropertySource; + +@PropertySource("classpath:connection.via.properties/application.properties") +@SpringBootApplication(exclude={EmbeddedMongoAutoConfiguration.class}) +public class SpringMongoConnectionViaPropertiesApp { + + public static void main(String... args) { + SpringApplication.run(SpringMongoConnectionViaPropertiesApp.class, args); + } +} \ No newline at end of file diff --git a/persistence-modules/spring-boot-persistence-mongodb/src/main/resources/connection.via.properties/application.properties b/persistence-modules/spring-boot-persistence-mongodb/src/main/resources/connection.via.properties/application.properties new file mode 100644 index 0000000000..e4161cd232 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-mongodb/src/main/resources/connection.via.properties/application.properties @@ -0,0 +1,5 @@ +spring.data.mongodb.host=localhost +spring.data.mongodb.port=27017 +spring.data.mongodb.database=baeldung +spring.data.mongodb.username=admin +spring.data.mongodb.password=password \ No newline at end of file diff --git a/persistence-modules/spring-boot-persistence-mongodb/src/test/java/com/baeldung/boot/connection/via/MongoConnectionApplicationLiveTest.java b/persistence-modules/spring-boot-persistence-mongodb/src/test/java/com/baeldung/boot/connection/via/MongoConnectionApplicationLiveTest.java new file mode 100644 index 0000000000..59c509d9d4 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-mongodb/src/test/java/com/baeldung/boot/connection/via/MongoConnectionApplicationLiveTest.java @@ -0,0 +1,99 @@ +package com.baeldung.boot.connection.via; + +import com.baeldung.boot.connection.via.client.SpringMongoConnectionViaClientApp; +import com.baeldung.boot.connection.via.properties.SpringMongoConnectionViaPropertiesApp; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.BeanCreationException; +import org.springframework.boot.WebApplicationType; +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.data.mongodb.core.MongoTemplate; +import org.bson.Document; + +import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; +import static org.junit.jupiter.api.Assertions.*; + +public class MongoConnectionApplicationLiveTest { + private static final String HOST = "localhost"; + private static final String PORT = "27017"; + private static final String DB = "baeldung"; + private static final String USER = "admin"; + private static final String PASS = "password"; + + private void assertInsertSucceeds(ConfigurableApplicationContext context) { + String name = "A"; + + MongoTemplate mongo = context.getBean(MongoTemplate.class); + Document doc = Document.parse("{\"name\":\"" + name + "\"}"); + Document inserted = mongo.insert(doc, "items"); + + assertNotNull(inserted.get("_id")); + assertEquals(inserted.get("name"), name); + } + + @Test + public void whenPropertiesConfig_thenInsertSucceeds() { + SpringApplicationBuilder app = new SpringApplicationBuilder(SpringMongoConnectionViaPropertiesApp.class); + app.run(); + + assertInsertSucceeds(app.context()); + } + + @Test + public void givenPrecedence_whenSystemConfig_thenInsertSucceeds() { + System.setProperty("spring.data.mongodb.host", HOST); + System.setProperty("spring.data.mongodb.port", PORT); + System.setProperty("spring.data.mongodb.database", DB); + System.setProperty("spring.data.mongodb.username", USER); + System.setProperty("spring.data.mongodb.password", PASS); + + SpringApplicationBuilder app = new SpringApplicationBuilder(SpringMongoConnectionViaPropertiesApp.class) + .properties( + "spring.data.mongodb.host=oldValue", + "spring.data.mongodb.port=oldValue", + "spring.data.mongodb.database=oldValue", + "spring.data.mongodb.username=oldValue", + "spring.data.mongodb.password=oldValue" + ); + app.run(); + + assertInsertSucceeds(app.context()); + } + + @Test + public void givenConnectionUri_whenAlsoIncludingIndividualParameters_thenInvalidConfig() { + System.setProperty( + "spring.data.mongodb.uri", + "mongodb://" + USER + ":" + PASS + "@" + HOST + ":" + PORT + "/" + DB + ); + + SpringApplicationBuilder app = new SpringApplicationBuilder(SpringMongoConnectionViaPropertiesApp.class) + .properties( + "spring.data.mongodb.host=" + HOST, + "spring.data.mongodb.port=" + PORT, + "spring.data.mongodb.username=" + USER, + "spring.data.mongodb.password=" + PASS + ); + + BeanCreationException e = assertThrows(BeanCreationException.class, () -> { + app.run(); + }); + + Throwable rootCause = e.getRootCause(); + assertTrue(rootCause instanceof IllegalStateException); + assertThat(rootCause.getMessage() + .contains("Invalid mongo configuration, either uri or host/port/credentials/replicaSet must be specified")); + } + + @Test + public void whenClientConfig_thenInsertSucceeds() { + SpringApplicationBuilder app = new SpringApplicationBuilder(SpringMongoConnectionViaClientApp.class); + app.web(WebApplicationType.NONE) + .run( + "--spring.data.mongodb.uri=mongodb://" + USER + ":" + PASS + "@" + HOST + ":" + PORT + "/" + DB, + "--spring.data.mongodb.database=" + DB + ); + + assertInsertSucceeds(app.context()); + } +} \ No newline at end of file From ce26271629df5d36bb2fb352233bf4cdb135f4de Mon Sep 17 00:00:00 2001 From: Sam Gardner Date: Tue, 13 Feb 2024 14:27:10 +0000 Subject: [PATCH 06/38] BAEL-7522 Add code for Java 18 simple web server --- .../baeldung/simple_web_server/WebServer.java | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 core-java-modules/core-java-18/src/main/java/com/baeldung/simple_web_server/WebServer.java diff --git a/core-java-modules/core-java-18/src/main/java/com/baeldung/simple_web_server/WebServer.java b/core-java-modules/core-java-18/src/main/java/com/baeldung/simple_web_server/WebServer.java new file mode 100644 index 0000000000..db36477fdb --- /dev/null +++ b/core-java-modules/core-java-18/src/main/java/com/baeldung/simple_web_server/WebServer.java @@ -0,0 +1,59 @@ +package com.baeldung.simple_web_server; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.nio.file.Path; +import java.util.function.Predicate; + +import com.sun.net.httpserver.Filter; +import com.sun.net.httpserver.Headers; +import com.sun.net.httpserver.HttpHandler; +import com.sun.net.httpserver.HttpHandlers; +import com.sun.net.httpserver.HttpServer; +import com.sun.net.httpserver.Request; +import com.sun.net.httpserver.SimpleFileServer; + +public class WebServer { + + private final InetSocketAddress address = new InetSocketAddress(8080); + private final Path path = Path.of("/"); + + public static void main(String[] args) { + WebServer webServer = new WebServer(); + HttpServer server = webServer.createWithHandler_401Response(); + server.start(); + } + + private HttpServer createBasic() { + return SimpleFileServer.createFileServer(address, path, SimpleFileServer.OutputLevel.VERBOSE); + } + + private HttpServer createWithHandler() throws IOException { + HttpServer server = SimpleFileServer.createFileServer(address, path, SimpleFileServer.OutputLevel.VERBOSE); + HttpHandler handler = SimpleFileServer.createFileHandler(Path.of("/Users")); + server.createContext("/test", handler); + return server; + } + + private HttpServer createWithHandler_401Response() { + Predicate findAllowedPath = r -> r.getRequestURI() + .getPath() + .equals("/test/allowed"); + + HttpHandler allowedResponse = HttpHandlers.of(200, Headers.of("Allow", "GET"), "Welcome"); + HttpHandler deniedResponse = HttpHandlers.of(401, Headers.of("Deny", "GET"), "Denied"); + + HttpHandler handler = HttpHandlers.handleOrElse(findAllowedPath, allowedResponse, deniedResponse); + + HttpServer server = SimpleFileServer.createFileServer(address, path, SimpleFileServer.OutputLevel.VERBOSE); + server.createContext("/test", handler); + return server; + } + + private HttpServer createWithFilter() throws IOException { + Filter filter = SimpleFileServer.createOutputFilter(System.out, SimpleFileServer.OutputLevel.INFO); + HttpHandler handler = SimpleFileServer.createFileHandler(Path.of("/Users")); + return HttpServer.create(new InetSocketAddress(8080), 10, "/test", handler, filter); + } + +} From ff272d2dde18ba208e74c3ce8391c686effb7d60 Mon Sep 17 00:00:00 2001 From: Ana Peterlic Date: Sat, 17 Feb 2024 06:59:18 +0100 Subject: [PATCH 07/38] Change log level --- .../src/main/java/com/baeldung/logging/LoggingAspect.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/spring-aop-2/src/main/java/com/baeldung/logging/LoggingAspect.java b/spring-aop-2/src/main/java/com/baeldung/logging/LoggingAspect.java index 6641b70eec..82b52bea25 100644 --- a/spring-aop-2/src/main/java/com/baeldung/logging/LoggingAspect.java +++ b/spring-aop-2/src/main/java/com/baeldung/logging/LoggingAspect.java @@ -28,13 +28,13 @@ public class LoggingAspect { public void logBefore(JoinPoint joinPoint) { Object[] args = joinPoint.getArgs(); String methodName = joinPoint.getSignature().getName(); - logger.info(">> {}() - {}", methodName, Arrays.toString(args)); + logger.debug(">> {}() - {}", methodName, Arrays.toString(args)); } @AfterReturning(value = "publicMethodsFromLoggingPackage()", returning = "result") public void logAfter(JoinPoint joinPoint, Object result) { String methodName = joinPoint.getSignature().getName(); - logger.info("<< {}() - {}", methodName, result); + logger.debug("<< {}() - {}", methodName, result); } @AfterThrowing(pointcut = "publicMethodsFromLoggingPackage()", throwing = "exception") @@ -47,9 +47,9 @@ public class LoggingAspect { public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable { Object[] args = joinPoint.getArgs(); String methodName = joinPoint.getSignature().getName(); - logger.info(">> {}() - {}", methodName, Arrays.toString(args)); + logger.debug(">> {}() - {}", methodName, Arrays.toString(args)); Object result = joinPoint.proceed(); - logger.info("<< {}() - {}", methodName, result); + logger.debug("<< {}() - {}", methodName, result); return result; } } From c96bfc17634741f7bdd8c72674085ef96c71f11b Mon Sep 17 00:00:00 2001 From: Ana Peterlic Date: Sat, 17 Feb 2024 18:13:10 +0100 Subject: [PATCH 08/38] Update GreetingServiceWithoutAOP.java --- .../java/com/baeldung/logging/GreetingServiceWithoutAOP.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spring-aop-2/src/main/java/com/baeldung/logging/GreetingServiceWithoutAOP.java b/spring-aop-2/src/main/java/com/baeldung/logging/GreetingServiceWithoutAOP.java index eee90af669..f13c70f93b 100644 --- a/spring-aop-2/src/main/java/com/baeldung/logging/GreetingServiceWithoutAOP.java +++ b/spring-aop-2/src/main/java/com/baeldung/logging/GreetingServiceWithoutAOP.java @@ -10,9 +10,9 @@ public class GreetingServiceWithoutAOP { private static final Logger logger = LoggerFactory.getLogger(GreetingServiceWithoutAOP.class); public String greet(String name) { - logger.info(">> greet() - {}", name); + logger.debug(">> greet() - {}", name); String result = String.format("Hello %s", name); - logger.info("<< greet() - {}", result); + logger.debug("<< greet() - {}", result); return result; } } From 988d1640e05a980624df7c96747664913bdf2a1b Mon Sep 17 00:00:00 2001 From: Amit Pandey Date: Sat, 17 Feb 2024 23:15:04 +0530 Subject: [PATCH 09/38] Java 31205 :- Upgrade Spring Cloud Eureka to Latest Spring Cloud version (#15881) --- spring-cloud-modules/spring-cloud-eureka/pom.xml | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/spring-cloud-modules/spring-cloud-eureka/pom.xml b/spring-cloud-modules/spring-cloud-eureka/pom.xml index 9966459a5c..686ca4f0e9 100644 --- a/spring-cloud-modules/spring-cloud-eureka/pom.xml +++ b/spring-cloud-modules/spring-cloud-eureka/pom.xml @@ -10,9 +10,10 @@ Spring Cloud Eureka Server and Sample Clients - com.baeldung.spring.cloud - spring-cloud-modules - 1.0.0-SNAPSHOT + com.baeldung + parent-boot-3 + 0.0.1-SNAPSHOT + ../../parent-boot-3 @@ -23,6 +24,10 @@ spring-cloud-eureka-server + + 2023.0.0 + + org.springframework.boot From 7cbf2eafcd03e4702734967a4fc8dbb340bb013e Mon Sep 17 00:00:00 2001 From: DiegoMarti2 <150871541+DiegoMarti2@users.noreply.github.com> Date: Sat, 17 Feb 2024 14:12:34 -0800 Subject: [PATCH 10/38] baeldung-articles : BAEL-7442 (#15887) * baeldung-articles : BAEL-7442 Check if String is Base64 Encoded (commit) * Update CheckIfStringIsBased64UnitTest.java --- .../CheckIfStringIsBased64UnitTest.java | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 core-java-modules/core-java-string-operations-8/src/test/java/com/baeldung/checkifstringisbased64/CheckIfStringIsBased64UnitTest.java diff --git a/core-java-modules/core-java-string-operations-8/src/test/java/com/baeldung/checkifstringisbased64/CheckIfStringIsBased64UnitTest.java b/core-java-modules/core-java-string-operations-8/src/test/java/com/baeldung/checkifstringisbased64/CheckIfStringIsBased64UnitTest.java new file mode 100644 index 0000000000..fdb543b3f5 --- /dev/null +++ b/core-java-modules/core-java-string-operations-8/src/test/java/com/baeldung/checkifstringisbased64/CheckIfStringIsBased64UnitTest.java @@ -0,0 +1,40 @@ +package com.baeldung.checkifstringisbased64; + +import org.junit.jupiter.api.Test; + +import java.util.Base64; +import java.util.regex.Pattern; + +import static org.junit.jupiter.api.Assertions.*; + +public class CheckIfStringIsBased64UnitTest { + + @Test + public void givenBase64EncodedString_whenDecoding_thenNoException() { + try { + Base64.getDecoder().decode("SGVsbG8gd29ybGQ="); + assertTrue(true); + } catch (IllegalArgumentException e) { + fail("Unexpected exception: " + e.getMessage()); + } + } + + @Test + public void givenNonBase64String_whenDecoding_thenCatchException() { + try { + Base64.getDecoder().decode("Hello world!"); + fail("Expected IllegalArgumentException was not thrown"); + } catch (IllegalArgumentException e) { + assertTrue(true); + } + } + + @Test + public void givenString_whenOperatingRegex_thenCheckIfItIsBase64Encoded() { + Pattern BASE64_PATTERN = Pattern.compile( + "^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$" + ); + + assertTrue(BASE64_PATTERN.matcher("SGVsbG8gd29ybGQ=").matches()); + } +} From 972571e258ac01d2466320ea036e3ac99b978411 Mon Sep 17 00:00:00 2001 From: "Kai.Yuan" Date: Sun, 18 Feb 2024 07:48:29 +0800 Subject: [PATCH 11/38] [string-in-mirror] string - mirror reflection --- ...kStringEqualsMirrorReflectionUnitTest.java | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 core-java-modules/core-java-string-algorithms-4/src/test/java/com/baeldung/string/chkstringinmirror/CheckStringEqualsMirrorReflectionUnitTest.java diff --git a/core-java-modules/core-java-string-algorithms-4/src/test/java/com/baeldung/string/chkstringinmirror/CheckStringEqualsMirrorReflectionUnitTest.java b/core-java-modules/core-java-string-algorithms-4/src/test/java/com/baeldung/string/chkstringinmirror/CheckStringEqualsMirrorReflectionUnitTest.java new file mode 100644 index 0000000000..16360aff39 --- /dev/null +++ b/core-java-modules/core-java-string-algorithms-4/src/test/java/com/baeldung/string/chkstringinmirror/CheckStringEqualsMirrorReflectionUnitTest.java @@ -0,0 +1,46 @@ +package com.baeldung.string.chkstringinmirror; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.Set; +import java.util.stream.Collectors; + +import org.junit.jupiter.api.Test; + +public class CheckStringEqualsMirrorReflectionUnitTest { + + private final static Set SYMMETRIC_LETTERS = Set.of('A', 'H', 'I', 'M', 'O', 'T', 'U', 'V', 'W', 'X', 'Y'); + + boolean isReflectionEqual(String input) { + return containsOnlySymmetricLetters(input) && isPalindrome(input); + } + + private boolean containsOnlySymmetricLetters(String input) { + Set characterSet = input.chars() + .mapToObj(c -> (char) c) + .collect(Collectors.toSet()); + characterSet.removeAll(SYMMETRIC_LETTERS); + return characterSet.isEmpty(); + } + + private boolean isPalindrome(String input) { + String reversed = new StringBuilder(input).reverse() + .toString(); + return input.equals(reversed); + } + + @Test + void whenCallingIsReflectionEqual_thenGetExpectedResults() { + assertFalse(isReflectionEqual("LOL")); + assertFalse(isReflectionEqual("AXY")); + assertFalse(isReflectionEqual("HUHU")); + + assertTrue(isReflectionEqual("")); + assertTrue(isReflectionEqual("AAA")); + assertTrue(isReflectionEqual("HUH")); + assertTrue(isReflectionEqual("HIMMIH")); + assertTrue(isReflectionEqual("HIMIH")); + } + +} \ No newline at end of file From d658a3d2b83958f0deefc37f6a098c7754f6cd5c Mon Sep 17 00:00:00 2001 From: timis1 <12120641+timis1@users.noreply.github.com> Date: Sun, 18 Feb 2024 04:09:28 +0200 Subject: [PATCH 12/38] JAVA-29303 Upgrade spring-security-web-angular (#15853) * JAVA-29303 Upgrade spring-security-web-angular * JAVA-29303 Fix indentation --------- Co-authored-by: timis1 --- .../spring-security-web-angular/pom.xml | 3 ++- .../spring-security-web-angular-server/pom.xml | 4 ---- .../config/BasicAuthConfiguration.java | 18 +++++++----------- .../controller/UserController.java | 2 +- 4 files changed, 10 insertions(+), 17 deletions(-) diff --git a/spring-security-modules/spring-security-web-angular/pom.xml b/spring-security-modules/spring-security-web-angular/pom.xml index 15dc4d007c..67b6d233e6 100644 --- a/spring-security-modules/spring-security-web-angular/pom.xml +++ b/spring-security-modules/spring-security-web-angular/pom.xml @@ -10,7 +10,8 @@ com.baeldung - spring-security-modules + parent-boot-3 + ../../parent-boot-3 0.0.1-SNAPSHOT diff --git a/spring-security-modules/spring-security-web-angular/spring-security-web-angular-server/pom.xml b/spring-security-modules/spring-security-web-angular/spring-security-web-angular-server/pom.xml index b33e0925a3..bf9fed6898 100644 --- a/spring-security-modules/spring-security-web-angular/spring-security-web-angular-server/pom.xml +++ b/spring-security-modules/spring-security-web-angular/spring-security-web-angular-server/pom.xml @@ -15,10 +15,6 @@ - - - - org.springframework.boot spring-boot-starter-security diff --git a/spring-security-modules/spring-security-web-angular/spring-security-web-angular-server/src/main/java/com/baeldung/springbootsecurityrest/basicauth/config/BasicAuthConfiguration.java b/spring-security-modules/spring-security-web-angular/spring-security-web-angular-server/src/main/java/com/baeldung/springbootsecurityrest/basicauth/config/BasicAuthConfiguration.java index 5f4b82a191..37b63d95b4 100644 --- a/spring-security-modules/spring-security-web-angular/spring-security-web-angular-server/src/main/java/com/baeldung/springbootsecurityrest/basicauth/config/BasicAuthConfiguration.java +++ b/spring-security-modules/spring-security-web-angular/spring-security-web-angular-server/src/main/java/com/baeldung/springbootsecurityrest/basicauth/config/BasicAuthConfiguration.java @@ -7,6 +7,7 @@ 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.AbstractHttpConfigurer; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.provisioning.InMemoryUserDetailsManager; @@ -27,18 +28,13 @@ public class BasicAuthConfiguration { @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { - http.csrf() - .disable() + http.csrf(AbstractHttpConfigurer::disable) .cors(withDefaults()) - .authorizeRequests() - .antMatchers(HttpMethod.OPTIONS, "/**") - .permitAll() - .antMatchers("/login") - .permitAll() - .anyRequest() - .authenticated() - .and() - .httpBasic(); + .authorizeHttpRequests(authorizationManagerRequestMatcherRegistry -> authorizationManagerRequestMatcherRegistry + .requestMatchers(HttpMethod.OPTIONS, "/**").permitAll() + .requestMatchers("/login").permitAll() + .anyRequest().authenticated()) + .httpBasic(withDefaults()); return http.build(); } } diff --git a/spring-security-modules/spring-security-web-angular/spring-security-web-angular-server/src/main/java/com/baeldung/springbootsecurityrest/controller/UserController.java b/spring-security-modules/spring-security-web-angular/spring-security-web-angular-server/src/main/java/com/baeldung/springbootsecurityrest/controller/UserController.java index 0eef4198a1..3413eaf69b 100644 --- a/spring-security-modules/spring-security-web-angular/spring-security-web-angular-server/src/main/java/com/baeldung/springbootsecurityrest/controller/UserController.java +++ b/spring-security-modules/spring-security-web-angular/spring-security-web-angular-server/src/main/java/com/baeldung/springbootsecurityrest/controller/UserController.java @@ -3,7 +3,7 @@ package com.baeldung.springbootsecurityrest.controller; import java.security.Principal; import java.util.Base64; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.RequestBody; From e20c10f0187e3e888a0ea47c92851cd2885112fe Mon Sep 17 00:00:00 2001 From: Sam Date: Sun, 18 Feb 2024 12:30:11 -0500 Subject: [PATCH 13/38] implementation for bael-7284 (#15636) * implementation * feedback --------- Co-authored-by: technoddy --- .../java/com/baeldung/findby/Account.java | 69 ++++++++++++ .../baeldung/findby/AccountApplication.java | 11 ++ .../baeldung/findby/AccountRepository.java | 18 +++ .../java/com/baeldung/findby/Permission.java | 24 ++++ .../baeldung/findby/PermissionRepository.java | 9 ++ .../findby/AccountRepositoryUnitTest.java | 105 ++++++++++++++++++ 6 files changed, 236 insertions(+) create mode 100644 persistence-modules/spring-boot-persistence-3/src/main/java/com/baeldung/findby/Account.java create mode 100644 persistence-modules/spring-boot-persistence-3/src/main/java/com/baeldung/findby/AccountApplication.java create mode 100644 persistence-modules/spring-boot-persistence-3/src/main/java/com/baeldung/findby/AccountRepository.java create mode 100644 persistence-modules/spring-boot-persistence-3/src/main/java/com/baeldung/findby/Permission.java create mode 100644 persistence-modules/spring-boot-persistence-3/src/main/java/com/baeldung/findby/PermissionRepository.java create mode 100644 persistence-modules/spring-boot-persistence-3/src/test/java/com/baeldung/boot/findby/AccountRepositoryUnitTest.java diff --git a/persistence-modules/spring-boot-persistence-3/src/main/java/com/baeldung/findby/Account.java b/persistence-modules/spring-boot-persistence-3/src/main/java/com/baeldung/findby/Account.java new file mode 100644 index 0000000000..e70e699303 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-3/src/main/java/com/baeldung/findby/Account.java @@ -0,0 +1,69 @@ +package com.baeldung.findby; + +import jakarta.persistence.*; + +import java.sql.Timestamp; + +@Entity +@Table(name = "ACCOUNTS") +public class Account { + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "accounts_seq") + @SequenceGenerator(name = "accounts_seq", sequenceName = "accounts_seq", allocationSize = 1) + @Column(name = "user_id") + private int userId; + private String username; + private String password; + private String email; + private Timestamp createdOn; + private Timestamp lastLogin; + + @OneToOne + @JoinColumn(name = "permissions_id") + private Permission permission; + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public void setPassword(String password) { + this.password = password; + } + + public void setEmail(String email) { + this.email = email; + } + + public Timestamp getCreatedOn() { + return createdOn; + } + + public void setCreatedOn(Timestamp createdOn) { + this.createdOn = createdOn; + } + + public void setLastLogin(Timestamp lastLogin) { + this.lastLogin = lastLogin; + } + + public Permission getPermission() { + return permission; + } + + public void setPermission(Permission permission) { + this.permission = permission; + } + + public String getEmail() { + return email; + } + + @Override + public String toString() { + return "Account{" + "userId=" + userId + ", username='" + username + '\'' + ", password='" + password + '\'' + ", email='" + email + '\'' + ", createdOn=" + createdOn + ", lastLogin=" + lastLogin + ", permission=" + permission + '}'; + } +} \ No newline at end of file diff --git a/persistence-modules/spring-boot-persistence-3/src/main/java/com/baeldung/findby/AccountApplication.java b/persistence-modules/spring-boot-persistence-3/src/main/java/com/baeldung/findby/AccountApplication.java new file mode 100644 index 0000000000..45d0560529 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-3/src/main/java/com/baeldung/findby/AccountApplication.java @@ -0,0 +1,11 @@ +package com.baeldung.findby; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class AccountApplication { + public static void main(String[] args) { + SpringApplication.run(AccountApplication.class, args); + } +} diff --git a/persistence-modules/spring-boot-persistence-3/src/main/java/com/baeldung/findby/AccountRepository.java b/persistence-modules/spring-boot-persistence-3/src/main/java/com/baeldung/findby/AccountRepository.java new file mode 100644 index 0000000000..b6504bff3c --- /dev/null +++ b/persistence-modules/spring-boot-persistence-3/src/main/java/com/baeldung/findby/AccountRepository.java @@ -0,0 +1,18 @@ +package com.baeldung.findby; + +import java.util.List; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface AccountRepository extends JpaRepository { + + Account findByEmail(String email); + + Account findByUsernameAndEmail(String username, String email); + + Account findByUsernameOrEmail(String username, String email); + + List findByUsernameInOrEmailIn(List usernames, List emails); +} diff --git a/persistence-modules/spring-boot-persistence-3/src/main/java/com/baeldung/findby/Permission.java b/persistence-modules/spring-boot-persistence-3/src/main/java/com/baeldung/findby/Permission.java new file mode 100644 index 0000000000..06c9d3d213 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-3/src/main/java/com/baeldung/findby/Permission.java @@ -0,0 +1,24 @@ +package com.baeldung.findby; + +import jakarta.persistence.*; + +@Entity +@Table(name = "PERMISSIONS") +public class Permission { + + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "permissions_id_sq") + @SequenceGenerator(name = "permissions_id_sq", sequenceName = "permissions_id_sq", allocationSize = 1) + private int id; + + private String type; + + public void setType(String type) { + this.type = type; + } + + @Override + public String toString() { + return "Permission{" + "id=" + id + ", type='" + type + '\'' + '}'; + } +} diff --git a/persistence-modules/spring-boot-persistence-3/src/main/java/com/baeldung/findby/PermissionRepository.java b/persistence-modules/spring-boot-persistence-3/src/main/java/com/baeldung/findby/PermissionRepository.java new file mode 100644 index 0000000000..294b81bd15 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-3/src/main/java/com/baeldung/findby/PermissionRepository.java @@ -0,0 +1,9 @@ +package com.baeldung.findby; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface PermissionRepository extends JpaRepository { + Permission findByType(String type); +} \ No newline at end of file diff --git a/persistence-modules/spring-boot-persistence-3/src/test/java/com/baeldung/boot/findby/AccountRepositoryUnitTest.java b/persistence-modules/spring-boot-persistence-3/src/test/java/com/baeldung/boot/findby/AccountRepositoryUnitTest.java new file mode 100644 index 0000000000..ce0a7d8f3e --- /dev/null +++ b/persistence-modules/spring-boot-persistence-3/src/test/java/com/baeldung/boot/findby/AccountRepositoryUnitTest.java @@ -0,0 +1,105 @@ +package com.baeldung.boot.findby; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; + +import java.sql.Timestamp; +import java.time.Instant; +import java.util.Arrays; +import java.util.List; +import java.util.UUID; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import com.baeldung.findby.Account; +import com.baeldung.findby.AccountApplication; +import com.baeldung.findby.AccountRepository; +import com.baeldung.findby.Permission; +import com.baeldung.findby.PermissionRepository; + +@SpringBootTest(classes = AccountApplication.class) +public class AccountRepositoryUnitTest { + + @Autowired + private AccountRepository accountRepository; + + @Autowired + private PermissionRepository permissionRepository; + + @BeforeEach + void setup() { + saveAccount(); + } + + @AfterEach + void tearDown() { + accountRepository.deleteAll(); + permissionRepository.deleteAll(); + } + + @Test + void givenAccountInDb_whenPerformFindByEmail_thenReturnsAccount() { + String email = "test@test.com"; + Account account = accountRepository.findByEmail(email); + assertThat(account.getEmail()).isEqualTo(email); + } + + @Test + void givenAccountInDb_whenPerformFindByUsernameAndEmail_thenReturnsAccount() { + String email = "test@test.com"; + String username = "user_admin"; + Account account = accountRepository.findByUsernameAndEmail(username, email); + assertThat(account.getUsername()).isEqualTo(username); + assertThat(account.getEmail()).isEqualTo(email); + } + + @Test + void givenAccountInDb_whenPerformFindByUsernameOrEmail_thenReturnsAccount() { + String email = "test@test.com"; + String username = "user_editor"; + Account account = accountRepository.findByUsernameOrEmail(username, email); + assertThat(account.getUsername()).isNotEqualTo(username); + assertThat(account.getEmail()).isEqualTo(email); + } + + @Test + void givenAccountInDb_whenPerformFindByUsernameInOrEmailIn_thenReturnsAccounts() { + List emails = Arrays.asList("test@test.com", "abc@abc.com", "pqr@pqr.com"); + List usernames = Arrays.asList("user_editor", "user_admin"); + List byUsernameInOrEmailIn = accountRepository.findByUsernameInOrEmailIn(usernames, emails); + assertThat(byUsernameInOrEmailIn.size()).isEqualTo(1); + assertThat(byUsernameInOrEmailIn.get(0) + .getEmail()).isEqualTo("test@test.com"); + } + + private Permission getPermissions() { + Permission editor = new Permission(); + editor.setType("editor"); + permissionRepository.save(editor); + return editor; + } + + private void saveAccount() { + List> sampleRecords = Arrays.asList( + Arrays.asList("test@test.com", "user_admin"), + Arrays.asList("test1@test.com", "user_admin_1"), + Arrays.asList("test2@test.com", "user_admin_2") + ); + + sampleRecords.forEach(sampleRecord -> { + Account account = new Account(); + account.setEmail(sampleRecord.get(0)); + account.setUsername(sampleRecord.get(1)); + account.setPermission(getPermissions()); + account.setPassword(UUID.randomUUID() + .toString()); + account.setCreatedOn(Timestamp.from(Instant.now())); + account.setLastLogin(Timestamp.from(Instant.now())); + accountRepository.save(account); + System.out.println(account.toString()); + }); + } +} From 6a80f8562525a059953f9059f584fa53bd3dc0bf Mon Sep 17 00:00:00 2001 From: Wynn Teo <49014791+wynnteo@users.noreply.github.com> Date: Mon, 19 Feb 2024 03:47:45 +0800 Subject: [PATCH 14/38] Bael 7489 (#15828) * BAEL-7490 read write file in separate thread * Change the to try resources * Update the code to sync with article * BAEL-7489 first draft * Change to spring-kafka-3 module * moved to another repo --- .../HandleInstanceAlreadyExistsException.java | 56 ++++++++ .../kafka/kafkaexception/KafkaAppMain.java | 12 ++ ...imulateInstanceAlreadyExistsException.java | 123 ++++++++++++++++++ 3 files changed, 191 insertions(+) create mode 100644 spring-kafka-3/src/main/java/com/baeldung/spring/kafka/kafkaexception/HandleInstanceAlreadyExistsException.java create mode 100644 spring-kafka-3/src/main/java/com/baeldung/spring/kafka/kafkaexception/KafkaAppMain.java create mode 100644 spring-kafka-3/src/main/java/com/baeldung/spring/kafka/kafkaexception/SimulateInstanceAlreadyExistsException.java diff --git a/spring-kafka-3/src/main/java/com/baeldung/spring/kafka/kafkaexception/HandleInstanceAlreadyExistsException.java b/spring-kafka-3/src/main/java/com/baeldung/spring/kafka/kafkaexception/HandleInstanceAlreadyExistsException.java new file mode 100644 index 0000000000..1de39987b8 --- /dev/null +++ b/spring-kafka-3/src/main/java/com/baeldung/spring/kafka/kafkaexception/HandleInstanceAlreadyExistsException.java @@ -0,0 +1,56 @@ +package com.baeldung.spring.kafka.kafkaexception; + +import java.lang.management.ManagementFactory; +import java.util.Properties; +import java.util.UUID; + +import javax.management.MBeanServer; +import javax.management.ObjectName; + +import org.apache.kafka.clients.producer.KafkaProducer; +import org.apache.kafka.common.serialization.StringSerializer; + +public class HandleInstanceAlreadyExistsException { + + public static void generateUniqueClientIDUsingUUIDRandom() { + Properties props = new Properties(); + props.put("bootstrap.servers", "localhost:9092"); + props.put("key.serializer", StringSerializer.class); + props.put("value.serializer", StringSerializer.class); + + String clientId = "my-producer-" + UUID.randomUUID(); + props.setProperty("client.id", clientId); + KafkaProducer producer1 = new KafkaProducer<>(props); + + clientId = "my-producer-" + UUID.randomUUID(); + props.setProperty("client.id", clientId); + KafkaProducer producer2 = new KafkaProducer<>(props); + } + + public static void closeProducerProperlyBeforeReinstantiate() { + Properties props = new Properties(); + props.put("bootstrap.servers", "localhost:9092"); + props.put("client.id", "my-producer"); + props.put("key.serializer", StringSerializer.class); + props.put("value.serializer", StringSerializer.class); + + KafkaProducer producer1 = new KafkaProducer<>(props); + producer1.close(); + + producer1 = new KafkaProducer<>(props); + } + + public static void useUniqueObjectName() throws Exception { + MBeanServer mBeanServer1 = ManagementFactory.getPlatformMBeanServer(); + MBeanServer mBeanServer2 = ManagementFactory.getPlatformMBeanServer(); + + ObjectName objectName1 = new ObjectName("kafka.server:type=KafkaMetrics,id=metric1"); + ObjectName objectName2 = new ObjectName("kafka.server:type=KafkaMetrics,id=metric2"); + + MyMBean mBean1 = new MyMBean(); + mBeanServer1.registerMBean(mBean1, objectName1); + + MyMBean mBean2 = new MyMBean(); + mBeanServer2.registerMBean(mBean2, objectName2); + } +} diff --git a/spring-kafka-3/src/main/java/com/baeldung/spring/kafka/kafkaexception/KafkaAppMain.java b/spring-kafka-3/src/main/java/com/baeldung/spring/kafka/kafkaexception/KafkaAppMain.java new file mode 100644 index 0000000000..14d6b71b10 --- /dev/null +++ b/spring-kafka-3/src/main/java/com/baeldung/spring/kafka/kafkaexception/KafkaAppMain.java @@ -0,0 +1,12 @@ +package com.baeldung.spring.kafka.kafkaexception; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class KafkaAppMain { + + public static void main(String[] args) { + SpringApplication.run(KafkaAppMain.class, args); + } +} diff --git a/spring-kafka-3/src/main/java/com/baeldung/spring/kafka/kafkaexception/SimulateInstanceAlreadyExistsException.java b/spring-kafka-3/src/main/java/com/baeldung/spring/kafka/kafkaexception/SimulateInstanceAlreadyExistsException.java new file mode 100644 index 0000000000..d454d317f2 --- /dev/null +++ b/spring-kafka-3/src/main/java/com/baeldung/spring/kafka/kafkaexception/SimulateInstanceAlreadyExistsException.java @@ -0,0 +1,123 @@ +package com.baeldung.spring.kafka.kafkaexception; + +import java.lang.management.ManagementFactory; +import java.util.Properties; + +import javax.management.Attribute; +import javax.management.AttributeList; +import javax.management.AttributeNotFoundException; +import javax.management.DynamicMBean; +import javax.management.InvalidAttributeValueException; +import javax.management.MBeanAttributeInfo; +import javax.management.MBeanConstructorInfo; +import javax.management.MBeanException; +import javax.management.MBeanInfo; +import javax.management.MBeanNotificationInfo; +import javax.management.MBeanOperationInfo; +import javax.management.MBeanServer; +import javax.management.ObjectName; +import javax.management.ReflectionException; + +import org.apache.kafka.clients.consumer.KafkaConsumer; +import org.apache.kafka.clients.producer.KafkaProducer; +import org.apache.kafka.common.serialization.StringDeserializer; +import org.apache.kafka.common.serialization.StringSerializer; +import org.springframework.stereotype.Service; + +@Service +public class SimulateInstanceAlreadyExistsException { + + public static void jmxRegistrationConflicts() throws Exception { + // Create two instances of MBeanServer + MBeanServer mBeanServer1 = ManagementFactory.getPlatformMBeanServer(); + MBeanServer mBeanServer2 = ManagementFactory.getPlatformMBeanServer(); + + // Define the same ObjectName for both MBeans + ObjectName objectName = new ObjectName("kafka.server:type=KafkaMetrics"); + + // Create and register the first MBean + MyMBean mBean1 = new MyMBean(); + mBeanServer1.registerMBean(mBean1, objectName); + + // Attempt to register the second MBean with the same ObjectName + MyMBean mBean2 = new MyMBean(); + mBeanServer2.registerMBean(mBean2, objectName); + } + + public static void duplicateConsumerClientID() { + Properties props = new Properties(); + props.put("bootstrap.servers", "localhost:9092"); + props.put("client.id", "my-consumer"); + props.put("group.id", "test-group"); + props.put("key.deserializer", StringDeserializer.class); + props.put("value.deserializer", StringDeserializer.class); + + // Simulating concurrent client creation by multiple threads + for (int i = 0; i < 3; i++) { + new Thread(() -> { + KafkaConsumer consumer = new KafkaConsumer<>(props); + }).start(); + } + } + + public void duplicateProducerClientID() throws Exception { + Properties props = new Properties(); + props.put("bootstrap.servers", "localhost:9092"); + props.put("client.id", "my-producer"); + props.put("key.serializer", StringSerializer.class); + props.put("value.serializer", StringSerializer.class); + + KafkaProducer producer1 = new KafkaProducer<>(props); + // Attempting to create another producer using same client.id + KafkaProducer producer2 = new KafkaProducer<>(props); + } + + public static void unclosedProducerAndReinitialize() { + Properties props = new Properties(); + props.put("bootstrap.servers", "localhost:9092"); + props.put("client.id", "my-producer"); + props.put("key.serializer", StringSerializer.class); + props.put("value.serializer", StringSerializer.class); + + KafkaProducer producer1 = new KafkaProducer<>(props); + // Attempting to reinitialize without proper close + producer1 = new KafkaProducer<>(props); + } +} + +class MyMBean implements DynamicMBean { + + @Override + public Object getAttribute(String attribute) throws AttributeNotFoundException, MBeanException, ReflectionException { + return null; + } + + @Override + public void setAttribute(Attribute attribute) throws AttributeNotFoundException, InvalidAttributeValueException, MBeanException, ReflectionException { + + } + + @Override + public AttributeList getAttributes(String[] attributes) { + return null; + } + + @Override + public AttributeList setAttributes(AttributeList attributes) { + return null; + } + + @Override + public Object invoke(String actionName, Object[] params, String[] signature) throws MBeanException, ReflectionException { + return null; + } + + @Override + public MBeanInfo getMBeanInfo() { + MBeanAttributeInfo[] attributes = new MBeanAttributeInfo[0]; + MBeanConstructorInfo[] constructors = new MBeanConstructorInfo[0]; + MBeanOperationInfo[] operations = new MBeanOperationInfo[0]; + MBeanNotificationInfo[] notifications = new MBeanNotificationInfo[0]; + return new MBeanInfo(MyMBean.class.getName(), "My MBean", attributes, constructors, operations, notifications); + } +} From bac8dd053630174dc448cd5310c8b855f9284ae2 Mon Sep 17 00:00:00 2001 From: Bipin kumar Date: Mon, 19 Feb 2024 13:13:39 +0530 Subject: [PATCH 15/38] [JAVA-28926] Changes made to upgrade lightrun to Spring Boot 3 (#15880) --- lightrun/lightrun-tasks-service/pom.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lightrun/lightrun-tasks-service/pom.xml b/lightrun/lightrun-tasks-service/pom.xml index 773c81a9d5..c27ef103b9 100644 --- a/lightrun/lightrun-tasks-service/pom.xml +++ b/lightrun/lightrun-tasks-service/pom.xml @@ -48,6 +48,7 @@ org.apache.activemq artemis-jms-server + ${activemq.version} org.springframework.boot @@ -65,4 +66,8 @@ + + 2.32.0 + + \ No newline at end of file From b8c241574575b33294df3f6129be08c32531d8f4 Mon Sep 17 00:00:00 2001 From: Sam Gardner Date: Mon, 19 Feb 2024 13:16:43 +0000 Subject: [PATCH 16/38] BAEL-7522-Rename-package-for-simple-web-server --- .../{simple_web_server => simplewebserver}/WebServer.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) rename core-java-modules/core-java-18/src/main/java/com/baeldung/{simple_web_server => simplewebserver}/WebServer.java (92%) diff --git a/core-java-modules/core-java-18/src/main/java/com/baeldung/simple_web_server/WebServer.java b/core-java-modules/core-java-18/src/main/java/com/baeldung/simplewebserver/WebServer.java similarity index 92% rename from core-java-modules/core-java-18/src/main/java/com/baeldung/simple_web_server/WebServer.java rename to core-java-modules/core-java-18/src/main/java/com/baeldung/simplewebserver/WebServer.java index db36477fdb..ba1747b379 100644 --- a/core-java-modules/core-java-18/src/main/java/com/baeldung/simple_web_server/WebServer.java +++ b/core-java-modules/core-java-18/src/main/java/com/baeldung/simplewebserver/WebServer.java @@ -1,4 +1,4 @@ -package com.baeldung.simple_web_server; +package com.baeldung.simplewebserver; import java.io.IOException; import java.net.InetSocketAddress; @@ -20,7 +20,7 @@ public class WebServer { public static void main(String[] args) { WebServer webServer = new WebServer(); - HttpServer server = webServer.createWithHandler_401Response(); + HttpServer server = webServer.createWithHandler401Response(); server.start(); } @@ -35,7 +35,7 @@ public class WebServer { return server; } - private HttpServer createWithHandler_401Response() { + private HttpServer createWithHandler401Response() { Predicate findAllowedPath = r -> r.getRequestURI() .getPath() .equals("/test/allowed"); From a407c2f01543573752cd05ca2d31ff5885980064 Mon Sep 17 00:00:00 2001 From: Amit Pandey Date: Mon, 19 Feb 2024 19:26:56 +0530 Subject: [PATCH 17/38] JAVA-24962 - Modifications to make client work with EJB deployed in Wildfly. (#15753) --- spring-ejb-modules/spring-ejb-client/pom.xml | 12 ++++++++++++ .../springejbclient/SpringEjbClientApplication.java | 4 ++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/spring-ejb-modules/spring-ejb-client/pom.xml b/spring-ejb-modules/spring-ejb-client/pom.xml index b3a65db32b..a94a2e96e0 100644 --- a/spring-ejb-modules/spring-ejb-client/pom.xml +++ b/spring-ejb-modules/spring-ejb-client/pom.xml @@ -50,6 +50,18 @@ io.undertow undertow-servlet + + org.wildfly + wildfly-naming-client + + + org.jboss + jboss-ejb-client + + + org.wildfly.common + wildfly-common + diff --git a/spring-ejb-modules/spring-ejb-client/src/main/java/com/baeldung/springejbclient/SpringEjbClientApplication.java b/spring-ejb-modules/spring-ejb-client/src/main/java/com/baeldung/springejbclient/SpringEjbClientApplication.java index 554fac3417..1f04dcb113 100644 --- a/spring-ejb-modules/spring-ejb-client/src/main/java/com/baeldung/springejbclient/SpringEjbClientApplication.java +++ b/spring-ejb-modules/spring-ejb-client/src/main/java/com/baeldung/springejbclient/SpringEjbClientApplication.java @@ -21,7 +21,7 @@ public class SpringEjbClientApplication { Properties jndiProps = new Properties(); jndiProps.put("java.naming.factory.initial", "org.jboss.naming.remote.client.InitialContextFactory"); jndiProps.put("jboss.naming.client.ejb.context", true); - jndiProps.put("java.naming.provider.url", "http-remoting://localhost:8080"); + jndiProps.put("java.naming.provider.url", "remote+http://localhost:8080"); return new InitialContext(jndiProps); } @@ -37,7 +37,7 @@ public class SpringEjbClientApplication { @SuppressWarnings("rawtypes") private String getFullName(Class classType) { - String moduleName = "spring-ejb-remote/"; + String moduleName = "ejb:/spring-ejb-remote/"; String beanName = classType.getSimpleName(); String viewClassName = classType.getName(); From b4bbf687344f8d859e90d4dd133f5524a542687f Mon Sep 17 00:00:00 2001 From: Harry9656 Date: Mon, 19 Feb 2024 17:39:32 +0100 Subject: [PATCH 18/38] JAVA-29311: migrate spring-security-web-login-2 to parent-boot-3. (#15913) --- .../spring-security-web-login-2/pom.xml | 8 +++++-- .../securityconfig/SpringSecurityConfig.java | 6 ++--- .../SimpleSecurityConfiguration.java | 24 +++++++++---------- .../ManualLogoutIntegrationTest.java | 6 ++--- 4 files changed, 24 insertions(+), 20 deletions(-) diff --git a/spring-security-modules/spring-security-web-login-2/pom.xml b/spring-security-modules/spring-security-web-login-2/pom.xml index a44543a6ba..be2352b299 100644 --- a/spring-security-modules/spring-security-web-login-2/pom.xml +++ b/spring-security-modules/spring-security-web-login-2/pom.xml @@ -10,8 +10,9 @@ com.baeldung - spring-security-modules + parent-boot-3 0.0.1-SNAPSHOT + ../../parent-boot-3 @@ -29,7 +30,7 @@ org.thymeleaf.extras - thymeleaf-extras-springsecurity5 + thymeleaf-extras-springsecurity6 org.springframework @@ -56,4 +57,7 @@ + + com.baeldung.manuallogout.ManualLogoutApplication + \ No newline at end of file diff --git a/spring-security-modules/spring-security-web-login-2/src/main/java/com/baeldung/logoutredirects/securityconfig/SpringSecurityConfig.java b/spring-security-modules/spring-security-web-login-2/src/main/java/com/baeldung/logoutredirects/securityconfig/SpringSecurityConfig.java index ae2cdc20ec..99059112bc 100644 --- a/spring-security-modules/spring-security-web-login-2/src/main/java/com/baeldung/logoutredirects/securityconfig/SpringSecurityConfig.java +++ b/spring-security-modules/spring-security-web-login-2/src/main/java/com/baeldung/logoutredirects/securityconfig/SpringSecurityConfig.java @@ -1,20 +1,20 @@ package com.baeldung.logoutredirects.securityconfig; -import javax.servlet.http.HttpServletResponse; - import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.web.SecurityFilterChain; +import jakarta.servlet.http.HttpServletResponse; + @Configuration @EnableWebSecurity public class SpringSecurityConfig { @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { - http.authorizeRequests(authz -> authz.mvcMatchers("/login") + http.authorizeHttpRequests(authz -> authz.requestMatchers("/login") .permitAll() .anyRequest() .authenticated()) diff --git a/spring-security-modules/spring-security-web-login-2/src/main/java/com/baeldung/manuallogout/SimpleSecurityConfiguration.java b/spring-security-modules/spring-security-web-login-2/src/main/java/com/baeldung/manuallogout/SimpleSecurityConfiguration.java index 3991d9a264..92ee4a84a6 100644 --- a/spring-security-modules/spring-security-web-login-2/src/main/java/com/baeldung/manuallogout/SimpleSecurityConfiguration.java +++ b/spring-security-modules/spring-security-web-login-2/src/main/java/com/baeldung/manuallogout/SimpleSecurityConfiguration.java @@ -5,9 +5,6 @@ import static org.springframework.security.web.header.writers.ClearSiteDataHeade import static org.springframework.security.web.header.writers.ClearSiteDataHeaderWriter.Directive.EXECUTION_CONTEXTS; import static org.springframework.security.web.header.writers.ClearSiteDataHeaderWriter.Directive.STORAGE; -import javax.servlet.ServletException; -import javax.servlet.http.Cookie; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.annotation.Bean; @@ -20,11 +17,14 @@ import org.springframework.security.web.authentication.logout.HeaderWriterLogout import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler; import org.springframework.security.web.header.writers.ClearSiteDataHeaderWriter; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.Cookie; + @Configuration @EnableWebSecurity public class SimpleSecurityConfiguration { - private static Logger logger = LoggerFactory.getLogger(SimpleSecurityConfiguration.class); + private static final Logger logger = LoggerFactory.getLogger(SimpleSecurityConfiguration.class); @Order(4) @Configuration @@ -32,8 +32,8 @@ public class SimpleSecurityConfiguration { @Bean public SecurityFilterChain filterChainLogoutOnRequest(HttpSecurity http) throws Exception { - http.antMatcher("/request/**") - .authorizeRequests(authz -> authz.anyRequest() + http.securityMatcher("/request/**") + .authorizeHttpRequests(authz -> authz.anyRequest() .permitAll()) .logout(logout -> logout.logoutUrl("/request/logout") .addLogoutHandler((request, response, auth) -> { @@ -53,8 +53,8 @@ public class SimpleSecurityConfiguration { @Bean public SecurityFilterChain filterChainDefaultLogout(HttpSecurity http) throws Exception { - http.antMatcher("/basic/**") - .authorizeRequests(authz -> authz.anyRequest() + http.securityMatcher("/basic/**") + .authorizeHttpRequests(authz -> authz.anyRequest() .permitAll()) .logout(logout -> logout.logoutUrl("/basic/basiclogout")); return http.build(); @@ -67,8 +67,8 @@ public class SimpleSecurityConfiguration { @Bean public SecurityFilterChain filterChainAllCookieClearing(HttpSecurity http) throws Exception { - http.antMatcher("/cookies/**") - .authorizeRequests(authz -> authz.anyRequest() + http.securityMatcher("/cookies/**") + .authorizeHttpRequests(authz -> authz.anyRequest() .permitAll()) .logout(logout -> logout.logoutUrl("/cookies/cookielogout") .addLogoutHandler(new SecurityContextLogoutHandler()) @@ -92,8 +92,8 @@ public class SimpleSecurityConfiguration { @Bean public SecurityFilterChain filterChainClearSiteDataHeader(HttpSecurity http) throws Exception { - http.antMatcher("/csd/**") - .authorizeRequests(authz -> authz.anyRequest() + http.securityMatcher("/csd/**") + .authorizeHttpRequests(authz -> authz.anyRequest() .permitAll()) .logout(logout -> logout.logoutUrl("/csd/csdlogout") .addLogoutHandler(new HeaderWriterLogoutHandler(new ClearSiteDataHeaderWriter(SOURCE)))); diff --git a/spring-security-modules/spring-security-web-login-2/src/test/java/com/baeldung/manuallogout/ManualLogoutIntegrationTest.java b/spring-security-modules/spring-security-web-login-2/src/test/java/com/baeldung/manuallogout/ManualLogoutIntegrationTest.java index a9ad907c30..528bb5e80f 100644 --- a/spring-security-modules/spring-security-web-login-2/src/test/java/com/baeldung/manuallogout/ManualLogoutIntegrationTest.java +++ b/spring-security-modules/spring-security-web-login-2/src/test/java/com/baeldung/manuallogout/ManualLogoutIntegrationTest.java @@ -9,9 +9,6 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpSession; - import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; @@ -22,6 +19,9 @@ import org.springframework.security.test.context.support.WithMockUser; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.web.servlet.MockMvc; +import jakarta.servlet.http.Cookie; +import jakarta.servlet.http.HttpSession; + @RunWith(SpringRunner.class) @WebMvcTest(SimpleSecurityConfiguration.class) public class ManualLogoutIntegrationTest { From c90cd8ace873779d9d3f93f556c97ebf68da5962 Mon Sep 17 00:00:00 2001 From: panos-kakos <102670093+panos-kakos@users.noreply.github.com> Date: Mon, 19 Feb 2024 19:28:46 +0200 Subject: [PATCH 19/38] [JAVA-30178] Upgraded byte-buddy version in main pom.xml (#15860) --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 6de6042906..f87e8689e1 100644 --- a/pom.xml +++ b/pom.xml @@ -1167,7 +1167,7 @@ 2.2 1.3 4.4.0 - 1.14.6 + 1.14.11 From 9d13085bbc7e11a4c8ad76a21a090e915ea24b0f Mon Sep 17 00:00:00 2001 From: "Kai.Yuan" Date: Tue, 20 Feb 2024 07:30:30 +0800 Subject: [PATCH 20/38] [string-in-mirror] renaming etc. --- ...kStringEqualsMirrorReflectionUnitTest.java | 29 ++++++++++--------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/core-java-modules/core-java-string-algorithms-4/src/test/java/com/baeldung/string/chkstringinmirror/CheckStringEqualsMirrorReflectionUnitTest.java b/core-java-modules/core-java-string-algorithms-4/src/test/java/com/baeldung/string/chkstringinmirror/CheckStringEqualsMirrorReflectionUnitTest.java index 16360aff39..69329bf37c 100644 --- a/core-java-modules/core-java-string-algorithms-4/src/test/java/com/baeldung/string/chkstringinmirror/CheckStringEqualsMirrorReflectionUnitTest.java +++ b/core-java-modules/core-java-string-algorithms-4/src/test/java/com/baeldung/string/chkstringinmirror/CheckStringEqualsMirrorReflectionUnitTest.java @@ -12,7 +12,21 @@ public class CheckStringEqualsMirrorReflectionUnitTest { private final static Set SYMMETRIC_LETTERS = Set.of('A', 'H', 'I', 'M', 'O', 'T', 'U', 'V', 'W', 'X', 'Y'); - boolean isReflectionEqual(String input) { + @Test + void whenCallingIsReflectionEqual_thenGetExpectedResults() { + assertFalse(isMirrorImageEqual("LOL")); + assertFalse(isMirrorImageEqual("AXY")); + assertFalse(isMirrorImageEqual("HUHU")); + + assertTrue(isMirrorImageEqual("")); + assertTrue(isMirrorImageEqual("AAA")); + assertTrue(isMirrorImageEqual("HUH")); + assertTrue(isMirrorImageEqual("HIMMIH")); + assertTrue(isMirrorImageEqual("HIMIH")); + } + + + public boolean isMirrorImageEqual(String input) { return containsOnlySymmetricLetters(input) && isPalindrome(input); } @@ -30,17 +44,4 @@ public class CheckStringEqualsMirrorReflectionUnitTest { return input.equals(reversed); } - @Test - void whenCallingIsReflectionEqual_thenGetExpectedResults() { - assertFalse(isReflectionEqual("LOL")); - assertFalse(isReflectionEqual("AXY")); - assertFalse(isReflectionEqual("HUHU")); - - assertTrue(isReflectionEqual("")); - assertTrue(isReflectionEqual("AAA")); - assertTrue(isReflectionEqual("HUH")); - assertTrue(isReflectionEqual("HIMMIH")); - assertTrue(isReflectionEqual("HIMIH")); - } - } \ No newline at end of file From bd36eddecaa79e19316fd270790822eec7de7731 Mon Sep 17 00:00:00 2001 From: Harry9656 Date: Tue, 20 Feb 2024 01:19:05 +0100 Subject: [PATCH 21/38] JAVA-29315: Upgrade spring-security-web-react to parent-spring-6 (#15920) --- .../spring-security-web-react/pom.xml | 27 ++++++------- .../com/baeldung/spring/RestController.java | 3 +- .../baeldung/spring/SecSecurityConfig.java | 39 ++++++++----------- .../java/com/baeldung/SpringContextTest.java | 19 +++++---- 4 files changed, 43 insertions(+), 45 deletions(-) diff --git a/spring-security-modules/spring-security-web-react/pom.xml b/spring-security-modules/spring-security-web-react/pom.xml index 3a519acf09..f8f98ced23 100644 --- a/spring-security-modules/spring-security-web-react/pom.xml +++ b/spring-security-modules/spring-security-web-react/pom.xml @@ -10,9 +10,9 @@ com.baeldung - parent-spring-5 + parent-spring-6 0.0.1-SNAPSHOT - ../../parent-spring-5 + ../../parent-spring-6 @@ -20,17 +20,17 @@ org.springframework.security spring-security-web - ${spring-security.version} + ${spring.version} org.springframework.security spring-security-config - ${spring-security.version} + ${spring.version} org.springframework.security spring-security-taglibs - ${spring-security.version} + ${spring.version} @@ -65,22 +65,21 @@ - javax.servlet - javax.servlet-api - ${javax.servlet-api.version} + jakarta.servlet + jakarta.servlet-api + ${jakarta-servlet-api.version} provided - javax.servlet - jstl - ${jstl.version} - runtime + jakarta.servlet.jsp.jstl + jakarta.servlet.jsp.jstl-api + ${jakarta-servlet-jsp.version} org.springframework.boot spring-boot-starter-test - ${spring-boot-starter-test.version} + ${spring-boot.version} test @@ -153,6 +152,8 @@ v8.11.3 6.1.0 + 3.0.0 + 6.1.0-M1 \ No newline at end of file diff --git a/spring-security-modules/spring-security-web-react/src/main/java/com/baeldung/spring/RestController.java b/spring-security-modules/spring-security-web-react/src/main/java/com/baeldung/spring/RestController.java index 4084df9698..07e2b9c2ea 100644 --- a/spring-security-modules/spring-security-web-react/src/main/java/com/baeldung/spring/RestController.java +++ b/spring-security-modules/spring-security-web-react/src/main/java/com/baeldung/spring/RestController.java @@ -1,5 +1,4 @@ package com.baeldung.spring; -import javax.servlet.http.HttpServletRequest; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -10,6 +9,8 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; +import jakarta.servlet.http.HttpServletRequest; + @Controller @RequestMapping("/rest") public class RestController { diff --git a/spring-security-modules/spring-security-web-react/src/main/java/com/baeldung/spring/SecSecurityConfig.java b/spring-security-modules/spring-security-web-react/src/main/java/com/baeldung/spring/SecSecurityConfig.java index 7e588f4d97..67c0c181ca 100644 --- a/spring-security-modules/spring-security-web-react/src/main/java/com/baeldung/spring/SecSecurityConfig.java +++ b/spring-security-modules/spring-security-web-react/src/main/java/com/baeldung/spring/SecSecurityConfig.java @@ -38,28 +38,21 @@ public class SecSecurityConfig { @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { - http.csrf() - .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()) - .and() - .authorizeRequests() - .antMatchers("/admin/**") - .hasRole("ADMIN") - .antMatchers("/anonymous*") - .anonymous() - .antMatchers(HttpMethod.GET, "/index*", "/static/**", "/*.js", "/*.json", "/*.ico", "/rest") - .permitAll() - .anyRequest() - .authenticated() - .and() - .formLogin() - .loginPage("/index.html") - .loginProcessingUrl("/perform_login") - .defaultSuccessUrl("/homepage.html", true) - .failureUrl("/index.html?error=true") - .and() - .logout() - .logoutUrl("/perform_logout") - .deleteCookies("JSESSIONID"); - return http.build(); + return http.csrf(csrf -> csrf.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())) + .authorizeHttpRequests(request -> request.requestMatchers("/admin/**") + .hasRole("ADMIN") + .requestMatchers("/anonymous*") + .anonymous() + .requestMatchers(HttpMethod.GET, "/index*", "/static/**", "/*.js", "/*.json", "/*.ico", "/rest") + .permitAll() + .anyRequest() + .authenticated()) + .formLogin(form -> form.loginPage("/index.html") + .loginProcessingUrl("/perform_login") + .defaultSuccessUrl("/homepage.html", true) + .failureUrl("/index.html?error=true")) + .logout(logout -> logout.logoutUrl("/perform_logout") + .deleteCookies("JSESSIONID")) + .build(); } } diff --git a/spring-security-modules/spring-security-web-react/src/test/java/com/baeldung/SpringContextTest.java b/spring-security-modules/spring-security-web-react/src/test/java/com/baeldung/SpringContextTest.java index 43ddb515eb..fcb1764aa0 100644 --- a/spring-security-modules/spring-security-web-react/src/test/java/com/baeldung/SpringContextTest.java +++ b/spring-security-modules/spring-security-web-react/src/test/java/com/baeldung/SpringContextTest.java @@ -1,19 +1,22 @@ package com.baeldung; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; +import org.springframework.test.context.web.WebAppConfiguration; + import com.baeldung.spring.MvcConfig; import com.baeldung.spring.SecSecurityConfig; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.test.context.web.WebAppConfiguration; -@RunWith(SpringJUnit4ClassRunner.class) @WebAppConfiguration @ContextConfiguration(classes = { MvcConfig.class, SecSecurityConfig.class }) -public class SpringContextTest { +@ExtendWith(SpringExtension.class) +class SpringContextTest { @Test - public void whenSpringContextIsBootstrapped_thenNoExceptions() { + void whenSpringContextIsBootstrapped_thenNoExceptions() { } } + + From d4f8b4ff660b894f92369d53157c5e4213f7e1ce Mon Sep 17 00:00:00 2001 From: Diegom203 <153622681+Diegom203@users.noreply.github.com> Date: Mon, 19 Feb 2024 18:24:35 -0800 Subject: [PATCH 22/38] baeldung-articles : BAEL-5937 (#15922) Create JavaType From Class with Jackson (commit). --- .../JavaTypeFromClassUnitTest.java | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 jackson-modules/jackson-custom-conversions/javatypefromclassinjava/JavaTypeFromClassUnitTest.java diff --git a/jackson-modules/jackson-custom-conversions/javatypefromclassinjava/JavaTypeFromClassUnitTest.java b/jackson-modules/jackson-custom-conversions/javatypefromclassinjava/JavaTypeFromClassUnitTest.java new file mode 100644 index 0000000000..bb95d9987b --- /dev/null +++ b/jackson-modules/jackson-custom-conversions/javatypefromclassinjava/JavaTypeFromClassUnitTest.java @@ -0,0 +1,38 @@ +package com.baeldung.javatypefromclassinjava; + +import com.fasterxml.jackson.databind.JavaType; +import com.fasterxml.jackson.databind.type.TypeFactory; +import org.junit.Test; + +import static org.junit.Assert.assertNotNull; + +public class JavaTypeFromClassUnitTest { + + @Test + public void givenGenericClass_whenCreatingJavaType_thenJavaTypeNotNull() { + Class myClass = MyGenericClass.class; + + JavaType javaType = TypeFactory.defaultInstance().constructType(myClass); + + assertNotNull(javaType); + } + + @Test + public void givenParametricType_whenCreatingJavaType_thenJavaTypeNotNull() { + Class containerClass = Container.class; + Class elementType = String.class; + + JavaType javaType = TypeFactory.defaultInstance().constructParametricType(containerClass, elementType); + + assertNotNull(javaType); + } + + static class MyGenericClass { + // Class implementation + } + + static class Container { + // Class implementation + } + +} From abb1f462b9d3ddddab54eba7fc6c1684f26e6b21 Mon Sep 17 00:00:00 2001 From: Wynn Teo <49014791+wynnteo@users.noreply.github.com> Date: Tue, 20 Feb 2024 11:11:25 +0800 Subject: [PATCH 23/38] Bael 7541 (#15877) * BAEL-7490 read write file in separate thread * Change the to try resources * Update the code to sync with article * BAEL-7541 compare runAsync and supplyAsync --- .../runvssupply/RunAndSupplyCompare.java | 79 +++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 core-java-modules/core-java-concurrency-2/src/main/java/com/baeldung/runvssupply/RunAndSupplyCompare.java diff --git a/core-java-modules/core-java-concurrency-2/src/main/java/com/baeldung/runvssupply/RunAndSupplyCompare.java b/core-java-modules/core-java-concurrency-2/src/main/java/com/baeldung/runvssupply/RunAndSupplyCompare.java new file mode 100644 index 0000000000..a3b80d2db2 --- /dev/null +++ b/core-java-modules/core-java-concurrency-2/src/main/java/com/baeldung/runvssupply/RunAndSupplyCompare.java @@ -0,0 +1,79 @@ +package com.baeldung.runvssupply; + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; + +public class RunAndSupplyCompare { + + public static void main(String args[]) throws ExecutionException, InterruptedException { + chainingOperationCompare(); + } + + public static void inputAndReturnCompare() throws ExecutionException, InterruptedException { + CompletableFuture runAsyncFuture = CompletableFuture.runAsync(() -> { + // Perform non-result producing task + System.out.println("Task executed asynchronously"); + }); + + CompletableFuture supplyAsyncFuture = CompletableFuture.supplyAsync(() -> { + // Perform result-producing task + return "Result of the asynchronous computation"; + }); + // Get the result later + String result = supplyAsyncFuture.get(); + System.out.println("Result: " + result); + } + + public static void exceptionHandlingCompare() { + CompletableFuture runAsyncFuture = CompletableFuture.runAsync(() -> { + // Task that may throw an exception + throw new RuntimeException("Exception occurred in asynchronous task"); + }); + try { + runAsyncFuture.get(); + // Exception will be thrown here + } catch (ExecutionException ex) { + Throwable cause = ex.getCause(); + System.out.println("Exception caught: " + cause.getMessage()); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + + CompletableFuture supplyAsyncFuture = CompletableFuture.supplyAsync(() -> { + // Task that may throw an exception + throw new RuntimeException("Exception occurred in asynchronous task"); + }) + .exceptionally(ex -> { + // Exception handling logic + return "Default value"; + }); + + Object result = supplyAsyncFuture.join(); + // Get the result or default value + System.out.println("Result: " + result); + } + + public static void chainingOperationCompare() { + CompletableFuture runAsyncFuture = CompletableFuture.runAsync(() -> { + // Perform non-result producing task + System.out.println("Task executed asynchronously"); + }); + runAsyncFuture.thenRun(() -> { + // Execute another task after the completion of runAsync() + System.out.println("Another task executed after runAsync() completes"); + }); + + CompletableFuture supplyAsyncFuture = CompletableFuture.supplyAsync(() -> { + // Perform result-producing task + return "Result of the asynchronous computation"; + }); + supplyAsyncFuture.thenApply(result -> { + // Transform the result + return result.toUpperCase(); + }) + .thenAccept(transformedResult -> { + // Consume the transformed result + System.out.println("Transformed Result: " + transformedResult); + }); + } +} From 536ffe9106ad7baf9f20b4bf572fc7d9e75dc5e0 Mon Sep 17 00:00:00 2001 From: vaibhav007jain <72961247+vaibhav007jain@users.noreply.github.com> Date: Tue, 20 Feb 2024 11:34:26 +0530 Subject: [PATCH 24/38] Bael-7439-intro-to-etcd (#15892) * Update pom.xml * Create JetcdExample.java --- libraries-data-io/pom.xml | 9 +++++- .../java/com/baeldung/etcd/JetcdExample.java | 32 +++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 libraries-data-io/src/main/java/com/baeldung/etcd/JetcdExample.java diff --git a/libraries-data-io/pom.xml b/libraries-data-io/pom.xml index 9fc2814312..0101f724f0 100644 --- a/libraries-data-io/pom.xml +++ b/libraries-data-io/pom.xml @@ -95,6 +95,12 @@ protobuf-java ${google-protobuf.version} + + + io.etcd + jetcd-core + ${jetcd-version} + @@ -110,6 +116,7 @@ 1.15 0.14.2 3.17.3 + 0.7.7 - \ No newline at end of file + diff --git a/libraries-data-io/src/main/java/com/baeldung/etcd/JetcdExample.java b/libraries-data-io/src/main/java/com/baeldung/etcd/JetcdExample.java new file mode 100644 index 0000000000..4174143d8a --- /dev/null +++ b/libraries-data-io/src/main/java/com/baeldung/etcd/JetcdExample.java @@ -0,0 +1,32 @@ +package com.baeldung.etcd; + +import java.util.concurrent.CompletableFuture; + +import io.etcd.jetcd.kv.GetResponse; +import io.etcd.jetcd.ByteSequence; +import io.etcd.jetcd.KV; +import io.etcd.jetcd.Client; + +public class JetcdExample { + public static void main(String[] args) { + String etcdEndpoint = "http://localhost:2379"; + ByteSequence key = ByteSequence.from("/mykey".getBytes()); + ByteSequence value = ByteSequence.from("Hello, etcd!".getBytes()); + + try (Client client = Client.builder().endpoints(etcdEndpoint).build()) { + KV kvClient = client.getKVClient(); + + // Put a key-value pair + kvClient.put(key, value).get(); + + // Retrieve the value using CompletableFuture + CompletableFuture getFuture = kvClient.get(key); + GetResponse response = getFuture.get(); + + // Delete the key + kvClient.delete(key).get(); + } catch (Exception e) { + e.printStackTrace(); + } + } +} From b4107947fc382253c1efbf55d5b95070d201170d Mon Sep 17 00:00:00 2001 From: Ana Peterlic Date: Tue, 20 Feb 2024 08:31:33 +0100 Subject: [PATCH 25/38] Update index.html --- .../src/main/resources/templates/index.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/spring-boot-modules/spring-boot-artifacts/src/main/resources/templates/index.html b/spring-boot-modules/spring-boot-artifacts/src/main/resources/templates/index.html index c1314558f6..f41373d093 100644 --- a/spring-boot-modules/spring-boot-artifacts/src/main/resources/templates/index.html +++ b/spring-boot-modules/spring-boot-artifacts/src/main/resources/templates/index.html @@ -1,7 +1,7 @@ WebJars Demo - +

Welcome Home

@@ -12,8 +12,8 @@ - - + + From a4b26ac450a62fd21cd63b63b02f5146d4cad246 Mon Sep 17 00:00:00 2001 From: Amit Pandey Date: Tue, 20 Feb 2024 17:01:36 +0530 Subject: [PATCH 26/38] JAVA-31205 Fix parent pom names for spring-cloud-eureka (#15911) --- .../spring-cloud-eureka-client-profiles/pom.xml | 2 +- .../spring-cloud-eureka/spring-cloud-eureka-client/pom.xml | 2 +- .../spring-cloud-eureka-feign-client-integration-test/pom.xml | 2 +- .../spring-cloud-eureka-feign-client/pom.xml | 2 +- .../spring-cloud-eureka/spring-cloud-eureka-server/pom.xml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/spring-cloud-modules/spring-cloud-eureka/spring-cloud-eureka-client-profiles/pom.xml b/spring-cloud-modules/spring-cloud-eureka/spring-cloud-eureka-client-profiles/pom.xml index 23e06a55f9..283cfcf7bb 100644 --- a/spring-cloud-modules/spring-cloud-eureka/spring-cloud-eureka-client-profiles/pom.xml +++ b/spring-cloud-modules/spring-cloud-eureka/spring-cloud-eureka-client-profiles/pom.xml @@ -10,7 +10,7 @@ Spring Cloud Eureka Sample Client - com.baeldung.spring.cloud + com.baeldung spring-cloud-eureka 1.0.0-SNAPSHOT diff --git a/spring-cloud-modules/spring-cloud-eureka/spring-cloud-eureka-client/pom.xml b/spring-cloud-modules/spring-cloud-eureka/spring-cloud-eureka-client/pom.xml index a16059a19b..2b7a8d0a69 100644 --- a/spring-cloud-modules/spring-cloud-eureka/spring-cloud-eureka-client/pom.xml +++ b/spring-cloud-modules/spring-cloud-eureka/spring-cloud-eureka-client/pom.xml @@ -10,7 +10,7 @@ Spring Cloud Eureka Sample Client - com.baeldung.spring.cloud + com.baeldung spring-cloud-eureka 1.0.0-SNAPSHOT diff --git a/spring-cloud-modules/spring-cloud-eureka/spring-cloud-eureka-feign-client-integration-test/pom.xml b/spring-cloud-modules/spring-cloud-eureka/spring-cloud-eureka-feign-client-integration-test/pom.xml index 1ed514d146..f8b8a32719 100644 --- a/spring-cloud-modules/spring-cloud-eureka/spring-cloud-eureka-feign-client-integration-test/pom.xml +++ b/spring-cloud-modules/spring-cloud-eureka/spring-cloud-eureka-feign-client-integration-test/pom.xml @@ -10,7 +10,7 @@ Spring Cloud Eureka - Feign Client Integration Tests - com.baeldung.spring.cloud + com.baeldung spring-cloud-eureka 1.0.0-SNAPSHOT diff --git a/spring-cloud-modules/spring-cloud-eureka/spring-cloud-eureka-feign-client/pom.xml b/spring-cloud-modules/spring-cloud-eureka/spring-cloud-eureka-feign-client/pom.xml index ca29a890dd..6c3b25f878 100644 --- a/spring-cloud-modules/spring-cloud-eureka/spring-cloud-eureka-feign-client/pom.xml +++ b/spring-cloud-modules/spring-cloud-eureka/spring-cloud-eureka-feign-client/pom.xml @@ -10,7 +10,7 @@ Spring Cloud Eureka - Sample Feign Client - com.baeldung.spring.cloud + com.baeldung spring-cloud-eureka 1.0.0-SNAPSHOT diff --git a/spring-cloud-modules/spring-cloud-eureka/spring-cloud-eureka-server/pom.xml b/spring-cloud-modules/spring-cloud-eureka/spring-cloud-eureka-server/pom.xml index 7ba300289e..f3e5a78be3 100644 --- a/spring-cloud-modules/spring-cloud-eureka/spring-cloud-eureka-server/pom.xml +++ b/spring-cloud-modules/spring-cloud-eureka/spring-cloud-eureka-server/pom.xml @@ -10,7 +10,7 @@ Spring Cloud Eureka Server Demo - com.baeldung.spring.cloud + com.baeldung spring-cloud-eureka 1.0.0-SNAPSHOT From c77c0deea5d8e5a9f22dee5a55a3c1b9c7fc61be Mon Sep 17 00:00:00 2001 From: panos-kakos <102670093+panos-kakos@users.noreply.github.com> Date: Tue, 20 Feb 2024 13:34:36 +0200 Subject: [PATCH 27/38] [JAVA-31203] Upgraded spring-cloud-config to spring boot 3 (#15861) --- spring-cloud-modules/spring-cloud-config/pom.xml | 9 +++++---- .../config/server/SecurityConfiguration.java | 15 ++++++++------- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/spring-cloud-modules/spring-cloud-config/pom.xml b/spring-cloud-modules/spring-cloud-config/pom.xml index c256e82d1b..1c5b16916e 100644 --- a/spring-cloud-modules/spring-cloud-config/pom.xml +++ b/spring-cloud-modules/spring-cloud-config/pom.xml @@ -10,9 +10,10 @@ pom - com.baeldung.spring.cloud - spring-cloud-modules - 1.0.0-SNAPSHOT + com.baeldung + parent-boot-3 + 0.0.1-SNAPSHOT + ../../parent-boot-3 @@ -35,7 +36,7 @@ - 2021.0.3 + 2022.0.3 \ No newline at end of file diff --git a/spring-cloud-modules/spring-cloud-config/spring-cloud-config-server/src/main/java/com/baeldung/spring/cloud/config/server/SecurityConfiguration.java b/spring-cloud-modules/spring-cloud-config/spring-cloud-config-server/src/main/java/com/baeldung/spring/cloud/config/server/SecurityConfiguration.java index 428a8f23c6..ebe9205a45 100644 --- a/spring-cloud-modules/spring-cloud-config/spring-cloud-config-server/src/main/java/com/baeldung/spring/cloud/config/server/SecurityConfiguration.java +++ b/spring-cloud-modules/spring-cloud-config/spring-cloud-config-server/src/main/java/com/baeldung/spring/cloud/config/server/SecurityConfiguration.java @@ -2,6 +2,7 @@ package com.baeldung.spring.cloud.config.server; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.Customizer; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.web.SecurityFilterChain; @@ -10,13 +11,13 @@ public class SecurityConfiguration { @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { - http.csrf() - .ignoringAntMatchers("/encrypt/**") - .ignoringAntMatchers("/decrypt/**"); - http.authorizeRequests((requests) -> requests.anyRequest() - .authenticated()); - http.formLogin(); - http.httpBasic(); + http.csrf(csrf -> csrf.ignoringRequestMatchers( + "/encrypt/**", "/decrypt/**" + )) + .authorizeRequests(authz -> authz.anyRequest().authenticated()) + .formLogin(Customizer.withDefaults()) + .httpBasic(Customizer.withDefaults()); + return http.build(); } } From acb28bdec3102f39cb94133d2740cef81df19580 Mon Sep 17 00:00:00 2001 From: anuragkumawat Date: Tue, 20 Feb 2024 19:58:46 +0530 Subject: [PATCH 28/38] JAVA-31341 Fix spring-jooq and spring-mybatis module (#15897) --- persistence-modules/spring-jooq/pom.xml | 2 +- persistence-modules/spring-mybatis/pom.xml | 9 --------- spring-boot-modules/spring-boot-properties/pom.xml | 10 ++++++++-- spring-boot-modules/spring-boot-ssl-bundles/pom.xml | 1 - .../SecureRestTemplateConfig.java | 2 +- .../springbootsslbundles/SecureServiceRestApi.java | 3 ++- spring-jinq/pom.xml | 2 -- .../spring-reactive-exceptions/pom.xml | 11 +++++++---- spring-web-modules/spring-rest-http/pom.xml | 7 +++++++ 9 files changed, 26 insertions(+), 21 deletions(-) diff --git a/persistence-modules/spring-jooq/pom.xml b/persistence-modules/spring-jooq/pom.xml index 1387635afe..230397da9d 100644 --- a/persistence-modules/spring-jooq/pom.xml +++ b/persistence-modules/spring-jooq/pom.xml @@ -194,7 +194,7 @@ 1.0.0 1.5 1.0.0 - 3.1.5 + 2.2.224 \ No newline at end of file diff --git a/persistence-modules/spring-mybatis/pom.xml b/persistence-modules/spring-mybatis/pom.xml index d179881710..f164f4b6f9 100644 --- a/persistence-modules/spring-mybatis/pom.xml +++ b/persistence-modules/spring-mybatis/pom.xml @@ -19,12 +19,10 @@ org.springframework spring-context - ${org.springframework.version} org.springframework spring-beans - ${org.springframework.version} @@ -36,12 +34,10 @@ com.h2database h2 - ${h2.version} org.springframework spring-jdbc - ${org.springframework.version} org.mybatis @@ -61,7 +57,6 @@ org.springframework spring-test - ${org.springframework.version} test @@ -77,14 +72,10 @@ - - 6.0.13 - 3.0.3 3.5.2 3.0.3 true - 3.1.5 \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-properties/pom.xml b/spring-boot-modules/spring-boot-properties/pom.xml index 7614941f2d..fa3fc954b3 100644 --- a/spring-boot-modules/spring-boot-properties/pom.xml +++ b/spring-boot-modules/spring-boot-properties/pom.xml @@ -104,6 +104,13 @@ false + + org.apache.maven.plugins + maven-compiler-plugin + + true + + @@ -142,12 +149,11 @@ - 2022.0.4 + 2023.0.0 1.10 @ com.baeldung.yaml.MyApplication - 3.1.5 \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-ssl-bundles/pom.xml b/spring-boot-modules/spring-boot-ssl-bundles/pom.xml index 8edbd9c79e..1f4e58f21f 100644 --- a/spring-boot-modules/spring-boot-ssl-bundles/pom.xml +++ b/spring-boot-modules/spring-boot-ssl-bundles/pom.xml @@ -53,7 +53,6 @@ 5.0.3 - 3.1.5 \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-ssl-bundles/src/main/java/com/baeldung/springbootsslbundles/SecureRestTemplateConfig.java b/spring-boot-modules/spring-boot-ssl-bundles/src/main/java/com/baeldung/springbootsslbundles/SecureRestTemplateConfig.java index 48eda219dd..cae3b24d8c 100644 --- a/spring-boot-modules/spring-boot-ssl-bundles/src/main/java/com/baeldung/springbootsslbundles/SecureRestTemplateConfig.java +++ b/spring-boot-modules/spring-boot-ssl-bundles/src/main/java/com/baeldung/springbootsslbundles/SecureRestTemplateConfig.java @@ -27,7 +27,7 @@ public class SecureRestTemplateConfig { this.sslContext = sslBundle.createSslContext(); } - @Bean + @Bean(name="secureRestTemplate") public RestTemplate secureRestTemplate() { final SSLConnectionSocketFactory sslSocketFactory = SSLConnectionSocketFactoryBuilder.create().setSslContext(this.sslContext).build(); final HttpClientConnectionManager cm = PoolingHttpClientConnectionManagerBuilder.create().setSSLSocketFactory(sslSocketFactory).build(); diff --git a/spring-boot-modules/spring-boot-ssl-bundles/src/main/java/com/baeldung/springbootsslbundles/SecureServiceRestApi.java b/spring-boot-modules/spring-boot-ssl-bundles/src/main/java/com/baeldung/springbootsslbundles/SecureServiceRestApi.java index 3ed919b957..d7b87c4c5a 100644 --- a/spring-boot-modules/spring-boot-ssl-bundles/src/main/java/com/baeldung/springbootsslbundles/SecureServiceRestApi.java +++ b/spring-boot-modules/spring-boot-ssl-bundles/src/main/java/com/baeldung/springbootsslbundles/SecureServiceRestApi.java @@ -1,6 +1,7 @@ package com.baeldung.springbootsslbundles; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.http.HttpMethod; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; @@ -11,7 +12,7 @@ public class SecureServiceRestApi { private final RestTemplate restTemplate; @Autowired - public SecureServiceRestApi(RestTemplate restTemplate) { + public SecureServiceRestApi(@Qualifier("secureRestTemplate") RestTemplate restTemplate) { this.restTemplate = restTemplate; } diff --git a/spring-jinq/pom.xml b/spring-jinq/pom.xml index 4ba2028bc6..4695950153 100644 --- a/spring-jinq/pom.xml +++ b/spring-jinq/pom.xml @@ -38,7 +38,6 @@ org.hibernate.orm hibernate-core - ${hibernate-core.version} @@ -65,7 +64,6 @@ 2.0.1 6.4.2.Final - 3.1.5 \ No newline at end of file diff --git a/spring-reactive-modules/spring-reactive-exceptions/pom.xml b/spring-reactive-modules/spring-reactive-exceptions/pom.xml index e9208c8b20..1f24f9cd1c 100644 --- a/spring-reactive-modules/spring-reactive-exceptions/pom.xml +++ b/spring-reactive-modules/spring-reactive-exceptions/pom.xml @@ -51,11 +51,14 @@ JAR + + org.apache.maven.plugins + maven-compiler-plugin + + true + + - - 3.1.5 - - diff --git a/spring-web-modules/spring-rest-http/pom.xml b/spring-web-modules/spring-rest-http/pom.xml index 8d3ea82c44..f93e4274e9 100644 --- a/spring-web-modules/spring-rest-http/pom.xml +++ b/spring-web-modules/spring-rest-http/pom.xml @@ -71,6 +71,13 @@ true + + org.apache.maven.plugins + maven-compiler-plugin + + true + + From 6328bf349e9a3e47a615bc466028d56516df466f Mon Sep 17 00:00:00 2001 From: Constantin <50400363+constantinurs@users.noreply.github.com> Date: Wed, 21 Feb 2024 00:14:38 +0200 Subject: [PATCH 29/38] [BAEL-7199] Override bootstrap servers property (#15708) --- spring-kafka-2/src/main/resources/application.properties | 2 +- .../com/baeldung/spring/kafka/dlt/KafkaDltIntegrationTest.java | 3 ++- .../multipletopics/KafkaMultipleTopicsIntegrationTest.java | 3 ++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/spring-kafka-2/src/main/resources/application.properties b/spring-kafka-2/src/main/resources/application.properties index 8a74074cf5..9111491b58 100644 --- a/spring-kafka-2/src/main/resources/application.properties +++ b/spring-kafka-2/src/main/resources/application.properties @@ -1,4 +1,4 @@ -spring.kafka.bootstrap-servers=localhost:9092,localhost:9093,localhost:9094,localhost:9095 +spring.kafka.bootstrap-servers=localhost:9092,localhost:9093,localhost:9094 message.topic.name=baeldung long.message.topic.name=longMessage greeting.topic.name=greeting diff --git a/spring-kafka-2/src/test/java/com/baeldung/spring/kafka/dlt/KafkaDltIntegrationTest.java b/spring-kafka-2/src/test/java/com/baeldung/spring/kafka/dlt/KafkaDltIntegrationTest.java index 6059de9c45..72b77c360f 100644 --- a/spring-kafka-2/src/test/java/com/baeldung/spring/kafka/dlt/KafkaDltIntegrationTest.java +++ b/spring-kafka-2/src/test/java/com/baeldung/spring/kafka/dlt/KafkaDltIntegrationTest.java @@ -26,7 +26,8 @@ import com.baeldung.spring.kafka.dlt.listener.PaymentListenerDltRetryOnError; import com.baeldung.spring.kafka.dlt.listener.PaymentListenerNoDlt; import org.springframework.test.context.ActiveProfiles; -@SpringBootTest(classes = KafkaDltApplication.class) +@SpringBootTest(classes = KafkaDltApplication.class, + properties = "spring.kafka.bootstrap-servers=localhost:9095") @EmbeddedKafka( partitions = 1, brokerProperties = { "listeners=PLAINTEXT://localhost:9095", "port=9095" }, diff --git a/spring-kafka-2/src/test/java/com/baeldung/spring/kafka/multipletopics/KafkaMultipleTopicsIntegrationTest.java b/spring-kafka-2/src/test/java/com/baeldung/spring/kafka/multipletopics/KafkaMultipleTopicsIntegrationTest.java index e8aecf9549..088e1eba53 100644 --- a/spring-kafka-2/src/test/java/com/baeldung/spring/kafka/multipletopics/KafkaMultipleTopicsIntegrationTest.java +++ b/spring-kafka-2/src/test/java/com/baeldung/spring/kafka/multipletopics/KafkaMultipleTopicsIntegrationTest.java @@ -21,7 +21,8 @@ import org.springframework.kafka.test.context.EmbeddedKafka; import org.springframework.kafka.test.utils.ContainerTestUtils; import org.springframework.test.context.ActiveProfiles; -@SpringBootTest(classes = KafkaMultipleTopicsApplication.class) +@SpringBootTest(classes = KafkaMultipleTopicsApplication.class, + properties = "spring.kafka.bootstrap-servers=localhost:9099") @EmbeddedKafka(partitions = 1, brokerProperties = { "listeners=PLAINTEXT://localhost:9099", "port=9099" }) @ActiveProfiles("multipletopics") public class KafkaMultipleTopicsIntegrationTest { From 1b843fd34a24fef67979bcd1e84667f50a7af236 Mon Sep 17 00:00:00 2001 From: Manfred <77407079+manfred106@users.noreply.github.com> Date: Wed, 21 Feb 2024 03:31:55 +0000 Subject: [PATCH 30/38] BAEL-7296: Calling Custom Database Functions with JPA (#15869) --- .../spring-boot-persistence-4/pom.xml | 6 ++ .../customfunc/CustomFunctionApplication.java | 13 +++++ .../baeldung/customfunc/CustomH2Dialect.java | 25 ++++++++ .../customfunc/CustomHibernateConfig.java | 16 +++++ .../java/com/baeldung/customfunc/Product.java | 31 ++++++++++ .../customfunc/ProductRepository.java | 24 ++++++++ .../ProductRepositoryIntegrationTest.java | 58 +++++++++++++++++++ .../src/test/resources/product-data.sql | 17 ++++++ 8 files changed, 190 insertions(+) create mode 100644 persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/customfunc/CustomFunctionApplication.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/customfunc/CustomH2Dialect.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/customfunc/CustomHibernateConfig.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/customfunc/Product.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/customfunc/ProductRepository.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/customfunc/ProductRepositoryIntegrationTest.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/test/resources/product-data.sql diff --git a/persistence-modules/spring-boot-persistence-4/pom.xml b/persistence-modules/spring-boot-persistence-4/pom.xml index 13cb4d5b82..acff937114 100644 --- a/persistence-modules/spring-boot-persistence-4/pom.xml +++ b/persistence-modules/spring-boot-persistence-4/pom.xml @@ -62,6 +62,11 @@ modelmapper ${modelmapper.version} + + commons-codec + commons-codec + ${commons-codec.version} + org.projectlombok lombok @@ -88,6 +93,7 @@ 3.7.0 2.16.0 3.2.0 + 1.16.1 1.18.30 diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/customfunc/CustomFunctionApplication.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/customfunc/CustomFunctionApplication.java new file mode 100644 index 0000000000..6e731501cb --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/customfunc/CustomFunctionApplication.java @@ -0,0 +1,13 @@ +package com.baeldung.customfunc; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class CustomFunctionApplication { + + public static void main(String[] args) { + SpringApplication.run(CustomFunctionApplication.class, args); + } + +} \ No newline at end of file diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/customfunc/CustomH2Dialect.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/customfunc/CustomH2Dialect.java new file mode 100644 index 0000000000..56b26a8fcf --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/customfunc/CustomH2Dialect.java @@ -0,0 +1,25 @@ +package com.baeldung.customfunc; + +import org.hibernate.boot.model.FunctionContributions; +import org.hibernate.dialect.H2Dialect; + +import org.hibernate.query.sqm.function.FunctionKind; +import org.hibernate.query.sqm.function.SqmFunctionRegistry; +import org.hibernate.query.sqm.produce.function.PatternFunctionDescriptorBuilder; +import org.hibernate.type.spi.TypeConfiguration; + +public class CustomH2Dialect extends H2Dialect { + + @Override + public void initializeFunctionRegistry(FunctionContributions functionContributions) { + super.initializeFunctionRegistry(functionContributions); + SqmFunctionRegistry registry = functionContributions.getFunctionRegistry(); + TypeConfiguration types = functionContributions.getTypeConfiguration(); + + new PatternFunctionDescriptorBuilder(registry, "sha256hex", FunctionKind.NORMAL, "SHA256_HEX(?1)") + .setExactArgumentCount(1) + .setInvariantType(types.getBasicTypeForJavaType(String.class)) + .register(); + } + +} \ No newline at end of file diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/customfunc/CustomHibernateConfig.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/customfunc/CustomHibernateConfig.java new file mode 100644 index 0000000000..424970f59a --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/customfunc/CustomHibernateConfig.java @@ -0,0 +1,16 @@ +package com.baeldung.customfunc; + +import org.springframework.context.annotation.Configuration; +import org.springframework.boot.autoconfigure.orm.jpa.HibernatePropertiesCustomizer; + +import java.util.Map; + +@Configuration +public class CustomHibernateConfig implements HibernatePropertiesCustomizer { + + @Override + public void customize(Map hibernateProperties) { + hibernateProperties.put("hibernate.dialect", "com.baeldung.customfunc.CustomH2Dialect"); + } + +} \ No newline at end of file diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/customfunc/Product.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/customfunc/Product.java new file mode 100644 index 0000000000..bfbea7a0c5 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/customfunc/Product.java @@ -0,0 +1,31 @@ +package com.baeldung.customfunc; + +import jakarta.persistence.*; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; + +@Entity +@Table(name = "product") +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(of = {"id"}) +@NamedStoredProcedureQuery( + name = "Product.sha256Hex", + procedureName = "SHA256_HEX", + parameters = @StoredProcedureParameter(mode = ParameterMode.IN, name = "value", type = String.class) +) +public class Product { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "product_id") + private Integer id; + + private String name; + +} \ No newline at end of file diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/customfunc/ProductRepository.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/customfunc/ProductRepository.java new file mode 100644 index 0000000000..ea9ceba0ff --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/customfunc/ProductRepository.java @@ -0,0 +1,24 @@ +package com.baeldung.customfunc; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.jpa.repository.query.Procedure; +import org.springframework.data.repository.query.Param; + +import java.util.List; + +public interface ProductRepository extends JpaRepository { + + @Procedure(name = "Product.sha256Hex") + String getSha256HexByNamedMapping(@Param("value") String value); + + @Query(value = "CALL SHA256_HEX(:value)", nativeQuery = true) + String getSha256HexByNativeCall(@Param("value") String value); + + @Query(value = "SELECT SHA256_HEX(name) FROM product", nativeQuery = true) + List getProductNameListInSha256HexByNativeSelect(); + + @Query(value = "SELECT sha256Hex(p.name) FROM Product p") + List getProductNameListInSha256Hex(); + +} \ No newline at end of file diff --git a/persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/customfunc/ProductRepositoryIntegrationTest.java b/persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/customfunc/ProductRepositoryIntegrationTest.java new file mode 100644 index 0000000000..a5b2ebe461 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/test/java/com/baeldung/customfunc/ProductRepositoryIntegrationTest.java @@ -0,0 +1,58 @@ +package com.baeldung.customfunc; + +import org.apache.commons.codec.binary.Hex; +import org.apache.commons.codec.digest.DigestUtils; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.transaction.annotation.Transactional; + +import java.nio.charset.StandardCharsets; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; + +@SpringBootTest(classes = CustomFunctionApplication.class, properties = { + "spring.jpa.show-sql=true", + "spring.jpa.properties.hibernate.format_sql=true", + "spring.jpa.generate-ddl=true", + "spring.jpa.defer-datasource-initialization=true", + "spring.sql.init.data-locations=classpath:product-data.sql" +}) +@Transactional +public class ProductRepositoryIntegrationTest { + + private static final String TEXT = "Hand Grip Strengthener"; + private static final String EXPECTED_HASH_HEX = getSha256Hex(TEXT); + + @Autowired + private ProductRepository productRepository; + + private static String getSha256Hex(String value) { + return Hex.encodeHexString(DigestUtils.sha256(value.getBytes(StandardCharsets.UTF_8))); + } + + @Test + void whenGetSha256HexByNamedMapping_thenReturnCorrectHash() { + var hash = productRepository.getSha256HexByNamedMapping(TEXT); + assertThat(hash).isEqualTo(EXPECTED_HASH_HEX); + } + + @Test + void whenGetSha256HexByNativeCall_thenReturnCorrectHash() { + var hash = productRepository.getSha256HexByNativeCall(TEXT); + assertThat(hash).isEqualTo(EXPECTED_HASH_HEX); + } + + @Test + void whenCallGetSha256HexNative_thenReturnCorrectHash() { + var hashList = productRepository.getProductNameListInSha256HexByNativeSelect(); + assertThat(hashList.get(0)).isEqualTo(EXPECTED_HASH_HEX); + } + + @Test + void whenCallGetSha256Hex_thenReturnCorrectHash() { + var hashList = productRepository.getProductNameListInSha256Hex(); + assertThat(hashList.get(0)).isEqualTo(EXPECTED_HASH_HEX); + } + +} \ No newline at end of file diff --git a/persistence-modules/spring-boot-persistence-4/src/test/resources/product-data.sql b/persistence-modules/spring-boot-persistence-4/src/test/resources/product-data.sql new file mode 100644 index 0000000000..7a59da68b7 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/test/resources/product-data.sql @@ -0,0 +1,17 @@ +CREATE ALIAS SHA256_HEX AS ' + import java.sql.*; + @CODE + String getSha256Hex(Connection conn, String value) throws SQLException { + var sql = "SELECT RAWTOHEX(HASH(''SHA-256'', ?))"; + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setString(1, value); + ResultSet rs = stmt.executeQuery(); + if (rs.next()) { + return rs.getString(1); + } + } + return null; + } +'; + +INSERT INTO product(name) VALUES('Hand Grip Strengthener'); \ No newline at end of file From fcb6efbf0089b19f3a11d0559e6065e1cecbd2f1 Mon Sep 17 00:00:00 2001 From: Wynn Teo <49014791+wynnteo@users.noreply.github.com> Date: Wed, 21 Feb 2024 11:36:34 +0800 Subject: [PATCH 31/38] BAEL-6622 (#15905) * BAEL-7490 read write file in separate thread * Change the to try resources * Update the code to sync with article * BAEL-6622 compare thenApply() and thenApplyAsync() * BAEL-6622 change to unit test * Tidy up the code --- .../ThenApplyAndThenApplyAsyncUnitTest.java | 91 +++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 core-java-modules/core-java-concurrency-2/src/test/java/com/baeldung/concurrent/applyvsapplyasync/ThenApplyAndThenApplyAsyncUnitTest.java diff --git a/core-java-modules/core-java-concurrency-2/src/test/java/com/baeldung/concurrent/applyvsapplyasync/ThenApplyAndThenApplyAsyncUnitTest.java b/core-java-modules/core-java-concurrency-2/src/test/java/com/baeldung/concurrent/applyvsapplyasync/ThenApplyAndThenApplyAsyncUnitTest.java new file mode 100644 index 0000000000..ee7f6d7a82 --- /dev/null +++ b/core-java-modules/core-java-concurrency-2/src/test/java/com/baeldung/concurrent/applyvsapplyasync/ThenApplyAndThenApplyAsyncUnitTest.java @@ -0,0 +1,91 @@ +package com.baeldung.concurrent.applyvsapplyasync; + +import org.junit.jupiter.api.Test; + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +public class ThenApplyAndThenApplyAsyncUnitTest { + + @Test + public void givenCompletableFuture_whenUsingThenApply_thenResultIsAsExpected() { + CompletableFuture future = CompletableFuture.supplyAsync(() -> 5); + CompletableFuture thenApplyResultFuture = future.thenApply(num -> "Result: " + num); + + String thenApplyResult = thenApplyResultFuture.join(); + assertEquals("Result: 5", thenApplyResult); + } + + @Test + public void givenCompletableFuture_whenUsingThenApplyAsync_thenResultIsAsExpected() { + CompletableFuture future = CompletableFuture.supplyAsync(() -> 5); + CompletableFuture thenApplyAsyncResultFuture = future.thenApplyAsync(num -> "Result: " + num); + + String thenApplyAsyncResult = thenApplyAsyncResultFuture.join(); + assertEquals("Result: 5", thenApplyAsyncResult); + } + + @Test + public void givenCompletableFuture_whenUsingThenApply_thenExceptionIsPropagated() { + CompletableFuture future = CompletableFuture.supplyAsync(() -> 5); + CompletableFuture resultFuture = future.thenApply(num -> "Result: " + num / 0); + assertThrows(CompletionException.class, () -> resultFuture.join()); + } + + @Test + public void givenCompletableFuture_whenUsingThenApply_thenExceptionIsHandledAsExpected() { + CompletableFuture future = CompletableFuture.supplyAsync(() -> 5); + CompletableFuture resultFuture = future.thenApply(num -> "Result: " + num / 0); + try { + // Accessing the result + String result = resultFuture.join(); + assertEquals("Result: 5", result); + } catch (CompletionException e) { + assertEquals("java.lang.ArithmeticException: / by zero", e.getMessage()); + System.err.println("Exception caught: " + e.getMessage()); + } + } + + @Test + public void givenCompletableFuture_whenUsingThenApplyAsync_thenExceptionIsHandledAsExpected() { + CompletableFuture future = CompletableFuture.supplyAsync(() -> 5); + CompletableFuture thenApplyAsyncResultFuture = future.thenApplyAsync(num -> "Result: " + num / 0); + + String result = thenApplyAsyncResultFuture.handle((res, error) -> { + if (error != null) { + // Handle the error appropriately, e.g., return a default value + return "Error occurred"; + } else { + return res; + } + }) + .join(); // Now join() won't throw the exception + assertEquals("Error occurred", result); + } + + @Test + public void givenCompletableFutureWithExecutor_whenUsingThenApplyAsync_thenThreadExecutesAsExpected() { + ExecutorService customExecutor = Executors.newFixedThreadPool(4); + + CompletableFuture future = CompletableFuture.supplyAsync(() -> { + try { + Thread.sleep(2000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + return 5; + }, customExecutor); + + CompletableFuture resultFuture = future.thenApplyAsync(num -> "Result: " + num, customExecutor); + + String result = resultFuture.join(); + assertEquals("Result: 5", result); + + customExecutor.shutdown(); + } +} From c5a3c01108e2e288470497aff2e3247797058408 Mon Sep 17 00:00:00 2001 From: lucaCambi77 Date: Wed, 21 Feb 2024 04:43:07 +0100 Subject: [PATCH 32/38] Check if two strings are rotations of each other [BAEL-7493] (#15864) * feat: string rotation * fix: test names --- .../stringrotation/StringRotation.java | 123 ++++++++++++++++++ .../StringRotationUnitTest.java | 61 +++++++++ 2 files changed, 184 insertions(+) create mode 100644 algorithms-modules/algorithms-miscellaneous-7/src/main/java/com/baeldung/algorithms/stringrotation/StringRotation.java create mode 100644 algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/stringrotation/StringRotationUnitTest.java diff --git a/algorithms-modules/algorithms-miscellaneous-7/src/main/java/com/baeldung/algorithms/stringrotation/StringRotation.java b/algorithms-modules/algorithms-miscellaneous-7/src/main/java/com/baeldung/algorithms/stringrotation/StringRotation.java new file mode 100644 index 0000000000..862c745c9e --- /dev/null +++ b/algorithms-modules/algorithms-miscellaneous-7/src/main/java/com/baeldung/algorithms/stringrotation/StringRotation.java @@ -0,0 +1,123 @@ +package com.baeldung.algorithms.stringrotation; + +import java.util.LinkedList; +import java.util.List; +import java.util.Queue; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +public class StringRotation { + + public static boolean doubledOriginContainsRotation(String origin, String rotation) { + if (origin.length() == rotation.length()) { + return origin.concat(origin) + .contains(rotation); + } + + return false; + } + + public static boolean isRotationUsingCommonStartWithOrigin(String origin, String rotation) { + + if (origin.length() == rotation.length()) { + + List indexes = IntStream.range(0, origin.length()) + .filter(i -> rotation.charAt(i) == origin.charAt(0)) + .boxed() + .collect(Collectors.toList()); + + for (int startingAt : indexes) { + if (isRotation(startingAt, rotation, origin)) { + return true; + } + } + } + + return false; + } + + static boolean isRotation(int startingAt, String rotation, String origin) { + + for (int i = 0; i < origin.length(); i++) { + if (rotation.charAt((startingAt + i) % origin.length()) != origin.charAt(i)) { + return false; + } + } + + return true; + } + + public static boolean isRotationUsingQueue(String origin, String rotation) { + + if (origin.length() == rotation.length()) { + return checkWithQueue(origin, rotation); + } + + return false; + } + + static boolean checkWithQueue(String origin, String rotation) { + + if (origin.length() == rotation.length()) { + + Queue originQueue = getCharactersQueue(origin); + + Queue rotationQueue = getCharactersQueue(rotation); + + int k = rotation.length(); + while (k > 0 && null != rotationQueue.peek()) { + k--; + char ch = rotationQueue.peek(); + rotationQueue.remove(); + rotationQueue.add(ch); + if (rotationQueue.equals(originQueue)) { + return true; + } + } + } + + return false; + } + + static Queue getCharactersQueue(String origin) { + return origin.chars() + .mapToObj(c -> (char) c) + .collect(Collectors.toCollection(LinkedList::new)); + } + + public static boolean isRotationUsingSuffixAndPrefix(String origin, String rotation) { + + if (origin.length() == rotation.length()) { + return checkPrefixAndSuffix(origin, rotation); + } + + return false; + } + + static boolean checkPrefixAndSuffix(String origin, String rotation) { + if (origin.length() == rotation.length()) { + + for (int i = 0; i < origin.length(); i++) { + if (origin.charAt(i) == rotation.charAt(0)) { + if (checkRotationPrefixWithOriginSuffix(origin, rotation, i)) { + if (checkOriginPrefixWithRotationSuffix(origin, rotation, i)) + return true; + } + } + } + + } + + return false; + } + + private static boolean checkRotationPrefixWithOriginSuffix(String origin, String rotation, int i) { + return origin.substring(i) + .equals(rotation.substring(0, origin.length() - i)); + } + + private static boolean checkOriginPrefixWithRotationSuffix(String origin, String rotation, int i) { + return origin.substring(0, i) + .equals(rotation.substring(origin.length() - i)); + } +} diff --git a/algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/stringrotation/StringRotationUnitTest.java b/algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/stringrotation/StringRotationUnitTest.java new file mode 100644 index 0000000000..5558c6ca9f --- /dev/null +++ b/algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/stringrotation/StringRotationUnitTest.java @@ -0,0 +1,61 @@ +package com.baeldung.algorithms.stringrotation; + +import static com.baeldung.algorithms.stringrotation.StringRotation.doubledOriginContainsRotation; +import static com.baeldung.algorithms.stringrotation.StringRotation.isRotationUsingCommonStartWithOrigin; +import static com.baeldung.algorithms.stringrotation.StringRotation.isRotationUsingQueue; +import static com.baeldung.algorithms.stringrotation.StringRotation.isRotationUsingSuffixAndPrefix; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; + +class StringRotationUnitTest { + + @Test + void givenOriginAndRotationInput_whenCheckIfOriginContainsRotation_thenIsRotation() { + assertTrue(doubledOriginContainsRotation("abcd", "cdab")); + assertTrue(doubledOriginContainsRotation("abcd", "abcd")); + } + + @Test + void givenOriginAndRotationInput_whenCheckIfOriginContainsRotation_thenNoRotation() { + assertFalse(doubledOriginContainsRotation("abcd", "bbbb")); + assertFalse(doubledOriginContainsRotation("abcd", "abcde")); + } + + @Test + void givenOriginAndRotationInput_whenCheckingCommonStartWithOrigin_thenIsRotation() { + assertTrue(isRotationUsingCommonStartWithOrigin("abcd", "cdab")); + assertTrue(isRotationUsingCommonStartWithOrigin("abcd", "abcd")); + } + + @Test + void givenOriginAndRotationInput_whenCheckingCommonStartWithOrigin_thenNoRotation() { + assertFalse(isRotationUsingCommonStartWithOrigin("abcd", "bbbb")); + assertFalse(isRotationUsingCommonStartWithOrigin("abcd", "abcde")); + } + + @Test + void givenOriginAndRotationInput_whenCheckingUsingQueues_thenIsRotation() { + assertTrue(isRotationUsingQueue("abcd", "cdab")); + assertTrue(isRotationUsingQueue("abcd", "abcd")); + } + + @Test + void givenOriginAndRotationInput_whenCheckingUsingQueues_thenNoRotation() { + assertFalse(isRotationUsingQueue("abcd", "bbbb")); + assertFalse(isRotationUsingQueue("abcd", "abcde")); + } + + @Test + void givenOriginAndRotationInput_whenCheckingUsingSuffixAndPrefix_thenIsRotation() { + assertTrue(isRotationUsingSuffixAndPrefix("abcd", "cdab")); + assertTrue(isRotationUsingSuffixAndPrefix("abcd", "abcd")); + } + + @Test + void givenOriginAndRotationInput_whenCheckingUsingSuffixAndPrefix_thenNoRotation() { + assertFalse(isRotationUsingSuffixAndPrefix("abcd", "bbbb")); + assertFalse(isRotationUsingSuffixAndPrefix("abcd", "abcde")); + } +} From c8c29a78067cb219ba72a3c7042088fceb14094b Mon Sep 17 00:00:00 2001 From: MohamedHelmyKassab <137485958+MohamedHelmyKassab@users.noreply.github.com> Date: Wed, 21 Feb 2024 10:11:24 +0200 Subject: [PATCH 33/38] This PR is related to BAEL-7556 (#15900) * This commit is related to BAEL-7556 This commit aims to add a test class "FindUniqueEmailsUnitTest.java". * Update FindUniqueEmailsUnitTest.java --- .../FindUniqueEmailsUnitTest.java | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 core-java-modules/core-java-string-operations-8/src/test/java/com/baeldung/finduniqueemails/FindUniqueEmailsUnitTest.java diff --git a/core-java-modules/core-java-string-operations-8/src/test/java/com/baeldung/finduniqueemails/FindUniqueEmailsUnitTest.java b/core-java-modules/core-java-string-operations-8/src/test/java/com/baeldung/finduniqueemails/FindUniqueEmailsUnitTest.java new file mode 100644 index 0000000000..d358091db9 --- /dev/null +++ b/core-java-modules/core-java-string-operations-8/src/test/java/com/baeldung/finduniqueemails/FindUniqueEmailsUnitTest.java @@ -0,0 +1,40 @@ +package com.baeldung.finduniqueemails; + +import org.junit.jupiter.api.Test; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; +import java.util.stream.Collectors; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class FindUniqueEmailsUnitTest { + String[] emailList = {"user@example.com", "user@example.com", "user@gmail.com", "admin@example.com", "USER@example.com"}; + Set expectedUniqueEmails = new HashSet<>(); + + FindUniqueEmailsUnitTest() { + expectedUniqueEmails.add("user@example.com"); + expectedUniqueEmails.add("user@gmail.com"); + expectedUniqueEmails.add("admin@example.com"); + } + + @Test + public void givenEmailList_whenUsingStringManipulation_thenFindUniqueEmails() { + Set uniqueEmails = new HashSet<>(); + for (String email : emailList) { + uniqueEmails.add(email.toLowerCase()); + } + + assertEquals(expectedUniqueEmails, uniqueEmails); + } + + @Test + public void givenEmailList_whenUsingJavaStreams_thenFindUniqueEmails() { + Set uniqueEmails = Arrays.stream(emailList) + .map(String::toLowerCase) + .collect(Collectors.toSet()); + + assertEquals(expectedUniqueEmails, uniqueEmails); + } +} From d8e2c61003dd9b3102841090762396a43b589c63 Mon Sep 17 00:00:00 2001 From: Alexandru Borza Date: Wed, 21 Feb 2024 12:26:19 +0200 Subject: [PATCH 34/38] BAEL-7255 - Implementing GraphQL Mutation without Returning Data (#15820) --- .../returnnull/GraphQLVoidScalar.java | 30 +++++++++++ .../baeldung/returnnull/GraphQlConfig.java | 14 +++++ .../java/com/baeldung/returnnull/Post.java | 51 +++++++++++++++++++ .../baeldung/returnnull/PostController.java | 28 ++++++++++ .../baeldung/returnnull/ReturnNullApp.java | 14 +++++ .../main/resources/application-returnnull.yml | 9 ++++ .../resources/returnnull/returnnull.graphqls | 18 +++++++ .../PostControllerIntegrationTest.java | 48 +++++++++++++++++ .../create_post_return_custom_scalar.graphql | 3 ++ .../create_post_return_nullable_type.graphql | 3 ++ 10 files changed, 218 insertions(+) create mode 100644 spring-boot-modules/spring-boot-graphql/src/main/java/com/baeldung/returnnull/GraphQLVoidScalar.java create mode 100644 spring-boot-modules/spring-boot-graphql/src/main/java/com/baeldung/returnnull/GraphQlConfig.java create mode 100644 spring-boot-modules/spring-boot-graphql/src/main/java/com/baeldung/returnnull/Post.java create mode 100644 spring-boot-modules/spring-boot-graphql/src/main/java/com/baeldung/returnnull/PostController.java create mode 100644 spring-boot-modules/spring-boot-graphql/src/main/java/com/baeldung/returnnull/ReturnNullApp.java create mode 100644 spring-boot-modules/spring-boot-graphql/src/main/resources/application-returnnull.yml create mode 100644 spring-boot-modules/spring-boot-graphql/src/main/resources/returnnull/returnnull.graphqls create mode 100644 spring-boot-modules/spring-boot-graphql/src/test/java/com/baeldung/returnnull/PostControllerIntegrationTest.java create mode 100644 spring-boot-modules/spring-boot-graphql/src/test/resources/graphql-test/create_post_return_custom_scalar.graphql create mode 100644 spring-boot-modules/spring-boot-graphql/src/test/resources/graphql-test/create_post_return_nullable_type.graphql diff --git a/spring-boot-modules/spring-boot-graphql/src/main/java/com/baeldung/returnnull/GraphQLVoidScalar.java b/spring-boot-modules/spring-boot-graphql/src/main/java/com/baeldung/returnnull/GraphQLVoidScalar.java new file mode 100644 index 0000000000..0ff1721c13 --- /dev/null +++ b/spring-boot-modules/spring-boot-graphql/src/main/java/com/baeldung/returnnull/GraphQLVoidScalar.java @@ -0,0 +1,30 @@ +package com.baeldung.returnnull; + +import graphql.schema.Coercing; +import graphql.schema.GraphQLScalarType; + +public class GraphQLVoidScalar { + + public static final GraphQLScalarType Void = GraphQLScalarType.newScalar() + .name("Void") + .description("A custom scalar that represents the null value") + .coercing(new Coercing() { + + @Override + public Object serialize(Object dataFetcherResult) { + return null; + } + + @Override + public Object parseValue(Object input) { + return null; + } + + @Override + public Object parseLiteral(Object input) { + return null; + } + }) + .build(); + +} diff --git a/spring-boot-modules/spring-boot-graphql/src/main/java/com/baeldung/returnnull/GraphQlConfig.java b/spring-boot-modules/spring-boot-graphql/src/main/java/com/baeldung/returnnull/GraphQlConfig.java new file mode 100644 index 0000000000..3ba508eb90 --- /dev/null +++ b/spring-boot-modules/spring-boot-graphql/src/main/java/com/baeldung/returnnull/GraphQlConfig.java @@ -0,0 +1,14 @@ +package com.baeldung.returnnull; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.graphql.execution.RuntimeWiringConfigurer; + +@Configuration +public class GraphQlConfig { + + @Bean + public RuntimeWiringConfigurer runtimeWiringConfigurer() { + return wiringBuilder -> wiringBuilder.scalar(GraphQLVoidScalar.Void); + } +} diff --git a/spring-boot-modules/spring-boot-graphql/src/main/java/com/baeldung/returnnull/Post.java b/spring-boot-modules/spring-boot-graphql/src/main/java/com/baeldung/returnnull/Post.java new file mode 100644 index 0000000000..e882bf6621 --- /dev/null +++ b/spring-boot-modules/spring-boot-graphql/src/main/java/com/baeldung/returnnull/Post.java @@ -0,0 +1,51 @@ +package com.baeldung.returnnull; + +public class Post { + + private String id; + private String title; + private String text; + private String category; + private String author; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getText() { + return text; + } + + public void setText(String text) { + this.text = text; + } + + public String getCategory() { + return category; + } + + public void setCategory(String category) { + this.category = category; + } + + public String getAuthor() { + return author; + } + + public void setAuthor(String author) { + this.author = author; + } + +} diff --git a/spring-boot-modules/spring-boot-graphql/src/main/java/com/baeldung/returnnull/PostController.java b/spring-boot-modules/spring-boot-graphql/src/main/java/com/baeldung/returnnull/PostController.java new file mode 100644 index 0000000000..99ce33c230 --- /dev/null +++ b/spring-boot-modules/spring-boot-graphql/src/main/java/com/baeldung/returnnull/PostController.java @@ -0,0 +1,28 @@ +package com.baeldung.returnnull; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +import org.springframework.graphql.data.method.annotation.Argument; +import org.springframework.graphql.data.method.annotation.MutationMapping; +import org.springframework.stereotype.Controller; + +@Controller +public class PostController { + + List posts = new ArrayList<>(); + + @MutationMapping + public Void createPostReturnCustomScalar(@Argument String title, @Argument String text, @Argument String category, @Argument String author) { + Post post = new Post(); + post.setId(UUID.randomUUID() + .toString()); + post.setTitle(title); + post.setText(text); + post.setCategory(category); + post.setAuthor(author); + posts.add(post); + return null; + } +} diff --git a/spring-boot-modules/spring-boot-graphql/src/main/java/com/baeldung/returnnull/ReturnNullApp.java b/spring-boot-modules/spring-boot-graphql/src/main/java/com/baeldung/returnnull/ReturnNullApp.java new file mode 100644 index 0000000000..7e24b0d9d7 --- /dev/null +++ b/spring-boot-modules/spring-boot-graphql/src/main/java/com/baeldung/returnnull/ReturnNullApp.java @@ -0,0 +1,14 @@ +package com.baeldung.returnnull; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class ReturnNullApp { + + public static void main(String[] args) { + System.setProperty("spring.profiles.default", "returnnull"); + SpringApplication.run(com.baeldung.chooseapi.ChooseApiApp.class, args); + } +} + diff --git a/spring-boot-modules/spring-boot-graphql/src/main/resources/application-returnnull.yml b/spring-boot-modules/spring-boot-graphql/src/main/resources/application-returnnull.yml new file mode 100644 index 0000000000..eabd906273 --- /dev/null +++ b/spring-boot-modules/spring-boot-graphql/src/main/resources/application-returnnull.yml @@ -0,0 +1,9 @@ +server: + port: 8082 + +spring: + graphql: + graphiql: + enabled: true + schema: + locations: classpath:returnnull/ diff --git a/spring-boot-modules/spring-boot-graphql/src/main/resources/returnnull/returnnull.graphqls b/spring-boot-modules/spring-boot-graphql/src/main/resources/returnnull/returnnull.graphqls new file mode 100644 index 0000000000..2cdff0878e --- /dev/null +++ b/spring-boot-modules/spring-boot-graphql/src/main/resources/returnnull/returnnull.graphqls @@ -0,0 +1,18 @@ +scalar Void + +type Mutation { + createPostReturnNullableType(title: String!, text: String!, category: String!, author: String!) : Int + createPostReturnCustomScalar(title: String!, text: String!, category: String!, author: String!) : Void +} + +type Post { + id: ID + title: String + text: String + category: String + author: String +} + +type Query { + recentPosts(count: Int, offset: Int): [Post]! +} diff --git a/spring-boot-modules/spring-boot-graphql/src/test/java/com/baeldung/returnnull/PostControllerIntegrationTest.java b/spring-boot-modules/spring-boot-graphql/src/test/java/com/baeldung/returnnull/PostControllerIntegrationTest.java new file mode 100644 index 0000000000..4d9dad0b40 --- /dev/null +++ b/spring-boot-modules/spring-boot-graphql/src/test/java/com/baeldung/returnnull/PostControllerIntegrationTest.java @@ -0,0 +1,48 @@ +package com.baeldung.returnnull; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.graphql.GraphQlTest; +import org.springframework.context.annotation.Import; +import org.springframework.graphql.test.tester.GraphQlTester; +import org.springframework.test.context.ActiveProfiles; + +@GraphQlTest(PostController.class) +@ActiveProfiles("returnnull") +@Import(GraphQlConfig.class) +class PostControllerIntegrationTest { + + @Autowired + private GraphQlTester graphQlTester; + + @Test + void givenNewPostData_whenExecuteMutation_thenReturnCustomNullScalar() { + String documentName = "create_post_return_custom_scalar"; + + graphQlTester.documentName(documentName) + .variable("title", "New Post") + .variable("text", "New post text") + .variable("category", "category") + .variable("author", "Alex") + .execute() + .path("createPostReturnCustomScalar") + .valueIsNull(); + + } + + @Test + void givenNewPostData_whenExecuteMutation_thenReturnNullType() { + String documentName = "create_post_return_nullable_type"; + + graphQlTester.documentName(documentName) + .variable("title", "New Post") + .variable("text", "New post text") + .variable("category", "category") + .variable("author", "Alex") + .execute() + .path("createPostReturnNullableType") + .valueIsNull(); + + } + +} diff --git a/spring-boot-modules/spring-boot-graphql/src/test/resources/graphql-test/create_post_return_custom_scalar.graphql b/spring-boot-modules/spring-boot-graphql/src/test/resources/graphql-test/create_post_return_custom_scalar.graphql new file mode 100644 index 0000000000..9400903ce1 --- /dev/null +++ b/spring-boot-modules/spring-boot-graphql/src/test/resources/graphql-test/create_post_return_custom_scalar.graphql @@ -0,0 +1,3 @@ +mutation createPostReturnCustomScalar($title: String!, $text: String!, $category: String!, $author: String!) { + createPostReturnCustomScalar(title: $title, text: $text, category: $category, author: $author) +} diff --git a/spring-boot-modules/spring-boot-graphql/src/test/resources/graphql-test/create_post_return_nullable_type.graphql b/spring-boot-modules/spring-boot-graphql/src/test/resources/graphql-test/create_post_return_nullable_type.graphql new file mode 100644 index 0000000000..f43c9bddf9 --- /dev/null +++ b/spring-boot-modules/spring-boot-graphql/src/test/resources/graphql-test/create_post_return_nullable_type.graphql @@ -0,0 +1,3 @@ +mutation createPostReturnNullableType($title: String!, $text: String!, $category: String!, $author: String!) { + createPostReturnNullableType(title: $title, text: $text, category: $category, author: $author) +} From 63399a9560cd6f2bf6d3da6d2cd7dd39b1e5a934 Mon Sep 17 00:00:00 2001 From: Bipin kumar Date: Wed, 21 Feb 2024 19:33:44 +0530 Subject: [PATCH 35/38] JAVA-29166: Upgrade spring-caching to Spring Boot 3 (#15875) --- spring-boot-modules/spring-caching/pom.xml | 21 +++++++++++++++---- .../springdatacaching/model/Book.java | 4 ++-- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/spring-boot-modules/spring-caching/pom.xml b/spring-boot-modules/spring-caching/pom.xml index f3d9488b89..4a8d586f82 100644 --- a/spring-boot-modules/spring-caching/pom.xml +++ b/spring-boot-modules/spring-caching/pom.xml @@ -9,9 +9,10 @@ war - com.baeldung.spring-boot-modules - spring-boot-modules - 1.0.0-SNAPSHOT + com.baeldung + parent-boot-3 + 0.0.1-SNAPSHOT + ../../parent-boot-3 @@ -42,6 +43,7 @@ org.ehcache ehcache + jakarta org.springframework @@ -77,8 +79,19 @@ + + + + org.springframework.boot + spring-boot-maven-plugin + + true + + + + + - 3.5.2 3.1.8 diff --git a/spring-boot-modules/spring-caching/src/main/java/com/baeldung/springdatacaching/model/Book.java b/spring-boot-modules/spring-caching/src/main/java/com/baeldung/springdatacaching/model/Book.java index 02285e3894..40402f692e 100644 --- a/spring-boot-modules/spring-caching/src/main/java/com/baeldung/springdatacaching/model/Book.java +++ b/spring-boot-modules/spring-caching/src/main/java/com/baeldung/springdatacaching/model/Book.java @@ -4,8 +4,8 @@ import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; -import javax.persistence.Entity; -import javax.persistence.Id; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; import java.io.Serializable; import java.util.UUID; From 6aff5d5c66983aa05f0ac16aa5c8f973e5345cf3 Mon Sep 17 00:00:00 2001 From: Harry9656 Date: Wed, 21 Feb 2024 20:37:27 +0100 Subject: [PATCH 36/38] JAVA-29330: Migrate spring-security-web-rest-custom to parent-boot-3. (#15932) --- .../spring-security-web-rest-custom/pom.xml | 24 ++++++------ .../config/MainWebAppInitializer.java | 18 +++------ .../config/child/MethodSecurityConfig.java | 11 +++--- .../com/baeldung/config/child/WebConfig.java | 25 +++++-------- .../config/parent/SecurityConfig.java | 20 +++++----- .../baeldung/config/parent/ServiceConfig.java | 6 --- .../security/AuthenticationFacade.java | 2 - .../CustomAuthenticationProvider.java | 18 ++++----- ...uestAwareAuthenticationSuccessHandler.java | 8 ++-- .../RestAuthenticationEntryPoint.java | 6 +-- .../java/com/baeldung/service/FooService.java | 12 +++--- .../com/baeldung/service/RunAsService.java | 5 +-- .../web/controller/FooController.java | 37 ++++++++----------- .../GetUserWithAuthenticationController.java | 13 ++----- .../GetUserWithCustomInterfaceController.java | 23 +++++------- ...tUserWithHTTPServletRequestController.java | 15 +++----- .../GetUserWithPrincipalController.java | 13 ++----- ...erWithSecurityContextHolderController.java | 22 ++--------- .../web/controller/RunAsController.java | 7 +--- .../main/webapp/WEB-INF/templates/runas.html | 5 +-- 20 files changed, 111 insertions(+), 179 deletions(-) diff --git a/spring-security-modules/spring-security-web-rest-custom/pom.xml b/spring-security-modules/spring-security-web-rest-custom/pom.xml index 2e55fe8b89..265adfa551 100644 --- a/spring-security-modules/spring-security-web-rest-custom/pom.xml +++ b/spring-security-modules/spring-security-web-rest-custom/pom.xml @@ -10,8 +10,9 @@ com.baeldung - spring-security-modules + parent-boot-3 0.0.1-SNAPSHOT + ../../parent-boot-3 @@ -26,11 +27,11 @@ org.thymeleaf.extras - thymeleaf-extras-springsecurity5 + thymeleaf-extras-springsecurity6 org.thymeleaf - thymeleaf-spring5 + thymeleaf-spring6 @@ -85,23 +86,24 @@ - javax.servlet - javax.servlet-api + jakarta.servlet + jakarta.servlet-api provided - javax.servlet - jstl + jakarta.servlet.jsp.jstl + jakarta.servlet.jsp.jstl-api runtime + - org.apache.httpcomponents - httpcore + org.apache.httpcomponents.core5 + httpcore5 - org.apache.httpcomponents - httpclient + org.apache.httpcomponents.client5 + httpclient5 diff --git a/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/config/MainWebAppInitializer.java b/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/config/MainWebAppInitializer.java index 4957a2604a..565bc999d4 100644 --- a/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/config/MainWebAppInitializer.java +++ b/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/config/MainWebAppInitializer.java @@ -2,36 +2,28 @@ package com.baeldung.config; import java.util.Set; -import javax.servlet.FilterRegistration.Dynamic; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.ServletRegistration; - import org.springframework.web.WebApplicationInitializer; import org.springframework.web.context.ContextLoaderListener; import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; import org.springframework.web.filter.DelegatingFilterProxy; import org.springframework.web.servlet.DispatcherServlet; +import jakarta.servlet.FilterRegistration.Dynamic; +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletRegistration; + public class MainWebAppInitializer implements WebApplicationInitializer { public MainWebAppInitializer() { super(); } - // - - /** - * Register and configure all Servlet container components necessary to power the web application. - */ @Override - public void onStartup(final ServletContext sc) throws ServletException { + public void onStartup(final ServletContext sc) { System.out.println("MyWebAppInitializer.onStartup()"); - // Create the 'root' Spring application context final AnnotationConfigWebApplicationContext root = new AnnotationConfigWebApplicationContext(); root.scan("com.baeldung.config.parent"); - // root.getEnvironment().setDefaultProfiles("embedded"); // Manages the lifecycle of the root application context sc.addListener(new ContextLoaderListener(root)); diff --git a/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/config/child/MethodSecurityConfig.java b/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/config/child/MethodSecurityConfig.java index 7fb282ae8b..50adc676dd 100644 --- a/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/config/child/MethodSecurityConfig.java +++ b/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/config/child/MethodSecurityConfig.java @@ -8,15 +8,14 @@ import org.springframework.security.access.intercept.RunAsManager; import org.springframework.security.access.intercept.RunAsManagerImpl; import org.springframework.security.authentication.AuthenticationProvider; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; -import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; -import org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration; +import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; @Configuration -@EnableGlobalMethodSecurity(securedEnabled = true) -public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration { +@EnableMethodSecurity(securedEnabled = true) +public class MethodSecurityConfig { - @Override + @Bean protected RunAsManager runAsManager() { RunAsManagerImpl runAsManager = new RunAsManagerImpl(); runAsManager.setKey("MyRunAsKey"); @@ -24,7 +23,7 @@ public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration { } @Autowired - public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { + public void configureGlobal(AuthenticationManagerBuilder auth) { auth.authenticationProvider(runAsAuthenticationProvider()); } diff --git a/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/config/child/WebConfig.java b/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/config/child/WebConfig.java index 011528e3cc..9e69e7ef80 100644 --- a/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/config/child/WebConfig.java +++ b/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/config/child/WebConfig.java @@ -2,7 +2,6 @@ package com.baeldung.config.child; import java.util.List; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; @@ -13,37 +12,31 @@ import org.springframework.http.converter.json.MappingJackson2HttpMessageConvert import org.springframework.web.servlet.ViewResolver; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; -import org.thymeleaf.extras.springsecurity5.dialect.SpringSecurityDialect; -import org.thymeleaf.spring5.ISpringTemplateEngine; -import org.thymeleaf.spring5.SpringTemplateEngine; -import org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver; -import org.thymeleaf.spring5.view.ThymeleafViewResolver; +import org.thymeleaf.extras.springsecurity6.dialect.SpringSecurityDialect; +import org.thymeleaf.spring6.ISpringTemplateEngine; +import org.thymeleaf.spring6.SpringTemplateEngine; +import org.thymeleaf.spring6.templateresolver.SpringResourceTemplateResolver; +import org.thymeleaf.spring6.view.ThymeleafViewResolver; import org.thymeleaf.templatemode.TemplateMode; import org.thymeleaf.templateresolver.ITemplateResolver; @Configuration @EnableWebMvc @ComponentScan("com.baeldung.web") -//@ImportResource({ "classpath:prop.xml" }) -//@PropertySource("classpath:foo.properties") public class WebConfig implements WebMvcConfigurer { - - @Autowired - private ApplicationContext applicationContext; - public WebConfig() { + private final ApplicationContext applicationContext; + + public WebConfig(ApplicationContext applicationContext) { super(); + this.applicationContext = applicationContext; } - // beans - @Override public void configureMessageConverters(final List> converters) { converters.add(new MappingJackson2HttpMessageConverter()); } - // beans - @Bean public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() { final PropertySourcesPlaceholderConfigurer ppc = new PropertySourcesPlaceholderConfigurer(); diff --git a/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/config/parent/SecurityConfig.java b/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/config/parent/SecurityConfig.java index 8682afbff9..a5ae48abb1 100644 --- a/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/config/parent/SecurityConfig.java +++ b/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/config/parent/SecurityConfig.java @@ -1,10 +1,10 @@ package com.baeldung.config.parent; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.config.Customizer; 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.EnableWebSecurity; @@ -18,8 +18,11 @@ import com.baeldung.security.CustomAuthenticationProvider; @ComponentScan("com.baeldung.security") public class SecurityConfig { - @Autowired - private CustomAuthenticationProvider authProvider; + private final CustomAuthenticationProvider authProvider; + + public SecurityConfig(CustomAuthenticationProvider authProvider) { + this.authProvider = authProvider; + } @Bean public AuthenticationManager authManager(HttpSecurity http) throws Exception { @@ -30,12 +33,9 @@ public class SecurityConfig { @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { - http.authorizeRequests() - .anyRequest() - .authenticated() - .and() - .httpBasic(); - return http.build(); + return http.authorizeHttpRequests(request -> request.anyRequest() + .authenticated()) + .httpBasic(Customizer.withDefaults()) + .build(); } - } diff --git a/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/config/parent/ServiceConfig.java b/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/config/parent/ServiceConfig.java index 55f837f674..b27c7961c2 100644 --- a/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/config/parent/ServiceConfig.java +++ b/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/config/parent/ServiceConfig.java @@ -12,12 +12,6 @@ import org.springframework.context.support.PropertySourcesPlaceholderConfigurer; @PropertySource("classpath:foo.properties") public class ServiceConfig { - public ServiceConfig() { - super(); - } - - // beans - @Bean public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() { final PropertySourcesPlaceholderConfigurer ppc = new PropertySourcesPlaceholderConfigurer(); diff --git a/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/security/AuthenticationFacade.java b/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/security/AuthenticationFacade.java index bcf0ef0499..975f65c5f7 100644 --- a/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/security/AuthenticationFacade.java +++ b/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/security/AuthenticationFacade.java @@ -11,8 +11,6 @@ public class AuthenticationFacade implements IAuthenticationFacade { super(); } - // API - @Override public final Authentication getAuthentication() { return SecurityContextHolder.getContext().getAuthentication(); diff --git a/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/security/CustomAuthenticationProvider.java b/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/security/CustomAuthenticationProvider.java index 8e67714431..251d8dcfa6 100644 --- a/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/security/CustomAuthenticationProvider.java +++ b/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/security/CustomAuthenticationProvider.java @@ -20,21 +20,21 @@ public class CustomAuthenticationProvider implements AuthenticationProvider { super(); } - // API - @Override public Authentication authenticate(final Authentication authentication) throws AuthenticationException { final String name = authentication.getName(); final String password = authentication.getCredentials().toString(); - if (name.equals("admin") && password.equals("system")) { - final List grantedAuths = new ArrayList<>(); - grantedAuths.add(new SimpleGrantedAuthority("ROLE_USER")); - final UserDetails principal = new User(name, password, grantedAuths); - final Authentication auth = new UsernamePasswordAuthenticationToken(principal, password, grantedAuths); - return auth; - } else { + if (!"admin".equals(name) || !"system".equals(password)) { return null; } + return authenticateAgainstThirdPartyAndGetAuthentication(name, password); + } + + private static UsernamePasswordAuthenticationToken authenticateAgainstThirdPartyAndGetAuthentication(String name, String password) { + final List grantedAuths = new ArrayList<>(); + grantedAuths.add(new SimpleGrantedAuthority("ROLE_USER")); + final UserDetails principal = new User(name, password, grantedAuths); + return new UsernamePasswordAuthenticationToken(principal, password, grantedAuths); } @Override diff --git a/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/security/MySavedRequestAwareAuthenticationSuccessHandler.java b/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/security/MySavedRequestAwareAuthenticationSuccessHandler.java index 7dc53e3e1e..32b10665e0 100644 --- a/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/security/MySavedRequestAwareAuthenticationSuccessHandler.java +++ b/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/security/MySavedRequestAwareAuthenticationSuccessHandler.java @@ -2,10 +2,6 @@ package com.baeldung.security; import java.io.IOException; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - import org.springframework.security.core.Authentication; import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler; import org.springframework.security.web.savedrequest.HttpSessionRequestCache; @@ -13,6 +9,10 @@ import org.springframework.security.web.savedrequest.RequestCache; import org.springframework.security.web.savedrequest.SavedRequest; import org.springframework.util.StringUtils; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + public class MySavedRequestAwareAuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler { private RequestCache requestCache = new HttpSessionRequestCache(); diff --git a/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/security/RestAuthenticationEntryPoint.java b/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/security/RestAuthenticationEntryPoint.java index 1ae89adb89..b9c29fdbff 100644 --- a/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/security/RestAuthenticationEntryPoint.java +++ b/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/security/RestAuthenticationEntryPoint.java @@ -2,13 +2,13 @@ package com.baeldung.security; import java.io.IOException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - import org.springframework.security.core.AuthenticationException; import org.springframework.security.web.AuthenticationEntryPoint; import org.springframework.stereotype.Component; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + /** * The Entry Point will not redirect to any sort of Login - it will return the 401 */ diff --git a/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/service/FooService.java b/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/service/FooService.java index f97c357566..614761a4ee 100644 --- a/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/service/FooService.java +++ b/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/service/FooService.java @@ -1,27 +1,25 @@ package com.baeldung.service; -import com.baeldung.web.dto.Foo; import org.springframework.beans.factory.InitializingBean; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.core.env.Environment; import org.springframework.stereotype.Service; +import com.baeldung.web.dto.Foo; + @Service public class FooService implements IFooService, InitializingBean { @Value("${foo1}") private String foo1; - @Autowired - private Environment env; + private final Environment env; - public FooService() { + public FooService(Environment env) { super(); + this.env = env; } - // API - @Override public Foo findOne(final Long id) { return new Foo(); diff --git a/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/service/RunAsService.java b/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/service/RunAsService.java index 412330006b..866d293a29 100644 --- a/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/service/RunAsService.java +++ b/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/service/RunAsService.java @@ -10,8 +10,7 @@ public class RunAsService { @Secured({ "ROLE_RUN_AS_REPORTER" }) public Authentication getCurrentUser() { - Authentication authentication = - SecurityContextHolder.getContext().getAuthentication(); - return authentication; + return SecurityContextHolder.getContext() + .getAuthentication(); } } \ No newline at end of file diff --git a/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/web/controller/FooController.java b/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/web/controller/FooController.java index 696dcccd02..60c9fdb2c9 100644 --- a/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/web/controller/FooController.java +++ b/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/web/controller/FooController.java @@ -1,39 +1,34 @@ package com.baeldung.web.controller; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.core.env.Environment; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + import com.baeldung.service.IFooService; import com.baeldung.web.dto.Foo; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.core.env.Environment; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.ResponseBody; -@Controller +@RestController @RequestMapping(value = "/foos") public class FooController implements InitializingBean { @Value("${foo1}") private String foo1; - @Autowired - private Environment env; + private final Environment env; + private final IFooService service; - @Autowired - private IFooService service; - - public FooController() { + public FooController(Environment env, IFooService service) { super(); + this.env = env; + this.service = service; } - // API - - @RequestMapping(value = "/{id}", method = RequestMethod.GET) - @ResponseBody - public Foo findOne(@PathVariable("id") final Long id) { + @GetMapping(value = "/{id}") + public Foo findOne(@PathVariable(name = "id") final Long id) { return service.findOne(id); } diff --git a/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/web/controller/GetUserWithAuthenticationController.java b/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/web/controller/GetUserWithAuthenticationController.java index 4f9b24cf36..9fcda178d0 100644 --- a/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/web/controller/GetUserWithAuthenticationController.java +++ b/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/web/controller/GetUserWithAuthenticationController.java @@ -2,22 +2,17 @@ package com.baeldung.web.controller; import org.springframework.security.core.Authentication; import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; -@Controller +@RestController public class GetUserWithAuthenticationController { public GetUserWithAuthenticationController() { super(); } - // API - - @RequestMapping(value = "/username3", method = RequestMethod.GET) - @ResponseBody + @GetMapping(value = "/username3") public String currentUserNameSimple(final Authentication authentication) { UserDetails userDetails = (UserDetails) authentication.getPrincipal(); System.out.println("Retrieved user with authorities: " + userDetails.getAuthorities()); diff --git a/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/web/controller/GetUserWithCustomInterfaceController.java b/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/web/controller/GetUserWithCustomInterfaceController.java index 4166ca9102..c547a9ad1d 100644 --- a/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/web/controller/GetUserWithCustomInterfaceController.java +++ b/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/web/controller/GetUserWithCustomInterfaceController.java @@ -1,27 +1,22 @@ package com.baeldung.web.controller; -import com.baeldung.security.IAuthenticationFacade; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.Authentication; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; -@Controller +import com.baeldung.security.IAuthenticationFacade; + +@RestController public class GetUserWithCustomInterfaceController { - @Autowired - private IAuthenticationFacade authenticationFacade; + private final IAuthenticationFacade authenticationFacade; - public GetUserWithCustomInterfaceController() { + public GetUserWithCustomInterfaceController(IAuthenticationFacade authenticationFacade) { super(); + this.authenticationFacade = authenticationFacade; } - // API - - @RequestMapping(value = "/username5", method = RequestMethod.GET) - @ResponseBody + @GetMapping(value = "/username5") public String currentUserNameSimple() { final Authentication authentication = authenticationFacade.getAuthentication(); return authentication.getName(); diff --git a/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/web/controller/GetUserWithHTTPServletRequestController.java b/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/web/controller/GetUserWithHTTPServletRequestController.java index 2e6951132d..e287185d91 100644 --- a/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/web/controller/GetUserWithHTTPServletRequestController.java +++ b/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/web/controller/GetUserWithHTTPServletRequestController.java @@ -2,24 +2,19 @@ package com.baeldung.web.controller; import java.security.Principal; -import javax.servlet.http.HttpServletRequest; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.ResponseBody; +import jakarta.servlet.http.HttpServletRequest; -@Controller +@RestController public class GetUserWithHTTPServletRequestController { public GetUserWithHTTPServletRequestController() { super(); } - // API - - @RequestMapping(value = "/username4", method = RequestMethod.GET) - @ResponseBody + @GetMapping(value = "/username4") public String currentUserNameSimple(final HttpServletRequest request) { final Principal principal = request.getUserPrincipal(); return principal.getName(); diff --git a/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/web/controller/GetUserWithPrincipalController.java b/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/web/controller/GetUserWithPrincipalController.java index ed3ea5b25d..cb4cfb35ca 100644 --- a/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/web/controller/GetUserWithPrincipalController.java +++ b/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/web/controller/GetUserWithPrincipalController.java @@ -2,22 +2,17 @@ package com.baeldung.web.controller; import java.security.Principal; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; -@Controller +@RestController public class GetUserWithPrincipalController { public GetUserWithPrincipalController() { super(); } - // API - - @RequestMapping(value = "/username2", method = RequestMethod.GET) - @ResponseBody + @GetMapping(value = "/username2") public String currentUserName(final Principal principal) { return principal.getName(); } diff --git a/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/web/controller/GetUserWithSecurityContextHolderController.java b/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/web/controller/GetUserWithSecurityContextHolderController.java index c63271ef77..5089f29cea 100644 --- a/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/web/controller/GetUserWithSecurityContextHolderController.java +++ b/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/web/controller/GetUserWithSecurityContextHolderController.java @@ -1,29 +1,15 @@ package com.baeldung.web.controller; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ApplicationEventPublisher; import org.springframework.security.authentication.AnonymousAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; -@Controller +@RestController public class GetUserWithSecurityContextHolderController { - @Autowired - private ApplicationEventPublisher eventPublisher; - - public GetUserWithSecurityContextHolderController() { - super(); - } - - // API - - @RequestMapping(value = "/username1", method = RequestMethod.GET) - @ResponseBody + @GetMapping(value = "/username1") public String currentUserName() { final Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); if (!(authentication instanceof AnonymousAuthenticationToken)) { diff --git a/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/web/controller/RunAsController.java b/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/web/controller/RunAsController.java index 13a3f45bf3..bbf0f70782 100644 --- a/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/web/controller/RunAsController.java +++ b/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/web/controller/RunAsController.java @@ -3,18 +3,15 @@ package com.baeldung.web.controller; import org.springframework.security.access.annotation.Secured; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; - -@Controller +@RestController @RequestMapping("/runas") public class RunAsController { @Secured({ "ROLE_USER", "RUN_AS_REPORTER" }) @RequestMapping - @ResponseBody public String tryRunAs() { Authentication auth = SecurityContextHolder.getContext().getAuthentication(); return "Current User Authorities inside this RunAS method only " + diff --git a/spring-security-modules/spring-security-web-rest-custom/src/main/webapp/WEB-INF/templates/runas.html b/spring-security-modules/spring-security-web-rest-custom/src/main/webapp/WEB-INF/templates/runas.html index c7c3b2e0e4..7e59c4b155 100644 --- a/spring-security-modules/spring-security-web-rest-custom/src/main/webapp/WEB-INF/templates/runas.html +++ b/spring-security-modules/spring-security-web-rest-custom/src/main/webapp/WEB-INF/templates/runas.html @@ -1,6 +1,5 @@ - + Current user authorities: user @@ -9,7 +8,7 @@ Generate Report As Super User + src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js">