Skip to content
Open
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
87 changes: 87 additions & 0 deletions contrib/database-session-service/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
# Database Session Service

JDBC-based session service implementation for ADK Java.

## Features

- **No ORM Dependencies**: Uses JDBC with HikariCP for connection pooling
- **Multi-Database Support**: PostgreSQL, MySQL, H2 (SQLite not supported)
- **Automatic Schema Management**: Flyway migrations handle table creation/updates
- **3-Tier State Storage**: Separate tables for app-level, user-level, and session-level state
- **Reactive API**: RxJava 3 Single/Maybe/Completable return types

## Dependencies

- **HikariCP**: High-performance JDBC connection pool
- **Flyway**: Database schema versioning and migration
- **Jackson**: JSON serialization for events and state
- **RxJava 3**: Reactive programming support

## Database Schema

The service creates and manages these tables:

- `app_states`: Application-level state (shared across all users)
- `user_states`: User-level state (shared across user's sessions)
- `sessions`: Individual session data
- `events`: Event history for each session

## Usage

```java
// Create service with database URL
String dbUrl = "jdbc:postgresql://localhost:5432/adk?user=postgres&password=secret";
try (DatabaseSessionService sessionService = new DatabaseSessionService(dbUrl)) {

// Create a session
Session session = sessionService.createSession(
"myApp",
"user123",
new ConcurrentHashMap<>(),
null
).blockingGet();

// Append an event
Event event = Event.builder()
.id(UUID.randomUUID().toString())
.invocationId("inv-1")
.timestamp(System.currentTimeMillis())
.build();

Event appendedEvent = sessionService.appendEvent(session, event).blockingGet();
}
```

## Supported Databases

- **PostgreSQL**: Full support with JSONB
- URL: `jdbc:postgresql://host:port/database?user=...&password=...`
- **MySQL**: Full support with JSON
- URL: `jdbc:mysql://host:port/database?user=...&password=...`
- **H2**: For testing and development
- URL: `jdbc:h2:mem:testdb` or `jdbc:h2:file:./data/mydb`
- **Cloud Spanner**: Full support
- URL: `jdbc:cloudspanner:/projects/PROJECT_ID/instances/INSTANCE_ID/databases/DATABASE_ID`
- **SQLite**: NOT supported (no UPSERT support)

## State Management

State is stored across three tables with merge priority:

1. **App State** (lowest priority): `app:key` prefix
2. **User State** (medium priority): `user:key` prefix
3. **Session State** (highest priority): No prefix

When retrieving a session, states are merged: app → user → session (higher priority overwrites).

## Configuration

Optional properties can be passed to the constructor:

```java
Map<String, Object> props = new HashMap<>();
props.put("connectionTimeout", 30000);
props.put("maximumPoolSize", 10);

DatabaseSessionService service = new DatabaseSessionService(dbUrl, props);
```
186 changes: 186 additions & 0 deletions contrib/database-session-service/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright 2025 Google LLC

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>com.google.adk</groupId>
<artifactId>google-adk-parent</artifactId>
<version>0.5.1-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>

<artifactId>google-adk-database-session-service</artifactId>
<name>Agent Development Kit - Database Session Service</name>
<description>Database integration with Agent Development Kit for User Session Management</description>

<dependencies>
<!-- ADK Core (required) -->
<dependency>
<groupId>com.google.adk</groupId>
<artifactId>google-adk</artifactId>
<version>${project.version}</version>
</dependency>

<!-- JDBC-based persistence with minimal dependencies -->

<!-- HikariCP - High-performance JDBC connection pool -->
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
</dependency>

<!-- Jackson for JSON serialization (minimal, standard library) -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>

<!-- RxJava for reactive API (required by BaseSessionService) -->
<dependency>
<groupId>io.reactivex.rxjava3</groupId>
<artifactId>rxjava</artifactId>
</dependency>

<!-- SLF4J API for logging -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>

<!-- Database Migration -->

<!-- Flyway Core - Database schema migration and versioning tool -->
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
</dependency>

<!-- Flyway PostgreSQL Support -->
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-database-postgresql</artifactId>
<scope>runtime</scope>
</dependency>

<!-- Flyway MySQL Support -->
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-mysql</artifactId>
<scope>runtime</scope>
</dependency>

<!-- Flyway Spanner Support -->
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-gcp-spanner</artifactId>
<scope>runtime</scope>
</dependency>

<!-- Database Drivers (optional - users choose their own) -->

<!-- PostgreSQL Driver -->
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<optional>true</optional>
</dependency>

<!-- MySQL Driver -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<optional>true</optional>
</dependency>

<!-- Spanner JDBC Driver -->
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>google-cloud-spanner-jdbc</artifactId>
<optional>true</optional>
</dependency>

<!-- Test Dependencies -->

<!-- H2 Database - In-memory database for testing -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>com.google.truth</groupId>
<artifactId>truth</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Loading