Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
8f06840
feat: add httpclient-vertx-5 module with Vert.x 5.x support
ByteSizedJoe Jul 22, 2025
d3723cf
chore: add changelog entry, update poms
ByteSizedJoe Jul 22, 2025
5e93d64
chore: renormalize changelog
ByteSizedJoe Jul 22, 2025
26be415
chore: renormalize pom
ByteSizedJoe Jul 22, 2025
99663d3
chore: merge main, update licensing, spots
ByteSizedJoe Jul 22, 2025
9779907
Merge branch 'main' into iss_7174
ByteSizedJoe Jul 22, 2025
6c4f4ad
chore: clean-up constructor with config object
ByteSizedJoe Jul 22, 2025
61def60
chore: simplify with stack-based recursion guarding
ByteSizedJoe Jul 22, 2025
9651292
chore: fix error handling race
ByteSizedJoe Jul 22, 2025
15f4783
Merge remote-tracking branch 'origin/iss_7174' into iss_7174
ByteSizedJoe Jul 22, 2025
239d70f
chore: vertx profile fixes for integration runs
ByteSizedJoe Jul 22, 2025
eb1eff1
Merge branch 'main' into iss_7174
ByteSizedJoe Jul 22, 2025
991745d
docs: add some documentation for usage, running with integration test…
ByteSizedJoe Jul 22, 2025
3961401
Merge branch 'main' into iss_7174
ByteSizedJoe Aug 6, 2025
bd3583d
Merge branch 'main' into iss_7174
ByteSizedJoe Aug 14, 2025
27dcf5b
chore: add vertx-5 to e2e testing
ByteSizedJoe Aug 14, 2025
f936b52
Merge branch 'main' into iss_7174
ByteSizedJoe Aug 15, 2025
ac1e03f
Merge branch 'main' into iss_7174
ByteSizedJoe Aug 26, 2025
2863529
Merge branch 'main' into iss_7174
ByteSizedJoe Sep 4, 2025
c5d0044
Merge branch 'main' into iss_7174
ash-thakur-rh Nov 11, 2025
5320d1d
Update pom.xml
ash-thakur-rh Nov 11, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/e2e-httpclient-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ jobs:
fail-fast: false
matrix:
kubernetes: [v1.33.0,v1.32.4,v1.31.8,v1.30.12,v1.29.14]
httpclient: [jdk,jetty,okhttp]
httpclient: [jdk,jetty,okhttp,vertx-5]
steps:
- name: Checkout
uses: actions/checkout@v5
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
* Fix #7266: bump jackson-bom from 2.19.2 to 2.20.0, fix overrides and handle jackson-annotations v2.20

#### New Features
* Fix #7174: Added Vert.x 5 HTTP client implementation with improved async handling and WebSocket separation

#### _**Note**_: Breaking changes
* #7266: bump jackson-bom from 2.19.2 to 2.20.0, fix overrides and handle jackson-annotations v2.20
Expand Down
65 changes: 65 additions & 0 deletions httpclient-vertx-5/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# Vert.x 5 HTTP Client For Fabric8 Kubernetes Client

This module provides Vert.x 5.x HTTP client implementation for the Fabric8 Kubernetes Client, featuring improved async handling and WebSocket separation introduced in Vert.x 5.

## Features

- **Vert.x 5.0.1**: Uses latest stable Vert.x 5.x release
- **Async Operations**: Enhanced async HTTP request handling
- **WebSocket Separation**: Vert.x 5's separate HTTP and WebSocket client architecture
- **Backpressure Support**: Built-in flow control for streaming operations
- **Stack-based Recursion Guard**: Memory-safe recursion protection without ThreadLocal

## Usage

Add the dependency to your project:

```xml
<dependency>
<groupId>io.fabric8</groupId>
<artifactId>kubernetes-httpclient-vertx-5</artifactId>
<version>${fabric8.version}</version>
</dependency>
```

The HTTP client will be automatically discovered via service loader.

## Testing

### Running Integration Tests

To run integration tests specifically with the Vert.x 5 HTTP client:

```bash
# Run all integration tests with Vert.x 5
mvn -Phttpclient-vertx-5 -Pitests verify -Dtest.httpclient=vertx-5

# Run specific test with Vert.x 5
mvn -Phttpclient-vertx-5 test -Dtest=ConfigMapIT -Dtest.httpclient=vertx-5

# Run WebSocket tests with Vert.x 5
mvn -Phttpclient-vertx-5 test -Dtest=WatchIT -Dtest.httpclient=vertx-5
```

### Version Validation Test

A special test (`VertxVersionValidationIT`) validates that Vert.x 5.0.1 is actually being used:

```bash
mvn -Phttpclient-vertx-5 test -Dtest=VertxVersionValidationIT -Dtest.httpclient=vertx-5
```

### Dependency Verification

Verify the correct Vert.x version is being used:

```bash
mvn -Phttpclient-vertx-5 dependency:tree | grep vertx
# Should show: vertx-core:jar:5.0.1:compile
```

## Architecture Notes

