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
35 changes: 29 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@

Java client SDK for the [Fila](https://github.com/faiscadev/fila) message broker.

Uses the **FIBP** (Fila Binary Protocol) — a length-prefixed binary protocol over raw TCP or TLS.
No gRPC or protobuf dependencies.

## Installation

### Gradle

```groovy
implementation 'dev.faisca:fila-client:0.1.0'
implementation 'dev.faisca:fila-client:0.3.0'
```

### Maven
Expand All @@ -16,7 +19,7 @@ implementation 'dev.faisca:fila-client:0.1.0'
<dependency>
<groupId>dev.faisca</groupId>
<artifactId>fila-client</artifactId>
<version>0.1.0</version>
<version>0.3.0</version>
</dependency>
```

Expand Down Expand Up @@ -101,7 +104,7 @@ try (FilaClient client = FilaClient.builder("localhost:5555")
}
```

The key is sent as a `Bearer` token in the `authorization` metadata header on every RPC.
The key is sent in an AUTH frame during the FIBP handshake before any other requests.

TLS and API key auth can be combined:

Expand Down Expand Up @@ -134,7 +137,8 @@ FilaClient client = FilaClient.builder("localhost:5555").build();
| `withTls()` | Enable TLS using JVM's default trust store (cacerts) |
| `withTlsCaCert(byte[] caCertPem)` | CA certificate for TLS server verification (implies `withTls()`) |
| `withTlsClientCert(byte[] certPem, byte[] keyPem)` | Client cert + key for mTLS |
| `withApiKey(String apiKey)` | API key sent as `Bearer` token on every RPC |
| `withApiKey(String apiKey)` | API key sent in AUTH frame during FIBP handshake |
| `withBatchMode(BatchMode batchMode)` | Configure enqueue batching (default: `BatchMode.auto()`) |

All builder methods are optional. When none are set, the client connects over plaintext without authentication (backward compatible).

Expand All @@ -144,9 +148,13 @@ Enqueue a message. Returns the broker-assigned message ID (UUIDv7).

Throws `QueueNotFoundException` if the queue does not exist.

#### `enqueueMany(List<EnqueueMessage> messages) -> List<EnqueueResult>`

Enqueue multiple messages in a single FIBP frame. Each message is independently processed. All messages must target the same queue.

#### `consume(String queue, Consumer<ConsumeMessage> handler) -> ConsumerHandle`

Start consuming messages from a queue. Messages are delivered to the handler on a background thread. Nacked messages are redelivered on the same stream.
Start consuming messages from a queue. Messages are delivered to the handler on the FIBP reader thread. Nacked messages are redelivered on the same stream.

Call `handle.cancel()` to stop consuming.

Expand Down Expand Up @@ -181,7 +189,9 @@ All exceptions extend `FilaException` (unchecked):

- `QueueNotFoundException` — queue does not exist
- `MessageNotFoundException` — message does not exist (or already acked)
- `RpcException` — unexpected gRPC failure (includes status code via `getCode()`)
- `RpcException` — transport-level failure (includes status code via `getCode()`)

`RpcException.Code` values: `INTERNAL`, `UNAUTHENTICATED`, `PERMISSION_DENIED`, `UNAVAILABLE`, `CANCELLED`, `UNKNOWN`.

```java
try {
Expand All @@ -191,6 +201,19 @@ try {
}
```

## Transport: FIBP

This SDK uses FIBP (Fila Binary Protocol) — a lightweight binary framing protocol over TCP. Each
frame is:

```
[4-byte big-endian length][flags:u8 | op:u8 | corr_id:u32 | payload]
```

All requests are multiplexed over a single TCP connection using correlation IDs. A background
reader thread dispatches responses. Authentication uses an AUTH op frame sent during connection
setup. Heartbeat frames keep the connection alive.

## License

AGPLv3 — see [LICENSE](LICENSE).
38 changes: 1 addition & 37 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,11 @@ plugins {
id 'maven-publish'
id 'signing'
id 'io.github.gradle-nexus.publish-plugin' version '2.0.0'
id 'com.google.protobuf' version '0.9.4'
id 'com.diffplug.spotless' version '7.0.2'
}

group = 'dev.faisca'
version = '0.2.0'
version = '0.3.0'

java {
sourceCompatibility = JavaVersion.VERSION_17
Expand All @@ -21,47 +20,12 @@ repositories {
mavenCentral()
}

def grpcVersion = '1.71.0'
def protobufVersion = '4.29.3'

dependencies {
api "io.grpc:grpc-stub:${grpcVersion}"
api "io.grpc:grpc-protobuf:${grpcVersion}"

implementation "io.grpc:grpc-netty-shaded:${grpcVersion}"
implementation "com.google.protobuf:protobuf-java:${protobufVersion}"

compileOnly 'org.apache.tomcat:annotations-api:6.0.53'

testImplementation platform('org.junit:junit-bom:5.11.4')
testImplementation 'org.junit.jupiter:junit-jupiter'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}

protobuf {
protoc {
artifact = "com.google.protobuf:protoc:${protobufVersion}"
}
plugins {
grpc {
artifact = "io.grpc:protoc-gen-grpc-java:${grpcVersion}"
}
}
generateProtoTasks {
all()*.plugins {
grpc {}
}
}
}

sourceSets {
main {
proto {
srcDir 'proto'
}
}
}

test {
useJUnitPlatform()
testLogging {
Expand Down
197 changes: 0 additions & 197 deletions proto/fila/v1/admin.proto

This file was deleted.

28 changes: 0 additions & 28 deletions proto/fila/v1/messages.proto

This file was deleted.

Loading
Loading