Merge branch 'eugenp:master' into master
This commit is contained in:
commit
36a88aebe9
@ -2,4 +2,5 @@
|
||||
|
||||
- [Algorithm to Identify and Validate a Credit Card Number](https://www.baeldung.com/java-validate-cc-number)
|
||||
- [Find the N Most Frequent Elements in a Java Array](https://www.baeldung.com/java-n-most-frequent-elements-array)
|
||||
- [Getting Pixel Array From Image in Java](https://www.baeldung.com/java-getting-pixel-array-from-image)
|
||||
- More articles: [[<-- prev]](/algorithms-miscellaneous-6)
|
||||
|
@ -0,0 +1,88 @@
|
||||
package com.baeldung.kafka.headers;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.apache.kafka.clients.consumer.ConsumerConfig;
|
||||
import org.apache.kafka.clients.consumer.ConsumerRecord;
|
||||
import org.apache.kafka.clients.consumer.ConsumerRecords;
|
||||
import org.apache.kafka.clients.consumer.KafkaConsumer;
|
||||
import org.apache.kafka.clients.producer.KafkaProducer;
|
||||
import org.apache.kafka.clients.producer.ProducerConfig;
|
||||
import org.apache.kafka.clients.producer.ProducerRecord;
|
||||
import org.apache.kafka.common.header.Header;
|
||||
import org.apache.kafka.common.header.Headers;
|
||||
import org.apache.kafka.common.header.internals.RecordHeader;
|
||||
import org.apache.kafka.common.serialization.StringDeserializer;
|
||||
import org.apache.kafka.common.serialization.StringSerializer;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class KafkaMessageHeaders {
|
||||
|
||||
private static Logger logger = LoggerFactory.getLogger(KafkaMessageHeaders.class);
|
||||
|
||||
private static String TOPIC = "baeldung";
|
||||
private static String MESSAGE_KEY = "message";
|
||||
private static String MESSAGE_VALUE = "Hello World";
|
||||
private static String HEADER_KEY = "website";
|
||||
private static String HEADER_VALUE = "baeldung.com";
|
||||
|
||||
private static KafkaProducer<String, String> producer;
|
||||
private static KafkaConsumer<String, String> consumer;
|
||||
|
||||
public static void main(String[] args) {
|
||||
setup();
|
||||
|
||||
publishMessageWithCustomHeaders();
|
||||
|
||||
consumeMessageWithCustomHeaders();
|
||||
}
|
||||
|
||||
private static void consumeMessageWithCustomHeaders() {
|
||||
consumer.subscribe(Arrays.asList(TOPIC));
|
||||
|
||||
ConsumerRecords<String, String> records = consumer.poll(Duration.ofMinutes(1));
|
||||
for (ConsumerRecord<String, String> record : records) {
|
||||
logger.info(record.key());
|
||||
logger.info(record.value());
|
||||
|
||||
Headers headers = record.headers();
|
||||
for (Header header : headers) {
|
||||
logger.info(header.key());
|
||||
logger.info(new String(header.value()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void publishMessageWithCustomHeaders() {
|
||||
List<Header> headers = new ArrayList<>();
|
||||
headers.add(new RecordHeader(HEADER_KEY, HEADER_VALUE.getBytes()));
|
||||
|
||||
ProducerRecord<String, String> record1 = new ProducerRecord<>(TOPIC, null, MESSAGE_KEY, MESSAGE_VALUE, headers);
|
||||
producer.send(record1);
|
||||
|
||||
ProducerRecord<String, String> record2 = new ProducerRecord<>(TOPIC, null, System.currentTimeMillis(), MESSAGE_KEY, MESSAGE_VALUE, headers);
|
||||
producer.send(record2);
|
||||
}
|
||||
|
||||
private static void setup() {
|
||||
Properties producerProperties = new Properties();
|
||||
producerProperties.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092");
|
||||
producerProperties.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName());
|
||||
producerProperties.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName());
|
||||
|
||||
Properties consumerProperties = new Properties();
|
||||
consumerProperties.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092");
|
||||
consumerProperties.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName());
|
||||
consumerProperties.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName());
|
||||
consumerProperties.put(ConsumerConfig.GROUP_ID_CONFIG, "ConsumerGroup1");
|
||||
|
||||
producer = new KafkaProducer<>(producerProperties);
|
||||
consumer = new KafkaConsumer<>(consumerProperties);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,104 @@
|
||||
package com.baeldung.kafka.headers;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
import org.apache.kafka.clients.consumer.ConsumerConfig;
|
||||
import org.apache.kafka.clients.consumer.ConsumerRecord;
|
||||
import org.apache.kafka.clients.consumer.ConsumerRecords;
|
||||
import org.apache.kafka.clients.consumer.KafkaConsumer;
|
||||
import org.apache.kafka.clients.producer.KafkaProducer;
|
||||
import org.apache.kafka.clients.producer.ProducerConfig;
|
||||
import org.apache.kafka.clients.producer.ProducerRecord;
|
||||
import org.apache.kafka.clients.producer.RecordMetadata;
|
||||
import org.apache.kafka.common.header.Header;
|
||||
import org.apache.kafka.common.header.Headers;
|
||||
import org.apache.kafka.common.header.internals.RecordHeader;
|
||||
import org.apache.kafka.common.serialization.StringDeserializer;
|
||||
import org.apache.kafka.common.serialization.StringSerializer;
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.testcontainers.containers.KafkaContainer;
|
||||
import org.testcontainers.junit.jupiter.Container;
|
||||
import org.testcontainers.junit.jupiter.Testcontainers;
|
||||
import org.testcontainers.utility.DockerImageName;
|
||||
|
||||
// This live test needs a Docker Daemon running so that a kafka container can be created
|
||||
|
||||
@Testcontainers
|
||||
public class KafkaMessageHeadersLiveTest {
|
||||
|
||||
private static String TOPIC = "baeldung";
|
||||
private static String MESSAGE_KEY = "message";
|
||||
private static String MESSAGE_VALUE = "Hello World";
|
||||
private static String HEADER_KEY = "website";
|
||||
private static String HEADER_VALUE = "baeldung.com";
|
||||
|
||||
private static KafkaProducer<String, String> producer;
|
||||
private static KafkaConsumer<String, String> consumer;
|
||||
|
||||
@Container
|
||||
private static final KafkaContainer KAFKA_CONTAINER = new KafkaContainer(DockerImageName.parse("confluentinc/cp-kafka:latest"));
|
||||
|
||||
@BeforeAll
|
||||
static void setup() {
|
||||
KAFKA_CONTAINER.addExposedPort(9092);
|
||||
|
||||
Properties producerProperties = new Properties();
|
||||
producerProperties.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, KAFKA_CONTAINER.getBootstrapServers());
|
||||
producerProperties.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName());
|
||||
producerProperties.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName());
|
||||
|
||||
Properties consumerProperties = new Properties();
|
||||
consumerProperties.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, KAFKA_CONTAINER.getBootstrapServers());
|
||||
consumerProperties.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName());
|
||||
consumerProperties.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName());
|
||||
consumerProperties.put(ConsumerConfig.GROUP_ID_CONFIG, "ConsumerGroup1");
|
||||
|
||||
producer = new KafkaProducer<>(producerProperties);
|
||||
consumer = new KafkaConsumer<>(consumerProperties);
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
static void destroy() {
|
||||
KAFKA_CONTAINER.stop();
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenAMessageWithCustomHeaders_whenPublishedToKafkaAndConsumed_thenCheckForCustomHeaders() throws ExecutionException, InterruptedException {
|
||||
List<Header> headers = new ArrayList<>();
|
||||
headers.add(new RecordHeader(HEADER_KEY, HEADER_VALUE.getBytes()));
|
||||
|
||||
ProducerRecord<String, String> record1 = new ProducerRecord<>(TOPIC, null, MESSAGE_KEY, MESSAGE_VALUE, headers);
|
||||
Future<RecordMetadata> future = producer.send(record1);
|
||||
|
||||
RecordMetadata metadata = future.get();
|
||||
|
||||
assertNotNull(metadata);
|
||||
|
||||
consumer.subscribe(Arrays.asList(TOPIC));
|
||||
|
||||
ConsumerRecords<String, String> records = consumer.poll(Duration.ofMinutes(1));
|
||||
for (ConsumerRecord<String, String> record : records) {
|
||||
assertEquals(MESSAGE_KEY, record.key());
|
||||
assertEquals(MESSAGE_VALUE, record.value());
|
||||
|
||||
Headers consumedHeaders = record.headers();
|
||||
assertNotNull(consumedHeaders);
|
||||
|
||||
for (Header header : consumedHeaders) {
|
||||
assertEquals(HEADER_KEY, header.key());
|
||||
assertEquals(HEADER_VALUE, new String(header.value()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,2 +1,2 @@
|
||||
## Relevant Articles
|
||||
- TBD
|
||||
- [Scoped Values in Java 20](https://www.baeldung.com/java-20-scoped-values)
|
||||
|
@ -11,3 +11,4 @@ This module contains articles about Java array fundamentals. They assume no prev
|
||||
- [Removing the First Element of an Array](https://www.baeldung.com/java-array-remove-first-element)
|
||||
- [Extending an Array’s Length](https://www.baeldung.com/java-array-add-element-at-the-end)
|
||||
- [Initializing a Boolean Array in Java](https://www.baeldung.com/java-initializing-boolean-array)
|
||||
- [Find the Index of an Element in a Java Array](https://www.baeldung.com/java-array-find-index)
|
||||
|
@ -0,0 +1,39 @@
|
||||
package com.baeldung.array.compare;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class CompareByteArraysUnitTest {
|
||||
private final static String INPUT = "I am a magic string.";
|
||||
private final static byte[] ARRAY1 = INPUT.getBytes();
|
||||
private final static byte[] ARRAY2 = INPUT.getBytes();
|
||||
|
||||
@Test
|
||||
void whenUsingEqualsSign_thenTwoArraysAreNotEqual() {
|
||||
assertFalse(ARRAY1 == ARRAY2);
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenUsingEquals_thenTwoArraysAreNotEqual() {
|
||||
assertFalse(ARRAY1.equals(ARRAY2));
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenUsingArrayEquals_thenTwoArraysAreEqual() {
|
||||
assertTrue(Arrays.equals(ARRAY1, ARRAY2));
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenComparingStringArrays_thenGetExpectedResult() {
|
||||
String[] strArray1 = new String[] { "Java", "is", "great" };
|
||||
String[] strArray2 = new String[] { "Java", "is", "great" };
|
||||
|
||||
assertFalse(strArray1 == strArray2);
|
||||
assertFalse(strArray1.equals(strArray2));
|
||||
assertTrue(Arrays.equals(strArray1, strArray2));
|
||||
}
|
||||
}
|
@ -4,3 +4,4 @@ This module contains articles about Java Character Class
|
||||
|
||||
### Relevant Articles:
|
||||
- [Character#isAlphabetic vs. Character#isLetter](https://www.baeldung.com/java-character-isletter-isalphabetic)
|
||||
- [Difference Between Java’s “char” and “String”](https://www.baeldung.com/java-char-vs-string)
|
||||
|
@ -42,6 +42,10 @@ public class Car {
|
||||
this.engine = engine;
|
||||
}
|
||||
|
||||
public static String getCarsInformation(Car car) {
|
||||
return car.getName() + "-" + car.getEngine();
|
||||
}
|
||||
|
||||
public static void setNumberOfCars(int numberOfCars) {
|
||||
Car.numberOfCars = numberOfCars;
|
||||
}
|
||||
|
@ -0,0 +1,21 @@
|
||||
package com.baeldung.staticmethod;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.baeldung.staticmodifier.Car;
|
||||
|
||||
public class CallNonStaticMethodUnitTest {
|
||||
@AfterClass
|
||||
public static void setUpCarInstance() {
|
||||
Car.setNumberOfCars(0);
|
||||
}
|
||||
@Test
|
||||
public void whenCallingNonStaticMethodInStaticMethodWithInstanceClass_thenSuccess() {
|
||||
Car car = new Car("Jaguar", "V8");
|
||||
assertEquals("Jaguar-V8", Car.getCarsInformation(car));
|
||||
}
|
||||
|
||||
}
|
@ -2,9 +2,16 @@ package com.baeldung.staticmodifier;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Test;
|
||||
|
||||
public class CarUnitTest {
|
||||
|
||||
@AfterClass
|
||||
public static void setUpCarInstance() {
|
||||
Car.setNumberOfCars(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenNumberOfCarObjectsInitialized_thenStaticCounterIncreases() {
|
||||
new Car("Jaguar", "V8");
|
||||
|
@ -14,3 +14,4 @@ This module contains articles about performance of Java applications
|
||||
- [JMX Ports](https://www.baeldung.com/jmx-ports)
|
||||
- [Calling JMX MBean Method From a Shell Script](https://www.baeldung.com/jmx-mbean-shell-access)
|
||||
- [External Debugging With JMXTerm](https://www.baeldung.com/java-jmxterm-external-debugging)
|
||||
- [Create and Detect Memory Leaks in Java](https://www.baeldung.com/java-create-detect-memory-leaks)
|
||||
|
32
core-java-modules/core-java-records/pom.xml
Normal file
32
core-java-modules/core-java-records/pom.xml
Normal file
@ -0,0 +1,32 @@
|
||||
<?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">
|
||||
<parent>
|
||||
<artifactId>core-java-modules</artifactId>
|
||||
<groupId>com.baeldung.core-java-modules</groupId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>core-java-records</artifactId>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>16</source>
|
||||
<target>16</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>19</maven.compiler.source>
|
||||
<maven.compiler.target>19</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
</project>
|
@ -0,0 +1,26 @@
|
||||
package com.baeldung.equalshashcoderecords;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
record Movie(String name, Integer yearOfRelease, String distributor) {
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if (this == other) {
|
||||
return true;
|
||||
}
|
||||
if (other == null) {
|
||||
return false;
|
||||
}
|
||||
Movie movie = (Movie) other;
|
||||
if (movie.name.equals(this.name) && movie.yearOfRelease.equals(this.yearOfRelease)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(name, yearOfRelease);
|
||||
}
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
package com.baeldung.equalshashcoderecords;
|
||||
|
||||
public record Person(String firstName, String lastName, String SSN, String dateOfBirth) {
|
||||
};
|
||||
|
@ -0,0 +1,30 @@
|
||||
package com.baeldung.equalshashcoderecords;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotEquals;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class CustomRecordEqualsHashCode {
|
||||
@Test
|
||||
public void givenTwoRecords_whenDefaultEquals_thenCompareEquality() {
|
||||
Person robert = new Person("Robert", "Frost", "HDHDB223", "2000-01-02");
|
||||
Person mike = new Person("Mike", "Adams", "ABJDJ2883", "2001-01-02");
|
||||
assertNotEquals(robert, mike);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenTwoRecords_hashCodesShouldBeSame() {
|
||||
Person robert = new Person("Robert", "Frost", "HDHDB223", "2000-01-02");
|
||||
Person robertCopy = new Person("Robert", "Frost", "HDHDB223", "2000-01-02");
|
||||
assertEquals(robert.hashCode(), robertCopy.hashCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenTwoRecords_whenCustomImplementation_thenCompareEquality() {
|
||||
Movie movie1 = new Movie("The Batman", 2022, "WB");
|
||||
Movie movie2 = new Movie("The Batman", 2022, "Dreamworks");
|
||||
assertEquals(movie1, movie2);
|
||||
assertEquals(movie1.hashCode(), movie2.hashCode());
|
||||
}
|
||||
}
|
@ -8,3 +8,5 @@
|
||||
- [Convert String to String Array](https://www.baeldung.com/java-convert-string-to-string-array)
|
||||
- [String Interpolation in Java](https://www.baeldung.com/java-string-interpolation)
|
||||
- [Guide to Splitting a String by Whitespace in Java](https://www.baeldung.com/java-splitting-a-string-by-whitespace)
|
||||
- [Check if the First Letter of a String Is a Number](https://www.baeldung.com/java-check-if-string-starts-with-number)
|
||||
- [Print “” Quotes Around a String in Java](https://www.baeldung.com/java-string-print-quotes)
|
||||
|
@ -0,0 +1,43 @@
|
||||
package com.baeldung.delpunctuation;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotEquals;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class RemovePunctuationUnitTest {
|
||||
private static final String INPUT = "Its 1 W o r d (!@#$%^&*{}[];':\")<>,.";
|
||||
private static final String EXPECTED = "Its 1 W o r d ";
|
||||
|
||||
private static final String UNICODE_INPUT = "3 March März 三月 březen маршировать (!@#$%^&*{}[];':\")<>,.";
|
||||
private static final String UNICODE_EXPECTED = "3 March März 三月 březen маршировать ";
|
||||
|
||||
@Test
|
||||
void whenUsingCharClassRange_thenGetExceptedResult() {
|
||||
String result = INPUT.replaceAll("[^\\sa-zA-Z0-9]", "");
|
||||
assertEquals(EXPECTED, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenUsingPunctuationCharClass_thenGetExceptedResult() {
|
||||
String result = INPUT.replaceAll("\\p{Punct}", "");
|
||||
assertEquals(EXPECTED, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenInputContainsUnicodeChars_thenGetExceptedResult() {
|
||||
String result1 = UNICODE_INPUT.replaceAll("[^\\sa-zA-Z0-9]", "");
|
||||
assertNotEquals(UNICODE_EXPECTED, result1);
|
||||
|
||||
String actualResult1 = "3 March Mrz bezen ";
|
||||
assertEquals(actualResult1, result1);
|
||||
|
||||
|
||||
String result2 = UNICODE_INPUT.replaceAll("\\p{Punct}", "");
|
||||
assertEquals(UNICODE_EXPECTED, result2);
|
||||
|
||||
String result3 = UNICODE_INPUT.replaceAll("[^\\s\\p{L}0-9]", "");
|
||||
assertEquals(UNICODE_EXPECTED, result3);
|
||||
}
|
||||
|
||||
}
|
@ -141,6 +141,7 @@
|
||||
<module>core-java-uuid</module>
|
||||
<module>pre-jpms</module>
|
||||
<module>core-java-collections-maps-6</module>
|
||||
<module>core-java-records</module>
|
||||
</modules>
|
||||
|
||||
<dependencyManagement>
|
||||
|
@ -5,11 +5,11 @@ import io.github.jhipster.config.JHipsterProperties;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.Base64Utils;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Base64;
|
||||
|
||||
/**
|
||||
* Client talking to UAA's token endpoint to do different OAuth2 grants.
|
||||
@ -34,7 +34,7 @@ public class UaaTokenEndpointClient extends OAuth2TokenEndpointClientAdapter imp
|
||||
String clientId = getClientId();
|
||||
String clientSecret = getClientSecret();
|
||||
String authorization = clientId + ":" + clientSecret;
|
||||
return "Basic " + Base64Utils.encodeToString(authorization.getBytes(StandardCharsets.UTF_8));
|
||||
return "Basic " + Base64.getEncoder().encodeToString(authorization.getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -4,4 +4,5 @@ This module contains articles about Hibernate Mappings.
|
||||
|
||||
### Relevant articles
|
||||
|
||||
- [Hibernate Many to Many Annotation Tutorial](https://www.baeldung.com/hibernate-many-to-many)
|
||||
- [Hibernate Many to Many Annotation Tutorial](https://www.baeldung.com/hibernate-many-to-many)
|
||||
- [Boolean Converters in Hibernate 6](https://www.baeldung.com/java-hibernate-6-boolean-converters)
|
||||
|
@ -107,7 +107,7 @@
|
||||
<!-- <module>spring-jpa</module>
|
||||
<module>spring-jpa-2</module> FAILED -->
|
||||
<module>spring-jdbc</module>
|
||||
<module>spring-jooq</module>
|
||||
<!-- <module>spring-jooq</module>--> <!-- parent-boot-2 is its parent. -->
|
||||
<module>spring-mybatis</module>
|
||||
<module>spring-persistence-simple</module>
|
||||
</modules>
|
||||
|
@ -16,6 +16,21 @@
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.mongodb</groupId>
|
||||
<artifactId>mongodb-driver-sync</artifactId>
|
||||
<version>${mongodb-driver.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mongodb</groupId>
|
||||
<artifactId>mongodb-driver-core</artifactId>
|
||||
<version>${mongodb-driver.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mongodb</groupId>
|
||||
<artifactId>bson</artifactId>
|
||||
<version>${mongodb-driver.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
@ -23,6 +38,16 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-mongodb</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.mongodb</groupId>
|
||||
<artifactId>mongodb-driver-sync</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.mongodb</groupId>
|
||||
<artifactId>mongodb-driver-core</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mongodb</groupId>
|
||||
@ -37,7 +62,8 @@
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<mongodb-crypt.version>1.6.1</mongodb-crypt.version>
|
||||
<mongodb-crypt.version>1.7.3</mongodb-crypt.version>
|
||||
<mongodb-driver.version>4.9.1</mongodb-driver.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
|
@ -1,5 +1,7 @@
|
||||
package com.baeldung.boot.csfle.config;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import org.bson.BsonBinary;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
@ -17,7 +19,13 @@ public class EncryptionConfig {
|
||||
private String keyVaultAlias;
|
||||
|
||||
@Value("${com.baeldung.csfle.auto-decryption:false}")
|
||||
private Boolean autoDecryption;
|
||||
private boolean autoDecryption;
|
||||
|
||||
@Value("${com.baeldung.csfle.auto-encryption:false}")
|
||||
private boolean autoEncryption;
|
||||
|
||||
@Value("${com.baeldung.csfle.auto-encryption-lib:#{null}}")
|
||||
private File autoEncryptionLib;
|
||||
|
||||
private BsonBinary dataKeyId;
|
||||
|
||||
@ -41,7 +49,23 @@ public class EncryptionConfig {
|
||||
return masterKeyPath;
|
||||
}
|
||||
|
||||
public Boolean getAutoDecryption() {
|
||||
public boolean isAutoDecryption() {
|
||||
return autoDecryption;
|
||||
}
|
||||
|
||||
public boolean isAutoEncryption() {
|
||||
return autoEncryption;
|
||||
}
|
||||
|
||||
public File getAutoEncryptionLib() {
|
||||
return autoEncryptionLib;
|
||||
}
|
||||
|
||||
public String dataKeyIdUuid() {
|
||||
if (dataKeyId == null)
|
||||
throw new IllegalStateException("data key not initialized");
|
||||
|
||||
return dataKeyId.asUuid()
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
|
@ -1,14 +1,15 @@
|
||||
package com.baeldung.boot.csfle.config;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.bson.BsonBinary;
|
||||
import org.bson.BsonDocument;
|
||||
import org.bson.Document;
|
||||
import org.bson.conversions.Bson;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
@ -51,14 +52,10 @@ public class MongoClientConfig extends AbstractMongoClientConfiguration {
|
||||
@Bean
|
||||
@Override
|
||||
public MongoClient mongoClient() {
|
||||
MongoClient client;
|
||||
try {
|
||||
client = MongoClients.create(clientSettings());
|
||||
|
||||
ClientEncryption encryption = clientEncryption();
|
||||
encryptionConfig.setDataKeyId(createOrRetrieveDataKey(client, encryption));
|
||||
|
||||
return client;
|
||||
encryptionConfig.setDataKeyId(createOrRetrieveDataKey(encryption));
|
||||
return MongoClients.create(clientSettings());
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException("unable to create client", e);
|
||||
}
|
||||
@ -77,19 +74,10 @@ public class MongoClientConfig extends AbstractMongoClientConfiguration {
|
||||
return ClientEncryptions.create(encryptionSettings);
|
||||
}
|
||||
|
||||
private BsonBinary createOrRetrieveDataKey(MongoClient client, ClientEncryption encryption) {
|
||||
MongoNamespace namespace = new MongoNamespace(encryptionConfig.getKeyVaultNamespace());
|
||||
MongoCollection<Document> keyVault = client.getDatabase(namespace.getDatabaseName())
|
||||
.getCollection(namespace.getCollectionName());
|
||||
|
||||
Bson query = Filters.in("keyAltNames", encryptionConfig.getKeyVaultAlias());
|
||||
BsonDocument key = keyVault.withDocumentClass(BsonDocument.class)
|
||||
.find(query)
|
||||
.first();
|
||||
|
||||
private BsonBinary createOrRetrieveDataKey(ClientEncryption encryption) {
|
||||
BsonDocument key = encryption.getKeyByAltName(encryptionConfig.getKeyVaultAlias());
|
||||
if (key == null) {
|
||||
keyVault.createIndex(Indexes.ascending("keyAltNames"), new IndexOptions().unique(true)
|
||||
.partialFilterExpression(Filters.exists("keyAltNames")));
|
||||
createKeyUniqueIndex();
|
||||
|
||||
DataKeyOptions options = new DataKeyOptions();
|
||||
options.keyAltNames(Arrays.asList(encryptionConfig.getKeyVaultAlias()));
|
||||
@ -99,16 +87,68 @@ public class MongoClientConfig extends AbstractMongoClientConfiguration {
|
||||
}
|
||||
}
|
||||
|
||||
private void createKeyUniqueIndex() {
|
||||
try (MongoClient client = MongoClients.create(MongoClientSettings.builder()
|
||||
.applyConnectionString(new ConnectionString(uri))
|
||||
.build())) {
|
||||
MongoNamespace namespace = new MongoNamespace(encryptionConfig.getKeyVaultNamespace());
|
||||
MongoCollection<Document> keyVault = client.getDatabase(namespace.getDatabaseName())
|
||||
.getCollection(namespace.getCollectionName());
|
||||
|
||||
keyVault.createIndex(Indexes.ascending("keyAltNames"), new IndexOptions().unique(true)
|
||||
.partialFilterExpression(Filters.exists("keyAltNames")));
|
||||
}
|
||||
}
|
||||
|
||||
private MongoClientSettings clientSettings() throws FileNotFoundException, IOException {
|
||||
Builder settings = MongoClientSettings.builder()
|
||||
.applyConnectionString(new ConnectionString(uri));
|
||||
|
||||
if (encryptionConfig.getAutoDecryption()) {
|
||||
settings.autoEncryptionSettings(AutoEncryptionSettings.builder()
|
||||
if (encryptionConfig.isAutoDecryption()) {
|
||||
AutoEncryptionSettings.Builder builder = AutoEncryptionSettings.builder()
|
||||
.keyVaultNamespace(encryptionConfig.getKeyVaultNamespace())
|
||||
.kmsProviders(LocalKmsUtils.providersMap(encryptionConfig.getMasterKeyPath()))
|
||||
.bypassAutoEncryption(true)
|
||||
.build());
|
||||
.kmsProviders(LocalKmsUtils.providersMap(encryptionConfig.getMasterKeyPath()));
|
||||
|
||||
if (encryptionConfig.isAutoEncryption() && encryptionConfig.getDataKeyId() != null) {
|
||||
File autoEncryptionLib = encryptionConfig.getAutoEncryptionLib();
|
||||
if (!autoEncryptionLib.isFile()) {
|
||||
throw new IllegalArgumentException("encryption lib must be an existing file");
|
||||
}
|
||||
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("cryptSharedLibRequired", true);
|
||||
map.put("cryptSharedLibPath", autoEncryptionLib.toString());
|
||||
builder.extraOptions(map);
|
||||
|
||||
String keyUuid = encryptionConfig.dataKeyIdUuid();
|
||||
HashMap<String, BsonDocument> schemaMap = new HashMap<>();
|
||||
schemaMap.put(getDatabaseName() + ".citizens",
|
||||
BsonDocument.parse("{"
|
||||
+ " bsonType: \"object\","
|
||||
+ " encryptMetadata: {"
|
||||
+ " keyId: [UUID(\"" + keyUuid + "\")]"
|
||||
+ " },"
|
||||
+ " properties: {"
|
||||
+ " email: {"
|
||||
+ " encrypt: {"
|
||||
+ " bsonType: \"string\","
|
||||
+ " algorithm: \"AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic\""
|
||||
+ " }"
|
||||
+ " },"
|
||||
+ " birthYear: {"
|
||||
+ " encrypt: {"
|
||||
+ " bsonType: \"int\","
|
||||
+ " algorithm: \"AEAD_AES_256_CBC_HMAC_SHA_512-Random\""
|
||||
+ " }"
|
||||
+ " }"
|
||||
+ " }"
|
||||
+ "}"));
|
||||
builder.schemaMap(schemaMap);
|
||||
} else {
|
||||
builder.bypassAutoEncryption(true);
|
||||
}
|
||||
|
||||
settings.autoEncryptionSettings(builder.build());
|
||||
}
|
||||
|
||||
return settings.build();
|
||||
|
@ -35,16 +35,20 @@ public class CitizenService {
|
||||
@Autowired
|
||||
private ClientEncryption clientEncryption;
|
||||
|
||||
public EncryptedCitizen save(Citizen citizen) {
|
||||
EncryptedCitizen encryptedCitizen = new EncryptedCitizen(citizen);
|
||||
encryptedCitizen.setEmail(encrypt(citizen.getEmail(), DETERMINISTIC_ALGORITHM));
|
||||
encryptedCitizen.setBirthYear(encrypt(citizen.getBirthYear(), RANDOM_ALGORITHM));
|
||||
public Object save(Citizen citizen) {
|
||||
if (encryptionConfig.isAutoEncryption()) {
|
||||
return mongo.save(citizen);
|
||||
} else {
|
||||
EncryptedCitizen encryptedCitizen = new EncryptedCitizen(citizen);
|
||||
encryptedCitizen.setEmail(encrypt(citizen.getEmail(), DETERMINISTIC_ALGORITHM));
|
||||
encryptedCitizen.setBirthYear(encrypt(citizen.getBirthYear(), RANDOM_ALGORITHM));
|
||||
|
||||
return mongo.save(encryptedCitizen);
|
||||
return mongo.save(encryptedCitizen);
|
||||
}
|
||||
}
|
||||
|
||||
public List<Citizen> findAll() {
|
||||
if (!encryptionConfig.getAutoDecryption()) {
|
||||
if (!encryptionConfig.isAutoDecryption()) {
|
||||
List<EncryptedCitizen> allEncrypted = mongo.findAll(EncryptedCitizen.class);
|
||||
|
||||
return allEncrypted.stream()
|
||||
@ -56,13 +60,20 @@ public class CitizenService {
|
||||
}
|
||||
|
||||
public Citizen findByEmail(String email) {
|
||||
Query byEmail = new Query(Criteria.where("email")
|
||||
.is(encrypt(email, DETERMINISTIC_ALGORITHM)));
|
||||
if (!encryptionConfig.getAutoDecryption()) {
|
||||
Criteria emailCriteria = Criteria.where("email");
|
||||
if (encryptionConfig.isAutoEncryption()) {
|
||||
emailCriteria.is(email);
|
||||
} else {
|
||||
emailCriteria
|
||||
.is(encrypt(email, DETERMINISTIC_ALGORITHM));
|
||||
}
|
||||
|
||||
Query byEmail = new Query(emailCriteria);
|
||||
if (encryptionConfig.isAutoDecryption()) {
|
||||
return mongo.findOne(byEmail, Citizen.class);
|
||||
} else {
|
||||
EncryptedCitizen encryptedCitizen = mongo.findOne(byEmail, EncryptedCitizen.class);
|
||||
return decrypt(encryptedCitizen);
|
||||
} else {
|
||||
return mongo.findOne(byEmail, Citizen.class);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,6 @@ import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.baeldung.boot.csfle.data.Citizen;
|
||||
import com.baeldung.boot.csfle.data.EncryptedCitizen;
|
||||
import com.baeldung.boot.csfle.service.CitizenService;
|
||||
|
||||
@RestController
|
||||
@ -32,7 +31,7 @@ public class CitizenController {
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
public EncryptedCitizen post(@RequestBody Citizen citizen) {
|
||||
public Object post(@RequestBody Citizen citizen) {
|
||||
return service.save(citizen);
|
||||
}
|
||||
}
|
||||
|
@ -38,10 +38,14 @@ public class CitizenServiceLiveTest {
|
||||
citizen.setName("Foo");
|
||||
citizen.setEmail("foo@citizen.com");
|
||||
|
||||
Binary encryptedEmail = service.encrypt(citizen.getEmail(), CitizenService.DETERMINISTIC_ALGORITHM);
|
||||
Object saved = service.save(citizen);
|
||||
if (saved instanceof EncryptedCitizen) {
|
||||
Binary encryptedEmail = service.encrypt(citizen.getEmail(), CitizenService.DETERMINISTIC_ALGORITHM);
|
||||
|
||||
EncryptedCitizen saved = service.save(citizen);
|
||||
assertEquals(encryptedEmail, saved.getEmail());
|
||||
assertEquals(encryptedEmail, ((EncryptedCitizen) saved).getEmail());
|
||||
} else {
|
||||
assertEquals(citizen.getEmail(), ((Citizen) saved).getEmail());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -1,10 +1,10 @@
|
||||
spring.mongodb.embedded.version=4.4.9
|
||||
|
||||
spring.data.mongodb.uri=changeit
|
||||
spring.data.mongodb.database=changeit
|
||||
#spring.data.mongodb.uri=changeit
|
||||
#spring.data.mongodb.database=changeit
|
||||
|
||||
com.baeldung.csfle.kms-provider=local
|
||||
com.baeldung.csfle.key-vault.namespace=encryption._keyVault
|
||||
com.baeldung.csfle.key-vault.alias=master.key
|
||||
com.baeldung.csfle.master-key-path=/tmp/master.key
|
||||
#com.baeldung.csfle.master-key-path=/tmp/master.key
|
||||
com.baeldung.csfle.auto-decryption=false
|
||||
|
@ -4,4 +4,5 @@ This module contains articles about Spring Data JPA.
|
||||
|
||||
### Relevant Articles:
|
||||
- [New CRUD Repository Interfaces in Spring Data 3](https://www.baeldung.com/spring-data-3-crud-repository-interfaces)
|
||||
- [How to Persist a List of String in JPA?](https://www.baeldung.com/java-jpa-persist-string-list)
|
||||
- More articles: [[<-- prev]](../spring-data-jpa-repo-2)
|
||||
|
@ -6,3 +6,4 @@
|
||||
- [Migrate Application From Spring Boot 2 to Spring Boot 3](https://www.baeldung.com/spring-boot-3-migration)
|
||||
- [Using Java Records with JPA](https://www.baeldung.com/spring-jpa-java-records)
|
||||
- [HTTP Interface in Spring 6](https://www.baeldung.com/spring-6-http-interface)
|
||||
- [Working with Virtual Threads in Spring 6](https://www.baeldung.com/spring-6-virtual-threads)
|
||||
|
@ -10,4 +10,5 @@ This module contains articles about various Spring Boot libraries
|
||||
- [Scanning Java Annotations At Runtime](https://www.baeldung.com/java-scan-annotations-runtime)
|
||||
- [Guide to Resilience4j With Spring Boot](https://www.baeldung.com/spring-boot-resilience4j)
|
||||
- [Using OpenAI ChatGPT APIs in Spring Boot](https://www.baeldung.com/spring-boot-chatgpt-api-openai)
|
||||
- [Introduction to Spring Modulith](https://www.baeldung.com/spring-modulith)
|
||||
- More articles: [[prev -->]](/spring-boot-modules/spring-boot-libraries)
|
||||
|
@ -1,12 +1,13 @@
|
||||
package com.baeldung.webclient.manualrequest.web;
|
||||
|
||||
import java.util.Base64;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
|
||||
import org.springframework.util.Base64Utils;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.reactive.function.BodyInserters;
|
||||
@ -41,7 +42,8 @@ public class ManualOauthRequestController {
|
||||
logger.info("Creating web client...");
|
||||
Mono<String> resource = client.post()
|
||||
.uri(tokenUri)
|
||||
.header(HttpHeaders.AUTHORIZATION, "Basic " + Base64Utils.encodeToString((clientId + ":" + clientSecret).getBytes()))
|
||||
.header(HttpHeaders.AUTHORIZATION, "Basic " + Base64.getEncoder()
|
||||
.encodeToString((clientId + ":" + clientSecret).getBytes()))
|
||||
.body(BodyInserters.fromFormData(OAuth2ParameterNames.GRANT_TYPE, GrantType.CLIENT_CREDENTIALS.getValue()))
|
||||
.retrieve()
|
||||
.bodyToMono(JsonNode.class)
|
||||
|
@ -1,5 +1,7 @@
|
||||
package com.baeldung.reactive.authresolver;
|
||||
|
||||
import java.util.Base64;
|
||||
|
||||
import org.junit.FixMethodOrder;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
@ -8,7 +10,6 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.springframework.test.web.reactive.server.WebTestClient;
|
||||
import org.springframework.util.Base64Utils;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = AuthResolverApplication.class)
|
||||
@ -22,7 +23,7 @@ public class AuthResolverIntegrationTest {
|
||||
testClient
|
||||
.get()
|
||||
.uri("/customer/welcome")
|
||||
.header("Authorization", "Basic " + Base64Utils.encodeToString("customer1:pass1".getBytes()))
|
||||
.header("Authorization", "Basic " + Base64.getEncoder().encodeToString("customer1:pass1".getBytes()))
|
||||
.exchange()
|
||||
.expectStatus()
|
||||
.isOk();
|
||||
@ -33,7 +34,7 @@ public class AuthResolverIntegrationTest {
|
||||
testClient
|
||||
.get()
|
||||
.uri("/customer/welcome")
|
||||
.header("Authorization", "Basic " + Base64Utils.encodeToString("employee1:pass1".getBytes()))
|
||||
.header("Authorization", "Basic " + Base64.getEncoder().encodeToString("employee1:pass1".getBytes()))
|
||||
.exchange()
|
||||
.expectStatus()
|
||||
.isUnauthorized();
|
||||
@ -44,7 +45,7 @@ public class AuthResolverIntegrationTest {
|
||||
testClient
|
||||
.get()
|
||||
.uri("/employee/welcome")
|
||||
.header("Authorization", "Basic " + Base64Utils.encodeToString("employee1:pass1".getBytes()))
|
||||
.header("Authorization", "Basic " + Base64.getEncoder().encodeToString("employee1:pass1".getBytes()))
|
||||
.exchange()
|
||||
.expectStatus()
|
||||
.isOk();
|
||||
@ -55,7 +56,7 @@ public class AuthResolverIntegrationTest {
|
||||
testClient
|
||||
.get()
|
||||
.uri("/employee/welcome")
|
||||
.header("Authorization", "Basic " + Base64Utils.encodeToString("customer1:pass1".getBytes()))
|
||||
.header("Authorization", "Basic " + Base64.getEncoder().encodeToString("customer1:pass1".getBytes()))
|
||||
.exchange()
|
||||
.expectStatus()
|
||||
.isUnauthorized();
|
||||
|
@ -11,13 +11,14 @@ import org.springframework.security.web.FilterChainProxy;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||
import org.springframework.util.Base64Utils;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
|
||||
import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.springSecurity;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
import java.util.Base64;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = AuthResolverApplication.class)
|
||||
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
||||
@ -44,7 +45,7 @@ public class AuthResolverIntegrationTest {
|
||||
this.mockMvc
|
||||
.perform(get("/customer/welcome")
|
||||
.header(
|
||||
"Authorization", String.format("Basic %s", Base64Utils.encodeToString("customer1:pass1".getBytes()))
|
||||
"Authorization", String.format("Basic %s", Base64.getEncoder().encodeToString("customer1:pass1".getBytes()))
|
||||
)
|
||||
)
|
||||
.andExpect(status().is2xxSuccessful());
|
||||
@ -55,7 +56,7 @@ public class AuthResolverIntegrationTest {
|
||||
this.mockMvc
|
||||
.perform(get("/customer/welcome")
|
||||
.header(
|
||||
"Authorization", "Basic " + Base64Utils.encodeToString("employee1:pass1".getBytes()))
|
||||
"Authorization", "Basic " + Base64.getEncoder().encodeToString("employee1:pass1".getBytes()))
|
||||
)
|
||||
.andExpect(status().isUnauthorized());
|
||||
}
|
||||
@ -65,7 +66,7 @@ public class AuthResolverIntegrationTest {
|
||||
this.mockMvc
|
||||
.perform(get("/employee/welcome")
|
||||
.header(
|
||||
"Authorization", "Basic " + Base64Utils.encodeToString("employee1:pass1".getBytes()))
|
||||
"Authorization", "Basic " + Base64.getEncoder().encodeToString("employee1:pass1".getBytes()))
|
||||
)
|
||||
.andExpect(status().is2xxSuccessful());
|
||||
}
|
||||
@ -75,7 +76,7 @@ public class AuthResolverIntegrationTest {
|
||||
this.mockMvc
|
||||
.perform(get("/employee/welcome")
|
||||
.header(
|
||||
"Authorization", "Basic " + Base64Utils.encodeToString("customer1:pass1".getBytes()))
|
||||
"Authorization", "Basic " + Base64.getEncoder().encodeToString("customer1:pass1".getBytes()))
|
||||
)
|
||||
.andExpect(status().isUnauthorized());
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
package com.baeldung.petstore.client.invoker.auth;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Base64;
|
||||
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.util.Base64Utils;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
|
||||
@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", date = "2020-03-15T06:14:01.568992-05:00[America/Chicago]")
|
||||
@ -33,6 +33,7 @@ public class HttpBasicAuth implements Authentication {
|
||||
return;
|
||||
}
|
||||
String str = (username == null ? "" : username) + ":" + (password == null ? "" : password);
|
||||
headerParams.add(HttpHeaders.AUTHORIZATION, "Basic " + Base64Utils.encodeToString(str.getBytes(StandardCharsets.UTF_8)));
|
||||
headerParams.add(HttpHeaders.AUTHORIZATION, "Basic " + Base64.getEncoder()
|
||||
.encodeToString(str.getBytes(StandardCharsets.UTF_8)));
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,9 @@
|
||||
package com.baeldung.petstore.client.invoker.auth;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Base64;
|
||||
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.util.Base64Utils;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
|
||||
@javax.annotation.Generated(value = "io.swagger.codegen.languages.JavaClientCodegen", date = "2017-08-29T12:04:37.072+02:00")
|
||||
@ -34,6 +33,7 @@ public class HttpBasicAuth implements Authentication {
|
||||
return;
|
||||
}
|
||||
String str = (username == null ? "" : username) + ":" + (password == null ? "" : password);
|
||||
headerParams.add(HttpHeaders.AUTHORIZATION, "Basic " + Base64Utils.encodeToString(str.getBytes(StandardCharsets.UTF_8)));
|
||||
headerParams.add(HttpHeaders.AUTHORIZATION, "Basic " + Base64.getEncoder()
|
||||
.encodeToString(str.getBytes(StandardCharsets.UTF_8)));
|
||||
}
|
||||
}
|
||||
|
@ -10,6 +10,7 @@
|
||||
- [Handle Browser Tabs With Selenium](https://www.baeldung.com/java-handle-browser-tabs-selenium)
|
||||
- [Implicit Wait vs Explicit Wait in Selenium Webdriver](https://www.baeldung.com/selenium-implicit-explicit-wait)
|
||||
- [StaleElementReferenceException in Selenium](https://www.baeldung.com/selenium-staleelementreferenceexception)
|
||||
- [Retrieve the Value of an HTML Input in Selenium WebDriver](https://www.baeldung.com/java-selenium-html-input-value)
|
||||
|
||||
#### Notes:
|
||||
- to run the live tests for the article *Fixing Selenium WebDriver Executable Path Error*, follow the manual setup described
|
||||
|
Loading…
x
Reference in New Issue
Block a user