Merge remote-tracking branch 'origin/master'

This commit is contained in:
alexandru.borza 2023-05-12 20:19:50 +03:00
commit 5c420784f5
2825 changed files with 38918 additions and 8860 deletions

10
.gitignore vendored
View File

@ -69,6 +69,7 @@ jmeter/src/main/resources/*-Basic*.csv
jmeter/src/main/resources/*-JMeter*.csv jmeter/src/main/resources/*-JMeter*.csv
jmeter/src/main/resources/*ReportsDashboard*.csv jmeter/src/main/resources/*ReportsDashboard*.csv
jmeter/src/main/resources/dashboard/*ReportsDashboard*.csv jmeter/src/main/resources/dashboard/*ReportsDashboard*.csv
jmeter/src/main/resources/*FileExtractionExample.csv
ninja/devDb.mv.db ninja/devDb.mv.db
@ -88,6 +89,7 @@ spring-soap/src/main/java/com/baeldung/springsoap/gen/
/report-*.json /report-*.json
transaction.log transaction.log
*-shell.log *-shell.log
customers.xml
apache-cxf/cxf-aegis/baeldung.xml apache-cxf/cxf-aegis/baeldung.xml
testing-modules/report-*.json testing-modules/report-*.json
@ -102,6 +104,7 @@ spring-boot-modules/spring-boot-react/frontend/build
spring-boot-modules/spring-boot-react/frontend/node spring-boot-modules/spring-boot-react/frontend/node
spring-boot-modules/spring-boot-react/frontend/yarn.lock spring-boot-modules/spring-boot-react/frontend/yarn.lock
spring-boot-modules/spring-boot-properties-3/*.log spring-boot-modules/spring-boot-properties-3/*.log
spring-boot-modules/spring-boot-properties-3/*.gz
# SDKMan # SDKMan
.sdkmanrc .sdkmanrc
@ -109,5 +112,12 @@ spring-boot-modules/spring-boot-properties-3/*.log
# Localstack # Localstack
**/.localstack **/.localstack
#libraries-2
libraries-2/employee*
libraries-2/src/test/resources/crawler4j/**
#web-modules/ninja #web-modules/ninja
devDb*.db devDb*.db
#jaxb
*.xjb

View File

@ -74,6 +74,10 @@ Building a single module
==================== ====================
To build a specific module, run the command: `mvn clean install` in the module directory. To build a specific module, run the command: `mvn clean install` in the module directory.
It can happen that your module is part of a parent module e.g. `parent-boot-1`,`parent-spring-5` etc, then you will need to build the parent module first so that you can build your module.
We have created a `parents` profile that you can use to build just the parent modules, just run the profile as:
`mvn clean install -Pparents`
Building modules from the root of the repository Building modules from the root of the repository
==================== ====================

View File

@ -36,7 +36,6 @@
</dependency> </dependency>
</dependencies> </dependencies>
<properties> <properties>
<akka.http.version>10.0.11</akka.http.version> <akka.http.version>10.0.11</akka.http.version>
<akka.stream.version>2.5.11</akka.stream.version> <akka.stream.version>2.5.11</akka.stream.version>

View File

@ -43,7 +43,7 @@
</dependencyManagement> </dependencyManagement>
<properties> <properties>
<spring.version>4.3.4.RELEASE</spring.version> <spring.version>5.3.25</spring.version>
<akka.version>2.4.14</akka.version> <akka.version>2.4.14</akka.version>
</properties> </properties>

View File

@ -0,0 +1,58 @@
package com.baeldung.algorithms.checktargetsum;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
public class CheckTargetSum {
public boolean isTargetSumExistNaive(int[] nums, int target) {
for (int i = 0; i < nums.length; i++) {
for (int j = i + 1; j < nums.length; j++) {
if (nums[i] + nums[j] == target) {
return true;
}
}
}
return false;
}
public boolean isTargetSumExistSorted(int[] nums, int target) {
Arrays.sort(nums);
int start = 0;
int end = nums.length - 1;
while (start < end) {
int sum = nums[start] + nums[end];
if (sum == target) {
return true;
}
if (sum < target) {
start++;
} else {
end--;
}
}
return false;
}
public boolean isTargetSumExistHashSet(int[] nums, int target) {
Set<Integer> hashSet = new HashSet<>();
for (int num : nums) {
int diff = target - num;
if (hashSet.contains(diff)) {
return true;
}
hashSet.add(num);
}
return false;
}
}

View File

@ -0,0 +1,46 @@
package com.baeldung.algorithms.checktargetsum;
import org.junit.Test;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
public class CheckTargetSumUnitTest {
private CheckTargetSum checkTargetSum = new CheckTargetSum();
private int[] nums = new int[] { 10, 5, 15, 7, 14, 1, 9 };
private int existingTarget = 6;
private int nonExistingTarget = 27;
@Test
public void givenArrayOfIntegers_whenTargetSumNaive_thenPairExists() {
assertTrue(checkTargetSum.isTargetSumExistNaive(nums, existingTarget));
}
@Test
public void givenArrayOfIntegers_whenTargetSumNaive_thenPairDoesNotExists() {
assertFalse(checkTargetSum.isTargetSumExistNaive(nums, nonExistingTarget));
}
@Test
public void givenArrayOfIntegers_whenTargetSumSorted_thenPairExists() {
assertTrue(checkTargetSum.isTargetSumExistNaive(nums, existingTarget));
}
@Test
public void givenArrayOfIntegers_whenTargetSumSorted_thenPairDoesNotExists() {
assertFalse(checkTargetSum.isTargetSumExistNaive(nums, nonExistingTarget));
}
@Test
public void givenArrayOfIntegers_whenTargetSumHashSet_thenPairExists() {
assertTrue(checkTargetSum.isTargetSumExistNaive(nums, existingTarget));
}
@Test
public void givenArrayOfIntegers_whenTargetSumHashSet_thenPairDoesNotExists() {
assertFalse(checkTargetSum.isTargetSumExistNaive(nums, nonExistingTarget));
}
}

View File

@ -1,4 +1,6 @@
### Relevant Articles: ### Relevant Articles:
- [Algorithm to Identify and Validate a Credit Card Number](https://www.baeldung.com/java-validate-cc-number) - [Algorithm to Identify and Validate a Credit Card Number](https://www.baeldung.com/java-validate-cc-number)
- [Find the N Most Frequent Elements in a Java Array](https://www.baeldung.com/java-n-most-frequent-elements-array)
- [Getting Pixel Array From Image in Java](https://www.baeldung.com/java-getting-pixel-array-from-image)
- More articles: [[<-- prev]](/algorithms-miscellaneous-6) - More articles: [[<-- prev]](/algorithms-miscellaneous-6)

View File

@ -0,0 +1,93 @@
package com.baeldung.algorithms.frequentelements;
import java.util.*;
import java.util.stream.Collectors;
public class MostFrequentElementsFinder {
public static List<Integer> findByHashMapAndPriorityQueue(Integer[] array, int n) {
Map<Integer, Integer> countMap = new HashMap<>();
// For each element i in the array, add it to the countMap and increment its count.
for (Integer i : array) {
countMap.put(i, countMap.getOrDefault(i, 0) + 1);
}
// Create a max heap (priority queue) that will prioritize elements with higher counts.
PriorityQueue<Integer> heap = new PriorityQueue<>(
(a, b) -> countMap.get(b) - countMap.get(a));
// Add all the unique elements in the array to the heap.
heap.addAll(countMap.keySet());
List<Integer> result = new ArrayList<>();
for (int i = 0; i < n && !heap.isEmpty(); i++) {
// Poll the highest-count element from the heap and add it to the result list.
result.add(heap.poll());
}
return result;
}
public static List<Integer> findByStream(Integer[] arr, int n) {
return Arrays.stream(arr).collect(Collectors.groupingBy(i -> i, Collectors.counting()))
.entrySet().stream()
.sorted(Collections.reverseOrder(Map.Entry.comparingByValue()))
.map(Map.Entry::getKey)
.limit(n)
.collect(Collectors.toList());
}
public static List<Integer> findByTreeMap(Integer[] arr, int n) {
// Create a TreeMap and use a reverse order comparator to sort the entries by frequency in descending order
Map<Integer, Integer> countMap = new TreeMap<>(Collections.reverseOrder());
for (int i : arr) {
countMap.put(i, countMap.getOrDefault(i, 0) + 1);
}
// Create a list of the map entries and sort them by value (i.e. by frequency) in descending order
List<Map.Entry<Integer, Integer>> sortedEntries = new ArrayList<>(countMap.entrySet());
sortedEntries.sort((e1, e2) -> e2.getValue().compareTo(e1.getValue()));
// Extract the n most frequent elements from the sorted list of entries
List<Integer> result = new ArrayList<>();
for (int i = 0; i < n && i < sortedEntries.size(); i++) {
result.add(sortedEntries.get(i).getKey());
}
return result;
}
public static List<Integer> findByBucketSort(Integer[] arr, int n) {
List<Integer> result = new ArrayList<>();
Map<Integer, Integer> freqMap = new HashMap<>();
List<Integer>[] bucket = new List[arr.length + 1];
// Loop through the input array and update the frequency count of each element in the HashMap
for (int num : arr) {
freqMap.put(num, freqMap.getOrDefault(num, 0) + 1);
}
// Loop through the HashMap and add each element to its corresponding bucket based on its frequency count
for (int num : freqMap.keySet()) {
int freq = freqMap.get(num);
if (bucket[freq] == null) {
bucket[freq] = new ArrayList<>();
}
bucket[freq].add(num);
}
// Loop through the bucket array in reverse order and add the elements to the result list
// until we have found the n most frequent elements
for (int i = bucket.length - 1; i >= 0 && result.size() < n; i--) {
if (bucket[i] != null) {
result.addAll(bucket[i]);
}
}
// Return a sublist of the result list containing only the first n elements
return result.subList(0, n);
}
}

View File

@ -0,0 +1,65 @@
package com.baeldung.algorithms.pixelarray;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
public class GetPixelArray {
public static int[][] get2DPixelArraySlow(BufferedImage sampleImage) {
int width = sampleImage.getWidth();
int height = sampleImage.getHeight();
int[][] result = new int[height][width];
for (int row = 0; row < height; row++) {
for (int col = 0; col < width; col++) {
result[row][col] = sampleImage.getRGB(col, row);
}
}
return result;
}
public static int[][] get2DPixelArrayFast(BufferedImage image) {
final byte[] pixelData = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();
final int width = image.getWidth();
final int height = image.getHeight();
final boolean hasAlphaChannel = image.getAlphaRaster() != null;
int[][] result = new int[height][width];
if (hasAlphaChannel) {
final int numberOfValues = 4;
for (int valueIndex = 0, row = 0, col = 0; valueIndex + numberOfValues - 1 < pixelData.length; valueIndex += numberOfValues) {
// Getting the values for each pixel from the pixelData array.
int argb = 0;
argb += (((int) pixelData[valueIndex] & 0xff) << 24); // alpha value
argb += ((int) pixelData[valueIndex + 1] & 0xff); // blue value
argb += (((int) pixelData[valueIndex + 2] & 0xff) << 8); // green value
argb += (((int) pixelData[valueIndex + 3] & 0xff) << 16); // red value
result[row][col] = argb;
col++;
if (col == width) {
col = 0;
row++;
}
}
} else {
final int numberOfValues = 3;
for (int valueIndex = 0, row = 0, col = 0; valueIndex + numberOfValues - 1 < pixelData.length; valueIndex += numberOfValues) {
int argb = 0;
argb += -16777216; // 255 alpha value (fully opaque)
argb += ((int) pixelData[valueIndex] & 0xff); // blue value
argb += (((int) pixelData[valueIndex + 1] & 0xff) << 8); // green value
argb += (((int) pixelData[valueIndex + 2] & 0xff) << 16); // red value
result[row][col] = argb;
col++;
if (col == width) {
col = 0;
row++;
}
}
}
return result;
}
}

View File

@ -0,0 +1,33 @@
package com.baeldung.algorithms.frequentelements;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Java6Assertions.assertThat;
public class MostFrequentElementsUnitTest {
private final Integer[] inputArray = {1, 2, 3, 4, 5, 5, 5, 6, 6, 7, 7, 7, 7, 8, 9, 9, 9, 9, 9};
private final int n = 3;
private final Integer[] outputArray = {9, 7, 5};
@Test
void givenIntegersArray_UseFindByHashMapAndPriorityQueueMethod_thenReturnMostFrequentElements() {
assertThat(MostFrequentElementsFinder.findByHashMapAndPriorityQueue(inputArray, n)).containsExactly(outputArray);
}
@Test
void givenIntegersArray_UseFindByBucketSortMethod_thenReturnMostFrequentElements() {
assertThat(MostFrequentElementsFinder.findByBucketSort(inputArray, n)).containsExactly(outputArray);
}
@Test
void givenIntegersArray_UseFindByStreamMethod_thenReturnMostFrequentElements() {
assertThat(MostFrequentElementsFinder.findByStream(inputArray, n)).containsExactly(outputArray);
}
@Test
void givenIntegersArray_UseFindByTreeMapMethod_thenReturnMostFrequentElements() {
assertThat(MostFrequentElementsFinder.findByTreeMap(inputArray, n)).containsExactly(outputArray);
}
}

View File

@ -0,0 +1,30 @@
package com.baeldung.algorithms.pixelarray;
import static com.baeldung.algorithms.pixelarray.GetPixelArray.get2DPixelArrayFast;
import static com.baeldung.algorithms.pixelarray.GetPixelArray.get2DPixelArraySlow;
import static org.junit.Assert.*;
import org.junit.Test;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
public class GetPixelArrayUnitTest {
@Test
public void givenImage_whenGetPixelArray_thenBothMethodsReturnEqualValues() {
BufferedImage sampleImage = null;
try {
sampleImage = ImageIO.read(new File("src/main/resources/images/sampleImage.jpg"));
} catch (IOException e) {
throw new RuntimeException(e);
}
int[][] firstResult = get2DPixelArraySlow(sampleImage);
int[][] secondResult = get2DPixelArrayFast(sampleImage);
assertTrue(Arrays.deepEquals(firstResult, secondResult));
}
}

View File

@ -21,7 +21,6 @@
</dependency> </dependency>
</dependencies> </dependencies>
<properties> <properties>
<auto-service.version>1.0-rc2</auto-service.version> <auto-service.version>1.0-rc2</auto-service.version>
</properties> </properties>

View File

@ -20,4 +20,8 @@
</dependency> </dependency>
</dependencies> </dependencies>
<properties>
<cxf.version>4.0.0</cxf.version>
</properties>
</project> </project>

View File

@ -23,6 +23,16 @@
<artifactId>cxf-rt-transports-http-jetty</artifactId> <artifactId>cxf-rt-transports-http-jetty</artifactId>
<version>${cxf.version}</version> <version>${cxf.version}</version>
</dependency> </dependency>
<dependency>
<groupId>jakarta.xml.ws</groupId>
<artifactId>jakarta.xml.ws-api</artifactId>
<version>${jakarta-xml.version}</version>
</dependency>
<dependency>
<groupId>jakarta.jws</groupId>
<artifactId>jakarta.jws-api</artifactId>
<version>${jakarta.jws.version}</version>
</dependency>
</dependencies> </dependencies>
<build> <build>
@ -37,4 +47,10 @@
</plugins> </plugins>
</build> </build>
<properties>
<cxf.version>4.0.0</cxf.version>
<jakarta-xml.version>4.0.0</jakarta-xml.version>
<jakarta.jws.version>3.0.0</jakarta.jws.version>
</properties>
</project> </project>

View File

@ -2,8 +2,8 @@ package com.baeldung.cxf.introduction;
import java.util.Map; import java.util.Map;
import javax.jws.WebService; import jakarta.jws.WebService;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; import jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
@WebService @WebService
public interface Baeldung { public interface Baeldung {

View File

@ -3,7 +3,7 @@ package com.baeldung.cxf.introduction;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.Map; import java.util.Map;
import javax.jws.WebService; import jakarta.jws.WebService;
@WebService(endpointInterface = "com.baeldung.cxf.introduction.Baeldung") @WebService(endpointInterface = "com.baeldung.cxf.introduction.Baeldung")
public class BaeldungImpl implements Baeldung { public class BaeldungImpl implements Baeldung {

View File

@ -1,6 +1,6 @@
package com.baeldung.cxf.introduction; package com.baeldung.cxf.introduction;
import javax.xml.ws.Endpoint; import jakarta.xml.ws.Endpoint;
public class Server { public class Server {
public static void main(String args[]) throws InterruptedException { public static void main(String args[]) throws InterruptedException {

View File

@ -1,6 +1,6 @@
package com.baeldung.cxf.introduction; package com.baeldung.cxf.introduction;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; import jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
@XmlJavaTypeAdapter(StudentAdapter.class) @XmlJavaTypeAdapter(StudentAdapter.class)
public interface Student { public interface Student {

View File

@ -1,6 +1,6 @@
package com.baeldung.cxf.introduction; package com.baeldung.cxf.introduction;
import javax.xml.bind.annotation.adapters.XmlAdapter; import jakarta.xml.bind.annotation.adapters.XmlAdapter;
public class StudentAdapter extends XmlAdapter<StudentImpl, Student> { public class StudentAdapter extends XmlAdapter<StudentImpl, Student> {
public StudentImpl marshal(Student student) throws Exception { public StudentImpl marshal(Student student) throws Exception {

View File

@ -1,6 +1,6 @@
package com.baeldung.cxf.introduction; package com.baeldung.cxf.introduction;
import javax.xml.bind.annotation.XmlType; import jakarta.xml.bind.annotation.XmlType;
@XmlType(name = "Student") @XmlType(name = "Student")
public class StudentImpl implements Student { public class StudentImpl implements Student {

View File

@ -3,8 +3,8 @@ package com.baeldung.cxf.introduction;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import javax.xml.bind.annotation.XmlElement; import jakarta.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType; import jakarta.xml.bind.annotation.XmlType;
@XmlType(name = "StudentMap") @XmlType(name = "StudentMap")
public class StudentMap { public class StudentMap {

View File

@ -3,7 +3,7 @@ package com.baeldung.cxf.introduction;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.Map; import java.util.Map;
import javax.xml.bind.annotation.adapters.XmlAdapter; import jakarta.xml.bind.annotation.adapters.XmlAdapter;
public class StudentMapAdapter extends XmlAdapter<StudentMap, Map<Integer, Student>> { public class StudentMapAdapter extends XmlAdapter<StudentMap, Map<Integer, Student>> {
public StudentMap marshal(Map<Integer, Student> boundMap) throws Exception { public StudentMap marshal(Map<Integer, Student> boundMap) throws Exception {

View File

@ -5,8 +5,8 @@ import static org.junit.Assert.assertEquals;
import java.util.Map; import java.util.Map;
import javax.xml.namespace.QName; import javax.xml.namespace.QName;
import javax.xml.ws.Service; import jakarta.xml.ws.Service;
import javax.xml.ws.soap.SOAPBinding; import jakarta.xml.ws.soap.SOAPBinding;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;

View File

@ -16,12 +16,28 @@
<dependency> <dependency>
<groupId>org.apache.cxf</groupId> <groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxrs</artifactId> <artifactId>cxf-rt-frontend-jaxrs</artifactId>
<version>${cxf.version}</version> <version>4.0.0</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.apache.cxf</groupId> <groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http-jetty</artifactId> <artifactId>cxf-rt-transports-http-jetty</artifactId>
<version>${cxf.version}</version> <version>4.0.0</version>
</dependency>
<dependency>
<groupId>jakarta.xml.ws</groupId>
<artifactId>jakarta.xml.ws-api</artifactId>
<version>${jakarta-xml.version}</version>
</dependency>
<dependency>
<groupId>jakarta.jws</groupId>
<artifactId>jakarta.jws-api</artifactId>
<version>${jakarta-jws.version}</version>
</dependency>
<dependency>
<groupId>jakarta.platform</groupId>
<artifactId>jakarta.jakartaee-web-api</artifactId>
<version>${jakarta-platform.version}</version>
<scope>compile</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.apache.httpcomponents</groupId> <groupId>org.apache.httpcomponents</groupId>
@ -50,6 +66,9 @@
<properties> <properties>
<httpclient.version>4.5.2</httpclient.version> <httpclient.version>4.5.2</httpclient.version>
<jakarta-xml.version>4.0.0</jakarta-xml.version>
<jakarta-jws.version>3.0.0</jakarta-jws.version>
<jakarta-platform.version>9.0.0</jakarta-platform.version>
</properties> </properties>
</project> </project>

View File

@ -1,8 +1,8 @@
package com.baeldung.cxf.jaxrs.implementation; package com.baeldung.cxf.jaxrs.implementation;
import javax.ws.rs.*; import jakarta.ws.rs.*;
import javax.ws.rs.core.Response; import jakarta.ws.rs.core.Response;
import javax.xml.bind.annotation.XmlRootElement; import jakarta.xml.bind.annotation.XmlRootElement;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;

View File

@ -1,7 +1,7 @@
package com.baeldung.cxf.jaxrs.implementation; package com.baeldung.cxf.jaxrs.implementation;
import javax.ws.rs.*; import jakarta.ws.rs.*;
import javax.ws.rs.core.Response; import jakarta.ws.rs.core.Response;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;

View File

@ -1,6 +1,6 @@
package com.baeldung.cxf.jaxrs.implementation; package com.baeldung.cxf.jaxrs.implementation;
import javax.xml.bind.annotation.XmlRootElement; import jakarta.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "Student") @XmlRootElement(name = "Student")
public class Student { public class Student {

View File

@ -7,7 +7,7 @@ import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.net.URL; import java.net.URL;
import javax.xml.bind.JAXB; import jakarta.xml.bind.JAXB;
import org.apache.http.HttpResponse; import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpDelete; import org.apache.http.client.methods.HttpDelete;

View File

@ -40,10 +40,22 @@
<artifactId>spring-webmvc</artifactId> <artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version> <version>${spring.version}</version>
</dependency> </dependency>
<dependency>
<groupId>com.sun.xml.ws</groupId>
<artifactId>jaxws-ri</artifactId>
<version>2.3.3</version>
<type>pom</type>
</dependency>
<dependency> <dependency>
<groupId>javax.servlet</groupId> <groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId> <artifactId>javax.servlet-api</artifactId>
<version>${javax.servlet-api.version}</version> <version>4.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency> </dependency>
</dependencies> </dependencies>
@ -103,8 +115,9 @@
</profiles> </profiles>
<properties> <properties>
<spring.version>4.3.4.RELEASE</spring.version> <spring.version>5.3.25</spring.version>
<cargo-maven2-plugin.version>1.6.1</cargo-maven2-plugin.version> <cargo-maven2-plugin.version>1.6.1</cargo-maven2-plugin.version>
<maven-war-plugin.version>3.3.2</maven-war-plugin.version>
</properties> </properties>
</project> </project>

View File

@ -23,6 +23,11 @@
<artifactId>cxf-rt-rs-sse</artifactId> <artifactId>cxf-rt-rs-sse</artifactId>
<version>${cxf-version}</version> <version>${cxf-version}</version>
</dependency> </dependency>
<dependency>
<groupId>jakarta.ws.rs</groupId>
<artifactId>jakarta.ws.rs-api</artifactId>
<version>${jakarta-ws.version}</version>
</dependency>
</dependencies> </dependencies>
<build> <build>
@ -55,7 +60,8 @@
</build> </build>
<properties> <properties>
<cxf-version>3.2.0</cxf-version> <cxf-version>4.0.0</cxf-version>
<jakarta-ws.version>3.1.0</jakarta-ws.version>
</properties> </properties>
</project> </project>

View File

@ -1,10 +1,10 @@
package com.baeldung.sse.jaxrs.client; package com.baeldung.sse.jaxrs.client;
import javax.ws.rs.client.Client; import jakarta.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder; import jakarta.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.WebTarget; import jakarta.ws.rs.client.WebTarget;
import javax.ws.rs.sse.InboundSseEvent; import jakarta.ws.rs.sse.InboundSseEvent;
import javax.ws.rs.sse.SseEventSource; import jakarta.ws.rs.sse.SseEventSource;
import java.util.function.Consumer; import java.util.function.Consumer;
public class SseClientApp { public class SseClientApp {

View File

@ -1,10 +1,10 @@
package com.baeldung.sse.jaxrs.client; package com.baeldung.sse.jaxrs.client;
import javax.ws.rs.client.Client; import jakarta.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder; import jakarta.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.WebTarget; import jakarta.ws.rs.client.WebTarget;
import javax.ws.rs.sse.InboundSseEvent; import jakarta.ws.rs.sse.InboundSseEvent;
import javax.ws.rs.sse.SseEventSource; import jakarta.ws.rs.sse.SseEventSource;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.function.Consumer; import java.util.function.Consumer;

View File

@ -15,16 +15,14 @@
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>javax.ws.rs</groupId> <groupId>jakarta.ws.rs</groupId>
<artifactId>javax.ws.rs-api</artifactId> <artifactId>jakarta.ws.rs-api</artifactId>
<version>${rs-api.version}</version> <version>${jakarta-ws.version}</version>
<scope>provided</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>javax.enterprise</groupId> <groupId>jakarta.enterprise</groupId>
<artifactId>cdi-api</artifactId> <artifactId>jakarta.enterprise.cdi-api</artifactId>
<version>${cdi-api.version}</version> <version>${jakarta-cdi-api}</version>
<scope>provided</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>javax.json.bind</groupId> <groupId>javax.json.bind</groupId>
@ -37,6 +35,11 @@
<build> <build>
<finalName>${project.artifactId}</finalName> <finalName>${project.artifactId}</finalName>
<plugins> <plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>${maven-war-plugin.version}</version>
</plugin>
<plugin> <plugin>
<groupId>net.wasdev.wlp.maven.plugins</groupId> <groupId>net.wasdev.wlp.maven.plugins</groupId>
<artifactId>liberty-maven-plugin</artifactId> <artifactId>liberty-maven-plugin</artifactId>
@ -78,9 +81,10 @@
<liberty-maven-plugin.version>2.4.2</liberty-maven-plugin.version> <liberty-maven-plugin.version>2.4.2</liberty-maven-plugin.version>
<failOnMissingWebXml>false</failOnMissingWebXml> <failOnMissingWebXml>false</failOnMissingWebXml>
<openliberty-version>18.0.0.2</openliberty-version> <openliberty-version>18.0.0.2</openliberty-version>
<rs-api.version>2.1</rs-api.version> <jakarta-ws.version>3.1.0</jakarta-ws.version>
<cdi-api.version>2.0</cdi-api.version> <jakarta-cdi-api>4.0.1</jakarta-cdi-api>
<bind-api.version>1.0</bind-api.version> <bind-api.version>1.0</bind-api.version>
<maven-war-plugin.version>3.3.2</maven-war-plugin.version>
</properties> </properties>
</project> </project>

View File

@ -1,7 +1,7 @@
package com.baeldung.sse.jaxrs; package com.baeldung.sse.jaxrs;
import javax.ws.rs.ApplicationPath; import jakarta.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application; import jakarta.ws.rs.core.Application;
@ApplicationPath("sse") @ApplicationPath("sse")
public class AppConfig extends Application { public class AppConfig extends Application {

View File

@ -1,15 +1,15 @@
package com.baeldung.sse.jaxrs; package com.baeldung.sse.jaxrs;
import javax.enterprise.context.ApplicationScoped; import jakarta.enterprise.context.ApplicationScoped;
import javax.inject.Inject; import jakarta.inject.Inject;
import javax.ws.rs.*; import jakarta.ws.rs.*;
import javax.ws.rs.core.Context; import jakarta.ws.rs.core.Context;
import javax.ws.rs.core.HttpHeaders; import jakarta.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType; import jakarta.ws.rs.core.MediaType;
import javax.ws.rs.sse.OutboundSseEvent; import jakarta.ws.rs.sse.OutboundSseEvent;
import javax.ws.rs.sse.Sse; import jakarta.ws.rs.sse.Sse;
import javax.ws.rs.sse.SseBroadcaster; import jakarta.ws.rs.sse.SseBroadcaster;
import javax.ws.rs.sse.SseEventSink; import jakarta.ws.rs.sse.SseEventSink;
@ApplicationScoped @ApplicationScoped
@Path("stock") @Path("stock")

View File

@ -1,11 +1,11 @@
package com.baeldung.sse.jaxrs; package com.baeldung.sse.jaxrs;
import javax.enterprise.context.ApplicationScoped; import jakarta.enterprise.context.ApplicationScoped;
import javax.enterprise.context.Initialized; import jakarta.enterprise.context.Initialized;
import javax.enterprise.event.Event; import jakarta.enterprise.event.Event;
import javax.enterprise.event.Observes; import jakarta.enterprise.event.Observes;
import javax.inject.Inject; import jakarta.inject.Inject;
import javax.inject.Named; import jakarta.inject.Named;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.RoundingMode; import java.math.RoundingMode;
import java.time.LocalDateTime; import java.time.LocalDateTime;

View File

@ -12,6 +12,6 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring
- [Reading an HTTP Response Body as a String in Java](https://www.baeldung.com/java-http-response-body-as-string) - [Reading an HTTP Response Body as a String in Java](https://www.baeldung.com/java-http-response-body-as-string)
- [How To Get Cookies From the Apache HttpClient Response](https://www.baeldung.com/java-apache-httpclient-cookies) - [How To Get Cookies From the Apache HttpClient Response](https://www.baeldung.com/java-apache-httpclient-cookies)
- [Enabling Logging for Apache HttpClient](https://www.baeldung.com/apache-httpclient-enable-logging) - [Enabling Logging for Apache HttpClient](https://www.baeldung.com/apache-httpclient-enable-logging)
- [Expand Shortened URLs with Apache HttpClient](https://www.baeldung.com/apache-httpclient-expand-url)
- [Apache HttpClient vs. CloseableHttpClient](https://www.baeldung.com/apache-httpclient-vs-closeablehttpclient) - [Apache HttpClient vs. CloseableHttpClient](https://www.baeldung.com/apache-httpclient-vs-closeablehttpclient)
- [Expand Shortened URLs with Apache HttpClient](https://www.baeldung.com/apache-httpclient-expand-url)
- More articles: [[<-- prev]](../apache-httpclient) - More articles: [[<-- prev]](../apache-httpclient)

View File

@ -21,17 +21,6 @@
<version>${commons-lang3.version}</version> <version>${commons-lang3.version}</version>
</dependency> </dependency>
<!-- http client --> <!-- http client -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>${httpclient.version}</version>
<exclusions>
<exclusion>
<artifactId>commons-logging</artifactId>
<groupId>commons-logging</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency> <dependency>
<groupId>org.apache.httpcomponents.client5</groupId> <groupId>org.apache.httpcomponents.client5</groupId>
<artifactId>httpclient5</artifactId> <artifactId>httpclient5</artifactId>
@ -97,8 +86,7 @@
<properties> <properties>
<assertj.version>3.22.0</assertj.version> <assertj.version>3.22.0</assertj.version>
<mockserver.version>5.11.2</mockserver.version> <mockserver.version>5.11.2</mockserver.version>
<httpclient.version>4.5.8</httpclient.version> <httpclient5.version>5.2.1</httpclient5.version>
<httpclient5.version>5.2</httpclient5.version>
<maven.compiler.source.version>11</maven.compiler.source.version> <maven.compiler.source.version>11</maven.compiler.source.version>
<maven.compiler.target.version>11</maven.compiler.target.version> <maven.compiler.target.version>11</maven.compiler.target.version>
<spring-boot.version>2.1.7.RELEASE</spring-boot.version> <spring-boot.version>2.1.7.RELEASE</spring-boot.version>

View File

@ -23,7 +23,7 @@ import java.io.IOException;
class HttpClientGettingCookieValueUnitTest { 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.github.com/";
@Test @Test
void whenSettingCustomCookieOnTheRequest_thenGettingTheSameCookieFromTheResponse() throws IOException { void whenSettingCustomCookieOnTheRequest_thenGettingTheSameCookieFromTheResponse() throws IOException {

View File

@ -0,0 +1,126 @@
package com.baeldung.httpclient.expandUrl;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import java.io.IOException;
import java.util.List;
import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.hc.client5.http.classic.methods.HttpHead;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
import org.apache.hc.core5.http.Header;
import org.apache.hc.core5.http.HttpHeaders;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
class HttpClientExpandUrlLiveTest {
private static CloseableHttpClient httpClient;
@BeforeAll
static void setup() {
httpClient = HttpClientBuilder.create()
.disableRedirectHandling()
.build();
}
@AfterAll
static void tearDown() throws IOException {
if (httpClient != null) {
httpClient.close();
}
}
@Test
void givenShortenedOnce_whenUrlIsExpanded_thenCorrectResult() throws IOException {
final String expectedResult = "https://www.baeldung.com/rest-versioning";
final String actualResult = expandSingleLevel("http://bit.ly/3LScTri");
assertThat(actualResult, equalTo(expectedResult));
}
@Test
void givenShortenedMultiple_whenUrlIsExpanded_thenCorrectResult() throws IOException {
final String expectedResult = "https://www.baeldung.com/rest-versioning";
final String actualResult = expand("http://t.co/e4rDDbnzmk");
assertThat(actualResult, equalTo(expectedResult));
}
private String expand(final String urlArg) throws IOException {
String originalUrl = urlArg;
String newUrl = expandSingleLevel(originalUrl);
while (!originalUrl.equals(newUrl)) {
originalUrl = newUrl;
newUrl = expandSingleLevel(originalUrl);
}
return newUrl;
}
final String expandSafe(final String urlArg) throws IOException {
String originalUrl = urlArg;
String newUrl = expandSingleLevelSafe(originalUrl).getRight();
final List<String> alreadyVisited = Lists.newArrayList(originalUrl, newUrl);
while (!originalUrl.equals(newUrl)) {
originalUrl = newUrl;
final Pair<Integer, String> statusAndUrl = expandSingleLevelSafe(originalUrl);
newUrl = statusAndUrl.getRight();
final boolean isRedirect = statusAndUrl.getLeft() == 301 || statusAndUrl.getLeft() == 302;
if (isRedirect && alreadyVisited.contains(newUrl)) {
throw new IllegalStateException("Likely a redirect loop");
}
alreadyVisited.add(newUrl);
}
return newUrl;
}
private Pair<Integer, String> expandSingleLevelSafe(final String url) throws IOException {
try {
HttpHead request = new HttpHead(url);
Pair<Integer, String> resp = httpClient.execute(request, response -> {
final int statusCode = response.getCode();
if (statusCode != 301 && statusCode != 302) {
return new ImmutablePair<>(statusCode, url);
}
final Header[] headers = response.getHeaders(HttpHeaders.LOCATION);
Preconditions.checkState(headers.length == 1);
final String newUrl = headers[0].getValue();
return new ImmutablePair<>(statusCode, newUrl);
});
return resp;
} catch (final IllegalArgumentException uriEx) {
return new ImmutablePair<>(500, url);
}
}
private String expandSingleLevel(final String url) throws IOException {
try {
HttpHead request = new HttpHead(url);
String expandedUrl = httpClient.execute(request, response -> {
final int statusCode = response.getCode();
if (statusCode != 301 && statusCode != 302) {
return url;
}
final Header[] headers = response.getHeaders(HttpHeaders.LOCATION);
Preconditions.checkState(headers.length == 1);
return headers[0].getValue();
});
return expandedUrl;
} catch (final IllegalArgumentException uriEx) {
return url;
}
}
}

View File

@ -1,37 +1,39 @@
package com.baeldung.httpclient.httpclient; package com.baeldung.httpclient.httpclient;
import static org.assertj.core.api.Assertions.assertThat;
import java.io.IOException;
import org.apache.hc.client5.http.classic.HttpClient; import org.apache.hc.client5.http.classic.HttpClient;
import org.apache.hc.client5.http.classic.methods.HttpGet; import org.apache.hc.client5.http.classic.methods.HttpGet;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient; import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
import org.apache.hc.client5.http.impl.classic.HttpClientBuilder; import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
import org.apache.hc.client5.http.impl.classic.HttpClients; import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.core5.http.HttpEntity; import org.apache.hc.core5.http.HttpEntity;
import org.apache.hc.core5.http.HttpResponse;
import org.apache.hc.core5.http.HttpStatus; import org.apache.hc.core5.http.HttpStatus;
import org.apache.hc.core5.http.io.entity.EntityUtils; import org.apache.hc.core5.http.io.entity.EntityUtils;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import java.io.IOException;
import static org.assertj.core.api.Assertions.assertThat;
class ApacheHttpClientUnitTest extends GetRequestMockServer { class ApacheHttpClientUnitTest extends GetRequestMockServer {
@Test @Test
void givenDeveloperUsedHttpClient_whenExecutingGetRequest_thenStatusIsOkButSonarReportsAnIssue() throws IOException { void givenDeveloperUsedHttpClient_whenExecutingGetRequest_thenStatusIsOkButSonarReportsAnIssue() throws IOException {
HttpClient httpClient = HttpClients.createDefault(); HttpClient httpClient = HttpClients.createDefault();
HttpGet httpGet = new HttpGet(serviceOneUrl); HttpGet httpGet = new HttpGet(serviceOneUrl);
HttpResponse response = httpClient.execute(httpGet); httpClient.execute(httpGet, response -> {
assertThat(response.getCode()).isEqualTo(HttpStatus.SC_OK); assertThat(response.getCode()).isEqualTo(HttpStatus.SC_OK);
return response;
});
} }
@Test @Test
void givenDeveloperUsedCloseableHttpClient_whenExecutingGetRequest_thenStatusIsOk() throws IOException { void givenDeveloperUsedCloseableHttpClient_whenExecutingGetRequest_thenStatusIsOk() throws IOException {
try (CloseableHttpClient httpClient = HttpClients.createDefault()) { try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
HttpGet httpGet = new HttpGet(serviceOneUrl); HttpGet httpGet = new HttpGet(serviceOneUrl);
HttpResponse response = httpClient.execute(httpGet); httpClient.execute(httpGet, response -> {
assertThat(response.getCode()).isEqualTo(HttpStatus.SC_OK); assertThat(response.getCode()).isEqualTo(HttpStatus.SC_OK);
return response;
});
} }
} }
@ -39,20 +41,10 @@ class ApacheHttpClientUnitTest extends GetRequestMockServer {
void givenDeveloperUsedHttpClientBuilder_whenExecutingGetRequest_thenStatusIsOk() throws IOException { void givenDeveloperUsedHttpClientBuilder_whenExecutingGetRequest_thenStatusIsOk() throws IOException {
try (CloseableHttpClient httpClient = HttpClientBuilder.create().build()) { try (CloseableHttpClient httpClient = HttpClientBuilder.create().build()) {
HttpGet httpGet = new HttpGet(serviceOneUrl); HttpGet httpGet = new HttpGet(serviceOneUrl);
HttpResponse response = httpClient.execute(httpGet); httpClient.execute(httpGet, response -> {
assertThat(response.getCode()).isEqualTo(HttpStatus.SC_OK); assertThat(response.getCode()).isEqualTo(HttpStatus.SC_OK);
} return response;
} });
@Test
void givenDeveloperUsedCloseableHttpResponse_whenExecutingGetRequest_thenStatusIsOk() throws IOException {
try (CloseableHttpClient httpClient = HttpClientBuilder.create().build()) {
HttpGet httpGet = new HttpGet(serviceOneUrl);
try (CloseableHttpResponse response = httpClient.execute(httpGet)) {
HttpEntity entity = response.getEntity();
EntityUtils.consume(entity);
assertThat(response.getCode()).isEqualTo(HttpStatus.SC_OK);
}
} }
} }
@ -60,18 +52,20 @@ class ApacheHttpClientUnitTest extends GetRequestMockServer {
void givenDeveloperUsedSingleClient_whenExecutingTwoGetRequest_thenStatusIsOk() throws IOException { void givenDeveloperUsedSingleClient_whenExecutingTwoGetRequest_thenStatusIsOk() throws IOException {
try (CloseableHttpClient httpClient = HttpClientBuilder.create().build()) { try (CloseableHttpClient httpClient = HttpClientBuilder.create().build()) {
HttpGet httpGetOne = new HttpGet(serviceOneUrl); HttpGet httpGetOne = new HttpGet(serviceOneUrl);
try (CloseableHttpResponse responseOne = httpClient.execute(httpGetOne)) { httpClient.execute(httpGetOne, responseOne -> {
HttpEntity entityOne = responseOne.getEntity(); HttpEntity entityOne = responseOne.getEntity();
EntityUtils.consume(entityOne); EntityUtils.consume(entityOne);
assertThat(responseOne.getCode()).isEqualTo(HttpStatus.SC_OK); assertThat(responseOne.getCode()).isEqualTo(HttpStatus.SC_OK);
} return responseOne;
});
HttpGet httpGetTwo = new HttpGet(serviceTwoUrl); HttpGet httpGetTwo = new HttpGet(serviceTwoUrl);
try (CloseableHttpResponse responseTwo = httpClient.execute(httpGetTwo)) { httpClient.execute(httpGetTwo, responseTwo -> {
HttpEntity entityTwo = responseTwo.getEntity(); HttpEntity entityTwo = httpGetTwo.getEntity();
EntityUtils.consume(entityTwo); EntityUtils.consume(entityTwo);
assertThat(responseTwo.getCode()).isEqualTo(HttpStatus.SC_OK); assertThat(responseTwo.getCode()).isEqualTo(HttpStatus.SC_OK);
} return responseTwo;
});
} }
} }

View File

@ -0,0 +1,40 @@
package com.baeldung.httpclient;
import static org.assertj.core.api.Assertions.assertThat;
import java.io.IOException;
import org.apache.hc.client5.http.classic.methods.HttpGet;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.core5.http.HttpEntity;
import org.apache.hc.core5.http.HttpStatus;
import org.junit.jupiter.api.Test;
class HttpClientCancelRequestLiveTest {
private static final String SAMPLE_URL = "http://www.github.com";
@Test
void whenRequestIsCanceled_thenCorrect() throws IOException {
HttpGet request = new HttpGet(SAMPLE_URL);
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
httpClient.execute(request, response -> {
HttpEntity entity = response.getEntity();
System.out.println("----------------------------------------");
System.out.println(response.getCode());
if (entity != null) {
System.out.println("Response content length: " + entity.getContentLength());
}
System.out.println("----------------------------------------");
// Do not feel like reading the response body
// Call abort on the request object
request.abort();
assertThat(response.getCode()).isEqualTo(HttpStatus.SC_OK);
return response;
});
}
}
}

View File

@ -1,8 +1,8 @@
package com.baeldung.httpclient.base; package com.baeldung.httpclient.base;
import com.baeldung.httpclient.ResponseUtil; import com.baeldung.httpclient.ResponseUtil;
import org.apache.http.Header; import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHeaders; import org.apache.http.HttpHeaders;
import org.apache.http.client.config.RequestConfig; import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.CloseableHttpResponse;
@ -10,7 +10,6 @@ import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.ConnectTimeoutException; import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.BasicHttpClientConnectionManager; import org.apache.http.impl.conn.BasicHttpClientConnectionManager;
import org.junit.After; import org.junit.After;
import org.junit.Before; import org.junit.Before;
@ -73,30 +72,4 @@ public class HttpClientLiveTest {
assertThat(headers, not(emptyArray())); assertThat(headers, not(emptyArray()));
} }
// tests - cancel request
@Test
public final void whenRequestIsCanceled_thenCorrect() throws IOException {
instance = HttpClients.custom().build();
final HttpGet request = new HttpGet(SAMPLE_URL);
response = instance.execute(request);
try {
final HttpEntity entity = response.getEntity();
System.out.println("----------------------------------------");
System.out.println(response.getStatusLine());
if (entity != null) {
System.out.println("Response content length: " + entity.getContentLength());
}
System.out.println("----------------------------------------");
// Do not feel like reading the response body
// Call abort on the request object
request.abort();
} finally {
response.close();
}
}
} }

View File

@ -1,12 +1,16 @@
## Apache HttpClient ## Apache HttpClient 4
This module contains articles about Apache HttpClient 4.5 This module contains articles about Apache HttpClient 4.5
### Relevant Articles ### Relevant Articles
- [Apache HttpClient Cancel Request](https://www.baeldung.com/httpclient-cancel-request)
- [Apache HttpClient with SSL](https://www.baeldung.com/httpclient-ssl) - [Apache HttpClient with SSL](https://www.baeldung.com/httpclient-ssl)
- [Apache HttpClient Timeout](https://www.baeldung.com/httpclient-timeout) - [Apache HttpClient Timeout](https://www.baeldung.com/httpclient-timeout)
- [Custom HTTP Header with the Apache HttpClient](https://www.baeldung.com/httpclient-custom-http-header) - [Custom HTTP Header with the Apache HttpClient](https://www.baeldung.com/httpclient-custom-http-header)
- [Apache HttpClient vs. CloseableHttpClient](https://www.baeldung.com/apache-httpclient-vs-closeablehttpclient)
- [Expand Shortened URLs with Apache HttpClient](https://www.baeldung.com/apache-httpclient-expand-url)
- [Retrying Requests using Apache HttpClient](https://www.baeldung.com/java-retrying-requests-using-apache-httpclient)
### Running the Tests ### Running the Tests
To run the live tests, use the command: mvn clean install -Plive To run the live tests, use the command: mvn clean install -Plive

View File

@ -3,9 +3,9 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<artifactId>httpclient4</artifactId> <artifactId>apache-httpclient4</artifactId>
<version>0.1-SNAPSHOT</version> <version>0.1-SNAPSHOT</version>
<name>httpclient4</name> <name>apache-httpclient4</name>
<packaging>war</packaging> <packaging>war</packaging>
<parent> <parent>
@ -152,6 +152,11 @@
</exclusion> </exclusion>
</exclusions> </exclusions>
</dependency> </dependency>
<dependency>
<groupId>org.mock-server</groupId>
<artifactId>mockserver-netty</artifactId>
<version>${mockserver.version}</version>
</dependency>
<dependency> <dependency>
<groupId>com.github.tomakehurst</groupId> <groupId>com.github.tomakehurst</groupId>
<artifactId>wiremock</artifactId> <artifactId>wiremock</artifactId>
@ -284,8 +289,10 @@
<wiremock.version>2.5.1</wiremock.version> <wiremock.version>2.5.1</wiremock.version>
<httpcore.version>4.4.16</httpcore.version> <httpcore.version>4.4.16</httpcore.version>
<httpclient.version>4.5.14</httpclient.version> <httpclient.version>4.5.14</httpclient.version>
<mockserver.version>5.11.2</mockserver.version>
<!-- maven plugins --> <!-- maven plugins -->
<cargo-maven2-plugin.version>1.6.1</cargo-maven2-plugin.version> <cargo-maven2-plugin.version>1.6.1</cargo-maven2-plugin.version>
<maven-war-plugin.version>3.3.2</maven-war-plugin.version>
</properties> </properties>
</project> </project>

View File

@ -0,0 +1,57 @@
package com.baeldung.httpclient;
import java.io.IOException;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
public class HttpClientCancelRequestV4LiveTest {
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);
}
@Test
public final void whenRequestIsCanceled_thenCorrect() throws IOException {
instance = HttpClients.custom().build();
final HttpGet request = new HttpGet(SAMPLE_URL);
response = instance.execute(request);
try {
final HttpEntity entity = response.getEntity();
System.out.println("----------------------------------------");
System.out.println(response.getStatusLine());
if (entity != null) {
System.out.println("Response content length: " + entity.getContentLength());
}
System.out.println("----------------------------------------");
// Do not feel like reading the response body
// Call abort on the request object
request.abort();
} finally {
response.close();
}
}
}

View File

@ -0,0 +1,31 @@
package com.baeldung.httpclient.httpclient;
import static org.assertj.core.api.Assertions.assertThat;
import java.io.IOException;
import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.junit.jupiter.api.Test;
class ApacheHttpClientUnitTest extends GetRequestMockServer {
@Test
void givenDeveloperUsedCloseableHttpResponse_whenExecutingGetRequest_thenStatusIsOk() throws IOException {
try (CloseableHttpClient httpClient = HttpClientBuilder.create().build()) {
HttpGet httpGet = new HttpGet(serviceOneUrl);
try (CloseableHttpResponse response = httpClient.execute(httpGet)) {
HttpEntity entity = response.getEntity();
EntityUtils.consume(entity);
assertThat(response.getStatusLine().getStatusCode()).isEqualTo(HttpStatus.SC_OK);
}
}
}
}

View File

@ -0,0 +1,78 @@
package com.baeldung.httpclient.httpclient;
import org.apache.http.HttpStatus;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.mockserver.client.MockServerClient;
import org.mockserver.integration.ClientAndServer;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.URISyntaxException;
import static org.mockserver.integration.ClientAndServer.startClientAndServer;
import static org.mockserver.matchers.Times.exactly;
import static org.mockserver.model.HttpRequest.request;
import static org.mockserver.model.HttpResponse.response;
public class GetRequestMockServer {
public static ClientAndServer mockServer;
public static String serviceOneUrl;
public static String serviceTwoUrl;
private static int serverPort;
public static final String SERVER_ADDRESS = "127.0.0.1";
public static final String PATH_ONE = "/test1";
public static final String PATH_TWO = "/test2";
public static final String METHOD = "GET";
@BeforeAll
static void startServer() throws IOException, URISyntaxException {
serverPort = getFreePort();
serviceOneUrl = "http://" + SERVER_ADDRESS + ":" + serverPort + PATH_ONE;
serviceTwoUrl = "http://" + SERVER_ADDRESS + ":" + serverPort + PATH_TWO;
mockServer = startClientAndServer(serverPort);
mockGetRequest();
}
@AfterAll
static void stopServer() {
mockServer.stop();
}
private static void mockGetRequest() {
new MockServerClient(SERVER_ADDRESS, serverPort)
.when(
request()
.withPath(PATH_ONE)
.withMethod(METHOD),
exactly(5)
)
.respond(
response()
.withStatusCode(HttpStatus.SC_OK)
.withBody("{\"status\":\"ok\"}")
);
new MockServerClient(SERVER_ADDRESS, serverPort)
.when(
request()
.withPath(PATH_TWO)
.withMethod(METHOD),
exactly(1)
)
.respond(
response()
.withStatusCode(HttpStatus.SC_OK)
.withBody("{\"status\":\"ok\"}")
);
}
private static int getFreePort () throws IOException {
try (ServerSocket serverSocket = new ServerSocket(0)) {
return serverSocket.getLocalPort();
}
}
}

View File

@ -0,0 +1,168 @@
package com.baeldung.httpclient.retry;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertThrows;
import java.io.IOException;
import java.net.URI;
import java.net.UnknownHostException;
import java.util.Objects;
import org.apache.http.HttpRequestInterceptor;
import org.apache.http.HttpResponseInterceptor;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPatch;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
import org.apache.http.impl.client.HttpClientBuilder;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
public class ApacheHttpClientRetryLiveTest {
private Integer requestCounter;
private CloseableHttpClient httpClient;
@BeforeEach
void setUp() {
requestCounter = 0;
}
@AfterEach
void tearDown() throws IOException {
if (httpClient != null) {
httpClient.close();
}
}
private void createDefaultApacheHttpClient() {
this.httpClient = HttpClientBuilder
.create()
.addInterceptorFirst((HttpRequestInterceptor) (httpRequest, httpContext) -> {
requestCounter++;
}).build();
}
private void createFailingHttpClient() {
this.httpClient = HttpClientBuilder
.create()
.addInterceptorFirst((HttpRequestInterceptor) (httpRequest, httpContext) -> requestCounter++)
.addInterceptorLast((HttpResponseInterceptor) (httpResponse, httpContext) -> {
throw new IOException();
})
.build();
}
private void createHttpClientWithRetryHandler() {
this.httpClient = HttpClientBuilder
.create()
.addInterceptorFirst((HttpRequestInterceptor) (httpRequest, httpContext) -> requestCounter++)
.addInterceptorLast((HttpResponseInterceptor) (httpRequest, httpContext) -> { throw new IOException(); })
.setRetryHandler(new DefaultHttpRequestRetryHandler(6, true))
.build();
}
private void createHttpClientWithCustomRetryHandler() {
this.httpClient = HttpClientBuilder
.create()
.addInterceptorFirst((HttpRequestInterceptor) (httpRequest, httpContext) -> requestCounter++)
.addInterceptorLast((HttpResponseInterceptor) (httpRequest, httpContext) -> { throw new IOException(); })
.setRetryHandler((exception, executionCount, context) -> {
if (executionCount < 5 && Objects.equals("GET", ((HttpClientContext) context).getRequest().getRequestLine().getMethod())) {
return true;
} else {
return false;
}
})
.build();
}
private void createHttpClientWithRetriesDisabled() {
this.httpClient = HttpClientBuilder
.create()
.addInterceptorFirst((HttpRequestInterceptor) (httpRequest, httpContext) -> requestCounter++)
.addInterceptorLast((HttpResponseInterceptor) (httpRequest, httpContext) -> { throw new IOException(); })
.disableAutomaticRetries()
.build();
}
@Test
public void givenDefaultConfiguration_whenReceivedIOException_thenRetriesPerformed() {
createFailingHttpClient();
assertThrows(IOException.class, () -> httpClient.execute(new HttpGet("https://httpstat.us/200")));
assertThat(requestCounter).isEqualTo(4);
}
@Test
public void givenDefaultConfiguration_whenDomainNameNotResolved_thenNoRetryApplied() {
createDefaultApacheHttpClient();
HttpGet request = new HttpGet(URI.create("http://domain.that.does.not.exist:80/api/v1"));
assertThrows(UnknownHostException.class, () -> httpClient.execute(request));
assertThat(requestCounter).isEqualTo(1);
}
@Test
public void givenDefaultConfiguration_whenGotInternalServerError_thenNoRetryLogicApplied() throws IOException {
createDefaultApacheHttpClient();
HttpGet request = new HttpGet(URI.create("https://httpstat.us/500"));
CloseableHttpResponse response = assertDoesNotThrow(() -> httpClient.execute(request));
assertThat(response.getStatusLine().getStatusCode()).isEqualTo(500);
assertThat(requestCounter).isEqualTo(1);
response.close();
}
@Test
public void givenDefaultConfiguration_whenHttpPatchRequest_thenRetryIsNotApplied() {
createFailingHttpClient();
HttpPatch request = new HttpPatch(URI.create("https://httpstat.us/500"));
assertThrows(IOException.class, () -> httpClient.execute(request));
assertThat(requestCounter).isEqualTo(1);
}
@Test
public void givenDefaultConfiguration_whenHttpPutRequest_thenRetryIsNotApplied() {
createFailingHttpClient();
HttpPut request = new HttpPut(URI.create("https://httpstat.us/500"));
assertThrows(IOException.class, () -> httpClient.execute(request));
assertThat(requestCounter).isEqualTo(1);
}
@Test
public void givenConfiguredRetryHandler_whenHttpPostRequest_thenRetriesPerformed() {
createHttpClientWithRetryHandler();
HttpPost request = new HttpPost(URI.create("https://httpstat.us/200"));
assertThrows(IOException.class, () -> httpClient.execute(request));
assertThat(requestCounter).isEqualTo(7);
}
@Test
public void givenCustomRetryHandler_whenUnknownHostException_thenRetryAnyway() {
createHttpClientWithCustomRetryHandler();
HttpGet request = new HttpGet(URI.create("https://domain.that.does.not.exist/200"));
assertThrows(IOException.class, () -> httpClient.execute(request));
assertThat(requestCounter).isEqualTo(5);
}
@Test
public void givenDisabledRetries_whenExecutedHttpRequestEndUpWithIOException_thenRetryIsNotApplied() {
createHttpClientWithRetriesDisabled();
HttpGet request = new HttpGet(URI.create("https://httpstat.us/200"));
assertThrows(IOException.class, () -> httpClient.execute(request));
assertThat(requestCounter).isEqualTo(1);
}
}

View File

@ -7,3 +7,4 @@ You can build the project from the command line using: *mvn clean install*, or i
### Relevant Articles: ### Relevant Articles:
- [Guide to Check if Apache Kafka Server Is Running](https://www.baeldung.com/apache-kafka-check-server-is-running) - [Guide to Check if Apache Kafka Server Is Running](https://www.baeldung.com/apache-kafka-check-server-is-running)
- [Add Custom Headers to a Kafka Message](https://www.baeldung.com/java-kafka-custom-headers)

View File

@ -0,0 +1,88 @@
package com.baeldung.kafka.headers;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;
import org.apache.kafka.clients.consumer.ConsumerConfig;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.apache.kafka.clients.consumer.ConsumerRecords;
import org.apache.kafka.clients.consumer.KafkaConsumer;
import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.ProducerConfig;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.apache.kafka.common.header.Header;
import org.apache.kafka.common.header.Headers;
import org.apache.kafka.common.header.internals.RecordHeader;
import org.apache.kafka.common.serialization.StringDeserializer;
import org.apache.kafka.common.serialization.StringSerializer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class KafkaMessageHeaders {
private static Logger logger = LoggerFactory.getLogger(KafkaMessageHeaders.class);
private static String TOPIC = "baeldung";
private static String MESSAGE_KEY = "message";
private static String MESSAGE_VALUE = "Hello World";
private static String HEADER_KEY = "website";
private static String HEADER_VALUE = "baeldung.com";
private static KafkaProducer<String, String> producer;
private static KafkaConsumer<String, String> consumer;
public static void main(String[] args) {
setup();
publishMessageWithCustomHeaders();
consumeMessageWithCustomHeaders();
}
private static void consumeMessageWithCustomHeaders() {
consumer.subscribe(Arrays.asList(TOPIC));
ConsumerRecords<String, String> records = consumer.poll(Duration.ofMinutes(1));
for (ConsumerRecord<String, String> record : records) {
logger.info(record.key());
logger.info(record.value());
Headers headers = record.headers();
for (Header header : headers) {
logger.info(header.key());
logger.info(new String(header.value()));
}
}
}
private static void publishMessageWithCustomHeaders() {
List<Header> headers = new ArrayList<>();
headers.add(new RecordHeader(HEADER_KEY, HEADER_VALUE.getBytes()));
ProducerRecord<String, String> record1 = new ProducerRecord<>(TOPIC, null, MESSAGE_KEY, MESSAGE_VALUE, headers);
producer.send(record1);
ProducerRecord<String, String> record2 = new ProducerRecord<>(TOPIC, null, System.currentTimeMillis(), MESSAGE_KEY, MESSAGE_VALUE, headers);
producer.send(record2);
}
private static void setup() {
Properties producerProperties = new Properties();
producerProperties.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092");
producerProperties.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName());
producerProperties.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName());
Properties consumerProperties = new Properties();
consumerProperties.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092");
consumerProperties.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName());
consumerProperties.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName());
consumerProperties.put(ConsumerConfig.GROUP_ID_CONFIG, "ConsumerGroup1");
producer = new KafkaProducer<>(producerProperties);
consumer = new KafkaConsumer<>(consumerProperties);
}
}

View File

@ -0,0 +1,104 @@
package com.baeldung.kafka.headers;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import org.apache.kafka.clients.consumer.ConsumerConfig;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.apache.kafka.clients.consumer.ConsumerRecords;
import org.apache.kafka.clients.consumer.KafkaConsumer;
import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.ProducerConfig;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.apache.kafka.clients.producer.RecordMetadata;
import org.apache.kafka.common.header.Header;
import org.apache.kafka.common.header.Headers;
import org.apache.kafka.common.header.internals.RecordHeader;
import org.apache.kafka.common.serialization.StringDeserializer;
import org.apache.kafka.common.serialization.StringSerializer;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.testcontainers.containers.KafkaContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import org.testcontainers.utility.DockerImageName;
// This live test needs a Docker Daemon running so that a kafka container can be created
@Testcontainers
public class KafkaMessageHeadersLiveTest {
private static String TOPIC = "baeldung";
private static String MESSAGE_KEY = "message";
private static String MESSAGE_VALUE = "Hello World";
private static String HEADER_KEY = "website";
private static String HEADER_VALUE = "baeldung.com";
private static KafkaProducer<String, String> producer;
private static KafkaConsumer<String, String> consumer;
@Container
private static final KafkaContainer KAFKA_CONTAINER = new KafkaContainer(DockerImageName.parse("confluentinc/cp-kafka:latest"));
@BeforeAll
static void setup() {
KAFKA_CONTAINER.addExposedPort(9092);
Properties producerProperties = new Properties();
producerProperties.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, KAFKA_CONTAINER.getBootstrapServers());
producerProperties.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName());
producerProperties.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName());
Properties consumerProperties = new Properties();
consumerProperties.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, KAFKA_CONTAINER.getBootstrapServers());
consumerProperties.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName());
consumerProperties.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName());
consumerProperties.put(ConsumerConfig.GROUP_ID_CONFIG, "ConsumerGroup1");
producer = new KafkaProducer<>(producerProperties);
consumer = new KafkaConsumer<>(consumerProperties);
}
@AfterAll
static void destroy() {
KAFKA_CONTAINER.stop();
}
@Test
void givenAMessageWithCustomHeaders_whenPublishedToKafkaAndConsumed_thenCheckForCustomHeaders() throws ExecutionException, InterruptedException {
List<Header> headers = new ArrayList<>();
headers.add(new RecordHeader(HEADER_KEY, HEADER_VALUE.getBytes()));
ProducerRecord<String, String> record1 = new ProducerRecord<>(TOPIC, null, MESSAGE_KEY, MESSAGE_VALUE, headers);
Future<RecordMetadata> future = producer.send(record1);
RecordMetadata metadata = future.get();
assertNotNull(metadata);
consumer.subscribe(Arrays.asList(TOPIC));
ConsumerRecords<String, String> records = consumer.poll(Duration.ofMinutes(1));
for (ConsumerRecord<String, String> record : records) {
assertEquals(MESSAGE_KEY, record.key());
assertEquals(MESSAGE_VALUE, record.value());
Headers consumedHeaders = record.headers();
assertNotNull(consumedHeaders);
for (Header header : consumedHeaders) {
assertEquals(HEADER_KEY, header.key());
assertEquals(HEADER_VALUE, new String(header.value()));
}
}
}
}

View File

@ -35,12 +35,12 @@
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.apache.flink</groupId> <groupId>org.apache.flink</groupId>
<artifactId>flink-connector-kafka-0.11_2.11</artifactId> <artifactId>flink-connector-kafka</artifactId>
<version>${flink.version}</version> <version>${flink.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.apache.flink</groupId> <groupId>org.apache.flink</groupId>
<artifactId>flink-streaming-java_2.11</artifactId> <artifactId>flink-streaming-java</artifactId>
<version>${flink.version}</version> <version>${flink.version}</version>
</dependency> </dependency>
<dependency> <dependency>
@ -67,7 +67,7 @@
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.apache.flink</groupId> <groupId>org.apache.flink</groupId>
<artifactId>flink-test-utils_2.11</artifactId> <artifactId>flink-test-utils</artifactId>
<version>${flink.version}</version> <version>${flink.version}</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
@ -163,11 +163,28 @@
</dependency> </dependency>
</dependencies> </dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>
--add-opens java.base/java.time=ALL-UNNAMED
--add-opens
java.base/java.nio=ALL-UNNAMED
--add-opens java.base/java.util=ALL-UNNAMED
</argLine>
</configuration>
</plugin>
</plugins>
</build>
<properties> <properties>
<kafka.version>2.8.0</kafka.version> <kafka.version>3.4.0</kafka.version>
<testcontainers-kafka.version>1.15.3</testcontainers-kafka.version> <testcontainers-kafka.version>1.15.3</testcontainers-kafka.version>
<testcontainers-jupiter.version>1.15.3</testcontainers-jupiter.version> <testcontainers-jupiter.version>1.15.3</testcontainers-jupiter.version>
<flink.version>1.5.0</flink.version> <flink.version>1.16.1</flink.version>
<awaitility.version>3.0.0</awaitility.version> <awaitility.version>3.0.0</awaitility.version>
<org.apache.spark.spark-core.version>2.4.8</org.apache.spark.spark-core.version> <org.apache.spark.spark-core.version>2.4.8</org.apache.spark.spark-core.version>
<graphframes.version>0.8.1-spark3.0-s_2.12</graphframes.version> <graphframes.version>0.8.1-spark3.0-s_2.12</graphframes.version>

View File

@ -9,8 +9,8 @@ import org.apache.flink.streaming.api.TimeCharacteristic;
import org.apache.flink.streaming.api.datastream.DataStream; import org.apache.flink.streaming.api.datastream.DataStream;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment; import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.streaming.api.windowing.time.Time; import org.apache.flink.streaming.api.windowing.time.Time;
import org.apache.flink.streaming.connectors.kafka.FlinkKafkaConsumer011; import org.apache.flink.streaming.connectors.kafka.FlinkKafkaConsumer;
import org.apache.flink.streaming.connectors.kafka.FlinkKafkaProducer011; import org.apache.flink.streaming.connectors.kafka.FlinkKafkaProducer;
import static com.baeldung.flink.connector.Consumers.*; import static com.baeldung.flink.connector.Consumers.*;
import static com.baeldung.flink.connector.Producers.*; import static com.baeldung.flink.connector.Producers.*;
@ -25,12 +25,12 @@ public class FlinkDataPipeline {
StreamExecutionEnvironment environment = StreamExecutionEnvironment.getExecutionEnvironment(); StreamExecutionEnvironment environment = StreamExecutionEnvironment.getExecutionEnvironment();
FlinkKafkaConsumer011<String> flinkKafkaConsumer = createStringConsumerForTopic(inputTopic, address, consumerGroup); FlinkKafkaConsumer<String> flinkKafkaConsumer = createStringConsumerForTopic(inputTopic, address, consumerGroup);
flinkKafkaConsumer.setStartFromEarliest(); flinkKafkaConsumer.setStartFromEarliest();
DataStream<String> stringInputStream = environment.addSource(flinkKafkaConsumer); DataStream<String> stringInputStream = environment.addSource(flinkKafkaConsumer);
FlinkKafkaProducer011<String> flinkKafkaProducer = createStringProducer(outputTopic, address); FlinkKafkaProducer<String> flinkKafkaProducer = createStringProducer(outputTopic, address);
stringInputStream.map(new WordsCapitalizer()) stringInputStream.map(new WordsCapitalizer())
.addSink(flinkKafkaProducer); .addSink(flinkKafkaProducer);
@ -48,11 +48,11 @@ public class FlinkDataPipeline {
environment.setStreamTimeCharacteristic(TimeCharacteristic.EventTime); environment.setStreamTimeCharacteristic(TimeCharacteristic.EventTime);
FlinkKafkaConsumer011<InputMessage> flinkKafkaConsumer = createInputMessageConsumer(inputTopic, kafkaAddress, consumerGroup); FlinkKafkaConsumer<InputMessage> flinkKafkaConsumer = createInputMessageConsumer(inputTopic, kafkaAddress, consumerGroup);
flinkKafkaConsumer.setStartFromEarliest(); flinkKafkaConsumer.setStartFromEarliest();
flinkKafkaConsumer.assignTimestampsAndWatermarks(new InputMessageTimestampAssigner()); flinkKafkaConsumer.assignTimestampsAndWatermarks(new InputMessageTimestampAssigner());
FlinkKafkaProducer011<Backup> flinkKafkaProducer = createBackupProducer(outputTopic, kafkaAddress); FlinkKafkaProducer<Backup> flinkKafkaProducer = createBackupProducer(outputTopic, kafkaAddress);
DataStream<InputMessage> inputMessagesStream = environment.addSource(flinkKafkaConsumer); DataStream<InputMessage> inputMessagesStream = environment.addSource(flinkKafkaConsumer);

View File

@ -3,26 +3,26 @@ package com.baeldung.flink.connector;
import com.baeldung.flink.model.InputMessage; import com.baeldung.flink.model.InputMessage;
import com.baeldung.flink.schema.InputMessageDeserializationSchema; import com.baeldung.flink.schema.InputMessageDeserializationSchema;
import org.apache.flink.api.common.serialization.SimpleStringSchema; import org.apache.flink.api.common.serialization.SimpleStringSchema;
import org.apache.flink.streaming.connectors.kafka.FlinkKafkaConsumer011; import org.apache.flink.streaming.connectors.kafka.FlinkKafkaConsumer;
import java.util.Properties; import java.util.Properties;
public class Consumers { public class Consumers {
public static FlinkKafkaConsumer011<String> createStringConsumerForTopic(String topic, String kafkaAddress, String kafkaGroup) { public static FlinkKafkaConsumer<String> createStringConsumerForTopic(String topic, String kafkaAddress, String kafkaGroup) {
Properties props = new Properties(); Properties props = new Properties();
props.setProperty("bootstrap.servers", kafkaAddress); props.setProperty("bootstrap.servers", kafkaAddress);
props.setProperty("group.id", kafkaGroup); props.setProperty("group.id", kafkaGroup);
FlinkKafkaConsumer011<String> consumer = new FlinkKafkaConsumer011<>(topic, new SimpleStringSchema(), props); FlinkKafkaConsumer<String> consumer = new FlinkKafkaConsumer<>(topic, new SimpleStringSchema(), props);
return consumer; return consumer;
} }
public static FlinkKafkaConsumer011<InputMessage> createInputMessageConsumer(String topic, String kafkaAddress, String kafkaGroup) { public static FlinkKafkaConsumer<InputMessage> createInputMessageConsumer(String topic, String kafkaAddress, String kafkaGroup) {
Properties properties = new Properties(); Properties properties = new Properties();
properties.setProperty("bootstrap.servers", kafkaAddress); properties.setProperty("bootstrap.servers", kafkaAddress);
properties.setProperty("group.id", kafkaGroup); properties.setProperty("group.id", kafkaGroup);
FlinkKafkaConsumer011<InputMessage> consumer = new FlinkKafkaConsumer011<InputMessage>(topic, new InputMessageDeserializationSchema(), properties); FlinkKafkaConsumer<InputMessage> consumer = new FlinkKafkaConsumer<InputMessage>(topic, new InputMessageDeserializationSchema(), properties);
return consumer; return consumer;
} }

View File

@ -3,15 +3,15 @@ package com.baeldung.flink.connector;
import com.baeldung.flink.model.Backup; import com.baeldung.flink.model.Backup;
import com.baeldung.flink.schema.BackupSerializationSchema; import com.baeldung.flink.schema.BackupSerializationSchema;
import org.apache.flink.api.common.serialization.SimpleStringSchema; import org.apache.flink.api.common.serialization.SimpleStringSchema;
import org.apache.flink.streaming.connectors.kafka.FlinkKafkaProducer011; import org.apache.flink.streaming.connectors.kafka.FlinkKafkaProducer;
public class Producers { public class Producers {
public static FlinkKafkaProducer011<String> createStringProducer(String topic, String kafkaAddress) { public static FlinkKafkaProducer<String> createStringProducer(String topic, String kafkaAddress) {
return new FlinkKafkaProducer011<>(kafkaAddress, topic, new SimpleStringSchema()); return new FlinkKafkaProducer<>(kafkaAddress, topic, new SimpleStringSchema());
} }
public static FlinkKafkaProducer011<Backup> createBackupProducer(String topic, String kafkaAddress) { public static FlinkKafkaProducer<Backup> createBackupProducer(String topic, String kafkaAddress) {
return new FlinkKafkaProducer011<Backup>(kafkaAddress, topic, new BackupSerializationSchema()); return new FlinkKafkaProducer<Backup>(kafkaAddress, topic, new BackupSerializationSchema());
} }
} }

View File

@ -188,13 +188,13 @@
<properties> <properties>
<avro.version>1.8.2</avro.version> <avro.version>1.8.2</avro.version>
<beam.version>2.45.0</beam.version> <beam.version>2.45.0</beam.version>
<bval.version>1.1.2</bval.version> <bval.version>2.0.6</bval.version>
<javax.validation.validation-api.version>1.1.0.Final</javax.validation.validation-api.version> <javax.validation.validation-api.version>2.0.1.Final</javax.validation.validation-api.version>
<meecrowave-junit.version>1.2.0</meecrowave-junit.version> <meecrowave-junit.version>1.2.15</meecrowave-junit.version>
<okhttp.version>3.10.0</okhttp.version> <okhttp.version>3.10.0</okhttp.version>
<meecrowave-jpa.version>1.2.1</meecrowave-jpa.version> <meecrowave-jpa.version>1.2.15</meecrowave-jpa.version>
<meecrowave-core.version>1.2.1</meecrowave-core.version> <meecrowave-core.version>1.2.15</meecrowave-core.version>
<meecrowave-maven-plugin.version>1.2.1</meecrowave-maven-plugin.version> <meecrowave-maven-plugin.version>1.2.15</meecrowave-maven-plugin.version>
<opennlp.opennlp-tools.version>1.8.4</opennlp.opennlp-tools.version> <opennlp.opennlp-tools.version>1.8.4</opennlp.opennlp-tools.version>
<pulsar-client.version>2.1.1-incubating</pulsar-client.version> <pulsar-client.version>2.1.1-incubating</pulsar-client.version>
<zookeeper.version>3.4.11</zookeeper.version> <zookeeper.version>3.4.11</zookeeper.version>

View File

@ -7,7 +7,7 @@ import org.junit.Test;
import com.baeldung.apache.beam.intro.WordCount; import com.baeldung.apache.beam.intro.WordCount;
public class WordCountUnitTest { public class WordCountIntegrationTest {
@Test @Test
public void givenInputFile_whenWordCountRuns_thenJobFinishWithoutError() { public void givenInputFile_whenWordCountRuns_thenJobFinishWithoutError() {

View File

@ -30,6 +30,16 @@
</exclusion> </exclusion>
</exclusions> </exclusions>
</dependency> </dependency>
<dependency>
<groupId>org.dhatim</groupId>
<artifactId>fastexcel</artifactId>
<version>${fastexcel.version}</version>
</dependency>
<dependency>
<groupId>org.dhatim</groupId>
<artifactId>fastexcel-reader</artifactId>
<version>${fastexcel.version}</version>
</dependency>
</dependencies> </dependencies>
<build> <build>
@ -52,6 +62,7 @@
<properties> <properties>
<poi.version>5.2.0</poi.version> <poi.version>5.2.0</poi.version>
<jexcel.version>1.0.6</jexcel.version> <jexcel.version>1.0.6</jexcel.version>
<fastexcel.version>0.15.3</fastexcel.version>
<maven.resources.plugin.version>3.2.0</maven.resources.plugin.version> <maven.resources.plugin.version>3.2.0</maven.resources.plugin.version>
</properties> </properties>

View File

@ -0,0 +1,63 @@
package com.baeldung.fastexcel;
import org.dhatim.fastexcel.Workbook;
import org.dhatim.fastexcel.Worksheet;
import org.dhatim.fastexcel.reader.Cell;
import org.dhatim.fastexcel.reader.ReadableWorkbook;
import org.dhatim.fastexcel.reader.Row;
import org.dhatim.fastexcel.reader.Sheet;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Stream;
public class FastexcelHelper {
public Map<Integer, List<String>> readExcel(String fileLocation) throws IOException {
Map<Integer, List<String>> data = new HashMap<>();
try (FileInputStream file = new FileInputStream(fileLocation); ReadableWorkbook wb = new ReadableWorkbook(file)) {
Sheet sheet = wb.getFirstSheet();
try (Stream<Row> rows = sheet.openStream()) {
rows.forEach(r -> {
data.put(r.getRowNum(), new ArrayList<>());
for (Cell cell : r) {
data.get(r.getRowNum()).add(cell.getRawValue());
}
});
}
}
return data;
}
public void writeExcel() throws IOException {
File currDir = new File(".");
String path = currDir.getAbsolutePath();
String fileLocation = path.substring(0, path.length() - 1) + "fastexcel.xlsx";
try (OutputStream os = Files.newOutputStream(Paths.get(fileLocation)); Workbook wb = new Workbook(os, "MyApplication", "1.0")) {
Worksheet ws = wb.newWorksheet("Sheet 1");
ws.width(0, 25);
ws.width(1, 15);
ws.range(0, 0, 0, 1).style().fontName("Arial").fontSize(16).bold().fillColor("3366FF").set();
ws.value(0, 0, "Name");
ws.value(0, 1, "Age");
ws.range(2, 0, 2, 1).style().wrapText(true).set();
ws.value(2, 0, "John Smith");
ws.value(2, 1, 20L);
}
}
}

View File

@ -0,0 +1,49 @@
package com.baeldung.fastexcel;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import static org.junit.Assert.assertEquals;
public class FastexcelIntegrationTest {
private FastexcelHelper fastexcelHelper;
private static String FILE_NAME = "fastexcel.xlsx";
private String fileLocation;
@Before
public void generateExcelFile() throws IOException {
File currDir = new File(".");
String path = currDir.getAbsolutePath();
fileLocation = path.substring(0, path.length() - 1) + FILE_NAME;
fastexcelHelper = new FastexcelHelper();
fastexcelHelper.writeExcel();
}
@Test
public void whenParsingExcelFile_thenCorrect() throws IOException {
Map<Integer, List<String>> data = fastexcelHelper.readExcel(fileLocation);
assertEquals("Name", data.get(1).get(0));
assertEquals("Age", data.get(1).get(1));
assertEquals("John Smith", data.get(3).get(0));
assertEquals("20", data.get(3).get(1));
}
@After
public void cleanup() {
File testFile = new File(fileLocation);
if (testFile.exists()) {
testFile.delete();
}
}
}

View File

@ -7,7 +7,6 @@
<version>1.0-SNAPSHOT</version> <version>1.0-SNAPSHOT</version>
<name>apache-spark</name> <name>apache-spark</name>
<packaging>jar</packaging> <packaging>jar</packaging>
<url>http://maven.apache.org</url>
<parent> <parent>
<groupId>com.baeldung</groupId> <groupId>com.baeldung</groupId>

View File

@ -3,14 +3,14 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<artifactId>lambda</artifactId> <artifactId>lambda-function</artifactId>
<version>0.1.0-SNAPSHOT</version> <version>0.1.0-SNAPSHOT</version>
<name>lambda</name> <name>lambda-function</name>
<packaging>jar</packaging> <packaging>jar</packaging>
<parent> <parent>
<groupId>com.baeldung</groupId> <groupId>com.baeldung</groupId>
<artifactId>aws-lambda</artifactId> <artifactId>aws-lambda-modules</artifactId>
<version>1.0.0-SNAPSHOT</version> <version>1.0.0-SNAPSHOT</version>
</parent> </parent>

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