생성한 UDF 인터페이스 구현과 예제 테스트
정의 YAML을 저장한 뒤 코드 생성을 실행하면 입력, 출력, configuration과 UDF factory 및 실행 인터페이스가 만들어집니다. 기본 템플릿의 생성 위치는 udf-definitions-map-udf-definition/build/generated/sources/udf/main/java입니다.
직접 작성하는 구현은 Java 소스 경로인 src/main/java/myproject에 둡니다. 생성 디렉터리의 파일을 직접 수정하는 대신 YAML과 구현 클래스를 변경합니다.
Row map
Row map은 입력 행 하나마다 정확히 한 행을 반환하며 기본 UDF 유형입니다.
| 클래스 | 구현할 계약 |
|---|---|
YourUdfNameMapUdfFactoryImpl | 생성한 YourUdfNameMapUdfFactory를 구현합니다. 런타임의 create에서 인스턴스를 만들고 args.config()의 인자를 전달합니다. |
YourUdfNameMapUdfImpl | 생성한 YourUdfNameMapUdf를 구현합니다. 각 입력 행에 대해 한 출력 행을 계산합니다. |
Factory의 create는 UDF 인스턴스를 초기화할 때 호출됩니다. 행별 계산은 구현 객체의 map 로직에서 수행합니다. 여러 작업자 전체에서 factory가 한 번만 호출되는 전역 singleton으로 해석하지 않습니다.
입력, 출력과 인자는 이름의 camelCase 메서드로 접근합니다. argument_one이면 argumentOne()입니다. YAML의 nullable 필드에 맞춰 누락값의 처리도 구현해야 합니다.
기본 저장소에는 MultiplyMapUdfFactoryImpl.java와 MultiplyMapUdfImpl.java가 포함됩니다. 인자 기반 곱셈 예제의 입력, 출력과 configuration 계약을 바탕으로 실제 로직을 작성할 수 있습니다.
Flat map
Flat map은 입력 하나에서 0개, 1개 또는 여러 행을 방출합니다. DuplicateRows 정의의 생성 클래스를 사용하여 각 입력을 두 번 방출하는 예를 구현합니다.
Factory
파일 src/main/java/myproject/DuplicateRowsFlatMapUdfFactoryImpl.java:
package myproject;
import com.google.auto.service.AutoService;
import com.palantir.foundry.duplicaterows.DuplicateRowsFlatMapUdf;
import com.palantir.foundry.duplicaterows.DuplicateRowsFlatMapUdfAdapter;
import com.palantir.foundry.duplicaterows.DuplicateRowsFlatMapUdfFactory;
import com.palantir.foundry.duplicaterows.config.DuplicateRowsConfiguration;
import com.palantir.foundry.udf.api.flatmap.FoundryRowFlatMapUdf;
import com.palantir.foundry.udf.api.flatmap.FoundryRowFlatMapUdfFactory;
@AutoService(FoundryRowFlatMapUdfFactory.class)
public final class DuplicateRowsFlatMapUdfFactoryImpl
implements DuplicateRowsFlatMapUdfFactory {
public DuplicateRowsFlatMapUdfFactoryImpl() {}
@Override
public FoundryRowFlatMapUdf create(
FoundryRowFlatMapUdfFactory.Arguments<DuplicateRowsConfiguration> args) {
DuplicateRowsFlatMapUdf implementation = new DuplicateRowsFlatMapUdfImpl();
return new DuplicateRowsFlatMapUdfAdapter(implementation);
}
}
서비스 로딩에는 public 무인자 생성자가 필요합니다. 생성 adapter로 실제 구현을 감싸서 반환합니다. 이 예제는 인자를 정의하지 않아 configuration을 사용하지 않으며, 인자가 있는 정의는 args.config()에서 받습니다.
행 방출
파일 src/main/java/myproject/DuplicateRowsFlatMapUdfImpl.java:
package myproject;
import com.palantir.foundry.duplicaterows.DuplicateRowsFlatMapUdf;
import com.palantir.foundry.duplicaterows.input.InputRow;
import com.palantir.foundry.duplicaterows.output.OutputRow;
import com.palantir.foundry.udf.api.flatmap.Collector;
public final class DuplicateRowsFlatMapUdfImpl implements DuplicateRowsFlatMapUdf {
@Override
public void flatMap(Context ctx, InputRow input, Collector<OutputRow> output)
throws Exception {
OutputRow row = OutputRow.create(ctx.getRowBuilderFactory())
.key(input.key())
.value(input.value());
output.collect(row);
output.collect(row);
}
}
행마다 두 번 collect하므로 두 결과를 냅니다. 방출하지 않으면 0개, 한 번이면 1개를 내는 것이 flat map의 계약입니다. 생성된 입력과 출력 스키마에 맞는 객체를 사용해야 합니다.
Builder에 표시할 row map 예제
Examples framework는 row map만 지원합니다. Flat map은 별도 JUnit 테스트를 작성해야 하며 그 테스트는 Builder의 변환 설명에 표시되지 않습니다.
기본 템플릿의 src/test/java/examples/registry/MultiplyExamples.java를 참고하여 examples.registry 아래에 Examples 구현을 추가합니다. name()은 테스트 대상 UDF 이름과 정확히 같아야 등록 및 게시됩니다. examples()는 실제 테스트 사례들을 반환합니다.
| 사례 구성 | Multiply의 기본 사례 |
|---|---|
| 고유 ID | ExampleId.of("baseCase") |
| 설명 | Multiply values by 2. |
| 표시 수준 | ExampleVisibility.DEFAULT입니다. PROMINENT도 사용할 수 있습니다. |
| 분류 | ExampleCategory.BASE입니다. 예제는 기본, null 및 경계 사례의 목적을 구분합니다. |
| Configuration | MultiplyConfiguration.builder().multiplier(2.0d).build() |
| 입력 객체 | SettableMultiplicand로 만든 ("key", 1.5d)와 ("key", 3.0d) |
| 기대 출력 객체 | Product로 만든 ("key", 3.0d)와 ("key", 6.0d) |
예제의 입력 및 출력 객체는 ctx().getRowBuilderFactory()로 생성합니다. UdfExample<SettableMultiplicand, Product, MultiplyConfiguration>의 builder에서 id, description, visibility, category, configuration, input, output을 구성한 뒤 build()하여 목록에 넣습니다.
ExamplesTest.testExamples()는 examples.registry의 구현을 찾아 유효성을 검사하고 실제 UDF를 입력과 configuration으로 실행하여 기대 출력과 비교합니다.
예제 작성은 선택 사항이지만 Builder 사용자가 기능을 이해하는 데 도움이 됩니다. 예제 테스트를 제공하지 않으려면 템플릿의 예제 전용 정의를 제거할 수 있습니다. src/test에 다른 실제 테스트가 있다면 함께 삭제하지 않습니다.
생성과 테스트 실행 위치
정의나 factory 및 구현을 바꿀 때마다 코드를 다시 생성해야 합니다.
| 위치 | 코드 생성 | 예제 검사 | 전체 테스트 |
|---|---|---|---|
| IntelliJ 로컬 | ./gradlew idea | ./gradlew test --tests examples.ExamplesTest.testExamples | ./gradlew test |
| Eclipse 로컬 | ./gradlew eclipse | 같은 Gradle test 명령 | ./gradlew test |
| Code Repositories Java Task Runner | generateUdfResources | 전체 test로 포함 | test |
변경을 commit하고 게시 절차에 따라 tag와 checks, 필요한 Builder lockfile을 관리합니다.