Skip to content

Commit 8026ea0

Browse files
author
lucas
committed
feat: Add MySQL Session Service implementation
1 parent 7045a4d commit 8026ea0

12 files changed

Lines changed: 2234 additions & 0 deletions

File tree

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
name: MySQL session service integration
2+
3+
on:
4+
pull_request:
5+
branches:
6+
- main
7+
paths:
8+
- "contrib/mysql-session-service/**"
9+
- "core/**"
10+
- "pom.xml"
11+
- ".mvn/**"
12+
- ".github/workflows/mysql-session-service-integration.yml"
13+
- "mvnw"
14+
- "mvnw.cmd"
15+
16+
concurrency:
17+
group: ${{ github.workflow }}-${{ github.head_ref || github.ref }}
18+
cancel-in-progress: true
19+
20+
permissions:
21+
contents: read
22+
23+
jobs:
24+
mysql-integration:
25+
runs-on: ubuntu-latest
26+
timeout-minutes: 20
27+
28+
steps:
29+
- name: Checkout code
30+
uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
31+
32+
- name: Set up Java 17
33+
uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5
34+
with:
35+
distribution: temurin
36+
java-version: "17"
37+
cache: maven
38+
39+
- name: Install ADK core without tests
40+
run: ./mvnw -pl core -am -DskipTests install
41+
42+
- name: Run MySQL unit and container integration tests
43+
run: ./mvnw -pl contrib/mysql-session-service -Pintegration-tests verify
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
# MySQL Session Service for ADK
2+
3+
This module provides a MySQL-backed implementation of ADK's `BaseSessionService`. It persists
4+
sessions, events, and app- and user-scoped state while keeping the MySQL JDBC driver and connection
5+
pool under the application's control.
6+
7+
## Dependency
8+
9+
Use the same version for ADK core and this module. The MySQL driver and a production connection pool
10+
are intentionally not forced on consumers; add the implementations used by your application.
11+
12+
```xml
13+
<properties>
14+
<adk.version>1.7.2-SNAPSHOT</adk.version>
15+
</properties>
16+
17+
<dependencies>
18+
<dependency>
19+
<groupId>com.google.adk</groupId>
20+
<artifactId>google-adk</artifactId>
21+
<version>${adk.version}</version>
22+
</dependency>
23+
<dependency>
24+
<groupId>com.google.adk</groupId>
25+
<artifactId>google-adk-mysql-session-service</artifactId>
26+
<version>${adk.version}</version>
27+
</dependency>
28+
<dependency>
29+
<groupId>com.mysql</groupId>
30+
<artifactId>mysql-connector-j</artifactId>
31+
<version>8.3.0</version>
32+
</dependency>
33+
<dependency>
34+
<groupId>com.zaxxer</groupId>
35+
<artifactId>HikariCP</artifactId>
36+
<version>5.1.0</version>
37+
</dependency>
38+
</dependencies>
39+
```
40+
41+
## Database schema
42+
43+
MySQL 8.0 or newer is required. Apply the packaged
44+
[`mysql-session-service-schema.sql`](src/main/resources/mysql-session-service-schema.sql) before
45+
constructing the service.
46+
47+
The session identity is the ADK `SessionKey` tuple `(app_name, user_id, session_id)`, so the same
48+
client-generated session ID can safely be reused in a different app or user scope. Events use an
49+
internal monotonic sequence to provide deterministic ordering when multiple events have the same
50+
millisecond timestamp.
51+
52+
The schema in earlier preview revisions of this contribution used globally unique `session_id` and
53+
`event_id` primary keys. Recreate or migrate those tables before upgrading to this schema.
54+
55+
## Usage
56+
57+
Configure a `DataSource`, construct the service, and pass it to the current `Runner` builder.
58+
59+
```java
60+
import com.google.adk.runner.Runner;
61+
import com.google.adk.sessions.MySqlSessionService;
62+
import com.zaxxer.hikari.HikariConfig;
63+
import com.zaxxer.hikari.HikariDataSource;
64+
65+
HikariConfig config = new HikariConfig();
66+
config.setJdbcUrl("jdbc:mysql://localhost:3306/my_db");
67+
config.setUsername("user");
68+
config.setPassword("password");
69+
HikariDataSource dataSource = new HikariDataSource(config);
70+
71+
MySqlSessionService sessionService = new MySqlSessionService(dataSource);
72+
Runner runner =
73+
Runner.builder()
74+
.agent(myAgent)
75+
.appName("my-app")
76+
.sessionService(sessionService)
77+
.build();
78+
```
79+
80+
App-prefixed (`app:`) and user-prefixed (`user:`) values supplied when creating a session are
81+
persisted in their respective shared state scopes. Temporary (`temp:`) values are returned on the
82+
newly created session but are intentionally not persisted and therefore do not appear after a
83+
reload.
84+
85+
## Testing
86+
87+
Unit and contract tests use H2 in MySQL compatibility mode and require no external services:
88+
89+
```bash
90+
./mvnw -pl contrib/mysql-session-service -am test
91+
```
92+
93+
The integration profile runs the `*IT` tests against a real MySQL container and therefore requires
94+
Docker:
95+
96+
```bash
97+
./mvnw -pl contrib/mysql-session-service -am -Pintegration-tests verify
98+
```
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
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>1.7.2-SNAPSHOT</version><!-- {x-version-update:google-adk:current} -->
26+
<relativePath>../../pom.xml</relativePath>
27+
</parent>
28+
29+
<artifactId>google-adk-mysql-session-service</artifactId>
30+
<name>Agent Development Kit - MySQL Session Management</name>
31+
<description>MySQL integration with Agent Development Kit for User Session Management</description>
32+
33+
<properties>
34+
<testcontainers.version>1.21.3</testcontainers.version>
35+
</properties>
36+
37+
<dependencyManagement>
38+
<dependencies>
39+
<dependency>
40+
<groupId>org.testcontainers</groupId>
41+
<artifactId>testcontainers-bom</artifactId>
42+
<version>${testcontainers.version}</version>
43+
<type>pom</type>
44+
<scope>import</scope>
45+
</dependency>
46+
</dependencies>
47+
</dependencyManagement>
48+
49+
<dependencies>
50+
<dependency>
51+
<groupId>com.google.adk</groupId>
52+
<artifactId>google-adk</artifactId>
53+
<version>${project.version}</version>
54+
</dependency>
55+
<dependency>
56+
<groupId>com.mysql</groupId>
57+
<artifactId>mysql-connector-j</artifactId>
58+
<version>8.3.0</version>
59+
<scope>provided</scope>
60+
</dependency>
61+
62+
<!-- Testing -->
63+
<dependency>
64+
<groupId>com.google.truth</groupId>
65+
<artifactId>truth</artifactId>
66+
<scope>test</scope>
67+
</dependency>
68+
<dependency>
69+
<groupId>org.mockito</groupId>
70+
<artifactId>mockito-core</artifactId>
71+
<scope>test</scope>
72+
</dependency>
73+
<dependency>
74+
<groupId>org.junit.jupiter</groupId>
75+
<artifactId>junit-jupiter-api</artifactId>
76+
<scope>test</scope>
77+
</dependency>
78+
<dependency>
79+
<groupId>org.junit.jupiter</groupId>
80+
<artifactId>junit-jupiter-engine</artifactId>
81+
<scope>test</scope>
82+
</dependency>
83+
84+
<dependency>
85+
<groupId>org.testcontainers</groupId>
86+
<artifactId>mysql</artifactId>
87+
<scope>test</scope>
88+
</dependency>
89+
<dependency>
90+
<groupId>org.testcontainers</groupId>
91+
<artifactId>junit-jupiter</artifactId>
92+
<scope>test</scope>
93+
</dependency>
94+
<dependency>
95+
<groupId>com.zaxxer</groupId>
96+
<artifactId>HikariCP</artifactId>
97+
<scope>test</scope>
98+
</dependency>
99+
<dependency>
100+
<groupId>org.slf4j</groupId>
101+
<artifactId>slf4j-simple</artifactId>
102+
<scope>test</scope>
103+
</dependency>
104+
<dependency>
105+
<groupId>com.h2database</groupId>
106+
<artifactId>h2</artifactId>
107+
<scope>test</scope>
108+
</dependency>
109+
</dependencies>
110+
111+
<profiles>
112+
<profile>
113+
<id>integration-tests</id>
114+
<build>
115+
<plugins>
116+
<plugin>
117+
<groupId>org.apache.maven.plugins</groupId>
118+
<artifactId>maven-failsafe-plugin</artifactId>
119+
<version>3.5.2</version>
120+
<executions>
121+
<execution>
122+
<goals>
123+
<goal>integration-test</goal>
124+
<goal>verify</goal>
125+
</goals>
126+
</execution>
127+
</executions>
128+
</plugin>
129+
</plugins>
130+
</build>
131+
</profile>
132+
</profiles>
133+
</project>

0 commit comments

Comments
 (0)