Skip to content

Commit 8bd47fd

Browse files
feat: Add DatabaseSessionService with JDBC and Flyway support
fixes #665 Summary Implements a production-ready database-backed session service that provides persistent storage for ADK sessions, events, and state using JDBC. Key Features JDBC with HikariCP connection pooling for optimal performance Flyway migrations for schema versioning and zero-downtime deployments Multi-database support: PostgreSQL, MySQL, H2, Cloud Spanner, and other RDBMS Thread-safe operations with pessimistic locking for concurrent updates Comprehensive test coverage with H2 in-memory database and Integration tests for PostgreSQL , MySQL and Spanner(using emulator). Dialect-aware JSON storage (JSONB for PostgreSQL, CLOB for others) Event filtering and pagination for efficient data retrieval Architecture Located in contrib/database-session-service module Minimal core dependencies footprint Users explicitly opt-in via dependency Follows existing contrib pattern Tasks [] Implement DatabaseSessionService with JDBC (no ORM dependencies) [] Add multi-database support (PostgreSQL, MySQL, H2, Spanner) [] Implement 3-tier state storage (app/user/session levels) [] Add Flyway migrations for schema management [] Add comprehensive test suite (unit + integration tests) [] Add documentation and usage examples [] Address code review feedback
1 parent e01df11 commit 8bd47fd

Some content is hidden

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

54 files changed

