Skip to content

Conversation

@middt
Copy link

@middt middt commented Feb 23, 2025

Description

This PR adds a new state store component for ClickHouse, a column-oriented database management system. The ClickHouse state store component provides the following features:

  • Basic CRUD operations for state management
  • Support for TTL (Time-To-Live)
  • ETag support for optimistic concurrency
  • Bulk operations support
  • Username/password authentication
  • Uses ReplacingMergeTree engine for efficient updates

Key implementation details:

  • Uses the official ClickHouse Go driver
  • Implements the full state.Store interface
  • Handles connection management and cleanup
  • Includes comprehensive integration tests
  • Follows Dapr's component development guidelines

Implementation Details

The component includes:

  1. State store implementation (clickhouse.go)

    • Full CRUD operations
    • Bulk operations
    • TTL support
    • ETag support
    • Authentication support
  2. Tests (clickhouse_test.go)

    • Integration tests for CRUD operations
    • Metadata validation tests
    • Authentication tests
    • Cleanup handling
  3. Configuration options:

    apiVersion: dapr.io/v1alpha1
    kind: Component
    metadata:
      name: statestore
      namespace: default
    spec:
      type: state.clickhouse
      version: v1
      metadata:
      - name: clickhouseURL
        value: "tcp://localhost:9000"
      - name: databaseName
        value: "dapr_state"
      - name: tableName
        value: "state_store"
      - name: username
        value: "default"
      - name: password
        value: ""

Checklist

  • Code compiles correctly
  • Created/updated tests
  • Extended the documentation / Created issue in the https://github.com/dapr/docs/ repo: dapr/docs#[issue number]

Testing Done

  1. Unit tests for metadata validation
  2. Integration tests for:
    • Basic CRUD operations
    • TTL functionality
    • ETag support
    • Bulk operations
    • Authentication
    • Error handling

Tests were run against ClickHouse v23.8 using the official Go driver.

Additional Notes

  • The component uses ReplacingMergeTree engine for better update performance
  • Includes proper cleanup in tests to avoid test pollution
  • Follows ClickHouse best practices for table design
  • Implements proper connection management and cleanup

@middt middt requested review from a team as code owners February 23, 2025 04:10
@JoshVanL
Copy link
Contributor

Thanks @middt, implementation generally looks good to me!

Would it be possible to add conformance tests for this too? It seems like we should be able to spin up a click house docker compose.

middt added 3 commits March 14, 2025 10:02
…tation

Signed-off-by: Mehmet TOSUN <93265833+middt@users.noreply.github.com>
…tion handling

Signed-off-by: Mehmet TOSUN <93265833+middt@users.noreply.github.com>
… connection handling

Signed-off-by: Mehmet TOSUN <93265833+middt@users.noreply.github.com>
@middt middt force-pushed the dapr-state-store-clickhouse branch from 1b2a8de to 2c8934c Compare March 14, 2025 07:02
@middt
Copy link
Author

middt commented Mar 14, 2025

Thank you for the feedback! @JoshVanL I've implemented the conformance tests for the ClickHouse state store in this PR:

  1. Created a Docker Compose setup in /tests/certification/state/clickhouse/docker-compose.yml that spins up a ClickHouse server with proper configuration
  2. Added a conformance test file in /tests/certification/state/clickhouse/clickhouse_test.go that verifies all state store operations
  3. Created configuration files in /tests/config/state/clickhouse/clickhouse.yml for the test environment
  4. Added ClickHouse to the state store tests configuration in /tests/config/state/tests.yml

The tests verify all the key functionality including:

  • Basic CRUD operations
  • ETag support for optimistic concurrency
  • Error handling for empty and non-existent keys
  • Feature reporting

I've also addressed authentication issues by properly configuring username and password in both the Docker Compose setup and the state store implementation.

All unit tests are now passing, confirming that the implementation works correctly with the ClickHouse server.

middt added 2 commits March 14, 2025 10:05
Signed-off-by: Mehmet TOSUN <93265833+middt@users.noreply.github.com>
Signed-off-by: Mehmet TOSUN <93265833+middt@users.noreply.github.com>
@JoshVanL
Copy link
Contributor

JoshVanL commented Apr 9, 2025

Thanks @middt, I think the only thing left is to do a go mod tidy and it should be good to go 🙂

Appreciate the work on this!

…tests

Signed-off-by: Mehmet TOSUN <mehmet.tosun@gmail.com>
@middt middt force-pushed the dapr-state-store-clickhouse branch from 4f3e99d to e35c604 Compare September 1, 2025 07:33
@github-actions
Copy link

github-actions bot commented Nov 8, 2025

This pull request has been automatically marked as stale because it has not had activity in the last 30 days. It will be closed in 7 days if no further activity occurs. Please feel free to give a status update now, ping for review, or re-open when it's ready. Thank you for your contributions!

@github-actions github-actions bot added the stale label Nov 8, 2025
@github-actions
Copy link

