Merge branch 'eugenp:master' into master
This commit is contained in:
commit
1bdb77da2b
|
@ -1,46 +1,50 @@
|
||||||
package com.baeldung.httpclient.cookies;
|
package com.baeldung.httpclient.cookies;
|
||||||
|
|
||||||
import org.apache.http.client.CookieStore;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
|
||||||
import org.apache.http.client.methods.HttpGet;
|
import org.apache.hc.client5.http.classic.methods.HttpGet;
|
||||||
import org.apache.http.client.protocol.HttpClientContext;
|
import org.apache.hc.client5.http.cookie.BasicCookieStore;
|
||||||
import org.apache.http.cookie.ClientCookie;
|
import org.apache.hc.client5.http.cookie.Cookie;
|
||||||
import org.apache.http.cookie.Cookie;
|
import org.apache.hc.client5.http.cookie.CookieStore;
|
||||||
import org.apache.http.impl.client.BasicCookieStore;
|
|
||||||
import org.apache.http.impl.client.CloseableHttpClient;
|
import org.apache.hc.client5.http.impl.classic.BasicHttpClientResponseHandler;
|
||||||
import org.apache.http.impl.client.HttpClients;
|
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
|
||||||
import org.apache.http.impl.cookie.BasicClientCookie;
|
import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
|
||||||
|
|
||||||
|
import org.apache.hc.client5.http.impl.cookie.BasicClientCookie;
|
||||||
|
import org.apache.hc.client5.http.protocol.HttpClientContext;
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
class HttpClientGettingCookieValueUnitTest {
|
||||||
|
|
||||||
|
|
||||||
public class HttpClientGettingCookieValueUnitTest {
|
|
||||||
private static Logger log = LoggerFactory.getLogger(HttpClientGettingCookieValueUnitTest.class);
|
private static Logger log = LoggerFactory.getLogger(HttpClientGettingCookieValueUnitTest.class);
|
||||||
|
|
||||||
private static final String SAMPLE_URL = "http://www.baeldung.com/";
|
private static final String SAMPLE_URL = "http://www.baeldung.com/";
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public final void whenSettingCustomCookieOnTheRequest_thenGettingTheSameCookieFromTheResponse() throws IOException {
|
void whenSettingCustomCookieOnTheRequest_thenGettingTheSameCookieFromTheResponse() throws IOException {
|
||||||
|
|
||||||
HttpClientContext context = HttpClientContext.create();
|
HttpClientContext context = HttpClientContext.create();
|
||||||
context.setAttribute(HttpClientContext.COOKIE_STORE, createCustomCookieStore());
|
context.setAttribute(HttpClientContext.COOKIE_STORE, createCustomCookieStore());
|
||||||
|
|
||||||
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
|
final HttpGet request = new HttpGet(SAMPLE_URL);
|
||||||
try (CloseableHttpResponse response = httpClient.execute(new HttpGet(SAMPLE_URL), context)) {
|
|
||||||
CookieStore cookieStore = context.getCookieStore();
|
|
||||||
Cookie customCookie = cookieStore.getCookies()
|
|
||||||
.stream()
|
|
||||||
.peek(cookie -> log.info("cookie name:{}", cookie.getName()))
|
|
||||||
.filter(cookie -> "custom_cookie".equals(cookie.getName()))
|
|
||||||
.findFirst()
|
|
||||||
.orElseThrow(IllegalStateException::new);
|
|
||||||
|
|
||||||
assertEquals("test_value", customCookie.getValue());
|
try (CloseableHttpClient client = HttpClientBuilder.create()
|
||||||
}
|
.build()) {
|
||||||
|
client.execute(request, context, new BasicHttpClientResponseHandler());
|
||||||
|
CookieStore cookieStore = context.getCookieStore();
|
||||||
|
Cookie customCookie = cookieStore.getCookies()
|
||||||
|
.stream()
|
||||||
|
.peek(cookie -> log.info("cookie name:{}", cookie.getName()))
|
||||||
|
.filter(cookie -> "custom_cookie".equals(cookie.getName()))
|
||||||
|
.findFirst()
|
||||||
|
.orElseThrow(IllegalStateException::new);
|
||||||
|
|
||||||
|
assertEquals("test_value", customCookie.getValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,7 +52,7 @@ public class HttpClientGettingCookieValueUnitTest {
|
||||||
BasicCookieStore cookieStore = new BasicCookieStore();
|
BasicCookieStore cookieStore = new BasicCookieStore();
|
||||||
BasicClientCookie cookie = new BasicClientCookie("custom_cookie", "test_value");
|
BasicClientCookie cookie = new BasicClientCookie("custom_cookie", "test_value");
|
||||||
cookie.setDomain("baeldung.com");
|
cookie.setDomain("baeldung.com");
|
||||||
cookie.setAttribute(ClientCookie.DOMAIN_ATTR, "true");
|
cookie.setAttribute("domain", "true");
|
||||||
cookie.setPath("/");
|
cookie.setPath("/");
|
||||||
cookieStore.addCookie(cookie);
|
cookieStore.addCookie(cookie);
|
||||||
return cookieStore;
|
return cookieStore;
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
## Relevant Articles
|
||||||
|
- [Record Patterns in Java 19](https://www.baeldung.com/java-19-record-patterns)
|
|
@ -0,0 +1,82 @@
|
||||||
|
package com.baeldung.monad;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
class MonadBaseExample {
|
||||||
|
|
||||||
|
public double multiplyBy2(double n) {
|
||||||
|
return n * 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double divideBy2(double n) {
|
||||||
|
return n / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double add3(double n) {
|
||||||
|
return n + 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double subtract1(double n) {
|
||||||
|
return n - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class MonadSample1 extends MonadBaseExample {
|
||||||
|
|
||||||
|
public double apply(double n) {
|
||||||
|
return subtract1(add3(divideBy2(multiplyBy2(multiplyBy2(2)))));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MonadSample2 extends MonadBaseExample {
|
||||||
|
public double apply(double n) {
|
||||||
|
double n1 = multiplyBy2(n);
|
||||||
|
double n2 = multiplyBy2(n1);
|
||||||
|
double n3 = divideBy2(n2);
|
||||||
|
double n4 = add3(n3);
|
||||||
|
return subtract1(n4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MonadSample3 extends MonadBaseExample {
|
||||||
|
|
||||||
|
public double apply(double n) {
|
||||||
|
return Optional.of(n)
|
||||||
|
.flatMap(value -> Optional.of(multiplyBy2(value)))
|
||||||
|
.flatMap(value -> Optional.of(multiplyBy2(value)))
|
||||||
|
.flatMap(value -> Optional.of(divideBy2(value)))
|
||||||
|
.flatMap(value -> Optional.of(add3(value)))
|
||||||
|
.flatMap(value -> Optional.of(subtract1(value)))
|
||||||
|
.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class MonadSample4 extends MonadBaseExample {
|
||||||
|
public boolean leftIdentity() {
|
||||||
|
Function<Integer, Optional<Integer>> mapping = value -> Optional.of(value + 1);
|
||||||
|
return Optional.of(3).flatMap(mapping).equals(mapping.apply(3));
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean rightIdentity() {
|
||||||
|
return Optional.of(3).flatMap(Optional::of).equals(Optional.of(3));
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean associativity() {
|
||||||
|
Function<Integer, Optional<Integer>> mapping = value -> Optional.of(value + 1);
|
||||||
|
Optional<Integer> leftSide = Optional.of(3).flatMap(mapping).flatMap(Optional::of);
|
||||||
|
Optional<Integer> rightSide = Optional.of(3).flatMap(v -> mapping.apply(v).flatMap(Optional::of));
|
||||||
|
return leftSide.equals(rightSide);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class MonadSample5 extends MonadBaseExample {
|
||||||
|
public boolean fail() {
|
||||||
|
Function<Integer, Optional<Integer>> mapping = value -> Optional.of(value == null ? -1 : value + 1);
|
||||||
|
return Optional.ofNullable((Integer) null).flatMap(mapping).equals(mapping.apply(null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
package com.baeldung.monad;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class MonadSampleUnitTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenNotUsingMonad_shouldBeOk() {
|
||||||
|
MonadSample1 test = new MonadSample1();
|
||||||
|
Assert.assertEquals(6.0, test.apply(2), 0.000);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenNotUsingMonadButUsingTempVars_shouldBeOk() {
|
||||||
|
MonadSample2 test = new MonadSample2();
|
||||||
|
Assert.assertEquals(6.0, test.apply(2), 0.000);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenUsingMonad_shouldBeOk() {
|
||||||
|
MonadSample3 test = new MonadSample3();
|
||||||
|
Assert.assertEquals(6.0, test.apply(2), 0.000);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenTestingMonadProperties_shouldBeOk() {
|
||||||
|
MonadSample4 test = new MonadSample4();
|
||||||
|
Assert.assertEquals(true, test.leftIdentity());
|
||||||
|
Assert.assertEquals(true, test.rightIdentity());
|
||||||
|
Assert.assertEquals(true, test.associativity());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenBreakingMonadProperties_shouldBeFalse() {
|
||||||
|
MonadSample5 test = new MonadSample5();
|
||||||
|
Assert.assertEquals(false, test.fail());
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,3 +6,4 @@ This module contains articles about arrays conversion in Java
|
||||||
- [Convert a Float to a Byte Array in Java](https://www.baeldung.com/java-convert-float-to-byte-array)
|
- [Convert a Float to a Byte Array in Java](https://www.baeldung.com/java-convert-float-to-byte-array)
|
||||||
- [Converting Between Stream and Array in Java](https://www.baeldung.com/java-stream-to-array)
|
- [Converting Between Stream and Array in Java](https://www.baeldung.com/java-stream-to-array)
|
||||||
- [Convert a Byte Array to a Numeric Representation in Java](https://www.baeldung.com/java-byte-array-to-number)
|
- [Convert a Byte Array to a Numeric Representation in Java](https://www.baeldung.com/java-byte-array-to-number)
|
||||||
|
- [Converting a String Array Into an int Array in Java](https://www.baeldung.com/java-convert-string-array-to-int-array)
|
||||||
|
|
|
@ -13,3 +13,4 @@
|
||||||
- [Getting the Size of an Iterable in Java](https://www.baeldung.com/java-iterable-size)
|
- [Getting the Size of an Iterable in Java](https://www.baeldung.com/java-iterable-size)
|
||||||
- [Java Null-Safe Streams from Collections](https://www.baeldung.com/java-null-safe-streams-from-collections)
|
- [Java Null-Safe Streams from Collections](https://www.baeldung.com/java-null-safe-streams-from-collections)
|
||||||
- [Differences Between Iterator and Iterable and How to Use Them?](https://www.baeldung.com/java-iterator-vs-iterable)
|
- [Differences Between Iterator and Iterable and How to Use Them?](https://www.baeldung.com/java-iterator-vs-iterable)
|
||||||
|
- More articles: [[<-- prev]](/core-java-modules/core-java-collections-1) [[next -->]](/core-java-modules/core-java-collections-3)
|
|
@ -7,7 +7,6 @@
|
||||||
- [ArrayList vs. LinkedList vs. HashMap in Java](https://www.baeldung.com/java-arraylist-vs-linkedlist-vs-hashmap)
|
- [ArrayList vs. LinkedList vs. HashMap in Java](https://www.baeldung.com/java-arraylist-vs-linkedlist-vs-hashmap)
|
||||||
- [Java Deque vs. Stack](https://www.baeldung.com/java-deque-vs-stack)
|
- [Java Deque vs. Stack](https://www.baeldung.com/java-deque-vs-stack)
|
||||||
- [Collection.toArray(new T[0]) or .toArray(new T[size])](https://www.baeldung.com/java-collection-toarray-methods)
|
- [Collection.toArray(new T[0]) or .toArray(new T[size])](https://www.baeldung.com/java-collection-toarray-methods)
|
||||||
- [Create an Empty Map in Java](https://www.baeldung.com/java-create-empty-map)
|
|
||||||
- [Sorting Objects in a List by Date](https://www.baeldung.com/java-sort-list-by-date)
|
- [Sorting Objects in a List by Date](https://www.baeldung.com/java-sort-list-by-date)
|
||||||
- [Fixed Size Queue Implementations in Java](https://www.baeldung.com/java-fixed-size-queue)
|
- [Fixed Size Queue Implementations in Java](https://www.baeldung.com/java-fixed-size-queue)
|
||||||
- [Difference Between Java Enumeration and Iterator](https://www.baeldung.com/java-enumeration-vs-iterator)
|
- [Difference Between Java Enumeration and Iterator](https://www.baeldung.com/java-enumeration-vs-iterator)
|
||||||
|
@ -15,4 +14,4 @@
|
||||||
- [Guide to Java PriorityQueue](https://www.baeldung.com/java-priorityqueue)
|
- [Guide to Java PriorityQueue](https://www.baeldung.com/java-priorityqueue)
|
||||||
- [Java Generics PECS – Producer Extends Consumer Super](https://www.baeldung.com/java-generics-pecs)
|
- [Java Generics PECS – Producer Extends Consumer Super](https://www.baeldung.com/java-generics-pecs)
|
||||||
- [Reversing a Stack in Java](https://www.baeldung.com/java-reversing-a-stack)
|
- [Reversing a Stack in Java](https://www.baeldung.com/java-reversing-a-stack)
|
||||||
- [Sorting a HashSet in Java](https://www.baeldung.com/java-sort-hashset)
|
- More articles: [[<-- prev]](/core-java-modules/core-java-collections-3)
|
|
@ -25,6 +25,12 @@
|
||||||
<artifactId>commons-lang3</artifactId>
|
<artifactId>commons-lang3</artifactId>
|
||||||
<version>${commons-lang3.version}</version>
|
<version>${commons-lang3.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.junit.platform</groupId>
|
||||||
|
<artifactId>junit-platform-runner</artifactId>
|
||||||
|
<version>${junit-platform.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
|
|
|
@ -2,9 +2,7 @@ package com.baeldung.collections.comparation;
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
|
@ -2,10 +2,8 @@ package com.baeldung.collections.comparation;
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import org.apache.commons.lang.time.DateUtils;
|
import org.apache.commons.lang.time.DateUtils;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
public class EmployeeSortingByDateUnitTest {
|
public class EmployeeSortingByDateUnitTest {
|
||||||
|
|
||||||
|
|
|
@ -5,8 +5,9 @@ import java.util.Comparator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
public class ComparatorsUnitTest {
|
public class ComparatorsUnitTest {
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
package com.baeldung.stackreversal;
|
package com.baeldung.stackreversal;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
import com.baeldung.collections.sorting.Employee;
|
import com.baeldung.collections.sorting.Employee;
|
||||||
import com.baeldung.collections.stackreversal.ReverseStackUsingQueue;
|
import com.baeldung.collections.stackreversal.ReverseStackUsingQueue;
|
||||||
import com.baeldung.collections.stackreversal.ReverseStackUsingRecursion;
|
import com.baeldung.collections.stackreversal.ReverseStackUsingRecursion;
|
||||||
import org.junit.Assert;
|
|
||||||
import org.junit.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
@ -15,7 +17,7 @@ public class StackReversalUnitTest {
|
||||||
ReverseStackUsingQueue reverseStack = new ReverseStackUsingQueue();
|
ReverseStackUsingQueue reverseStack = new ReverseStackUsingQueue();
|
||||||
Stack<Integer> originalStack = generateStackFromGivenList(Arrays.stream(new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}).boxed().collect(Collectors.toList()), new Stack<Integer>());
|
Stack<Integer> originalStack = generateStackFromGivenList(Arrays.stream(new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}).boxed().collect(Collectors.toList()), new Stack<Integer>());
|
||||||
Stack<Integer> reverseList = generateStackFromGivenList(Arrays.stream(new int[]{10, 9, 8, 7, 6, 5, 4, 3, 2, 1}).boxed().collect(Collectors.toList()), new Stack<Integer>());
|
Stack<Integer> reverseList = generateStackFromGivenList(Arrays.stream(new int[]{10, 9, 8, 7, 6, 5, 4, 3, 2, 1}).boxed().collect(Collectors.toList()), new Stack<Integer>());
|
||||||
Assert.assertEquals(reverseStack.reverseIntegerStack(originalStack), reverseList);
|
assertEquals(reverseStack.reverseIntegerStack(originalStack), reverseList);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -26,7 +28,7 @@ public class StackReversalUnitTest {
|
||||||
Collections.reverse(listOfWordsReversed);
|
Collections.reverse(listOfWordsReversed);
|
||||||
Stack<String> originalStack = generateStackFromGivenList(listOfWords, new Stack<String>());
|
Stack<String> originalStack = generateStackFromGivenList(listOfWords, new Stack<String>());
|
||||||
Stack<String> reversedStack = generateStackFromGivenList(listOfWordsReversed, new Stack<String>());
|
Stack<String> reversedStack = generateStackFromGivenList(listOfWordsReversed, new Stack<String>());
|
||||||
Assert.assertEquals(stackReversal.reverseStringStack(originalStack), reversedStack);
|
assertEquals(stackReversal.reverseStringStack(originalStack), reversedStack);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -43,7 +45,7 @@ public class StackReversalUnitTest {
|
||||||
Collections.reverse(employeeReversed);
|
Collections.reverse(employeeReversed);
|
||||||
Stack<Employee> originalStack = generateStackFromGivenList(employeeList, new Stack<Employee>());
|
Stack<Employee> originalStack = generateStackFromGivenList(employeeList, new Stack<Employee>());
|
||||||
Stack<Employee> reverseStack = generateStackFromGivenList(employeeReversed, new Stack<Employee>());
|
Stack<Employee> reverseStack = generateStackFromGivenList(employeeReversed, new Stack<Employee>());
|
||||||
Assert.assertEquals(stackReversal.reverseEmployeeStack(originalStack), reverseStack);
|
assertEquals(stackReversal.reverseEmployeeStack(originalStack), reverseStack);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -51,7 +53,7 @@ public class StackReversalUnitTest {
|
||||||
ReverseStackUsingRecursion reverseStack = new ReverseStackUsingRecursion();
|
ReverseStackUsingRecursion reverseStack = new ReverseStackUsingRecursion();
|
||||||
Stack<Integer> originalStack = generateStackFromGivenList(Arrays.stream(new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}).boxed().collect(Collectors.toList()), new Stack<Integer>());
|
Stack<Integer> originalStack = generateStackFromGivenList(Arrays.stream(new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}).boxed().collect(Collectors.toList()), new Stack<Integer>());
|
||||||
Stack<Integer> reversedStack = generateStackFromGivenList(Arrays.stream(new int[]{10, 9, 8, 7, 6, 5, 4, 3, 2, 1}).boxed().collect(Collectors.toList()), new Stack<Integer>());
|
Stack<Integer> reversedStack = generateStackFromGivenList(Arrays.stream(new int[]{10, 9, 8, 7, 6, 5, 4, 3, 2, 1}).boxed().collect(Collectors.toList()), new Stack<Integer>());
|
||||||
Assert.assertEquals(reverseStack.reverseIntegerStack(originalStack), reversedStack);
|
assertEquals(reverseStack.reverseIntegerStack(originalStack), reversedStack);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Stack generateStackFromGivenList(List elements, Stack stack){
|
private Stack generateStackFromGivenList(List elements, Stack stack){
|
||||||
|
|
|
@ -5,6 +5,33 @@
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<artifactId>core-java-collections-array-list</artifactId>
|
<artifactId>core-java-collections-array-list</artifactId>
|
||||||
<version>0.1.0-SNAPSHOT</version>
|
<version>0.1.0-SNAPSHOT</version>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<source>${maven-compiler-plugin.source}</source>
|
||||||
|
<target>${maven-compiler-plugin.target}</target>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<version>${surefire.plugin.version}</version>
|
||||||
|
<configuration>
|
||||||
|
<argLine>
|
||||||
|
--add-opens java.base/java.util=ALL-UNNAMED
|
||||||
|
</argLine>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
<properties>
|
||||||
|
<maven-compiler-plugin.source>16</maven-compiler-plugin.source>
|
||||||
|
<maven-compiler-plugin.target>16</maven-compiler-plugin.target>
|
||||||
|
<surefire.plugin.version>3.0.0-M3</surefire.plugin.version>
|
||||||
|
</properties>
|
||||||
<name>core-java-collections-array-list</name>
|
<name>core-java-collections-array-list</name>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
@ -20,6 +47,12 @@
|
||||||
<artifactId>commons-collections4</artifactId>
|
<artifactId>commons-collections4</artifactId>
|
||||||
<version>${commons-collections4.version}</version>
|
<version>${commons-collections4.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.guava</groupId>
|
||||||
|
<artifactId>guava</artifactId>
|
||||||
|
<version>31.1-jre</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
</project>
|
</project>
|
|
@ -0,0 +1,14 @@
|
||||||
|
package com.baeldung.list.ignorecase;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class IgnoreCaseSearchUtil {
|
||||||
|
public static boolean ignoreCaseContains(List<String> theList, String searchStr) {
|
||||||
|
for (String s : theList) {
|
||||||
|
if (searchStr.equalsIgnoreCase(s)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
package com.baeldung.list.ignorecase;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
public class IgnoreCaseStringList extends ArrayList<String> {
|
||||||
|
|
||||||
|
public IgnoreCaseStringList() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public IgnoreCaseStringList(Collection<? extends String> c) {
|
||||||
|
super(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean contains(Object o) {
|
||||||
|
String searchStr = (String) o;
|
||||||
|
// Using Stream API:
|
||||||
|
// return this.stream().anyMatch(searchStr::equalsIgnoreCase);
|
||||||
|
for (String s : this) {
|
||||||
|
if (searchStr.equalsIgnoreCase(s)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
package com.baeldung.listofobjectstolistofstring;
|
||||||
|
|
||||||
|
public class Node {
|
||||||
|
|
||||||
|
private final int x;
|
||||||
|
private final int y;
|
||||||
|
|
||||||
|
public Node(int x, int y) {
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Node (" + "x=" + x + ", y=" + y + ')';
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
package com.baeldung.listofobjectstolistofstring;
|
||||||
|
|
||||||
|
public class User {
|
||||||
|
private final String fullName;
|
||||||
|
|
||||||
|
public User(String fullName) {
|
||||||
|
this.fullName = fullName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "User (" + "full name='" + fullName + ')';
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
package com.baeldung.triple;
|
||||||
|
|
||||||
|
public class Triple<L, M, R> {
|
||||||
|
|
||||||
|
private final L left;
|
||||||
|
private final M middle;
|
||||||
|
private final R right;
|
||||||
|
|
||||||
|
public Triple(L left, M middle, R right) {
|
||||||
|
this.left = left;
|
||||||
|
this.middle = middle;
|
||||||
|
this.right = right;
|
||||||
|
}
|
||||||
|
|
||||||
|
public L getLeft() {
|
||||||
|
return left;
|
||||||
|
}
|
||||||
|
|
||||||
|
public M getMiddle() {
|
||||||
|
return middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
public R getRight() {
|
||||||
|
return right;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
package com.baeldung.list.ignorecase;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
|
public class IgnoreCaseContainsUnitTest {
|
||||||
|
private static final List<String> LANGUAGES = Arrays.asList("Java", "Python", "Kotlin", "Ruby", "Javascript", "Go");
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenStringList_whenCallTheStandardContains_shouldReturnFalse() {
|
||||||
|
String searchStr = "jAvA";
|
||||||
|
boolean result = LANGUAGES.contains(searchStr);
|
||||||
|
assertFalse(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenStringList_whenSearchIgnoreCaseUsingStreamAPI_shouldReturnTrue() {
|
||||||
|
String searchStr = "koTliN";
|
||||||
|
boolean result = LANGUAGES.stream().anyMatch(searchStr::equalsIgnoreCase);
|
||||||
|
assertTrue(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenStringList_whenUsingUtilClass_shouldReturnTrue() {
|
||||||
|
String searchStr = "ruBY";
|
||||||
|
boolean result = IgnoreCaseSearchUtil.ignoreCaseContains(LANGUAGES, searchStr);
|
||||||
|
assertTrue(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenStringList_whenUsingIgnoreCaseStringList_shouldReturnTrue() {
|
||||||
|
String searchStr = "pYtHoN";
|
||||||
|
List<String> ignoreCaseList = new IgnoreCaseStringList(LANGUAGES);
|
||||||
|
boolean result = ignoreCaseList.contains(searchStr);
|
||||||
|
assertTrue(result);
|
||||||
|
|
||||||
|
boolean resultContainAll = ignoreCaseList.containsAll(Arrays.asList("pYtHon", "jAvA", "koTliN", "ruBY"));
|
||||||
|
assertTrue(resultContainAll);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,92 @@
|
||||||
|
package com.baeldung.listofobjectstolistofstring;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class ConvertObjectListToStringListUnitTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenObjectList_whenForEachUsedToConvert_thenReturnSuccess() {
|
||||||
|
List<String> outputList = new ArrayList<>(objectListWithNull().size());
|
||||||
|
for (Object obj : objectListWithNull()) {
|
||||||
|
outputList.add(Objects.toString(obj, null));
|
||||||
|
}
|
||||||
|
Assert.assertEquals(expectedStringListWithNull(), outputList);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenObjectList_whenUsingStreamsToConvert_thenReturnSuccess() {
|
||||||
|
List<String> outputList;
|
||||||
|
outputList = objectListWithNull().stream()
|
||||||
|
.map((obj) -> Objects.toString(obj, null))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
Assert.assertEquals(expectedStringListWithNull(), outputList);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenObjectList_whenUsingStreamsUnmodifiableListToConvert_thenReturnSuccess() {
|
||||||
|
List<String> outputList;
|
||||||
|
outputList = objectListWithNull().stream()
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.map((obj) -> Objects.toString(obj, null))
|
||||||
|
.collect(Collectors.toUnmodifiableList());
|
||||||
|
Assert.assertEquals(expectedStringListWithoutNull(), outputList);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenObjectList_whenUsingGuavaTransform_thenReturnSuccess() {
|
||||||
|
List<String> outputList;
|
||||||
|
outputList = Lists.transform(objectListWithNull(), obj -> Objects.toString(obj, null));
|
||||||
|
Assert.assertEquals(expectedStringListWithNull(), outputList);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenObjectListWithNoNull_whenUsingToList_thenReturnSuccess() {
|
||||||
|
List<String> outputList;
|
||||||
|
outputList = objectListWithoutNull().stream()
|
||||||
|
.map((obj) -> Objects.toString(obj, null))
|
||||||
|
.toList();
|
||||||
|
Assert.assertEquals(expectedStringListWithoutNull(), outputList);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<String> expectedStringListWithNull() {
|
||||||
|
List<String> listOfStrings = new ArrayList<>();
|
||||||
|
listOfStrings.add("1");
|
||||||
|
listOfStrings.add("true");
|
||||||
|
listOfStrings.add("hello");
|
||||||
|
listOfStrings.add(Double.toString(273773.98));
|
||||||
|
listOfStrings.add(null);
|
||||||
|
listOfStrings.add(new Node(2, 4).toString());
|
||||||
|
listOfStrings.add(new User("John Doe").toString());
|
||||||
|
return listOfStrings;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Object> objectListWithNull() {
|
||||||
|
List<Object> listOfStrings = new ArrayList<>();
|
||||||
|
listOfStrings.add(1);
|
||||||
|
listOfStrings.add(true);
|
||||||
|
listOfStrings.add("hello");
|
||||||
|
listOfStrings.add(Double.valueOf(273773.98));
|
||||||
|
listOfStrings.add(null);
|
||||||
|
listOfStrings.add(new Node(2, 4));
|
||||||
|
listOfStrings.add(new User("John Doe"));
|
||||||
|
return listOfStrings;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<String> expectedStringListWithoutNull() {
|
||||||
|
return List.of("1", "true", "hello", Double.toString(273773.98), new Node(2, 4).toString(), new User("John Doe").toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Object> objectListWithoutNull() {
|
||||||
|
return List.of(1, true, "hello", Double.valueOf(273773.98), new Node(2, 4), new User("John Doe"));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,105 @@
|
||||||
|
package com.baeldung.triple;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
public class TripleInListUnitTest {
|
||||||
|
|
||||||
|
enum OP {
|
||||||
|
PLUS("+"), MINUS("-"), MULTIPLY("x");
|
||||||
|
final String opSign;
|
||||||
|
|
||||||
|
OP(String x) {
|
||||||
|
this.opSign = x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String createQuestion(Long num1, OP operator, Long num2) {
|
||||||
|
long result;
|
||||||
|
switch (operator) {
|
||||||
|
case PLUS:
|
||||||
|
result = num1 + num2;
|
||||||
|
break;
|
||||||
|
case MINUS:
|
||||||
|
result = num1 - num2;
|
||||||
|
break;
|
||||||
|
case MULTIPLY:
|
||||||
|
result = num1 * num2;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException("Unknown operator");
|
||||||
|
}
|
||||||
|
return String.format("%d %s %d = ? ( answer: %d )", num1, operator.opSign, num2, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final List<String> EXPECTED_QUESTIONS = Arrays.asList(
|
||||||
|
"100 - 42 = ? ( answer: 58 )",
|
||||||
|
"100 + 42 = ? ( answer: 142 )",
|
||||||
|
"100 x 42 = ? ( answer: 4200 )");
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenTripleValues_whenStoreAsList_thenTypeIsNotSafe() {
|
||||||
|
|
||||||
|
List myTriple1 = new ArrayList(3);
|
||||||
|
myTriple1.add(100L);
|
||||||
|
myTriple1.add(OP.MINUS);
|
||||||
|
myTriple1.add(42L);
|
||||||
|
|
||||||
|
List myTriple2 = new ArrayList(3);
|
||||||
|
myTriple2.add(100L);
|
||||||
|
myTriple2.add(OP.PLUS);
|
||||||
|
myTriple2.add(42L);
|
||||||
|
|
||||||
|
List myTriple3 = new ArrayList(3);
|
||||||
|
myTriple3.add(100L);
|
||||||
|
myTriple3.add(OP.MULTIPLY);
|
||||||
|
myTriple3.add(42L);
|
||||||
|
|
||||||
|
List<List> listOfTriples = new ArrayList<>(Arrays.asList(myTriple1, myTriple2, myTriple3));
|
||||||
|
|
||||||
|
List oopsTriple = new ArrayList(3);
|
||||||
|
oopsTriple.add("Oops");
|
||||||
|
oopsTriple.add(911L);
|
||||||
|
oopsTriple.add("The type is wrong");
|
||||||
|
|
||||||
|
listOfTriples.add(oopsTriple);
|
||||||
|
assertEquals(4, listOfTriples.size());
|
||||||
|
|
||||||
|
List<String> questions = listOfTriples.stream()
|
||||||
|
.filter(
|
||||||
|
triple -> triple.size() == 3
|
||||||
|
&& triple.get(0) instanceof Long
|
||||||
|
&& triple.get(1) instanceof OP
|
||||||
|
&& triple.get(2) instanceof Long
|
||||||
|
).map(triple -> {
|
||||||
|
Long left = (Long) triple.get(0);
|
||||||
|
OP op = (OP) triple.get(1);
|
||||||
|
Long right = (Long) triple.get(2);
|
||||||
|
return createQuestion(left, op, right);
|
||||||
|
}).collect(Collectors.toList());
|
||||||
|
|
||||||
|
assertEquals(EXPECTED_QUESTIONS, questions);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenTripleValues_whenUsingTheTripleClass_thenTypeIsSafeAndNeat() {
|
||||||
|
Triple<Long, OP, Long> triple1 = new Triple<>(100L, OP.MINUS, 42L);
|
||||||
|
Triple<Long, OP, Long> triple2 = new Triple<>(100L, OP.PLUS, 42L);
|
||||||
|
Triple<Long, OP, Long> triple3 = new Triple<>(100L, OP.MULTIPLY, 42L);
|
||||||
|
Triple<String, Long, String> tripleOops = new Triple<>("Oops", 911L, "The type is wrong");
|
||||||
|
|
||||||
|
List<Triple<Long, OP, Long>> listOfTriples = new ArrayList<>(Arrays.asList(triple1, triple2, triple3));
|
||||||
|
// listOfTriples.add(tripleOops); // Compiler error: "java: incompatible types ... "
|
||||||
|
|
||||||
|
List<String> questions = listOfTriples.stream()
|
||||||
|
.map(triple -> createQuestion(triple.getLeft(), triple.getMiddle(), triple.getRight()))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
assertEquals(EXPECTED_QUESTIONS, questions);
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,4 +12,5 @@ This module contains articles about Map data structures in Java.
|
||||||
- [Immutable Map Implementations in Java](https://www.baeldung.com/java-immutable-maps)
|
- [Immutable Map Implementations in Java](https://www.baeldung.com/java-immutable-maps)
|
||||||
- [Guide to Apache Commons MultiValuedMap](https://www.baeldung.com/apache-commons-multi-valued-map)
|
- [Guide to Apache Commons MultiValuedMap](https://www.baeldung.com/apache-commons-multi-valued-map)
|
||||||
- [The Java HashMap Under the Hood](https://www.baeldung.com/java-hashmap-advanced)
|
- [The Java HashMap Under the Hood](https://www.baeldung.com/java-hashmap-advanced)
|
||||||
|
- [Create an Empty Map in Java](https://www.baeldung.com/java-create-empty-map)
|
||||||
- More articles: [[next -->]](/core-java-modules/core-java-collections-maps-2)
|
- More articles: [[next -->]](/core-java-modules/core-java-collections-maps-2)
|
||||||
|
|
|
@ -20,6 +20,12 @@
|
||||||
<artifactId>commons-collections4</artifactId>
|
<artifactId>commons-collections4</artifactId>
|
||||||
<version>${commons-collections4.version}</version>
|
<version>${commons-collections4.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.junit.platform</groupId>
|
||||||
|
<artifactId>junit-platform-runner</artifactId>
|
||||||
|
<version>${junit-platform.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
</project>
|
</project>
|
|
@ -1,7 +1,5 @@
|
||||||
package com.baeldung.maps.initialize;
|
package com.baeldung.map;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
|
||||||
import com.google.common.collect.Maps;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
|
@ -10,6 +8,9 @@ import java.util.NavigableMap;
|
||||||
import java.util.SortedMap;
|
import java.util.SortedMap;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
|
|
||||||
public class EmptyMapInitializer {
|
public class EmptyMapInitializer {
|
||||||
|
|
||||||
public static Map<String, String> articleMap;
|
public static Map<String, String> articleMap;
|
|
@ -1,11 +1,12 @@
|
||||||
package com.baeldung.maps.initialize;
|
package com.baeldung.map;
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
public class EmptyMapInitializerUnitTest {
|
public class EmptyMapInitializerUnitTest {
|
||||||
|
|
||||||
@Test(expected=UnsupportedOperationException.class)
|
@Test(expected=UnsupportedOperationException.class)
|
|
@ -2,3 +2,5 @@
|
||||||
|
|
||||||
- [Using Streams to Collect Into a TreeSet](https://www.baeldung.com/java-stream-collect-into-treeset)
|
- [Using Streams to Collect Into a TreeSet](https://www.baeldung.com/java-stream-collect-into-treeset)
|
||||||
- [A Guide to LinkedHashSet in Java](https://www.baeldung.com/java-linkedhashset)
|
- [A Guide to LinkedHashSet in Java](https://www.baeldung.com/java-linkedhashset)
|
||||||
|
- [Sorting a HashSet in Java](https://www.baeldung.com/java-sort-hashset)
|
||||||
|
- More articles: [[<-- prev]](/core-java-modules/core-java-collections-set)
|
|
@ -15,6 +15,12 @@
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.junit.platform</groupId>
|
||||||
|
<artifactId>junit-platform-runner</artifactId>
|
||||||
|
<version>${junit-platform.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package com.baeldung.collections.sorting;
|
package com.baeldung.hashset.sorting;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
|
@ -13,5 +13,6 @@ This module contains articles about core Java input and output (IO)
|
||||||
- [Generate the MD5 Checksum for a File in Java](https://www.baeldung.com/java-md5-checksum-file)
|
- [Generate the MD5 Checksum for a File in Java](https://www.baeldung.com/java-md5-checksum-file)
|
||||||
- [Getting the Filename From a String Containing an Absolute File Path](https://www.baeldung.com/java-filename-full-path)
|
- [Getting the Filename From a String Containing an Absolute File Path](https://www.baeldung.com/java-filename-full-path)
|
||||||
- [Mocking Java InputStream Object](https://www.baeldung.com/java-mocking-inputstream)
|
- [Mocking Java InputStream Object](https://www.baeldung.com/java-mocking-inputstream)
|
||||||
|
- [PrintStream vs PrintWriter in Java](https://www.baeldung.com/java-printstream-vs-printwriter)
|
||||||
- [[<-- Prev]](/core-java-modules/core-java-io-3)
|
- [[<-- Prev]](/core-java-modules/core-java-io-3)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
package com.baeldung.inmemorycompilation;
|
||||||
|
|
||||||
|
public interface InMemoryClass {
|
||||||
|
|
||||||
|
void runCode();
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
package com.baeldung.inmemorycompilation;
|
||||||
|
|
||||||
|
import static java.util.Objects.requireNonNull;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class InMemoryClassLoader extends ClassLoader {
|
||||||
|
|
||||||
|
private final InMemoryFileManager manager;
|
||||||
|
|
||||||
|
public InMemoryClassLoader(ClassLoader parent, InMemoryFileManager manager) {
|
||||||
|
super(parent);
|
||||||
|
this.manager = requireNonNull(manager, "manager must not be null");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Class<?> findClass(String name) throws ClassNotFoundException {
|
||||||
|
|
||||||
|
Map<String, JavaClassAsBytes> compiledClasses = manager
|
||||||
|
.getBytesMap();
|
||||||
|
|
||||||
|
if (compiledClasses.containsKey(name)) {
|
||||||
|
byte[] bytes = compiledClasses.get(name)
|
||||||
|
.getBytes();
|
||||||
|
return defineClass(name, bytes, 0, bytes.length);
|
||||||
|
} else {
|
||||||
|
throw new ClassNotFoundException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,52 @@
|
||||||
|
package com.baeldung.inmemorycompilation;
|
||||||
|
|
||||||
|
import java.util.Hashtable;
|
||||||
|
import java.util.Map;
|
||||||
|
import javax.tools.FileObject;
|
||||||
|
import javax.tools.ForwardingJavaFileManager;
|
||||||
|
import javax.tools.JavaFileManager;
|
||||||
|
import javax.tools.JavaFileObject;
|
||||||
|
import javax.tools.JavaFileObject.Kind;
|
||||||
|
import javax.tools.StandardJavaFileManager;
|
||||||
|
|
||||||
|
public class InMemoryFileManager extends ForwardingJavaFileManager<JavaFileManager> {
|
||||||
|
|
||||||
|
private final Map<String, JavaClassAsBytes> compiledClasses;
|
||||||
|
private final ClassLoader loader;
|
||||||
|
|
||||||
|
public InMemoryFileManager(StandardJavaFileManager standardManager) {
|
||||||
|
super(standardManager);
|
||||||
|
this.compiledClasses = new Hashtable<>();
|
||||||
|
this.loader = new InMemoryClassLoader(this.getClass()
|
||||||
|
.getClassLoader(),
|
||||||
|
this
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to get the class loader for our compiled class. It creates an anonymous class extending
|
||||||
|
* the SecureClassLoader which uses the byte code created by the compiler and stored in the
|
||||||
|
* JavaClassObject, and returns the Class for it
|
||||||
|
*
|
||||||
|
* @param location where to place or search for file objects.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public ClassLoader getClassLoader(Location location) {
|
||||||
|
return loader;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JavaFileObject getJavaFileForOutput(Location location, String className, Kind kind,
|
||||||
|
FileObject sibling) {
|
||||||
|
|
||||||
|
JavaClassAsBytes classAsBytes = new JavaClassAsBytes(
|
||||||
|
className, kind);
|
||||||
|
compiledClasses.put(className, classAsBytes);
|
||||||
|
|
||||||
|
return classAsBytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, JavaClassAsBytes> getBytesMap() {
|
||||||
|
return compiledClasses;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
package com.baeldung.inmemorycompilation;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.net.URI;
|
||||||
|
import javax.tools.SimpleJavaFileObject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a Java class file (compiled byte-code)
|
||||||
|
*/
|
||||||
|
public class JavaClassAsBytes extends SimpleJavaFileObject {
|
||||||
|
|
||||||
|
protected final ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||||
|
|
||||||
|
public JavaClassAsBytes(String name, Kind kind) {
|
||||||
|
super(URI.create("string:///" + name.replace('.', '/') + kind.extension), kind);
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] getBytes() {
|
||||||
|
return bos.toByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public OutputStream openOutputStream() {
|
||||||
|
return bos;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
package com.baeldung.inmemorycompilation;
|
||||||
|
|
||||||
|
import static java.util.Objects.requireNonNull;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import javax.tools.SimpleJavaFileObject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a Java source code file
|
||||||
|
*/
|
||||||
|
public class JavaSourceFromString extends SimpleJavaFileObject {
|
||||||
|
|
||||||
|
private final String sourceCode;
|
||||||
|
|
||||||
|
public JavaSourceFromString(String name, String sourceCode) {
|
||||||
|
super(URI.create("string:///" + name.replace('.', '/') + Kind.SOURCE.extension),
|
||||||
|
Kind.SOURCE
|
||||||
|
);
|
||||||
|
this.sourceCode = requireNonNull(sourceCode, "sourceCode must not be null");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CharSequence getCharContent(boolean ignoreEncodingErrors) {
|
||||||
|
return sourceCode;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,57 @@
|
||||||
|
package com.baeldung.inmemorycompilation;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.tools.DiagnosticCollector;
|
||||||
|
import javax.tools.JavaCompiler;
|
||||||
|
import javax.tools.JavaFileObject;
|
||||||
|
import javax.tools.ToolProvider;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Assertions;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class InMemoryCompilationUnitTest {
|
||||||
|
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(InMemoryCompilationUnitTest.class);
|
||||||
|
|
||||||
|
final static String QUALIFIED_CLASS_NAME = "com.baeldung.inmemorycompilation.TestClass";
|
||||||
|
|
||||||
|
final static String SOURCE_CODE =
|
||||||
|
"package com.baeldung.inmemorycompilation;\n"
|
||||||
|
+ "public class TestClass implements InMemoryClass {\n"
|
||||||
|
+ "@Override\n"
|
||||||
|
+ " public void runCode() {\n"
|
||||||
|
+ " System.out.println(\"code is running...\");\n"
|
||||||
|
+ " }\n"
|
||||||
|
+ "}\n";
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenStringIsCompiled_ThenCodeShouldExecute() throws ClassNotFoundException, InstantiationException, IllegalAccessException {
|
||||||
|
|
||||||
|
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
|
||||||
|
DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<>();
|
||||||
|
InMemoryFileManager manager = new InMemoryFileManager(compiler.getStandardFileManager(null, null, null));
|
||||||
|
|
||||||
|
List<JavaFileObject> sourceFiles = Collections.singletonList(new JavaSourceFromString(QUALIFIED_CLASS_NAME, SOURCE_CODE));
|
||||||
|
|
||||||
|
JavaCompiler.CompilationTask task = compiler.getTask(null, manager, diagnostics, null, null, sourceFiles);
|
||||||
|
|
||||||
|
boolean result = task.call();
|
||||||
|
|
||||||
|
if (result) {
|
||||||
|
diagnostics.getDiagnostics()
|
||||||
|
.forEach(d -> LOGGER.error(String.valueOf(d)));
|
||||||
|
} else {
|
||||||
|
ClassLoader classLoader = manager.getClassLoader(null);
|
||||||
|
Class<?> clazz = classLoader.loadClass(QUALIFIED_CLASS_NAME);
|
||||||
|
InMemoryClass instanceOfClass = (InMemoryClass) clazz.newInstance();
|
||||||
|
|
||||||
|
Assertions.assertInstanceOf(InMemoryClass.class, instanceOfClass);
|
||||||
|
|
||||||
|
instanceOfClass.runCode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,10 +1,12 @@
|
||||||
package com.baeldung.resource;
|
package com.baeldung.resource;
|
||||||
|
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
|
import org.junit.jupiter.api.Disabled;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
|
||||||
|
@Disabled
|
||||||
class ClassGetResourceUnitTest {
|
class ClassGetResourceUnitTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
|
@ -1,10 +1,12 @@
|
||||||
package com.baeldung.resource;
|
package com.baeldung.resource;
|
||||||
|
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
|
import org.junit.jupiter.api.Disabled;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
|
||||||
|
@Disabled
|
||||||
class ClassLoaderGetResourceUnitTest {
|
class ClassLoaderGetResourceUnitTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
|
@ -13,4 +13,12 @@
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-lang3</artifactId>
|
||||||
|
<version>3.12.0</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
</project>
|
</project>
|
|
@ -0,0 +1,30 @@
|
||||||
|
package com.baeldung.nullchecking;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
public class Car {
|
||||||
|
|
||||||
|
Integer power;
|
||||||
|
|
||||||
|
Integer year;
|
||||||
|
|
||||||
|
public boolean allNull() {
|
||||||
|
|
||||||
|
if (power != null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (year != null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean allNullV2() {
|
||||||
|
|
||||||
|
return Stream.of(power, year)
|
||||||
|
.allMatch(Objects::isNull);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
package com.baeldung.nullchecking;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public class NullChecker {
|
||||||
|
|
||||||
|
public static boolean allNull(Object target) {
|
||||||
|
|
||||||
|
return Arrays.stream(target.getClass()
|
||||||
|
.getDeclaredFields())
|
||||||
|
.peek(f -> f.setAccessible(true))
|
||||||
|
.map(f -> getFieldValue(f, target))
|
||||||
|
.allMatch(Objects::isNull);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Object getFieldValue(Field field, Object target) {
|
||||||
|
try {
|
||||||
|
return field.get(target);
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
package com.baeldung.nullchecking;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.ObjectUtils;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
|
public class NullCheckUnitTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenNullFields_whenCheckForNullsUsingIfs_thenReturnCorrectValue(){
|
||||||
|
Car car = new Car();
|
||||||
|
|
||||||
|
boolean result = car.allNull();
|
||||||
|
|
||||||
|
assertTrue(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenNullFields_whenCheckForNullsUsingStreams_thenReturnCorrectValue(){
|
||||||
|
Car car = new Car();
|
||||||
|
|
||||||
|
boolean result = car.allNullV2();
|
||||||
|
|
||||||
|
assertTrue(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenNullFields_whenCheckForNullsUsingApacheCommons_thenReturnCorrectValue(){
|
||||||
|
Car car = new Car();
|
||||||
|
|
||||||
|
boolean result = ObjectUtils.allNull(car.power, car.year);
|
||||||
|
|
||||||
|
assertTrue(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenNullFields_whenCheckForNullsUsingReflection_thenReturnCorrectValue(){
|
||||||
|
Car car = new Car();
|
||||||
|
|
||||||
|
boolean result = NullChecker.allNull(car);
|
||||||
|
|
||||||
|
assertTrue(result);
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,3 +7,4 @@
|
||||||
- [Dynamic Proxies in Java](http://www.baeldung.com/java-dynamic-proxies)
|
- [Dynamic Proxies in Java](http://www.baeldung.com/java-dynamic-proxies)
|
||||||
- [What Causes java.lang.reflect.InvocationTargetException?](https://www.baeldung.com/java-lang-reflect-invocationtargetexception)
|
- [What Causes java.lang.reflect.InvocationTargetException?](https://www.baeldung.com/java-lang-reflect-invocationtargetexception)
|
||||||
- [How to Get a Name of a Method Being Executed?](http://www.baeldung.com/java-name-of-executing-method)
|
- [How to Get a Name of a Method Being Executed?](http://www.baeldung.com/java-name-of-executing-method)
|
||||||
|
- [Getting Class Type From a String in Java](https://www.baeldung.com/java-get-class-object-from-string)
|
||||||
|
|
|
@ -11,4 +11,5 @@ This module contains articles about core Java Security
|
||||||
- [Generating a Secure AES Key in Java](https://www.baeldung.com/java-secure-aes-key)
|
- [Generating a Secure AES Key in Java](https://www.baeldung.com/java-secure-aes-key)
|
||||||
- [Computing an X509 Certificate’s Thumbprint in Java](https://www.baeldung.com/java-x509-certificate-thumbprint)
|
- [Computing an X509 Certificate’s Thumbprint in Java](https://www.baeldung.com/java-x509-certificate-thumbprint)
|
||||||
- [Error: “trustAnchors parameter must be non-empty”](https://www.baeldung.com/java-trustanchors-parameter-must-be-non-empty)
|
- [Error: “trustAnchors parameter must be non-empty”](https://www.baeldung.com/java-trustanchors-parameter-must-be-non-empty)
|
||||||
|
- [Common Exceptions of Crypto APIs in Java](https://www.baeldung.com/java-crypto-apis-exceptions)
|
||||||
- More articles: [[<-- prev]](/core-java-modules/core-java-security-2)
|
- More articles: [[<-- prev]](/core-java-modules/core-java-security-2)
|
||||||
|
|
|
@ -59,6 +59,36 @@
|
||||||
<version>3.12.0</version>
|
<version>3.12.0</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.reactivex.rxjava3</groupId>
|
||||||
|
<artifactId>rxjava</artifactId>
|
||||||
|
<version>${rx.java3.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.vavr</groupId>
|
||||||
|
<artifactId>vavr</artifactId>
|
||||||
|
<version>${io.varv.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.projectreactor</groupId>
|
||||||
|
<artifactId>reactor-core</artifactId>
|
||||||
|
<version>${io.reactor3.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-collections4</artifactId>
|
||||||
|
<version>${apache.commons.collection4.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.guava</groupId>
|
||||||
|
<artifactId>guava</artifactId>
|
||||||
|
<version>${google.guava.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.oath.cyclops</groupId>
|
||||||
|
<artifactId>cyclops</artifactId>
|
||||||
|
<version>${cyclops.version}</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
@ -90,6 +120,12 @@
|
||||||
<maven.compiler.target>12</maven.compiler.target>
|
<maven.compiler.target>12</maven.compiler.target>
|
||||||
<rx.java.version>1.2.5</rx.java.version>
|
<rx.java.version>1.2.5</rx.java.version>
|
||||||
<rx.java2.version>2.2.2</rx.java2.version>
|
<rx.java2.version>2.2.2</rx.java2.version>
|
||||||
|
<rx.java3.version>3.1.5</rx.java3.version>
|
||||||
|
<io.varv.version>1.0.0-alpha-4</io.varv.version>
|
||||||
|
<io.reactor3.version>3.5.1</io.reactor3.version>
|
||||||
|
<apache.commons.collection4.version>4.4</apache.commons.collection4.version>
|
||||||
|
<google.guava.version>31.1-jre</google.guava.version>
|
||||||
|
<cyclops.version>10.4.1</cyclops.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
</project>
|
</project>
|
|
@ -0,0 +1,47 @@
|
||||||
|
package com.baeldung.streams.processing;
|
||||||
|
|
||||||
|
import static java.util.Spliterator.ORDERED;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Spliterators;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
import java.util.stream.StreamSupport;
|
||||||
|
|
||||||
|
public class CustomBatchIterator<T> implements Iterator<List<T>> {
|
||||||
|
private final int batchSize;
|
||||||
|
private List<T> currentBatch;
|
||||||
|
private final Iterator<T> iterator;
|
||||||
|
|
||||||
|
public CustomBatchIterator(Iterator<T> sourceIterator, int batchSize) {
|
||||||
|
this.batchSize = batchSize;
|
||||||
|
this.iterator = sourceIterator;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<T> next() {
|
||||||
|
return currentBatch;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasNext() {
|
||||||
|
prepareNextBatch();
|
||||||
|
return currentBatch != null && !currentBatch.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> Stream<List<T>> batchStreamOf(Stream<T> stream, int batchSize) {
|
||||||
|
return stream(new CustomBatchIterator<>(stream.iterator(), batchSize));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static <T> Stream<T> stream(Iterator<T> iterator) {
|
||||||
|
return StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator, ORDERED), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void prepareNextBatch() {
|
||||||
|
currentBatch = new ArrayList<>(batchSize);
|
||||||
|
while (iterator.hasNext() && currentBatch.size() < batchSize) {
|
||||||
|
currentBatch.add(iterator.next());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,141 @@
|
||||||
|
package com.baeldung.streams.processing;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.IntStream;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import org.apache.commons.collections4.ListUtils;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import com.google.common.collect.Iterators;
|
||||||
|
|
||||||
|
import cyclops.data.LazySeq;
|
||||||
|
import cyclops.reactive.ReactiveSeq;
|
||||||
|
import io.reactivex.rxjava3.core.Observable;
|
||||||
|
import reactor.core.publisher.Flux;
|
||||||
|
|
||||||
|
public class StreamProcessingUnitTest {
|
||||||
|
public final int BATCH_SIZE = 10;
|
||||||
|
|
||||||
|
private final List<Integer> firstBatch = List.of(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
|
||||||
|
private final List<Integer> secondBatch = List.of(10, 11, 12, 13, 14, 15, 16, 17, 18, 19);
|
||||||
|
private final List<Integer> thirdBatch = List.of(20, 21, 22, 23, 24, 25, 26, 27, 28, 29);
|
||||||
|
private final List<Integer> fourthBatch = List.of(30, 31, 32, 33);
|
||||||
|
|
||||||
|
public Stream<Integer> data;
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
public void setUp() {
|
||||||
|
data = IntStream.range(0, 34)
|
||||||
|
.boxed();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenAStreamOfData_whenIsProcessingInBatchUsingSpliterator_thenFourBatchesAreObtained() {
|
||||||
|
Collection<List<Integer>> result = new ArrayList<>();
|
||||||
|
CustomBatchIterator.batchStreamOf(data, BATCH_SIZE)
|
||||||
|
.forEach(result::add);
|
||||||
|
assertTrue(result.contains(firstBatch));
|
||||||
|
assertTrue(result.contains(secondBatch));
|
||||||
|
assertTrue(result.contains(thirdBatch));
|
||||||
|
assertTrue(result.contains(fourthBatch));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenAStreamOfData_whenIsProcessingInBatchUsingCollectionAPI_thenFourBatchesAreObtained() {
|
||||||
|
Collection<List<Integer>> result = data.collect(Collectors.groupingBy(it -> it / BATCH_SIZE))
|
||||||
|
.values();
|
||||||
|
assertTrue(result.contains(firstBatch));
|
||||||
|
assertTrue(result.contains(secondBatch));
|
||||||
|
assertTrue(result.contains(thirdBatch));
|
||||||
|
assertTrue(result.contains(fourthBatch));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenAStreamOfData_whenIsProcessingInBatchParallelUsingCollectionAPI_thenFourBatchesAreObtained() {
|
||||||
|
Collection<List<Integer>> result = data.parallel()
|
||||||
|
.collect(Collectors.groupingBy(it -> it / BATCH_SIZE))
|
||||||
|
.values();
|
||||||
|
assertTrue(result.contains(firstBatch));
|
||||||
|
assertTrue(result.contains(secondBatch));
|
||||||
|
assertTrue(result.contains(thirdBatch));
|
||||||
|
assertTrue(result.contains(fourthBatch));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenAStreamOfData_whenIsProcessingInBatchUsingRxJavaV3_thenFourBatchesAreObtained() {
|
||||||
|
// RxJava v3
|
||||||
|
Collection<List<Integer>> result = new ArrayList<>();
|
||||||
|
Observable.fromStream(data)
|
||||||
|
.buffer(BATCH_SIZE)
|
||||||
|
.subscribe(result::add);
|
||||||
|
assertTrue(result.contains(firstBatch));
|
||||||
|
assertTrue(result.contains(secondBatch));
|
||||||
|
assertTrue(result.contains(thirdBatch));
|
||||||
|
assertTrue(result.contains(fourthBatch));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenAStreamOfData_whenIsProcessingInBatchUsingReactor_thenFourBatchesAreObtained() {
|
||||||
|
Collection<List<Integer>> result = new ArrayList<>();
|
||||||
|
Flux.fromStream(data)
|
||||||
|
.buffer(BATCH_SIZE)
|
||||||
|
.subscribe(result::add);
|
||||||
|
assertTrue(result.contains(firstBatch));
|
||||||
|
assertTrue(result.contains(secondBatch));
|
||||||
|
assertTrue(result.contains(thirdBatch));
|
||||||
|
assertTrue(result.contains(fourthBatch));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenAStreamOfData_whenIsProcessingInBatchUsingApacheCommon_thenFourBatchesAreObtained() {
|
||||||
|
Collection<List<Integer>> result = new ArrayList<>(ListUtils.partition(data.collect(Collectors.toList()), BATCH_SIZE));
|
||||||
|
assertTrue(result.contains(firstBatch));
|
||||||
|
assertTrue(result.contains(secondBatch));
|
||||||
|
assertTrue(result.contains(thirdBatch));
|
||||||
|
assertTrue(result.contains(fourthBatch));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenAStreamOfData_whenIsProcessingInBatchUsingGuava_thenFourBatchesAreObtained() {
|
||||||
|
Collection<List<Integer>> result = new ArrayList<>();
|
||||||
|
Iterators.partition(data.iterator(), BATCH_SIZE)
|
||||||
|
.forEachRemaining(result::add);
|
||||||
|
assertTrue(result.contains(firstBatch));
|
||||||
|
assertTrue(result.contains(secondBatch));
|
||||||
|
assertTrue(result.contains(thirdBatch));
|
||||||
|
assertTrue(result.contains(fourthBatch));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenAStreamOfData_whenIsProcessingInBatchUsingCyclops_thenFourBatchesAreObtained() {
|
||||||
|
Collection<List<Integer>> result = new ArrayList<>();
|
||||||
|
ReactiveSeq.fromStream(data)
|
||||||
|
.grouped(BATCH_SIZE)
|
||||||
|
.toList()
|
||||||
|
.forEach(value -> result.add(value.collect(Collectors.toList())));
|
||||||
|
assertTrue(result.contains(firstBatch));
|
||||||
|
assertTrue(result.contains(secondBatch));
|
||||||
|
assertTrue(result.contains(thirdBatch));
|
||||||
|
assertTrue(result.contains(fourthBatch));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenAStreamOfData_whenIsProcessingInBatchUsingCyclopsLazy_thenFourBatchesAreObtained() {
|
||||||
|
Collection<List<Integer>> result = new ArrayList<>();
|
||||||
|
LazySeq.fromStream(data)
|
||||||
|
.grouped(BATCH_SIZE)
|
||||||
|
.toList()
|
||||||
|
.forEach(value -> result.add(value.collect(Collectors.toList())));
|
||||||
|
assertTrue(result.contains(firstBatch));
|
||||||
|
assertTrue(result.contains(secondBatch));
|
||||||
|
assertTrue(result.contains(thirdBatch));
|
||||||
|
assertTrue(result.contains(fourthBatch));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
package com.baeldung.streams.processing.vavr;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import com.baeldung.streams.processing.StreamProcessingUnitTest;
|
||||||
|
|
||||||
|
import io.vavr.collection.List;
|
||||||
|
import io.vavr.collection.Stream;
|
||||||
|
|
||||||
|
public class StreamProcessingWithVavrUnitTest extends StreamProcessingUnitTest {
|
||||||
|
|
||||||
|
private final List<Integer> firstBatch = List.of(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
|
||||||
|
private final List<Integer> secondBatch = List.of(10, 11, 12, 13, 14, 15, 16, 17, 18, 19);
|
||||||
|
private final List<Integer> thirdBatch = List.of(20, 21, 22, 23, 24, 25, 26, 27, 28, 29);
|
||||||
|
private final List<Integer> fourthBatch = List.of(30, 31, 32, 33);
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenAStreamOfData_whenIsProcessingInBatchUsingVavr_thenFourBatchesAreObtained() {
|
||||||
|
List<List<Integer>> result = Stream.ofAll(data)
|
||||||
|
.toList()
|
||||||
|
.grouped(BATCH_SIZE)
|
||||||
|
.toList();
|
||||||
|
assertTrue(result.contains(firstBatch));
|
||||||
|
assertTrue(result.contains(secondBatch));
|
||||||
|
assertTrue(result.contains(thirdBatch));
|
||||||
|
assertTrue(result.contains(fourthBatch));
|
||||||
|
}
|
||||||
|
}
|
|
@ -27,17 +27,17 @@ public final class UUIDGenerator {
|
||||||
|
|
||||||
private static long get64LeastSignificantBitsForVersion1() {
|
private static long get64LeastSignificantBitsForVersion1() {
|
||||||
final long random63BitLong = new Random().nextLong() & 0x3FFFFFFFFFFFFFFFL;
|
final long random63BitLong = new Random().nextLong() & 0x3FFFFFFFFFFFFFFFL;
|
||||||
final long variant3BitFlag = 0x8000000000000000L;
|
long variant3BitFlag = 0x8000000000000000L;
|
||||||
return random63BitLong + variant3BitFlag;
|
return random63BitLong | variant3BitFlag;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static long get64MostSignificantBitsForVersion1() {
|
private static long get64MostSignificantBitsForVersion1() {
|
||||||
final long timeForUuidIn100Nanos = System.currentTimeMillis();
|
final long currentTimeMillis = System.currentTimeMillis();
|
||||||
final long time_low = (timeForUuidIn100Nanos & 0x0000_0000_FFFF_FFFFL) << 32;
|
final long time_low = (currentTimeMillis & 0x0000_0000_FFFF_FFFFL) << 32;
|
||||||
final long time_mid = ((timeForUuidIn100Nanos >> 32) & 0xFFFF) << 16;
|
final long time_mid = ((currentTimeMillis >> 32) & 0xFFFF) << 16;
|
||||||
final long version = 1 << 12;
|
final long version = 1 << 12;
|
||||||
final long time_hi = ((timeForUuidIn100Nanos >> 48) & 0x0FFF);
|
final long time_high = ((currentTimeMillis >> 48) & 0x0FFF);
|
||||||
return time_low + time_mid + version + time_hi;
|
return time_low | time_mid | version | time_high;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -31,7 +31,6 @@
|
||||||
<module>core-java-collections-2</module>
|
<module>core-java-collections-2</module>
|
||||||
<module>core-java-collections-3</module>
|
<module>core-java-collections-3</module>
|
||||||
<module>core-java-collections-4</module>
|
<module>core-java-collections-4</module>
|
||||||
<module>core-java-collections-array-list</module>
|
|
||||||
<module>core-java-collections-conversions</module>
|
<module>core-java-collections-conversions</module>
|
||||||
<module>core-java-collections-conversions-2</module>
|
<module>core-java-collections-conversions-2</module>
|
||||||
<module>core-java-collections-set-2</module>
|
<module>core-java-collections-set-2</module>
|
||||||
|
|
|
@ -2,6 +2,7 @@ package com.baeldung.gcp.firebase.publisher.controller;
|
||||||
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
|
@ -103,7 +104,7 @@ public class FirebasePublisherController {
|
||||||
|
|
||||||
@DeleteMapping("/subscriptions/{topic}/{registrationToken}")
|
@DeleteMapping("/subscriptions/{topic}/{registrationToken}")
|
||||||
public ResponseEntity<Void> deleteSubscription(@PathVariable String topic, @PathVariable String registrationToken) throws FirebaseMessagingException {
|
public ResponseEntity<Void> deleteSubscription(@PathVariable String topic, @PathVariable String registrationToken) throws FirebaseMessagingException {
|
||||||
fcm.subscribeToTopic(List.of(registrationToken), topic);
|
fcm.subscribeToTopic(Arrays.asList(registrationToken), topic);
|
||||||
return ResponseEntity.ok().build();
|
return ResponseEntity.ok().build();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,3 +2,4 @@
|
||||||
### Relevant Articles:
|
### Relevant Articles:
|
||||||
|
|
||||||
- [How to Configure Conditional Dependencies in Gradle](https://www.baeldung.com/gradle-conditional-dependencies)
|
- [How to Configure Conditional Dependencies in Gradle](https://www.baeldung.com/gradle-conditional-dependencies)
|
||||||
|
- [Working With Multiple Repositories in Gradle](https://www.baeldung.com/java-gradle-multiple-repositories)
|
||||||
|
|
|
@ -1,72 +1,77 @@
|
||||||
package com.baeldung.httpclient.base;
|
package com.baeldung.httpclient.base;
|
||||||
|
|
||||||
import org.apache.http.HttpStatus;
|
import com.baeldung.handler.CustomHttpClientResponseHandler;
|
||||||
import org.apache.http.client.ClientProtocolException;
|
|
||||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
import org.apache.hc.client5.http.classic.methods.HttpGet;
|
||||||
import org.apache.http.client.methods.HttpGet;
|
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
|
||||||
import org.apache.http.entity.ContentType;
|
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
|
||||||
import org.apache.http.impl.client.CloseableHttpClient;
|
import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
|
||||||
import org.apache.http.impl.client.HttpClientBuilder;
|
|
||||||
import org.apache.http.util.EntityUtils;
|
import org.apache.hc.core5.http.ContentType;
|
||||||
import com.baeldung.httpclient.ResponseUtil;
|
import org.apache.hc.core5.http.HttpStatus;
|
||||||
import org.junit.After;
|
import org.apache.hc.core5.http.ParseException;
|
||||||
import org.junit.Before;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
import static org.hamcrest.Matchers.equalTo;
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
import static org.hamcrest.Matchers.notNullValue;
|
import static org.hamcrest.Matchers.notNullValue;
|
||||||
import static org.junit.Assert.assertThat;
|
|
||||||
|
|
||||||
public class HttpClientBasicLiveTest {
|
public class HttpClientBasicLiveTest {
|
||||||
|
|
||||||
private static final String SAMPLE_URL = "http://www.github.com";
|
private static final String SAMPLE_URL = "http://www.github.com";
|
||||||
|
|
||||||
private CloseableHttpClient instance;
|
|
||||||
|
|
||||||
private CloseableHttpResponse response;
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public final void before() {
|
|
||||||
instance = HttpClientBuilder.create().build();
|
|
||||||
}
|
|
||||||
|
|
||||||
@After
|
|
||||||
public final void after() throws IllegalStateException, IOException {
|
|
||||||
ResponseUtil.closeResponse(response);
|
|
||||||
}
|
|
||||||
|
|
||||||
// tests
|
|
||||||
|
|
||||||
// simple request - response
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public final void whenExecutingBasicGetRequest_thenNoExceptions() throws ClientProtocolException, IOException {
|
public final void whenExecutingBasicGetRequest_thenNoExceptions() throws IOException {
|
||||||
response = instance.execute(new HttpGet(SAMPLE_URL));
|
final HttpGet request = new HttpGet(SAMPLE_URL);
|
||||||
|
|
||||||
|
try (CloseableHttpClient client = HttpClientBuilder.create().build();
|
||||||
|
|
||||||
|
CloseableHttpResponse response = (CloseableHttpResponse) client
|
||||||
|
.execute(request, new CustomHttpClientResponseHandler())) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public final void givenGetRequestExecuted_whenAnalyzingTheResponse_thenCorrectStatusCode() throws ClientProtocolException, IOException {
|
public final void givenGetRequestExecuted_whenAnalyzingTheResponse_thenCorrectStatusCode() throws IOException {
|
||||||
response = instance.execute(new HttpGet(SAMPLE_URL));
|
final HttpGet request = new HttpGet(SAMPLE_URL);
|
||||||
final int statusCode = response.getStatusLine().getStatusCode();
|
try (CloseableHttpClient client = HttpClientBuilder.create().build();
|
||||||
assertThat(statusCode, equalTo(HttpStatus.SC_OK));
|
|
||||||
|
CloseableHttpResponse response = (CloseableHttpResponse) client
|
||||||
|
.execute(request, new CustomHttpClientResponseHandler())) {
|
||||||
|
|
||||||
|
assertThat(response.getCode(), equalTo(HttpStatus.SC_OK));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public final void givenGetRequestExecuted_whenAnalyzingTheResponse_thenCorrectMimeType() throws ClientProtocolException, IOException {
|
|
||||||
response = instance.execute(new HttpGet(SAMPLE_URL));
|
|
||||||
final String contentMimeType = ContentType.getOrDefault(response.getEntity()).getMimeType();
|
|
||||||
|
|
||||||
assertThat(contentMimeType, equalTo(ContentType.TEXT_HTML.getMimeType()));
|
@Test
|
||||||
|
public final void givenGetRequestExecuted_whenAnalyzingTheResponse_thenCorrectMimeType() throws IOException {
|
||||||
|
final HttpGet request = new HttpGet(SAMPLE_URL);
|
||||||
|
|
||||||
|
try (CloseableHttpClient client = HttpClientBuilder.create().build();
|
||||||
|
|
||||||
|
CloseableHttpResponse response = (CloseableHttpResponse) client
|
||||||
|
.execute(request, new CustomHttpClientResponseHandler())) {
|
||||||
|
|
||||||
|
final String contentMimeType = ContentType.parse(response.getEntity().getContentType()).getMimeType();
|
||||||
|
assertThat(contentMimeType, equalTo(ContentType.TEXT_HTML.getMimeType()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public final void givenGetRequestExecuted_whenAnalyzingTheResponse_thenCorrectBody() throws ClientProtocolException, IOException {
|
|
||||||
response = instance.execute(new HttpGet(SAMPLE_URL));
|
|
||||||
final String bodyAsString = EntityUtils.toString(response.getEntity());
|
|
||||||
|
|
||||||
assertThat(bodyAsString, notNullValue());
|
@Test
|
||||||
|
public final void givenGetRequestExecuted_whenAnalyzingTheResponse_thenCorrectBody() throws IOException, ParseException {
|
||||||
|
final HttpGet request = new HttpGet(SAMPLE_URL);
|
||||||
|
try (CloseableHttpClient client = HttpClientBuilder.create().build();
|
||||||
|
|
||||||
|
CloseableHttpResponse response = (CloseableHttpResponse) client
|
||||||
|
.execute(request, new CustomHttpClientResponseHandler())) {
|
||||||
|
|
||||||
|
assertThat(response, notNullValue());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,118 +1,119 @@
|
||||||
package com.baeldung.httpclient.sec;
|
package com.baeldung.httpclient.sec;
|
||||||
|
|
||||||
|
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
|
||||||
import org.apache.commons.codec.binary.Base64;
|
import org.apache.commons.codec.binary.Base64;
|
||||||
import org.apache.http.HttpHeaders;
|
|
||||||
import org.apache.http.HttpHost;
|
import com.baeldung.handler.CustomHttpClientResponseHandler;
|
||||||
import org.apache.http.HttpStatus;
|
|
||||||
import org.apache.http.auth.AuthScope;
|
import org.apache.hc.client5.http.auth.AuthScope;
|
||||||
import org.apache.http.auth.UsernamePasswordCredentials;
|
import org.apache.hc.client5.http.auth.AuthCache;
|
||||||
import org.apache.http.client.AuthCache;
|
import org.apache.hc.client5.http.auth.CredentialsProvider;
|
||||||
import org.apache.http.client.CredentialsProvider;
|
import org.apache.hc.client5.http.auth.UsernamePasswordCredentials;
|
||||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
import org.apache.hc.client5.http.classic.methods.HttpGet;
|
||||||
import org.apache.http.client.methods.HttpGet;
|
import org.apache.hc.client5.http.impl.auth.BasicAuthCache;
|
||||||
import org.apache.http.client.protocol.HttpClientContext;
|
import org.apache.hc.client5.http.impl.auth.BasicCredentialsProvider;
|
||||||
import org.apache.http.impl.auth.BasicScheme;
|
import org.apache.hc.client5.http.impl.auth.BasicScheme;
|
||||||
import org.apache.http.impl.client.BasicAuthCache;
|
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
|
||||||
import org.apache.http.impl.client.BasicCredentialsProvider;
|
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
|
||||||
import org.apache.http.impl.client.CloseableHttpClient;
|
import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
|
||||||
import org.apache.http.impl.client.HttpClientBuilder;
|
import org.apache.hc.client5.http.protocol.HttpClientContext;
|
||||||
import org.apache.http.protocol.HttpContext;
|
import org.apache.hc.core5.http.HttpHeaders;
|
||||||
import com.baeldung.httpclient.ResponseUtil;
|
import org.apache.hc.core5.http.HttpHost;
|
||||||
import org.junit.After;
|
import org.apache.hc.core5.http.HttpStatus;
|
||||||
import org.junit.Before;
|
import org.apache.hc.core5.http.protocol.HttpContext;
|
||||||
import org.junit.Test;
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.equalTo;
|
|
||||||
import static org.junit.Assert.assertThat;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* NOTE : Need module httpclient-simple to be running
|
* NOTE : Need module httpclient-simple to be running
|
||||||
*/
|
*/
|
||||||
|
class HttpClientAuthLiveTest {
|
||||||
public class HttpClientAuthLiveTest {
|
|
||||||
|
|
||||||
private static final String URL_SECURED_BY_BASIC_AUTHENTICATION = "http://localhost:8082/httpclient-simple/api/foos/1";
|
private static final String URL_SECURED_BY_BASIC_AUTHENTICATION = "http://localhost:8082/httpclient-simple/api/foos/1";
|
||||||
private static final String DEFAULT_USER = "user1";
|
private static final String DEFAULT_USER = "user1";
|
||||||
private static final String DEFAULT_PASS = "user1Pass";
|
private static final String DEFAULT_PASS = "user1Pass";
|
||||||
|
private final char[] DEFAULT_PASS_ARRAY = DEFAULT_PASS.toCharArray() ;
|
||||||
private CloseableHttpClient client;
|
|
||||||
|
|
||||||
private CloseableHttpResponse response;
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public final void before() {
|
|
||||||
client = HttpClientBuilder.create().build();
|
|
||||||
}
|
|
||||||
|
|
||||||
@After
|
|
||||||
public final void after() throws IllegalStateException, IOException {
|
|
||||||
ResponseUtil.closeResponse(response);
|
|
||||||
}
|
|
||||||
|
|
||||||
// tests
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public final void whenExecutingBasicGetRequestWithBasicAuthenticationEnabled_thenSuccess() throws IOException {
|
final void whenExecutingBasicGetRequestWithBasicAuthenticationEnabled_thenSuccess() throws IOException {
|
||||||
client = HttpClientBuilder.create().setDefaultCredentialsProvider(provider()).build();
|
final HttpGet request = new HttpGet(URL_SECURED_BY_BASIC_AUTHENTICATION);
|
||||||
|
try (CloseableHttpClient client = HttpClientBuilder.create()
|
||||||
|
.setDefaultCredentialsProvider(provider())
|
||||||
|
.build();
|
||||||
|
|
||||||
response = client.execute(new HttpGet(URL_SECURED_BY_BASIC_AUTHENTICATION));
|
CloseableHttpResponse response = (CloseableHttpResponse) client
|
||||||
|
.execute(request, new CustomHttpClientResponseHandler())) {
|
||||||
final int statusCode = response.getStatusLine().getStatusCode();
|
final int statusCode = response.getCode();
|
||||||
assertThat(statusCode, equalTo(HttpStatus.SC_OK));
|
assertThat(statusCode, equalTo(HttpStatus.SC_OK));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public final void givenAuthenticationIsPreemptive_whenExecutingBasicGetRequestWithBasicAuthenticationEnabled_thenSuccess() throws IOException {
|
final void givenAuthenticationIsPreemptive_whenExecutingBasicGetRequestWithBasicAuthenticationEnabled_thenSuccess() throws IOException {
|
||||||
client = HttpClientBuilder.create().build();
|
final HttpGet request = new HttpGet(URL_SECURED_BY_BASIC_AUTHENTICATION);
|
||||||
response = client.execute(new HttpGet(URL_SECURED_BY_BASIC_AUTHENTICATION), context());
|
try (CloseableHttpClient client = HttpClientBuilder.create()
|
||||||
|
.build();
|
||||||
|
|
||||||
final int statusCode = response.getStatusLine().getStatusCode();
|
CloseableHttpResponse response = (CloseableHttpResponse) client
|
||||||
assertThat(statusCode, equalTo(HttpStatus.SC_OK));
|
.execute(request, context(), new CustomHttpClientResponseHandler())) {
|
||||||
|
final int statusCode = response.getCode();
|
||||||
|
assertThat(statusCode, equalTo(200));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public final void givenAuthorizationHeaderIsSetManually_whenExecutingGetRequest_thenSuccess() throws IOException {
|
final void givenAuthorizationHeaderIsSetManually_whenExecutingGetRequest_thenSuccess() throws IOException {
|
||||||
client = HttpClientBuilder.create().build();
|
|
||||||
|
|
||||||
final HttpGet request = new HttpGet(URL_SECURED_BY_BASIC_AUTHENTICATION);
|
final HttpGet request = new HttpGet(URL_SECURED_BY_BASIC_AUTHENTICATION);
|
||||||
request.setHeader(HttpHeaders.AUTHORIZATION, authorizationHeader(DEFAULT_USER, DEFAULT_PASS));
|
request.setHeader(HttpHeaders.AUTHORIZATION, authorizationHeader(DEFAULT_USER, DEFAULT_PASS));
|
||||||
response = client.execute(request);
|
try (CloseableHttpClient client = HttpClientBuilder.create()
|
||||||
|
.build();
|
||||||
|
|
||||||
final int statusCode = response.getStatusLine().getStatusCode();
|
CloseableHttpResponse response = (CloseableHttpResponse) client
|
||||||
assertThat(statusCode, equalTo(HttpStatus.SC_OK));
|
.execute(request, context(), new CustomHttpClientResponseHandler())) {
|
||||||
|
final int statusCode = response.getCode();
|
||||||
|
assertThat(statusCode, equalTo(HttpStatus.SC_OK));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public final void givenAuthorizationHeaderIsSetManually_whenExecutingGetRequest_thenSuccess2() throws IOException {
|
final void givenAuthorizationHeaderIsSetManually_whenExecutingGetRequest_thenSuccess2() throws IOException {
|
||||||
final HttpGet request = new HttpGet(URL_SECURED_BY_BASIC_AUTHENTICATION);
|
final HttpGet request = new HttpGet(URL_SECURED_BY_BASIC_AUTHENTICATION);
|
||||||
final String auth = DEFAULT_USER + ":" + DEFAULT_PASS;
|
final String auth = DEFAULT_USER + ":" + DEFAULT_PASS;
|
||||||
final byte[] encodedAuth = Base64.encodeBase64(auth.getBytes(StandardCharsets.ISO_8859_1));
|
final byte[] encodedAuth = Base64.encodeBase64(auth.getBytes(StandardCharsets.ISO_8859_1));
|
||||||
final String authHeader = "Basic " + new String(encodedAuth);
|
final String authHeader = "Basic " + new String(encodedAuth);
|
||||||
request.setHeader(HttpHeaders.AUTHORIZATION, authHeader);
|
request.setHeader(HttpHeaders.AUTHORIZATION, authHeader);
|
||||||
|
|
||||||
client = HttpClientBuilder.create().build();
|
try (CloseableHttpClient client = HttpClientBuilder.create()
|
||||||
response = client.execute(request);
|
.build();
|
||||||
|
|
||||||
final int statusCode = response.getStatusLine().getStatusCode();
|
CloseableHttpResponse response = (CloseableHttpResponse) client
|
||||||
assertThat(statusCode, equalTo(HttpStatus.SC_OK));
|
.execute(request, new CustomHttpClientResponseHandler())) {
|
||||||
|
final int statusCode = response.getCode();
|
||||||
|
assertThat(statusCode, equalTo(HttpStatus.SC_OK));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// UTILS
|
// UTILS
|
||||||
|
|
||||||
private CredentialsProvider provider() {
|
private CredentialsProvider provider() {
|
||||||
final CredentialsProvider provider = new BasicCredentialsProvider();
|
final HttpHost targetHost = new HttpHost("http", "localhost", 8082);
|
||||||
final UsernamePasswordCredentials credentials = new UsernamePasswordCredentials(DEFAULT_USER, DEFAULT_PASS);
|
final BasicCredentialsProvider provider = new BasicCredentialsProvider();
|
||||||
provider.setCredentials(AuthScope.ANY, credentials);
|
AuthScope authScope = new AuthScope(targetHost);
|
||||||
|
provider.setCredentials(authScope, new UsernamePasswordCredentials(DEFAULT_USER, DEFAULT_PASS_ARRAY));
|
||||||
return provider;
|
return provider;
|
||||||
}
|
}
|
||||||
|
|
||||||
private HttpContext context() {
|
private HttpContext context() {
|
||||||
final HttpHost targetHost = new HttpHost("localhost", 8082, "http");
|
final HttpHost targetHost = new HttpHost("http", "localhost", 8082);
|
||||||
final CredentialsProvider credsProvider = new BasicCredentialsProvider();
|
final BasicCredentialsProvider credsProvider = new BasicCredentialsProvider();
|
||||||
credsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(DEFAULT_USER, DEFAULT_PASS));
|
AuthScope authScope = new AuthScope(targetHost);
|
||||||
|
credsProvider.setCredentials(authScope, new UsernamePasswordCredentials(DEFAULT_USER, DEFAULT_PASS_ARRAY));
|
||||||
|
|
||||||
// Create AuthCache instance
|
// Create AuthCache instance
|
||||||
final AuthCache authCache = new BasicAuthCache();
|
final AuthCache authCache = new BasicAuthCache();
|
||||||
|
|
|
@ -26,24 +26,10 @@ class HttpClientCookieLiveTest {
|
||||||
final void whenSettingCookiesOnARequest_thenCorrect() throws IOException {
|
final void whenSettingCookiesOnARequest_thenCorrect() throws IOException {
|
||||||
final HttpGet request = new HttpGet("http://www.github.com");
|
final HttpGet request = new HttpGet("http://www.github.com");
|
||||||
request.setHeader("Cookie", "JSESSIONID=1234");
|
request.setHeader("Cookie", "JSESSIONID=1234");
|
||||||
try (CloseableHttpClient client = HttpClients.createDefault(); CloseableHttpResponse response = (CloseableHttpResponse) client.execute(request, new CustomHttpClientResponseHandler());) {
|
try (CloseableHttpClient client = HttpClients.createDefault();
|
||||||
assertThat(response.getCode(), equalTo(200));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
final void givenUsingDeprecatedApi_whenSettingCookiesOnTheHttpClient_thenCorrect() throws IOException {
|
|
||||||
final BasicCookieStore cookieStore = new BasicCookieStore();
|
|
||||||
final BasicClientCookie cookie = new BasicClientCookie("JSESSIONID", "1234");
|
|
||||||
cookie.setDomain(".github.com");
|
|
||||||
cookie.setAttribute("domain", "true");
|
|
||||||
cookie.setPath("/");
|
|
||||||
cookieStore.addCookie(cookie);
|
|
||||||
final HttpGet request = new HttpGet("https://www.github.com");
|
|
||||||
try (CloseableHttpClient client = HttpClientBuilder.create()
|
|
||||||
.setDefaultCookieStore(cookieStore)
|
|
||||||
.build(); CloseableHttpResponse response = (CloseableHttpResponse) client.execute(request, new CustomHttpClientResponseHandler())) {
|
|
||||||
|
|
||||||
|
CloseableHttpResponse response = (CloseableHttpResponse) client
|
||||||
|
.execute(request, new CustomHttpClientResponseHandler())) {
|
||||||
assertThat(response.getCode(), equalTo(200));
|
assertThat(response.getCode(), equalTo(200));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -58,9 +44,12 @@ class HttpClientCookieLiveTest {
|
||||||
cookieStore.addCookie(cookie);
|
cookieStore.addCookie(cookie);
|
||||||
final HttpGet request = new HttpGet("http://www.github.com");
|
final HttpGet request = new HttpGet("http://www.github.com");
|
||||||
|
|
||||||
try (CloseableHttpClient client = HttpClientBuilder.create().setDefaultCookieStore(cookieStore).build();
|
try (CloseableHttpClient client = HttpClientBuilder.create()
|
||||||
CloseableHttpResponse response = (CloseableHttpResponse) client.execute(request, new CustomHttpClientResponseHandler())) {
|
.setDefaultCookieStore(cookieStore)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
CloseableHttpResponse response = (CloseableHttpResponse) client
|
||||||
|
.execute(request, new CustomHttpClientResponseHandler())) {
|
||||||
assertThat(response.getCode(), equalTo(200));
|
assertThat(response.getCode(), equalTo(200));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,7 +68,9 @@ class HttpClientCookieLiveTest {
|
||||||
// localContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore); // before 4.3
|
// localContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore); // before 4.3
|
||||||
|
|
||||||
try (CloseableHttpClient client = HttpClientBuilder.create().build();
|
try (CloseableHttpClient client = HttpClientBuilder.create().build();
|
||||||
CloseableHttpResponse response = (CloseableHttpResponse) client.execute(request, localContext, new CustomHttpClientResponseHandler())) {
|
|
||||||
|
CloseableHttpResponse response = (CloseableHttpResponse) client
|
||||||
|
.execute(request, localContext, new CustomHttpClientResponseHandler())) {
|
||||||
assertThat(response.getCode(), equalTo(200));
|
assertThat(response.getCode(), equalTo(200));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,27 @@
|
||||||
<version>${rest-assured.version}</version>
|
<version>${rest-assured.version}</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||||
|
<version>${spring-boot.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-data-jdbc</artifactId>
|
||||||
|
<version>${spring-boot.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.h2database</groupId>
|
||||||
|
<artifactId>h2</artifactId>
|
||||||
|
<version>${h2.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
|
<version>${spring-boot.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
@ -38,7 +59,9 @@
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
|
<h2.version>2.1.214</h2.version>
|
||||||
<rest-assured.version>3.1.1</rest-assured.version>
|
<rest-assured.version>3.1.1</rest-assured.version>
|
||||||
|
<spring-boot.version>2.5.0</spring-boot.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
</project>
|
</project>
|
|
@ -0,0 +1,13 @@
|
||||||
|
package com.baeldung.jackson.jsonignorevstransient;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
public class Application {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(Application.class, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
package com.baeldung.jackson.jsonignorevstransient;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
class Person implements Serializable {
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
private final Long id;
|
||||||
|
|
||||||
|
private final String firstName;
|
||||||
|
|
||||||
|
private final String lastName;
|
||||||
|
|
||||||
|
public Person(Long id, String firstName, String lastName) {
|
||||||
|
this.id = id;
|
||||||
|
this.firstName = firstName;
|
||||||
|
this.lastName = lastName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFirstName() {
|
||||||
|
return firstName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLastName() {
|
||||||
|
return lastName;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,64 @@
|
||||||
|
package com.baeldung.jackson.jsonignorevstransient;
|
||||||
|
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
import javax.persistence.Transient;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "Users")
|
||||||
|
class User implements Serializable {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
private String username;
|
||||||
|
|
||||||
|
private String password;
|
||||||
|
|
||||||
|
@Transient
|
||||||
|
private String repeatedPassword;
|
||||||
|
|
||||||
|
public User() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public User(Long id, String username, String password, String repeatedPassword) {
|
||||||
|
this.id = id;
|
||||||
|
this.username = username;
|
||||||
|
this.password = password;
|
||||||
|
this.repeatedPassword = repeatedPassword;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUsername() {
|
||||||
|
return username;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUsername(String username) {
|
||||||
|
this.username = username;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPassword() {
|
||||||
|
return password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPassword(String password) {
|
||||||
|
this.password = password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRepeatedPassword() {
|
||||||
|
return repeatedPassword;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRepeatedPassword(String repeatedPassword) {
|
||||||
|
this.repeatedPassword = repeatedPassword;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
package com.baeldung.jackson.jsonignorevstransient;
|
||||||
|
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
|
@Repository
|
||||||
|
public interface UserRepository extends JpaRepository<User, Long> {
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
package com.baeldung.jackson.jsonignorevstransient;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
import static org.hamcrest.Matchers.containsString;
|
||||||
|
import static org.hamcrest.Matchers.not;
|
||||||
|
|
||||||
|
class PersonUnitTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenPerson_whenSerializing_thenIdFieldIgnored() throws JsonProcessingException {
|
||||||
|
|
||||||
|
Person person = new Person(1L, "My First Name", "My Last Name");
|
||||||
|
String result = new ObjectMapper().writeValueAsString(person);
|
||||||
|
|
||||||
|
assertThat(result, containsString("firstName"));
|
||||||
|
assertThat(result, containsString("lastName"));
|
||||||
|
assertThat(result, not(containsString("id")));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
package com.baeldung.jackson.jsonignorevstransient;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
import static org.hamcrest.Matchers.containsString;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||||
|
|
||||||
|
@SpringBootTest
|
||||||
|
class UserUnitTest {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
UserRepository userRepository;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenUser_whenSave_thenSkipTransientFields() {
|
||||||
|
User user = new User(1L, "user", "newPassword123", "newPassword123");
|
||||||
|
User savedUser = userRepository.save(user);
|
||||||
|
|
||||||
|
assertNotNull(savedUser);
|
||||||
|
assertNotNull(savedUser.getPassword());
|
||||||
|
assertNull(savedUser.getRepeatedPassword());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenUser_whenSerializing_thenTransientFieldNotIgnored() throws JsonProcessingException {
|
||||||
|
User user = new User(1L, "user", "newPassword123", "newPassword123");
|
||||||
|
String result = new ObjectMapper().writeValueAsString(user);
|
||||||
|
|
||||||
|
assertThat(result, containsString("user"));
|
||||||
|
assertThat(result, containsString("repeatedPassword"));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
hibernate.hbm2ddl.auto=create-drop
|
||||||
|
|
||||||
|
spring.datasource.jdbcUrl=jdbc:h2:mem:testDb;DB_CLOSE_DELAY=-1
|
||||||
|
spring.datasource.username=sa
|
||||||
|
spring.datasource.password=sa
|
|
@ -1,2 +1,4 @@
|
||||||
## Relevant Articles
|
## Relevant Articles
|
||||||
- [Trigger Another Job from a Jenkins Pipeline](https://www.baeldung.com/ops/jenkins-pipeline-trigger-new-job)
|
- [Trigger Another Job from a Jenkins Pipeline](https://www.baeldung.com/ops/jenkins-pipeline-trigger-new-job)
|
||||||
|
- [Fixing the “No Such DSL method” Error in Jenkins Pipeline](https://www.baeldung.com/ops/jenkins-pipeline-no-such-dsl-method-error)
|
||||||
|
- [Jenkins Pipeline – Change to Another Folder](https://www.baeldung.com/ops/jenkins-pipeline-change-to-another-folder)
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
pipeline {
|
||||||
|
agent any
|
||||||
|
stages {
|
||||||
|
stage('Infinite Loop') {
|
||||||
|
steps {
|
||||||
|
script {
|
||||||
|
while (true) {
|
||||||
|
println 'This is an infinite loop!'
|
||||||
|
Thread.sleep(10000)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
Jenkins.instance.getItemByFullName("sampleZombieJob")
|
||||||
|
.getBuildByNumber(17)
|
||||||
|
.finish(hudson.model.Result.ABORTED, new java.io.IOException("Aborting build"));
|
|
@ -0,0 +1,6 @@
|
||||||
|
Thread.getAllStackTraces().keySet().each() {
|
||||||
|
if (it.name.contains('sampleZombieJob')) {
|
||||||
|
println "Stopping $it.name"
|
||||||
|
it.interrupt()
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
Thread.getAllStackTraces().keySet().each() {
|
||||||
|
if (it.name.contains('sampleZombieJob')) {
|
||||||
|
println "Stopping $it.name"
|
||||||
|
it.stop()
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,11 +1,15 @@
|
||||||
package com.baeldung.jsonvalidation;
|
package com.baeldung.jsonvalidation;
|
||||||
|
|
||||||
import com.fasterxml.jackson.core.JacksonException;
|
import com.fasterxml.jackson.core.JacksonException;
|
||||||
|
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.fasterxml.jackson.databind.json.JsonMapper;
|
||||||
|
|
||||||
public class JacksonValidator {
|
public class JacksonValidator {
|
||||||
|
|
||||||
final ObjectMapper mapper = new ObjectMapper();
|
final ObjectMapper mapper = JsonMapper.builder()
|
||||||
|
.enable(DeserializationFeature.FAIL_ON_TRAILING_TOKENS)
|
||||||
|
.build();
|
||||||
|
|
||||||
public boolean isValid(String json) {
|
public boolean isValid(String json) {
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -2,3 +2,4 @@
|
||||||
### Relevant Articles:
|
### Relevant Articles:
|
||||||
|
|
||||||
- [How to Parse an INI File in Java](https://www.baeldung.com/java-parse-ini-file)
|
- [How to Parse an INI File in Java](https://www.baeldung.com/java-parse-ini-file)
|
||||||
|
- [Using Watermarks with iText in Java](https://www.baeldung.com/java-watermarks-with-itext)
|
||||||
|
|
|
@ -76,7 +76,7 @@
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<org.mapstruct.version>1.4.2.Final</org.mapstruct.version>
|
<org.mapstruct.version>1.5.3.Final</org.mapstruct.version>
|
||||||
<springframework.version>4.3.4.RELEASE</springframework.version>
|
<springframework.version>4.3.4.RELEASE</springframework.version>
|
||||||
<maven.compiler.source>1.8</maven.compiler.source>
|
<maven.compiler.source>1.8</maven.compiler.source>
|
||||||
<maven.compiler.target>1.8</maven.compiler.target>
|
<maven.compiler.target>1.8</maven.compiler.target>
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
<module>microprofile</module>
|
<module>microprofile</module>
|
||||||
<module>msf4j</module>
|
<module>msf4j</module>
|
||||||
<module>open-liberty</module>
|
<module>open-liberty</module>
|
||||||
|
<module>rest-express</module>
|
||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
</project>
|
</project>
|
|
@ -0,0 +1,5 @@
|
||||||
|
## RestExpress
|
||||||
|
|
||||||
|
This module contains articles about RestExpress.
|
||||||
|
|
||||||
|
### Relevant articles
|
|
@ -0,0 +1,153 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<parent>
|
||||||
|
<artifactId>microservices-modules</artifactId>
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<version>1.0.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<name>rest-express</name>
|
||||||
|
<!--
|
||||||
|
To run the project: mvn clean package exec:java
|
||||||
|
* mongod must be running.
|
||||||
|
|
||||||
|
To create a project deployable assembly (zip file):
|
||||||
|
mvn clean package
|
||||||
|
mvn assembly:single
|
||||||
|
-->
|
||||||
|
<description>A Basic, MongoDB-backed Service Suite</description>
|
||||||
|
<url>https://github.com/RestExpress/RestExpress-Scaffold</url>
|
||||||
|
<version>1.0.0-SNAPSHOT</version>
|
||||||
|
<artifactId>rest-express</artifactId>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<RestExpress.plugin.version>0.3.3</RestExpress.plugin.version>
|
||||||
|
<metrics-graphite.version>3.1.2</metrics-graphite.version>
|
||||||
|
<HyperExpressPlugin.version>2.6</HyperExpressPlugin.version>
|
||||||
|
<RestExpress.version>0.11.3</RestExpress.version>
|
||||||
|
<Syntaxe.version>1.0</Syntaxe.version>
|
||||||
|
<repoexpress-mongodb.version>0.4.8</repoexpress-mongodb.version>
|
||||||
|
<junit4.version>4.11</junit4.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.strategicgains</groupId>
|
||||||
|
<artifactId>RestExpress</artifactId>
|
||||||
|
<version>${RestExpress.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.strategicgains</groupId>
|
||||||
|
<artifactId>Syntaxe</artifactId>
|
||||||
|
<version>${Syntaxe.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.strategicgains.repoexpress</groupId>
|
||||||
|
<artifactId>repoexpress-mongodb</artifactId>
|
||||||
|
<version>${repoexpress-mongodb.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.strategicgains.plugin-express</groupId>
|
||||||
|
<artifactId>CacheControlPlugin</artifactId>
|
||||||
|
<version>${RestExpress.plugin.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.strategicgains</groupId>
|
||||||
|
<artifactId>HyperExpressPlugin</artifactId>
|
||||||
|
<version>${HyperExpressPlugin.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.strategicgains.plugin-express</groupId>
|
||||||
|
<artifactId>MetricsPlugin</artifactId>
|
||||||
|
<version>${RestExpress.plugin.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.strategicgains.plugin-express</groupId>
|
||||||
|
<artifactId>SwaggerPlugin</artifactId>
|
||||||
|
<version>${RestExpress.plugin.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.strategicgains.plugin-express</groupId>
|
||||||
|
<artifactId>CORSPlugin</artifactId>
|
||||||
|
<version>${RestExpress.plugin.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.dropwizard.metrics</groupId>
|
||||||
|
<artifactId>metrics-graphite</artifactId>
|
||||||
|
<version>${metrics-graphite.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<version>${junit4.version}</version>
|
||||||
|
<type>jar</type>
|
||||||
|
<scope>test</scope>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>3.0</version>
|
||||||
|
<configuration>
|
||||||
|
<source>1.8</source>
|
||||||
|
<target>1.8</target>
|
||||||
|
<encoding>UTF-8</encoding>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.codehaus.mojo</groupId>
|
||||||
|
<artifactId>exec-maven-plugin</artifactId>
|
||||||
|
<version>1.2.1</version>
|
||||||
|
<configuration>
|
||||||
|
<mainClass>com.baeldung.restexpress.Main</mainClass>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-shade-plugin</artifactId>
|
||||||
|
<version>2.4.1</version>
|
||||||
|
<configuration>
|
||||||
|
<createDependencyReducedPom>false</createDependencyReducedPom>
|
||||||
|
<filters>
|
||||||
|
<filter>
|
||||||
|
<artifact>*:*</artifact>
|
||||||
|
</filter>
|
||||||
|
</filters>
|
||||||
|
</configuration>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<phase>package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>shade</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<transformers>
|
||||||
|
<transformer
|
||||||
|
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
|
||||||
|
<mainClass>com.baeldung.restexpress.Main</mainClass>
|
||||||
|
</transformer>
|
||||||
|
</transformers>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
<reporting>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.codehaus.mojo</groupId>
|
||||||
|
<artifactId>versions-maven-plugin</artifactId>
|
||||||
|
<version>2.0</version>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</reporting>
|
||||||
|
</project>
|
|
@ -0,0 +1,75 @@
|
||||||
|
package com.baeldung.restexpress;
|
||||||
|
|
||||||
|
import com.baeldung.restexpress.objectid.SampleOidEntityController;
|
||||||
|
import com.baeldung.restexpress.objectid.SampleOidEntityRepository;
|
||||||
|
import com.baeldung.restexpress.objectid.SampleOidEntityService;
|
||||||
|
import com.baeldung.restexpress.uuid.SampleUuidEntityController;
|
||||||
|
import com.baeldung.restexpress.uuid.SampleUuidEntityRepository;
|
||||||
|
import com.baeldung.restexpress.uuid.SampleUuidEntityService;
|
||||||
|
import com.strategicgains.repoexpress.mongodb.MongoConfig;
|
||||||
|
import com.strategicgains.restexpress.plugin.metrics.MetricsConfig;
|
||||||
|
import org.restexpress.RestExpress;
|
||||||
|
import org.restexpress.util.Environment;
|
||||||
|
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
public class Configuration
|
||||||
|
extends Environment {
|
||||||
|
private static final String DEFAULT_EXECUTOR_THREAD_POOL_SIZE = "20";
|
||||||
|
|
||||||
|
private static final String PORT_PROPERTY = "port";
|
||||||
|
private static final String BASE_URL_PROPERTY = "base.url";
|
||||||
|
private static final String EXECUTOR_THREAD_POOL_SIZE = "executor.threadPool.size";
|
||||||
|
|
||||||
|
private int port;
|
||||||
|
private String baseUrl;
|
||||||
|
private int executorThreadPoolSize;
|
||||||
|
private MetricsConfig metricsSettings;
|
||||||
|
|
||||||
|
private SampleUuidEntityController sampleUuidController;
|
||||||
|
private SampleOidEntityController sampleOidController;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void fillValues(Properties p) {
|
||||||
|
this.port = Integer.parseInt(p.getProperty(PORT_PROPERTY, String.valueOf(RestExpress.DEFAULT_PORT)));
|
||||||
|
this.baseUrl = p.getProperty(BASE_URL_PROPERTY, "http://localhost:" + String.valueOf(port));
|
||||||
|
this.executorThreadPoolSize = Integer.parseInt(p.getProperty(EXECUTOR_THREAD_POOL_SIZE, DEFAULT_EXECUTOR_THREAD_POOL_SIZE));
|
||||||
|
this.metricsSettings = new MetricsConfig(p);
|
||||||
|
MongoConfig mongo = new MongoConfig(p);
|
||||||
|
initialize(mongo);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initialize(MongoConfig mongo) {
|
||||||
|
SampleUuidEntityRepository samplesUuidRepository = new SampleUuidEntityRepository(mongo.getClient(), mongo.getDbName());
|
||||||
|
SampleUuidEntityService sampleUuidService = new SampleUuidEntityService(samplesUuidRepository);
|
||||||
|
sampleUuidController = new SampleUuidEntityController(sampleUuidService);
|
||||||
|
|
||||||
|
SampleOidEntityRepository samplesOidRepository = new SampleOidEntityRepository(mongo.getClient(), mongo.getDbName());
|
||||||
|
SampleOidEntityService sampleOidService = new SampleOidEntityService(samplesOidRepository);
|
||||||
|
sampleOidController = new SampleOidEntityController(sampleOidService);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPort() {
|
||||||
|
return port;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getBaseUrl() {
|
||||||
|
return baseUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getExecutorThreadPoolSize() {
|
||||||
|
return executorThreadPoolSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MetricsConfig getMetricsConfig() {
|
||||||
|
return metricsSettings;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SampleUuidEntityController getSampleUuidEntityController() {
|
||||||
|
return sampleUuidController;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SampleOidEntityController getSampleOidEntityController() {
|
||||||
|
return sampleOidController;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
package com.baeldung.restexpress;
|
||||||
|
|
||||||
|
public class Constants {
|
||||||
|
/**
|
||||||
|
* These define the URL parmaeters used in the route definition strings (e.g. '{userId}').
|
||||||
|
*/
|
||||||
|
public class Url {
|
||||||
|
//TODO: Your URL parameter names here...
|
||||||
|
public static final String SAMPLE_ID = "uuid";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* These define the route names used in naming each route definitions. These names are used
|
||||||
|
* to retrieve URL patterns within the controllers by name to create links in responses.
|
||||||
|
*/
|
||||||
|
public class Routes {
|
||||||
|
//TODO: Your Route names here...
|
||||||
|
public static final String SINGLE_UUID_SAMPLE = "sample.single.route.uuid";
|
||||||
|
public static final String SAMPLE_UUID_COLLECTION = "sample.collection.route.uuid";
|
||||||
|
public static final String SINGLE_OID_SAMPLE = "sample.single.route.oid";
|
||||||
|
public static final String SAMPLE_OID_COLLECTION = "sample.collection.route.oid";
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
package com.baeldung.restexpress;
|
||||||
|
|
||||||
|
import com.strategicgains.repoexpress.domain.Timestamped;
|
||||||
|
import com.strategicgains.util.date.DateAdapter;
|
||||||
|
import com.strategicgains.util.date.HttpHeaderTimestampAdapter;
|
||||||
|
import org.restexpress.Request;
|
||||||
|
import org.restexpress.Response;
|
||||||
|
import org.restexpress.pipeline.Postprocessor;
|
||||||
|
|
||||||
|
import static io.netty.handler.codec.http.HttpHeaders.Names.LAST_MODIFIED;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assigns the Last-Modified HTTP header on the response for GET responses, if applicable.
|
||||||
|
*
|
||||||
|
* @author toddf
|
||||||
|
* @since May 15, 2012
|
||||||
|
*/
|
||||||
|
public class LastModifiedHeaderPostprocessor
|
||||||
|
implements Postprocessor {
|
||||||
|
DateAdapter fmt = new HttpHeaderTimestampAdapter();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void process(Request request, Response response) {
|
||||||
|
if (!request.isMethodGet()) return;
|
||||||
|
if (!response.hasBody()) return;
|
||||||
|
|
||||||
|
Object body = response.getBody();
|
||||||
|
|
||||||
|
if (!response.hasHeader(LAST_MODIFIED) && body.getClass().isAssignableFrom(Timestamped.class)) {
|
||||||
|
response.addHeader(LAST_MODIFIED, fmt.format(((Timestamped) body).getUpdatedAt()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
package com.baeldung.restexpress;
|
||||||
|
|
||||||
|
import org.restexpress.util.Environment;
|
||||||
|
|
||||||
|
public class Main {
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
Configuration config = Environment.load(args, Configuration.class);
|
||||||
|
Server server = new Server(config);
|
||||||
|
server.start().awaitShutdown();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
package com.baeldung.restexpress;
|
||||||
|
|
||||||
|
import com.baeldung.restexpress.objectid.SampleOidEntity;
|
||||||
|
import com.baeldung.restexpress.uuid.SampleUuidEntity;
|
||||||
|
import com.strategicgains.hyperexpress.HyperExpress;
|
||||||
|
import com.strategicgains.hyperexpress.RelTypes;
|
||||||
|
import org.restexpress.RestExpress;
|
||||||
|
import org.restexpress.common.exception.ConfigurationException;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public abstract class Relationships {
|
||||||
|
private static Map<String, String> ROUTES;
|
||||||
|
|
||||||
|
public static void define(RestExpress server) {
|
||||||
|
ROUTES = server.getRouteUrlsByName();
|
||||||
|
|
||||||
|
HyperExpress.relationships()
|
||||||
|
.forCollectionOf(SampleUuidEntity.class)
|
||||||
|
.rel(RelTypes.SELF, href(Constants.Routes.SAMPLE_UUID_COLLECTION))
|
||||||
|
.withQuery("limit={limit}")
|
||||||
|
.withQuery("offset={offset}")
|
||||||
|
.rel(RelTypes.NEXT, href(Constants.Routes.SAMPLE_UUID_COLLECTION) + "?offset={nextOffset}")
|
||||||
|
.withQuery("limit={limit}")
|
||||||
|
.optional()
|
||||||
|
.rel(RelTypes.PREV, href(Constants.Routes.SAMPLE_UUID_COLLECTION) + "?offset={prevOffset}")
|
||||||
|
.withQuery("limit={limit}")
|
||||||
|
.optional()
|
||||||
|
|
||||||
|
.forClass(SampleUuidEntity.class)
|
||||||
|
.rel(RelTypes.SELF, href(Constants.Routes.SINGLE_UUID_SAMPLE))
|
||||||
|
.rel(RelTypes.UP, href(Constants.Routes.SAMPLE_UUID_COLLECTION))
|
||||||
|
|
||||||
|
.forCollectionOf(SampleOidEntity.class)
|
||||||
|
.rel(RelTypes.SELF, href(Constants.Routes.SAMPLE_OID_COLLECTION))
|
||||||
|
.withQuery("limit={limit}")
|
||||||
|
.withQuery("offset={offset}")
|
||||||
|
.rel(RelTypes.NEXT, href(Constants.Routes.SAMPLE_OID_COLLECTION) + "?offset={nextOffset}")
|
||||||
|
.withQuery("limit={limit}")
|
||||||
|
.optional()
|
||||||
|
.rel(RelTypes.PREV, href(Constants.Routes.SAMPLE_OID_COLLECTION) + "?offset={prevOffset}")
|
||||||
|
.withQuery("limit={limit}")
|
||||||
|
.optional()
|
||||||
|
|
||||||
|
.forClass(SampleOidEntity.class)
|
||||||
|
.rel(RelTypes.SELF, href(Constants.Routes.SINGLE_OID_SAMPLE))
|
||||||
|
.rel(RelTypes.UP, href(Constants.Routes.SAMPLE_OID_COLLECTION));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String href(String name) {
|
||||||
|
String href = ROUTES.get(name);
|
||||||
|
if (href == null) throw new ConfigurationException("Route name not found: " + name);
|
||||||
|
return href;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
package com.baeldung.restexpress;
|
||||||
|
|
||||||
|
import io.netty.handler.codec.http.HttpMethod;
|
||||||
|
import org.restexpress.RestExpress;
|
||||||
|
|
||||||
|
public abstract class Routes {
|
||||||
|
public static void define(Configuration config, RestExpress server) {
|
||||||
|
// TODO: Your routes here...
|
||||||
|
server.uri("/samples/uuid/{uuid}.{format}", config.getSampleUuidEntityController())
|
||||||
|
.method(HttpMethod.GET, HttpMethod.PUT, HttpMethod.DELETE)
|
||||||
|
.name(Constants.Routes.SINGLE_UUID_SAMPLE);
|
||||||
|
|
||||||
|
server.uri("/samples/uuid.{format}", config.getSampleUuidEntityController())
|
||||||
|
.action("readAll", HttpMethod.GET)
|
||||||
|
.method(HttpMethod.POST)
|
||||||
|
.name(Constants.Routes.SAMPLE_UUID_COLLECTION);
|
||||||
|
|
||||||
|
server.uri("/samples/oid/{uuid}.{format}", config.getSampleOidEntityController())
|
||||||
|
.method(HttpMethod.GET, HttpMethod.PUT, HttpMethod.DELETE)
|
||||||
|
.name(Constants.Routes.SINGLE_OID_SAMPLE);
|
||||||
|
|
||||||
|
server.uri("/samples/oid.{format}", config.getSampleOidEntityController())
|
||||||
|
.action("readAll", HttpMethod.GET)
|
||||||
|
.method(HttpMethod.POST)
|
||||||
|
.name(Constants.Routes.SAMPLE_OID_COLLECTION);
|
||||||
|
|
||||||
|
// or REGEX matching routes...
|
||||||
|
// server.regex("/some.regex", config.getRouteController());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,129 @@
|
||||||
|
package com.baeldung.restexpress;
|
||||||
|
|
||||||
|
import com.baeldung.restexpress.serialization.SerializationProvider;
|
||||||
|
import com.codahale.metrics.MetricFilter;
|
||||||
|
import com.codahale.metrics.MetricRegistry;
|
||||||
|
import com.codahale.metrics.graphite.Graphite;
|
||||||
|
import com.codahale.metrics.graphite.GraphiteReporter;
|
||||||
|
import com.strategicgains.repoexpress.adapter.Identifiers;
|
||||||
|
import com.strategicgains.repoexpress.exception.DuplicateItemException;
|
||||||
|
import com.strategicgains.repoexpress.exception.InvalidObjectIdException;
|
||||||
|
import com.strategicgains.repoexpress.exception.ItemNotFoundException;
|
||||||
|
import com.strategicgains.restexpress.plugin.cache.CacheControlPlugin;
|
||||||
|
import com.strategicgains.restexpress.plugin.cors.CorsHeaderPlugin;
|
||||||
|
import com.strategicgains.restexpress.plugin.metrics.MetricsConfig;
|
||||||
|
import com.strategicgains.restexpress.plugin.metrics.MetricsPlugin;
|
||||||
|
import com.strategicgains.restexpress.plugin.swagger.SwaggerPlugin;
|
||||||
|
import com.strategicgains.syntaxe.ValidationException;
|
||||||
|
import org.restexpress.Flags;
|
||||||
|
import org.restexpress.RestExpress;
|
||||||
|
import org.restexpress.exception.BadRequestException;
|
||||||
|
import org.restexpress.exception.ConflictException;
|
||||||
|
import org.restexpress.exception.NotFoundException;
|
||||||
|
import org.restexpress.pipeline.SimpleConsoleLogMessageObserver;
|
||||||
|
import org.restexpress.plugin.hyperexpress.HyperExpressPlugin;
|
||||||
|
import org.restexpress.plugin.hyperexpress.Linkable;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import static io.netty.handler.codec.http.HttpHeaders.Names.*;
|
||||||
|
import static org.restexpress.Flags.Auth.PUBLIC_ROUTE;
|
||||||
|
|
||||||
|
public class Server {
|
||||||
|
private static final String SERVICE_NAME = "TODO: Enter service name";
|
||||||
|
private static final Logger LOG = LoggerFactory.getLogger(SERVICE_NAME);
|
||||||
|
|
||||||
|
private RestExpress server;
|
||||||
|
private Configuration config;
|
||||||
|
private boolean isStarted = false;
|
||||||
|
|
||||||
|
public Server(Configuration config) {
|
||||||
|
this.config = config;
|
||||||
|
RestExpress.setDefaultSerializationProvider(new SerializationProvider());
|
||||||
|
Identifiers.UUID.useShortUUID(true);
|
||||||
|
|
||||||
|
this.server = new RestExpress()
|
||||||
|
.setName(SERVICE_NAME)
|
||||||
|
.setBaseUrl(config.getBaseUrl())
|
||||||
|
.setExecutorThreadCount(config.getExecutorThreadPoolSize())
|
||||||
|
.addMessageObserver(new SimpleConsoleLogMessageObserver());
|
||||||
|
|
||||||
|
Routes.define(config, server);
|
||||||
|
Relationships.define(server);
|
||||||
|
configurePlugins(config, server);
|
||||||
|
mapExceptions(server);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Server start() {
|
||||||
|
if (!isStarted) {
|
||||||
|
server.bind(config.getPort());
|
||||||
|
isStarted = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void awaitShutdown() {
|
||||||
|
if (isStarted) server.awaitShutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void shutdown() {
|
||||||
|
if (isStarted) server.shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void configurePlugins(Configuration config, RestExpress server) {
|
||||||
|
configureMetrics(config, server);
|
||||||
|
|
||||||
|
new SwaggerPlugin()
|
||||||
|
.flag(Flags.Auth.PUBLIC_ROUTE)
|
||||||
|
.register(server);
|
||||||
|
|
||||||
|
new CacheControlPlugin()
|
||||||
|
.register(server);
|
||||||
|
|
||||||
|
new HyperExpressPlugin(Linkable.class)
|
||||||
|
.register(server);
|
||||||
|
|
||||||
|
new CorsHeaderPlugin("*")
|
||||||
|
.flag(PUBLIC_ROUTE)
|
||||||
|
.allowHeaders(CONTENT_TYPE, ACCEPT, AUTHORIZATION, REFERER, LOCATION)
|
||||||
|
.exposeHeaders(LOCATION)
|
||||||
|
.register(server);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void configureMetrics(Configuration config, RestExpress server) {
|
||||||
|
MetricsConfig mc = config.getMetricsConfig();
|
||||||
|
|
||||||
|
if (mc.isEnabled()) {
|
||||||
|
MetricRegistry registry = new MetricRegistry();
|
||||||
|
new MetricsPlugin(registry)
|
||||||
|
.register(server);
|
||||||
|
|
||||||
|
if (mc.isGraphiteEnabled()) {
|
||||||
|
final Graphite graphite = new Graphite(new InetSocketAddress(mc.getGraphiteHost(), mc.getGraphitePort()));
|
||||||
|
final GraphiteReporter reporter = GraphiteReporter.forRegistry(registry)
|
||||||
|
.prefixedWith(mc.getPrefix())
|
||||||
|
.convertRatesTo(TimeUnit.SECONDS)
|
||||||
|
.convertDurationsTo(TimeUnit.MILLISECONDS)
|
||||||
|
.filter(MetricFilter.ALL)
|
||||||
|
.build(graphite);
|
||||||
|
reporter.start(mc.getPublishSeconds(), TimeUnit.SECONDS);
|
||||||
|
} else {
|
||||||
|
LOG.warn("*** Graphite Metrics Publishing is Disabled ***");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
LOG.warn("*** Metrics Generation is Disabled ***");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void mapExceptions(RestExpress server) {
|
||||||
|
server
|
||||||
|
.mapException(ItemNotFoundException.class, NotFoundException.class)
|
||||||
|
.mapException(DuplicateItemException.class, ConflictException.class)
|
||||||
|
.mapException(ValidationException.class, BadRequestException.class)
|
||||||
|
.mapException(InvalidObjectIdException.class, BadRequestException.class);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
package com.baeldung.restexpress.objectid;
|
||||||
|
|
||||||
|
import com.baeldung.restexpress.Constants;
|
||||||
|
import com.strategicgains.hyperexpress.annotation.BindToken;
|
||||||
|
import com.strategicgains.hyperexpress.annotation.TokenBindings;
|
||||||
|
import com.strategicgains.repoexpress.mongodb.AbstractMongodbEntity;
|
||||||
|
import org.restexpress.plugin.hyperexpress.Linkable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is a sample entity identified by a MongoDB ObjectID (instead of a UUID).
|
||||||
|
* It also contains createdAt and updatedAt properties that are automatically maintained
|
||||||
|
* by the persistence layer (SampleOidEntityRepository).
|
||||||
|
*/
|
||||||
|
@TokenBindings({
|
||||||
|
@BindToken(value = Constants.Url.SAMPLE_ID, field = "id")
|
||||||
|
})
|
||||||
|
public class SampleOidEntity
|
||||||
|
extends AbstractMongodbEntity
|
||||||
|
implements Linkable {
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
public SampleOidEntity() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,80 @@
|
||||||
|
package com.baeldung.restexpress.objectid;
|
||||||
|
|
||||||
|
import com.baeldung.restexpress.Constants;
|
||||||
|
import com.strategicgains.hyperexpress.builder.DefaultTokenResolver;
|
||||||
|
import com.strategicgains.hyperexpress.builder.DefaultUrlBuilder;
|
||||||
|
import com.strategicgains.hyperexpress.builder.UrlBuilder;
|
||||||
|
import com.strategicgains.repoexpress.mongodb.Identifiers;
|
||||||
|
import io.netty.handler.codec.http.HttpMethod;
|
||||||
|
import org.restexpress.Request;
|
||||||
|
import org.restexpress.Response;
|
||||||
|
import org.restexpress.common.query.QueryFilter;
|
||||||
|
import org.restexpress.common.query.QueryOrder;
|
||||||
|
import org.restexpress.common.query.QueryRange;
|
||||||
|
import org.restexpress.query.QueryFilters;
|
||||||
|
import org.restexpress.query.QueryOrders;
|
||||||
|
import org.restexpress.query.QueryRanges;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is the 'controller' layer, where HTTP details are converted to domain concepts and passed to the service layer.
|
||||||
|
* Then service layer response information is enhanced with HTTP details, if applicable, for the response.
|
||||||
|
* <p/>
|
||||||
|
* This controller demonstrates how to process an entity that is identified by a MongoDB ObjectId.
|
||||||
|
*/
|
||||||
|
public class SampleOidEntityController {
|
||||||
|
private static final UrlBuilder LOCATION_BUILDER = new DefaultUrlBuilder();
|
||||||
|
private SampleOidEntityService service;
|
||||||
|
|
||||||
|
public SampleOidEntityController(SampleOidEntityService sampleService) {
|
||||||
|
super();
|
||||||
|
this.service = sampleService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SampleOidEntity create(Request request, Response response) {
|
||||||
|
SampleOidEntity entity = request.getBodyAs(SampleOidEntity.class, "Resource details not provided");
|
||||||
|
SampleOidEntity saved = service.create(entity);
|
||||||
|
|
||||||
|
// Construct the response for create...
|
||||||
|
response.setResponseCreated();
|
||||||
|
|
||||||
|
// Include the Location header...
|
||||||
|
String locationPattern = request.getNamedUrl(HttpMethod.GET, Constants.Routes.SINGLE_OID_SAMPLE);
|
||||||
|
response.addLocationHeader(LOCATION_BUILDER.build(locationPattern, new DefaultTokenResolver()));
|
||||||
|
|
||||||
|
// Return the newly-created resource...
|
||||||
|
return saved;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SampleOidEntity read(Request request, Response response) {
|
||||||
|
String id = request.getHeader(Constants.Url.SAMPLE_ID, "No resource ID supplied");
|
||||||
|
SampleOidEntity entity = service.read(Identifiers.MONGOID.parse(id));
|
||||||
|
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<SampleOidEntity> readAll(Request request, Response response) {
|
||||||
|
QueryFilter filter = QueryFilters.parseFrom(request);
|
||||||
|
QueryOrder order = QueryOrders.parseFrom(request);
|
||||||
|
QueryRange range = QueryRanges.parseFrom(request, 20);
|
||||||
|
List<SampleOidEntity> entities = service.readAll(filter, range, order);
|
||||||
|
long count = service.count(filter);
|
||||||
|
response.setCollectionResponse(range, entities.size(), count);
|
||||||
|
return entities;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void update(Request request, Response response) {
|
||||||
|
String id = request.getHeader(Constants.Url.SAMPLE_ID, "No resource ID supplied");
|
||||||
|
SampleOidEntity entity = request.getBodyAs(SampleOidEntity.class, "Resource details not provided");
|
||||||
|
entity.setId(Identifiers.MONGOID.parse(id));
|
||||||
|
service.update(entity);
|
||||||
|
response.setResponseNoContent();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void delete(Request request, Response response) {
|
||||||
|
String id = request.getHeader(Constants.Url.SAMPLE_ID, "No resource ID supplied");
|
||||||
|
service.delete(Identifiers.MONGOID.parse(id));
|
||||||
|
response.setResponseNoContent();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
package com.baeldung.restexpress.objectid;
|
||||||
|
|
||||||
|
import com.mongodb.MongoClient;
|
||||||
|
import com.strategicgains.repoexpress.mongodb.MongodbEntityRepository;
|
||||||
|
|
||||||
|
public class SampleOidEntityRepository
|
||||||
|
extends MongodbEntityRepository<SampleOidEntity> {
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public SampleOidEntityRepository(MongoClient mongo, String dbName) {
|
||||||
|
super(mongo, dbName, SampleOidEntity.class);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
package com.baeldung.restexpress.objectid;
|
||||||
|
|
||||||
|
import com.strategicgains.repoexpress.domain.Identifier;
|
||||||
|
import com.strategicgains.syntaxe.ValidationEngine;
|
||||||
|
import org.restexpress.common.query.QueryFilter;
|
||||||
|
import org.restexpress.common.query.QueryOrder;
|
||||||
|
import org.restexpress.common.query.QueryRange;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is the 'service' or 'business logic' layer, where business logic, syntactic and semantic
|
||||||
|
* domain validation occurs, along with calls to the persistence layer.
|
||||||
|
*/
|
||||||
|
public class SampleOidEntityService {
|
||||||
|
private SampleOidEntityRepository samples;
|
||||||
|
|
||||||
|
public SampleOidEntityService(SampleOidEntityRepository samplesRepository) {
|
||||||
|
super();
|
||||||
|
this.samples = samplesRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SampleOidEntity create(SampleOidEntity entity) {
|
||||||
|
ValidationEngine.validateAndThrow(entity);
|
||||||
|
return samples.create(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SampleOidEntity read(Identifier id) {
|
||||||
|
return samples.read(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void update(SampleOidEntity entity) {
|
||||||
|
ValidationEngine.validateAndThrow(entity);
|
||||||
|
samples.update(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void delete(Identifier id) {
|
||||||
|
samples.delete(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<SampleOidEntity> readAll(QueryFilter filter, QueryRange range, QueryOrder order) {
|
||||||
|
return samples.readAll(filter, range, order);
|
||||||
|
}
|
||||||
|
|
||||||
|
public long count(QueryFilter filter) {
|
||||||
|
return samples.count(filter);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
package com.baeldung.restexpress.serialization;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.module.SimpleModule;
|
||||||
|
import com.strategicgains.hyperexpress.domain.hal.HalResource;
|
||||||
|
import com.strategicgains.hyperexpress.serialization.jackson.HalResourceDeserializer;
|
||||||
|
import com.strategicgains.hyperexpress.serialization.jackson.HalResourceSerializer;
|
||||||
|
import org.bson.types.ObjectId;
|
||||||
|
import org.restexpress.ContentType;
|
||||||
|
import org.restexpress.serialization.json.JacksonJsonProcessor;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class JsonSerializationProcessor
|
||||||
|
extends JacksonJsonProcessor {
|
||||||
|
public JsonSerializationProcessor() {
|
||||||
|
super();
|
||||||
|
addSupportedMediaTypes(ContentType.HAL_JSON);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void initializeModule(SimpleModule module) {
|
||||||
|
super.initializeModule(module);
|
||||||
|
// For UUID as entity identifiers...
|
||||||
|
module.addDeserializer(UUID.class, new UuidDeserializer());
|
||||||
|
module.addSerializer(UUID.class, new UuidSerializer());
|
||||||
|
|
||||||
|
// For MongoDB ObjectId as entity identifiers...
|
||||||
|
module.addDeserializer(ObjectId.class, new ObjectIdDeserializer());
|
||||||
|
module.addSerializer(ObjectId.class, new ObjectIdSerializer());
|
||||||
|
|
||||||
|
// Support HalResource (de)serialization.
|
||||||
|
module.addDeserializer(HalResource.class, new HalResourceDeserializer());
|
||||||
|
module.addSerializer(HalResource.class, new HalResourceSerializer());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
package com.baeldung.restexpress.serialization;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonParser;
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import com.fasterxml.jackson.databind.DeserializationContext;
|
||||||
|
import com.fasterxml.jackson.databind.JsonDeserializer;
|
||||||
|
import com.strategicgains.repoexpress.mongodb.Identifiers;
|
||||||
|
import org.bson.types.ObjectId;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class ObjectIdDeserializer
|
||||||
|
extends JsonDeserializer<ObjectId> {
|
||||||
|
@Override
|
||||||
|
public ObjectId deserialize(JsonParser json, DeserializationContext context)
|
||||||
|
throws IOException, JsonProcessingException {
|
||||||
|
return (ObjectId) Identifiers.MONGOID.parse(json.getText()).primaryKey();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
package com.baeldung.restexpress.serialization;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonGenerator;
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import com.fasterxml.jackson.databind.JsonSerializer;
|
||||||
|
import com.fasterxml.jackson.databind.SerializerProvider;
|
||||||
|
import org.bson.types.ObjectId;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class ObjectIdSerializer
|
||||||
|
extends JsonSerializer<ObjectId> {
|
||||||
|
@Override
|
||||||
|
public void serialize(ObjectId objectId, JsonGenerator json, SerializerProvider provider)
|
||||||
|
throws IOException, JsonProcessingException {
|
||||||
|
json.writeString(objectId.toString());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
package com.baeldung.restexpress.serialization;
|
||||||
|
|
||||||
|
import org.restexpress.response.ErrorResponseWrapper;
|
||||||
|
import org.restexpress.response.ResponseWrapper;
|
||||||
|
import org.restexpress.serialization.AbstractSerializationProvider;
|
||||||
|
import org.restexpress.serialization.SerializationProcessor;
|
||||||
|
|
||||||
|
public class SerializationProvider
|
||||||
|
extends AbstractSerializationProvider {
|
||||||
|
// SECTION: CONSTANTS
|
||||||
|
|
||||||
|
private static final SerializationProcessor JSON_SERIALIZER = new JsonSerializationProcessor();
|
||||||
|
private static final SerializationProcessor XML_SERIALIZER = new XmlSerializationProcessor();
|
||||||
|
private static final ResponseWrapper RESPONSE_WRAPPER = new ErrorResponseWrapper();
|
||||||
|
|
||||||
|
public SerializationProvider() {
|
||||||
|
super();
|
||||||
|
add(JSON_SERIALIZER, RESPONSE_WRAPPER, true);
|
||||||
|
add(XML_SERIALIZER, RESPONSE_WRAPPER);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SerializationProcessor json() {
|
||||||
|
return JSON_SERIALIZER;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SerializationProcessor xml() {
|
||||||
|
return XML_SERIALIZER;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
package com.baeldung.restexpress.serialization;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonParser;
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import com.fasterxml.jackson.databind.DeserializationContext;
|
||||||
|
import com.fasterxml.jackson.databind.JsonDeserializer;
|
||||||
|
import com.strategicgains.repoexpress.util.UuidConverter;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class UuidDeserializer
|
||||||
|
extends JsonDeserializer<UUID> {
|
||||||
|
@Override
|
||||||
|
public UUID deserialize(JsonParser json, DeserializationContext context)
|
||||||
|
throws IOException, JsonProcessingException {
|
||||||
|
return UuidConverter.parse(json.getText());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
package com.baeldung.restexpress.serialization;
|
||||||
|
|
||||||
|
import com.strategicgains.hyperexpress.annotation.TokenFormatter;
|
||||||
|
import com.strategicgains.repoexpress.util.UuidConverter;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class UuidFormatter
|
||||||
|
implements TokenFormatter {
|
||||||
|
@Override
|
||||||
|
public String format(Object field) {
|
||||||
|
return UuidConverter.format((UUID) field);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
package com.baeldung.restexpress.serialization;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonGenerator;
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import com.fasterxml.jackson.databind.JsonSerializer;
|
||||||
|
import com.fasterxml.jackson.databind.SerializerProvider;
|
||||||
|
import com.strategicgains.repoexpress.util.UuidConverter;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class UuidSerializer
|
||||||
|
extends JsonSerializer<UUID> {
|
||||||
|
@Override
|
||||||
|
public void serialize(UUID objectId, JsonGenerator json, SerializerProvider provider)
|
||||||
|
throws IOException, JsonProcessingException {
|
||||||
|
json.writeString(UuidConverter.format(objectId));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
package com.baeldung.restexpress.serialization;
|
||||||
|
|
||||||
|
import com.baeldung.restexpress.uuid.SampleUuidEntity;
|
||||||
|
import org.restexpress.serialization.xml.XstreamXmlProcessor;
|
||||||
|
|
||||||
|
public class XmlSerializationProcessor
|
||||||
|
extends XstreamXmlProcessor {
|
||||||
|
public XmlSerializationProcessor() {
|
||||||
|
super();
|
||||||
|
alias("sample", SampleUuidEntity.class);
|
||||||
|
// alias("element_name", Element.class);
|
||||||
|
// alias("element_name", Element.class);
|
||||||
|
// alias("element_name", Element.class);
|
||||||
|
// alias("element_name", Element.class);
|
||||||
|
registerConverter(new XstreamUuidConverter());
|
||||||
|
registerConverter(new XstreamOidConverter());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
package com.baeldung.restexpress.serialization;
|
||||||
|
|
||||||
|
import com.strategicgains.repoexpress.mongodb.Identifiers;
|
||||||
|
import com.thoughtworks.xstream.converters.SingleValueConverter;
|
||||||
|
import org.bson.types.ObjectId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author toddf
|
||||||
|
* @since Feb 16, 2011
|
||||||
|
*/
|
||||||
|
public class XstreamOidConverter
|
||||||
|
implements SingleValueConverter {
|
||||||
|
@SuppressWarnings("rawtypes")
|
||||||
|
@Override
|
||||||
|
public boolean canConvert(Class aClass) {
|
||||||
|
return ObjectId.class.isAssignableFrom(aClass);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object fromString(String value) {
|
||||||
|
return (ObjectId) Identifiers.MONGOID.parse(value).primaryKey();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString(Object objectId) {
|
||||||
|
return ((ObjectId) objectId).toString();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
package com.baeldung.restexpress.serialization;
|
||||||
|
|
||||||
|
import com.strategicgains.repoexpress.util.UuidConverter;
|
||||||
|
import com.thoughtworks.xstream.converters.SingleValueConverter;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author toddf
|
||||||
|
* @since Feb 16, 2011
|
||||||
|
*/
|
||||||
|
public class XstreamUuidConverter
|
||||||
|
implements SingleValueConverter {
|
||||||
|
@SuppressWarnings("rawtypes")
|
||||||
|
@Override
|
||||||
|
public boolean canConvert(Class aClass) {
|
||||||
|
return UUID.class.isAssignableFrom(aClass);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object fromString(String value) {
|
||||||
|
return UuidConverter.parse(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString(Object objectId) {
|
||||||
|
return UuidConverter.format((UUID) objectId);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
package com.baeldung.restexpress.uuid;
|
||||||
|
|
||||||
|
import com.baeldung.restexpress.Constants;
|
||||||
|
import com.baeldung.restexpress.serialization.UuidFormatter;
|
||||||
|
import com.strategicgains.hyperexpress.annotation.BindToken;
|
||||||
|
import com.strategicgains.hyperexpress.annotation.TokenBindings;
|
||||||
|
import com.strategicgains.repoexpress.mongodb.AbstractUuidMongodbEntity;
|
||||||
|
import org.restexpress.plugin.hyperexpress.Linkable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is a sample entity identified by a UUID (instead of a MongoDB ObjectID).
|
||||||
|
* It also contains createdAt and updatedAt properties that are automatically maintained
|
||||||
|
* by the persistence layer (SampleUuidEntityRepository).
|
||||||
|
*/
|
||||||
|
@TokenBindings({
|
||||||
|
@BindToken(value = Constants.Url.SAMPLE_ID, field = "id", formatter = UuidFormatter.class)
|
||||||
|
})
|
||||||
|
public class SampleUuidEntity
|
||||||
|
extends AbstractUuidMongodbEntity
|
||||||
|
implements Linkable {
|
||||||
|
public SampleUuidEntity() {
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,79 @@
|
||||||
|
package com.baeldung.restexpress.uuid;
|
||||||
|
|
||||||
|
import com.baeldung.restexpress.Constants;
|
||||||
|
import com.strategicgains.hyperexpress.builder.DefaultTokenResolver;
|
||||||
|
import com.strategicgains.hyperexpress.builder.DefaultUrlBuilder;
|
||||||
|
import com.strategicgains.hyperexpress.builder.UrlBuilder;
|
||||||
|
import com.strategicgains.repoexpress.adapter.Identifiers;
|
||||||
|
import io.netty.handler.codec.http.HttpMethod;
|
||||||
|
import org.restexpress.Request;
|
||||||
|
import org.restexpress.Response;
|
||||||
|
import org.restexpress.common.query.QueryFilter;
|
||||||
|
import org.restexpress.common.query.QueryOrder;
|
||||||
|
import org.restexpress.common.query.QueryRange;
|
||||||
|
import org.restexpress.query.QueryFilters;
|
||||||
|
import org.restexpress.query.QueryOrders;
|
||||||
|
import org.restexpress.query.QueryRanges;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is the 'controller' layer, where HTTP details are converted to domain concepts and passed to the service layer.
|
||||||
|
* Then service layer response information is enhanced with HTTP details, if applicable, for the response.
|
||||||
|
* <p/>
|
||||||
|
* This controller demonstrates how to process a MongoDB entity that is identified by a UUID.
|
||||||
|
*/
|
||||||
|
public class SampleUuidEntityController {
|
||||||
|
private static final UrlBuilder LOCATION_BUILDER = new DefaultUrlBuilder();
|
||||||
|
private SampleUuidEntityService service;
|
||||||
|
|
||||||
|
public SampleUuidEntityController(SampleUuidEntityService sampleService) {
|
||||||
|
super();
|
||||||
|
this.service = sampleService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SampleUuidEntity create(Request request, Response response) {
|
||||||
|
SampleUuidEntity entity = request.getBodyAs(SampleUuidEntity.class, "Resource details not provided");
|
||||||
|
SampleUuidEntity saved = service.create(entity);
|
||||||
|
|
||||||
|
// Construct the response for create...
|
||||||
|
response.setResponseCreated();
|
||||||
|
|
||||||
|
// Include the Location header...
|
||||||
|
String locationPattern = request.getNamedUrl(HttpMethod.GET, Constants.Routes.SINGLE_UUID_SAMPLE);
|
||||||
|
response.addLocationHeader(LOCATION_BUILDER.build(locationPattern, new DefaultTokenResolver()));
|
||||||
|
|
||||||
|
// Return the newly-created resource...
|
||||||
|
return saved;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SampleUuidEntity read(Request request, Response response) {
|
||||||
|
String id = request.getHeader(Constants.Url.SAMPLE_ID, "No resource ID supplied");
|
||||||
|
SampleUuidEntity entity = service.read(Identifiers.UUID.parse(id));
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<SampleUuidEntity> readAll(Request request, Response response) {
|
||||||
|
QueryFilter filter = QueryFilters.parseFrom(request);
|
||||||
|
QueryOrder order = QueryOrders.parseFrom(request);
|
||||||
|
QueryRange range = QueryRanges.parseFrom(request, 20);
|
||||||
|
List<SampleUuidEntity> entities = service.readAll(filter, range, order);
|
||||||
|
long count = service.count(filter);
|
||||||
|
response.setCollectionResponse(range, entities.size(), count);
|
||||||
|
return entities;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void update(Request request, Response response) {
|
||||||
|
String id = request.getHeader(Constants.Url.SAMPLE_ID, "No resource ID supplied");
|
||||||
|
SampleUuidEntity entity = request.getBodyAs(SampleUuidEntity.class, "Resource details not provided");
|
||||||
|
entity.setId(Identifiers.UUID.parse(id));
|
||||||
|
service.update(entity);
|
||||||
|
response.setResponseNoContent();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void delete(Request request, Response response) {
|
||||||
|
String id = request.getHeader(Constants.Url.SAMPLE_ID, "No resource ID supplied");
|
||||||
|
service.delete(Identifiers.UUID.parse(id));
|
||||||
|
response.setResponseNoContent();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
package com.baeldung.restexpress.uuid;
|
||||||
|
|
||||||
|
import com.mongodb.MongoClient;
|
||||||
|
import com.strategicgains.repoexpress.mongodb.MongodbUuidEntityRepository;
|
||||||
|
|
||||||
|
public class SampleUuidEntityRepository
|
||||||
|
extends MongodbUuidEntityRepository<SampleUuidEntity> {
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public SampleUuidEntityRepository(MongoClient mongo, String dbName) {
|
||||||
|
super(mongo, dbName, SampleUuidEntity.class);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
package com.baeldung.restexpress.uuid;
|
||||||
|
|
||||||
|
import com.strategicgains.repoexpress.domain.Identifier;
|
||||||
|
import com.strategicgains.syntaxe.ValidationEngine;
|
||||||
|
import org.restexpress.common.query.QueryFilter;
|
||||||
|
import org.restexpress.common.query.QueryOrder;
|
||||||
|
import org.restexpress.common.query.QueryRange;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is the 'service' or 'business logic' layer, where business logic, syntactic and semantic
|
||||||
|
* domain validation occurs, along with calls to the persistence layer.
|
||||||
|
*/
|
||||||
|
public class SampleUuidEntityService {
|
||||||
|
private SampleUuidEntityRepository samples;
|
||||||
|
|
||||||
|
public SampleUuidEntityService(SampleUuidEntityRepository samplesRepository) {
|
||||||
|
super();
|
||||||
|
this.samples = samplesRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SampleUuidEntity create(SampleUuidEntity entity) {
|
||||||
|
ValidationEngine.validateAndThrow(entity);
|
||||||
|
return samples.create(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SampleUuidEntity read(Identifier id) {
|
||||||
|
return samples.read(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void update(SampleUuidEntity entity) {
|
||||||
|
ValidationEngine.validateAndThrow(entity);
|
||||||
|
samples.update(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void delete(Identifier id) {
|
||||||
|
samples.delete(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<SampleUuidEntity> readAll(QueryFilter filter, QueryRange range, QueryOrder order) {
|
||||||
|
return samples.readAll(filter, range, order);
|
||||||
|
}
|
||||||
|
|
||||||
|
public long count(QueryFilter filter) {
|
||||||
|
return samples.count(filter);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
# Default is 8081
|
||||||
|
port = 8081
|
||||||
|
|
||||||
|
# The size of the executor thread pool (that can handle blocking back-end processing).
|
||||||
|
executor.threadPool.size = 20
|
||||||
|
|
||||||
|
# A MongoDB URI/Connection string
|
||||||
|
# see: http://docs.mongodb.org/manual/reference/connection-string/
|
||||||
|
mongodb.uri = mongodb://localhost:27017/scaffolding_mongodb
|
||||||
|
|
||||||
|
# The base URL, used as a prefix for links returned in data
|
||||||
|
# default is http://localhost:<port>
|
||||||
|
#base.url = http://localhost:8081
|
||||||
|
|
||||||
|
#Configuration for the MetricsPlugin/Graphite
|
||||||
|
metrics.isEnabled = true
|
||||||
|
#metrics.machineName =
|
||||||
|
metrics.prefix = web1.example.com
|
||||||
|
metrics.graphite.isEnabled = false
|
||||||
|
metrics.graphite.host = graphite.example.com
|
||||||
|
metrics.graphite.port = 2003
|
||||||
|
metrics.graphite.publishSeconds = 60
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue