streampark
AGENTS.md4.3k starsChanged 21 months agoApache-2.0View on GitHub
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 conventions, architecture, and coding patterns for the StreamPark codebase. StreamPark is a Maven multi-module project with five top-level reactor modules. Each has a clear responsibility boundary. The strongest compatibility contracts…
Trending
Quiet this year.thin dataabout the whole repository
Who's talking about apache/streampark
- A Hacker News story“StreamPark: A streaming application development framework”Hacker News · Aug 3, 2025 · 8 points
- projectdiscovery/nuclei-templates“Create apache-streampark-detect.yaml and apache-streampark-default-login.yaml”GitHub · Sep 7, 2025
The biggest 2 of 2 mentions linking to the repository that our crawl found. Each line is their own headline.
Where files are headingNew AGENTS.md files have more rules about keeping secrets out of the code, and fewer about code style.
Of the AGENTS.md files we read, the 31,439 first seen in the last six months, against the older ones: the kind of rule that gained most share, and the kind that lost most. About files like this in general, not this one, and an estimate, since a kind is a pattern in the words.
The file
Show its rules and text
We split this AGENTS.md into the rules it gives an agent
21 rules. About 1 is common, 7 are distinctive, and 13 are very specific to this project.
≈1
Common · estimate
Many files like this have a rule of this kind.
≈7
Distinctive · estimate
This author's own choices. Worth a look.
13
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- could be automatic: a setting could enforce it
- Very specific: line 68
Database schema changes: All schema changes must have corresponding upgrade scripts under …
- Very specific: line 86
Typed request and option APIs: Prefer typed enums, request objects, ConfigOption, and immutable maps over unstructured string bags.
- Very specific: line 90
File system abstraction: Use FsOperator (with HdfsOperator / LfsOperator implementations) for file operations.
- Very specific: line 99
Lombok: Use @Slf4j, @Data, @Builder where appropriate.
- Very specific: line 110
Style: Use val over var. Prefer Option over null in public APIs.
- Very specific: line 115
Vue 3 Composition API: Use <script setup lang="ts"> for new components.
- Very specific: line 116
API layer: All HTTP calls go through src/api/ modules using defHttp.
- Distinctive: line 124
No personal pronouns in comments: Use descriptive, impersonal documentation.
- Very specific: line 126
Logging: Use Lombok @Slf4j (Java) or Logger trait (Scala).
- Very specific: line 208
Schema changes: Must include matching scripts for MySQL and PostgreSQL under …
- Distinctive: line 209
Shims changes: Keep shared methods in shims-base only when every supported version can implement them.
- Distinctive: line 217
Never: remove or rename canonical or fallback configuration keys without an explicit compatibility decision.
- Very specific: line 218
Never: add classes or methods under streampark-flink-shims without an explicit architecture decision.
- Very specific: line 219
Never: add business workflows or infrastructure access to streampark-console-service/.../core/entity.
- Common: line 220
Never: commit secrets, credentials, API keys, or cloud-specific tokens.
- Distinctive: line 222
Never: add a new database migration without providing both MySQL and PostgreSQL upgrade scripts.
- Distinctive: line 227
Ask first: before adding new third-party dependencies — license compatibility with Apache 2.0 matters.
- Distinctive: line 228
Ask first: before promoting package-private classes/methods to public.
- Distinctive: line 229
Ask first: before adding new Maven modules or restructuring the module hierarchy.
- Very specific: line 230
Ask first: before introducing new Scala implicits in streampark-scala — they affect all downstream Scala code.
- Very specific: line 231
Ask first: before changing the authentication model (Shiro/JWT/Pac4j configuration).
≈ “Common” is an estimate: at least 1 in 5 of the 40,246 AGENTS.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you 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.
-->Apache StreamPark — Agent Instructions
Project conventions, architecture, and coding patterns for the StreamPark codebase.
Architecture
Module Boundaries
StreamPark is a Maven multi-module project with five top-level reactor modules. Each has a clear responsibility boundary.
streampark-common(streampark-common/): Engine-API-free foundation layer. It owns the immutable configuration model (ConfigOption,Configuration,ConfigurationLoader, andGlobalConfiguration), shared option catalogs, workspace layout, utilities, file system abstractions, and common enums. It may understand external formats such as Flink YAML, but must not depend on Flink or Spark runtime APIs.streampark-scala(streampark-scala/): Small Scala compatibility layer containing shared Scala logging and implicit utilities. Java-only common code belongs instreampark-common; reusable Scala code belongs here instead of being embedded in an engine module.streampark-flink(streampark-flink/): Flink runtime integration. Its reactor contains the version-isolated shims, SQL client, submission client, packer, and Kubernetes integration. Connector modules are enabled by the module'sshadedprofile.FlinkShimsProxyin the client API is the entry point for executing version-specific code.streampark-spark(streampark-spark/): Spark runtime integration. It contains Spark configuration and SQL utilities, submission client API/core, and SQL client. It is a regular root reactor module; the retainedsparkprofile is not required to include it in a normal build.streampark-console(streampark-console/): Web management platform. Its Maven reactor contains the Spring Boot service. The siblingstreampark-console-webapp/Vue 3 application is built into the service only when the service'swebappprofile is enabled; it is not a Maven child module.
The strongest compatibility contracts are the common configuration keys and value semantics, Flink client request/response types, shims proxy serialization boundary, database schema, and REST API. Changes to these surfaces require cross-module impact analysis and focused compatibility tests.
High-Sensitivity Areas
- Configuration model (
org.apache.streampark.common.configuration):ConfigOptiondeclares typed metadata,ConfigurationParserparses raw documents,ConfigurationLoadercomposes ordered sources, and immutableConfigurationsnapshots perform typed reads.GlobalConfigurationis the process-boundary atomic reference, not a mutable property bag. Option keys and fallback keys are user-facing contracts. - Configuration ownership: Common option catalogs contain only settings owned by common infrastructure. Console and engine settings stay in their owning modules.
SpringConfigurationInitializeris the Console composition root and owns the explicit list of options bound from Spring; do not add globalALLregistries to option catalogs. - Workspace initialization:
Workspace.LOCAL,Workspace.REMOTE, and derived constants are initialized from one immutable snapshot. Spring bootstrap must publish its completed configuration before workspace paths are first accessed, and must retain theWorkspace.verifyInitializedFromguard. - Flink YAML compatibility (
FlinkConfigurationLoader): Before Flink 1.19, load onlyflink-conf.yamlwith the legacy line parser. Flink 1.19 and 1.20 support both names and preferflink-conf.yamlwhen both exist; parser selection follows the selected filename. Flink 2.0 and later load onlyconfig.yamlwith standard nested YAML parsing. Directory-based loading must always receive the target Flink version. This common utility returns engine-neutral maps; conversion to Flink'sConfigurationbelongs in a Flink module. FlinkShimsProxy: The multi-version classloader isolation mechanism usesChildFirstClassLoaderand serializes request/response objects across the boundary. Classloaders are cached by concrete Flink version. Never pass target-runtime Flink objects into the parent classloader or introduce target-specific static state that can leak across classloaders.- Shims modules:
streampark-flink-shims-basecontains only contracts and implementation shared by every supported shim. Supported concrete modules are Flink 1.18, 1.19, 1.20, 2.0, 2.1, 2.2, and 2.3. APIs removed from Flink 2.x, such as legacyregisterDataStreamand table-functionregisterFunctionoverloads, belong only in the compatible 1.x implementations. Do not add classes or methods anywhere understreampark-flink-shimswithout an explicit shims architecture decision. - Flink submission flow:
FlinkClientand its request/response packages form the stable API.FlinkClientEntrypoint,SubmitRequestResolver,FlinkConfigurationBuilder, and deployment-specific clients own request normalization, configuration assembly, and submission. Keep Flink-version calls behind the shims boundary. FlinkApplicationController/FlinkApplicationManageService/FlinkApplicationActionService: The core application management flow. Operations (start, stop, cancel, deploy) must be idempotent and handle all Flink states correctly. TheAppChangeEventannotation triggers state synchronization.- Persistence entities (
console/core/entity): These classes map database rows. Keep configuration discovery, parsing, filesystem access, and other business logic in assemblers, services, or utility classes such asFlinkEnvUtilsandFlinkApplicationConfigUtils. Existing small mapping operations may remain, but new domain workflows must not be added to entities. - SQL parsing and validation: Flink SQL validation is version-aware and executes through the selected 1.18-2.3 shim.
FlinkSql,FlinkSqlService, and the SQL client have different persistence, orchestration, and execution responsibilities.sql-rev.dicthandles database SQL differences between MySQL and PostgreSQL; it is unrelated to Flink SQL syntax compatibility. - Kubernetes integration (
FlinkKubernetesWatchController): Uses Caffeine caches (TrackIdCache,JobStatusCache,MetricCache) for tracking K8s-deployed Flink jobs. Cache invalidation and TTL must be correct to avoid stale state. - HTTP client and proxying:
OkHttpUtilsin common owns the shared connection pool, timeouts, and bounded retries for idempotent requests. Console proxy code inWebUtilsowns servlet adaptation, hop-by-hop header filtering, response streaming, and response closure. Do not create ad hoc clients per request or retry non-idempotent methods implicitly. - Database schema changes: All schema changes must have corresponding upgrade scripts under
streampark-console/streampark-console-service/src/main/assembly/script/upgrade/for bothmysql/andpgsql/. Updatesql-rev.dictwhen a mapper or initialization statement needs a MySQL-to-PostgreSQL rewrite. - Authentication & Authorization:
ShiroConfig,JWTUtil,ShiroRealm— changes here affect all user access. The@Permissionannotation andPermissionAspectenforce team-level resource isolation. Never weaken RBAC checks.
Design Patterns
- Immutable configuration pipeline: Declare typed options in the owning module, parse external input without a central registry, compose sources by precedence, and capture one immutable snapshot at the start of a multi-step operation. Do not repeatedly read mutable global state inside a workflow.
- Shims / Proxy pattern:
FlinkShimsProxy.proxy(flinkVersion, function)loads the target installation and matching shim behind a child-first classloader. Shared behavior stays in shims-base; version-only API calls stay in the concrete version module. Cross-boundary values must use stable serializable StreamPark request/response types. - Initializer pattern:
FlinkStreamInitializerandFlinkTableInitializerassemble application configuration namespaces and construct Flink environments inside the target classloader. Nativeflink.property.*, userapp.*, and command-line sources remain distinct until their documented composition point. - Service layer separation: Console services are split by responsibility —
FlinkApplicationManageService(CRUD),FlinkApplicationActionService(start/stop/cancel),FlinkApplicationInfoService(query/info). Follow this pattern when adding new application operations. - Scala compatibility layer: Shared Scala helpers live in
streampark-scala. New implicits must be narrowly scoped and must not introduce engine dependencies into the common foundation. - MyBatis-Plus entity pattern: Mappers extend MyBatis-Plus
BaseMapper; entities use@TableNameand related mapping annotations. Only entities that need the shared audit fields extendBaseEntity. Pagination usesMybatisPagerandPaginationInterceptor. Keep entities focused on persistence data. - Typed request and option APIs: Prefer typed enums, request objects,
ConfigOption, and immutable maps over unstructured string bags. Preserve serialized field names across the Console-to-client and client-to-shims boundaries. - REST response pattern: Normal API endpoints return
RestResponseBody<T>created throughRestResponseBody.success(...)orRestResponseBody.fail(...). The map-basedRestResponseis a deprecated compatibility type and must not be introduced at new controller boundaries. Streaming proxy endpoints may write directly toHttpServletResponse. Use@Permissionfor protected resources and@AppChangeEventfor audited application changes. - File system abstraction: Use
FsOperator(withHdfsOperator/LfsOperatorimplementations) for file operations. Never use rawjava.io.Fileor HadoopFileSystemdirectly in business logic.
Coding Conventions
Java (Backend)
- Formatting: Eclipse formatter via Spotless (
tools/checkstyle/spotless_streampark_formatter.xml). Run./mvnw spotless:applybefore committing. - Import order:
org.apache.streampark,org.apache.streampark.shaded,org.apache,javax,java,scala,\#(all others). - Static checks: Checkstyle (
tools/checkstyle/checkstyle.xml) + Spotless. No wildcard imports. No@authortags. No JUnit 4 imports. - Lombok: Use
@Slf4j,@Data,@Builderwhere appropriate. Do not use@EqualsAndHashCodeon JPA/Hibernate entities. - Testing: JUnit 5 (
org.junit.jupiter) + AssertJ. Use@Test(not@Testfrom JUnit 4). UseassertThat(...).isEqualTo(...)style. Test classes should be in the same package as the code under test. - Method names: New production and test method names must be concise, readable, and no longer than 40 characters.
- Package structure: Controllers in
controller/, service interfaces inservice/, implementations inservice/impl/, entities inentity/, mappers inmapper/, enums inenums/.
Scala (Scala Support / Spark)
- Formatting: Scalafmt 3.7.5 (
tools/checkstyle/.scalafmt.conf). Max column 160. Run./mvnw spotless:applyto format. - Import ordering:
org.apache.streampark.*first, then other third-party, thenjavax.*,java.*,scala.*. - Static checks: Scalastyle (
tools/checkstyle/scalastyle-config.xml). No wildcard imports. Noprintlnstatements (useLoggertrait). - Testing: ScalaTest 3.2.9. Use
FlatSpecorFunSuitestyle consistent with existing tests. - Style: Use
valovervar. PreferOptionovernullin public APIs. Uselazy valfor expensive initialization. Use pattern matching instead ofisInstanceOf/asInstanceOf.
TypeScript / Vue (Frontend)
- Formatting: ESLint + Prettier. Run
pnpm lint:eslintandpnpm lint:prettier. - Vue 3 Composition API: Use
<script setup lang="ts">for new components. Use Pinia for state management (not Vuex). - API layer: All HTTP calls go through
src/api/modules usingdefHttp. API URLs are defined as enum constants. Never useaxiosorfetchdirectly in components. - Component naming: PascalCase for component files and names. Use
index.tsbarrel exports in component directories. - Unused variables: Prefix with
_to suppress ESLint warnings (argsIgnorePattern: '^_').
General
- Apache License header: Required on all new files. Use the copyright header from
tools/checkstyle/copyright.txt. Enforced by Spotless and Apache RAT. - No wildcard imports: Prohibited in both Java and Scala (enforced by Spotless).
- No personal pronouns in comments: Use descriptive, impersonal documentation.
- Database: Support both MySQL and PostgreSQL. All new SQL must be tested against both. Use
sql-rev.dictfor dialect differences. - Logging: Use Lombok
@Slf4j(Java) orLoggertrait (Scala). Uselog.info/log.errorwith parameterized messages. Never log credentials or sensitive data.
Commands
- Full build (backend + frontend, skip tests):
Equivalent to:./build.sh./mvnw -Pshaded,webapp,dist -DskipTests clean install - Fast build (backend only, skip all checks):
./mvnw -Pfast clean install -DskipTests - Build backend reactor with shaded artifacts:
./mvnw -Pshaded clean install -DskipTests - Build backend only:
./mvnw clean install -DskipTests - Run single test class (Java):
./mvnw test -pl streampark-console/streampark-console-service -Dtest=FlinkSavepointServiceTest - Run common configuration tests:
./mvnw test -pl streampark-common -Dtest=ConfigurationTest,FlinkConfigurationUtilsTest - Build all supported Flink shims:
./mvnw -f streampark-flink/streampark-flink-shims/pom.xml clean install - Format code (Java + Scala):
./mvnw spotless:apply - Check formatting:
./mvnw spotless:check - Run Checkstyle:
./mvnw checkstyle:check - Frontend development server:
cd streampark-console/streampark-console-webapp && pnpm dev - Frontend lint:
cd streampark-console/streampark-console-webapp && pnpm lint:eslint && pnpm lint:prettier - Frontend build:
cd streampark-console/streampark-console-webapp && pnpm build - Run Docker Compose (local):
docker compose -f docker/docker-compose.yaml up -d
PR & Commit Conventions
- PR title format:
[Module] Description(e.g.,[Flink] Fix shims classloader isolation,[Console] Add team-level resource filtering,[Common] Support Hadoop 3.x configuration). - Module prefixes:
[Common],[Flink],[Spark],[Console],[K8s],[Docs],[CI],[Build]. - One concern per PR: Unrelated whitespace, import, or formatting changes go in separate PRs. Do not mix refactoring with feature work.
- Commit messages: Describe the what and why, not implementation details. Reference related GitHub issues with
#xxx. - Apache License header: Required on all new files (enforced by Spotless and Apache RAT). The
spotless:checkandapache-rat:checkgoals run in CI. - Schema changes: Must include matching scripts for MySQL and PostgreSQL under
streampark-console/streampark-console-service/src/main/assembly/script/upgrade/. - Shims changes: Keep shared methods in shims-base only when every supported version can implement them. Put version-specific Flink APIs only in the applicable 1.18-2.3 concrete modules, and verify the full shims reactor.
Boundaries
Never Without Explicit Discussion
- Never modify
.asf.yaml,LICENSE,NOTICE, or.gitignorewithout explicit discussion. - Never upgrade Flink, Spark, Scala, Spring Boot, or other major dependency versions without discussion — these changes have broad impact across the entire project.
- Never remove or rename canonical or fallback configuration keys without an explicit compatibility decision; they are user-facing contracts.
- Never add classes or methods under
streampark-flink-shimswithout an explicit architecture decision. General utilities, Console logic, and configuration-file parsing belong outside shims. - Never add business workflows or infrastructure access to
streampark-console-service/.../core/entity. - Never commit secrets, credentials, API keys, or cloud-specific tokens.
- Never introduce a new Flink version shims module without adding the corresponding CI build configuration.
- Never add a new database migration without providing both MySQL and PostgreSQL upgrade scripts.
- Never change the
SqlConvertUtilsdialect conversion logic without testing against both MySQL and PostgreSQL.
Ask First
- Ask first before adding new third-party dependencies — license compatibility with Apache 2.0 matters.
- Ask first before promoting package-private classes/methods to public.
- Ask first before adding new Maven modules or restructuring the module hierarchy.
- Ask first before introducing new Scala implicits in
streampark-scala— they affect all downstream Scala code. - Ask first before changing the authentication model (Shiro/JWT/Pac4j configuration).
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

