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
42 changes: 35 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,15 @@ Official open-source Graftcode Gateway plugins. Each plugin carries Graft calls

| Plugin | Channel | Modes | Local setup | Docs |
|--------|---------|-------|-------------|------|
| [rabbitmq](rabbitmq/Readme.md) | RabbitMQ (AMQP 0-9-1) | request/reply | Docker image in `rabbitmq/` | [Readme](rabbitmq/Readme.md) |
| [servicebus](servicebus/Readme.md) | Azure Service Bus (AMQP 1.0) | request/reply and one-way | Service Bus emulator | [Readme](servicebus/Readme.md) |
| [kafka](kafka/Readme.md) | Apache Kafka | request/reply | [samples/kafka](samples/kafka/README.md) | [Readme](kafka/Readme.md) |
| [sqs](sqs/Readme.md) | Amazon SQS | request/reply and one-way | [samples/sqs](samples/sqs/README.md) (LocalStack) | [Readme](sqs/Readme.md) |
| [pubsub](pubsub/Readme.md) | Google Cloud Pub/Sub | request/reply and one-way | [samples/pubsub](samples/pubsub/README.md) (Pub/Sub emulator) | [Readme](pubsub/Readme.md) |
| [rabbitmq](rabbitmq/Readme.md) | RabbitMQ (AMQP 0-9-1) | request/reply | [samples/rabbitmq](samples/rabbitmq) | [Readme](rabbitmq/Readme.md) |
| [servicebus](servicebus/Readme.md) | Azure Service Bus (AMQP 1.0) | request/reply and one-way | [samples/servicebus](samples/servicebus) | [Readme](servicebus/Readme.md) |
| [kafka](kafka/Readme.md) | Apache Kafka | request/reply | [samples/kafka](samples/kafka) | [Readme](kafka/Readme.md) |
| [sqs](sqs/Readme.md) | Amazon SQS | request/reply and one-way | [samples/sqs](samples/sqs) (LocalStack) | [Readme](sqs/Readme.md) |
| [pubsub](pubsub/Readme.md) | Google Cloud Pub/Sub | request/reply and one-way | [samples/pubsub](samples/pubsub) (Pub/Sub emulator) | [Readme](pubsub/Readme.md) |

All local Docker setups, ports, and startup instructions are documented in
[samples/README.md](samples/README.md). Each setup starts its middleware and
three Gateway servers consuming from the same request destination.

OpenTelemetry / Application Insights lives under [observability/opentelemetry](observability/opentelemetry/dotnet/Graft.Netcore.Telemetry.AppInsightsConnector/README.md). It is not a transport plugin.

Expand All @@ -30,8 +34,8 @@ Each release archive is flat and contains the plugin shared library. Third-party

1. Download the release archive for the platform, or build the plugin (see its Readme).
2. Put `gg`, the hosted module, and the plugin library in one folder. For Linux Kafka, also put `libsasl2.so.2` and `libsasl2.so.2.0.25` from the same archive there.
3. Start the Gateway with `--config` and one of the JSON files below. A verified SQS layout is in [samples/sqs](samples/sqs/README.md): `gg netapp.dll --config sqsplugin.json`.
4. Open `http://localhost:81/GV`, install the generated package, and call `GraftConfig.SetConfig` with the same channel settings inside `plugin`. `host` next to `runtime` is the Gateway HTTP address, not the broker.
3. Start the Gateway with `--config` and one of the JSON files below. Verified local Docker layouts are available under [samples](samples/README.md).
4. Call the Gateway from .NET with the Hypertube SDK (see [Client configuration](#client-configuration)), or open `http://localhost:81/GV` and install the generated package.

How the Gateway loads a plugin is described in the "Plugin server config" section of the [Graftcode Gateway](https://github.com/grft-dev/graftcode-gateway) README.

Expand Down Expand Up @@ -110,4 +114,28 @@ Pub/Sub (`pubsub/Readme.md`, emulator):
}
```

## Client configuration

A .NET client can call the gateway directly through the Hypertube SDK. The client config wraps the plugin object in `configurations` → package name → `plugin`, with no `runtime` or `host` keys; the plugin carries the transport.

```csharp
using Hypertube.Netcore.Sdk;
using Hypertube.Netcore.Sdk.Configuration;

RuntimeBridge.AddConfig(ConfigPriority.User, configJsonOrPathToFile);
var rtmCtx = RuntimeBridge.InitializeRC("graft.nuget.netapp");
var result = rtmCtx.GetType("netapp.Calculator").CreateInstance()
.InvokeInstanceMethod("Add", 1, 2).Execute().GetValue();
```

`AddConfig` accepts a JSON string, a path to a JSON file, or the name of an environment variable holding either. The key under `configurations` must match the name passed to `InitializeRC`. Load one plugin config per process.

| Plugin | Client config | `name` |
|---|---|---|
| RabbitMQ | [rabbitmq/Readme.md](rabbitmq/Readme.md#client-configuration) | `RabbitmqPlugin` |
| Kafka | [kafka/Readme.md](kafka/Readme.md#client-configuration) | `KafkaPlugin` |
| Service Bus | [servicebus/Readme.md](servicebus/Readme.md#client-configuration) | `ServiceBusPlugin` |
| SQS | [sqs/Readme.md](sqs/Readme.md#client-configuration) | `SqsPlugin` |
| Pub/Sub | [pubsub/Readme.md](pubsub/Readme.md#client-configuration) | `PubSubPlugin` |

Part of the [Graftcode](https://github.com/grft-dev/graftcode) project.
31 changes: 18 additions & 13 deletions kafka/Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ Download `gg` from https://github.com/grft-dev/graftcode-gateway/releases/.

## Local broker

Compose files are in [`samples/kafka`](../samples/kafka/README.md), not in this directory.
Compose files are in [`samples/kafka`](../samples/kafka) (see [samples/README.md](../samples/README.md)), not in this directory.

Apache Kafka (KRaft), broker `localhost:9092`, UI `http://localhost:8080`:

Expand All @@ -56,7 +56,7 @@ Set `"brokers": "localhost:19092"` when using Redpanda.

## Gateway

`pluginConfig.json` (also [`samples/kafka/pluginConfig.gateway.json`](../samples/kafka/pluginConfig.gateway.json)):
`pluginConfig.json`:

```json
{
Expand All @@ -73,20 +73,16 @@ Set `"brokers": "localhost:19092"` when using Redpanda.
./gg .\PhysicsCalculator.dll --config .\pluginConfig.json
```

Open `http://localhost:81/GV` and install the generated package.
Open `http://localhost:81/GV` to install the generated package, or call the Gateway from .NET with the Hypertube SDK (see [Client configuration](#client-configuration)).

## Client
## Client configuration

A full example is [`samples/kafka/graftConfig.kafka.example.json`](../samples/kafka/graftConfig.kafka.example.json). Use a client `groupId` such as `graft-client`; the plugin still adds a unique suffix. Kafka bootstrap servers belong in `plugin.brokers`. When the runtime also needs the Gateway HTTP address, set `"host": "localhost:80"` next to `runtime`, as in the [SQS client config](../samples/sqs/graftConfig.sqs.example.json).
A .NET client can call the gateway through the Hypertube SDK. The client config has no `runtime` or `host` keys; the plugin carries the transport. Use a `groupId` different from the gateway's (`graft-gateway`).

```csharp
string configSource =
"""
```json
{
"configurations": {
"graft.nuget.PhysicsCalculator": {
"runtime": "netcore",
"stateless": true,
"graft.nuget.netapp": {
"plugin": {
"name": "KafkaPlugin",
"brokers": "localhost:9092",
Expand All @@ -98,11 +94,20 @@ string configSource =
}
}
}
""";
```

graft.nuget.PhysicsCalculator.GraftConfig.SetConfig(configSource);
```csharp
using Hypertube.Netcore.Sdk;
using Hypertube.Netcore.Sdk.Configuration;

RuntimeBridge.AddConfig(ConfigPriority.User, configJsonOrPathToFile);
var rtmCtx = RuntimeBridge.InitializeRC("graft.nuget.netapp");
var result = rtmCtx.GetType("netapp.Calculator").CreateInstance()
.InvokeInstanceMethod("Add", 1, 2).Execute().GetValue();
```

`AddConfig` accepts a JSON string, a path to a JSON file, or the name of an environment variable holding either. The key under `configurations` must match the name passed to `InitializeRC`. Load one plugin config per process.

## Configuration reference

| Field | Required | Description |
Expand Down
59 changes: 38 additions & 21 deletions pubsub/Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ Download `gg` from https://github.com/grft-dev/graftcode-gateway/releases/.

## Emulator

Sample files and compose live in [`samples/pubsub`](../samples/pubsub/README.md). From `pubsub/` you can start the same emulator:
Sample files and compose live in [`samples/pubsub`](../samples/pubsub) (see [samples/README.md](../samples/README.md)). From `pubsub/` you can start the same emulator:

```bash
docker compose up -d
Expand All @@ -84,7 +84,7 @@ This layout is the same shape as the SQS sample. Put these files in one folder:
- the hosted module, for example `netapp.dll`
- `PubSubPlugin.dll`

`pubsubplugin.json` (same contents as [`samples/pubsub/pluginConfig.gateway.json`](../samples/pubsub/pluginConfig.gateway.json)):
`pubsubplugin.json`:

```json
{
Expand All @@ -104,25 +104,42 @@ From that folder, with the emulator running:
.\gg.exe netapp.dll --config pubsubplugin.json
```

Open `http://localhost:81/GV` and install the generated package.
Open `http://localhost:81/GV` to install the generated package, or call the Gateway from .NET with the Hypertube SDK (see [Client configuration](#client-configuration)).

## Client
## Google Cloud credentials and permissions

`host` is the Gateway (`localhost:80`), not Pub/Sub. `clientconfig.json` matches [`samples/pubsub/graftConfig.pubsub.example.json`](../samples/pubsub/graftConfig.pubsub.example.json):
On Google Cloud, omit `emulatorHost` and `verifySsl`. Provide credentials with one of:

```csharp
graft.nuget.netapp.GraftConfig.SetConfig("clientconfig.json");
var calculator = new graft.nuget.netapp.Calculator();
calculator.Add(1, 2);
- `accessToken`, or `PUBSUB_ACCESS_TOKEN`
- `credentialsFile`, or `GOOGLE_APPLICATION_CREDENTIALS`, pointing at a service-account JSON key
- the GCE metadata server, when neither of the above is set

The gateway identity needs `pubsub.subscriptions.consume` on the request subscription and `pubsub.topics.publish` on reply topics. A client needs `pubsub.topics.publish` on the request topic and `pubsub.subscriptions.consume` on its reply subscription. `autoCreate` also needs permission to create topics and subscriptions. Set `autoCreate` to false in production and create the resources ahead of time when the runtime identity should not administer Pub/Sub.

## One-way calls

Set `"oneWay": true` on both sides. The client omits `replyTo` and does not wait. The gateway processes the request and acks it without publishing a reply. A reply topic is not required. Client `plugin` object:

```json
{
"name": "PubSubPlugin",
"projectId": "graftcode-local",
"emulatorHost": "localhost:8085",
"requestTopic": "graft-requests",
"oneWay": true,
"autoCreate": true,
"verifySsl": false
}
```

## Client configuration

A .NET client can call the gateway through the Hypertube SDK. The client config has no `runtime` or `host` keys; the plugin carries the transport. Emulator values. Each client process needs its own `replyTopic`.

```json
{
"configurations": {
"graft.nuget.netapp": {
"runtime": "netcore",
"host": "localhost:80",
"stateless": true,
"plugin": {
"name": "PubSubPlugin",
"projectId": "graftcode-local",
Expand All @@ -139,17 +156,17 @@ calculator.Add(1, 2);
}
```

On Google Cloud, omit `emulatorHost` and `verifySsl`. Provide credentials with one of:

- `accessToken`, or `PUBSUB_ACCESS_TOKEN`
- `credentialsFile`, or `GOOGLE_APPLICATION_CREDENTIALS`, pointing at a service-account JSON key
- the GCE metadata server, when neither of the above is set

The gateway identity needs `pubsub.subscriptions.consume` on the request subscription and `pubsub.topics.publish` on reply topics. A client needs `pubsub.topics.publish` on the request topic and `pubsub.subscriptions.consume` on its reply subscription. `autoCreate` also needs permission to create topics and subscriptions. Set `autoCreate` to false in production and create the resources ahead of time when the runtime identity should not administer Pub/Sub.
```csharp
using Hypertube.Netcore.Sdk;
using Hypertube.Netcore.Sdk.Configuration;

## One-way calls
RuntimeBridge.AddConfig(ConfigPriority.User, configJsonOrPathToFile);
var rtmCtx = RuntimeBridge.InitializeRC("graft.nuget.netapp");
var result = rtmCtx.GetType("netapp.Calculator").CreateInstance()
.InvokeInstanceMethod("Add", 1, 2).Execute().GetValue();
```

Set `"oneWay": true` on both sides. The client omits `replyTo` and does not wait. The gateway processes the request and acks it without publishing a reply. A reply topic is not required. See [`samples/pubsub/pluginConfig.oneway.json`](../samples/pubsub/pluginConfig.oneway.json).
`AddConfig` accepts a JSON string, a path to a JSON file, or the name of an environment variable holding either. The key under `configurations` must match the name passed to `InitializeRC`. Load one plugin config per process.

## Configuration reference

Expand Down
34 changes: 19 additions & 15 deletions rabbitmq/Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,40 +73,44 @@ docker exec -it graftcode-rabbitmq rabbitmqadmin declare queue name=myqueue.repl
./gg .\PhysicsCalculator.dll --config .\pluginConfig.json
```

Open `http://localhost:81/GV` and install the generated package.
Open `http://localhost:81/GV` to install the generated package, or call the Gateway from .NET with the Hypertube SDK (see [Client configuration](#client-configuration)).

## Client
## Client configuration

`host` inside `configurations` is the Gateway address. Broker host and port stay in `plugin`.
A .NET client can call the gateway through the Hypertube SDK. The client config has no `runtime` or `host` keys; the plugin carries the transport. Port `5673` and user `graftcode` match [samples/rabbitmq](../samples/rabbitmq). The standalone broker above uses `5672` and `guest`.

```csharp
string configSource =
"""
```json
{
"configurations": {
"graft.nuget.PhysicsCalculator": {
"runtime": "netcore",
"host": "localhost:80",
"stateless": true,
"graft.nuget.netapp": {
"plugin": {
"name": "RabbitmqPlugin",
"host": "localhost",
"port": 5672,
"port": 5673,
"queue": "myqueue",
"replyQueue": "myqueue.reply",
"user": "guest",
"password": "guest",
"user": "graftcode",
"password": "graftcode",
"vhost": "/",
"rpcTimeoutMs": 30000
}
}
}
}
""";
```

graft.nuget.PhysicsCalculator.GraftConfig.SetConfig(configSource);
```csharp
using Hypertube.Netcore.Sdk;
using Hypertube.Netcore.Sdk.Configuration;

RuntimeBridge.AddConfig(ConfigPriority.User, configJsonOrPathToFile);
var rtmCtx = RuntimeBridge.InitializeRC("graft.nuget.netapp");
var result = rtmCtx.GetType("netapp.Calculator").CreateInstance()
.InvokeInstanceMethod("Add", 1, 2).Execute().GetValue();
```

`AddConfig` accepts a JSON string, a path to a JSON file, or the name of an environment variable holding either. The key under `configurations` must match the name passed to `InitializeRC`. Load one plugin config per process.

## Configuration reference

| Field | Required | Description |
Expand Down
60 changes: 60 additions & 0 deletions samples/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# Local Docker samples

These samples run each messaging service locally together with three Graftcode
Gateway (`gg`) servers consuming from the same request queue or topic.

Available samples:

- `servicebus` - Azure Service Bus emulator on port `5672`; GG on `10301`
- `rabbitmq` - RabbitMQ on port `5673`, management UI on `15672`; GG on `10302`
- `kafka` - Kafka on port `9092`, Kafka UI on `8080`; GG on `10303`
- `sqs` - LocalStack SQS on port `4566`; GG on `10304`
- `pubsub` - Google Pub/Sub emulator on port `8085`; GG on `10305`

The corresponding Graft Vision ports are `10401` through `10405`.

## Prerequisites

- Docker Desktop with Docker Compose
- Internet access during the first image build

The server image downloads the latest Linux Graftcode Gateway and the latest
matching plugin release. Each sample includes `server/netapp.dll` as the hosted
test module.

## Run a sample

Open PowerShell in a sample directory and run:

```powershell
.\run.ps1
```

This executes:

```powershell
docker compose up -d --build
```

Only the first GG server publishes its WebSocket and Vision ports to the host.
The other two servers are internal consumers, avoiding host-port conflicts
while demonstrating competing consumers.

Stop a sample with:

```powershell
docker compose down
```

Use `docker compose down -v` for SQS if you also want to remove persisted
LocalStack data.

## Configuration

The gateway-side plugin configuration is in `server/pluginconfig.json`.
Client applications must use the matching broker address, request destination,
reply destination, and credentials.

`kafka-init` and `sqs-init` are one-shot initialization services. Their expected
state after startup is `Exited (0)`: Kafka topics or SQS queues have been
created successfully.
29 changes: 0 additions & 29 deletions samples/kafka/README.md

This file was deleted.

10 changes: 0 additions & 10 deletions samples/kafka/docker-compose.redpanda.yml

This file was deleted.

Loading
Loading