Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
65 changes: 41 additions & 24 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@ on:
paths:
- "rabbitmq/**"
- "servicebus/**"
- "kafka/**"
- ".github/workflows/release.yml"
pull_request:
branches: [ "main" ]
paths:
- "rabbitmq/**"
- "servicebus/**"
- "kafka/**"
- ".github/workflows/release.yml"
workflow_dispatch:
inputs:
Expand All @@ -34,7 +36,7 @@ jobs:
strategy:
fail-fast: false
matrix:
plugin: [rabbitmq, servicebus]
plugin: [rabbitmq, servicebus, kafka]
platform: [windows-latest, windows-11-arm, ubuntu-22.04, ubuntu-22.04-arm, macos-26-intel, macos-14]

steps:
Expand Down Expand Up @@ -76,29 +78,44 @@ jobs:
;;
esac

if [ "${{ matrix.plugin }}" = "servicebus" ]; then
echo "DIRECTORY=servicebus" >> "$GITHUB_ENV"
echo "ARTIFACT_PATH=servicebus/build/ServiceBusPlugin" >> "$GITHUB_ENV"
echo "CONFIGURE_ARGS=-DCMAKE_TOOLCHAIN_FILE=${VCPKG_INSTALLATION_ROOT}/scripts/buildsystems/vcpkg.cmake" >> "$GITHUB_ENV"
if [ "${{ runner.os }}" = "Linux" ]; then
echo "INSTALL_PACKAGES=build-essential cmake git ninja-build pkg-config" >> "$GITHUB_ENV"
elif [ "${{ runner.os }}" = "macOS" ]; then
echo "INSTALL_PACKAGES=cmake ninja pkg-config" >> "$GITHUB_ENV"
else
echo "INSTALL_PACKAGES=cmake" >> "$GITHUB_ENV"
fi
else
echo "DIRECTORY=rabbitmq" >> "$GITHUB_ENV"
echo "ARTIFACT_PATH=rabbitmq/build/RabbitmqPlugin" >> "$GITHUB_ENV"
echo "CONFIGURE_ARGS=" >> "$GITHUB_ENV"
if [ "${{ runner.os }}" = "Linux" ]; then
echo "INSTALL_PACKAGES=build-essential cmake git" >> "$GITHUB_ENV"
elif [ "${{ runner.os }}" = "macOS" ]; then
echo "INSTALL_PACKAGES=cmake" >> "$GITHUB_ENV"
else
echo "INSTALL_PACKAGES=cmake" >> "$GITHUB_ENV"
fi
fi
case "${{ matrix.plugin }}" in
servicebus)
echo "DIRECTORY=servicebus" >> "$GITHUB_ENV"
echo "ARTIFACT_PATH=servicebus/build/ServiceBusPlugin" >> "$GITHUB_ENV"
echo "CONFIGURE_ARGS=-DCMAKE_TOOLCHAIN_FILE=${VCPKG_INSTALLATION_ROOT}/scripts/buildsystems/vcpkg.cmake" >> "$GITHUB_ENV"
if [ "${{ runner.os }}" = "Linux" ]; then
echo "INSTALL_PACKAGES=build-essential cmake git ninja-build pkg-config" >> "$GITHUB_ENV"
elif [ "${{ runner.os }}" = "macOS" ]; then
echo "INSTALL_PACKAGES=cmake ninja pkg-config" >> "$GITHUB_ENV"
else
echo "INSTALL_PACKAGES=cmake" >> "$GITHUB_ENV"
fi
;;
kafka)
echo "DIRECTORY=kafka" >> "$GITHUB_ENV"
echo "ARTIFACT_PATH=kafka/build/KafkaPlugin" >> "$GITHUB_ENV"
echo "CONFIGURE_ARGS=" >> "$GITHUB_ENV"
if [ "${{ runner.os }}" = "Linux" ]; then
echo "INSTALL_PACKAGES=build-essential cmake git libssl-dev libsasl2-dev zlib1g-dev" >> "$GITHUB_ENV"
elif [ "${{ runner.os }}" = "macOS" ]; then
echo "INSTALL_PACKAGES=cmake openssl" >> "$GITHUB_ENV"
else
echo "INSTALL_PACKAGES=cmake" >> "$GITHUB_ENV"
fi
;;
*)
echo "DIRECTORY=rabbitmq" >> "$GITHUB_ENV"
echo "ARTIFACT_PATH=rabbitmq/build/RabbitmqPlugin" >> "$GITHUB_ENV"
echo "CONFIGURE_ARGS=" >> "$GITHUB_ENV"
if [ "${{ runner.os }}" = "Linux" ]; then
echo "INSTALL_PACKAGES=build-essential cmake git" >> "$GITHUB_ENV"
elif [ "${{ runner.os }}" = "macOS" ]; then
echo "INSTALL_PACKAGES=cmake" >> "$GITHUB_ENV"
else
echo "INSTALL_PACKAGES=cmake" >> "$GITHUB_ENV"
fi
;;
esac

echo "PLUGIN_NAME=${{ matrix.plugin }}" >> "$GITHUB_ENV"

Expand Down
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,7 @@
.cursor

