REST API server. Entry point for the UI and external clients (curl, Python SDK). Uses Spring Boot with Jetty (not Tomcat) and springdoc-openapi for Swagger UI.
org.apache.dolphinscheduler.api
ApiApplicationServer — @SpringBootApplication. On startup it:
- Loads
DataSourcePluginManagerandTaskPluginManager(plugin discovery). - Binds to the port in
server.port(default 12345). - Starts the Py4J gateway used by the Python SDK.
api.controller— 30+@RestControllerclasses, one per domain (workflows, tasks, users, projects, tenants, resources, data sources, alerts, monitoring, …). All URLs rooted at/dolphinscheduler/*.api.service/api.service.impl— business-logic layer wrappingdolphinscheduler-serviceand adding API-level concerns (auth checks, DTO mapping).api.security— pluggable authenticators:PASSWORD(default),LDAP,OIDC,CASDOOR,SSO. Selected bysecurity.authentication.type.api.interceptor—LoginHandlerInterceptor(session cookie check),RateLimitInterceptor,LocaleChangeInterceptor.api.configuration— Spring config beans: Swagger, OAuth2, task-type catalog.api.dto— request/response DTOs.api.exceptions—ApiExceptionHandler(@RestControllerAdvice) maps exceptions → structured JSON responses.
Authenticator— implement a new one to support additional login backends (added cases go intoAuthenticationTypeenum + registered inSecurityConfig).- Controllers auto-pick up new task types via
TaskTypeConfigurationreadingtask-type-config.yaml/dynamic-task-type-config.yaml.
src/main/resources:
application.yaml— server port, datasource, registry, security mode, CORS, OpenAPI.task-type-config.yaml,dynamic-task-type-config.yaml— the catalog of task types exposed to the UI.i18n/messages_*.properties— English + Simplified Chinese server-side messages.swagger.properties— springdoc config (UI lives at/dolphinscheduler/swagger-ui/index.html).logback-spring.xml— logging.
- Jetty, not Tomcat.
spring-boot-starter-tomcatis excluded transitively viadolphinscheduler-meter. Avoid accidentally pulling Tomcat in. - Session-based auth:
LoginHandlerInterceptorreads thesessionIdcookie. There is no JWT by default. OIDC/CASDOOR paths still set a session. - OIDC requires
casdoor-spring-boot-starter;OAuth2Configurationis@ConditionalOnProperty(security.authentication.type = OIDC|CASDOOR). - Python SDK integration uses Py4J gateway, not REST. If a Python SDK change misbehaves, check
api-serverlogs for Py4J init messages. - Controllers mix
@PostMappingwith form params and JSON bodies inconsistently — this is legacy. Follow whatever shape the adjacent endpoint uses rather than converting to JSON across the board. - Swagger annotations are required on new endpoints (
@Operation,@Parameter). Missing ones break auto-generated docs the UI team consumes.
Unit tests live in src/test/java. Integration tests live in dolphinscheduler-api-test (separate module, Docker Compose + Testcontainers).
The CI flow (.github/workflows/unit-test.yml) runs in two phases. Mirror it locally:
One-time setup — install BOM + upstream deps to local m2:
export MAVEN_OPTS="-Xmx4g -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=1024m"
./mvnw install -B \
-pl "dolphinscheduler-bom,dolphinscheduler-api" \
-am -DskipTests=true -Dspotless.skip=true -DskipUT=true \
-Djacoco.skip=true -Danalyze.skip=trueRun tests — use verify (NOT test), no -am, no clean:
./mvnw verify -B -pl "dolphinscheduler-api" \
-Dmaven.test.skip=false -Dspotless.skip=true -DskipUT=false -Danalyze.skip=true \
-Dsurefire.printSummary=true -Dsurefire.useFile=false \
-Dsurefire.reportFormat=plain -Dsurefire.redirectTestOutputToFile=false \
-Dsurefire.failIfNoSpecifiedTests=false \
-Dtest='EnvironmentServiceTest#testVerifyEnvironment'Drop the -Dtest=... filter to run the whole module.
verifynottest— root pom usesjacoco-maven-pluginin offline-instrument + restore-instrumented-classes mode. Only theverifylifecycle runs therestoregoal, sotestalone leavestarget/classesinstrumented and the next build fails with "Cannot process instrumented class".dolphinscheduler-bommust be in the install-pl— without it, the installed pom lacks effective dependencyManagement and downstream compile/test classpaths drop transitive deps likecommons-collections4andoshi-core.-DskipTests=true(not-Dmaven.test.skip=true) during install —maven.test.skipskips test-source attach which breaks downstream modules that depend on the test-jar.- No
-amon the test run —-amre-instruments upstream modules with jacoco and triggers the same "Cannot process instrumented class" failure. - No
cleanbetweeninstallandverify— clean wipestarget/classesand the next compile re-resolves transitive deps from the (still installed) pom; some resolutions fail with[WARNING] The POM for ... is invalidand the build can't seecommons-collections4etc.
Cannot process instrumented class— re-run with-Djacoco.skip=true, or wipetarget/for the affected module and re-run.NoClassDefFoundError: oshi/SystemInfoorcommons-collections4/CollectionUtilsat test runtime — the bom didn't get installed; redo the setup step includingdolphinscheduler-bomin-pl.class file contains wrong class— local~/.m2/.../dolphinscheduler-*-dev-SNAPSHOT.jaris stale/corrupt. Delete the offendingdev-SNAPSHOTdirectory under~/.m2/repository/org/apache/dolphinscheduler/and re-run install.
Surefire XML reports land at target/surefire-reports/TEST-<class>.xml for the per-test counts.
dolphinscheduler-service,dolphinscheduler-dao— primary deps.dolphinscheduler-extract-master/-worker/-alert— RPC into servers.dolphinscheduler-authentication(actuator sub-module) — secures/actuator/**.dolphinscheduler-ui— primary consumer.dolphinscheduler-api-test— integration harness.