Merge branch 'eugenp:master' into master
This commit is contained in:
		
						commit
						463a4aeee9
					
				| @ -13,4 +13,3 @@ This module contains articles about Java 11 core features | |||||||
| - [Call Methods at Runtime Using Java Reflection](https://www.baeldung.com/java-method-reflection) | - [Call Methods at Runtime Using Java Reflection](https://www.baeldung.com/java-method-reflection) | ||||||
| - [Java HttpClient Basic Authentication](https://www.baeldung.com/java-httpclient-basic-auth) | - [Java HttpClient Basic Authentication](https://www.baeldung.com/java-httpclient-basic-auth) | ||||||
| - [Java HttpClient With SSL](https://www.baeldung.com/java-httpclient-ssl) | - [Java HttpClient With SSL](https://www.baeldung.com/java-httpclient-ssl) | ||||||
| - [Adding Parameters to Java HttpClient Requests](https://www.baeldung.com/java-httpclient-request-parameters) |  | ||||||
|  | |||||||
							
								
								
									
										6
									
								
								core-java-modules/core-java-11-3/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								core-java-modules/core-java-11-3/README.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,6 @@ | |||||||
|  | ## Core Java 11 | ||||||
|  | 
 | ||||||
|  | This module contains articles about Java 11 core features | ||||||
|  | 
 | ||||||
|  | ### Relevant articles | ||||||
|  | - [Adding Parameters to Java HttpClient Requests](https://www.baeldung.com/java-httpclient-request-parameters) | ||||||
							
								
								
									
										37
									
								
								core-java-modules/core-java-11-3/pom.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								core-java-modules/core-java-11-3/pom.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,37 @@ | |||||||
|  | <?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-11-3</artifactId> | ||||||
|  |     <version>0.1.0-SNAPSHOT</version> | ||||||
|  |     <name>core-java-11-3</name> | ||||||
|  |     <packaging>jar</packaging> | ||||||
|  | 
 | ||||||
|  |     <parent> | ||||||
|  |         <groupId>com.baeldung</groupId> | ||||||
|  |         <artifactId>parent-modules</artifactId> | ||||||
|  |         <version>1.0.0-SNAPSHOT</version> | ||||||
|  |         <relativePath>../../pom.xml</relativePath> | ||||||
|  |     </parent> | ||||||
|  | 
 | ||||||
|  |     <build> | ||||||
|  |         <plugins> | ||||||
|  |             <plugin> | ||||||
|  |                 <groupId>org.apache.maven.plugins</groupId> | ||||||
|  |                 <artifactId>maven-compiler-plugin</artifactId> | ||||||
|  |                 <version>${maven-compiler-plugin.version}</version> | ||||||
|  |                 <configuration> | ||||||
|  |                     <source>${maven.compiler.source.version}</source> | ||||||
|  |                     <target>${maven.compiler.target.version}</target> | ||||||
|  |                 </configuration> | ||||||
|  |             </plugin> | ||||||
|  |         </plugins> | ||||||
|  |     </build> | ||||||
|  | 
 | ||||||
|  |     <properties> | ||||||
|  |         <maven.compiler.source.version>11</maven.compiler.source.version> | ||||||
|  |         <maven.compiler.target.version>11</maven.compiler.target.version> | ||||||
|  |     </properties> | ||||||
|  | 
 | ||||||
|  | </project> | ||||||
| @ -0,0 +1,24 @@ | |||||||
|  | package com.baeldung.map.multikey; | ||||||
|  | 
 | ||||||
|  | import java.util.HashMap; | ||||||
|  | import java.util.Map; | ||||||
|  | 
 | ||||||
|  | public class BaseClassUserCache { | ||||||
|  |     private final Map<Object, User> cache = new HashMap<>(); | ||||||
|  | 
 | ||||||
|  |     public User getById(String id) { | ||||||
|  |         return cache.get(id); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public User getById(Long id) { | ||||||
|  |         return cache.get(id); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void storeById(String id, User user) { | ||||||
|  |         cache.put(id, user); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void storeById(Long id, User user) { | ||||||
|  |         cache.put(id, user); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,25 @@ | |||||||
|  | package com.baeldung.map.multikey; | ||||||
|  | 
 | ||||||
|  | import java.util.HashMap; | ||||||
|  | import java.util.Map; | ||||||
|  | 
 | ||||||
|  | public class MultipleMapsUserCache { | ||||||
|  |     private final Map<String, User> stringCache = new HashMap<>(); | ||||||
|  |     private final Map<Long, User> longCache = new HashMap<>(); | ||||||
|  | 
 | ||||||
|  |     public User getById(String id) { | ||||||
|  |         return stringCache.get(id); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public User getById(Long id) { | ||||||
|  |         return longCache.get(id); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void storeById(String id, User user) { | ||||||
|  |         stringCache.put(id, user); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void storeById(Long id, User user) { | ||||||
|  |         longCache.put(id, user); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,13 @@ | |||||||
|  | package com.baeldung.map.multikey; | ||||||
|  | 
 | ||||||
|  | public class User { | ||||||
|  |     private final String name; | ||||||
|  | 
 | ||||||
|  |     public User(String name) { | ||||||
|  |         this.name = name; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public String getName() { | ||||||
|  |         return name; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,42 @@ | |||||||
|  | package com.baeldung.map.multikey; | ||||||
|  | 
 | ||||||
|  | import java.util.HashMap; | ||||||
|  | import java.util.Map; | ||||||
|  | import java.util.Objects; | ||||||
|  | 
 | ||||||
|  | public class WrapperClassUserCache { | ||||||
|  |     private Map<CacheKey, User> cache = new HashMap<>(); | ||||||
|  | 
 | ||||||
|  |     public User getById(CacheKey key) { | ||||||
|  |         return cache.get(key); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void storeById(CacheKey key, User user) { | ||||||
|  |         cache.put(key, user); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static class CacheKey { | ||||||
|  |         private final Object value; | ||||||
|  | 
 | ||||||
|  |         public CacheKey(String value) { | ||||||
|  |             this.value = value; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public CacheKey(Long value) { | ||||||
|  |             this.value = value; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         @Override | ||||||
|  |         public boolean equals(Object o) { | ||||||
|  |             if (this == o) return true; | ||||||
|  |             if (o == null || getClass() != o.getClass()) return false; | ||||||
|  |             CacheKey cacheKey = (CacheKey) o; | ||||||
|  |             return value.equals(cacheKey.value); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         @Override | ||||||
|  |         public int hashCode() { | ||||||
|  |             return Objects.hash(value); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,62 @@ | |||||||
|  | package com.baeldung.map.multikey; | ||||||
|  | 
 | ||||||
|  | import java.util.HashMap; | ||||||
|  | import java.util.Map; | ||||||
|  | import java.util.Objects; | ||||||
|  | 
 | ||||||
|  | public class WrapperInterfaceUserCache { | ||||||
|  |     private Map<CacheKey, User> cache = new HashMap<>(); | ||||||
|  | 
 | ||||||
|  |     public User getById(CacheKey key) { | ||||||
|  |         return cache.get(key); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void storeById(CacheKey key, User user) { | ||||||
|  |         cache.put(key, user); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public interface CacheKey { | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static class StringCacheKey implements CacheKey{ | ||||||
|  |         private final String value; | ||||||
|  | 
 | ||||||
|  |         public StringCacheKey(String value) { | ||||||
|  |             this.value = value; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         @Override | ||||||
|  |         public boolean equals(Object o) { | ||||||
|  |             if (this == o) return true; | ||||||
|  |             if (o == null || getClass() != o.getClass()) return false; | ||||||
|  |             StringCacheKey that = (StringCacheKey) o; | ||||||
|  |             return value.equals(that.value); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         @Override | ||||||
|  |         public int hashCode() { | ||||||
|  |             return Objects.hash(value); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static class LongCacheKey implements CacheKey { | ||||||
|  |         private final Long value; | ||||||
|  | 
 | ||||||
|  |         public LongCacheKey(Long value) { | ||||||
|  |             this.value = value; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         @Override | ||||||
|  |         public boolean equals(Object o) { | ||||||
|  |             if (this == o) return true; | ||||||
|  |             if (o == null || getClass() != o.getClass()) return false; | ||||||
|  |             LongCacheKey that = (LongCacheKey) o; | ||||||
|  |             return value.equals(that.value); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         @Override | ||||||
|  |         public int hashCode() { | ||||||
|  |             return Objects.hash(value); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,32 @@ | |||||||
|  | package com.baeldung.map.multikey; | ||||||
|  | 
 | ||||||
|  | import org.junit.jupiter.api.BeforeEach; | ||||||
|  | import org.junit.jupiter.api.Test; | ||||||
|  | 
 | ||||||
|  | import static org.junit.jupiter.api.Assertions.*; | ||||||
|  | 
 | ||||||
|  | class BaseClassUserCacheUnitTest { | ||||||
|  |     private BaseClassUserCache cache = new BaseClassUserCache(); | ||||||
|  | 
 | ||||||
|  |     @BeforeEach | ||||||
|  |     public void setup() { | ||||||
|  |         cache.storeById("a", new User("User A")); | ||||||
|  |         cache.storeById("b", new User("User B")); | ||||||
|  |         cache.storeById(3L, new User("User 3")); | ||||||
|  |         cache.storeById(4L, new User("User 4")); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void getByString() { | ||||||
|  |         User user = cache.getById("b"); | ||||||
|  |         assertNotNull(user); | ||||||
|  |         assertEquals("User B", user.getName()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void getByLong() { | ||||||
|  |         User user = cache.getById(4L); | ||||||
|  |         assertNotNull(user); | ||||||
|  |         assertEquals("User 4", user.getName()); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,33 @@ | |||||||
|  | package com.baeldung.map.multikey; | ||||||
|  | 
 | ||||||
|  | import org.junit.jupiter.api.BeforeEach; | ||||||
|  | import org.junit.jupiter.api.Test; | ||||||
|  | 
 | ||||||
|  | import static org.junit.jupiter.api.Assertions.assertEquals; | ||||||
|  | import static org.junit.jupiter.api.Assertions.assertNotNull; | ||||||
|  | 
 | ||||||
|  | class MultipleMapsUserCacheUnitTest { | ||||||
|  |     private MultipleMapsUserCache cache = new MultipleMapsUserCache(); | ||||||
|  | 
 | ||||||
|  |     @BeforeEach | ||||||
|  |     public void setup() { | ||||||
|  |         cache.storeById("a", new User("User A")); | ||||||
|  |         cache.storeById("b", new User("User B")); | ||||||
|  |         cache.storeById(3L, new User("User 3")); | ||||||
|  |         cache.storeById(4L, new User("User 4")); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void getByString() { | ||||||
|  |         User user = cache.getById("b"); | ||||||
|  |         assertNotNull(user); | ||||||
|  |         assertEquals("User B", user.getName()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void getByLong() { | ||||||
|  |         User user = cache.getById(4L); | ||||||
|  |         assertNotNull(user); | ||||||
|  |         assertEquals("User 4", user.getName()); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,33 @@ | |||||||
|  | package com.baeldung.map.multikey; | ||||||
|  | 
 | ||||||
|  | import org.junit.jupiter.api.BeforeEach; | ||||||
|  | import org.junit.jupiter.api.Test; | ||||||
|  | 
 | ||||||
|  | import static org.junit.jupiter.api.Assertions.assertEquals; | ||||||
|  | import static org.junit.jupiter.api.Assertions.assertNotNull; | ||||||
|  | 
 | ||||||
|  | class WrapperClassUserCacheUnitTest { | ||||||
|  |     private WrapperClassUserCache cache = new WrapperClassUserCache(); | ||||||
|  | 
 | ||||||
|  |     @BeforeEach | ||||||
|  |     public void setup() { | ||||||
|  |         cache.storeById(new WrapperClassUserCache.CacheKey("a"), new User("User A")); | ||||||
|  |         cache.storeById(new WrapperClassUserCache.CacheKey("b"), new User("User B")); | ||||||
|  |         cache.storeById(new WrapperClassUserCache.CacheKey(3L), new User("User 3")); | ||||||
|  |         cache.storeById(new WrapperClassUserCache.CacheKey(4L), new User("User 4")); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void getByString() { | ||||||
|  |         User user = cache.getById(new WrapperClassUserCache.CacheKey("b")); | ||||||
|  |         assertNotNull(user); | ||||||
|  |         assertEquals("User B", user.getName()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void getByLong() { | ||||||
|  |         User user = cache.getById(new WrapperClassUserCache.CacheKey(4L)); | ||||||
|  |         assertNotNull(user); | ||||||
|  |         assertEquals("User 4", user.getName()); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,33 @@ | |||||||
|  | package com.baeldung.map.multikey; | ||||||
|  | 
 | ||||||
|  | import org.junit.jupiter.api.BeforeEach; | ||||||
|  | import org.junit.jupiter.api.Test; | ||||||
|  | 
 | ||||||
|  | import static org.junit.jupiter.api.Assertions.assertEquals; | ||||||
|  | import static org.junit.jupiter.api.Assertions.assertNotNull; | ||||||
|  | 
 | ||||||
|  | class WrapperInterfaceUserCacheUnitTest { | ||||||
|  |     private WrapperInterfaceUserCache cache = new WrapperInterfaceUserCache(); | ||||||
|  | 
 | ||||||
|  |     @BeforeEach | ||||||
|  |     public void setup() { | ||||||
|  |         cache.storeById(new WrapperInterfaceUserCache.StringCacheKey("a"), new User("User A")); | ||||||
|  |         cache.storeById(new WrapperInterfaceUserCache.StringCacheKey("b"), new User("User B")); | ||||||
|  |         cache.storeById(new WrapperInterfaceUserCache.LongCacheKey(3L), new User("User 3")); | ||||||
|  |         cache.storeById(new WrapperInterfaceUserCache.LongCacheKey(4L), new User("User 4")); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void getByString() { | ||||||
|  |         User user = cache.getById(new WrapperInterfaceUserCache.StringCacheKey("b")); | ||||||
|  |         assertNotNull(user); | ||||||
|  |         assertEquals("User B", user.getName()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void getByLong() { | ||||||
|  |         User user = cache.getById(new WrapperInterfaceUserCache.LongCacheKey(4L)); | ||||||
|  |         assertNotNull(user); | ||||||
|  |         assertEquals("User 4", user.getName()); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -43,6 +43,16 @@ | |||||||
|             <version>3.23.1</version> |             <version>3.23.1</version> | ||||||
|             <scope>test</scope> |             <scope>test</scope> | ||||||
|         </dependency> |         </dependency> | ||||||
|  |         <dependency> | ||||||
|  |             <groupId>org.openjdk.jmh</groupId> | ||||||
|  |             <artifactId>jmh-core</artifactId> | ||||||
|  |             <version>${jmh-core.version}</version> | ||||||
|  |         </dependency> | ||||||
|  |         <dependency> | ||||||
|  |             <groupId>org.openjdk.jmh</groupId> | ||||||
|  |             <artifactId>jmh-generator-annprocess</artifactId> | ||||||
|  |             <version>${jmh-generator.version}</version> | ||||||
|  |         </dependency> | ||||||
|     </dependencies> |     </dependencies> | ||||||
| 
 | 
 | ||||||
|     <build> |     <build> | ||||||
|  | |||||||
| @ -0,0 +1,56 @@ | |||||||
|  | package com.baeldung.streams.filteronlyoneelement; | ||||||
|  | 
 | ||||||
|  | import java.util.function.Predicate; | ||||||
|  | import java.util.stream.IntStream; | ||||||
|  | import java.util.stream.Stream; | ||||||
|  | 
 | ||||||
|  | import org.openjdk.jmh.annotations.Benchmark; | ||||||
|  | import org.openjdk.jmh.annotations.Scope; | ||||||
|  | import org.openjdk.jmh.annotations.State; | ||||||
|  | import org.openjdk.jmh.infra.Blackhole; | ||||||
|  | 
 | ||||||
|  | public class BenchmarkRunner { | ||||||
|  | 
 | ||||||
|  |     public static void main(String[] args) throws Exception { | ||||||
|  |         org.openjdk.jmh.Main.main(args); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @State(Scope.Benchmark) | ||||||
|  |     public static class MyState { | ||||||
|  |         final Stream<Integer> getIntegers() { | ||||||
|  |             return IntStream.range(1, 1000000) | ||||||
|  |                 .boxed(); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         final Predicate<Integer> PREDICATE = i -> i == 751879; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Benchmark | ||||||
|  |     public void evaluateFindUniqueElementMatchingPredicate_WithReduction(Blackhole blackhole, MyState state) { | ||||||
|  |         blackhole.consume(FilterUtils.findUniqueElementMatchingPredicate_WithReduction(state.getIntegers(), state.PREDICATE)); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Benchmark | ||||||
|  |     public void evaluateFindUniqueElementMatchingPredicate_WithCollectingAndThen(Blackhole blackhole, MyState state) { | ||||||
|  |         blackhole.consume(FilterUtils.findUniqueElementMatchingPredicate_WithCollectingAndThen(state.getIntegers(), state.PREDICATE)); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Benchmark | ||||||
|  |     public void evaluateGetUniqueElementMatchingPredicate_WithReduction(Blackhole blackhole, MyState state) { | ||||||
|  |         try { | ||||||
|  |             FilterUtils.getUniqueElementMatchingPredicate_WithReduction(state.getIntegers(), state.PREDICATE); | ||||||
|  |         } catch (IllegalStateException exception) { | ||||||
|  |             blackhole.consume(exception); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Benchmark | ||||||
|  |     public void evaluateGetUniqueElementMatchingPredicate_WithCollectingAndThen(Blackhole blackhole, MyState state) { | ||||||
|  |         try { | ||||||
|  |             FilterUtils.getUniqueElementMatchingPredicate_WithCollectingAndThen(state.getIntegers(), state.PREDICATE); | ||||||
|  |         } catch (IllegalStateException exception) { | ||||||
|  |             blackhole.consume(exception); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
| @ -0,0 +1,50 @@ | |||||||
|  | package com.baeldung.streams.filteronlyoneelement; | ||||||
|  | 
 | ||||||
|  | import java.util.List; | ||||||
|  | import java.util.Optional; | ||||||
|  | import java.util.function.Predicate; | ||||||
|  | import java.util.stream.Collectors; | ||||||
|  | import java.util.stream.Stream; | ||||||
|  | 
 | ||||||
|  | public class FilterUtils { | ||||||
|  | 
 | ||||||
|  |     public static <T> Optional<T> findUniqueElementMatchingPredicate_WithReduction(Stream<T> elements, Predicate<T> predicate) { | ||||||
|  |         return elements.filter(predicate) | ||||||
|  |             .collect(Collectors.reducing((a, b) -> null)); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static <T> T getUniqueElementMatchingPredicate_WithReduction(Stream<T> elements, Predicate<T> predicate) { | ||||||
|  |         return elements.filter(predicate) | ||||||
|  |             .reduce((a, b) -> { | ||||||
|  |                 throw new IllegalStateException("Too many elements match the predicate"); | ||||||
|  |             }) | ||||||
|  |             .orElseThrow(() -> new IllegalStateException("No element matches the predicate")); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static <T> Optional<T> findUniqueElementMatchingPredicate_WithCollectingAndThen(Stream<T> elements, Predicate<T> predicate) { | ||||||
|  |         return elements.filter(predicate) | ||||||
|  |             .collect(Collectors.collectingAndThen(Collectors.toList(), list -> Optional.ofNullable(findUniqueElement(list)))); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private static <T> T findUniqueElement(List<T> elements) { | ||||||
|  |         if (elements.size() == 1) { | ||||||
|  |             return elements.get(0); | ||||||
|  |         } | ||||||
|  |         return null; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static <T> T getUniqueElementMatchingPredicate_WithCollectingAndThen(Stream<T> elements, Predicate<T> predicate) { | ||||||
|  |         return elements.filter(predicate) | ||||||
|  |             .collect(Collectors.collectingAndThen(Collectors.toList(), FilterUtils::getUniqueElement)); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private static <T> T getUniqueElement(List<T> elements) { | ||||||
|  |         if (elements.size() > 1) { | ||||||
|  |             throw new IllegalStateException("Too many elements match the predicate"); | ||||||
|  |         } else if (elements.size() == 0) { | ||||||
|  |             throw new IllegalStateException("No element matches the predicate"); | ||||||
|  |         } | ||||||
|  |         return elements.get(0); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
| @ -0,0 +1,88 @@ | |||||||
|  | package com.baeldung.streams.filteronlyoneelement; | ||||||
|  | 
 | ||||||
|  | import static org.junit.jupiter.api.Assertions.assertEquals; | ||||||
|  | import static org.junit.jupiter.api.Assertions.assertThrows; | ||||||
|  | import static org.junit.jupiter.api.Assertions.assertTrue; | ||||||
|  | 
 | ||||||
|  | import java.util.function.Predicate; | ||||||
|  | import java.util.stream.Stream; | ||||||
|  | 
 | ||||||
|  | import org.junit.jupiter.api.Test; | ||||||
|  | 
 | ||||||
|  | public class FilterUtilsUnitTest { | ||||||
|  | 
 | ||||||
|  |     private static final Predicate<Integer> IS_STRICTLY_GREATER_THAN5 = i -> i > 5; | ||||||
|  |     private static final Predicate<Integer> IS_STRICTLY_GREATER_THAN4 = i -> i > 4; | ||||||
|  |     private static final Predicate<Integer> IS_STRICTLY_GREATER_THAN3 = i -> i > 3; | ||||||
|  | 
 | ||||||
|  |     private Stream getIntegers() { | ||||||
|  |         return Stream.of(1, 2, 3, 4, 5); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     void givenNoElementMatchingPredicate_WhenFindUniqueElementMatchingPredicateWithReduction_ThenNoneFound() { | ||||||
|  |         assertTrue(FilterUtils.findUniqueElementMatchingPredicate_WithReduction(getIntegers(), IS_STRICTLY_GREATER_THAN5) | ||||||
|  |             .isEmpty()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     void givenTwoElementsMatchingPredicate_WhenFindUniqueElementMatchingPredicateWithReduction_ThenEmpty() { | ||||||
|  |         assertTrue(FilterUtils.findUniqueElementMatchingPredicate_WithReduction(getIntegers(), IS_STRICTLY_GREATER_THAN3) | ||||||
|  |             .isEmpty()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     void givenOnlyOneElementMatchingPredicate_WhenFindUniqueElementMatchingPredicateWithReduction_ThenFindsIt() { | ||||||
|  |         assertEquals(5, FilterUtils.findUniqueElementMatchingPredicate_WithReduction(getIntegers(), IS_STRICTLY_GREATER_THAN4) | ||||||
|  |             .get()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     void givenNoElementMatchingPredicate_WhenGetUniqueElementMatchingPredicateWithReduction_ThenThrows() { | ||||||
|  |         assertThrows(IllegalStateException.class, () -> FilterUtils.getUniqueElementMatchingPredicate_WithReduction(getIntegers(), IS_STRICTLY_GREATER_THAN5)); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     void givenTwoElementsMatchingPredicate_WhenGetUniqueElementMatchingPredicateWithReduction_ThenThrows() { | ||||||
|  |         assertThrows(IllegalStateException.class, () -> FilterUtils.getUniqueElementMatchingPredicate_WithReduction(getIntegers(), IS_STRICTLY_GREATER_THAN3)); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     void givenOnlyOneElementMatchingPredicate_WhenFindUniqueElementMatchingPredicateWithReduction_ThenGetIt() { | ||||||
|  |         assertEquals(5, FilterUtils.getUniqueElementMatchingPredicate_WithReduction(getIntegers(), IS_STRICTLY_GREATER_THAN4)); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     void givenNoElementMatchingPredicate_WhenFindUniqueElementMatchingPredicateWithCollectingAndThen_ThenEmpty() { | ||||||
|  |         assertTrue(FilterUtils.findUniqueElementMatchingPredicate_WithCollectingAndThen(getIntegers(), IS_STRICTLY_GREATER_THAN5) | ||||||
|  |             .isEmpty()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     void givenTwoElementsMatchingPredicate_WhenFindUniqueElementMatchingPredicateWithCollectingAndThen_ThenEmpty() { | ||||||
|  |         assertTrue(FilterUtils.findUniqueElementMatchingPredicate_WithCollectingAndThen(getIntegers(), IS_STRICTLY_GREATER_THAN3) | ||||||
|  |             .isEmpty()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     void givenOnlyOneElementMatchingPredicate_WhenFindUniqueElementMatchingPredicateWithCollectingAndThen_ThenFindsIt() { | ||||||
|  |         assertEquals(5, FilterUtils.findUniqueElementMatchingPredicate_WithCollectingAndThen(getIntegers(), IS_STRICTLY_GREATER_THAN4) | ||||||
|  |             .get()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     void givenNoElementMatchingPredicate_WhenGetUniqueElementMatchingPredicateWithCollectingAndThen_ThenThrows() { | ||||||
|  |         assertThrows(IllegalStateException.class, () -> FilterUtils.getUniqueElementMatchingPredicate_WithCollectingAndThen(getIntegers(), IS_STRICTLY_GREATER_THAN5)); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     void givenTwoElementsMatchingPredicate_WhenGetUniqueElementMatchingPredicateWithCollectingAndThen_ThenThrows() { | ||||||
|  |         assertThrows(IllegalStateException.class, () -> FilterUtils.getUniqueElementMatchingPredicate_WithCollectingAndThen(getIntegers(), IS_STRICTLY_GREATER_THAN3)); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     void givenOnlyOneElementMatchingPredicate_WhenFindUniqueElementMatchingPredicateWithCollectingAndThen_ThenGetIt() { | ||||||
|  |         assertEquals(5, FilterUtils.getUniqueElementMatchingPredicate_WithCollectingAndThen(getIntegers(), IS_STRICTLY_GREATER_THAN4)); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
| @ -0,0 +1,35 @@ | |||||||
|  | package com.baeldung.removewhitespace; | ||||||
|  | 
 | ||||||
|  | import org.apache.commons.lang3.StringUtils; | ||||||
|  | import org.junit.jupiter.api.Test; | ||||||
|  | 
 | ||||||
|  | import static org.assertj.core.api.Assertions.assertThat; | ||||||
|  | 
 | ||||||
|  | class RemoveWhitespaceUnitTest { | ||||||
|  |     private final String myString = "   I    am a    wonderful String     !   "; | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     void givenStringWithWhitespace_whenRemoveAllWhitespace_shouldGetExpectedResult() { | ||||||
|  |         String result = myString.replaceAll("\\s", ""); | ||||||
|  |         assertThat(result).isEqualTo("IamawonderfulString!"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     void givenStringWithWhitespace_whenRemoveAllWhitespaceUsingStringUtils_shouldGetExpectedResult() { | ||||||
|  |         String result = StringUtils.deleteWhitespace(myString); | ||||||
|  |         assertThat(result).isEqualTo("IamawonderfulString!"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     void givenStringWithWhitespace_whenReplaceConsecutiveSpacesWithSingleSpace_shouldGetExpectedResult() { | ||||||
|  |         String result = myString.replaceAll("\\s+", " "); | ||||||
|  |         assertThat(result).isEqualTo(" I am a wonderful String ! "); | ||||||
|  |         assertThat(result.trim()).isEqualTo("I am a wonderful String !"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     void givenStringWithWhitespace_whenNormalizeWithApacheCommons_shouldGetExpectedResult() { | ||||||
|  |         String result = StringUtils.normalizeSpace(myString); | ||||||
|  |         assertThat(result).isEqualTo("I am a wonderful String !"); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -6,6 +6,10 @@ | |||||||
|         </encoder> |         </encoder> | ||||||
|     </appender> |     </appender> | ||||||
| 
 | 
 | ||||||
|  |     <logger name="org.xacml4j.v30.XacmlPolicyTestSupport" level="warn"> | ||||||
|  |         <appender-ref ref="STDOUT" /> | ||||||
|  |     </logger> | ||||||
|  | 
 | ||||||
|     <root level="INFO"> |     <root level="INFO"> | ||||||
|         <appender-ref ref="STDOUT" /> |         <appender-ref ref="STDOUT" /> | ||||||
|     </root> |     </root> | ||||||
|  | |||||||
| @ -10,10 +10,9 @@ | |||||||
|     <description>Aggregator Service for LightRun Article</description> |     <description>Aggregator Service for LightRun Article</description> | ||||||
| 
 | 
 | ||||||
|     <parent> |     <parent> | ||||||
|         <groupId>org.springframework.boot</groupId> |         <groupId>com.baelduung</groupId> | ||||||
|         <artifactId>spring-boot-starter-parent</artifactId> |         <artifactId>lightrun</artifactId> | ||||||
|         <version>2.6.7</version> |         <version>0.0.1-SNAPSHOT</version> | ||||||
|         <relativePath /> <!-- lookup parent from repository --> |  | ||||||
|     </parent> |     </parent> | ||||||
| 
 | 
 | ||||||
|     <dependencies> |     <dependencies> | ||||||
| @ -43,6 +42,7 @@ | |||||||
| 
 | 
 | ||||||
|     <properties> |     <properties> | ||||||
|         <java.version>17</java.version> |         <java.version>17</java.version> | ||||||
|  |         <maven-pmd-plugin.version>3.17.0</maven-pmd-plugin.version> | ||||||
|     </properties> |     </properties> | ||||||
| 
 | 
 | ||||||
| </project> | </project> | ||||||
| @ -10,6 +10,13 @@ | |||||||
|     <description>Services for LightRun Article</description> |     <description>Services for LightRun Article</description> | ||||||
|     <packaging>pom</packaging> |     <packaging>pom</packaging> | ||||||
|      |      | ||||||
|  |     <parent> | ||||||
|  |         <groupId>com.baeldung</groupId> | ||||||
|  |         <artifactId>parent-boot-2</artifactId> | ||||||
|  |         <version>0.0.1-SNAPSHOT</version> | ||||||
|  |         <relativePath>../parent-boot-2</relativePath> | ||||||
|  |     </parent> | ||||||
|  | 
 | ||||||
|     <modules> |     <modules> | ||||||
|         <module>tasks-service</module> |         <module>tasks-service</module> | ||||||
|         <module>users-service</module> |         <module>users-service</module> | ||||||
|  | |||||||
| @ -10,10 +10,9 @@ | |||||||
|     <description>Tasks Service for LightRun Article</description> |     <description>Tasks Service for LightRun Article</description> | ||||||
| 
 | 
 | ||||||
|     <parent> |     <parent> | ||||||
|         <groupId>org.springframework.boot</groupId> |         <groupId>com.baelduung</groupId> | ||||||
|         <artifactId>spring-boot-starter-parent</artifactId> |         <artifactId>lightrun</artifactId> | ||||||
|         <version>2.6.7</version> |         <version>0.0.1-SNAPSHOT</version> | ||||||
|         <relativePath /> <!-- lookup parent from repository --> |  | ||||||
|     </parent> |     </parent> | ||||||
| 
 | 
 | ||||||
|     <dependencies> |     <dependencies> | ||||||
| @ -64,6 +63,7 @@ | |||||||
| 
 | 
 | ||||||
|     <properties> |     <properties> | ||||||
|         <java.version>17</java.version> |         <java.version>17</java.version> | ||||||
|  |         <maven-pmd-plugin.version>3.17.0</maven-pmd-plugin.version> | ||||||
|     </properties> |     </properties> | ||||||
| 
 | 
 | ||||||
| </project> | </project> | ||||||
| @ -10,10 +10,9 @@ | |||||||
|     <description>Users Service for LightRun Article</description> |     <description>Users Service for LightRun Article</description> | ||||||
| 
 | 
 | ||||||
|     <parent> |     <parent> | ||||||
|         <groupId>org.springframework.boot</groupId> |         <groupId>com.baelduung</groupId> | ||||||
|         <artifactId>spring-boot-starter-parent</artifactId> |         <artifactId>lightrun</artifactId> | ||||||
|         <version>2.6.7</version> |         <version>0.0.1-SNAPSHOT</version> | ||||||
|         <relativePath /> <!-- lookup parent from repository --> |  | ||||||
|     </parent> |     </parent> | ||||||
| 
 | 
 | ||||||
|     <dependencies> |     <dependencies> | ||||||
| @ -60,6 +59,7 @@ | |||||||
| 
 | 
 | ||||||
|     <properties> |     <properties> | ||||||
|         <java.version>17</java.version> |         <java.version>17</java.version> | ||||||
|  |         <maven-pmd-plugin.version>3.17.0</maven-pmd-plugin.version> | ||||||
|     </properties> |     </properties> | ||||||
| 
 | 
 | ||||||
| </project> | </project> | ||||||
| @ -6,17 +6,20 @@ import com.baeldung.entity.Division; | |||||||
| import com.baeldung.entity.Employee; | import com.baeldung.entity.Employee; | ||||||
| import org.mapstruct.Mapper; | import org.mapstruct.Mapper; | ||||||
| import org.mapstruct.Mapping; | import org.mapstruct.Mapping; | ||||||
| import org.mapstruct.Mappings; |  | ||||||
| 
 | 
 | ||||||
| import java.util.List; | import java.util.List; | ||||||
| 
 | 
 | ||||||
| @Mapper | @Mapper | ||||||
| public interface EmployeeMapper { | public interface EmployeeMapper { | ||||||
| 
 | 
 | ||||||
|     @Mappings({ @Mapping(target = "employeeId", source = "entity.id"), @Mapping(target = "employeeName", source = "entity.name"), @Mapping(target = "employeeStartDt", source = "entity.startDt", dateFormat = "dd-MM-yyyy HH:mm:ss") }) |     @Mapping(target = "employeeId", source = "entity.id") | ||||||
|  |     @Mapping(target = "employeeName", source = "entity.name") | ||||||
|  |     @Mapping(target = "employeeStartDt", source = "entity.startDt", dateFormat = "dd-MM-yyyy HH:mm:ss") | ||||||
|     EmployeeDTO employeeToEmployeeDTO(Employee entity); |     EmployeeDTO employeeToEmployeeDTO(Employee entity); | ||||||
| 
 | 
 | ||||||
|     @Mappings({ @Mapping(target = "id", source = "dto.employeeId"), @Mapping(target = "name", source = "dto.employeeName"), @Mapping(target = "startDt", source = "dto.employeeStartDt", dateFormat = "dd-MM-yyyy HH:mm:ss") }) |     @Mapping(target = "id", source = "dto.employeeId") | ||||||
|  |     @Mapping(target = "name", source = "dto.employeeName") | ||||||
|  |     @Mapping(target = "startDt", source = "dto.employeeStartDt", dateFormat = "dd-MM-yyyy HH:mm:ss") | ||||||
|     Employee employeeDTOtoEmployee(EmployeeDTO dto); |     Employee employeeDTOtoEmployee(EmployeeDTO dto); | ||||||
| 
 | 
 | ||||||
|     DivisionDTO divisionToDivisionDTO(Division entity); |     DivisionDTO divisionToDivisionDTO(Division entity); | ||||||
|  | |||||||
| @ -0,0 +1,52 @@ | |||||||
|  | <?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>maven-repository-download</artifactId> | ||||||
|  |     <name>Maven Release Repository</name> | ||||||
|  |     <version>1.0.0-SNAPSHOT</version> | ||||||
|  | 
 | ||||||
|  |     <parent> | ||||||
|  |         <groupId>com.baeldung</groupId> | ||||||
|  |         <artifactId>maven-repositories</artifactId> | ||||||
|  |         <version>1.0.0-SNAPSHOT</version> | ||||||
|  |     </parent> | ||||||
|  | 
 | ||||||
|  |     <repositories> | ||||||
|  |         <repository> | ||||||
|  |             <id>nexus-snapshot</id> | ||||||
|  |             <name>nexus-snapshot</name> | ||||||
|  |             <url>http://localhost:8081/repository/maven-snapshots/</url> | ||||||
|  |             <snapshots> | ||||||
|  |                 <enabled>true</enabled> | ||||||
|  |             </snapshots> | ||||||
|  |             <releases> | ||||||
|  |                 <enabled>false</enabled> | ||||||
|  |             </releases> | ||||||
|  |         </repository> | ||||||
|  |         <repository> | ||||||
|  |             <id>nexus-release</id> | ||||||
|  |             <name>nexus-release</name> | ||||||
|  |             <url>http://localhost:8081/repository/maven-releases/</url> | ||||||
|  |             <snapshots> | ||||||
|  |                 <enabled>false</enabled> | ||||||
|  |             </snapshots> | ||||||
|  |         </repository> | ||||||
|  |     </repositories> | ||||||
|  | 
 | ||||||
|  |     <dependencies> | ||||||
|  |         <dependency> | ||||||
|  |             <groupId>com.baeldung</groupId> | ||||||
|  |             <artifactId>maven-release-repository</artifactId> | ||||||
|  |             <version>1.0.0</version> | ||||||
|  |         </dependency> | ||||||
|  | 
 | ||||||
|  |         <dependency> | ||||||
|  |             <groupId>com.baeldung</groupId> | ||||||
|  |             <artifactId>maven-snapshot-repository</artifactId> | ||||||
|  |             <version>1.0.0-SNAPSHOT</version> | ||||||
|  |         </dependency> | ||||||
|  |     </dependencies> | ||||||
|  | 
 | ||||||
|  | </project> | ||||||
| @ -0,0 +1,38 @@ | |||||||
|  | <?xml version="1.0" encoding="UTF-8"?> | ||||||
|  | <project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||||||
|  |     xmlns="http://maven.apache.org/POM/4.0.0" | ||||||
|  |     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||||||
|  |     <modelVersion>4.0.0</modelVersion> | ||||||
|  |     <artifactId>maven-release-repository</artifactId> | ||||||
|  |     <name>Maven Release Repository</name> | ||||||
|  |     <version>1.0.0</version> | ||||||
|  | 
 | ||||||
|  |     <parent> | ||||||
|  |         <groupId>com.baeldung</groupId> | ||||||
|  |         <artifactId>maven-repositories</artifactId> | ||||||
|  |         <version>1.0.0-SNAPSHOT</version> | ||||||
|  |     </parent> | ||||||
|  | 
 | ||||||
|  |     <repositories> | ||||||
|  |         <repository> | ||||||
|  |             <id>nexus</id> | ||||||
|  |             <name>nexus-release</name> | ||||||
|  |             <url>http://localhost:8081/repository/maven-releases/</url> | ||||||
|  |             <snapshots> | ||||||
|  |                 <enabled>false</enabled> | ||||||
|  |             </snapshots> | ||||||
|  |             <releases> | ||||||
|  |                 <enabled>true</enabled> | ||||||
|  |             </releases> | ||||||
|  |         </repository> | ||||||
|  |     </repositories> | ||||||
|  | 
 | ||||||
|  |     <distributionManagement> | ||||||
|  |         <repository> | ||||||
|  |             <id>nexus</id> | ||||||
|  |             <name>nexus-release</name> | ||||||
|  |             <url>http://localhost:8081/repository/maven-releases/</url> | ||||||
|  |         </repository> | ||||||
|  |     </distributionManagement> | ||||||
|  | 
 | ||||||
|  | </project> | ||||||
| @ -0,0 +1,38 @@ | |||||||
|  | <?xml version="1.0" encoding="UTF-8"?> | ||||||
|  | <project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||||||
|  |          xmlns="http://maven.apache.org/POM/4.0.0" | ||||||
|  |          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||||||
|  |     <modelVersion>4.0.0</modelVersion> | ||||||
|  |     <artifactId>maven-snapshot-repository</artifactId> | ||||||
|  |     <name>Maven Snapshot Repository</name> | ||||||
|  |     <version>1.0.0-SNAPSHOT</version> | ||||||
|  | 
 | ||||||
|  |     <parent> | ||||||
|  |         <groupId>com.baeldung</groupId> | ||||||
|  |         <artifactId>maven-repositories</artifactId> | ||||||
|  |         <version>1.0.0-SNAPSHOT</version> | ||||||
|  |     </parent> | ||||||
|  | 
 | ||||||
|  |     <repositories> | ||||||
|  |         <repository> | ||||||
|  |             <id>nexus</id> | ||||||
|  |             <name>nexus-snapshot</name> | ||||||
|  |             <url>http://localhost:8081/repository/maven-snapshots/</url> | ||||||
|  |             <snapshots> | ||||||
|  |                 <enabled>true</enabled> | ||||||
|  |             </snapshots> | ||||||
|  |             <releases> | ||||||
|  |                 <enabled>false</enabled> | ||||||
|  |             </releases> | ||||||
|  |         </repository> | ||||||
|  |     </repositories> | ||||||
|  | 
 | ||||||
|  |     <distributionManagement> | ||||||
|  |         <snapshotRepository> | ||||||
|  |             <id>nexus</id> | ||||||
|  |             <name>nexus-snapshot</name> | ||||||
|  |             <url>http://localhost:8081/repository/maven-snapshots/</url> | ||||||
|  |         </snapshotRepository> | ||||||
|  |     </distributionManagement> | ||||||
|  | 
 | ||||||
|  | </project> | ||||||
							
								
								
									
										23
									
								
								maven-modules/maven-repositories/pom.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								maven-modules/maven-repositories/pom.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,23 @@ | |||||||
|  | <?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>maven-repositories</artifactId> | ||||||
|  |     <version>1.0.0-SNAPSHOT</version> | ||||||
|  |     <name>Maven Repositories</name> | ||||||
|  |     <packaging>pom</packaging> | ||||||
|  | 
 | ||||||
|  |     <parent> | ||||||
|  |         <groupId>com.baeldung</groupId> | ||||||
|  |         <artifactId>maven-modules</artifactId> | ||||||
|  |         <version>0.0.1-SNAPSHOT</version> | ||||||
|  |     </parent> | ||||||
|  | 
 | ||||||
|  |     <modules> | ||||||
|  |         <module>maven-release-repository</module> | ||||||
|  |         <module>maven-snapshot-repository</module> | ||||||
|  |         <module>maven-download-artifacts</module> | ||||||
|  |     </modules> | ||||||
|  | 
 | ||||||
|  | </project> | ||||||
| @ -41,6 +41,7 @@ | |||||||
|         <module>maven-parent-pom-resolution</module> |         <module>maven-parent-pom-resolution</module> | ||||||
|         <module>maven-simple</module> |         <module>maven-simple</module> | ||||||
|         <module>maven-classifier</module> |         <module>maven-classifier</module> | ||||||
|  |         <module>maven-repositories</module> | ||||||
|     </modules> |     </modules> | ||||||
| 
 | 
 | ||||||
|     <dependencyManagement> |     <dependencyManagement> | ||||||
|  | |||||||
| @ -37,7 +37,7 @@ import com.netflix.spectator.atlas.AtlasConfig; | |||||||
| /** | /** | ||||||
|  * @author aiet |  * @author aiet | ||||||
|  */ |  */ | ||||||
| public class MicrometerAtlasIntegrationTest { | public class MicrometerAtlasManualTest { | ||||||
| 
 | 
 | ||||||
|     private AtlasConfig atlasConfig; |     private AtlasConfig atlasConfig; | ||||||
| 
 | 
 | ||||||
| @ -9,11 +9,11 @@ | |||||||
|     <name>fauna</name> |     <name>fauna</name> | ||||||
|     <description>Blogging Service built with FaunaDB</description> |     <description>Blogging Service built with FaunaDB</description> | ||||||
| 
 | 
 | ||||||
|     <parent> |    <parent> | ||||||
|         <groupId>org.springframework.boot</groupId> |         <groupId>com.baeldung</groupId> | ||||||
|         <artifactId>spring-boot-starter-parent</artifactId> |         <artifactId>parent-boot-2</artifactId> | ||||||
|         <version>2.6.2</version> |         <version>0.0.1-SNAPSHOT</version> | ||||||
|         <relativePath /> <!-- lookup parent from repository --> |         <relativePath>../../parent-boot-2</relativePath> | ||||||
|     </parent> |     </parent> | ||||||
| 
 | 
 | ||||||
|     <dependencies> |     <dependencies> | ||||||
| @ -54,6 +54,7 @@ | |||||||
| 
 | 
 | ||||||
|     <properties> |     <properties> | ||||||
|         <java.version>17</java.version> |         <java.version>17</java.version> | ||||||
|  |         <maven-pmd-plugin.version>3.17.0</maven-pmd-plugin.version> | ||||||
|     </properties> |     </properties> | ||||||
| 
 | 
 | ||||||
| </project> | </project> | ||||||
| @ -24,7 +24,8 @@ public class HibernateUtil { | |||||||
|                 settings.put(Environment.USER, "sa"); |                 settings.put(Environment.USER, "sa"); | ||||||
|                 settings.put(Environment.PASS, ""); |                 settings.put(Environment.PASS, ""); | ||||||
|                 settings.put(Environment.DIALECT, "org.hibernate.dialect.HSQLDialect"); |                 settings.put(Environment.DIALECT, "org.hibernate.dialect.HSQLDialect"); | ||||||
|                 settings.put(Environment.SHOW_SQL, "true"); |                 // enable to show Hibernate generated SQL | ||||||
|  |                 settings.put(Environment.SHOW_SQL, "false"); | ||||||
|                 settings.put(Environment.FORMAT_SQL, "true"); |                 settings.put(Environment.FORMAT_SQL, "true"); | ||||||
|                 settings.put(Environment.USE_SQL_COMMENTS, "true"); |                 settings.put(Environment.USE_SQL_COMMENTS, "true"); | ||||||
|                 settings.put(Environment.HBM2DDL_AUTO, "update"); |                 settings.put(Environment.HBM2DDL_AUTO, "update"); | ||||||
|  | |||||||
| @ -2,11 +2,14 @@ | |||||||
| <configuration> | <configuration> | ||||||
|     <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> |     <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> | ||||||
|         <encoder> |         <encoder> | ||||||
|             <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n |             <pattern>[%d{ISO8601}]-[%thread] %-5level %logger - %msg%n</pattern> | ||||||
|             </pattern> |  | ||||||
|         </encoder> |         </encoder> | ||||||
|     </appender> |     </appender> | ||||||
| 
 | 
 | ||||||
|  |     <logger name="org.hibernate" level="error"> | ||||||
|  |         <appender-ref ref="STDOUT" /> | ||||||
|  |     </logger> | ||||||
|  | 
 | ||||||
|     <root level="INFO"> |     <root level="INFO"> | ||||||
|         <appender-ref ref="STDOUT" /> |         <appender-ref ref="STDOUT" /> | ||||||
|     </root> |     </root> | ||||||
| @ -0,0 +1,13 @@ | |||||||
|  | package com.baeldung.boot.count; | ||||||
|  | 
 | ||||||
|  | import org.springframework.boot.SpringApplication; | ||||||
|  | import org.springframework.boot.autoconfigure.SpringBootApplication; | ||||||
|  | import org.springframework.data.mongodb.repository.config.EnableMongoRepositories; | ||||||
|  | 
 | ||||||
|  | @SpringBootApplication | ||||||
|  | @EnableMongoRepositories(basePackages = { "com.baeldung.boot.count" }) | ||||||
|  | public class SpringBootCountApplication { | ||||||
|  |     public static void main(String... args) { | ||||||
|  |         SpringApplication.run(SpringBootCountApplication.class, args); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,16 @@ | |||||||
|  | package com.baeldung.boot.count.dao; | ||||||
|  | 
 | ||||||
|  | import org.springframework.data.mongodb.repository.MongoRepository; | ||||||
|  | import org.springframework.data.mongodb.repository.Query; | ||||||
|  | 
 | ||||||
|  | import com.baeldung.boot.count.data.Car; | ||||||
|  | 
 | ||||||
|  | public interface CarRepository extends MongoRepository<Car, String> { | ||||||
|  |     @Query(value = "{brand: ?0}", count = true) | ||||||
|  |     public long countBrand(String brand); | ||||||
|  | 
 | ||||||
|  |     Long countByBrand(String brand); | ||||||
|  | 
 | ||||||
|  |     @Query(value = "{}", count = true) | ||||||
|  |     Long countWithAnnotation(); | ||||||
|  | } | ||||||
| @ -0,0 +1,33 @@ | |||||||
|  | package com.baeldung.boot.count.data; | ||||||
|  | 
 | ||||||
|  | import org.springframework.data.mongodb.core.mapping.Document; | ||||||
|  | 
 | ||||||
|  | @Document | ||||||
|  | public class Car { | ||||||
|  |     private String name; | ||||||
|  | 
 | ||||||
|  |     private String brand; | ||||||
|  | 
 | ||||||
|  |     public Car() { | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public Car(String brand) { | ||||||
|  |         this.brand = brand; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public String getBrand() { | ||||||
|  |         return brand; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void setBrand(String brand) { | ||||||
|  |         this.brand = brand; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public String getName() { | ||||||
|  |         return name; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void setName(String name) { | ||||||
|  |         this.name = name; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,69 @@ | |||||||
|  | package com.baeldung.boot.count.service; | ||||||
|  | 
 | ||||||
|  | import java.util.List; | ||||||
|  | import java.util.Optional; | ||||||
|  | 
 | ||||||
|  | import org.springframework.beans.factory.annotation.Autowired; | ||||||
|  | import org.springframework.data.domain.Example; | ||||||
|  | import org.springframework.data.mongodb.core.MongoTemplate; | ||||||
|  | import org.springframework.data.mongodb.core.query.Criteria; | ||||||
|  | import org.springframework.data.mongodb.core.query.Query; | ||||||
|  | import org.springframework.stereotype.Service; | ||||||
|  | 
 | ||||||
|  | import com.baeldung.boot.count.dao.CarRepository; | ||||||
|  | import com.baeldung.boot.count.data.Car; | ||||||
|  | 
 | ||||||
|  | @Service | ||||||
|  | public class CountCarService { | ||||||
|  | 
 | ||||||
|  |     @Autowired | ||||||
|  |     private CarRepository repo; | ||||||
|  | 
 | ||||||
|  |     @Autowired | ||||||
|  |     private MongoTemplate mongo; | ||||||
|  | 
 | ||||||
|  |     public List<Car> findCars() { | ||||||
|  |         return repo.findAll(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public Optional<Car> findCar(String id) { | ||||||
|  |         return repo.findById(id); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public Car insertCar(Car item) { | ||||||
|  |         return repo.insert(item); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public long getCountWithQueryAnnotation() { | ||||||
|  |         return repo.countWithAnnotation(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public long getCountWithCrudRepository() { | ||||||
|  |         return repo.count(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public long getCountBrandWithQueryMethod(String brand) { | ||||||
|  |         return repo.countByBrand(brand); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public long getCountWithExample(Car item) { | ||||||
|  |         return repo.count(Example.of(item)); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public long getCountWithExampleCriteria(Car item) { | ||||||
|  |         Query query = new Query(); | ||||||
|  |         query.addCriteria(Criteria.byExample(item)); | ||||||
|  |         return mongo.count(query, Car.class); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public long getCountBrandWithQueryAnnotation(String brand) { | ||||||
|  |         return repo.countBrand(brand); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public long getCountBrandWithCriteria(String brand) { | ||||||
|  |         Query query = new Query(); | ||||||
|  |         query.addCriteria(Criteria.where("brand") | ||||||
|  |             .is(brand)); | ||||||
|  |         return mongo.count(query, Car.class); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,118 @@ | |||||||
|  | package com.baeldung.boot.count.service; | ||||||
|  | 
 | ||||||
|  | import static org.junit.Assert.assertEquals; | ||||||
|  | 
 | ||||||
|  | import java.util.List; | ||||||
|  | 
 | ||||||
|  | import org.junit.Before; | ||||||
|  | import org.junit.Test; | ||||||
|  | import org.junit.runner.RunWith; | ||||||
|  | import org.springframework.beans.factory.annotation.Autowired; | ||||||
|  | import org.springframework.boot.test.context.SpringBootTest; | ||||||
|  | import org.springframework.test.annotation.DirtiesContext; | ||||||
|  | import org.springframework.test.context.junit4.SpringRunner; | ||||||
|  | 
 | ||||||
|  | import com.baeldung.boot.count.data.Car; | ||||||
|  | 
 | ||||||
|  | @SpringBootTest | ||||||
|  | @DirtiesContext | ||||||
|  | @RunWith(SpringRunner.class) | ||||||
|  | public class CountCarServiceIntegrationTest { | ||||||
|  |     @Autowired | ||||||
|  |     private CountCarService service; | ||||||
|  | 
 | ||||||
|  |     Car car1 = new Car("B-A"); | ||||||
|  | 
 | ||||||
|  |     @Before | ||||||
|  |     public void init() { | ||||||
|  |         service.insertCar(car1); | ||||||
|  |         service.insertCar(new Car("B-B")); | ||||||
|  |         service.insertCar(new Car("B-C")); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void givenAllDocs_whenQueryAnnotationCount_thenCountEqualsSize() { | ||||||
|  |         List<Car> all = service.findCars(); | ||||||
|  | 
 | ||||||
|  |         long count = service.getCountWithQueryAnnotation(); | ||||||
|  | 
 | ||||||
|  |         assertEquals(count, all.size()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void givenAllDocs_whenCrudRepositoryCount_thenCountEqualsSize() { | ||||||
|  |         List<Car> all = service.findCars(); | ||||||
|  | 
 | ||||||
|  |         long count = service.getCountWithCrudRepository(); | ||||||
|  | 
 | ||||||
|  |         assertEquals(count, all.size()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void givenFilteredDocs_whenCriteriaCountByBrand_thenCountEqualsSize() { | ||||||
|  |         String filter = "B-A"; | ||||||
|  |         long all = service.findCars() | ||||||
|  |             .stream() | ||||||
|  |             .filter(car -> car.getBrand() | ||||||
|  |                 .equals(filter)) | ||||||
|  |             .count(); | ||||||
|  | 
 | ||||||
|  |         long count = service.getCountBrandWithCriteria(filter); | ||||||
|  | 
 | ||||||
|  |         assertEquals(count, all); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void givenQueryAnnotation_whenCountingByBrand_thenCountEqualsSize() { | ||||||
|  |         String filter = "B-A"; | ||||||
|  |         long all = service.findCars() | ||||||
|  |             .stream() | ||||||
|  |             .filter(car -> car.getBrand() | ||||||
|  |                 .equals(filter)) | ||||||
|  |             .count(); | ||||||
|  | 
 | ||||||
|  |         long count = service.getCountBrandWithQueryAnnotation(filter); | ||||||
|  | 
 | ||||||
|  |         assertEquals(count, all); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void givenFilteredDocs_whenQueryMethodCountByBrand_thenCountEqualsSize() { | ||||||
|  |         String filter = "B-A"; | ||||||
|  |         long all = service.findCars() | ||||||
|  |             .stream() | ||||||
|  |             .filter(car -> car.getBrand() | ||||||
|  |                 .equals(filter)) | ||||||
|  |             .count(); | ||||||
|  | 
 | ||||||
|  |         long count = service.getCountBrandWithQueryMethod(filter); | ||||||
|  | 
 | ||||||
|  |         assertEquals(count, all); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void givenFilteredDocs_whenExampleCount_thenCountEqualsSize() { | ||||||
|  |         long all = service.findCars() | ||||||
|  |             .stream() | ||||||
|  |             .filter(car -> car.getBrand() | ||||||
|  |                 .equals(car1.getBrand())) | ||||||
|  |             .count(); | ||||||
|  | 
 | ||||||
|  |         long count = service.getCountWithExample(car1); | ||||||
|  | 
 | ||||||
|  |         assertEquals(count, all); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void givenFilteredDocs_whenExampleCriteriaCount_thenCountEqualsSize() { | ||||||
|  |         long all = service.findCars() | ||||||
|  |             .stream() | ||||||
|  |             .filter(car -> car.getBrand() | ||||||
|  |                 .equals(car1.getBrand())) | ||||||
|  |             .count(); | ||||||
|  | 
 | ||||||
|  |         long count = service.getCountWithExampleCriteria(car1); | ||||||
|  | 
 | ||||||
|  |         assertEquals(count, all); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -87,7 +87,7 @@ | |||||||
| 
 | 
 | ||||||
|     <properties> |     <properties> | ||||||
|         <mapstruct.version>1.3.1.Final</mapstruct.version> |         <mapstruct.version>1.3.1.Final</mapstruct.version> | ||||||
|         <testcontainers.version>1.12.2</testcontainers.version> |         <testcontainers.version>1.17.3</testcontainers.version> | ||||||
|     </properties> |     </properties> | ||||||
| 
 | 
 | ||||||
| </project> | </project> | ||||||
| @ -1,6 +1,7 @@ | |||||||
| spring: | spring: | ||||||
|   datasource: |   datasource: | ||||||
|     url: jdbc:tc:postgresql:11.1:///integration-tests-db |     url: jdbc:tc:postgresql:11.1:///integration-tests-db | ||||||
|  |     driver-class-name: org.testcontainers.jdbc.ContainerDatabaseDriver | ||||||
|   jpa: |   jpa: | ||||||
|     hibernate: |     hibernate: | ||||||
|       ddl-auto: create |       ddl-auto: create | ||||||
| @ -0,0 +1,94 @@ | |||||||
|  | package com.baeldung.databuffer; | ||||||
|  | 
 | ||||||
|  | import org.slf4j.Logger; | ||||||
|  | import org.slf4j.LoggerFactory; | ||||||
|  | import org.springframework.core.io.buffer.DataBuffer; | ||||||
|  | import org.springframework.core.io.buffer.DataBufferUtils; | ||||||
|  | import org.springframework.web.reactive.function.BodyExtractors; | ||||||
|  | import org.springframework.web.reactive.function.client.WebClient; | ||||||
|  | 
 | ||||||
|  | import reactor.core.publisher.Flux; | ||||||
|  | 
 | ||||||
|  | import java.io.IOException; | ||||||
|  | import java.io.InputStream; | ||||||
|  | import java.io.PipedInputStream; | ||||||
|  | import java.io.PipedOutputStream; | ||||||
|  | 
 | ||||||
|  | public class DataBufferToInputStream { | ||||||
|  |     private static final Logger logger = LoggerFactory.getLogger(DataBufferToInputStream.class); | ||||||
|  |     private static final String REQUEST_ENDPOINT = "https://gorest.co.in/public/v2/users"; | ||||||
|  | 
 | ||||||
|  |     private static WebClient getWebClient() { | ||||||
|  |         WebClient.Builder webClientBuilder = WebClient.builder(); | ||||||
|  |         return webClientBuilder.build(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static InputStream getResponseAsInputStream(WebClient client, String url) throws IOException, InterruptedException { | ||||||
|  | 
 | ||||||
|  |         PipedOutputStream pipedOutputStream = new PipedOutputStream(); | ||||||
|  |         PipedInputStream pipedInputStream = new PipedInputStream(1024 * 10); | ||||||
|  |         pipedInputStream.connect(pipedOutputStream); | ||||||
|  | 
 | ||||||
|  |         Flux<DataBuffer> body = client.get() | ||||||
|  |             .uri(url) | ||||||
|  |             .exchangeToFlux(clientResponse -> { | ||||||
|  |                 return clientResponse.body(BodyExtractors.toDataBuffers()); | ||||||
|  |             }) | ||||||
|  |             .doOnError(error -> { | ||||||
|  |                 logger.error("error occurred while reading body", error); | ||||||
|  |             }) | ||||||
|  |             .doFinally(s -> { | ||||||
|  |                 try { | ||||||
|  |                     pipedOutputStream.close(); | ||||||
|  |                 } catch (IOException e) { | ||||||
|  |                     throw new RuntimeException(e); | ||||||
|  |                 } | ||||||
|  |             }) | ||||||
|  |             .doOnCancel(() -> { | ||||||
|  |                 logger.error("Get request is cancelled"); | ||||||
|  |             }); | ||||||
|  | 
 | ||||||
|  |         DataBufferUtils.write(body, pipedOutputStream) | ||||||
|  |             .log("Writing to output buffer") | ||||||
|  |             .subscribe(); | ||||||
|  |         return pipedInputStream; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private static String readContentFromPipedInputStream(PipedInputStream stream) throws IOException { | ||||||
|  |         StringBuffer contentStringBuffer = new StringBuffer(); | ||||||
|  |         try { | ||||||
|  |             Thread pipeReader = new Thread(() -> { | ||||||
|  |                 try { | ||||||
|  |                     contentStringBuffer.append(readContent(stream)); | ||||||
|  |                 } catch (IOException e) { | ||||||
|  |                     throw new RuntimeException(e); | ||||||
|  |                 } | ||||||
|  |             }); | ||||||
|  |             pipeReader.start(); | ||||||
|  |             pipeReader.join(); | ||||||
|  |         } catch (InterruptedException e) { | ||||||
|  |             throw new RuntimeException(e); | ||||||
|  |         } finally { | ||||||
|  |             stream.close(); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         return String.valueOf(contentStringBuffer); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private static String readContent(InputStream stream) throws IOException { | ||||||
|  |         StringBuffer contentStringBuffer = new StringBuffer(); | ||||||
|  |         byte[] tmp = new byte[stream.available()]; | ||||||
|  |         int byteCount = stream.read(tmp, 0, tmp.length); | ||||||
|  |         logger.info(String.format("read %d bytes from the stream\n", byteCount)); | ||||||
|  |         contentStringBuffer.append(new String(tmp)); | ||||||
|  |         return String.valueOf(contentStringBuffer); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static void main(String[] args) throws IOException, InterruptedException { | ||||||
|  |         WebClient webClient = getWebClient(); | ||||||
|  |         InputStream inputStream = getResponseAsInputStream(webClient, REQUEST_ENDPOINT); | ||||||
|  |         Thread.sleep(3000); | ||||||
|  |         String content = readContentFromPipedInputStream((PipedInputStream) inputStream); | ||||||
|  |         logger.info("response content: \n{}", content.replace("}", "}\n")); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,77 @@ | |||||||
|  | package databuffer; | ||||||
|  | 
 | ||||||
|  | import com.baeldung.databuffer.DataBufferToInputStream; | ||||||
|  | 
 | ||||||
|  | import io.restassured.internal.util.IOUtils; | ||||||
|  | 
 | ||||||
|  | import org.junit.jupiter.api.Test; | ||||||
|  | import org.mockito.Mockito; | ||||||
|  | import org.springframework.http.HttpStatus; | ||||||
|  | import org.springframework.web.reactive.function.client.ClientResponse; | ||||||
|  | import org.springframework.web.reactive.function.client.ExchangeFunction; | ||||||
|  | import org.springframework.web.reactive.function.client.WebClient; | ||||||
|  | 
 | ||||||
|  | import reactor.core.publisher.Mono; | ||||||
|  | 
 | ||||||
|  | import java.io.BufferedReader; | ||||||
|  | import java.io.IOException; | ||||||
|  | import java.io.InputStream; | ||||||
|  | import java.io.InputStreamReader; | ||||||
|  | import java.util.stream.Collectors; | ||||||
|  | 
 | ||||||
|  | import static org.junit.jupiter.api.Assertions.assertArrayEquals; | ||||||
|  | 
 | ||||||
|  | class DataBufferToInputStreamUnitTest { | ||||||
|  |     private String getResponseStub() throws IOException { | ||||||
|  |         InputStream inputStream = null; | ||||||
|  |         BufferedReader reader = null; | ||||||
|  |         String content = null; | ||||||
|  |         try { | ||||||
|  |             inputStream = this.getClass() | ||||||
|  |                 .getClassLoader() | ||||||
|  |                 .getResourceAsStream("user-response.json"); | ||||||
|  |             if (inputStream != null) { | ||||||
|  |                 reader = new BufferedReader(new InputStreamReader(inputStream)); | ||||||
|  |                 content = reader.lines() | ||||||
|  |                     .collect(Collectors.joining(System.lineSeparator())); | ||||||
|  |             } | ||||||
|  |         } catch (Exception ex) { | ||||||
|  |             throw new RuntimeException("exception caught while getting response stub"); | ||||||
|  |         } finally { | ||||||
|  |             reader.close(); | ||||||
|  |             inputStream.close(); | ||||||
|  |         } | ||||||
|  |         return content; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private InputStream getResponseStubAsInputStream() { | ||||||
|  |         return this.getClass() | ||||||
|  |             .getClassLoader() | ||||||
|  |             .getResourceAsStream("user-response.json"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private WebClient getMockWebClient() throws IOException { | ||||||
|  |         String content = getResponseStub(); | ||||||
|  |         ClientResponse clientResponse = ClientResponse.create(HttpStatus.OK) | ||||||
|  |             .header("Content-Type", "application/json") | ||||||
|  |             .body(content) | ||||||
|  |             .build(); | ||||||
|  | 
 | ||||||
|  |         ExchangeFunction exchangeFunction = clientRequest -> Mono.just(clientResponse); | ||||||
|  | 
 | ||||||
|  |         WebClient.Builder webClientBuilder = WebClient.builder() | ||||||
|  |             .exchangeFunction(exchangeFunction); | ||||||
|  |         WebClient webClient = webClientBuilder.build(); | ||||||
|  |         return webClient; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void testResponseAsInputStream() throws IOException, InterruptedException { | ||||||
|  |         String mockUrl = Mockito.anyString(); | ||||||
|  |         WebClient mockWebClient = getMockWebClient(); | ||||||
|  |         InputStream inputStream = DataBufferToInputStream.getResponseAsInputStream(mockWebClient, mockUrl); | ||||||
|  |         byte[] expectedBytes = IOUtils.toByteArray(getResponseStubAsInputStream()); | ||||||
|  |         byte[] actualBytes = IOUtils.toByteArray(inputStream); | ||||||
|  |         assertArrayEquals(expectedBytes, actualBytes); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,72 @@ | |||||||
|  | [ | ||||||
|  |   { | ||||||
|  |     "id": 2683, | ||||||
|  |     "name": "Maheswar Kocchar", | ||||||
|  |     "email": "maheswar_kocchar@kihn.info", | ||||||
|  |     "gender": "male", | ||||||
|  |     "status": "active" | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |     "id": 2680, | ||||||
|  |     "name": "Lakshminath Khan", | ||||||
|  |     "email": "lakshminath_khan@barrows-cormier.biz", | ||||||
|  |     "gender": "female", | ||||||
|  |     "status": "inactive" | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |     "id": 2679, | ||||||
|  |     "name": "Tarun Arora", | ||||||
|  |     "email": "tarun_arora@rolfson.net", | ||||||
|  |     "gender": "female", | ||||||
|  |     "status": "inactive" | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |     "id": 2678, | ||||||
|  |     "name": "Agnivesh Dubashi", | ||||||
|  |     "email": "dubashi_agnivesh@senger.name", | ||||||
|  |     "gender": "male", | ||||||
|  |     "status": "inactive" | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |     "id": 2677, | ||||||
|  |     "name": "Dhanu Gowda", | ||||||
|  |     "email": "gowda_dhanu@hayes.org", | ||||||
|  |     "gender": "male", | ||||||
|  |     "status": "active" | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |     "id": 2675, | ||||||
|  |     "name": "Harinakshi Pilla Jr.", | ||||||
|  |     "email": "pilla_jr_harinakshi@rutherford-monahan.com", | ||||||
|  |     "gender": "female", | ||||||
|  |     "status": "inactive" | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |     "id": 2673, | ||||||
|  |     "name": "Kalpana Prajapat", | ||||||
|  |     "email": "prajapat_kalpana@wilkinson-schaefer.net", | ||||||
|  |     "gender": "female", | ||||||
|  |     "status": "active" | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |     "id": 2672, | ||||||
|  |     "name": "Chakradhar Jha", | ||||||
|  |     "email": "jha_chakradhar@baumbach.info", | ||||||
|  |     "gender": "male", | ||||||
|  |     "status": "active" | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |     "id": 2670, | ||||||
|  |     "name": "Divaakar Deshpande Jr.", | ||||||
|  |     "email": "deshpande_jr_divaakar@mertz.info", | ||||||
|  |     "gender": "female", | ||||||
|  |     "status": "inactive" | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |     "id": 2669, | ||||||
|  |     "name": "Prasanna Mehra", | ||||||
|  |     "email": "prasanna_mehra@ruecker-larkin.name", | ||||||
|  |     "gender": "female", | ||||||
|  |     "status": "active" | ||||||
|  |   } | ||||||
|  | ] | ||||||
| @ -62,6 +62,16 @@ | |||||||
|             <artifactId>spqr</artifactId> |             <artifactId>spqr</artifactId> | ||||||
|             <version>0.11.2</version> |             <version>0.11.2</version> | ||||||
|         </dependency> |         </dependency> | ||||||
|  |         <dependency> | ||||||
|  |             <groupId>org.reflections</groupId> | ||||||
|  |             <artifactId>reflections</artifactId> | ||||||
|  |             <version>0.10.2</version> | ||||||
|  |         </dependency> | ||||||
|  |         <dependency> | ||||||
|  |             <groupId>org.jboss</groupId> | ||||||
|  |             <artifactId>jandex</artifactId> | ||||||
|  |             <version>2.4.3.Final</version> | ||||||
|  |         </dependency> | ||||||
|     </dependencies> |     </dependencies> | ||||||
| 
 | 
 | ||||||
|     <build> |     <build> | ||||||
| @ -92,6 +102,27 @@ | |||||||
|                     </execution> |                     </execution> | ||||||
|                 </executions> |                 </executions> | ||||||
|             </plugin> |             </plugin> | ||||||
|  |             <plugin> | ||||||
|  |                 <groupId>org.jboss.jandex</groupId> | ||||||
|  |                 <artifactId>jandex-maven-plugin</artifactId> | ||||||
|  |                 <version>1.2.3</version> | ||||||
|  |                 <executions> | ||||||
|  |                     <execution> | ||||||
|  |                         <phase>compile</phase> | ||||||
|  |                         <id>make-index</id> | ||||||
|  |                         <goals> | ||||||
|  |                             <goal>jandex</goal> | ||||||
|  |                         </goals> | ||||||
|  |                         <configuration> | ||||||
|  |                             <fileSets> | ||||||
|  |                                 <fileSet> | ||||||
|  |                                     <directory>${project.build.outputDirectory}</directory> | ||||||
|  |                                 </fileSet> | ||||||
|  |                             </fileSets> | ||||||
|  |                         </configuration> | ||||||
|  |                     </execution> | ||||||
|  |                 </executions> | ||||||
|  |             </plugin> | ||||||
|         </plugins> |         </plugins> | ||||||
|     </build> |     </build> | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -0,0 +1,14 @@ | |||||||
|  | package com.baeldung.annotation.scanner; | ||||||
|  | 
 | ||||||
|  | @SampleAnnotation(name = "SampleAnnotatedClass") | ||||||
|  | public class SampleAnnotatedClass { | ||||||
|  | 
 | ||||||
|  |     @SampleAnnotation(name = "annotatedMethod") | ||||||
|  |     public void annotatedMethod() { | ||||||
|  |         //Do something | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void notAnnotatedMethod() { | ||||||
|  |         //Do something | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,14 @@ | |||||||
|  | package com.baeldung.annotation.scanner; | ||||||
|  | 
 | ||||||
|  | import static java.lang.annotation.ElementType.METHOD; | ||||||
|  | import static java.lang.annotation.ElementType.TYPE; | ||||||
|  | import static java.lang.annotation.RetentionPolicy.RUNTIME; | ||||||
|  | 
 | ||||||
|  | import java.lang.annotation.Retention; | ||||||
|  | import java.lang.annotation.Target; | ||||||
|  | 
 | ||||||
|  | @Target({ METHOD, TYPE }) | ||||||
|  | @Retention(RUNTIME) | ||||||
|  | public @interface SampleAnnotation { | ||||||
|  |     String name(); | ||||||
|  | } | ||||||
| @ -0,0 +1,13 @@ | |||||||
|  | package com.baeldung.annotation.scanner; | ||||||
|  | 
 | ||||||
|  | import java.util.List; | ||||||
|  | 
 | ||||||
|  | public interface SampleAnnotationScanner { | ||||||
|  |     List<String> scanAnnotatedMethods(); | ||||||
|  | 
 | ||||||
|  |     List<String> scanAnnotatedClasses(); | ||||||
|  | 
 | ||||||
|  |     boolean supportsMethodScan(); | ||||||
|  | 
 | ||||||
|  |     boolean supportsClassScan(); | ||||||
|  | } | ||||||
| @ -0,0 +1,4 @@ | |||||||
|  | package com.baeldung.annotation.scanner; | ||||||
|  | 
 | ||||||
|  | public class ScanNotSupportedException extends RuntimeException{ | ||||||
|  | } | ||||||
| @ -0,0 +1,7 @@ | |||||||
|  | package com.baeldung.annotation.scanner; | ||||||
|  | 
 | ||||||
|  | public class UnexpectedScanException extends RuntimeException { | ||||||
|  |     public UnexpectedScanException(Throwable ex) { | ||||||
|  |         super(ex); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,76 @@ | |||||||
|  | package com.baeldung.annotation.scanner.jandexlib; | ||||||
|  | 
 | ||||||
|  | import java.io.IOException; | ||||||
|  | import java.util.ArrayList; | ||||||
|  | import java.util.Collections; | ||||||
|  | import java.util.List; | ||||||
|  | 
 | ||||||
|  | import org.jboss.jandex.AnnotationInstance; | ||||||
|  | import org.jboss.jandex.AnnotationTarget; | ||||||
|  | import org.jboss.jandex.DotName; | ||||||
|  | import org.jboss.jandex.Index; | ||||||
|  | import org.jboss.jandex.IndexReader; | ||||||
|  | import org.springframework.beans.factory.annotation.Value; | ||||||
|  | import org.springframework.core.io.Resource; | ||||||
|  | import org.springframework.stereotype.Service; | ||||||
|  | 
 | ||||||
|  | import com.baeldung.annotation.scanner.SampleAnnotationScanner; | ||||||
|  | import com.baeldung.annotation.scanner.UnexpectedScanException; | ||||||
|  | 
 | ||||||
|  | @Service | ||||||
|  | public class JandexScannerService implements SampleAnnotationScanner { | ||||||
|  |     @Value("classpath:META-INF/jandex.idx") | ||||||
|  |     private Resource appFile; | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public List<String> scanAnnotatedMethods() { | ||||||
|  |         try { | ||||||
|  |             final IndexReader reader = new IndexReader(appFile.getInputStream()); | ||||||
|  |             Index jandexFile = reader.read(); | ||||||
|  |             final List<AnnotationInstance> appAnnotationList = jandexFile.getAnnotations(DotName.createSimple("com.baeldung.annotation.scanner.SampleAnnotation")); | ||||||
|  |             List<String> annotatedMethods = new ArrayList<>(); | ||||||
|  |             for (AnnotationInstance annotationInstance : appAnnotationList) { | ||||||
|  |                 if (annotationInstance.target() | ||||||
|  |                     .kind() == AnnotationTarget.Kind.METHOD) { | ||||||
|  |                     annotatedMethods.add(annotationInstance.value("name") | ||||||
|  |                         .value() | ||||||
|  |                         .toString()); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             return Collections.unmodifiableList(annotatedMethods); | ||||||
|  |         } catch (IOException e) { | ||||||
|  |             throw new UnexpectedScanException(e); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public List<String> scanAnnotatedClasses() { | ||||||
|  |         try { | ||||||
|  |             final IndexReader reader = new IndexReader(appFile.getInputStream()); | ||||||
|  |             Index jandexFile = reader.read(); | ||||||
|  |             final List<AnnotationInstance> appAnnotationList = jandexFile.getAnnotations(DotName.createSimple("com.baeldung.annotation.scanner.SampleAnnotation")); | ||||||
|  |             List<String> annotatedClasses = new ArrayList<>(); | ||||||
|  |             for (AnnotationInstance annotationInstance : appAnnotationList) { | ||||||
|  |                 if (annotationInstance.target() | ||||||
|  |                     .kind() == AnnotationTarget.Kind.CLASS) { | ||||||
|  |                     annotatedClasses.add(annotationInstance.value("name") | ||||||
|  |                         .value() | ||||||
|  |                         .toString()); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             return Collections.unmodifiableList(annotatedClasses); | ||||||
|  |         } catch (IOException e) { | ||||||
|  |             throw new UnexpectedScanException(e); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public boolean supportsMethodScan() { | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public boolean supportsClassScan() { | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,58 @@ | |||||||
|  | package com.baeldung.annotation.scanner.javareflectionlib; | ||||||
|  | 
 | ||||||
|  | import java.lang.reflect.Method; | ||||||
|  | import java.util.ArrayList; | ||||||
|  | import java.util.Collections; | ||||||
|  | import java.util.List; | ||||||
|  | 
 | ||||||
|  | import org.springframework.stereotype.Service; | ||||||
|  | 
 | ||||||
|  | import com.baeldung.annotation.scanner.SampleAnnotation; | ||||||
|  | import com.baeldung.annotation.scanner.SampleAnnotationScanner; | ||||||
|  | import com.baeldung.annotation.scanner.UnexpectedScanException; | ||||||
|  | 
 | ||||||
|  | @Service | ||||||
|  | public class JavaReflectionsScannerService implements SampleAnnotationScanner { | ||||||
|  |     @Override | ||||||
|  |     public List<String> scanAnnotatedMethods() { | ||||||
|  |         try { | ||||||
|  |             Class<?> clazz = ClassLoader.getSystemClassLoader() | ||||||
|  |                 .loadClass("com.baeldung.annotation.scanner.SampleAnnotatedClass"); | ||||||
|  |             Method[] methods = clazz.getMethods(); | ||||||
|  |             List<String> annotatedMethods = new ArrayList<>(); | ||||||
|  |             for (Method method : methods) { | ||||||
|  |                 SampleAnnotation annotation = method.getAnnotation(SampleAnnotation.class); | ||||||
|  |                 if (annotation != null) { | ||||||
|  |                     annotatedMethods.add(annotation.name()); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             return Collections.unmodifiableList(annotatedMethods); | ||||||
|  |         } catch (ClassNotFoundException e) { | ||||||
|  |             throw new UnexpectedScanException(e); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public List<String> scanAnnotatedClasses() { | ||||||
|  |         try { | ||||||
|  |             Class<?> clazz = ClassLoader.getSystemClassLoader() | ||||||
|  |                 .loadClass("com.baeldung.annotation.scanner.SampleAnnotatedClass"); | ||||||
|  |             SampleAnnotation classAnnotation = clazz.getAnnotation(SampleAnnotation.class); | ||||||
|  |             List<String> annotatedClasses = new ArrayList<>(); | ||||||
|  |             annotatedClasses.add(classAnnotation.name()); | ||||||
|  |             return Collections.unmodifiableList(annotatedClasses); | ||||||
|  |         } catch (ClassNotFoundException e) { | ||||||
|  |             throw new UnexpectedScanException(e); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public boolean supportsMethodScan() { | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public boolean supportsClassScan() { | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,45 @@ | |||||||
|  | package com.baeldung.annotation.scanner.reflectionslib; | ||||||
|  | 
 | ||||||
|  | import java.lang.reflect.Method; | ||||||
|  | import java.util.List; | ||||||
|  | import java.util.Set; | ||||||
|  | import java.util.stream.Collectors; | ||||||
|  | 
 | ||||||
|  | import org.reflections.Reflections; | ||||||
|  | import org.springframework.stereotype.Service; | ||||||
|  | 
 | ||||||
|  | import com.baeldung.annotation.scanner.SampleAnnotation; | ||||||
|  | import com.baeldung.annotation.scanner.SampleAnnotationScanner; | ||||||
|  | 
 | ||||||
|  | @Service | ||||||
|  | public class ReflectionsScannerService implements SampleAnnotationScanner { | ||||||
|  |     @Override | ||||||
|  |     public List<String> scanAnnotatedMethods() { | ||||||
|  |         Reflections reflections = new Reflections("com.baeldung.annotation.scanner"); | ||||||
|  |         Set<Method> methods = reflections.getMethodsAnnotatedWith(SampleAnnotation.class); | ||||||
|  |         return methods.stream() | ||||||
|  |             .map(method -> method.getAnnotation(SampleAnnotation.class) | ||||||
|  |                 .name()) | ||||||
|  |             .collect(Collectors.toList()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public List<String> scanAnnotatedClasses() { | ||||||
|  |         Reflections reflections = new Reflections("com.baeldung.annotation.scanner"); | ||||||
|  |         Set<Class<?>> types = reflections.getTypesAnnotatedWith(SampleAnnotation.class); | ||||||
|  |         return types.stream() | ||||||
|  |             .map(clazz -> clazz.getAnnotation(SampleAnnotation.class) | ||||||
|  |                 .name()) | ||||||
|  |             .collect(Collectors.toList()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public boolean supportsMethodScan() { | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public boolean supportsClassScan() { | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,52 @@ | |||||||
|  | package com.baeldung.annotation.scanner.springcontextlib; | ||||||
|  | 
 | ||||||
|  | import java.util.ArrayList; | ||||||
|  | import java.util.Collections; | ||||||
|  | import java.util.List; | ||||||
|  | import java.util.Map; | ||||||
|  | import java.util.Set; | ||||||
|  | 
 | ||||||
|  | import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition; | ||||||
|  | import org.springframework.beans.factory.config.BeanDefinition; | ||||||
|  | import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider; | ||||||
|  | import org.springframework.core.type.filter.AnnotationTypeFilter; | ||||||
|  | import org.springframework.stereotype.Service; | ||||||
|  | 
 | ||||||
|  | import com.baeldung.annotation.scanner.SampleAnnotation; | ||||||
|  | import com.baeldung.annotation.scanner.SampleAnnotationScanner; | ||||||
|  | import com.baeldung.annotation.scanner.ScanNotSupportedException; | ||||||
|  | 
 | ||||||
|  | @Service | ||||||
|  | public class SpringBeanAnnotationScannerService implements SampleAnnotationScanner { | ||||||
|  |     @Override | ||||||
|  |     public List<String> scanAnnotatedMethods() { | ||||||
|  |         throw new ScanNotSupportedException(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public List<String> scanAnnotatedClasses() { | ||||||
|  |         ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(false); | ||||||
|  |         provider.addIncludeFilter(new AnnotationTypeFilter(SampleAnnotation.class)); | ||||||
|  |         Set<BeanDefinition> beanDefs = provider.findCandidateComponents("com.baeldung.annotation.scanner"); | ||||||
|  |         List<String> annotatedBeans = new ArrayList<>(); | ||||||
|  |         for (BeanDefinition bd : beanDefs) { | ||||||
|  |             if (bd instanceof AnnotatedBeanDefinition) { | ||||||
|  |                 Map<String, Object> annotAttributeMap = ((AnnotatedBeanDefinition) bd).getMetadata() | ||||||
|  |                     .getAnnotationAttributes(SampleAnnotation.class.getCanonicalName()); | ||||||
|  |                 annotatedBeans.add(annotAttributeMap.get("name") | ||||||
|  |                     .toString()); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         return Collections.unmodifiableList(annotatedBeans); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public boolean supportsMethodScan() { | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public boolean supportsClassScan() { | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,42 @@ | |||||||
|  | package com.baeldung.annotation.scanner.springcorelib; | ||||||
|  | 
 | ||||||
|  | import java.util.Arrays; | ||||||
|  | import java.util.List; | ||||||
|  | import java.util.stream.Collectors; | ||||||
|  | 
 | ||||||
|  | import org.springframework.core.annotation.AnnotationUtils; | ||||||
|  | import org.springframework.stereotype.Service; | ||||||
|  | import org.springframework.util.ClassUtils; | ||||||
|  | 
 | ||||||
|  | import com.baeldung.annotation.scanner.SampleAnnotationScanner; | ||||||
|  | import com.baeldung.annotation.scanner.SampleAnnotatedClass; | ||||||
|  | import com.baeldung.annotation.scanner.SampleAnnotation; | ||||||
|  | import com.baeldung.annotation.scanner.ScanNotSupportedException; | ||||||
|  | 
 | ||||||
|  | @Service | ||||||
|  | public class SpringCoreAnnotationScannerService implements SampleAnnotationScanner { | ||||||
|  |     @Override | ||||||
|  |     public List<String> scanAnnotatedMethods() { | ||||||
|  |         final Class<?> userClass = ClassUtils.getUserClass(SampleAnnotatedClass.class); | ||||||
|  |         return Arrays.stream(userClass.getMethods()) | ||||||
|  |             .filter(method -> AnnotationUtils.getAnnotation(method, SampleAnnotation.class) != null) | ||||||
|  |             .map(method -> method.getAnnotation(SampleAnnotation.class) | ||||||
|  |                 .name()) | ||||||
|  |             .collect(Collectors.toList()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public List<String> scanAnnotatedClasses() { | ||||||
|  |         throw new ScanNotSupportedException(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public boolean supportsMethodScan() { | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public boolean supportsClassScan() { | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,47 @@ | |||||||
|  | package com.baeldung.annotation.scanner; | ||||||
|  | 
 | ||||||
|  | import java.util.Collection; | ||||||
|  | import java.util.List; | ||||||
|  | import java.util.stream.Collectors; | ||||||
|  | 
 | ||||||
|  | import org.junit.Test; | ||||||
|  | import org.junit.runner.RunWith; | ||||||
|  | import org.springframework.beans.factory.annotation.Autowired; | ||||||
|  | import org.springframework.boot.test.context.SpringBootTest; | ||||||
|  | import org.springframework.test.context.junit4.SpringRunner; | ||||||
|  | 
 | ||||||
|  | import static org.junit.Assert.*; | ||||||
|  | 
 | ||||||
|  | @RunWith(SpringRunner.class) | ||||||
|  | @SpringBootTest | ||||||
|  | public class SampleAnnotationScannerUnitTest { | ||||||
|  |     @Autowired | ||||||
|  |     private List<SampleAnnotationScanner> scannerList; | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void givenPackage_whenScanAnnotatedClasses_thenAnnotationValues() { | ||||||
|  |         final List<String> annotatedClasses = scannerList.stream() | ||||||
|  |             .filter(SampleAnnotationScanner::supportsClassScan) | ||||||
|  |             .map(SampleAnnotationScanner::scanAnnotatedClasses) | ||||||
|  |             .flatMap(Collection::stream) | ||||||
|  |             .collect(Collectors.toList()); | ||||||
|  | 
 | ||||||
|  |         assertNotNull(annotatedClasses); | ||||||
|  |         assertEquals(4, annotatedClasses.size()); | ||||||
|  |         annotatedClasses.forEach(annotValue -> assertEquals("SampleAnnotatedClass", annotValue)); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void givenPackage_whenScanAnnotatedMethods_thenAnnotationValues() { | ||||||
|  |         final List<String> annotatedMethods = scannerList.stream() | ||||||
|  |             .filter(SampleAnnotationScanner::supportsMethodScan) | ||||||
|  |             .map(SampleAnnotationScanner::scanAnnotatedMethods) | ||||||
|  |             .flatMap(Collection::stream) | ||||||
|  |             .collect(Collectors.toList()); | ||||||
|  | 
 | ||||||
|  |         assertNotNull(annotatedMethods); | ||||||
|  |         assertEquals(3, annotatedMethods.size()); | ||||||
|  |         annotatedMethods.forEach(annotValue -> assertEquals("annotatedMethod", annotValue)); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
| @ -40,6 +40,18 @@ | |||||||
|             <artifactId>commons-io</artifactId> |             <artifactId>commons-io</artifactId> | ||||||
|             <version>${commons-io.version}</version> |             <version>${commons-io.version}</version> | ||||||
|         </dependency> |         </dependency> | ||||||
|  |         <dependency> | ||||||
|  |             <groupId>org.springframework.boot</groupId> | ||||||
|  |             <artifactId>spring-boot-starter-test</artifactId> | ||||||
|  |             <scope>test</scope> | ||||||
|  |         </dependency> | ||||||
|     </dependencies> |     </dependencies> | ||||||
| 
 | 
 | ||||||
|  |     <build> | ||||||
|  |         <resources> | ||||||
|  |             <resource> | ||||||
|  |                 <directory>/src/main/resources</directory> | ||||||
|  |             </resource> | ||||||
|  |         </resources> | ||||||
|  |     </build> | ||||||
| </project> | </project> | ||||||
| @ -1,9 +1,12 @@ | |||||||
| package com.baeldung.produceimage.controller; | package com.baeldung.produceimage.controller; | ||||||
| 
 | 
 | ||||||
| import org.apache.commons.io.IOUtils; | import org.apache.commons.io.IOUtils; | ||||||
|  | import org.springframework.core.io.InputStreamResource; | ||||||
| import org.springframework.http.MediaType; | import org.springframework.http.MediaType; | ||||||
|  | import org.springframework.http.ResponseEntity; | ||||||
| import org.springframework.stereotype.Controller; | import org.springframework.stereotype.Controller; | ||||||
| import org.springframework.web.bind.annotation.GetMapping; | import org.springframework.web.bind.annotation.GetMapping; | ||||||
|  | import org.springframework.web.bind.annotation.RequestParam; | ||||||
| import org.springframework.web.bind.annotation.ResponseBody; | import org.springframework.web.bind.annotation.ResponseBody; | ||||||
| 
 | 
 | ||||||
| import java.io.IOException; | import java.io.IOException; | ||||||
| @ -29,6 +32,18 @@ public class DataProducerController { | |||||||
|         return IOUtils.toByteArray(in); |         return IOUtils.toByteArray(in); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     @GetMapping("/get-image-dynamic-type") | ||||||
|  |     @ResponseBody | ||||||
|  |     public ResponseEntity<InputStreamResource> getImageDynamicType(@RequestParam("jpg") boolean jpg) { | ||||||
|  |         final MediaType contentType = jpg ? MediaType.IMAGE_JPEG : MediaType.IMAGE_PNG; | ||||||
|  |         final InputStream in = jpg ? | ||||||
|  |                 getClass().getResourceAsStream("/com/baeldung/produceimage/image.jpg") : | ||||||
|  |                 getClass().getResourceAsStream("/com/baeldung/produceimage/image.png"); | ||||||
|  |         return ResponseEntity.ok() | ||||||
|  |                 .contentType(contentType) | ||||||
|  |                 .body(new InputStreamResource(in)); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     @GetMapping(value = "/get-file", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE) |     @GetMapping(value = "/get-file", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE) | ||||||
|     public @ResponseBody byte[] getFile() throws IOException { |     public @ResponseBody byte[] getFile() throws IOException { | ||||||
|         final InputStream in = getClass().getResourceAsStream("/com/baeldung/produceimage/data.txt"); |         final InputStream in = getClass().getResourceAsStream("/com/baeldung/produceimage/data.txt"); | ||||||
|  | |||||||
| @ -0,0 +1 @@ | |||||||
|  | Hello Baeldung! | ||||||
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 8.1 KiB | 
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 4.5 KiB | 
| @ -0,0 +1,46 @@ | |||||||
|  | package com.baeldung.produceimage; | ||||||
|  | 
 | ||||||
|  | import org.junit.jupiter.api.BeforeEach; | ||||||
|  | import org.junit.jupiter.api.Test; | ||||||
|  | import org.springframework.beans.factory.annotation.Autowired; | ||||||
|  | import org.springframework.boot.test.context.SpringBootTest; | ||||||
|  | import org.springframework.http.HttpHeaders; | ||||||
|  | import org.springframework.http.MediaType; | ||||||
|  | import org.springframework.test.web.servlet.MockMvc; | ||||||
|  | import org.springframework.test.web.servlet.setup.MockMvcBuilders; | ||||||
|  | import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; | ||||||
|  | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; | ||||||
|  | 
 | ||||||
|  | import org.springframework.web.context.WebApplicationContext; | ||||||
|  | 
 | ||||||
|  | @SpringBootTest(classes = ImageApplication.class, | ||||||
|  |         webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) | ||||||
|  | public class DataProducerControllerIntegrationTest { | ||||||
|  | 
 | ||||||
|  |     @Autowired | ||||||
|  |     private WebApplicationContext webApplicationContext; | ||||||
|  | 
 | ||||||
|  |     private MockMvc mockMvc; | ||||||
|  | 
 | ||||||
|  |     @BeforeEach | ||||||
|  |     public void setup() { | ||||||
|  |         this.mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     void givenJpgTrue_whenGetImageDynamicType_ThenContentTypeIsJpg() throws Exception { | ||||||
|  |         mockMvc.perform(get("/get-image-dynamic-type?jpg=true")) | ||||||
|  |                 .andExpect(status().isOk()) | ||||||
|  |                 .andExpect(content().contentType(MediaType.IMAGE_JPEG)) | ||||||
|  |                 .andExpect(header().stringValues(HttpHeaders.CONTENT_TYPE, MediaType.IMAGE_JPEG_VALUE)); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     void givenJpgFalse_whenGetImageDynamicType_ThenContentTypeIsFalse() throws Exception { | ||||||
|  |         mockMvc.perform(get("/get-image-dynamic-type?jpg=false")) | ||||||
|  |                 .andExpect(status().isOk()) | ||||||
|  |                 .andExpect(content().contentType(MediaType.IMAGE_PNG)) | ||||||
|  |                 .andExpect(header().stringValues(HttpHeaders.CONTENT_TYPE, MediaType.IMAGE_PNG_VALUE)); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
| @ -1,9 +1,7 @@ | |||||||
| package com.baeldung.springvalidation; | package com.baeldung.springvalidation; | ||||||
| 
 | 
 | ||||||
| import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; | import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; | ||||||
| import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.model; | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; | ||||||
| import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; |  | ||||||
| import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.view; |  | ||||||
| 
 | 
 | ||||||
| import org.junit.jupiter.api.Test; | import org.junit.jupiter.api.Test; | ||||||
| import org.springframework.beans.factory.annotation.Autowired; | import org.springframework.beans.factory.annotation.Autowired; | ||||||
| @ -15,7 +13,7 @@ import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; | |||||||
| 
 | 
 | ||||||
| @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) | @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) | ||||||
| @AutoConfigureMockMvc | @AutoConfigureMockMvc | ||||||
| public class UserAccountUnitTest { | public class UserAccountIntegrationTest { | ||||||
| 
 | 
 | ||||||
|     @Autowired |     @Autowired | ||||||
|     private MockMvc mockMvc; |     private MockMvc mockMvc; | ||||||
| @ -46,10 +44,8 @@ public class UserAccountUnitTest { | |||||||
|     public void givenSaveBasicInfoStep1_whenIncorrectInput_thenError() throws Exception { |     public void givenSaveBasicInfoStep1_whenIncorrectInput_thenError() throws Exception { | ||||||
|         this.mockMvc.perform(MockMvcRequestBuilders.post("/saveBasicInfoStep1") |         this.mockMvc.perform(MockMvcRequestBuilders.post("/saveBasicInfoStep1") | ||||||
|             .accept(MediaType.TEXT_HTML)) |             .accept(MediaType.TEXT_HTML)) | ||||||
|             // .param("name", "test123") |  | ||||||
|             // .param("password", "pass")) |  | ||||||
|             .andExpect(model().errorCount(2)) |             .andExpect(model().errorCount(2)) | ||||||
|             // .andExpect(view().name("error")) |             .andExpect(view().name("error")) | ||||||
|             .andExpect(status().isOk()) |             .andExpect(status().isOk()) | ||||||
|             .andDo(print()); |             .andDo(print()); | ||||||
|     } |     } | ||||||
| @ -0,0 +1,32 @@ | |||||||
|  | package com.baeldung.defaultglobalsecurityscheme; | ||||||
|  | 
 | ||||||
|  | import org.springframework.boot.SpringApplication; | ||||||
|  | import org.springframework.boot.autoconfigure.SpringBootApplication; | ||||||
|  | import org.springframework.context.annotation.Bean; | ||||||
|  | import org.springframework.security.config.annotation.web.builders.HttpSecurity; | ||||||
|  | import org.springframework.security.web.SecurityFilterChain; | ||||||
|  | 
 | ||||||
|  | import io.swagger.v3.oas.annotations.OpenAPIDefinition; | ||||||
|  | import io.swagger.v3.oas.annotations.enums.SecuritySchemeIn; | ||||||
|  | import io.swagger.v3.oas.annotations.enums.SecuritySchemeType; | ||||||
|  | import io.swagger.v3.oas.annotations.info.Info; | ||||||
|  | import io.swagger.v3.oas.annotations.security.SecurityRequirement; | ||||||
|  | import io.swagger.v3.oas.annotations.security.SecurityScheme; | ||||||
|  | 
 | ||||||
|  | @SpringBootApplication | ||||||
|  | @OpenAPIDefinition(info = @Info(title = "Apply Default Global SecurityScheme in springdoc-openapi", version = "1.0.0"), security = { @SecurityRequirement(name = "api_key") }) | ||||||
|  | @SecurityScheme(type = SecuritySchemeType.APIKEY, name = "api_key", in = SecuritySchemeIn.HEADER) | ||||||
|  | public class DefaultGlobalSecuritySchemeApplication { | ||||||
|  |     @Bean | ||||||
|  |     public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { | ||||||
|  |         return http.authorizeHttpRequests(authorizeRequests -> authorizeRequests.antMatchers("/api/auth/**", "/swagger-ui-custom.html", "/swagger-ui.html", "/swagger-ui/**", "/v3/api-docs/**", "/webjars/**", "/swagger-ui/index.html", "/api-docs/**") | ||||||
|  |             .permitAll() | ||||||
|  |             .anyRequest() | ||||||
|  |             .authenticated()) | ||||||
|  |             .build(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static void main(String[] args) { | ||||||
|  |         SpringApplication.run(DefaultGlobalSecuritySchemeApplication.class, args); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,61 @@ | |||||||
|  | package com.baeldung.defaultglobalsecurityscheme.controller; | ||||||
|  | 
 | ||||||
|  | import java.time.OffsetDateTime; | ||||||
|  | import java.time.ZoneOffset; | ||||||
|  | 
 | ||||||
|  | import javax.validation.Valid; | ||||||
|  | 
 | ||||||
|  | import org.springframework.http.ResponseEntity; | ||||||
|  | import org.springframework.web.bind.annotation.RequestBody; | ||||||
|  | import org.springframework.web.bind.annotation.RequestHeader; | ||||||
|  | import org.springframework.web.bind.annotation.RequestMapping; | ||||||
|  | import org.springframework.web.bind.annotation.RequestMethod; | ||||||
|  | import org.springframework.web.bind.annotation.RestController; | ||||||
|  | 
 | ||||||
|  | import com.baeldung.defaultglobalsecurityscheme.dto.LoginDto; | ||||||
|  | import com.baeldung.defaultglobalsecurityscheme.dto.ApplicationExceptionDto; | ||||||
|  | import com.baeldung.defaultglobalsecurityscheme.dto.PingResponseDto; | ||||||
|  | import com.baeldung.defaultglobalsecurityscheme.dto.TokenDto; | ||||||
|  | 
 | ||||||
|  | import io.swagger.v3.oas.annotations.Operation; | ||||||
|  | import io.swagger.v3.oas.annotations.Parameter; | ||||||
|  | import io.swagger.v3.oas.annotations.media.Content; | ||||||
|  | import io.swagger.v3.oas.annotations.media.ExampleObject; | ||||||
|  | import io.swagger.v3.oas.annotations.media.Schema; | ||||||
|  | import io.swagger.v3.oas.annotations.responses.ApiResponse; | ||||||
|  | import io.swagger.v3.oas.annotations.security.SecurityRequirements; | ||||||
|  | 
 | ||||||
|  | @RestController | ||||||
|  | @RequestMapping("/") | ||||||
|  | public class DefaultGlobalSecuritySchemeOpenApiController { | ||||||
|  |     @RequestMapping(method = RequestMethod.POST, value = "/login", produces = { "application/json" }, consumes = { "application/json" }) | ||||||
|  |     @Operation(operationId = "login", responses = { | ||||||
|  |             @ApiResponse(responseCode = "200", description = "api_key to be used in the secured-ping entry point", content = { @Content(mediaType = "application/json", schema = @Schema(implementation = TokenDto.class)) }), | ||||||
|  |             @ApiResponse(responseCode = "401", description = "Unauthorized request", content = { @Content(mediaType = "application/json", schema = @Schema(implementation = ApplicationExceptionDto.class)) }) }) | ||||||
|  |     @SecurityRequirements() | ||||||
|  |     public ResponseEntity<TokenDto> login(@Parameter(name = "LoginDto", description = "Login") @Valid @RequestBody(required = true) LoginDto loginDto) { | ||||||
|  |         TokenDto token = new TokenDto(); | ||||||
|  |         token.setRaw("Generated Token"); | ||||||
|  |         return ResponseEntity.ok(token); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Operation(operationId = "ping", responses = { | ||||||
|  |             @ApiResponse(responseCode = "200", description = "Ping that needs an api_key attribute in the header", content = { | ||||||
|  |                     @Content(mediaType = "application/json", schema = @Schema(implementation = PingResponseDto.class), examples = { @ExampleObject(value = "{ pong: '2022-06-17T18:30:33.465+02:00' }") }) }), | ||||||
|  |             @ApiResponse(responseCode = "401", description = "Unauthorized request", content = { @Content(mediaType = "application/json", schema = @Schema(implementation = ApplicationExceptionDto.class)) }), | ||||||
|  |             @ApiResponse(responseCode = "403", description = "Forbidden request", content = { @Content(mediaType = "application/json", schema = @Schema(implementation = ApplicationExceptionDto.class)) }) }) | ||||||
|  |     @RequestMapping(method = RequestMethod.GET, value = "/ping", produces = { "application/json" }) | ||||||
|  |     public ResponseEntity<PingResponseDto> ping(@RequestHeader(name = "api_key", required = false) String api_key) { | ||||||
|  |         int year = 2000; | ||||||
|  |         int month = 1; | ||||||
|  |         int dayOfMonth = 1; | ||||||
|  |         int hour = 0; | ||||||
|  |         int minute = 0; | ||||||
|  |         int second = 0; | ||||||
|  |         int nanoSeccond = 0; | ||||||
|  |         ZoneOffset offset = ZoneOffset.UTC; | ||||||
|  |         PingResponseDto response = new PingResponseDto(); | ||||||
|  |         response.setPong(OffsetDateTime.of(year, month, dayOfMonth, hour, minute, second, nanoSeccond, offset)); | ||||||
|  |         return ResponseEntity.ok(response); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,26 @@ | |||||||
|  | package com.baeldung.defaultglobalsecurityscheme.dto; | ||||||
|  | 
 | ||||||
|  | public class ApplicationExceptionDto { | ||||||
|  |     private long errorCode; | ||||||
|  |     private String description; | ||||||
|  | 
 | ||||||
|  |     public ApplicationExceptionDto() { | ||||||
|  |         super(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public long getErrorCode() { | ||||||
|  |         return errorCode; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void setErrorCode(long errorCode) { | ||||||
|  |         this.errorCode = errorCode; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public String getDescription() { | ||||||
|  |         return description; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void setDescription(String description) { | ||||||
|  |         this.description = description; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,103 @@ | |||||||
|  | package com.baeldung.defaultglobalsecurityscheme.dto; | ||||||
|  | 
 | ||||||
|  | import java.util.Objects; | ||||||
|  | 
 | ||||||
|  | import com.fasterxml.jackson.annotation.JsonProperty; | ||||||
|  | import com.fasterxml.jackson.annotation.JsonTypeName; | ||||||
|  | 
 | ||||||
|  | import io.swagger.v3.oas.annotations.media.Schema; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * LoginDto | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | @JsonTypeName("Login") | ||||||
|  | public class LoginDto { | ||||||
|  | 
 | ||||||
|  |     @JsonProperty("user") | ||||||
|  |     private String user; | ||||||
|  | 
 | ||||||
|  |     @JsonProperty("pass") | ||||||
|  |     private String pass; | ||||||
|  | 
 | ||||||
|  |     public LoginDto user(String user) { | ||||||
|  |         this.user = user; | ||||||
|  |         return this; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Get user | ||||||
|  |      * @return user | ||||||
|  |     */ | ||||||
|  | 
 | ||||||
|  |     @Schema(name = "user", required = true) | ||||||
|  |     public String getUser() { | ||||||
|  |         return user; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void setUser(String user) { | ||||||
|  |         this.user = user; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public LoginDto pass(String pass) { | ||||||
|  |         this.pass = pass; | ||||||
|  |         return this; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Get pass | ||||||
|  |      * @return pass | ||||||
|  |     */ | ||||||
|  | 
 | ||||||
|  |     @Schema(name = "pass", required = true) | ||||||
|  |     public String getPass() { | ||||||
|  |         return pass; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void setPass(String pass) { | ||||||
|  |         this.pass = pass; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public boolean equals(Object o) { | ||||||
|  |         if (this == o) { | ||||||
|  |             return true; | ||||||
|  |         } | ||||||
|  |         if (o == null || getClass() != o.getClass()) { | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|  |         LoginDto login = (LoginDto) o; | ||||||
|  |         return Objects.equals(this.user, login.user) && Objects.equals(this.pass, login.pass); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public int hashCode() { | ||||||
|  |         return Objects.hash(user, pass); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public String toString() { | ||||||
|  |         StringBuilder sb = new StringBuilder(); | ||||||
|  |         sb.append("class LoginDto {\n"); | ||||||
|  |         sb.append("    user: ") | ||||||
|  |             .append(toIndentedString(user)) | ||||||
|  |             .append("\n"); | ||||||
|  |         sb.append("    pass: ") | ||||||
|  |             .append(toIndentedString(pass)) | ||||||
|  |             .append("\n"); | ||||||
|  |         sb.append("}"); | ||||||
|  |         return sb.toString(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Convert the given object to string with each line indented by 4 spaces | ||||||
|  |      * (except the first line). | ||||||
|  |      */ | ||||||
|  |     private String toIndentedString(Object o) { | ||||||
|  |         if (o == null) { | ||||||
|  |             return "null"; | ||||||
|  |         } | ||||||
|  |         return o.toString() | ||||||
|  |             .replace("\n", "\n    "); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,84 @@ | |||||||
|  | package com.baeldung.defaultglobalsecurityscheme.dto; | ||||||
|  | 
 | ||||||
|  | import java.time.OffsetDateTime; | ||||||
|  | import java.util.Objects; | ||||||
|  | 
 | ||||||
|  | import javax.validation.Valid; | ||||||
|  | 
 | ||||||
|  | import org.springframework.format.annotation.DateTimeFormat; | ||||||
|  | 
 | ||||||
|  | import com.fasterxml.jackson.annotation.JsonProperty; | ||||||
|  | import com.fasterxml.jackson.annotation.JsonTypeName; | ||||||
|  | 
 | ||||||
|  | import io.swagger.v3.oas.annotations.media.Schema; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * SecuredPingResponseDto | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | @JsonTypeName("PingResponse") | ||||||
|  | public class PingResponseDto { | ||||||
|  | 
 | ||||||
|  |     @JsonProperty("pong") | ||||||
|  |     @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) | ||||||
|  |     private OffsetDateTime pong; | ||||||
|  | 
 | ||||||
|  |     public PingResponseDto pong(OffsetDateTime pong) { | ||||||
|  |         this.pong = pong; | ||||||
|  |         return this; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Get pong | ||||||
|  |      * @return pong | ||||||
|  |     */ | ||||||
|  |     @Valid | ||||||
|  |     @Schema(name = "pong", required = false) | ||||||
|  |     public OffsetDateTime getPong() { | ||||||
|  |         return pong; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void setPong(OffsetDateTime pong) { | ||||||
|  |         this.pong = pong; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public boolean equals(Object o) { | ||||||
|  |         if (this == o) { | ||||||
|  |             return true; | ||||||
|  |         } | ||||||
|  |         if (o == null || getClass() != o.getClass()) { | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|  |         PingResponseDto securedPingResponse = (PingResponseDto) o; | ||||||
|  |         return Objects.equals(this.pong, securedPingResponse.pong); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public int hashCode() { | ||||||
|  |         return Objects.hash(pong); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public String toString() { | ||||||
|  |         StringBuilder sb = new StringBuilder(); | ||||||
|  |         sb.append("class PingResponseDto {\n"); | ||||||
|  |         sb.append("    pong: ") | ||||||
|  |             .append(toIndentedString(pong)) | ||||||
|  |             .append("\n"); | ||||||
|  |         sb.append("}"); | ||||||
|  |         return sb.toString(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Convert the given object to string with each line indented by 4 spaces | ||||||
|  |      * (except the first line). | ||||||
|  |      */ | ||||||
|  |     private String toIndentedString(Object o) { | ||||||
|  |         if (o == null) { | ||||||
|  |             return "null"; | ||||||
|  |         } | ||||||
|  |         return o.toString() | ||||||
|  |             .replace("\n", "\n    "); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,57 @@ | |||||||
|  | package com.baeldung.defaultglobalsecurityscheme.dto; | ||||||
|  | 
 | ||||||
|  | import com.fasterxml.jackson.annotation.JsonProperty; | ||||||
|  | import com.fasterxml.jackson.annotation.JsonTypeName; | ||||||
|  | 
 | ||||||
|  | import io.swagger.v3.oas.annotations.media.Schema; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * LoginDto | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | @JsonTypeName("Token") | ||||||
|  | public class TokenDto { | ||||||
|  | 
 | ||||||
|  |     @JsonProperty("raw") | ||||||
|  |     private String raw; | ||||||
|  | 
 | ||||||
|  |     @Schema(name = "raw", example = "app token") | ||||||
|  |     public String getRaw() { | ||||||
|  |         return raw; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void setRaw(String raw) { | ||||||
|  |         this.raw = raw; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public String toString() { | ||||||
|  |         return "TokenDto [raw=" + raw + "]"; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public int hashCode() { | ||||||
|  |         final int prime = 31; | ||||||
|  |         int result = 1; | ||||||
|  |         result = prime * result + ((raw == null) ? 0 : raw.hashCode()); | ||||||
|  |         return result; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public boolean equals(Object obj) { | ||||||
|  |         if (this == obj) | ||||||
|  |             return true; | ||||||
|  |         if (obj == null) | ||||||
|  |             return false; | ||||||
|  |         if (getClass() != obj.getClass()) | ||||||
|  |             return false; | ||||||
|  |         TokenDto other = (TokenDto) obj; | ||||||
|  |         if (raw == null) { | ||||||
|  |             if (other.raw != null) | ||||||
|  |                 return false; | ||||||
|  |         } else if (!raw.equals(other.raw)) | ||||||
|  |             return false; | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
| @ -26,11 +26,11 @@ import org.springframework.web.reactive.function.client.WebClient; | |||||||
| import dasniko.testcontainers.keycloak.KeycloakContainer; | import dasniko.testcontainers.keycloak.KeycloakContainer; | ||||||
| import io.restassured.RestAssured; | import io.restassured.RestAssured; | ||||||
| 
 | 
 | ||||||
| @ContextConfiguration(initializers = { IntegrationTest.Initializer.class }) | @ContextConfiguration(initializers = { KeycloakTestContainers.Initializer.class }) | ||||||
| @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) | @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) | ||||||
| public abstract class IntegrationTest { | public abstract class KeycloakTestContainers { | ||||||
| 
 | 
 | ||||||
|     private static final Logger LOGGER = LoggerFactory.getLogger(IntegrationTest.class.getName()); |     private static final Logger LOGGER = LoggerFactory.getLogger(KeycloakTestContainers.class.getName()); | ||||||
| 
 | 
 | ||||||
|     @LocalServerPort |     @LocalServerPort | ||||||
|     private int port; |     private int port; | ||||||
| @ -5,7 +5,11 @@ import static org.hamcrest.Matchers.equalTo; | |||||||
| 
 | 
 | ||||||
| import org.junit.jupiter.api.Test; | import org.junit.jupiter.api.Test; | ||||||
| 
 | 
 | ||||||
| class UserControllerIntegrationTest extends IntegrationTest { | /** | ||||||
|  |  * Requires Docker running on the machine to run without errors | ||||||
|  |  * Therefore, skipped from pipeline | ||||||
|  |  */ | ||||||
|  | class UserControllerManualTest extends KeycloakTestContainers { | ||||||
| 
 | 
 | ||||||
|     @Test |     @Test | ||||||
|     void givenAuthenticatedUser_whenGetMe_shouldReturnMyInfo() { |     void givenAuthenticatedUser_whenGetMe_shouldReturnMyInfo() { | ||||||
| @ -16,11 +16,11 @@ | |||||||
|     </parent> |     </parent> | ||||||
| 
 | 
 | ||||||
|     <modules> |     <modules> | ||||||
|         <module>basic-config</module> |  | ||||||
|         <module>additional-sources-simple</module> |         <module>additional-sources-simple</module> | ||||||
|  |         <module>basic-config</module> | ||||||
|  |         <module>dynamodb-config</module> | ||||||
|         <module>extra-configs</module> |         <module>extra-configs</module> | ||||||
|         <module>jdbc-config</module> |         <module>jdbc-config</module> | ||||||
|         <module>dynamodb-config</module> |  | ||||||
|         <module>zookeeper-config</module> |         <module>zookeeper-config</module> | ||||||
|     </modules> |     </modules> | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -16,10 +16,11 @@ | |||||||
|     </parent> |     </parent> | ||||||
| 
 | 
 | ||||||
|     <modules> |     <modules> | ||||||
|         <module>spring-cloud-eureka-server</module> |  | ||||||
|         <module>spring-cloud-eureka-client</module> |         <module>spring-cloud-eureka-client</module> | ||||||
|  |         <module>spring-cloud-eureka-client-profiles</module> | ||||||
|         <module>spring-cloud-eureka-feign-client</module> |         <module>spring-cloud-eureka-feign-client</module> | ||||||
|         <module>spring-cloud-eureka-feign-client-integration-test</module> |         <module>spring-cloud-eureka-feign-client-integration-test</module> | ||||||
|  |         <module>spring-cloud-eureka-server</module> | ||||||
|     </modules> |     </modules> | ||||||
| 
 | 
 | ||||||
|     <dependencyManagement> |     <dependencyManagement> | ||||||
|  | |||||||
| @ -15,9 +15,9 @@ | |||||||
|     </parent> |     </parent> | ||||||
| 
 | 
 | ||||||
|     <modules> |     <modules> | ||||||
|  |         <module>feign-rest-consumer</module> | ||||||
|         <module>rest-producer</module> |         <module>rest-producer</module> | ||||||
|         <module>rest-consumer</module> |         <module>rest-consumer</module> | ||||||
|         <module>feign-rest-consumer</module> |  | ||||||
|     </modules> |     </modules> | ||||||
| 
 | 
 | ||||||
| </project> | </project> | ||||||
| @ -9,7 +9,6 @@ | |||||||
|         <groupId>com.baeldung.cloud</groupId> |         <groupId>com.baeldung.cloud</groupId> | ||||||
|         <artifactId>spring-cloud-netflix-sidecar</artifactId> |         <artifactId>spring-cloud-netflix-sidecar</artifactId> | ||||||
|         <version>0.0.1-SNAPSHOT</version> |         <version>0.0.1-SNAPSHOT</version> | ||||||
|         <relativePath>../pom.xml</relativePath> |  | ||||||
|     </parent> |     </parent> | ||||||
|     <dependencies> |     <dependencies> | ||||||
|         <dependency> |         <dependency> | ||||||
|  | |||||||
| @ -11,10 +11,9 @@ | |||||||
|     <description>Netflix Sidecar project for Spring Boot</description> |     <description>Netflix Sidecar project for Spring Boot</description> | ||||||
| 
 | 
 | ||||||
|     <parent> |     <parent> | ||||||
|         <groupId>com.baeldung</groupId> |         <groupId>com.baeldung.spring.cloud</groupId> | ||||||
|         <artifactId>parent-boot-2</artifactId> |         <artifactId>spring-cloud-modules</artifactId> | ||||||
|         <version>0.0.1-SNAPSHOT</version> |         <version>1.0.0-SNAPSHOT</version> | ||||||
|         <relativePath>../../parent-boot-2</relativePath> |  | ||||||
|     </parent> |     </parent> | ||||||
| 
 | 
 | ||||||
|     <modules> |     <modules> | ||||||
|  | |||||||
| @ -11,7 +11,6 @@ | |||||||
|         <groupId>com.baeldung.cloud</groupId> |         <groupId>com.baeldung.cloud</groupId> | ||||||
|         <artifactId>spring-cloud-netflix-sidecar</artifactId> |         <artifactId>spring-cloud-netflix-sidecar</artifactId> | ||||||
|         <version>0.0.1-SNAPSHOT</version> |         <version>0.0.1-SNAPSHOT</version> | ||||||
|         <relativePath>../pom.xml</relativePath> |  | ||||||
|     </parent> |     </parent> | ||||||
| 
 | 
 | ||||||
|     <dependencies> |     <dependencies> | ||||||
|  | |||||||
| @ -9,10 +9,9 @@ | |||||||
|     <description>OpenFeign project for Spring Boot</description> |     <description>OpenFeign project for Spring Boot</description> | ||||||
| 
 | 
 | ||||||
|     <parent> |     <parent> | ||||||
|         <groupId>com.baeldung</groupId> |         <groupId>com.baeldung.spring.cloud</groupId> | ||||||
|         <artifactId>parent-boot-2</artifactId> |         <artifactId>spring-cloud-modules</artifactId> | ||||||
|         <version>0.0.1-SNAPSHOT</version> |         <version>1.0.0-SNAPSHOT</version> | ||||||
|         <relativePath>../../parent-boot-2</relativePath> |  | ||||||
|     </parent> |     </parent> | ||||||
| 
 | 
 | ||||||
|     <dependencyManagement> |     <dependencyManagement> | ||||||
|  | |||||||
| @ -17,9 +17,9 @@ | |||||||
| 
 | 
 | ||||||
|     <modules> |     <modules> | ||||||
|         <module>spring-zuul-foos-resource</module> |         <module>spring-zuul-foos-resource</module> | ||||||
|         <module>spring-zuul-ui</module> |  | ||||||
|         <module>spring-zuul-rate-limiting</module> |  | ||||||
|         <module>spring-zuul-post-filter</module> |         <module>spring-zuul-post-filter</module> | ||||||
|  |         <module>spring-zuul-rate-limiting</module> | ||||||
|  |         <module>spring-zuul-ui</module> | ||||||
|     </modules> |     </modules> | ||||||
| 
 | 
 | ||||||
|     <dependencyManagement> |     <dependencyManagement> | ||||||
|  | |||||||
| @ -41,6 +41,25 @@ | |||||||
|             <version>${spring-boot-test.version}</version> |             <version>${spring-boot-test.version}</version> | ||||||
|             <scope>test</scope> |             <scope>test</scope> | ||||||
|         </dependency> |         </dependency> | ||||||
|  |         <!-- https://mvnrepository.com/artifact/org.mockito/mockito-core --> | ||||||
|  |         <dependency> | ||||||
|  |             <groupId>org.mockito</groupId> | ||||||
|  |             <artifactId>mockito-core</artifactId> | ||||||
|  |             <version>4.6.1</version> | ||||||
|  |             <scope>test</scope> | ||||||
|  |         </dependency> | ||||||
|  |         <dependency> | ||||||
|  |             <groupId>org.apache.activemq.tooling</groupId> | ||||||
|  |             <artifactId>activemq-junit</artifactId> | ||||||
|  |             <version>5.16.5</version> | ||||||
|  |             <scope>test</scope> | ||||||
|  |         </dependency> | ||||||
|  |         <dependency> | ||||||
|  |             <groupId>org.testcontainers</groupId> | ||||||
|  |             <artifactId>testcontainers</artifactId> | ||||||
|  |             <version>1.17.3</version> | ||||||
|  |             <scope>test</scope> | ||||||
|  |         </dependency> | ||||||
|     </dependencies> |     </dependencies> | ||||||
| 
 | 
 | ||||||
|     <build> |     <build> | ||||||
|  | |||||||
| @ -0,0 +1,13 @@ | |||||||
|  | package com.baeldung.spring.jms.testing; | ||||||
|  | 
 | ||||||
|  | import org.springframework.context.ApplicationContext; | ||||||
|  | import org.springframework.context.annotation.AnnotationConfigApplicationContext; | ||||||
|  | import org.springframework.context.annotation.ComponentScan; | ||||||
|  | 
 | ||||||
|  | @ComponentScan | ||||||
|  | public class JmsApplication { | ||||||
|  | 
 | ||||||
|  |     public static void main(String[] args) { | ||||||
|  |         ApplicationContext context = new AnnotationConfigApplicationContext(JmsApplication.class); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,34 @@ | |||||||
|  | package com.baeldung.spring.jms.testing; | ||||||
|  | 
 | ||||||
|  | import javax.jms.ConnectionFactory; | ||||||
|  | 
 | ||||||
|  | import org.apache.activemq.ActiveMQConnectionFactory; | ||||||
|  | import org.springframework.context.annotation.Bean; | ||||||
|  | import org.springframework.context.annotation.Configuration; | ||||||
|  | import org.springframework.jms.annotation.EnableJms; | ||||||
|  | import org.springframework.jms.config.DefaultJmsListenerContainerFactory; | ||||||
|  | import org.springframework.jms.config.JmsListenerContainerFactory; | ||||||
|  | import org.springframework.jms.core.JmsTemplate; | ||||||
|  | 
 | ||||||
|  | @Configuration | ||||||
|  | @EnableJms | ||||||
|  | public class JmsConfig { | ||||||
|  | 
 | ||||||
|  |     @Bean | ||||||
|  |     public JmsListenerContainerFactory<?> jmsListenerContainerFactory() { | ||||||
|  |         DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory(); | ||||||
|  |         factory.setConnectionFactory(connectionFactory()); | ||||||
|  |         return factory; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Bean | ||||||
|  |     public ConnectionFactory connectionFactory() { | ||||||
|  |         return new ActiveMQConnectionFactory("tcp://localhost:61616"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Bean | ||||||
|  |     public JmsTemplate jmsTemplate() { | ||||||
|  |         return new JmsTemplate(connectionFactory()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
| @ -0,0 +1,20 @@ | |||||||
|  | package com.baeldung.spring.jms.testing; | ||||||
|  | 
 | ||||||
|  | import javax.jms.JMSException; | ||||||
|  | import javax.jms.TextMessage; | ||||||
|  | 
 | ||||||
|  | import org.slf4j.Logger; | ||||||
|  | import org.slf4j.LoggerFactory; | ||||||
|  | import org.springframework.jms.annotation.JmsListener; | ||||||
|  | import org.springframework.stereotype.Component; | ||||||
|  | 
 | ||||||
|  | @Component | ||||||
|  | public class MessageListener { | ||||||
|  | 
 | ||||||
|  |     private static final Logger logger = LoggerFactory.getLogger(MessageListener.class); | ||||||
|  | 
 | ||||||
|  |     @JmsListener(destination = "queue-1") | ||||||
|  |     public void sampleJmsListenerMethod(TextMessage message) throws JMSException { | ||||||
|  |         logger.info("JMS listener received text message: {}", message.getText()); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,21 @@ | |||||||
|  | package com.baeldung.spring.jms.testing; | ||||||
|  | 
 | ||||||
|  | import org.slf4j.Logger; | ||||||
|  | import org.slf4j.LoggerFactory; | ||||||
|  | import org.springframework.beans.factory.annotation.Autowired; | ||||||
|  | import org.springframework.jms.core.JmsTemplate; | ||||||
|  | import org.springframework.stereotype.Component; | ||||||
|  | 
 | ||||||
|  | @Component | ||||||
|  | public class MessageSender { | ||||||
|  | 
 | ||||||
|  |     @Autowired | ||||||
|  |     private JmsTemplate jmsTemplate; | ||||||
|  | 
 | ||||||
|  |     private static final Logger logger = LoggerFactory.getLogger(MessageSender.class); | ||||||
|  | 
 | ||||||
|  |     public void sendTextMessage(String destination, String message) { | ||||||
|  |         logger.info("Sending message to {} destination with text {}", destination, message); | ||||||
|  |         jmsTemplate.send(destination, s -> s.createTextMessage(message)); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,91 @@ | |||||||
|  | package com.baeldung.spring.jms.testing; | ||||||
|  | 
 | ||||||
|  | import static org.junit.jupiter.api.Assertions.assertEquals; | ||||||
|  | 
 | ||||||
|  | import javax.jms.ConnectionFactory; | ||||||
|  | import javax.jms.JMSException; | ||||||
|  | import javax.jms.TextMessage; | ||||||
|  | 
 | ||||||
|  | import org.apache.activemq.ActiveMQConnectionFactory; | ||||||
|  | import org.apache.activemq.junit.EmbeddedActiveMQBroker; | ||||||
|  | import org.junit.ClassRule; | ||||||
|  | import org.junit.Test; | ||||||
|  | import org.junit.runner.RunWith; | ||||||
|  | import org.mockito.ArgumentCaptor; | ||||||
|  | import org.mockito.Mockito; | ||||||
|  | import org.springframework.boot.test.mock.mockito.SpyBean; | ||||||
|  | import org.springframework.context.annotation.Bean; | ||||||
|  | import org.springframework.context.annotation.Configuration; | ||||||
|  | import org.springframework.jms.annotation.EnableJms; | ||||||
|  | import org.springframework.jms.config.DefaultJmsListenerContainerFactory; | ||||||
|  | import org.springframework.jms.config.JmsListenerContainerFactory; | ||||||
|  | import org.springframework.jms.core.JmsTemplate; | ||||||
|  | import org.springframework.test.context.ContextConfiguration; | ||||||
|  | import org.springframework.test.context.junit4.SpringRunner; | ||||||
|  | 
 | ||||||
|  | import com.baeldung.spring.jms.testing.EmbeddedActiveMqIntegrationTest.TestConfiguration; | ||||||
|  | 
 | ||||||
|  | @RunWith(SpringRunner.class) | ||||||
|  | @ContextConfiguration(classes = { TestConfiguration.class }) | ||||||
|  | public class EmbeddedActiveMqIntegrationTest { | ||||||
|  | 
 | ||||||
|  |     @ClassRule | ||||||
|  |     public static EmbeddedActiveMQBroker embeddedBroker = new EmbeddedActiveMQBroker(); | ||||||
|  | 
 | ||||||
|  |     @SpyBean | ||||||
|  |     private MessageListener messageListener; | ||||||
|  | 
 | ||||||
|  |     @SpyBean | ||||||
|  |     private MessageSender messageSender; | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void whenListening_thenReceivingCorrectMessage() throws JMSException { | ||||||
|  |         String queueName = "queue-1"; | ||||||
|  |         String messageText = "Test message"; | ||||||
|  | 
 | ||||||
|  |         embeddedBroker.pushMessage(queueName, messageText); | ||||||
|  |         assertEquals(1, embeddedBroker.getMessageCount(queueName)); | ||||||
|  | 
 | ||||||
|  |         ArgumentCaptor<TextMessage> messageCaptor = ArgumentCaptor.forClass(TextMessage.class); | ||||||
|  | 
 | ||||||
|  |         Mockito.verify(messageListener, Mockito.timeout(100)) | ||||||
|  |             .sampleJmsListenerMethod(messageCaptor.capture()); | ||||||
|  |          | ||||||
|  |         TextMessage receivedMessage = messageCaptor.getValue(); | ||||||
|  |         assertEquals(messageText, receivedMessage.getText()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void whenSendingMessage_thenCorrectQueueAndMessageText() throws JMSException { | ||||||
|  |         String queueName = "queue-2"; | ||||||
|  |         String messageText = "Test message"; | ||||||
|  | 
 | ||||||
|  |         messageSender.sendTextMessage(queueName, messageText); | ||||||
|  | 
 | ||||||
|  |         assertEquals(1, embeddedBroker.getMessageCount(queueName)); | ||||||
|  |         TextMessage sentMessage = embeddedBroker.peekTextMessage(queueName); | ||||||
|  |         assertEquals(messageText, sentMessage.getText()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Configuration | ||||||
|  |     @EnableJms | ||||||
|  |     static class TestConfiguration { | ||||||
|  |         @Bean | ||||||
|  |         public JmsListenerContainerFactory<?> jmsListenerContainerFactory() { | ||||||
|  |             DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory(); | ||||||
|  |             factory.setConnectionFactory(connectionFactory()); | ||||||
|  |             return factory; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         @Bean | ||||||
|  |         public ConnectionFactory connectionFactory() { | ||||||
|  |             return new ActiveMQConnectionFactory(embeddedBroker.getVmURL()); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         @Bean | ||||||
|  |         public JmsTemplate jmsTemplate() { | ||||||
|  |             return new JmsTemplate(connectionFactory()); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
| @ -0,0 +1,101 @@ | |||||||
|  | package com.baeldung.spring.jms.testing; | ||||||
|  | 
 | ||||||
|  | import static org.junit.jupiter.api.Assertions.assertEquals; | ||||||
|  | 
 | ||||||
|  | import javax.jms.ConnectionFactory; | ||||||
|  | import javax.jms.JMSException; | ||||||
|  | import javax.jms.Message; | ||||||
|  | import javax.jms.TextMessage; | ||||||
|  | 
 | ||||||
|  | import org.apache.activemq.ActiveMQConnectionFactory; | ||||||
|  | import org.assertj.core.api.Assertions; | ||||||
|  | import org.junit.ClassRule; | ||||||
|  | import org.junit.Test; | ||||||
|  | import org.junit.runner.RunWith; | ||||||
|  | import org.mockito.ArgumentCaptor; | ||||||
|  | import org.mockito.Mockito; | ||||||
|  | import org.springframework.beans.factory.annotation.Autowired; | ||||||
|  | import org.springframework.boot.test.mock.mockito.SpyBean; | ||||||
|  | import org.springframework.context.annotation.Bean; | ||||||
|  | import org.springframework.context.annotation.Configuration; | ||||||
|  | import org.springframework.jms.annotation.EnableJms; | ||||||
|  | import org.springframework.jms.config.DefaultJmsListenerContainerFactory; | ||||||
|  | import org.springframework.jms.config.JmsListenerContainerFactory; | ||||||
|  | import org.springframework.jms.core.JmsTemplate; | ||||||
|  | import org.springframework.test.context.ContextConfiguration; | ||||||
|  | import org.springframework.test.context.junit4.SpringRunner; | ||||||
|  | import org.testcontainers.containers.GenericContainer; | ||||||
|  | import org.testcontainers.utility.DockerImageName; | ||||||
|  | 
 | ||||||
|  | import com.baeldung.spring.jms.testing.TestContainersActiveMqIntegrationTest.TestConfiguration; | ||||||
|  | 
 | ||||||
|  | @RunWith(SpringRunner.class) | ||||||
|  | @ContextConfiguration(classes = { TestConfiguration.class, MessageSender.class }) | ||||||
|  | public class TestContainersActiveMqIntegrationTest { | ||||||
|  | 
 | ||||||
|  |     @ClassRule | ||||||
|  |     public static GenericContainer<?> activeMqContainer = new GenericContainer<>(DockerImageName.parse("rmohr/activemq:5.14.3")).withExposedPorts(61616); | ||||||
|  | 
 | ||||||
|  |     @SpyBean | ||||||
|  |     private MessageListener messageListener; | ||||||
|  | 
 | ||||||
|  |     @Autowired | ||||||
|  |     private MessageSender messageSender; | ||||||
|  | 
 | ||||||
|  |     @Autowired | ||||||
|  |     private JmsTemplate jmsTemplate; | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void whenListening_thenReceivingCorrectMessage() throws JMSException { | ||||||
|  |         String queueName = "queue-1"; | ||||||
|  |         String messageText = "Test message"; | ||||||
|  | 
 | ||||||
|  |         jmsTemplate.send(queueName, s -> s.createTextMessage(messageText)); | ||||||
|  | 
 | ||||||
|  |         ArgumentCaptor<TextMessage> messageCaptor = ArgumentCaptor.forClass(TextMessage.class); | ||||||
|  | 
 | ||||||
|  |         Mockito.verify(messageListener, Mockito.timeout(100)) | ||||||
|  |             .sampleJmsListenerMethod(messageCaptor.capture()); | ||||||
|  | 
 | ||||||
|  |         TextMessage receivedMessage = messageCaptor.getValue(); | ||||||
|  |         assertEquals(messageText, receivedMessage.getText()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void whenSendingMessage_thenCorrectQueueAndMessageText() throws JMSException { | ||||||
|  |         String queueName = "queue-2"; | ||||||
|  |         String messageText = "Test message"; | ||||||
|  | 
 | ||||||
|  |         messageSender.sendTextMessage(queueName, messageText); | ||||||
|  | 
 | ||||||
|  |         Message sentMessage = jmsTemplate.receive(queueName); | ||||||
|  |         Assertions.assertThat(sentMessage) | ||||||
|  |             .isInstanceOf(TextMessage.class); | ||||||
|  | 
 | ||||||
|  |         assertEquals(messageText, ((TextMessage) sentMessage).getText()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Configuration | ||||||
|  |     @EnableJms | ||||||
|  |     static class TestConfiguration { | ||||||
|  |         @Bean | ||||||
|  |         public JmsListenerContainerFactory<?> jmsListenerContainerFactory() { | ||||||
|  |             DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory(); | ||||||
|  |             factory.setConnectionFactory(connectionFactory()); | ||||||
|  |             return factory; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         @Bean | ||||||
|  |         public ConnectionFactory connectionFactory() { | ||||||
|  |             String brokerUrlFormat = "tcp://%s:%d"; | ||||||
|  |             String brokerUrl = String.format(brokerUrlFormat, activeMqContainer.getHost(), activeMqContainer.getFirstMappedPort()); | ||||||
|  |             return new ActiveMQConnectionFactory(brokerUrl); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         @Bean | ||||||
|  |         public JmsTemplate jmsTemplate() { | ||||||
|  |             return new JmsTemplate(connectionFactory()); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
| @ -12,7 +12,7 @@ | |||||||
|         <groupId>com.baeldung</groupId> |         <groupId>com.baeldung</groupId> | ||||||
|         <artifactId>parent-boot-2</artifactId> |         <artifactId>parent-boot-2</artifactId> | ||||||
|         <version>0.0.1-SNAPSHOT</version> |         <version>0.0.1-SNAPSHOT</version> | ||||||
|         <relativePath>../../parent-boot-2/pom.xml</relativePath> |         <relativePath>../../parent-boot-2</relativePath> | ||||||
|     </parent> |     </parent> | ||||||
| 
 | 
 | ||||||
|     <dependencies> |     <dependencies> | ||||||
|  | |||||||
							
								
								
									
										14
									
								
								testing-modules/mockito-2/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										14
									
								
								testing-modules/mockito-2/.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -1,14 +0,0 @@ | |||||||
| *.class |  | ||||||
| 
 |  | ||||||
| .settings |  | ||||||
| .project |  | ||||||
| 
 |  | ||||||
| #folders# |  | ||||||
| /target |  | ||||||
| /src/main/webapp/WEB-INF/classes |  | ||||||
| */META-INF/* |  | ||||||
| 
 |  | ||||||
| # Packaged files # |  | ||||||
| *.jar |  | ||||||
| *.war |  | ||||||
| *.ear |  | ||||||
| @ -1,10 +0,0 @@ | |||||||
| ### Relevant articles |  | ||||||
| 
 |  | ||||||
| - [Mockito’s Java 8 Features](https://www.baeldung.com/mockito-2-java-8) |  | ||||||
| - [Lazy Verification with Mockito 2](https://www.baeldung.com/mockito-2-lazy-verification) |  | ||||||
| - [Mockito Strict Stubbing and The UnnecessaryStubbingException](https://www.baeldung.com/mockito-unnecessary-stubbing-exception) |  | ||||||
| - [Mockito and Fluent APIs](https://www.baeldung.com/mockito-fluent-apis) |  | ||||||
| - [Mocking the ObjectMapper readValue() Method](https://www.baeldung.com/mockito-mock-jackson-read-value) |  | ||||||
| - [Introduction to Mockito’s AdditionalAnswers](https://www.baeldung.com/mockito-additionalanswers) |  | ||||||
| - [Difference Between when() and doXxx() Methods in Mockito](https://www.baeldung.com/java-mockito-when-vs-do) |  | ||||||
| - [Overview of Mockito MockSettings](https://www.baeldung.com/mockito-mocksettings) |  | ||||||
| @ -1,31 +0,0 @@ | |||||||
| <?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>mockito-2</artifactId> |  | ||||||
|     <version>0.0.1-SNAPSHOT</version> |  | ||||||
|     <name>mockito-2</name> |  | ||||||
|     <packaging>jar</packaging> |  | ||||||
| 
 |  | ||||||
|     <parent> |  | ||||||
|         <groupId>com.baeldung</groupId> |  | ||||||
|         <artifactId>testing-modules</artifactId> |  | ||||||
|         <version>1.0.0-SNAPSHOT</version> |  | ||||||
|     </parent> |  | ||||||
| 
 |  | ||||||
|     <dependencies> |  | ||||||
|         <dependency> |  | ||||||
|             <groupId>com.fasterxml.jackson.core</groupId> |  | ||||||
|             <artifactId>jackson-databind</artifactId> |  | ||||||
|             <version>${jackson.version}</version> |  | ||||||
|         </dependency> |  | ||||||
|         <dependency> |  | ||||||
|             <groupId>org.mockito</groupId> |  | ||||||
|             <artifactId>mockito-junit-jupiter</artifactId> |  | ||||||
|             <version>${mockito.version}</version> |  | ||||||
|             <scope>test</scope> |  | ||||||
|         </dependency> |  | ||||||
|     </dependencies> |  | ||||||
| 
 |  | ||||||
| </project> |  | ||||||
| @ -29,35 +29,16 @@ | |||||||
|             <artifactId>spring-context</artifactId> |             <artifactId>spring-context</artifactId> | ||||||
|             <version>${spring-framework.version}</version> |             <version>${spring-framework.version}</version> | ||||||
|         </dependency> |         </dependency> | ||||||
|         <dependency> |          | ||||||
|             <groupId>org.springframework.data</groupId> |  | ||||||
|             <artifactId>spring-data-jpa</artifactId> |  | ||||||
|             <version>${spring-data.version}</version> |  | ||||||
|         </dependency> |  | ||||||
|         <dependency> |  | ||||||
|             <groupId>org.eclipse.persistence</groupId> |  | ||||||
|             <artifactId>javax.persistence</artifactId> |  | ||||||
|             <version>${javax.persistence.version}</version> |  | ||||||
|         </dependency> |  | ||||||
|         <!-- utils --> |         <!-- utils --> | ||||||
|         <dependency> |         <dependency> | ||||||
|             <groupId>org.apache.commons</groupId> |             <groupId>org.apache.commons</groupId> | ||||||
|             <artifactId>commons-lang3</artifactId> |             <artifactId>commons-lang3</artifactId> | ||||||
|             <version>${commons-lang3.version}</version> |             <version>${commons-lang3.version}</version> | ||||||
|         </dependency> |         </dependency> | ||||||
|  |          | ||||||
|         <!-- test scoped --> |         <!-- test scoped --> | ||||||
|         <dependency> | 
 | ||||||
|             <groupId>org.springframework.boot</groupId> |  | ||||||
|             <artifactId>spring-boot-starter</artifactId> |  | ||||||
|             <version>${spring-boot.version}</version> |  | ||||||
|             <scope>test</scope> |  | ||||||
|         </dependency> |  | ||||||
|         <dependency> |  | ||||||
|             <groupId>org.springframework.boot</groupId> |  | ||||||
|             <artifactId>spring-boot-starter-test</artifactId> |  | ||||||
|             <version>${spring-boot.version}</version> |  | ||||||
|             <scope>test</scope> |  | ||||||
|         </dependency> |  | ||||||
|         <dependency> |         <dependency> | ||||||
|             <groupId>org.mockito</groupId> |             <groupId>org.mockito</groupId> | ||||||
|             <artifactId>mockito-junit-jupiter</artifactId> |             <artifactId>mockito-junit-jupiter</artifactId> | ||||||
| @ -77,12 +58,10 @@ | |||||||
|     </build> |     </build> | ||||||
| 
 | 
 | ||||||
|     <properties> |     <properties> | ||||||
|         <spring-boot.version>2.0.4.RELEASE</spring-boot.version> |         <spring-boot.version>2.6.4</spring-boot.version> | ||||||
|         <spring-framework.version>5.0.8.RELEASE</spring-framework.version> |         <spring-framework.version>5.3.20</spring-framework.version> | ||||||
|         <spring-data.version>2.0.9.RELEASE</spring-data.version> |  | ||||||
|         <!-- testing --> |         <!-- testing --> | ||||||
|         <powermock.version>2.0.2</powermock.version> |         <mockito.version>4.6.1</mockito.version>         | ||||||
|         <javax.persistence.version>2.1.1</javax.persistence.version> |  | ||||||
|     </properties> |     </properties> | ||||||
| 
 | 
 | ||||||
| </project> | </project> | ||||||
|  | |||||||
| @ -1,35 +0,0 @@ | |||||||
| package com.baeldung.mockito; |  | ||||||
| 
 |  | ||||||
| import org.junit.Test; |  | ||||||
| 
 |  | ||||||
| import static org.junit.Assert.assertNotEquals; |  | ||||||
| import static org.mockito.Mockito.mock; |  | ||||||
| import static org.mockito.Mockito.when; |  | ||||||
| 
 |  | ||||||
| public class MockFinals { |  | ||||||
| 
 |  | ||||||
|       @Test |  | ||||||
|       public void whenMockFinalClassMockWorks() { |  | ||||||
| 
 |  | ||||||
|         FinalList finalList = new FinalList(); |  | ||||||
| 
 |  | ||||||
|         FinalList mock = mock(FinalList.class); |  | ||||||
|         when(mock.size()).thenReturn(2); |  | ||||||
| 
 |  | ||||||
|         assertNotEquals(mock.size(), finalList.size()); |  | ||||||
| 
 |  | ||||||
|       } |  | ||||||
| 
 |  | ||||||
|     @Test |  | ||||||
|     public void whenMockFinalMethodMockWorks() { |  | ||||||
| 
 |  | ||||||
|       MyList myList = new MyList(); |  | ||||||
| 
 |  | ||||||
|       MyList mock = mock(MyList.class); |  | ||||||
|       when(mock.finalMethod()).thenReturn(1); |  | ||||||
| 
 |  | ||||||
|       assertNotEquals(mock.finalMethod(), myList.finalMethod()); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|   } |  | ||||||
| @ -1,16 +1,22 @@ | |||||||
| package com.baeldung.mockito; | package com.baeldung.mockito; | ||||||
| 
 | 
 | ||||||
| import org.junit.Before; | import static org.junit.Assert.assertEquals; | ||||||
| import org.junit.Test; |  | ||||||
| import org.mockito.*; |  | ||||||
| 
 | 
 | ||||||
| import java.util.ArrayList; | import java.util.ArrayList; | ||||||
| import java.util.List; | import java.util.List; | ||||||
| import java.util.Map; | import java.util.Map; | ||||||
| 
 | 
 | ||||||
| import static org.junit.Assert.assertEquals; | import org.junit.Test; | ||||||
|  | import org.junit.runner.RunWith; | ||||||
|  | import org.mockito.ArgumentCaptor; | ||||||
|  | import org.mockito.Captor; | ||||||
|  | import org.mockito.InjectMocks; | ||||||
|  | import org.mockito.Mock; | ||||||
|  | import org.mockito.Mockito; | ||||||
|  | import org.mockito.Spy; | ||||||
|  | import org.mockito.junit.MockitoJUnitRunner; | ||||||
| 
 | 
 | ||||||
| //@RunWith(MockitoJUnitRunner.class) | @RunWith(MockitoJUnitRunner.class) | ||||||
| public class MockitoAnnotationUnitTest { | public class MockitoAnnotationUnitTest { | ||||||
| 
 | 
 | ||||||
|     @Mock |     @Mock | ||||||
| @ -19,10 +25,13 @@ public class MockitoAnnotationUnitTest { | |||||||
|     @Spy |     @Spy | ||||||
|     private List<String> spiedList = new ArrayList<>(); |     private List<String> spiedList = new ArrayList<>(); | ||||||
| 
 | 
 | ||||||
|  |     // Use either @RunWith(MockitoJUnitRunner.class) or manually openMocks in the @Before method | ||||||
|  |     /* | ||||||
|     @Before |     @Before | ||||||
|     public void init() { |     public void init() { | ||||||
|         MockitoAnnotations.initMocks(this); |         MockitoAnnotations.openMocks(this); | ||||||
|     } |     } | ||||||
|  |     */ | ||||||
|      |      | ||||||
|     // tests |     // tests | ||||||
| 
 | 
 | ||||||
| @ -91,7 +100,7 @@ public class MockitoAnnotationUnitTest { | |||||||
|     ArgumentCaptor<String> argCaptor; |     ArgumentCaptor<String> argCaptor; | ||||||
| 
 | 
 | ||||||
|     @Test |     @Test | ||||||
|     public void whenUseCaptorAnnotation_thenTheSam() { |     public void whenUseCaptorAnnotation_thenTheSame() { | ||||||
|         mockedList.add("one"); |         mockedList.add("one"); | ||||||
|         Mockito.verify(mockedList).add(argCaptor.capture()); |         Mockito.verify(mockedList).add(argCaptor.capture()); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -11,7 +11,7 @@ import java.util.List; | |||||||
| import static org.assertj.core.api.Assertions.assertThat; | import static org.assertj.core.api.Assertions.assertThat; | ||||||
| import static org.mockito.Mockito.when; | import static org.mockito.Mockito.when; | ||||||
| 
 | 
 | ||||||
| public class MockitoInitWithMockitoJUnitRuleUnitTest { | public class MockitoAnnotationsInitWithMockitoJUnitRuleUnitTest { | ||||||
| 
 | 
 | ||||||
|     @Rule |     @Rule | ||||||
|     public MockitoRule initRule = MockitoJUnit.rule(); |     public MockitoRule initRule = MockitoJUnit.rule(); | ||||||
Some files were not shown because too many files have changed in this diff Show More
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user