Merge branch 'eugenp:master' into master

This commit is contained in:
sebx59 2022-11-24 10:55:33 +01:00 committed by GitHub
commit a30a85ddd4
48 changed files with 1205 additions and 201 deletions

View File

@ -0,0 +1,21 @@
package com.baeldung.shell;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.function.Consumer;
public class StreamGobbler implements Runnable {
private final InputStream inputStream;
private final Consumer<String> consumer;
public StreamGobbler(InputStream inputStream, Consumer<String> consumer) {
this.inputStream = inputStream;
this.consumer = consumer;
}
@Override
public void run() {
new BufferedReader(new InputStreamReader(inputStream)).lines().forEach(consumer);
}
}

View File

@ -5,10 +5,7 @@ import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import java.io.BufferedReader;
import java.io.File; import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.Future; import java.util.concurrent.Future;
@ -21,21 +18,6 @@ import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
public class JavaProcessUnitIntegrationTest { public class JavaProcessUnitIntegrationTest {
private static final boolean IS_WINDOWS = System.getProperty("os.name").toLowerCase().startsWith("windows"); private static final boolean IS_WINDOWS = System.getProperty("os.name").toLowerCase().startsWith("windows");
private static class StreamGobbler implements Runnable {
private InputStream inputStream;
private Consumer<String> consumer;
public StreamGobbler(InputStream inputStream, Consumer<String> consumer) {
this.inputStream = inputStream;
this.consumer = consumer;
}
@Override
public void run() {
new BufferedReader(new InputStreamReader(inputStream)).lines().forEach(consumer);
}
}
private Consumer<String> consumer = Assert::assertNotNull; private Consumer<String> consumer = Assert::assertNotNull;
private String homeDirectory = System.getProperty("user.home"); private String homeDirectory = System.getProperty("user.home");
@ -58,7 +40,7 @@ public class JavaProcessUnitIntegrationTest {
if (IS_WINDOWS) { if (IS_WINDOWS) {
process = Runtime.getRuntime().exec(String.format("cmd.exe /c dir %s", homeDirectory)); process = Runtime.getRuntime().exec(String.format("cmd.exe /c dir %s", homeDirectory));
} else { } else {
process = Runtime.getRuntime().exec(String.format("sh -c ls %s", homeDirectory)); process = Runtime.getRuntime().exec(String.format("/bin/sh -c ls %s", homeDirectory));
} }
StreamGobbler streamGobbler = new StreamGobbler(process.getInputStream(), consumer); StreamGobbler streamGobbler = new StreamGobbler(process.getInputStream(), consumer);
@ -70,13 +52,34 @@ public class JavaProcessUnitIntegrationTest {
assertEquals(0, exitCode); assertEquals(0, exitCode);
} }
@Test
public void shouldExecuteCommandWithPipesWithRuntimeProcess(){
Process process;
try {
if (IS_WINDOWS) {
process = Runtime.getRuntime().exec(String.format("cmd.exe /c dir %s | findstr \"Desktop\"", homeDirectory));
} else {
process = Runtime.getRuntime().exec(String.format("/bin/sh -c ls %s | grep \"Desktop\"", homeDirectory));
}
StreamGobbler streamGobbler = new StreamGobbler(process.getInputStream(), consumer);
Future<?> future = executorService.submit(streamGobbler);
int exitCode = process.waitFor();
// verify the stream output from the process
assertDoesNotThrow(() -> future.get(10, TimeUnit.SECONDS));
assertEquals(0, exitCode);
} catch (Exception e) {
e.printStackTrace();
}
}
@Test @Test
public void givenProcess_whenCreatingViaProcessBuilder_shouldSucceed() throws Exception { public void givenProcess_whenCreatingViaProcessBuilder_shouldSucceed() throws Exception {
ProcessBuilder builder = new ProcessBuilder(); ProcessBuilder builder = new ProcessBuilder();
if (IS_WINDOWS) { if (IS_WINDOWS) {
builder.command("cmd.exe", "/c", "dir"); builder.command("cmd.exe", "/c", "dir");
} else { } else {
builder.command("sh", "-c", "ls"); builder.command("/bin/sh", "-c", "ls");
} }
builder.directory(new File(homeDirectory)); builder.directory(new File(homeDirectory));
Process process = builder.start(); Process process = builder.start();

View File

@ -1,15 +1,41 @@
package com.baeldung.system.exit; package com.baeldung.system.exit;
import static org.junit.Assert.assertEquals;
import java.security.Permission;
import org.junit.After; import org.junit.After;
import org.junit.Before; import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
import java.security.Permission;
import static org.junit.Assert.assertEquals;
@Ignore("This test is ignored because it tests deprecated code")
public class SystemExitUnitTest { public class SystemExitUnitTest {
private SecurityManager securityManager;
private SystemExitExample example;
@Before
public void setUp() {
example = new SystemExitExample();
securityManager = System.getSecurityManager();
System.setSecurityManager(new NoExitSecurityManager());
}
@After
public void tearDown() throws Exception {
System.setSecurityManager(securityManager);
}
@Test
public void testExit() throws Exception {
try {
example.readFile();
} catch (ExitException e) {
assertEquals("Exit status", 2, e.status);
}
}
protected static class ExitException extends SecurityException { protected static class ExitException extends SecurityException {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@ -35,29 +61,4 @@ public class SystemExitUnitTest {
throw new ExitException(status); throw new ExitException(status);
} }
} }
private SecurityManager securityManager;
private SystemExitExample example;
@Before
public void setUp() throws Exception {
example = new SystemExitExample();
securityManager = System.getSecurityManager();
System.setSecurityManager(new NoExitSecurityManager());
}
@After
public void tearDown() throws Exception {
System.setSecurityManager(securityManager);
}
@Test
public void testExit() throws Exception {
try {
example.readFile();
} catch (ExitException e) {
assertEquals("Exit status", 2, e.status);
}
}
} }

View File

@ -3,8 +3,6 @@ package com.baeldung.uuid;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.security.MessageDigest; import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.Arrays; import java.util.Arrays;
import java.util.Random; import java.util.Random;
import java.util.UUID; import java.util.UUID;
@ -13,7 +11,8 @@ public final class UUIDGenerator {
private static final char[] hexArray = "0123456789ABCDEF".toCharArray(); private static final char[] hexArray = "0123456789ABCDEF".toCharArray();
private UUIDGenerator() {} private UUIDGenerator() {
}
/** /**
* Type 1 UUID Generation * Type 1 UUID Generation
@ -33,14 +32,12 @@ public final class UUIDGenerator {
} }
private static long get64MostSignificantBitsForVersion1() { private static long get64MostSignificantBitsForVersion1() {
final LocalDateTime start = LocalDateTime.of(1582, 10, 15, 0, 0, 0); final long timeForUuidIn100Nanos = System.currentTimeMillis();
final Duration duration = Duration.between(start, LocalDateTime.now()); final long time_low = (timeForUuidIn100Nanos & 0x0000_0000_FFFF_FFFFL) << 32;
final long seconds = duration.getSeconds(); final long time_mid = ((timeForUuidIn100Nanos >> 32) & 0xFFFF) << 16;
final long nanos = duration.getNano();
final long timeForUuidIn100Nanos = seconds * 10000000 + nanos * 100;
final long least12SignificantBitOfTime = (timeForUuidIn100Nanos & 0x000000000000FFFFL) >> 4;
final long version = 1 << 12; final long version = 1 << 12;
return (timeForUuidIn100Nanos & 0xFFFFFFFFFFFF0000L) + version + least12SignificantBitOfTime; final long time_hi = ((timeForUuidIn100Nanos >> 48) & 0x0FFF);
return time_low + time_mid + version + time_hi;
} }
/** /**
@ -94,32 +91,14 @@ public final class UUIDGenerator {
long lsb = 0; long lsb = 0;
assert data.length == 16 : "data must be 16 bytes in length"; assert data.length == 16 : "data must be 16 bytes in length";
for (int i = 0; i < 8; i++) {msb = (msb << 8) | (data[i] & 0xff);} for (int i = 0; i < 8; i++) {
msb = (msb << 8) | (data[i] & 0xff);
for (int i = 8; i < 16; i++) {lsb = (lsb << 8) | (data[i] & 0xff);}
return new UUID(msb, lsb);
}
/**
* Unique Keys Generation Using Message Digest and Type 4 UUID
* @throws NoSuchAlgorithmException
*/
public static String generateUniqueKeysWithUUIDAndMessageDigest() throws NoSuchAlgorithmException {
final MessageDigest salt = MessageDigest.getInstance("SHA-256");
salt.update(UUID.randomUUID()
.toString()
.getBytes(StandardCharsets.UTF_8));
return bytesToHex(salt.digest());
}
private static String bytesToHex(byte[] bytes) {
final char[] hexChars = new char[bytes.length * 2];
for (int j = 0; j < bytes.length; j++) {
final int v = bytes[j] & 0xFF;
hexChars[j * 2] = hexArray[v >>> 4];
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
} }
return new String(hexChars);
for (int i = 8; i < 16; i++) {
lsb = (lsb << 8) | (data[i] & 0xff);
}
return new UUID(msb, lsb);
} }
private static byte[] bytesFromUUID(String uuidHexString) { private static byte[] bytesFromUUID(String uuidHexString) {

View File

@ -3,6 +3,10 @@ package com.baeldung.uuid;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.UUID; import java.util.UUID;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
@ -13,17 +17,23 @@ class UUIDGeneratorUnitTest {
private static final String NAMESPACE_DNS = "6ba7b810-9dad-11d1-80b4-00c04fd430c8"; private static final String NAMESPACE_DNS = "6ba7b810-9dad-11d1-80b4-00c04fd430c8";
@Test @Test
public void version_1_UUID_is_generated_with_correct_length_version_and_variant() { void shouldGenerateType1UUIDWithCorrectVersionAndVariant() {
UUID uuid = UUIDGenerator.generateType1UUID(); UUID uuid = UUIDGenerator.generateType1UUID();
assertEquals(36, uuid.toString().length()); assertEquals(36, uuid.toString().length());
assertEquals(1, uuid.version()); assertEquals(1, uuid.version());
assertEquals(2, uuid.variant()); assertEquals(2, uuid.variant());
} }
@Test @Test
public void version_3_UUID_is_correctly_generated_for_domain_baeldung_com() throws UnsupportedEncodingException { void shouldGenerateType1UUIDWithTheCurrentDate() {
UUID uuid = UUIDGenerator.generateType1UUID();
long time = uuid.timestamp();
LocalDateTime dateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(time), ZoneId.systemDefault());
assertEquals(LocalDate.now(), dateTime.toLocalDate());
}
@Test
void version_3_UUID_is_correctly_generated_for_domain_baeldung_com() {
UUID uuid = UUIDGenerator.generateType3UUID(NAMESPACE_DNS, "baeldung.com"); UUID uuid = UUIDGenerator.generateType3UUID(NAMESPACE_DNS, "baeldung.com");
@ -33,7 +43,7 @@ class UUIDGeneratorUnitTest {
} }
@Test @Test
public void version_3_UUID_is_correctly_generated_for_domain_d() throws UnsupportedEncodingException { void version_3_UUID_is_correctly_generated_for_domain_d() {
UUID uuid = UUIDGenerator.generateType3UUID(NAMESPACE_DNS, "d"); UUID uuid = UUIDGenerator.generateType3UUID(NAMESPACE_DNS, "d");

View File

@ -1,2 +1,2 @@
config.stopBubbling = true config.stopBubbling = true
lombok.experimental.flagUsage = warning lombok.experimental.flagUsage = warning

View File

@ -20,6 +20,15 @@
<version>${lombok.version}</version> <version>${lombok.version}</version>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
</dependencies> </dependencies>
<properties>
<jackson.version>2.14.1</jackson.version>
</properties>
</project> </project>

View File

@ -0,0 +1,39 @@
package com.baeldung.lombok.jackson;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
@Data
@Builder(builderClassName = "EmployeeBuilder")
@JsonDeserialize(builder = Employee.EmployeeBuilder.class)
@AllArgsConstructor
public class Employee {
private int identity;
private String firstName;
@JsonPOJOBuilder(buildMethodName = "createEmployee", withPrefix = "construct")
public static class EmployeeBuilder {
private int idValue;
private String nameValue;
public EmployeeBuilder constructId(int id) {
idValue = id;
return this;
}
public EmployeeBuilder constructName(String name) {
nameValue = name;
return this;
}
public Employee createEmployee() {
return new Employee(idValue, nameValue);
}
}
}

View File

@ -0,0 +1,15 @@
package com.baeldung.lombok.jackson;
import lombok.Builder;
import lombok.Data;
import lombok.extern.jackson.Jacksonized;
@Data
@Builder
@Jacksonized
public class Fruit {
private String name;
private int id;
}

View File

@ -0,0 +1,35 @@
package com.baeldung.lombok.jackson;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.io.IOException;
import org.junit.jupiter.api.Test;
import com.fasterxml.jackson.databind.ObjectMapper;
class LombokWithJacksonEmployeeUnitTest {
@Test
void withEmployeeObject_thenSerializeSucessfully() throws IOException {
Employee employee = Employee.builder()
.identity(5)
.firstName("Bob")
.build();
String json = newObjectMapper().writeValueAsString(employee);
assertEquals("{\"identity\":5,\"firstName\":\"Bob\"}", json);
}
@Test
public void withEmployeeJSON_thenDeserializeSucessfully() throws IOException {
String json = "{\"id\":5,\"name\":\"Bob\"}";
Employee employee = newObjectMapper().readValue(json, Employee.class);
assertEquals(5, employee.getIdentity());
assertEquals("Bob", employee.getFirstName());
}
private ObjectMapper newObjectMapper() {
return new ObjectMapper();
}
}

View File

@ -0,0 +1,33 @@
package com.baeldung.lombok.jackson;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.io.IOException;
import org.junit.jupiter.api.Test;
import com.fasterxml.jackson.databind.ObjectMapper;
class LombokWithJacksonFruitUnitTest {
@Test
void withFruitObject_thenSerializeSucessfully() throws IOException {
Fruit fruit = Fruit.builder()
.id(101)
.name("Apple")
.build();
String json = newObjectMapper().writeValueAsString(fruit);
assertEquals("{\"name\":\"Apple\",\"id\":101}", json);
}
@Test
public void withFruitJSON_thenDeserializeSucessfully() throws IOException {
String json = "{\"name\":\"Apple\",\"id\":101}";
Fruit fruit = newObjectMapper().readValue(json, Fruit.class);
assertEquals(new Fruit("Apple", 101), fruit);
}
private ObjectMapper newObjectMapper() {
return new ObjectMapper();
}
}

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" <project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<artifactId>parent-boot-3</artifactId> <artifactId>parent-boot-3</artifactId>
<version>0.0.1-SNAPSHOT</version> <version>0.0.1-SNAPSHOT</version>
@ -34,6 +34,26 @@
</dependencies> </dependencies>
</dependencyManagement> </dependencyManagement>
<dependencies> <dependencies>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>${logback.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId> <artifactId>spring-boot-starter-test</artifactId>
@ -44,26 +64,166 @@
<build> <build>
<pluginManagement> <pluginManagement>
<plugins> <plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-clean-plugin</artifactId>
<version>${maven-clean-plugin.version}</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler-plugin.version}</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>${maven-jar-plugin.version}</version>
<configuration>
<archive>
<manifest>
<mainClass>${start-class}</mainClass>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>${maven-surefire-plugin.version}</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>${maven-resources-plugin.version}</version>
</plugin>
<plugin>
<groupId>org.graalvm.buildtools</groupId>
<artifactId>native-maven-plugin</artifactId>
<version>${native-build-tools-plugin.version}</version>
<extensions>true</extensions>
</plugin>
<plugin> <plugin>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId> <artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version> <version>${spring-boot.version}</version>
<configuration> <configuration>
<mainClass>${start-class}</mainClass> <mainClass>${start-class}</mainClass>
<!-- this is necessary as we're not using the Boot parent -->
</configuration> </configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin> </plugin>
</plugins> </plugins>
</pluginManagement> </pluginManagement>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build> </build>
<profiles>
<profile>
<id>native</id>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<image>
<builder>paketobuildpacks/builder:tiny</builder>
<env>
<BP_NATIVE_IMAGE>true</BP_NATIVE_IMAGE>
</env>
</image>
</configuration>
<executions>
<execution>
<id>process-aot</id>
<goals>
<goal>process-aot</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.graalvm.buildtools</groupId>
<artifactId>native-maven-plugin</artifactId>
<configuration>
<classesDirectory>${project.build.outputDirectory}</classesDirectory>
<metadataRepository>
<enabled>true</enabled>
</metadataRepository>
<requiredVersion>22.3</requiredVersion>
</configuration>
<executions>
<execution>
<id>add-reachability-metadata</id>
<goals>
<goal>add-reachability-metadata</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>nativeTest</id>
<dependencies>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-launcher</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<id>process-test-aot</id>
<goals>
<goal>process-test-aot</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.graalvm.buildtools</groupId>
<artifactId>native-maven-plugin</artifactId>
<configuration>
<classesDirectory>${project.build.outputDirectory}</classesDirectory>
<metadataRepository>
<enabled>true</enabled>
</metadataRepository>
<requiredVersion>22.3</requiredVersion>
</configuration>
<executions>
<execution>
<id>native-test</id>
<goals>
<goal>test</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<!-- We currently use a Release Candidate, that is not available in Maven Central -->
<repositories> <repositories>
<repository> <repository>
<id>spring-milestones</id> <id>spring-milestones</id>
@ -87,10 +247,21 @@
</pluginRepositories> </pluginRepositories>
<properties> <properties>
<maven-clean-plugin.version>3.2.0</maven-clean-plugin.version>
<maven-compiler-plugin.version>3.10.1</maven-compiler-plugin.version>
<maven-jar-plugin.version>3.3.0</maven-jar-plugin.version>
<maven-resources-plugin.version>3.3.0</maven-resources-plugin.version>
<maven-surefire-plugin.version>2.22.2</maven-surefire-plugin.version>
<spring-boot.version>3.0.0-M3</spring-boot.version> <spring-boot.version>3.0.0-M3</spring-boot.version>
<junit-jupiter.version>5.8.2</junit-jupiter.version> <junit-jupiter.version>5.8.2</junit-jupiter.version>
<maven-surefire-plugin.version>3.0.0-M7</maven-surefire-plugin.version> <maven-surefire-plugin.version>3.0.0-M7</maven-surefire-plugin.version>
<native-build-tools-plugin.version>0.9.17</native-build-tools-plugin.version>
<java.version>17</java.version> <java.version>17</java.version>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<logback.version>1.4.4</logback.version>
<slf4j.version>2.0.3</slf4j.version>
</properties> </properties>
</project> </project>

View File

@ -8,27 +8,30 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity; 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.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.SecurityFilterChain;
@Configuration @Configuration
@EnableWebSecurity @EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true) @EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter { public class WebSecurityConfiguration {
@Autowired @Autowired
private FaunaClient faunaClient; private FaunaClient faunaClient;
@Override @Bean
protected void configure(HttpSecurity http) throws Exception { public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.csrf().disable(); http.csrf()
.disable();
http.authorizeRequests() http.authorizeRequests()
.antMatchers("/**").permitAll() .antMatchers("/**")
.and().httpBasic(); .permitAll()
.and()
.httpBasic();
return http.build();
} }
@Bean @Bean
@Override
public UserDetailsService userDetailsService() { public UserDetailsService userDetailsService() {
return new FaunaUserDetailsService(faunaClient); return new FaunaUserDetailsService(faunaClient);
} }

12
pom.xml
View File

@ -326,7 +326,6 @@
<modules> <modules>
<module>parent-boot-1</module> <module>parent-boot-1</module>
<module>parent-boot-2</module> <module>parent-boot-2</module>
<module>parent-boot-3</module>
<module>parent-spring-4</module> <module>parent-spring-4</module>
<module>parent-spring-5</module> <module>parent-spring-5</module>
<module>parent-java</module> <module>parent-java</module>
@ -456,7 +455,6 @@
<module>logging-modules</module> <module>logging-modules</module>
<module>lombok-modules</module> <module>lombok-modules</module>
<module>lucene</module> <module>lucene</module>
<module>mapstruct</module> <module>mapstruct</module>
<module>maven-modules</module> <module>maven-modules</module>
@ -534,7 +532,6 @@
<modules> <modules>
<module>parent-boot-1</module> <module>parent-boot-1</module>
<module>parent-boot-2</module> <module>parent-boot-2</module>
<module>parent-boot-3</module>
<module>parent-spring-4</module> <module>parent-spring-4</module>
<module>parent-spring-5</module> <module>parent-spring-5</module>
<module>parent-java</module> <module>parent-java</module>
@ -677,7 +674,6 @@
<modules> <modules>
<module>parent-boot-1</module> <module>parent-boot-1</module>
<module>parent-boot-2</module> <module>parent-boot-2</module>
<module>parent-boot-3</module>
<module>parent-spring-4</module> <module>parent-spring-4</module>
<module>parent-spring-5</module> <module>parent-spring-5</module>
<module>parent-java</module> <module>parent-java</module>
@ -732,7 +728,6 @@
<modules> <modules>
<module>parent-boot-1</module> <module>parent-boot-1</module>
<module>parent-boot-2</module> <module>parent-boot-2</module>
<module>parent-boot-3</module>
<module>parent-spring-4</module> <module>parent-spring-4</module>
<module>parent-spring-5</module> <module>parent-spring-5</module>
<module>parent-java</module> <module>parent-java</module>
@ -861,7 +856,6 @@
<module>logging-modules</module> <module>logging-modules</module>
<module>lombok-modules</module> <module>lombok-modules</module>
<module>lucene</module> <module>lucene</module>
<module>mapstruct</module> <module>mapstruct</module>
<module>maven-modules</module> <module>maven-modules</module>
@ -930,7 +924,6 @@
<modules> <modules>
<module>parent-boot-1</module> <module>parent-boot-1</module>
<module>parent-boot-2</module> <module>parent-boot-2</module>
<module>parent-boot-3</module>
<module>parent-spring-4</module> <module>parent-spring-4</module>
<module>parent-spring-5</module> <module>parent-spring-5</module>
<module>parent-java</module> <module>parent-java</module>
@ -1066,7 +1059,6 @@
<modules> <modules>
<module>parent-boot-1</module> <module>parent-boot-1</module>
<module>parent-boot-2</module> <module>parent-boot-2</module>
<module>parent-boot-3</module>
<module>parent-spring-4</module> <module>parent-spring-4</module>
<module>parent-spring-5</module> <module>parent-spring-5</module>
<module>parent-java</module> <module>parent-java</module>
@ -1204,10 +1196,12 @@
<module>spring-boot-modules/spring-boot-cassandre</module> <module>spring-boot-modules/spring-boot-cassandre</module>
<module>spring-boot-modules/spring-boot-camel</module> <module>spring-boot-modules/spring-boot-camel</module>
<module>spring-boot-modules/spring-boot-3</module> <module>spring-boot-modules/spring-boot-3</module>
<module>spring-boot-modules/spring-boot-3-native</module>
<module>spring-swagger-codegen/custom-validations-opeanpi-codegen</module> <module>spring-swagger-codegen/custom-validations-opeanpi-codegen</module>
<module>testing-modules/testing-assertions</module> <module>testing-modules/testing-assertions</module>
<module>persistence-modules/fauna</module> <module>persistence-modules/fauna</module>
<module>lightrun</module> <module>lightrun</module>
<module>tablesaw</module>
</modules> </modules>
</profile> </profile>
@ -1280,11 +1274,13 @@
<module>spring-boot-modules/spring-boot-cassandre</module> <module>spring-boot-modules/spring-boot-cassandre</module>
<module>spring-boot-modules/spring-boot-camel</module> <module>spring-boot-modules/spring-boot-camel</module>
<module>spring-boot-modules/spring-boot-3</module> <module>spring-boot-modules/spring-boot-3</module>
<module>spring-boot-modules/spring-boot-3-native</module>
<module>spring-swagger-codegen/custom-validations-opeanpi-codegen</module> <module>spring-swagger-codegen/custom-validations-opeanpi-codegen</module>
<module>testing-modules/testing-assertions</module> <module>testing-modules/testing-assertions</module>
<module>persistence-modules/fauna</module> <module>persistence-modules/fauna</module>
<module>lightrun</module> <module>lightrun</module>
<module>spring-core-6</module> <module>spring-core-6</module>
<module>tablesaw</module>
</modules> </modules>
</profile> </profile>
</profiles> </profiles>

View File

@ -1,40 +1,46 @@
package com.baeldung.comparison.springsecurity.config; package com.baeldung.comparison.springsecurity.config;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
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.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
@EnableWebSecurity @EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter { public class SecurityConfig {
@Override @Bean
protected void configure(HttpSecurity http) throws Exception { public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.csrf().disable().authorizeRequests(authorize -> authorize.antMatchers("/index", "/login") http.csrf()
.permitAll() .disable()
.antMatchers("/home", "/logout") .authorizeRequests(authorize -> authorize.antMatchers("/index", "/login")
.authenticated() .permitAll()
.antMatchers("/admin/**") .antMatchers("/home", "/logout")
.hasRole("ADMIN")) .authenticated()
.antMatchers("/admin/**")
.hasRole("ADMIN"))
.formLogin(formLogin -> formLogin.loginPage("/login") .formLogin(formLogin -> formLogin.loginPage("/login")
.failureUrl("/login-error")); .failureUrl("/login-error"));
return http.build();
} }
@Override @Bean
protected void configure(AuthenticationManagerBuilder auth) throws Exception { public InMemoryUserDetailsManager userDetailsService() throws Exception {
auth.inMemoryAuthentication() UserDetails jerry = User.withUsername("Jerry")
.withUser("Jerry")
.password(passwordEncoder().encode("password")) .password(passwordEncoder().encode("password"))
.authorities("READ", "WRITE") .authorities("READ", "WRITE")
.roles("ADMIN") .roles("ADMIN")
.and() .build();
.withUser("Tom") UserDetails tom = User.withUsername("Tom")
.password(passwordEncoder().encode("password")) .password(passwordEncoder().encode("password"))
.authorities("READ") .authorities("READ")
.roles("USER"); .roles("USER")
.build();
return new InMemoryUserDetailsManager(jerry, tom);
} }
@Bean @Bean

View File

@ -0,0 +1,86 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>spring-boot-3-native</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>spring-boot-3-native</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>com.baeldung</groupId>
<artifactId>parent-boot-3</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../../parent-boot-3/pom.xml</relativePath>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>${spring-doc.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-graphql</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.graalvm.buildtools</groupId>
<artifactId>native-maven-plugin</artifactId>
<configuration>
<!-- Mockito is not supported -->
<skipNativeTests>true</skipNativeTests>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
<profiles>
<!-- The native profile is already defined by the parent POM. -->
<!-- To use this plugin, we need GraalVM (located under $GRAALVM_HOME) and native-builder (located in the $PATH)-->
<profile>
<id>native</id>
<build>
<plugins>
<plugin>
<groupId>org.graalvm.buildtools</groupId>
<artifactId>native-maven-plugin</artifactId>
<executions>
<execution>
<id>build-native</id>
<goals>
<goal>compile-no-fork</goal>
</goals>
<phase>package</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<properties>
<spring-boot.version>3.0.0-RC2</spring-boot.version>
<spring-doc.version>2.0.0-RC1</spring-doc.version>
<native.maven.plugin.version>0.9.17</native.maven.plugin.version>
<start-class>com.baeldung.sample.TodoApplication</start-class>
</properties>
</project>

View File

@ -0,0 +1,23 @@
package com.baeldung.sample;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class BoundaryConfiguration {
@Bean
public WebMvcConfigurer webMvcConfigurer() {
return new WebMvcConfigurer() {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry
.addViewController("/")
.setViewName("redirect:/index.html");
}
};
}
}

View File

@ -0,0 +1,22 @@
package com.baeldung.sample;
import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.RuntimeHintsRegistrar;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportRuntimeHints;
@ImportRuntimeHints(GraphQlRuntimeHints.GraphQlResourcesRegistrar.class)
@Configuration
public class GraphQlRuntimeHints {
static class GraphQlResourcesRegistrar implements RuntimeHintsRegistrar {
@Override
public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
hints.resources()
.registerPattern("graphql/**/")
.registerPattern("graphiql/index.html");
}
}
}

View File

@ -0,0 +1,30 @@
package com.baeldung.sample;
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.RuntimeHintsRegistrar;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportRuntimeHints;
@Configuration
@ImportRuntimeHints(JacksonRuntimeHints.PropertyNamingStrategyRegistrar.class)
public class JacksonRuntimeHints {
private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(JacksonRuntimeHints.class);
static class PropertyNamingStrategyRegistrar implements RuntimeHintsRegistrar {
@Override
public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
try {
hints
.reflection()
.registerField(PropertyNamingStrategies.class.getDeclaredField("SNAKE_CASE"));
log.info("Registered native hint for SNAKE_CASE!");
} catch (NoSuchFieldException e) {
log.warn("Unable to register native hint for SNAKE_CASE!");
}
}
}
}

View File

@ -0,0 +1,11 @@
package com.baeldung.sample;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class TodoApplication {
public static void main(String[] args) {
SpringApplication.run(TodoApplication.class, args);
}
}

View File

@ -0,0 +1,31 @@
package com.baeldung.sample;
public class User {
private String firstName;
private String lastName;
public User(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
public User() {
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
}

View File

@ -0,0 +1,19 @@
package com.baeldung.sample;
import org.springframework.graphql.data.method.annotation.QueryMapping;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api/v1/user")
public class UserController {
@QueryMapping("getUser")
@GetMapping(produces = MediaType.APPLICATION_JSON_VALUE)
public User getUser() {
return new User("John", "Doe");
}
}

View File

@ -0,0 +1,6 @@
spring:
graphql:
graphiql:
enabled: true
jackson:
property-naming-strategy: SNAKE_CASE

View File

@ -0,0 +1,8 @@
type User {
firstName: String!
lastName: String!
}
type Query {
getUser: User!
}

View File

@ -0,0 +1,17 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Spring Native Demo Application</title>
</head>
<body>
<h1>Spring Native Demo Application</h1>
<p>
This is a sample application that can be built as native executable.
</p>
<ul>
<li><a href="./swagger-ui.html">REST API Test Client</a></li>
<li><a href="./graphiql">GraphQL API Test Client</a></li>
</ul>
</body>
</html>

View File

@ -0,0 +1,23 @@
package com.baeldung.sample;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import static org.assertj.core.api.Assertions.assertThat;
@SpringBootTest
class JacksonAutoConfigurationIntegrationTest {
@Autowired
ObjectMapper mapper;
@Test
void shouldUseSnakeCasePropertyNamingStrategy() {
assertThat(mapper.getPropertyNamingStrategy())
.isSameAs(PropertyNamingStrategies.SNAKE_CASE);
}
}

View File

@ -0,0 +1,27 @@
package com.baeldung.sample;
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
import org.junit.jupiter.api.Test;
import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.predicate.RuntimeHintsPredicates;
import static org.assertj.core.api.Assertions.assertThat;
class JacksonRuntimeHintsUnitTest {
@Test
void shouldRegisterSnakeCasePropertyNamingStrategy() {
// arrange
final var hints = new RuntimeHints();
final var expectSnakeCaseHint = RuntimeHintsPredicates
.reflection()
.onField(PropertyNamingStrategies.class, "SNAKE_CASE");
// act
new JacksonRuntimeHints.PropertyNamingStrategyRegistrar()
.registerHints(hints, getClass().getClassLoader());
// assert
assertThat(expectSnakeCaseHint).accepts(hints);
}
}

View File

@ -18,6 +18,8 @@
<modules> <modules>
<module>spring-cloud-config-server</module> <module>spring-cloud-config-server</module>
<module>spring-cloud-config-client</module> <module>spring-cloud-config-client</module>
<module>spring-cloud-config-overriding-properties-client</module>
<module>spring-cloud-config-overriding-properties-server</module>
</modules> </modules>
<dependencyManagement> <dependencyManagement>
@ -36,4 +38,4 @@
<spring-cloud-dependencies.version>2021.0.3</spring-cloud-dependencies.version> <spring-cloud-dependencies.version>2021.0.3</spring-cloud-dependencies.version>
</properties> </properties>
</project> </project>

View File

@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>spring-cloud-config-overriding-properties-client</artifactId>
<name>spring-cloud-config-overriding-properties-client</name>
<parent>
<groupId>com.baeldung.spring.cloud</groupId>
<artifactId>spring-cloud-config</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,14 @@
package com.baeldung.spring.cloud.config.overridingproperties;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Client {
public static void main(String[] args) {
SpringApplication.run(Client.class, args);
}
}

View File

@ -0,0 +1,33 @@
package com.baeldung.spring.cloud.config.overridingproperties;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
@Value("${hello}")
private String hello;
@Value("${welcome}")
private String welcome;
@Value("${shared-property}")
private String shared;
@GetMapping("hello")
public String hello() {
return this.hello;
}
@GetMapping("welcome")
public String welcome() {
return this.welcome;
}
@GetMapping("shared")
public String shared() {
return this.shared;
}
}

View File

@ -0,0 +1,3 @@
spring.cloud.config.name=baeldung
spring.config.import=optional:configserver:http://localhost:8081
app.hello=Hello, overriden local property!

View File

@ -0,0 +1,15 @@
package com.baeldung.spring.cloud.config.client;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit.jupiter.SpringExtension;
@ExtendWith(SpringExtension.class)
@SpringBootTest
public class SpringContextLiveTest {
@Test
public void contextLoads() {
}
}

View File

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>spring-cloud-config-overriding-properties-server</artifactId>
<name>spring-cloud-config-overriding-properties-server</name>
<parent>
<groupId>com.baeldung.spring.cloud</groupId>
<artifactId>spring-cloud-config</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,14 @@
package com.baeldung.spring.cloud.config.overridingproperties;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.config.server.EnableConfigServer;
@SpringBootApplication
@EnableConfigServer
public class ConfigServer {
public static void main(String[] args) {
SpringApplication.run(ConfigServer.class, args);
}
}

View File

@ -0,0 +1,3 @@
server.port=8081
spring.cloud.config.server.native.search-locations=classpath:/config
#spring.cloud.config.server.overrides.hello=Hello Jane Doe - application.properties!

View File

@ -0,0 +1 @@
shared-property=This property is shared accross all client applications

View File

@ -0,0 +1,2 @@
hello=${app.hello:Hello Jane Doe!}
welcome=Welcome Jane Doe!

View File

@ -0,0 +1,19 @@
package com.baeldung.spring.cloud.config.server;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import com.baeldung.spring.cloud.config.overridingproperties.ConfigServer;
@ExtendWith(SpringExtension.class)
@SpringBootTest(classes = ConfigServer.class)
@ActiveProfiles("native")
public class SpringContextTest {
@Test
public void whenSpringContextIsBootstrapped_thenNoExceptions() {
}
}

View File

@ -0,0 +1 @@
spring.cloud.config.server.native.search-locations=classpath:/config

View File

@ -111,12 +111,12 @@
</profiles> </profiles>
<properties> <properties>
<spring-boot.version>2.5.1</spring-boot.version> <spring-boot.version>2.7.1</spring-boot.version>
<spring-native.version>0.10.0</spring-native.version> <spring-native.version>0.12.1</spring-native.version>
<native-maven-plugin.version>0.9.0</native-maven-plugin.version> <native-maven-plugin.version>0.9.17</native-maven-plugin.version>
<java.version>1.8</java.version> <java.version>1.8</java.version>
<maven.compiler.target>1.8</maven.compiler.target> <maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.source>1.8</maven.compiler.source>
</properties> </properties>
</project> </project>

View File

@ -70,12 +70,12 @@
<properties> <properties>
<builder>paketobuildpacks/builder:tiny</builder> <builder>paketobuildpacks/builder:tiny</builder>
<spring-boot.version>2.5.1</spring-boot.version> <spring-boot.version>2.7.1</spring-boot.version>
<spring-native.version>0.10.0</spring-native.version> <spring-native.version>0.12.1</spring-native.version>
<java.version>1.8</java.version> <java.version>1.8</java.version>
<maven.compiler.target>1.8</maven.compiler.target> <maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.source>1.8</maven.compiler.source>
<log4j2.version>2.17.1</log4j2.version> <log4j2.version>2.17.1</log4j2.version>
</properties> </properties>
</project> </project>

View File

@ -1,26 +1,26 @@
package com.baeldung.clearsitedata; package com.baeldung.clearsitedata;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
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.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.authentication.logout.HeaderWriterLogoutHandler;
import org.springframework.security.web.header.writers.ClearSiteDataHeaderWriter;
import static org.springframework.security.web.header.writers.ClearSiteDataHeaderWriter.Directive.CACHE; import static org.springframework.security.web.header.writers.ClearSiteDataHeaderWriter.Directive.CACHE;
import static org.springframework.security.web.header.writers.ClearSiteDataHeaderWriter.Directive.COOKIES; import static org.springframework.security.web.header.writers.ClearSiteDataHeaderWriter.Directive.COOKIES;
import static org.springframework.security.web.header.writers.ClearSiteDataHeaderWriter.Directive.STORAGE; import static org.springframework.security.web.header.writers.ClearSiteDataHeaderWriter.Directive.STORAGE;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
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 org.springframework.security.web.authentication.logout.HeaderWriterLogoutHandler;
import org.springframework.security.web.header.writers.ClearSiteDataHeaderWriter;
@Configuration @Configuration
@EnableWebSecurity @EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true) @EnableGlobalMethodSecurity(prePostEnabled = true)
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter { public class SpringSecurityConfig {
@Override
protected void configure(HttpSecurity http) throws Exception {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.csrf() http.csrf()
.disable() .disable()
.formLogin() .formLogin()
@ -28,8 +28,9 @@ public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
.loginProcessingUrl("/perform_login") .loginProcessingUrl("/perform_login")
.defaultSuccessUrl("/homepage.html", true) .defaultSuccessUrl("/homepage.html", true)
.and() .and()
.logout().logoutUrl("/baeldung/logout") .logout()
.addLogoutHandler(new HeaderWriterLogoutHandler( .logoutUrl("/baeldung/logout")
new ClearSiteDataHeaderWriter(CACHE, COOKIES, STORAGE))); .addLogoutHandler(new HeaderWriterLogoutHandler(new ClearSiteDataHeaderWriter(CACHE, COOKIES, STORAGE)));
return http.build();
} }
} }

View File

@ -2,12 +2,14 @@ package com.baeldung.session.security.config;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler; import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.session.HttpSessionEventPublisher; import org.springframework.security.web.session.HttpSessionEventPublisher;
@ -15,50 +17,56 @@ import com.baeldung.security.MySimpleUrlAuthenticationSuccessHandler;
@Configuration @Configuration
// @ImportResource({ "classpath:webSecurityConfig.xml" }) // @ImportResource({ "classpath:webSecurityConfig.xml" })
public class SecSecurityConfig extends WebSecurityConfigurerAdapter { public class SecSecurityConfig {
public SecSecurityConfig() { @Bean
super(); public InMemoryUserDetailsManager userDetailsService() {
UserDetails user1 = User.withUsername("user1")
.password(passwordEncoder().encode("user1Pass"))
.roles("USER")
.build();
UserDetails admin1 = User.withUsername("admin1")
.password(passwordEncoder().encode("admin1Pass"))
.roles("ADMIN")
.build();
return new InMemoryUserDetailsManager(user1, admin1);
} }
@Override @Bean
protected void configure(final AuthenticationManagerBuilder auth) throws Exception { public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
// @formatter:off http.csrf()
auth.inMemoryAuthentication() .disable()
.withUser("user1").password(passwordEncoder().encode("user1Pass")).roles("USER") .authorizeRequests()
.and() .antMatchers("/anonymous*")
.withUser("admin1").password(passwordEncoder().encode("admin1Pass")).roles("ADMIN"); .anonymous()
// @formatter:on .antMatchers("/login*", "/invalidSession*", "/sessionExpired*", "/foo/**")
} .permitAll()
.anyRequest()
@Override .authenticated()
protected void configure(final HttpSecurity http) throws Exception { .and()
// @formatter:off .formLogin()
http .loginPage("/login.html")
.csrf().disable() .loginProcessingUrl("/login")
.authorizeRequests() .successHandler(successHandler())
.antMatchers("/anonymous*").anonymous() .failureUrl("/login.html?error=true")
.antMatchers("/login*","/invalidSession*", "/sessionExpired*", "/foo/**").permitAll() .and()
.anyRequest().authenticated() .logout()
.and() .deleteCookies("JSESSIONID")
.formLogin() .and()
.loginPage("/login.html") .rememberMe()
.loginProcessingUrl("/login") .key("uniqueAndSecret")
.successHandler(successHandler()) .tokenValiditySeconds(86400)
.failureUrl("/login.html?error=true") .and()
.and() .sessionManagement()
.logout().deleteCookies("JSESSIONID") .sessionFixation()
.and() .migrateSession()
.rememberMe().key("uniqueAndSecret").tokenValiditySeconds(86400) .sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
.and() .invalidSessionUrl("/invalidSession.html")
.sessionManagement() .maximumSessions(2)
.sessionFixation().migrateSession() .expiredUrl("/sessionExpired.html");
.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED) return http.build();
.invalidSessionUrl("/invalidSession.html")
.maximumSessions(2)
.expiredUrl("/sessionExpired.html");
// @formatter:on
} }
private AuthenticationSuccessHandler successHandler() { private AuthenticationSuccessHandler successHandler() {

5
tablesaw/README.md Normal file
View File

@ -0,0 +1,5 @@
This module contains tutorials related to the tablesaw java library.
### Relevant Articles:

41
tablesaw/pom.xml Normal file
View File

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>tablesaw</artifactId>
<parent>
<artifactId>parent-modules</artifactId>
<groupId>com.baeldung</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<dependencies>
<!-- TABLESAW -->
<dependency>
<groupId>tech.tablesaw</groupId>
<artifactId>tablesaw-core</artifactId>
<version>${tablesaw.version}</version>
</dependency>
</dependencies>
<properties>
<tablesaw.version>0.43.1</tablesaw.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<source>17</source>
<target>17</target>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,146 @@
package com.baeldung.tablesaw;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import tech.tablesaw.api.DateColumn;
import tech.tablesaw.api.DoubleColumn;
import tech.tablesaw.api.StringColumn;
import tech.tablesaw.api.Table;
import tech.tablesaw.api.TimeColumn;
import tech.tablesaw.io.csv.CsvReadOptions;
import tech.tablesaw.selection.Selection;
import java.io.File;
import java.net.URL;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.assertj.core.api.Assertions.assertThatNoException;
import static tech.tablesaw.aggregate.AggregateFunctions.max;
import static tech.tablesaw.aggregate.AggregateFunctions.mean;
import static tech.tablesaw.aggregate.AggregateFunctions.min;
import static tech.tablesaw.aggregate.AggregateFunctions.stdDev;
class CSVUnitTest {
private static Table table;
@BeforeEach
void setup() {
URL resource = CSVUnitTest.class.getClassLoader().getResource("avocado.csv");
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
Path filePath = Paths.get(resource.getPath());
File file = filePath.toFile();
CsvReadOptions csvReadOptions =
CsvReadOptions.builder(file)
.separator(',')
.header(true)
.dateFormat(formatter)
.build();
table = Table.read().usingOptions(csvReadOptions);
}
@Test
void shouldReturnTheShapeStringOnAvocadoDataSet() {
assertThat(table.shape()).isEqualTo("avocado.csv: 18249 rows X 14 cols");
}
@Test
void shouldOrderTheTableByDateInAscendingOrder() {
Table ascendingDateSortedTable = table.sortAscendingOn("Date");
assertThat(ascendingDateSortedTable.dateColumn("Date").get(0)).isEqualTo(LocalDate.parse("2015-01-04"));
}
@Test
void shouldOrderTheTableByDateInDescendingOrder() {
Table descendingDateSortedTable = table.sortDescendingOn("Date");
assertThat(descendingDateSortedTable.dateColumn("Date").get(0)).isEqualTo(LocalDate.parse("2018-03-25"));
}
@Test
void shouldOrderTheTableByYearAndAveragePriceInAscendingOrder() {
Table ascendingYearAndAveragePriceSortedTable = table.sortOn("year", "-AveragePrice");
assertThat(ascendingYearAndAveragePriceSortedTable.intColumn("year").get(0)).isEqualTo(2015);
assertThat(ascendingYearAndAveragePriceSortedTable.numberColumn("AveragePrice").get(0)).isEqualTo(2.79);
}
@Test
void shouldRemoveTheValueWhenSettingAsMissing() {
DoubleColumn averagePrice = table.doubleColumn("AveragePrice").setMissing(0);
assertThat(averagePrice.get(0)).isNull();
}
@Test
void shouldAppendDataToTheColumn() {
DoubleColumn averagePrice = table.doubleColumn("AveragePrice");
averagePrice.append(1.123);
assertThat(averagePrice.get(averagePrice.size() - 1)).isEqualTo(1.123);
}
@Test
void shouldAppendDataToAveragePriceColumn() {
DoubleColumn averagePrice2 = table.doubleColumn("AveragePrice").copy();
averagePrice2.setName("AveragePrice2");
averagePrice2.append(1.123);
assertThatExceptionOfType(IllegalArgumentException.class).isThrownBy(() -> table.addColumns(averagePrice2));
}
@Test
void shouldReturnTheTableContainingDataFrom2017andAveragePriceIsGreaterThan2Only() {
DateColumn dateTable = table.dateColumn("Date");
DoubleColumn averagePrice = table.doubleColumn("AveragePrice");
Selection selection = dateTable.isInYear(2017).and(averagePrice.isGreaterThan(2D));
Table table2017 = table.where(selection);
assertThat(table2017.intColumn("year")).containsOnly(2017);
assertThat(table2017.doubleColumn("AveragePrice")).allMatch(avrgPrice -> avrgPrice > 2D);
}
@Test
void shouldPrintToStandardOutputStatisticsOfAveragePriceByYearData() {
Table summary = table.summarize("AveragePrice", max, min, mean, stdDev).by("year");
System.out.println(summary.print());
Assertions.assertTrue(true);
}
@Test
void shouldThrowIllegalArgumentExceptionWhenCreatingTableWithDifferentSizeColumns() {
StringColumn type = StringColumn.create("type");
StringColumn region = StringColumn.create("region");
type.addAll(List.of("Country", "City"));
region.append("USA");
assertThatExceptionOfType(IllegalArgumentException.class).isThrownBy(() -> Table.create(type, region));
}
@Test
void shouldNotThrowIllegalArgumentExceptionWhenCreatingTableWithDifferentSameSizeColumns() {
StringColumn type = StringColumn.create("type");
StringColumn region = StringColumn.create("region");
type.addAll(List.of("Country", "City"));
region.append("USA");
region.appendMissing();
assertThatNoException().isThrownBy(() -> Table.create(type, region));
}
@Test
void shouldAddColumnToTable() {
TimeColumn time = TimeColumn.create("time");
Table table = Table.create("test");
table.addColumns(time);
assertThat(table.columnNames()).contains("time");
}
@Test
void shouldBeEqualTwoValuesFromDifferentRowsOnTheTypeColumn() {
StringColumn type = table.stringColumn("type");
List<String> conventional = type.where(type.isEqualTo("conventional")).asList().stream()
.limit(2)
.toList();
assertThat(conventional.get(0)).isSameAs(conventional.get(1));
}
}