+13438
-1
lines changed
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
# Database Session Service
2+
3+
JDBC-based session service implementation for ADK Java.
4+
5+
## Features
6+
7+
- **No ORM Dependencies**: Uses JDBC with HikariCP for connection pooling
8+
- **Multi-Database Support**: PostgreSQL, MySQL, H2 (SQLite not supported)
9+
- **Automatic Schema Management**: Flyway migrations handle table creation/updates
10+
- **3-Tier State Storage**: Separate tables for app-level, user-level, and session-level state
11+
- **Reactive API**: RxJava 3 Single/Maybe/Completable return types
12+
13+
## Dependencies
14+
15+
- **HikariCP**: High-performance JDBC connection pool
16+
- **Flyway**: Database schema versioning and migration
17+
- **Jackson**: JSON serialization for events and state
18+
- **RxJava 3**: Reactive programming support
19+
20+
## Database Schema
21+
22+
The service creates and manages these tables:
23+
24+
- `app_states`: Application-level state (shared across all users)
25+
- `user_states`: User-level state (shared across user's sessions)
26+
- `sessions`: Individual session data
27+
- `events`: Event history for each session
28+
29+
## Usage
30+
31+
```java
32+
// Create service with database URL
33+
String dbUrl = "jdbc:postgresql://localhost:5432/adk?user=postgres&password=secret";
34+
try (DatabaseSessionService sessionService = new DatabaseSessionService(dbUrl)) {
35+
36+
// Create a session
37+
Session session = sessionService.createSession(
38+
"myApp",
39+
"user123",
40+
new ConcurrentHashMap<>(),
41+
null
42+
).blockingGet();
43+
44+
// Append an event
45+
Event event = Event.builder()
46+
.id(UUID.randomUUID().toString())
47+
.invocationId("inv-1")
48+
.timestamp(System.currentTimeMillis())
49+
.build();
50+
51+
Event appendedEvent = sessionService.appendEvent(session, event).blockingGet();
52+
}
53+
```
54+
55+
## Supported Databases
56+
57+
- **PostgreSQL**: Full support with JSONB
58+
- URL: `jdbc:postgresql://host:port/database?user=...&password=...`
59+
- **MySQL**: Full support with JSON
60+
- URL: `jdbc:mysql://host:port/database?user=...&password=...`
61+
- **H2**: For testing and development
62+
- URL: `jdbc:h2:mem:testdb` or `jdbc:h2:file:./data/mydb`
63+
- **Cloud Spanner**: Full support
64+
- URL: `jdbc:cloudspanner:/projects/PROJECT_ID/instances/INSTANCE_ID/databases/DATABASE_ID`
65+
- **SQLite**: NOT supported (no UPSERT support)
66+
67+
## State Management
68+
69+
State is stored across three tables with merge priority:
70+
71+
1. **App State** (lowest priority): `app:key` prefix
72+
2. **User State** (medium priority): `user:key` prefix
73+
3. **Session State** (highest priority): No prefix
74+
75+
When retrieving a session, states are merged: app → user → session (higher priority overwrites).
76+
77+
## Configuration
78+
79+
Optional properties can be passed to the constructor:
80+
81+
```java
82+
Map<String, Object> props = new HashMap<>();
83+
props.put("connectionTimeout", 30000);
84+
props.put("maximumPoolSize", 10);
85+
86+
DatabaseSessionService service = new DatabaseSessionService(dbUrl, props);
87+
```
Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
Copyright 2025 Google LLC
4+
5+
Licensed under the Apache License, Version 2.0 (the "License");
6+
you may not use this file except in compliance with the License.
7+
You may obtain a copy of the License at
8+
9+
http://www.apache.org/licenses/LICENSE-2.0
10+
11+
Unless required by applicable law or agreed to in writing, software
12+
distributed under the License is distributed on an "AS IS" BASIS,
13+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
See the License for the specific language governing permissions and
15+
limitations under the License.
16+
-->
17+
<project xmlns="http://maven.apache.org/POM/4.0.0"
18+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
19+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
20+
<modelVersion>4.0.0</modelVersion>
21+
22+
<parent>
23+
<groupId>com.google.adk</groupId>
24+
<artifactId>google-adk-parent</artifactId>
25+
<version>0.5.1-SNAPSHOT</version>
26+
<relativePath>../../pom.xml</relativePath>
27+
</parent>
28+
29+
<artifactId>google-adk-database-session-service</artifactId>
30+
<name>Agent Development Kit - Database Session Service</name>
31+
<description>Database integration with Agent Development Kit for User Session Management</description>
32+
33+
<dependencies>
34+
<!-- ADK Core (required) -->
35+
<dependency>
36+
<groupId>com.google.adk</groupId>
37+
<artifactId>google-adk</artifactId>
38+
<version>${project.version}</version>
39+
</dependency>
40+
41+
<!-- JDBC-based persistence with minimal dependencies -->
42+
43+
<!-- HikariCP - High-performance JDBC connection pool -->
44+
<dependency>
45+
<groupId>com.zaxxer</groupId>
46+
<artifactId>HikariCP</artifactId>
47+
</dependency>
48+
49+
<!-- Jackson for JSON serialization (minimal, standard library) -->
50+
<dependency>
51+
<groupId>com.fasterxml.jackson.core</groupId>
52+
<artifactId>jackson-databind</artifactId>
53+
</dependency>
54+
55+
<!-- RxJava for reactive API (required by BaseSessionService) -->
56+
<dependency>
57+
<groupId>io.reactivex.rxjava3</groupId>
58+
<artifactId>rxjava</artifactId>
59+
</dependency>
60+
61+
<!-- SLF4J API for logging -->
62+
<dependency>
63+
<groupId>org.slf4j</groupId>
64+
<artifactId>slf4j-api</artifactId>
65+
</dependency>
66+
67+
<!-- Database Migration -->
68+
69+
<!-- Flyway Core - Database schema migration and versioning tool -->
70+
<dependency>
71+
<groupId>org.flywaydb</groupId>
72+
<artifactId>flyway-core</artifactId>
73+
</dependency>
74+
75+
<!-- Flyway PostgreSQL Support -->
76+
<dependency>
77+
<groupId>org.flywaydb</groupId>
78+
<artifactId>flyway-database-postgresql</artifactId>
79+
<scope>runtime</scope>
80+
</dependency>
81+
82+
<!-- Flyway MySQL Support -->
83+
<dependency>
84+
<groupId>org.flywaydb</groupId>
85+
<artifactId>flyway-mysql</artifactId>
86+
<scope>runtime</scope>
87+
</dependency>
88+
89+
<!-- Flyway Spanner Support -->
90+
<dependency>
91+
<groupId>org.flywaydb</groupId>
92+
<artifactId>flyway-gcp-spanner</artifactId>
93+
<scope>runtime</scope>
94+
</dependency>
95+
96+
<!-- Database Drivers (optional - users choose their own) -->
97+
98+
<!-- PostgreSQL Driver -->
99+
<dependency>
100+
<groupId>org.postgresql</groupId>
101+
<artifactId>postgresql</artifactId>
102+
<optional>true</optional>
103+
</dependency>
104+
105+
<!-- MySQL Driver -->
106+
<dependency>
107+
<groupId>com.mysql</groupId>
108+
<artifactId>mysql-connector-j</artifactId>
109+
<optional>true</optional>
110+
</dependency>
111+
112+
<!-- Spanner JDBC Driver -->
113+
<dependency>
114+
<groupId>com.google.cloud</groupId>
115+
<artifactId>google-cloud-spanner-jdbc</artifactId>
116+
<optional>true</optional>
117+
</dependency>
118+
119+
<!-- Test Dependencies -->
120+
121+
<!-- H2 Database - In-memory database for testing -->
122+
<dependency>
123+
<groupId>com.h2database</groupId>
124+
<artifactId>h2</artifactId>
125+
<scope>test</scope>
126+
</dependency>
127+
128+
<dependency>
129+
<groupId>org.junit.jupiter</groupId>
130+
<artifactId>junit-jupiter-api</artifactId>
131+
<scope>test</scope>
132+
</dependency>
133+
134+
<dependency>
135+
<groupId>org.junit.jupiter</groupId>
136+
<artifactId>junit-jupiter-params</artifactId>
137+
<scope>test</scope>
138+
</dependency>
139+
140+
<dependency>
141+
<groupId>org.junit.jupiter</groupId>
142+
<artifactId>junit-jupiter-engine</artifactId>
143+
<scope>test</scope>
144+
</dependency>
145+
146+
<dependency>
147+
<groupId>org.slf4j</groupId>
148+
<artifactId>slf4j-simple</artifactId>
149+
<scope>test</scope>
150+
</dependency>
151+
152+
<dependency>
153+
<groupId>com.google.truth</groupId>
154+
<artifactId>truth</artifactId>
155+
<scope>test</scope>
156+
</dependency>
157+
158+
<dependency>
159+
<groupId>org.mockito</groupId>
160+
<artifactId>mockito-core</artifactId>
161+
<scope>test</scope>
162+
</dependency>
163+
</dependencies>
164+
165+
<build>
166+
<resources>
167+
<resource>
168+
<directory>src/main/resources</directory>
169+
<filtering>true</filtering>
170+
</resource>
171+
</resources>
172+
<plugins>
173+
<plugin>
174+
<artifactId>maven-compiler-plugin</artifactId>
175+
</plugin>
176+
<plugin>
177+
<groupId>org.jacoco</groupId>
178+
<artifactId>jacoco-maven-plugin</artifactId>
179+
</plugin>
180+
<plugin>
181+
<groupId>org.apache.maven.plugins</groupId>
182+
<artifactId>maven-surefire-plugin</artifactId>
183+
</plugin>
184+
</plugins>
185+
</build>
186+
</project>

0 commit comments

Comments
 (0)