out/
build/
build/
bin/
obj/
Binaries/
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ Official open-source Graftcode Gateway plugins for carrying Graft calls over ext
|--------|---------|
| [rabbitmq](rabbitmq/) | RabbitMQ (AMQP 0-9-1), request/reply |
| [servicebus](servicebus/) | Azure Service Bus (AMQP 1.0), request/reply and one-way |
| [kafka](kafka/) | Apache Kafka, request/reply (correlation-id) |
| [observability/opentelemetry](observability/opentelemetry/) | OpenTelemetry / Azure Application Insights connector |

Each plugin has its own README with build and configuration steps. For how the Gateway loads a plugin, see the "Plugin server config" section of the [Graftcode Gateway](https://github.com/grft-dev/graftcode-gateway) README.
Expand Down
9 changes: 9 additions & 0 deletions kafka/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
build/
out/
.vs/
CMakeUserPresets.json
cmake-build-*/
vcpkg/
vcpkg_installed/
.cache/
*.user
5 changes: 5 additions & 0 deletions kafka/BUILD_NOTES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Kafka plugin build notes

- Dependencies: CMake `FetchContent` only (nlohmann/json + librdkafka). No vcpkg.
- Smoke test links factory exports; full RPC needs a live broker (see docker-compose).
- First configure needs network/git for FetchContent downloads.
22 changes: 22 additions & 0 deletions kafka/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
set(CMAKE_MIN 3.22)
cmake_minimum_required(VERSION ${CMAKE_MIN})
set(CMAKE_POLICY_VERSION_MINIMUM ${CMAKE_MIN})
cmake_policy(VERSION ${CMAKE_MIN})

project("KafkaPlugin" VERSION 1.0.0)

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)

add_definitions(-DUNICODE)
enable_testing()

set(CMAKE_POLICY_DEFAULT_CMP0135 NEW)

if(MSVC)
add_compile_options(/utf-8)
endif()

add_subdirectory("KafkaPlugin")
add_subdirectory("KafkaPluginTest")
16 changes: 16 additions & 0 deletions kafka/GraftcodePluginsInterfaces/IServer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#pragma once
#include <cstddef>

namespace GraftcodeGateway {
class IServer {
public:
using byte = unsigned char;
using WriteResponseFn = void(*)(void* context, const byte* data, std::size_t size);
using ProcessMessageFn = bool(*)(const byte* requestData, std::size_t requestSize, WriteResponseFn writeResponse, void* writeContext);

virtual ~IServer() = default;
virtual void configure(const char* jsonConfig, ProcessMessageFn processMessage) = 0;
virtual void start() = 0;
virtual void stop() = 0;
};
}
12 changes: 12 additions & 0 deletions kafka/GraftcodePluginsInterfaces/ITransport.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#pragma once
#include "_common.h"

namespace Hypertube::Native::Interfaces {
class ITransport {
public:
virtual ~ITransport() = default;
virtual int Initialize(byte callingRuntimeNumber, byte calledRuntimeNumber, byte calledRuntimeVersion) = 0;
virtual int SendCommand(byte* messageByteArray, int32_t messageByteArrayLen) = 0;
virtual int ReadResponse(byte* responseByteArray, int32_t responseByteArrayLen) = 0;
};
}
9 changes: 9 additions & 0 deletions kafka/GraftcodePluginsInterfaces/_common.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#pragma once
#ifndef byte
typedef unsigned char byte;
#endif
#ifndef int32_t
typedef int int32_t;
#endif
#include <string>
#include <iostream>
56 changes: 56 additions & 0 deletions kafka/KafkaPlugin/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Graftcode Kafka plugin (request/reply via librdkafka C++ API).
set(target_name KafkaPlugin)

add_library(${target_name} SHARED
TransportKafka.cpp
KafkaClient.cpp
KafkaServer.cpp
)

target_include_directories(${target_name} PUBLIC
"${CMAKE_SOURCE_DIR}/GraftcodePluginsInterfaces"
)

include(FetchContent)

FetchContent_Declare(
json
GIT_REPOSITORY https://github.com/nlohmann/json.git
GIT_TAG v3.12.0
GIT_SHALLOW TRUE
)
FetchContent_MakeAvailable(json)

set(RDKAFKA_BUILD_STATIC ON CACHE BOOL "Build librdkafka as static library" FORCE)
set(RDKAFKA_BUILD_EXAMPLES OFF CACHE BOOL "Skip librdkafka examples" FORCE)
set(RDKAFKA_BUILD_TESTS OFF CACHE BOOL "Skip librdkafka tests" FORCE)

FetchContent_Declare(
librdkafka
GIT_REPOSITORY https://github.com/confluentinc/librdkafka.git
GIT_TAG v2.8.0
GIT_SHALLOW TRUE
)
FetchContent_MakeAvailable(librdkafka)

if(NOT TARGET rdkafka++)
message(FATAL_ERROR "librdkafka FetchContent succeeded but rdkafka++ target was not found")
endif()

target_link_libraries(${target_name} PUBLIC
nlohmann_json::nlohmann_json
rdkafka++
)

if(TARGET rdkafka)
target_link_libraries(${target_name} PUBLIC rdkafka)
endif()

if(WIN32 OR CMAKE_SYSTEM_NAME STREQUAL "Windows")
target_link_libraries(${target_name} PUBLIC ws2_32)
endif()

if(UNIX AND NOT APPLE)
find_package(Threads REQUIRED)
target_link_libraries(${target_name} PUBLIC Threads::Threads)
endif()
Loading
Loading