This pull request has been automatically closed because it has not had activity in the last 37 days. Please feel free to give a status update now, ping for review, or re-open when it's ready. Thank you for your contributions!

@github-actions github-actions bot closed this Nov 15, 2025
@yaron2 yaron2 reopened this Nov 15, 2025
@github-actions github-actions bot removed the stale label Nov 15, 2025
Copy link
Contributor

@sicoyle sicoyle left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

few comments. Nice job 👏

@@ -0,0 +1,435 @@
/*
Copyright 2021 The Dapr Authors
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Copyright 2021 The Dapr Authors
Copyright 2025 The Dapr Authors

// Create database if not exists
// Note: Database and table names are validated during metadata parsing
// and come from trusted configuration, so direct string concatenation is acceptable here
createDBQuery := "CREATE DATABASE IF NOT EXISTS " + c.config.DatabaseName
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we need to make sure this behavior is documented. Have you created a docs PR for these changes by chance? We try to have a docs PR open before merging new components please 🙏

Comment on lines 330 to 334
if config.DatabaseName == "" {
return config, errors.New("ClickHouse database name is missing")
}

if config.TableName == "" {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are there fixed char limits on these we should check for by chance?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sicoyle looks like it's here.
@middt can you add a length check as well?

@@ -0,0 +1,569 @@
/*
Copyright 2021 The Dapr Authors
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Copyright 2021 The Dapr Authors
Copyright 2025 The Dapr Authors

@@ -0,0 +1,240 @@
/*
Copyright 2021 The Dapr Authors
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Copyright 2021 The Dapr Authors
Copyright 2025 The Dapr Authors

Comment on lines 16 to 34
- title: "Username and password"
description: "Authenticate using username and password."
metadata:
- name: Username
type: string
required: false
description: |
Username for ClickHouse host. Defaults to empty.
example: "default"
default: ""
- name: Password
type: string
required: false
sensitive: true
description: |
Password for ClickHouse host. No default. Use secretKeyRef for
secret reference
example: "mypassword"
default: ""
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this says that none of the fields for auth are required. Can you please confirm if this is this true that we can connect without a username and password?

example: "mypassword"
default: ""
metadata:
- name: ClickhouseURL
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you pls update these all to be camelcase?

// +build conftests

/*
Copyright 2021 The Dapr Authors
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Copyright 2021 The Dapr Authors
Copyright 2025 The Dapr Authors

@sicoyle
Copy link
Contributor

sicoyle commented Dec 9, 2025

@JoshVanL did you have any other feedback here by chance?

@CasperGN
Copy link

@sicoyle I think this one is actually super interesting to get in. I've seen an uptick in Clickhouse lately so supporting this would be beneficial imo.
@middt please address the comments so we can get this one merged 😄

… use camelCase for metadata

Signed-off-by: Mehmet TOSUN <mehmet.tosun@gmail.com>
@middt
Copy link
Author

middt commented Dec 15, 2025

Hi @sicoyle @CasperGN! Thank you for the thorough review! I've addressed all the feedback in the latest commit (1be750b):

✅ Changes Made:

  1. Copyright Year Updated (2021 → 2025)

    • Updated in all ClickHouse-related files (clickhouse.go, clickhouse_test.go, clickhouse_integration_test.go, and tests/certification/state/clickhouse/clickhouse_test.go)
  2. Added Length Checks for Database and Table Names

    • Added a maxIdentifierLength constant set to 256 characters (based on ClickHouse documentation)
    • Added validation in parseAndValidateMetadata() to return an error if names exceed the limit
  3. Updated Metadata Field Names to camelCase

    • ClickhouseURLclickhouseUrl
    • DatabaseNamedatabaseName
    • TableNametableName
    • Usernameusername
    • Passwordpassword
    • Added proper mapstructure tags in the Go struct for proper binding
    • Updated all test files and config files to use the new camelCase names
  4. Documentation PR

  5. Username/Password Authentication

    • Confirmed: ClickHouse can be configured to run without authentication (using the default user with no password). This is common in development environments. In production, authentication should be configured. The fields are correctly marked as required: false in the metadata schema.

All tests are passing and linting is clean. Ready for re-review! 🚀

}

// maxIdentifierLength is the maximum length for database and table names in ClickHouse
const maxIdentifierLength = 256

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Per their docs and this issue they reference a length of 206 and 250 respectively - are you positive about the 256 limit?

…test

The certification test had '//go:build conftests' but the CI runs with
'-tags=certtests,unit'. Other certification tests don't use build
constraints at all. Removed the build constraint to match the pattern
used by other certification tests in the repository.

Signed-off-by: Mehmet TOSUN <mehmet.tosun@gmail.com>
@middt middt force-pushed the dapr-state-store-clickhouse branch from 45c198f to da6d1a0 Compare December 16, 2025 08:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

autoupdate automatically keeps PR up to date against master documentation required This issue needs documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants