Skip to content

Commit 4d7a95b

Browse files
authored
feat: large refactor (#3)
- Pull in protos as submodule - Internal types to ser/de with proto codegen for validations - Full RPC coverage - Refac of client organization - Config classes - All unary RPCs return futures - Initial versions of "managed" streaming RPCs - Gradle submodules
1 parent 945998f commit 4d7a95b

File tree

85 files changed

+3115
-2295
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

85 files changed

+3115
-2295
lines changed

.github/workflows/ci.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ name: Test and submit dependencies
22

33
on:
44
push:
5-
branches: ["main"]
5+
branches: [ "main" ]
66
pull_request:
7-
branches: ["main"]
7+
branches: [ "main" ]
88

99
jobs:
1010
build:

.github/workflows/publish.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name: Package and publish
22

33
on:
44
release:
5-
types: [created]
5+
types: [ created ]
66

77
jobs:
88
build:

.gitmodules

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
[submodule "proto"]
2-
path = s2/src/main/proto
2+
path = s2-internal/src/main/proto
33
url = https://github.com/s2-streamstore/s2-protos.git

README.md

Lines changed: 17 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,7 @@
33
> [!WARNING]
44
> This SDK is actively in development, and not officially supported yet!
55
6-
A Java SDK for interacting with the S2 streaming service. This SDK provides a hopefully convenientinterface for working with S2's gRPC-based streaming API.
7-
8-
## Features
9-
10-
- Fluent builder pattern for client configuration
11-
- Synchronous and asynchronous stream operations
12-
- Basin and stream management
13-
- Automatic channel management for basin switching
6+
A Java SDK for interacting with the S2 streaming service.
147

158
## Prerequisites
169

@@ -21,30 +14,34 @@ A Java SDK for interacting with the S2 streaming service. This SDK provides a ho
2114
### Building from Source
2215

2316
1. Clone the repository:
17+
2418
```bash
2519
git clone --recurse-submodules https://github.com/s2-streamstore/s2-sdk-java
2620
cd s2-sdk-java
2721
```
2822

2923
2. Build the project:
24+
3025
```bash
3126
./gradlew build
3227
```
3328

3429
3. Install to local Maven repository:
30+
3531
```bash
36-
./gradlew s2:publishToMavenLocal
32+
./gradlew publishToMavenLocal
3733
```
3834

3935
### Using Maven (Local Published Artifact)
4036

4137
Add this dependency to your `pom.xml`:
4238

4339
```xml
40+
4441
<dependency>
45-
<groupId>dev.s2</groupId>
46-
<artifactId>s2</artifactId>
47-
<version>0.0.1</version>
42+
<groupId>dev.s2</groupId>
43+
<artifactId>s2-sdk</artifactId>
44+
<version>0.0.5-SNAPSHOT</version>
4845
</dependency>
4946
```
5047

@@ -54,120 +51,33 @@ Add this dependency to your `build.gradle.kts`:
5451

5552
```kotlin
5653
dependencies {
57-
implementation("dev.s2:s2:0.0.1")
58-
}
59-
```
60-
61-
## Quick Start
62-
63-
Here's a simple example that demonstrates the basic usage of the SDK:
64-
65-
```java
66-
import s2.services.Client;
67-
import s2.v1alpha.*;
68-
69-
// Create a client
70-
var client = Client.newBuilder()
71-
.host("aws.s2.dev")
72-
.port(443)
73-
.bearerToken("your-token")
74-
.build();
75-
76-
// List all basins
77-
var basins = client.account().listBasins("");
78-
basins.forEach(basin ->
79-
System.out.printf("Basin: %s (state: %s)%n",
80-
basin.getName(),
81-
basin.getState())
82-
);
83-
84-
// Create a new basin
85-
var basinConfig = BasinConfig.newBuilder()
86-
.setDefaultStreamConfig(
87-
StreamConfig.newBuilder()
88-
.setStorageClass(StorageClass.STORAGE_CLASS_STANDARD)
89-
.build()
90-
)
91-
.build();
92-
93-
var newBasin = client.account().createBasin("my-basin", basinConfig);
94-
95-
// Switch to the basin
96-
client.useBasin("my-basin");
97-
98-
// Create a stream
99-
var streamConfig = StreamConfig.newBuilder()
100-
.setStorageClass(StorageClass.STORAGE_CLASS_STANDARD)
101-
.build();
102-
103-
client.basin().createStream("my-stream", streamConfig);
104-
105-
// Append a record
106-
var record = AppendRecord.newBuilder()
107-
.setBody(ByteString.copyFromUtf8("Hello, S2!"))
108-
.build();
109-
110-
var appendOutput = client.stream().append("my-stream", List.of(record));
111-
112-
// Read records
113-
var readOutput = client.stream().read("my-stream", 0, null);
114-
if (readOutput.hasBatch()) {
115-
readOutput.getBatch().getRecordsList().forEach(r ->
116-
System.out.printf("Record %d: %s%n",
117-
r.getSeqNum(),
118-
r.getBody().toStringUtf8())
119-
);
54+
implementation("dev.s2:s2-sdk:0.0.5-SNAPSHOT")
12055
}
12156
```
12257

12358
## Project Structure
12459

125-
- `s2/` - The main SDK module
126-
- `src/main/java/s2/services/` - Core service implementations
127-
- `src/main/java/s2/channel/` - Channel management
128-
- `src/main/java/s2/auth/` - Authentication handling
129-
- `src/main/proto/` - Protocol Buffer definitions
130-
- `app/` - Example application demonstrating SDK usage
60+
- `s2/` - The main SDK module.
61+
- `s2-internal/` - Code and types generated from
62+
the [S2 protobuf definitions](https://github.com/s2-streamstore/s2-protos).
63+
- `app/` - Example application demonstrating SDK usage.
13164

13265
## Running the Example App
13366

13467
1. Set required environment variables:
68+
13569
```bash
13670
export S2_HOST=aws.s2.dev
13771
export S2_PORT=443
13872
export S2_TOKEN=your-token
13973
```
14074

14175
2. Run the example:
76+
14277
```bash
14378
./gradlew app:run
14479
```
14580

146-
## Advanced Usage
147-
148-
### Asynchronous Operations
149-
150-
The SDK supports asynchronous operations through the `AsyncStreamService`:
151-
152-
```java
153-
// Async append
154-
client.streamAsync().appendAsync(streamName, records)
155-
.thenAccept(output ->
156-
System.out.printf("Append completed: %d to %d%n",
157-
output.getStartSeqNum(),
158-
output.getEndSeqNum())
159-
);
160-
161-
// Streaming read session
162-
client.streamAsync().openReadSession(
163-
streamName,
164-
0,
165-
null,
166-
response -> System.out.println("Received records: " + response.getBatch().getRecordsCount()),
167-
error -> System.err.println("Error: " + error.getMessage())
168-
);
169-
```
170-
17181
## License
17282

173-
This project is licensed under the GNU General Public License v3.0 - see the [LICENSE](LICENSE) file for details.
83+
This project is licensed under the Apache 2.0 License. See the [LICENSE](LICENSE) file for details.

app/build.gradle.kts

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
*/
66

77
plugins {
8-
application
9-
java
8+
application
9+
java
1010
}
1111

1212
repositories {
@@ -22,14 +22,29 @@ dependencies {
2222
implementation("io.grpc:grpc-protobuf:$grpcVersion")
2323
implementation("io.grpc:grpc-stub:$grpcVersion")
2424
implementation("javax.annotation:javax.annotation-api:1.3.2")
25+
implementation("ch.qos.logback:logback-classic:1.2.6")
26+
implementation("org.slf4j:slf4j-api:1.7.32")
2527
testImplementation("org.junit.jupiter:junit-jupiter:5.9.2")
2628
}
2729

28-
application {
29-
// Define the main class for the application.
30-
mainClass.set("org.example.app.App")
30+
val executables = mapOf(
31+
"AccountDemo" to "org.example.app.AccountDemo",
32+
"BasinDemo" to "org.example.app.BasinDemo",
33+
"BufferedReadSessionDemo" to "org.example.app.BufferedReadSessionDemo",
34+
"FutureAppendSessionDemo" to "org.example.app.FutureAppendSessionDemo",
35+
"ReadSessionDemo" to "org.example.app.ReadSessionDemo",
36+
)
37+
38+
executables.forEach { name, mainClassName ->
39+
tasks.register<JavaExec>("run${name}") {
40+
group = "application"
41+
description = "Run the $name executable"
42+
classpath = sourceSets["main"].runtimeClasspath
43+
mainClass.set(mainClassName)
44+
}
3145
}
3246

47+
3348
tasks.test {
3449
useJUnitPlatform()
3550
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package org.example.app;
2+
3+
import java.time.Duration;
4+
import java.util.UUID;
5+
import org.slf4j.Logger;
6+
import org.slf4j.LoggerFactory;
7+
import s2.client.Client;
8+
import s2.config.Config;
9+
import s2.config.Endpoints;
10+
import s2.types.Age;
11+
import s2.types.CreateBasinRequest;
12+
import s2.types.ListBasinsRequest;
13+
import s2.types.StorageClass;
14+
import s2.types.StreamConfig;
15+
16+
public class AccountDemo {
17+
18+
private static final Logger logger = LoggerFactory.getLogger(AccountDemo.class.getName());
19+
20+
public static void main(String[] args) throws Exception {
21+
var config =
22+
Config.newBuilder(System.getenv("S2_AUTH_TOKEN"))
23+
.withEndpoints(Endpoints.fromEnvironment())
24+
.build();
25+
26+
try (var client = new Client(config)) {
27+
28+
var basins = client.listBasins(ListBasinsRequest.newBuilder().build()).get();
29+
basins.elems().forEach(basin -> logger.info("basin={}", basin));
30+
31+
var newBasin =
32+
client
33+
.createBasin(
34+
CreateBasinRequest.newBuilder()
35+
.withBasin(UUID.randomUUID().toString())
36+
.withDefaultStreamConfig(
37+
StreamConfig.newBuilder()
38+
.withRetentionPolicy(new Age(Duration.ofDays(7)))
39+
.withStorageClass(StorageClass.STANDARD)
40+
.build())
41+
.build())
42+
.get();
43+
logger.info("newBasin={}", newBasin);
44+
45+
client.deleteBasin(newBasin.name()).get();
46+
logger.info("deleted basin {}", newBasin);
47+
}
48+
}
49+
}

0 commit comments

Comments
 (0)