- **WebSocket Client Separation**: Unlike Vert.x 4, Vert.x 5 uses separate HTTP and WebSocket clients
- **Dependency Management**: This module overrides parent POM's Vert.x version to ensure 5.0.1 is used
- **Profile Isolation**: The httpclient-vertx-5 profile ensures no conflicts with default Vert.x 4 usage
235 changes: 235 additions & 0 deletions httpclient-vertx-5/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,235 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--

Copyright (C) 2015 Red Hat, Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>kubernetes-client-project</artifactId>
<groupId>io.fabric8</groupId>
<version>7.5-SNAPSHOT</version>
</parent>

<artifactId>kubernetes-httpclient-vertx-5</artifactId>
<packaging>jar</packaging>
<name>Fabric8 :: Kubernetes :: HttpClient :: Vert.x 5</name>

<properties>
<vertx.version>5.0.1</vertx.version>
<osgi.require-capability>
osgi.extender;
filter:="(osgi.extender=osgi.serviceloader.registrar)",
</osgi.require-capability>
<osgi.provide-capability>
osgi.serviceloader;
osgi.serviceloader=io.fabric8.kubernetes.client.http.HttpClient$Factory
</osgi.provide-capability>
<osgi.import>
!android.util*,
*,
</osgi.import>
<osgi.export>
io.fabric8.kubernetes.client.vertx*;-noimport:=true,
</osgi.export>
<osgi.private>
</osgi.private>
</properties>

<dependencyManagement>
<dependencies>
<!-- Override parent POM's Vert.x 4.x dependency management to force Vert.x 5.x -->
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-core</artifactId>
<version>${vertx.version}</version>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-web-client</artifactId>
<version>${vertx.version}</version>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-web-common</artifactId>
<version>${vertx.version}</version>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-auth-common</artifactId>
<version>${vertx.version}</version>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-core-logging</artifactId>
<version>${vertx.version}</version>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-web</artifactId>
<version>${vertx.version}</version>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-bridge-common</artifactId>
<version>${vertx.version}</version>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-uri-template</artifactId>
<version>${vertx.version}</version>
</dependency>
</dependencies>
</dependencyManagement>

<dependencies>
<dependency>
<groupId>io.fabric8</groupId>
<artifactId>kubernetes-client-api</artifactId>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-core</artifactId>
<version>${vertx.version}</version>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-web-client</artifactId>
<version>${vertx.version}</version>
</dependency>
<dependency>
<groupId>io.fabric8</groupId>
<artifactId>kubernetes-client-api</artifactId>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId>
</dependency>
<dependency>
<groupId>io.fabric8</groupId>
<artifactId>mockwebserver</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.awaitility</groupId>
<artifactId>awaitility</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<!-- Required by SslTest -->
<groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-jdk18on</artifactId>
<version>${bouncycastle.version}</version>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<rerunFailingTestsCount>1</rerunFailingTestsCount>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>java</goal>
</goals>
</execution>
</executions>
<configuration>
<classpathScope>test</classpathScope>
</configuration>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<executions>
<execution>
<id>report-aggregate</id>
<phase>verify</phase>
<goals>
<goal>report-aggregate</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>${maven.bundle.plugin.version}</version>
<executions>
<execution>
<id>bundle</id>
<phase>package</phase>
<goals>
<goal>bundle</goal>
</goals>
<configuration>
<instructions>
<Bundle-Name>${project.name}</Bundle-Name>
<Bundle-SymbolicName>${project.groupId}.${project.artifactId}</Bundle-SymbolicName>
<Export-Package>${osgi.export}</Export-Package>
<Import-Package>${osgi.import}</Import-Package>
<DynamicImport-Package>${osgi.dynamic.import}</DynamicImport-Package>
<Require-Capability>${osgi.require-capability}</Require-Capability>
<Provide-Capability>${osgi.provide-capability}</Provide-Capability>
<Private-Package>${osgi.private}</Private-Package>
<Require-Bundle>${osgi.bundles}</Require-Bundle>
<Bundle-Activator>${osgi.activator}</Bundle-Activator>
<Export-Service>${osgi.export.service}</Export-Service>
<Include-Resource>
/META-INF/services/io.fabric8.kubernetes.client.http.HttpClient$Factory=target/classes/META-INF/services/io.fabric8.kubernetes.client.http.HttpClient$Factory,
</Include-Resource>
</instructions>
<classifier>bundle</classifier>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* Copyright (C) 2015 Red Hat, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.fabric8.kubernetes.client.vertx;

import io.vertx.core.Future;
import io.vertx.core.Vertx;
import io.vertx.core.buffer.Buffer;
import lombok.RequiredArgsConstructor;

import java.io.InputStream;

@RequiredArgsConstructor
class AsyncInputReader {

private static final int CHUNK_SIZE = 2048;

private final Vertx vertx;
private final InputStream inputStream;
private byte[] readBuffer;

Future<Buffer> readNextChunk() {
return vertx.executeBlocking(() -> {
if (readBuffer == null) {
readBuffer = new byte[CHUNK_SIZE];
}
final int bytesRead = inputStream.read(readBuffer);
if (bytesRead == -1) {
return null; // EOF
}
return Buffer.buffer().appendBytes(readBuffer, 0, bytesRead);
});
}
}
Loading
Loading