Merge pull request #1 from eugenp/master

update
This commit is contained in:
Hamid Reza Sharifi 2021-03-20 19:34:01 +03:30 committed by GitHub
commit 9f508c34a7
126 changed files with 2546 additions and 124 deletions

View File

@ -11,3 +11,4 @@ This module contains articles about Apache POI
- [Get String Value of Excel Cell with Apache POI](https://www.baeldung.com/java-apache-poi-cell-string-value)
- [Read Excel Cell Value Rather Than Formula With Apache POI](https://www.baeldung.com/apache-poi-read-cell-value-formula)
- [Setting Formulas in Excel with Apache POI](https://www.baeldung.com/java-apache-poi-set-formulas)
- [Insert a Row in Excel Using Apache POI](https://www.baeldung.com/apache-poi-insert-excel-row)

View File

@ -11,3 +11,4 @@ This module contains articles about Java 10 core features
- [Copying Sets in Java](https://www.baeldung.com/java-copy-sets)
- [Converting between a List and a Set in Java](https://www.baeldung.com/convert-list-to-set-and-set-to-list)
- [Java IndexOutOfBoundsException “Source Does Not Fit in Dest”](https://www.baeldung.com/java-indexoutofboundsexception)
- [Collect a Java Stream to an Immutable Collection](https://www.baeldung.com/java-stream-immutable-collection)

View File

@ -0,0 +1,20 @@
package com.baeldung.java10.streams;
import static java.util.stream.Collectors.toUnmodifiableList;
import java.util.Arrays;
import java.util.List;
import org.junit.Test;
public class StreamToImmutableJava10UnitTest {
@Test
public void whenUsingCollectorsToUnmodifiableList_thenSuccess() {
List<String> givenList = Arrays.asList("a", "b", "c");
List<String> result = givenList.stream()
.collect(toUnmodifiableList());
System.out.println(result.getClass());
}
}

View File

@ -5,3 +5,4 @@
### Relevant Articles:
- [ArrayList vs. LinkedList vs. HashMap in Java](https://www.baeldung.com/java-arraylist-vs-linkedlist-vs-hashmap)
- [Java Deque vs. Stack](https://www.baeldung.com/java-deque-vs-stack)

View File

@ -8,6 +8,7 @@ import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;
@ -18,12 +19,12 @@ import java.util.concurrent.TimeUnit;
@State(Scope.Thread)
public class PrimitivesListPerformance {
private List<Integer> arrayList = new ArrayList<>();
private TIntArrayList tList = new TIntArrayList();
private cern.colt.list.IntArrayList coltList = new cern.colt.list.IntArrayList();
private IntArrayList fastUtilList = new IntArrayList();
private List<Integer> arrayList = new ArrayList<>(Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 9));
private TIntArrayList tList = new TIntArrayList(new int[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9});
private cern.colt.list.IntArrayList coltList = new cern.colt.list.IntArrayList(new int[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9});
private IntArrayList fastUtilList = new IntArrayList(new int[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9});
private int getValue = 10;
private int getValue = 4;
@Benchmark
public boolean addArrayList() {

View File

@ -8,4 +8,5 @@ This module contains articles about Map data structures in Java.
- [The Map.computeIfAbsent() Method](https://www.baeldung.com/java-map-computeifabsent)
- [Collections.synchronizedMap vs. ConcurrentHashMap](https://www.baeldung.com/java-synchronizedmap-vs-concurrenthashmap)
- [Java HashMap Load Factor](https://www.baeldung.com/java-hashmap-load-factor)
- [Converting java.util.Properties to HashMap](https://www.baeldung.com/java-convert-properties-to-hashmap)
- More articles: [[<-- prev]](/core-java-modules/core-java-collections-maps-2)

View File

@ -21,14 +21,16 @@ public class ThreadPoolInParallelStreamIntegrationTest {
long lastNum = 1_000_000;
List<Long> aList = LongStream.rangeClosed(firstNum, lastNum).boxed().collect(Collectors.toList());
ForkJoinPool customThreadPool = new ForkJoinPool(4);
long actualTotal = customThreadPool
.submit(() -> aList.parallelStream()
.reduce(0L, Long::sum))
.get();
assertEquals((lastNum + firstNum) * lastNum / 2, actualTotal);
try {
long actualTotal = customThreadPool
.submit(() -> aList.parallelStream().reduce(0L, Long::sum))
.get();
assertEquals((lastNum + firstNum) * lastNum / 2, actualTotal);
} finally {
customThreadPool.shutdown();
}
}
@Test

View File

@ -5,12 +5,12 @@ import com.google.common.io.CharSource;
import com.google.common.io.Files;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.io.input.ReaderInputStream;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;
import java.nio.charset.StandardCharsets;
public class JavaXToInputStreamUnitTest {
protected final Logger logger = LoggerFactory.getLogger(getClass());
@ -28,7 +28,7 @@ public class JavaXToInputStreamUnitTest {
@Test
public final void givenUsingGuava_whenConvertingStringToInputStream_thenCorrect() throws IOException {
final String initialString = "text";
final InputStream targetStream = new ReaderInputStream(CharSource.wrap(initialString).openStream());
final InputStream targetStream = CharSource.wrap(initialString).asByteSource(StandardCharsets.UTF_8).openStream();
IOUtils.closeQuietly(targetStream);
}

View File

@ -77,7 +77,6 @@
<assertj.version>3.6.1</assertj.version>
<!-- instrumentation -->
<javaassist.version>3.27.0-GA</javaassist.version>
<esapi.version>2.1.0.1</esapi.version>
<sun.tools.version>1.8.0</sun.tools.version>
<jol-core.version>0.10</jol-core.version>
<asm.version>8.0.1</asm.version>

View File

@ -0,0 +1,5 @@
## Core Java Lang (Part 4)
This module contains articles about core features in the Java language
- [The Java final Keyword Impact on Performance](https://www.baeldung.com/java-final-performance)

View File

@ -0,0 +1,47 @@
<?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>core-java-lang-4</artifactId>
<version>0.1.0-SNAPSHOT</version>
<name>core-java-lang-4</name>
<packaging>jar</packaging>
<parent>
<groupId>com.baeldung.core-java-modules</groupId>
<artifactId>core-java-modules</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
<dependencies>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-core</artifactId>
<version>${jmh.version}</version>
</dependency>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-generator-annprocess</artifactId>
<version>${jmh.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<finalName>core-java-lang-4</finalName>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
<properties>
<jmh.version>1.28</jmh.version>
</properties>
</project>

View File

@ -0,0 +1,34 @@
package com.baeldung.finalkeyword;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import java.util.concurrent.TimeUnit;
public class BenchmarkRunner {
public static void main(String[] args) throws Exception {
org.openjdk.jmh.Main.main(args);
}
@Benchmark
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@BenchmarkMode(Mode.AverageTime)
public static String concatNonFinalStrings() {
String x = "x";
String y = "y";
return x + y;
}
@Benchmark
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@BenchmarkMode(Mode.AverageTime)
public static String concatFinalStrings() {
final String x = "x";
final String y = "y";
return x + y;
}
}

View File

@ -0,0 +1,19 @@
package com.baeldung.finalkeyword;
import java.io.Console;
public class ClassVariableFinal {
static final boolean doX = false;
static final boolean doY = true;
public static void main(String[] args) {
Console console = System.console();
if (doX) {
console.writer().println("x");
} else if (doY) {
console.writer().println("y");
}
}
}

View File

@ -0,0 +1,19 @@
package com.baeldung.finalkeyword;
import java.io.Console;
public class ClassVariableNonFinal {
static boolean doX = false;
static boolean doY = true;
public static void main(String[] args) {
Console console = System.console();
if (doX) {
console.writer().println("x");
} else if (doY) {
console.writer().println("y");
}
}
}

View File

@ -0,0 +1,131 @@
package com.baeldung.classfile;
import org.apache.commons.lang3.StringUtils;
import com.baeldung.classfile.HelloWorld.HelloSomeone;
public class Outer {
// Static Nested class
static class StaticNested {
public String message() {
return "This is a static Nested Class";
}
}
// Non-static Nested class
class Nested {
public String message() {
return "This is a non-static Nested Class";
}
}
// Local class
public String message() {
class Local {
private String message() {
return "This is a Local Class within a method";
}
}
Local local = new Local();
return local.message();
}
// Local class within if clause
public String message(String name) {
if (StringUtils.isEmpty(name)) {
class Local {
private String message() {
return "This is a Local Class within if clause";
}
}
Local local = new Local();
return local.message();
} else
return "Welcome to " + name;
}
// Anonymous Inner class extending a class
public String greet() {
Outer anonymous = new Outer() {
public String greet() {
return "Running Anonymous Class...";
}
};
return anonymous.greet();
}
// Anonymous inner class implementing an interface
public String greet(String name) {
HelloWorld helloWorld = new HelloWorld() {
public String greet(String name) {
return "Welcome to " + name;
}
};
return helloWorld.greet(name);
}
// Anonymous inner class implementing nested interface
public String greetSomeone(String name) {
HelloSomeone helloSomeOne = new HelloSomeone() {
public String greet(String name) {
return "Hello " + name;
}
};
return helloSomeOne.greet(name);
}
// Nested interface within a class
interface HelloOuter {
public String hello(String name);
}
// Enum within a class
enum Color {
RED, GREEN, BLUE;
}
}
interface HelloWorld {
public String greet(String name);
// Nested class within an interface
class InnerClass {
public String greet(String name) {
return "Inner class within an interface";
}
}
// Nested interface within an interfaces
interface HelloSomeone {
public String greet(String name);
}
// Enum within an interface
enum Directon {
NORTH, SOUTH, EAST, WEST;
}
}
enum Level {
LOW, MEDIUM, HIGH;
}
enum Foods {
DRINKS, EATS;
// Enum within Enum
enum DRINKS {
APPLE_JUICE, COLA;
}
enum EATS {
POTATO, RICE;
}
}

View File

@ -0,0 +1,46 @@
package com.baeldung.classfile;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.Test;
import com.baeldung.classfile.Outer.Nested;
public class OuterUnitTest {
@Test
public void when_static_nestedClass_then_verifyOutput() {
Outer.StaticNested nestedClass = new Outer.StaticNested();
assertEquals("This is a static Nested Class", nestedClass.message());
}
@Test
public void when_nestedClass_then_verifyOutput() {
Outer outer = new Outer();
Nested nestedClass = outer.new Nested();
assertEquals("This is a non-static Nested Class", nestedClass.message());
}
@Test
public void when_localClass_then_verifyOutput() {
Outer outer = new Outer();
assertEquals("This is a Local Class within a method", outer.message());
}
@Test
public void when_localClassInIfClause_then_verifyOutput() {
Outer outer = new Outer();
assertEquals("Welcome to Baeldung", outer.message("Baeldung"));
assertEquals("This is a Local Class within if clause", outer.message(""));
}
@Test
public void when_anonymousClass_then_verifyOutput() {
Outer outer = new Outer();
assertEquals("Running Anonymous Class...", outer.greet());
}
@Test
public void when_anonymousClassHelloWorld_then_verifyOutput() {
Outer outer = new Outer();
assertEquals("Welcome to Baeldung", outer.greet("Baeldung"));
}
}

View File

@ -4,3 +4,4 @@
- [Set Field Value With Reflection](https://www.baeldung.com/java-set-private-field-value)
- [Checking If a Method is Static Using Reflection in Java](https://www.baeldung.com/java-check-method-is-static)
- [Checking if a Java Class is abstract Using Reflection](https://www.baeldung.com/java-reflection-is-class-abstract)
- [Invoking a Private Method in Java](https://www.baeldung.com/java-call-private-method)

View File

@ -14,6 +14,15 @@
<relativePath>../</relativePath>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<finalName>core-java-reflection-2</finalName>
<resources>
@ -40,5 +49,6 @@
<maven-compiler-plugin.version>3.8.0</maven-compiler-plugin.version>
<source.version>1.8</source.version>
<target.version>1.8</target.version>
<spring.version>5.3.4</spring.version>
</properties>
</project>

View File

@ -0,0 +1,18 @@
package com.baeldung.reflection.access.privatemethods;
public class LongArrayUtil {
public static int indexOf(long[] array, long target) {
return indexOf(array, target, 0, array.length);
}
private static int indexOf(long[] array, long target, int start, int end) {
for (int i = start; i < end; i++) {
if (array[i] == target) {
return i;
}
}
return -1;
}
}

View File

@ -0,0 +1,28 @@
package com.baeldung.reflection.access.privatemethods;
import org.junit.jupiter.api.Test;
import org.springframework.test.util.ReflectionTestUtils;
import java.lang.reflect.Method;
import static org.junit.jupiter.api.Assertions.assertEquals;
class InvokePrivateMethodsUnitTest {
private final long[] someLongArray = new long[] { 1L, 2L, 1L, 4L, 2L };
@Test
void whenSearchingForLongValueInSubsequenceUsingReflection_thenTheCorrectIndexOfTheValueIsReturned() throws Exception {
Method indexOfMethod = LongArrayUtil.class.getDeclaredMethod("indexOf", long[].class, long.class, int.class, int.class);
indexOfMethod.setAccessible(true);
assertEquals(2, indexOfMethod.invoke(LongArrayUtil.class, someLongArray, 1L, 1, someLongArray.length), "The index should be 2.");
}
@Test
void whenSearchingForLongValueInSubsequenceUsingSpring_thenTheCorrectIndexOfTheValueIsReturned() throws Exception {
int indexOfSearchTarget = ReflectionTestUtils.invokeMethod(LongArrayUtil.class, "indexOf", someLongArray, 1L, 1, someLongArray.length);
assertEquals(2, indexOfSearchTarget, "The index should be 2.");
}
}

View File

@ -15,4 +15,5 @@ This module contains articles about core Java Security
- [Security Context Basics: User, Subject and Principal](https://www.baeldung.com/security-context-basics)
- [Java AES Encryption and Decryption](https://www.baeldung.com/java-aes-encryption-decryption)
- [InvalidAlgorithmParameterException: Wrong IV Length](https://www.baeldung.com/java-invalidalgorithmparameter-exception)
- [The java.security.egd JVM Option](https://www.baeldung.com/java-security-egd)
- More articles: [[<-- prev]](/core-java-modules/core-java-security)

View File

@ -82,6 +82,7 @@
<module>core-java-lang</module>
<module>core-java-lang-2</module>
<module>core-java-lang-3</module>
<module>core-java-lang-4</module>
<module>core-java-lang-math</module>
<module>core-java-lang-math-2</module>
<module>core-java-lang-math-3</module>

View File

@ -10,10 +10,8 @@ public class CircularBuffer<E> {
@SuppressWarnings("unchecked")
public CircularBuffer(int capacity) {
this.capacity = (capacity < 1) ? DEFAULT_CAPACITY : capacity;
this.data = (E[]) new Object[capacity];
this.data = (E[]) new Object[this.capacity];
this.readSequence = 0;
this.writeSequence = -1;
}

View File

@ -5,7 +5,7 @@ import org.slf4j.LoggerFactory;
public class CircularLinkedList {
final Logger LOGGER = LoggerFactory.getLogger(CircularLinkedList.class);
final Logger logger = LoggerFactory.getLogger(CircularLinkedList.class);
private Node head = null;
private Node tail = null;
@ -42,24 +42,29 @@ public class CircularLinkedList {
}
public void deleteNode(int valueToDelete) {
Node currentNode = head;
if (head != null) {
if (currentNode.value == valueToDelete) {
head = head.nextNode;
tail.nextNode = head;
} else {
do {
Node nextNode = currentNode.nextNode;
if (nextNode.value == valueToDelete) {
currentNode.nextNode = nextNode.nextNode;
break;
}
currentNode = currentNode.nextNode;
} while (currentNode != head);
}
if (head == null) {
return;
}
do {
Node nextNode = currentNode.nextNode;
if (nextNode.value == valueToDelete) {
if (tail == head) {
head = null;
tail = null;
} else {
currentNode.nextNode = nextNode.nextNode;
if (head == nextNode) {
head = head.nextNode;
}
if (tail == nextNode) {
tail = currentNode;
}
}
break;
}
currentNode = nextNode;
} while (currentNode != head);
}
public void traverseList() {
@ -68,7 +73,7 @@ public class CircularLinkedList {
if (head != null) {
do {
LOGGER.info(currentNode.value + " ");
logger.info(currentNode.value + " ");
currentNode = currentNode.nextNode;
} while (currentNode != head);
}

View File

@ -1,10 +1,10 @@
package com.baeldung.circularlinkedlist;
import org.junit.Test;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
public class CircularLinkedListUnitTest {
@Test
@ -23,7 +23,7 @@ public class CircularLinkedListUnitTest {
}
@Test
public void givenACircularLinkedList_WhenDeletingElements_ThenListDoesNotContainThoseElements() {
public void givenACircularLinkedList_WhenDeletingInOrderHeadMiddleTail_ThenListDoesNotContainThoseElements() {
CircularLinkedList cll = createCircularLinkedList();
assertTrue(cll.containsNode(13));
@ -39,6 +39,32 @@ public class CircularLinkedListUnitTest {
assertFalse(cll.containsNode(46));
}
@Test
public void givenACircularLinkedList_WhenDeletingInOrderTailMiddleHead_ThenListDoesNotContainThoseElements() {
CircularLinkedList cll = createCircularLinkedList();
assertTrue(cll.containsNode(46));
cll.deleteNode(46);
assertFalse(cll.containsNode(46));
assertTrue(cll.containsNode(1));
cll.deleteNode(1);
assertFalse(cll.containsNode(1));
assertTrue(cll.containsNode(13));
cll.deleteNode(13);
assertFalse(cll.containsNode(13));
}
@Test
public void givenACircularLinkedListWithOneNode_WhenDeletingElement_ThenListDoesNotContainTheElement() {
CircularLinkedList cll = new CircularLinkedList();
cll.addNode(1);
cll.deleteNode(1);
assertFalse(cll.containsNode(1));
}
private CircularLinkedList createCircularLinkedList() {
CircularLinkedList cll = new CircularLinkedList();

View File

@ -3,3 +3,4 @@
- [Java Map With Case-Insensitive Keys](https://www.baeldung.com/java-map-with-case-insensitive-keys)
- [Using a Byte Array as Map Key in Java](https://www.baeldung.com/java-map-key-byte-array)
- [Using the Map.Entry Java Class](https://www.baeldung.com/java-map-entry)
- [Optimizing HashMaps Performance](https://www.baeldung.com/java-hashmap-optimize-performance)

View File

@ -20,7 +20,7 @@ public class JavaRMIIntegrationTest {
MessengerServiceImpl server = new MessengerServiceImpl();
server.createStubAndBind();
} catch (RemoteException e) {
fail("Exception Occurred");
fail("Exception Occurred: " + e);
}
}
@ -34,11 +34,9 @@ public class JavaRMIIntegrationTest {
String expectedMessage = "Server Message";
assertEquals(responseMessage, expectedMessage);
} catch (RemoteException e) {
fail("Exception Occurred");
} catch (NotBoundException nb) {
fail("Exception Occurred");
}
} catch (RemoteException | NotBoundException e) {
fail("Exception Occurred: " + e);
};
}
}

View File

@ -47,3 +47,4 @@ Available commands (assumes httpie - https://github.com/jkbrzt/httpie):
## Relevant articles:
- [Supercharge Java Authentication with JSON Web Tokens (JWTs)](https://www.baeldung.com/java-json-web-tokens-jjwt)
- [Decode a JWT Token in Java](https://www.baeldung.com/java-jwt-token-decode)

View File

@ -41,6 +41,12 @@
<artifactId>jjwt</artifactId>
<version>${jjwt.version}</version>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<properties>

View File

@ -0,0 +1,46 @@
package io.jsonwebtoken.jjwtfun.util;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.impl.crypto.DefaultJwtSignatureValidator;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
import static io.jsonwebtoken.SignatureAlgorithm.HS256;
public class JWTDecoderUtil {
public static String decodeJWTToken(String token) {
Base64.Decoder decoder = Base64.getDecoder();
String[] chunks = token.split("\\.");
String header = new String(decoder.decode(chunks[0]));
String payload = new String(decoder.decode(chunks[1]));
return header + " " + payload;
}
public static String decodeJWTToken(String token, String secretKey) throws Exception {
Base64.Decoder decoder = Base64.getDecoder();
String[] chunks = token.split("\\.");
String header = new String(decoder.decode(chunks[0]));
String payload = new String(decoder.decode(chunks[1]));
String tokenWithoutSignature = chunks[0] + "." + chunks[1];
String signature = chunks[2];
SignatureAlgorithm sa = HS256;
SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getBytes(), sa.getJcaName());
DefaultJwtSignatureValidator validator = new DefaultJwtSignatureValidator(sa, secretKeySpec);
if (!validator.isValid(tokenWithoutSignature, signature)) {
throw new Exception("Could not verify JWT token integrity!");
}
return header + " " + payload;
}
}

View File

@ -0,0 +1,32 @@
package io.jsonwebtoken.jjwtfun.util;
import io.jsonwebtoken.SignatureAlgorithm;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
class JWTDecoderUtilUnitTest {
private final static String SIMPLE_TOKEN = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkJhZWxkdW5nIFVzZXIiLCJpYXQiOjE1MTYyMzkwMjJ9";
private final static String SIGNED_TOKEN = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkJhZWxkdW5nIFVzZXIiLCJpYXQiOjE1MTYyMzkwMjJ9.qH7Zj_m3kY69kxhaQXTa-ivIpytKXXjZc1ZSmapZnGE";
@Test
void givenSimpleToken_whenDecoding_thenStringOfHeaderPayloadAreReturned() {
assertThat(JWTDecoderUtil.decodeJWTToken(SIMPLE_TOKEN))
.contains(SignatureAlgorithm.HS256.getValue());
}
@Test
void givenSignedToken_whenDecodingWithInvalidSecret_thenIntegrityIsNotValidated() {
assertThatThrownBy(() -> JWTDecoderUtil.decodeJWTToken(SIGNED_TOKEN, "BAD_SECRET"))
.hasMessage("Could not verify JWT token integrity!");
}
@Test
void givenSignedToken_whenDecodingWithValidSecret_thenIntegrityIsValidated() throws Exception {
assertThat(JWTDecoderUtil.decodeJWTToken(SIGNED_TOKEN, "MySecretKey"))
.contains("Baeldung User");
}
}

View File

@ -52,3 +52,4 @@ Enjoy it :)
- [Intro to Performance Testing using JMeter](https://www.baeldung.com/jmeter)
- [Configure Jenkins to Run and Show JMeter Tests](https://www.baeldung.com/jenkins-and-jmeter)
- [Write Extracted Data to a File Using JMeter](https://www.baeldung.com/jmeter-write-to-file)

View File

@ -0,0 +1,13 @@
# Kubernetes Java API Sample Code
This module contains sample code used to show how to use the Kubernetes client Java API.
Before running those samples, make sure that your environment is correctly configured to access
a working Kubernetes cluster.
An easy way to check that everything is working as expected is issuing any *kubectl get* command:
```shell
$ kubectl get nodes
```
If you get a valid response, then you're good to go.

View File

@ -0,0 +1,41 @@
<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>
<parent>
<groupId>com.baeldung</groupId>
<artifactId>kubernetes-parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>k8s-intro</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>io.kubernetes</groupId>
<artifactId>client-java</artifactId>
<version>11.0.0</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<!-- http://maven.apache.org/plugins/maven-compiler-plugin/ -->
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,11 @@
package com.baeldung.kubernetes.intro;
import io.kubernetes.client.openapi.ApiCallback;
import io.kubernetes.client.openapi.ApiException;
import io.kubernetes.client.openapi.apis.CoreV1Api;
import okhttp3.Call;
@FunctionalInterface
public interface ApiInvoker<R> {
Call apply(CoreV1Api api, ApiCallback<R> callback) throws ApiException;
}

View File

@ -0,0 +1,74 @@
package com.baeldung.kubernetes.intro;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Future;
import java.util.function.BiFunction;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import io.kubernetes.client.openapi.ApiCallback;
import io.kubernetes.client.openapi.ApiException;
import io.kubernetes.client.openapi.apis.CoreV1Api;
import okhttp3.Call;
public class AsyncHelper<R> implements ApiCallback<R> {
private static final Logger log = LoggerFactory.getLogger(AsyncHelper.class);
private CoreV1Api api;
private CompletableFuture<R> callResult;
private AsyncHelper(CoreV1Api api) {
this.api = api;
}
public static <T> CompletableFuture<T> doAsync(CoreV1Api api, ApiInvoker<T> invoker) {
AsyncHelper<T> p = new AsyncHelper<>(api);
return p.execute(invoker);
}
private CompletableFuture<R> execute( ApiInvoker<R> invoker) {
try {
callResult = new CompletableFuture<>();
log.info("[I38] Calling API...");
final Call call = invoker.apply(api,this);
log.info("[I41] API Succesfully invoked: method={}, url={}",
call.request().method(),
call.request().url());
return callResult;
}
catch(ApiException aex) {
callResult.completeExceptionally(aex);
return callResult;
}
}
@Override
public void onFailure(ApiException e, int statusCode, Map<String, List<String>> responseHeaders) {
log.error("[E53] onFailure",e);
callResult.completeExceptionally(e);
}
@Override
public void onSuccess(R result, int statusCode, Map<String, List<String>> responseHeaders) {
log.error("[E61] onSuccess: statusCode={}",statusCode);
callResult.complete(result);
}
@Override
public void onUploadProgress(long bytesWritten, long contentLength, boolean done) {
log.info("[E61] onUploadProgress: bytesWritten={}, contentLength={}, done={}",bytesWritten,contentLength,done);
}
@Override
public void onDownloadProgress(long bytesRead, long contentLength, boolean done) {
log.info("[E75] onDownloadProgress: bytesRead={}, contentLength={}, done={}",bytesRead,contentLength,done);
}
}

View File

@ -0,0 +1,31 @@
/**
*
*/
package com.baeldung.kubernetes.intro;
import io.kubernetes.client.openapi.ApiClient;
import io.kubernetes.client.openapi.apis.CoreV1Api;
import io.kubernetes.client.openapi.models.V1NodeList;
import io.kubernetes.client.util.Config;
/**
* @author Philippe
*
*/
public class ListNodes {
/**
* @param args
*/
public static void main(String[] args) throws Exception {
ApiClient client = Config.defaultClient();
CoreV1Api api = new CoreV1Api(client);
V1NodeList nodeList = api.listNode(null, null, null, null, null, null, null, null, 10, false);
nodeList.getItems()
.stream()
.forEach((node) -> System.out.println(node.getMetadata()));
}
}

View File

@ -0,0 +1,50 @@
/**
*
*/
package com.baeldung.kubernetes.intro;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import io.kubernetes.client.openapi.ApiClient;
import io.kubernetes.client.openapi.apis.CoreV1Api;
import io.kubernetes.client.openapi.models.V1NodeList;
import io.kubernetes.client.util.Config;
/**
* @author Philippe
*
*/
public class ListNodesAsync {
private static Logger log = LoggerFactory.getLogger(ListNodesAsync.class);
/**
* @param args
*/
public static void main(String[] args) throws Exception {
// Initial setup
ApiClient client = Config.defaultClient();
CoreV1Api api = new CoreV1Api(client);
// Start async call
CompletableFuture<V1NodeList> p = AsyncHelper.doAsync(api,(capi,cb) ->
capi.listNodeAsync(null, null, null, null, null, null, null, null, 10, false, cb)
);
p.thenAcceptAsync((nodeList) -> {
log.info("[I40] Processing results...");
nodeList.getItems()
.stream()
.forEach((node) -> System.out.println(node.getMetadata()));
});
log.info("[I46] Waiting results...");
p.get(10, TimeUnit.SECONDS);
}
}

View File

@ -0,0 +1,46 @@
/**
*
*/
package com.baeldung.kubernetes.intro;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import io.kubernetes.client.openapi.ApiClient;
import io.kubernetes.client.openapi.apis.CoreV1Api;
import io.kubernetes.client.openapi.models.V1NodeList;
import io.kubernetes.client.openapi.models.V1PodList;
import io.kubernetes.client.util.Config;
/**
* @author Philippe
*
*/
public class ListPodsPaged {
private static final Logger log = LoggerFactory.getLogger(ListPodsPaged.class);
/**
* @param args
*/
public static void main(String[] args) throws Exception {
ApiClient client = Config.defaultClient();
CoreV1Api api = new CoreV1Api(client);
String continuationToken = null;
int limit = 2; // Just for illustration purposes. Real world values would range from ~100 to ~1000/page
Long remaining = null;
do {
log.info("==========================================================================");
log.info("Retrieving data: continuationToken={}, remaining={}", continuationToken,remaining);
V1PodList items = api.listPodForAllNamespaces(null, continuationToken, null, null, limit, null, null, null, 10, false);
continuationToken = items.getMetadata().getContinue();
remaining = items.getMetadata().getRemainingItemCount();
items.getItems()
.stream()
.forEach((node) -> System.out.println(node.getMetadata()));
} while( continuationToken != null );
}
}

View File

@ -0,0 +1,10 @@
package com.baeldung.kubernetes.intro;
import org.junit.jupiter.api.Test;
class ListNodesAsyncLiveTest {
@Test
void whenListNodes_thenSuccess() throws Exception {
ListNodesAsync.main(new String[] {});
}
}

View File

@ -0,0 +1,10 @@
package com.baeldung.kubernetes.intro;
import org.junit.jupiter.api.Test;
class ListNodesLiveTest {
@Test
void whenListNodes_thenSuccess() throws Exception {
ListNodes.main(new String[] {});
}
}

View File

@ -0,0 +1,10 @@
package com.baeldung.kubernetes.intro;
import org.junit.jupiter.api.Test;
class ListPodsPagedLiveTest {
@Test
void whenListPodsPage_thenSuccess() throws Exception {
ListPodsPaged.main(new String[] {});
}
}

View File

@ -0,0 +1,11 @@
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root level="debug">
<appender-ref ref="STDOUT" />
</root>
</configuration>

13
kubernetes/pom.xml Normal file
View File

@ -0,0 +1,13 @@
<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>
<parent>
<groupId>com.baeldung</groupId>
<artifactId>parent-modules</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>kubernetes-parent</artifactId>
<packaging>pom</packaging>
<modules>
<module>k8s-intro</module>
</modules>
</project>

View File

@ -7,5 +7,6 @@ This module contains articles about HTTP libraries.
- [Jetty ReactiveStreams HTTP Client](https://www.baeldung.com/jetty-reactivestreams-http-client)
- [Decode an OkHttp JSON Response](https://www.baeldung.com/okhttp-json-response)
- [Retrofit 2 Dynamic URL](https://www.baeldung.com/retrofit-dynamic-url)
- [Adding Interceptors in OkHTTP](https://www.baeldung.com/java-okhttp-interceptors)
- More articles [[<-- prev]](/libraries-http)

View File

@ -1,7 +1,7 @@
<?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">
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>libraries-http-2</artifactId>
<name>libraries-http-2</name>
@ -13,12 +13,17 @@
</parent>
<dependencies>
<!-- Dependencies for response decoder with okhttp -->
<!-- Dependencies for response decoder with okhttp -->
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>${okhttp.version}</version>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>logging-interceptor</artifactId>
<version>${okhttp.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
@ -81,9 +86,9 @@
</dependencies>
<properties>
<okhttp.version>3.14.2</okhttp.version>
<okhttp.version>4.9.1</okhttp.version>
<gson.version>2.8.5</gson.version>
<mockwebserver.version>3.14.2</mockwebserver.version>
<mockwebserver.version>4.9.1</mockwebserver.version>
<jetty.httpclient.version>1.0.3</jetty.httpclient.version>
<jetty.server.version>9.4.19.v20190610</jetty.server.version>
<rxjava2.version>2.2.11</rxjava2.version>

View File

@ -0,0 +1,18 @@
package com.baeldung.okhttp.interceptors;
import java.io.IOException;
import okhttp3.Interceptor;
import okhttp3.Response;
public class CacheControlResponeInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
Response response = chain.proceed(chain.request());
return response.newBuilder()
.header("Cache-Control", "no-store")
.build();
}
}

View File

@ -0,0 +1,21 @@
package com.baeldung.okhttp.interceptors;
public class ErrorMessage {
private final int status;
private final String detail;
public ErrorMessage(int status, String detail) {
this.status = status;
this.detail = detail;
}
public int getStatus() {
return status;
}
public String getDetail() {
return detail;
}
}

View File

@ -0,0 +1,32 @@
package com.baeldung.okhttp.interceptors;
import java.io.IOException;
import com.google.gson.Gson;
import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.Response;
import okhttp3.ResponseBody;
public class ErrorResponseInterceptor implements Interceptor {
public static final MediaType APPLICATION_JSON = MediaType.get("application/json; charset=utf-8");
@Override
public Response intercept(Chain chain) throws IOException {
Response response = chain.proceed(chain.request());
if(!response.isSuccessful()) {
Gson gson = new Gson();
String body = gson.toJson(new ErrorMessage(response.code(), "The response from the server was not OK"));
ResponseBody responseBody = ResponseBody.create(body, APPLICATION_JSON);
return response.newBuilder()
.body(responseBody)
.build();
}
return response;
}
}

View File

@ -0,0 +1,25 @@
package com.baeldung.okhttp.interceptors;
import java.io.IOException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;
public class SimpleLoggingInterceptor implements Interceptor {
private static final Logger LOGGER = LoggerFactory.getLogger(SimpleLoggingInterceptor.class);
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
LOGGER.info("Intercepted headers: {} from URL: {}", request.headers(), request.url());
return chain.proceed(request);
}
}

View File

@ -0,0 +1,90 @@
package com.baeldung.okhttp.interceptors;
import static org.junit.Assert.assertEquals;
import java.io.IOException;
import org.junit.Rule;
import org.junit.Test;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.logging.HttpLoggingInterceptor;
import okhttp3.logging.HttpLoggingInterceptor.Level;
import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer;
public class InterceptorIntegrationTest {
@Rule
public MockWebServer server = new MockWebServer();
@Test
public void givenSimpleLogginInterceptor_whenRequestSent_thenHeadersLogged() throws IOException {
server.enqueue(new MockResponse().setBody("Hello Baeldung Readers!"));
OkHttpClient client = new OkHttpClient.Builder()
.addNetworkInterceptor(new SimpleLoggingInterceptor())
.build();
Request request = new Request.Builder()
.url(server.url("/greeting"))
.header("User-Agent", "A Baeldung Reader")
.build();
try (Response response = client.newCall(request).execute()) {
assertEquals("Response code should be: ", 200, response.code());
assertEquals("Body should be: ", "Hello Baeldung Readers!", response.body().string());
}
}
@Test
public void givenResponseInterceptor_whenRequestSent_thenCacheControlSetToNoStore() throws IOException {
server.enqueue(new MockResponse().setBody("Hello Baeldung Readers!"));
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(getHttpLogger())
.addInterceptor(new CacheControlResponeInterceptor())
.build();
Request request = new Request.Builder()
.url(server.url("/greeting"))
.header("User-Agent", "A Baeldung Reader")
.build();
try (Response response = client.newCall(request).execute()) {
assertEquals("Response code should be: ", 200, response.code());
assertEquals("Body should be: ", "Hello Baeldung Readers!", response.body().string());
assertEquals("Response cache-control should be", "no-store", response.header("Cache-Control"));
}
}
@Test
public void givenErrorResponseInterceptor_whenResponseIs500_thenBodyIsJsonWithStatus() throws IOException {
server.enqueue(new MockResponse().setResponseCode(500).setBody("Hello Baeldung Readers!"));
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(getHttpLogger())
.addInterceptor(new ErrorResponseInterceptor())
.build();
Request request = new Request.Builder()
.url(server.url("/greeting"))
.header("User-Agent", "A Baeldung Reader")
.build();
try (Response response = client.newCall(request).execute()) {
assertEquals("Response code should be: ", 500, response.code());
assertEquals("Body should be: ", "{\"status\":500,\"detail\":\"The response from the server was not OK\"}",
response.body().string());
}
}
private HttpLoggingInterceptor getHttpLogger() {
HttpLoggingInterceptor logger = new HttpLoggingInterceptor();
logger.setLevel(Level.HEADERS);
return logger;
}
}

View File

@ -0,0 +1,3 @@
### Relevant Articles:
- [Generate WSDL Stubs with Maven](https://www.baeldung.com/maven-wsdl-stubs)

View File

@ -0,0 +1,45 @@
<?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>maven-plugins</artifactId>
<groupId>com.baeldung</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jaxws</artifactId>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxws-maven-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<goals>
<goal>wsimport</goal>
</goals>
</execution>
</executions>
<configuration>
<wsdlDirectory>${project.basedir}/src/main/resources/</wsdlDirectory>
<packageName>com.baeldung.soap.ws.client</packageName>
<sourceDestDir>
${project.build.directory}/generated-sources/
</sourceDestDir>
</configuration>
</plugin>
<plugin>
<artifactId>maven-verifier-plugin</artifactId>
<version>${maven.verifier.version}</version>
<configuration>
<verificationFile>../input-resources/verifications.xml</verificationFile>
<failOnError>false</failOnError>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,8 @@
package com.baeldung.soap.ws.client;
public class CountryNotFoundException extends RuntimeException {
public CountryNotFoundException() {
super("Country not found!");
}
}

View File

@ -0,0 +1,27 @@
package com.baeldung.soap.ws.client;
import java.util.Optional;
public class CountryServiceClient {
private CountryService countryService;
public CountryServiceClient(CountryService countryService) {
this.countryService = countryService;
}
public String getCapitalByCountryName(String countryName) {
return Optional.of(countryService.findByName(countryName))
.map(Country::getCapital).orElseThrow(CountryNotFoundException::new);
}
public int getPopulationByCountryName(String countryName) {
return Optional.of(countryService.findByName(countryName))
.map(Country::getPopulation).orElseThrow(CountryNotFoundException::new);
}
public Currency getCurrencyByCountryName(String countryName) {
return Optional.of(countryService.findByName(countryName))
.map(Country::getCurrency).orElseThrow(CountryNotFoundException::new);
}
}

View File

@ -0,0 +1,38 @@
<!-- Published by JAX-WS RI (http://jax-ws.java.net). RI's version is JAX-WS RI 2.2.9-b130926.1035 svn-revision#5f6196f2b90e9460065a4c2f4e30e065b245e51e. -->
<!-- Generated by JAX-WS RI (http://jax-ws.java.net). RI's version is JAX-WS RI 2.2.9-b130926.1035 svn-revision#5f6196f2b90e9460065a4c2f4e30e065b245e51e. -->
<definitions xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsp="http://www.w3.org/ns/ws-policy" xmlns:wsp1_2="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://server.ws.soap.baeldung.com/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.xmlsoap.org/wsdl/" targetNamespace="http://server.ws.soap.baeldung.com/" name="CountryServiceImplService">
<types>
<xsd:schema>
<xsd:import namespace="http://server.ws.soap.baeldung.com/" schemaLocation="country.xsd"/>
</xsd:schema>
</types>
<message name="findByName">
<part name="arg0" type="xsd:string"/>
</message>
<message name="findByNameResponse">
<part name="return" type="tns:country"/>
</message>
<portType name="CountryService">
<operation name="findByName">
<input wsam:Action="http://server.ws.soap.baeldung.com/CountryService/findByNameRequest" message="tns:findByName"/>
<output wsam:Action="http://server.ws.soap.baeldung.com/CountryService/findByNameResponse" message="tns:findByNameResponse"/>
</operation>
</portType>
<binding name="CountryServiceImplPortBinding" type="tns:CountryService">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="rpc"/>
<operation name="findByName">
<soap:operation soapAction=""/>
<input>
<soap:body use="literal" namespace="http://server.ws.soap.baeldung.com/"/>
</input>
<output>
<soap:body use="literal" namespace="http://server.ws.soap.baeldung.com/"/>
</output>
</operation>
</binding>
<service name="CountryServiceImplService">
<port name="CountryServiceImplPort" binding="tns:CountryServiceImplPortBinding">
<soap:address location="http://localhost:8888/ws/country"/>
</port>
</service>
</definitions>

View File

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?><!-- Published by JAX-WS RI (http://jax-ws.java.net). RI's version is JAX-WS RI 2.2.9-b130926.1035 svn-revision#5f6196f2b90e9460065a4c2f4e30e065b245e51e. -->
<xs:schema xmlns:tns="http://server.ws.soap.baeldung.com/" xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" version="1.0"
targetNamespace="http://server.ws.soap.baeldung.com/">
<xs:complexType name="country">
<xs:sequence>
<xs:element name="capital" type="xs:string" minOccurs="0"></xs:element>
<xs:element name="currency" type="tns:currency" minOccurs="0"></xs:element>
<xs:element name="name" type="xs:string" minOccurs="0"></xs:element>
<xs:element name="population" type="xs:int"></xs:element>
</xs:sequence>
</xs:complexType>
<xs:simpleType name="currency">
<xs:restriction base="xs:string">
<xs:enumeration value="EUR"></xs:enumeration>
<xs:enumeration value="INR"></xs:enumeration>
<xs:enumeration value="USD"></xs:enumeration>
</xs:restriction>
</xs:simpleType>
</xs:schema>

View File

@ -0,0 +1,73 @@
package com.baeldung.soap.ws.client;
import org.junit.jupiter.api.*;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.*;
class CountryServiceClientUnitTest {
CountryServiceClient countryServiceClient;
CountryService countryService;
@BeforeEach
void setUp() {
countryService = mock(CountryService.class);
countryServiceClient = new CountryServiceClient(countryService);
}
@DisplayName("Get capital by country name when country not found")
@Test
void givenCountryDoesNotExist_whenGetCapitalByCountryName_thenThrowsCountryNotFoundException() {
doThrow(CountryNotFoundException.class).when(countryService).findByName(any());
Assertions.assertThrows(CountryNotFoundException.class, () -> countryServiceClient.getCapitalByCountryName(any()));
}
@DisplayName("Get capital by country name when country is India then should return capital")
@Test
void givenCountryIndia_whenGetCapitalByCountryName_thenShouldReturnCapital() {
Country country = mock(Country.class);
doReturn("New Delhi").when(country).getCapital();
doReturn(country).when(countryService).findByName("India");
Assertions.assertEquals("New Delhi", countryServiceClient.getCapitalByCountryName("India"));
}
@DisplayName("Get population by country name when country not found")
@Test
void givenCountryDoesNotExist_getPopulationByCountryName_thenThrowsCountryNotFoundException() {
doThrow(CountryNotFoundException.class).when(countryService).findByName(any());
Assertions.assertThrows(CountryNotFoundException.class, () -> countryServiceClient.getPopulationByCountryName(any()));
}
@DisplayName("Get population by country name when country is India then should return population")
@Test
void givenCountryIndia_getPopulationByCountryName_thenShouldReturnPopulation() {
Country country = mock(Country.class);
doReturn(1000000).when(country).getPopulation();
doReturn(country).when(countryService).findByName("India");
Assertions.assertEquals(1000000, countryServiceClient.getPopulationByCountryName("India"));
}
@DisplayName("Get currency by country name when country not found")
@Test
void givenCountryDoesNotExist_getCurrencyByCountryName_thenThrowsCountryNotFoundException() {
doThrow(CountryNotFoundException.class).when(countryService).findByName(any());
Assertions.assertThrows(CountryNotFoundException.class, () -> countryServiceClient.getCurrencyByCountryName(any()));
}
@DisplayName("Get currency by country name when country is India then should return currency")
@Test
void givenCountryIndia_getCurrencyByCountryName_thenShouldReturnCurrency() {
Country country = mock(Country.class);
doReturn(Currency.INR).when(country).getCurrency();
doReturn(country).when(countryService).findByName("India");
Assertions.assertEquals(Currency.INR, countryServiceClient.getCurrencyByCountryName("India"));
}
}

View File

@ -17,6 +17,7 @@
<modules>
<module>custom-rule</module>
<module>maven-enforcer</module>
<module>jaxws</module>
</modules>
<build>

View File

@ -82,7 +82,7 @@
<rest-assured.version>3.3.0</rest-assured.version>
<!-- plugins -->
<thin.version>1.0.22.RELEASE</thin.version>
<spring-boot.version>2.4.0</spring-boot.version>
<spring-boot.version>2.4.3</spring-boot.version>
<aspectjweaver.version>1.9.1</aspectjweaver.version>
<!-- this property can be removed once we update Mockito version in the main pom.xml -->
<mockito.version>3.4.0</mockito.version>

View File

@ -31,7 +31,7 @@
</dependencies>
<properties>
<spring.version>5.2.8.RELEASE</spring.version>
<spring.version>5.3.3</spring.version>
<spring-security.version>5.2.3.RELEASE</spring-security.version>
<spring-boot-starter-test.version>1.5.10.RELEASE</spring-boot-starter-test.version>
</properties>

View File

@ -50,7 +50,7 @@ public class Application implements CommandLineRunner {
LOGGER.info("@@ findByFirstName() call...");
repository.findByFirstName("Franz")
.forEach(person -> LOGGER.info(person.toString()));
LOGGER.info("@@ findByFirstName() call...");
LOGGER.info("@@ updateByFirstName() call...");
repository.updateByFirstName(2L, "Date Inferno");
repository.findAll()
.forEach(person -> LOGGER.info(person.toString()));

View File

@ -1,23 +1,20 @@
package com.baeldung.springdatajdbcintro.repository;
import java.util.List;
import com.baeldung.springdatajdbcintro.entity.Person;
import org.springframework.data.jdbc.repository.query.Modifying;
import org.springframework.data.jdbc.repository.query.Query;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import com.baeldung.springdatajdbcintro.entity.Person;
import java.util.List;
@Repository
public interface PersonRepository extends CrudRepository<Person,Long> {
public interface PersonRepository extends CrudRepository<Person, Long> {
@Query("select * from person where first_name=:firstName")
List<Person> findByFirstName(@Param("firstName") String firstName);
List<Person> findByFirstName(String firstName);
@Modifying
@Query("UPDATE person SET first_name = :name WHERE id = :id")
boolean updateByFirstName(@Param("id") Long id, @Param("name") String name);
}

View File

@ -6,7 +6,6 @@ This module contains articles about annotations used in Spring Data JPA
- [DDD Aggregates and @DomainEvents](https://www.baeldung.com/spring-data-ddd)
- [JPA @Embedded And @Embeddable](https://www.baeldung.com/jpa-embedded-embeddable)
- [Spring Data JPA @Modifying Annotation](https://www.baeldung.com/spring-data-jpa-modifying-annotation)
- [Spring JPA @Embedded and @EmbeddedId](https://www.baeldung.com/spring-jpa-embedded-method-parameters)
- [Programmatic Transaction Management in Spring](https://www.baeldung.com/spring-programmatic-transaction-management)
- [JPA Entity Lifecycle Events](https://www.baeldung.com/jpa-entity-lifecycle-events)

View File

@ -12,6 +12,7 @@ This module contains articles about Spring Data JPA used in enterprise applicati
- [Working with Lazy Element Collections in JPA](https://www.baeldung.com/java-jpa-lazy-collections)
- [Custom Naming Convention with Spring Data JPA](https://www.baeldung.com/spring-data-jpa-custom-naming)
- [Partial Data Update with Spring Data](https://www.baeldung.com/spring-data-partial-update)
- [Spring Data JPA @Modifying Annotation](https://www.baeldung.com/spring-data-jpa-modifying-annotation)
### Eclipse Config
After importing the project into Eclipse, you may see the following error:

View File

@ -93,6 +93,9 @@ public interface UserRepository extends JpaRepository<User, Integer> , UserRepos
@Query("delete User u where u.active = false")
int deleteDeactivatedUsers();
@Query("delete User u where u.active = false")
int deleteDeactivatedUsersWithNoModifyingAnnotation();
@Modifying(clearAutomatically = true, flushAutomatically = true)
@Query(value = "alter table USERS add column deleted int(1) not null default 0", nativeQuery = true)
void addDeletedColumn();

View File

@ -3,6 +3,7 @@ package com.baeldung.boot.daos;
import org.junit.After;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
@ -21,6 +22,7 @@ import java.util.function.Predicate;
import java.util.stream.Stream;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.junit.Assert.*;
public class UserRepositoryCommon {
@ -520,6 +522,22 @@ public class UserRepositoryCommon {
assertEquals(1, deletedUsersCount);
}
@Test
@Transactional
public void givenTwoUsers_whenDeleteDeactivatedUsersWithNoModifyingAnnotation_ThenException() {
User usr01 = new User("usr01", LocalDate.of(2018, 1, 1), "usr01@baeldung.com", 1);
usr01.setLastLoginDate(LocalDate.now());
User usr02 = new User("usr02", LocalDate.of(2018, 6, 1), "usr02@baeldung.com", 0);
usr02.setLastLoginDate(LocalDate.of(2018, 7, 20));
usr02.setActive(false);
userRepository.save(usr01);
userRepository.save(usr02);
assertThatThrownBy(() -> userRepository.deleteDeactivatedUsersWithNoModifyingAnnotation())
.isInstanceOf(InvalidDataAccessApiUsageException.class);
}
@Test
@Transactional
public void givenTwoUsers_whenAddDeletedColumn_ThenUsersHaveDeletedColumn() {

View File

@ -471,7 +471,7 @@
<module>json-path</module>
<module>jsoup</module>
<module>jta</module>
<module>kubernetes</module>
<!-- <module>lagom</module> --> <!-- Not a maven project -->
<module>language-interop</module>
<module>libraries-2</module>
@ -531,7 +531,7 @@
<module>protobuffer</module>
<module>quarkus</module>
<module>quarkus-extension</module>
<!-- <module>quarkus-extension</module> --> <!-- Module broken, fixing in http://team.baeldung.com/browse/JAVA-4770 -->
<module>rabbitmq</module>
<!-- <module>raml</module> --> <!-- Not a maven project -->
@ -992,7 +992,7 @@
<module>protobuffer</module>
<module>quarkus</module>
<module>quarkus-extension</module>
<!-- <module>quarkus-extension</module> --> <!-- Module broken, fixing in http://team.baeldung.com/browse/JAVA-4770 -->
<module>rabbitmq</module>
<!-- <module>raml</module> --> <!-- Not a maven project -->
@ -1370,7 +1370,7 @@
<exec-maven-plugin.version>1.6.0</exec-maven-plugin.version>
<java.version>1.8</java.version>
<log4j.version>1.2.17</log4j.version>
<esapi.version>2.1.0.1</esapi.version>
<esapi.version>2.2.2.0</esapi.version>
<jmh-core.version>1.19</jmh-core.version>
<jmh-generator.version>1.19</jmh-generator.version>
<exec-maven-plugin.version>1.6.0</exec-maven-plugin.version>

View File

@ -174,7 +174,7 @@
<jsonb-api.version>1.0</jsonb-api.version>
<geronimo-json_1.1_spec.version>1.0</geronimo-json_1.1_spec.version>
<commons-collections4.version>4.1</commons-collections4.version>
<jetty-reactive-httpclient.version>1.0.3</jetty-reactive-httpclient.version>
<jetty-reactive-httpclient.version>1.1.6</jetty-reactive-httpclient.version>
<okhttp.version>4.0.1</okhttp.version>
</properties>

View File

@ -0,0 +1,39 @@
package com.baeldung.boot.readonlyrepository;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity
public class Book
{
@Id
@GeneratedValue
private Long id;
private String author;
private String title;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}

View File

@ -0,0 +1,10 @@
package com.baeldung.boot.readonlyrepository;
import java.util.List;
public interface BookReadOnlyRepository extends ReadOnlyRepository<Book, Long> {
List<Book> findByAuthor(String author);
List<Book> findByTitle(String title);
}

View File

@ -0,0 +1,15 @@
package com.baeldung.boot.readonlyrepository;
import org.springframework.data.repository.NoRepositoryBean;
import org.springframework.data.repository.Repository;
import java.util.List;
import java.util.Optional;
@NoRepositoryBean
public interface ReadOnlyRepository<T, ID> extends Repository<T, ID> {
Optional<T> findById(ID id);
List<T> findAll();
}

View File

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

View File

@ -0,0 +1,6 @@
package com.baeldung.boot.readonlyrepository;
import org.springframework.data.repository.CrudRepository;
public interface BookRepository extends BookReadOnlyRepository, CrudRepository<Book, Long> {
}

View File

@ -0,0 +1,50 @@
package com.baeldung.boot.readonlyrepository;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.List;
import java.util.NoSuchElementException;
@SpringBootTest( classes = ReadOnlyRepositoryApplication.class )
public class ReadOnlyRepositoryUnitTest
{
@Autowired
private BookRepository bookRepository;
@Autowired
private BookReadOnlyRepository bookReadOnlyRepository;
@Test
public void givenBooks_whenUsingReadOnlyRepository_thenGetThem() {
Book aChristmasCarolCharlesDickens = new Book();
aChristmasCarolCharlesDickens.setTitle("A Christmas Carol");
aChristmasCarolCharlesDickens.setAuthor("Charles Dickens");
bookRepository.save(aChristmasCarolCharlesDickens);
Book greatExpectationsCharlesDickens = new Book();
greatExpectationsCharlesDickens.setTitle("Great Expectations");
greatExpectationsCharlesDickens.setAuthor("Charles Dickens");
bookRepository.save(greatExpectationsCharlesDickens);
Book greatExpectationsKathyAcker = new Book();
greatExpectationsKathyAcker.setTitle("Great Expectations");
greatExpectationsKathyAcker.setAuthor("Kathy Acker");
bookRepository.save(greatExpectationsKathyAcker);
List<Book> charlesDickensBooks = bookReadOnlyRepository.findByAuthor("Charles Dickens");
Assertions.assertEquals(2, charlesDickensBooks.size());
List<Book> greatExpectationsBooks = bookReadOnlyRepository.findByTitle("Great Expectations");
Assertions.assertEquals(2, greatExpectationsBooks.size());
List<Book> allBooks = bookReadOnlyRepository.findAll();
Assertions.assertEquals(3, allBooks.size());
Long bookId = allBooks.get(0).getId();
Book book = bookReadOnlyRepository.findById(bookId).orElseThrow(NoSuchElementException::new);
Assertions.assertNotNull(book);
}
}

View File

@ -84,12 +84,6 @@
<version>${jquery.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-context</artifactId>
<version>${springcloud.version}</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
@ -195,9 +189,7 @@
<jpa.version>2.2</jpa.version>
<guava.version>18.0</guava.version>
<subethasmtp.version>3.1.7</subethasmtp.version>
<springcloud.version>2.0.2.RELEASE</springcloud.version>
<httpclient.version>4.5.8</httpclient.version>
<spring-boot.version>2.3.3.RELEASE</spring-boot.version>
</properties>
</project>

View File

@ -1,34 +1,35 @@
package com.baeldung.charencoding.controller;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import java.io.IOException;
import org.junit.jupiter.api.Test;
import org.springframework.mock.web.MockFilterChain;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.web.filter.CharacterEncodingFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import org.junit.jupiter.api.Test;
import org.springframework.web.filter.CharacterEncodingFilter;
import static org.junit.jupiter.api.Assertions.assertEquals;
class CharEncodingCheckControllerUnitTest {
@Test
void whenCharEncodingFilter_thenVerifyEncoding() throws ServletException, IOException {
HttpServletRequest request = mock(HttpServletRequest.class);
HttpServletResponse response = mock(HttpServletResponse.class);
FilterChain chain = mock(FilterChain.class);
HttpServletRequest request = new MockHttpServletRequest();
HttpServletResponse response = new MockHttpServletResponse();
FilterChain chain = new MockFilterChain();
CharacterEncodingFilter filter = new CharacterEncodingFilter();
filter.setEncoding("UTF-8");
filter.setForceEncoding(true);
filter.doFilter(request, response, chain);
verify(request).setCharacterEncoding("UTF-8");
verify(response).setCharacterEncoding("UTF-8");
assertEquals("UTF-8", request.getCharacterEncoding());
assertEquals("UTF-8", response.getCharacterEncoding());
}
}

View File

@ -5,4 +5,4 @@ This module contains articles about Spring Boot: JAX-RS vs Spring
### Relevant Articles:
- [REST API: JAX-RS vs Spring](https://www.baeldung.com/TBD)
- [REST API: JAX-RS vs Spring](https://www.baeldung.com/rest-api-jax-rs-vs-spring)

View File

@ -2,6 +2,7 @@ package com.baeldung.boot.properties.multidocument;
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;
@ -21,6 +22,7 @@ public class StagingMultidocumentFilesIntegrationTest {
private String baelRootProperty;
@Test
@Disabled("Fix and update https://www.baeldung.com/spring-boot-yaml-vs-properties article")
public void givenProductionProfileActive_whenApplicationStarts_thenDefaultPropertiesUser() {
assertThat(baelCustomProperty).isEqualTo("stagingValue");
assertThat(baelRootProperty).isEqualTo("defaultRootLevelValue");

View File

@ -0,0 +1,3 @@
### Relevant Article:
- [Get All Endpoints in Spring Boot](https://www.baeldung.com/spring-boot-get-all-endpoints)

View File

@ -0,0 +1,44 @@
<?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>
<groupId>com.baeldung.web</groupId>
<artifactId>spring-boot-rest-2</artifactId>
<name>spring-boot-rest-2</name>
<packaging>war</packaging>
<description>Spring Boot Rest Module</description>
<parent>
<groupId>com.baeldung</groupId>
<artifactId>parent-boot-2</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../parent-boot-2</relativePath>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
<version>3.0.0</version>
</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,12 @@
package com.baeldung.endpoint;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringBootRestApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootRestApplication.class, args);
}
}

View File

@ -0,0 +1,15 @@
package com.baeldung.endpoint.controller;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
@GetMapping("/hello")
public ResponseEntity<String> hello() {
return ResponseEntity.ok("hello baeldung");
}
}

View File

@ -0,0 +1,27 @@
package com.baeldung.endpoint.listener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.context.event.EventListener;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import java.util.Map;
@Configuration
public class AnnotationDrivenEndpointsListener {
private final Logger LOGGER = LoggerFactory.getLogger("AnnotationDrivenEndpointsListener.class");
@EventListener
public void handleContextRefresh(ContextRefreshedEvent event) {
ApplicationContext applicationContext = event.getApplicationContext();
RequestMappingHandlerMapping requestMappingHandlerMapping = applicationContext
.getBean("requestMappingHandlerMapping", RequestMappingHandlerMapping.class);
Map<RequestMappingInfo, HandlerMethod> map = requestMappingHandlerMapping.getHandlerMethods();
map.forEach((key, value) -> LOGGER.info("{} {}", key, value));
}
}

View File

@ -0,0 +1,27 @@
package com.baeldung.endpoint.listener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import java.util.Map;
@Configuration
public class EndpointsListener implements ApplicationListener<ContextRefreshedEvent> {
private final Logger LOGGER = LoggerFactory.getLogger("EndpointsListener.class");
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
ApplicationContext applicationContext = event.getApplicationContext();
RequestMappingHandlerMapping requestMappingHandlerMapping = applicationContext
.getBean("requestMappingHandlerMapping", RequestMappingHandlerMapping.class);
Map<RequestMappingInfo, HandlerMethod> map = requestMappingHandlerMapping.getHandlerMethods();
map.forEach((key, value) -> LOGGER.info("{} {}", key, value));
}
}

View File

@ -0,0 +1,21 @@
package com.baeldung.endpoint.swagger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
@Configuration
public class SpringFoxConfig {
@Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any())
.build();
}
}

View File

@ -0,0 +1,2 @@
management.endpoints.web.exposure.include=mappings

View File

@ -79,7 +79,6 @@
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-commons</artifactId>
<version>2.3.0.RELEASE</version>
</dependency>
</dependencies>
<properties>

View File

@ -38,6 +38,11 @@
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
<version>${spring-cloud-netflix-zuul.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
@ -46,10 +51,6 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
@ -79,8 +80,8 @@
</build>
<properties>
<spring-cloud.version>Hoxton.SR4</spring-cloud.version>
<spring-boot.version>2.3.3.RELEASE</spring-boot.version>
<spring-cloud.version>2020.0.0</spring-cloud.version>
<spring-cloud-netflix-zuul.version>2.2.2.RELEASE</spring-cloud-netflix-zuul.version>
</properties>
</project>

View File

@ -19,6 +19,10 @@
<artifactId>spring-cloud-zuul-ratelimit</artifactId>
<version>${rate.limit.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>

View File

@ -13,6 +13,10 @@
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>

View File

@ -0,0 +1,45 @@
package com.baeldung.scheduling.dynamic;
import java.time.Instant;
import java.util.Date;
import java.util.Optional;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
@Configuration
@ComponentScan("com.baeldung.scheduling.dynamic")
@EnableScheduling
public class DynamicSchedulingConfig implements SchedulingConfigurer {
@Autowired
private TickService tickService;
@Bean
public Executor taskExecutor() {
return Executors.newSingleThreadScheduledExecutor();
}
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
taskRegistrar.setScheduler(taskExecutor());
taskRegistrar.addTriggerTask(
() -> tickService.tick(),
context -> {
Optional<Date> lastCompletionTime =
Optional.ofNullable(context.lastCompletionTime());
Instant nextExecutionTime =
lastCompletionTime.orElseGet(Date::new).toInstant()
.plusMillis(tickService.getDelay());
return Date.from(nextExecutionTime);
}
);
}
}

View File

@ -0,0 +1,22 @@
package com.baeldung.scheduling.dynamic;
import org.springframework.stereotype.Service;
@Service
public class TickService {
private long delay = 0;
public long getDelay() {
this.delay += 1000;
System.out.println("delaying " + this.delay + " milliseconds...");
return this.delay;
}
public void tick() {
final long now = System.currentTimeMillis() / 1000;
System.out
.println("schedule tasks with dynamic delay - " + now);
}
}

View File

@ -0,0 +1,19 @@
package com.baeldung.scheduling;
import com.baeldung.scheduling.dynamic.DynamicSchedulingConfig;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.support.AnnotationConfigContextLoader;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {
DynamicSchedulingConfig.class}, loader = AnnotationConfigContextLoader.class)
public class DynamicSchedulingIntegrationTest {
@Test
public void testTickServiceTick() throws InterruptedException {
Thread.sleep(6000);
}
}

View File

@ -35,6 +35,7 @@
<module>spring-security-legacy-oidc</module>
<module>spring-security-oidc</module>
<module>spring-security-okta</module>
<module>spring-security-saml</module>
<module>spring-security-web-react</module>
<module>spring-security-web-rest</module>
<module>spring-security-web-rest-basic-auth</module>

View File

@ -49,7 +49,7 @@
<dependency>
<groupId>org.owasp.esapi</groupId>
<artifactId>esapi</artifactId>
<version>2.2.2.0</version>
<version>${esapi.version}</version>
</dependency>
<dependency>
<groupId>org.jsoup</groupId>

View File

@ -0,0 +1,3 @@
### Relevant Articles:
- [A Guide to SAML with Spring Security](https://www.baeldung.com/spring-security-saml)

View File

@ -0,0 +1,73 @@
<?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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>spring-security-saml</artifactId>
<version>1.0-SNAPSHOT</version>
<name>spring-security-saml</name>
<packaging>war</packaging>
<parent>
<groupId>com.baeldung</groupId>
<artifactId>parent-boot-2</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../../parent-boot-2</relativePath>
</parent>
<repositories>
<repository>
<id>Shibboleth</id>
<name>Shibboleth</name>
<url>https://build.shibboleth.net/nexus/content/repositories/releases/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security.extensions</groupId>
<artifactId>spring-security-saml2-core</artifactId>
<version>${saml2-core.spring.version}</version>
</dependency>
</dependencies>
<build>
<finalName>spring-security-saml</finalName>
<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<addResources>true</addResources>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<properties>
<saml2-core.spring.version>1.0.10.RELEASE</saml2-core.spring.version>
</properties>
</project>

View File

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

View File

@ -0,0 +1,28 @@
package com.baeldung.saml.authentication;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.providers.ExpiringUsernameAuthenticationToken;
import org.springframework.security.saml.SAMLAuthenticationProvider;
import org.springframework.security.saml.SAMLCredential;
public class CustomSAMLAuthenticationProvider extends SAMLAuthenticationProvider {
@Override
public Collection<? extends GrantedAuthority> getEntitlements(SAMLCredential credential, Object userDetail) {
if(userDetail instanceof ExpiringUsernameAuthenticationToken) {
List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
authorities.addAll(((ExpiringUsernameAuthenticationToken) userDetail).getAuthorities());
return authorities;
} else {
return Collections.emptyList();
}
}
}

Some files were not shown because too many files have changed in this diff Show More