본문 바로가기
오픈소스

Apache / SeaTunnel 오픈소스 기여후기 (open source contribute)

by 준벨롭 2026. 5. 4.

Line의 Armeria에 이어, 근 1달만에 Apache의 SeaTunnel이라는 오픈소스에 기여할 수 있었습니다.

Good First Issue라서 쉬울거라 생각하고 맡았지만, 예상보다는 쉽지 않고 우여곡절도 꽤나 있었습니다 ㅋㅋ

메인테이너와 커미터들이 도와주지 않았다면 쉽지 않았을 여정이라고 생각합니다....!

 

https://github.com/apache/seatunnel/issues/10681

 

[Feature][Zeta] Implement proper dry-run mode with progressive validation layers · Issue #10681 · apache/seatunnel

Motivation SeaTunnel currently lacks a meaningful dry-run capability. The existing --check flag (SeaTunnelConfValidateCommand) is effectively a stub — its execute() body contains only a // TODO: va...

github.com

제가 기여한 코드는 위 이슈와 관련이 되어있습니다.

 

SeaTunnel은 대용량 데이터 모으고, 가공하고, 전송하는(ETL) 를 처리할 수 있는 파이프라인 엔진입니다.

SeaTunnel을 사용하기 위해서는 다음과 같은 설정 파일이 필요합니다.

env {
  job.mode = "BATCH"
}

source {
  FakeSource {
    plugin_output = "fake"
    row.num = 100
    schema = {
      fields {
        name = "string"
        age = "int"
        card = "int"
      }
    }
  }
}

transform {
  Filter {
    plugin_input = "fake"
    plugin_output = "fake1"
    fields = [name, card]
  }
}

sink {
  Clickhouse {
    host = "clickhouse:8123"
    database = "default"
    table = "seatunnel_console"
    fields = ["name", "card"]
    username = "default"
    password = ""
    plugin_input = "fake1"
  }
}

 

저는 dry-run 기능을 구현했고, 메인테이너가 제시한 layer 0-3 중 layer0을 우선적으로 구현했습니다.

 

cli에서 --dry-run=static을 입력하면 자체적으로 정적검사를 수행하는 기능입니다.

컴파일 단계와 비슷한 검증이라고 생각됩니다.

 

layer0에서는

- syntax

- option key

- required

- type

- plugin load

- DAG(Directed Acyclic Graph)

- SQL parsing

 

위와 같은 항목들을 정적으로 검증하는 로직을 구현했습니다.

 

SeaTunnel에서는 OptionRule이라는 기존 로직이 있었기 때문에 제가 검증로직을 0부터 개발하지는 않아도 됐습니다. (굿!)

 

이 과정에서 배운점이 몇가지 있었는데요,

 

1. JVM classLoader의 동작과정

막연하게 Java가 어떻게 코드를 실행하는가에 대해서는 알고있었습니다.

SeaTunnel에 기여하면서 ClassLoader의 동작 메커니즘을 조금 더 자세하게 알 수 있었는데요,

 

package org.apache.seatunnel.core.starter.seatunnel.command;

 

위 경로에서

Thread.currentThread().getContextClassLoader();

 

다음과 같은 코드를 호출하면

core 모듈 밖에 있는 plugin의 jar 파일들을 알 수 없기 때문에 실제 사용 시 문제가 발생할 수 있었습니다.

 

plugin jar 경로를 명시적으로 classloader에 추가하라는 팁을 받았고, 이를 구현하며 문제를 잘 해결할 수 있었습니다.

 

2. 테스트 코드의 중요성

오픈소스 기여할 때 마다 느끼고 있는 부분입니다.

AI로 인해 생산성이 많이 올라간 것을 다들 아실거라고 생각합니다.

저는 아직까지는 코드에 대해 안정성을 확보하기 위해선 잘 작성된 테스트 코드가 필수적이라고 생각합니다.

 

@Test
    public void testInvalidDagTopology() {
        ClientCommandArgs args = buildArgs("config/invalid_dag_topology.json");
        SeaTunnelConfValidateCommand command = new SeaTunnelConfValidateCommand(args);

        ConfigCheckException exception =
                Assertions.assertThrows(ConfigCheckException.class, command::execute);
        Assertions.assertTrue(
                exception.getMessage().contains("Miss <Sink> config"),
                "Should detect invalid DAG. Actual: " + exception.getMessage());
    }

 

위와 같은 테스트 코드를 작성했었는데요, 잘 돌아가던 CI에서 어느 순간 테스트가 깨져서 디버깅을 해봤습니다.

이유는 다른 PR에서 설정파일을 암호화, 복호화 하는 코드뿐만 아니라 설정 파일을 검증하는 코드도 try/catch문으로 감싸 설정파일 예외도 "Failed to decrypt config"와 같은 보안 관련 에러 메세지를 던져서 발생하는 문제였습니다.

 

문제가 발생한 코드의 구조를 수정해서 사용자에게 정확한 에러메세지를 제공할 수 있도록 했습니다.

 

테스트 코드의 역할은 의도하지 않은 사이드 이펙트를 잡아내는 것 뿐만 아니라
내가 작성한 코드의 안정성과 거대한 프로젝트에서의 협업에도 도움이 된다는 것을 다시 한 번 느끼게 되었습니다.

 

https://github.com/apache/seatunnel/pull/10763

 

[Feature][Zeta] Implement proper dry-run mode with progressive validation layer0 by junjunclub · Pull Request #10763 · apache/

Purpose of this pull request This pull request implements Layer 0 (Static Analysis) for the --dry-run feature, addressing the core requirements discussed in #10681. It enhances SeaTunnelConfValidat...

github.com

 

제가 올린 PR 링크입니다.

 

기회가 된다면 남은 layer 1, 2, 3도 구현해보고 싶다는 욕심이 듭니다 ㅎㅎ

긴 글 읽어주셔서 감사합니다!

728x90