Skip to content

Commit eb3fda3

Browse files
committed
add ml merge processor
Signed-off-by: Xun Zhang <xunzh@amazon.com>
1 parent 81d5dff commit eb3fda3

7 files changed

Lines changed: 486 additions & 0 deletions

File tree

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
2+
# ML Merge Processor
3+
4+
This plugin enables you to merge data from a S3 file with source data from your Data Prepper pipeline.
5+
6+
## Usage
7+
```aidl
8+
ml_merge-pipeline:
9+
...
10+
processor:
11+
- ml_merge:
12+
fields:
13+
- to_key: field_B
14+
from_key: /modelInput/inputText
15+
merge_all_fields: true # Whether to merge all fields from input source
16+
retry_on_failure: 3 # Retry attempts for failed requests
17+
tags_on_failure: ["lookup_failed"] # Tags for failed events
18+
# S3 source configuration
19+
source_path_prefix: "s3://bucket/input/" # Base path for source/input files
20+
result_file_suffix: ".out" # Suffix to identify result files
21+
correlation_field: "recordId" # Field used to match related records
22+
```
23+
`fields` as the fields to be merged into the pipeline.
24+
`merge_all_fields` as the flag to merge all data into the pipeline.
25+
`source_path_prefix` as the Base path for source/input files
26+
`correlation_field` as the field name used to match related records
27+
28+
# Metrics
29+
30+
### Counter
31+
32+
## Developer Guide
33+
34+
The integration tests for this plugin do not run as part of the Data Prepper build.
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*
2+
* Copyright OpenSearch Contributors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
dependencies {
7+
implementation project(path: ':data-prepper-plugins:common')
8+
implementation project(':data-prepper-plugins:aws-plugin-api')
9+
implementation 'software.amazon.awssdk:sdk-core'
10+
implementation 'software.amazon.awssdk:sts'
11+
implementation 'io.micrometer:micrometer-core'
12+
implementation 'org.json:json'
13+
implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310'
14+
implementation 'org.projectlombok:lombok:1.18.22'
15+
annotationProcessor 'org.projectlombok:lombok:1.18.20'
16+
implementation 'software.amazon.awssdk:s3'
17+
testImplementation project(':data-prepper-test:test-event')
18+
testImplementation testLibs.slf4j.simple
19+
}
20+
21+
test {
22+
useJUnitPlatform()
23+
}
24+
25+
sourceSets {
26+
integrationTest {
27+
java {
28+
compileClasspath += main.output + test.output
29+
runtimeClasspath += main.output + test.output
30+
srcDir file('src/integrationTest/java')
31+
}
32+
resources.srcDir file('src/integrationTest/resources')
33+
}
34+
}
35+
36+
configurations {
37+
integrationTestImplementation.extendsFrom testImplementation
38+
integrationTestRuntime.extendsFrom testRuntime
39+
}
40+
41+
task integrationTest(type: Test) {
42+
group = 'verification'
43+
testClassesDirs = sourceSets.integrationTest.output.classesDirs
44+
45+
useJUnitPlatform()
46+
47+
classpath = sourceSets.integrationTest.runtimeClasspath
48+
49+
systemProperty 'log4j.configurationFile', 'src/test/resources/log4j2.properties'
50+
51+
filter {
52+
includeTestsMatching '*IT'
53+
}
54+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
* Copyright OpenSearch Contributors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package org.opensearch.dataprepper.plugins.ml_merge.common.client;
7+
8+
import org.opensearch.dataprepper.aws.api.AwsCredentialsOptions;
9+
import org.opensearch.dataprepper.aws.api.AwsCredentialsSupplier;
10+
import org.opensearch.dataprepper.plugins.ml_merge.common.config.AwsAuthenticationOptions;
11+
import org.opensearch.dataprepper.plugins.ml_merge.processor.MLMergeProcessorConfig;
12+
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
13+
import software.amazon.awssdk.core.client.config.ClientOverrideConfiguration;
14+
import software.amazon.awssdk.regions.Region;
15+
import software.amazon.awssdk.services.s3.S3Client;
16+
17+
public class S3ClientFactory {
18+
19+
public static S3Client createS3Client(final MLMergeProcessorConfig mlProcessorConfig, final AwsCredentialsSupplier awsCredentialsSupplier) {
20+
final AwsCredentialsOptions awsCredentialsOptions = convertToCredentialsOptions(
21+
mlProcessorConfig.getAwsAuthenticationOptions());
22+
final Region region = mlProcessorConfig.getAwsAuthenticationOptions().getAwsRegion();
23+
final AwsCredentialsProvider awsCredentialsProvider = awsCredentialsSupplier.getProvider(
24+
awsCredentialsOptions);
25+
26+
return S3Client.builder()
27+
.region(region)
28+
.credentialsProvider(awsCredentialsProvider)
29+
.overrideConfiguration(ClientOverrideConfiguration.builder()
30+
.retryPolicy(retryPolicy -> retryPolicy.numRetries(5).build())
31+
.build())
32+
.build();
33+
}
34+
35+
public static AwsCredentialsOptions convertToCredentialsOptions(
36+
final AwsAuthenticationOptions awsAuthenticationOptions) {
37+
if (awsAuthenticationOptions == null || awsAuthenticationOptions.getAwsStsRoleArn() == null) {
38+
return AwsCredentialsOptions.defaultOptionsWithDefaultCredentialsProvider();
39+
}
40+
return AwsCredentialsOptions.builder()
41+
.withRegion(awsAuthenticationOptions.getAwsRegion())
42+
.withStsRoleArn(awsAuthenticationOptions.getAwsStsRoleArn())
43+
.withStsExternalId(awsAuthenticationOptions.getAwsStsExternalId())
44+
.withStsHeaderOverrides(awsAuthenticationOptions.getAwsStsHeaderOverrides())
45+
.build();
46+
}
47+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package org.opensearch.dataprepper.plugins.ml_merge.common.config;
2+
3+
import com.fasterxml.jackson.annotation.JsonProperty;
4+
import jakarta.validation.constraints.Size;
5+
import software.amazon.awssdk.regions.Region;
6+
7+
import java.util.Map;
8+
9+
public class AwsAuthenticationOptions {
10+
@JsonProperty("region")
11+
@Size(min = 1, message = "Region cannot be empty string")
12+
private String awsRegion;
13+
14+
@JsonProperty("sts_role_arn")
15+
@Size(min = 20, max = 2048, message = "awsStsRoleArn length should be between 1 and 2048 characters")
16+
private String awsStsRoleArn;
17+
18+
@JsonProperty("sts_external_id")
19+
@Size(min = 2, max = 1224, message = "awsStsExternalId length should be between 2 and 1224 characters")
20+
private String awsStsExternalId;
21+
22+
@JsonProperty("sts_header_overrides")
23+
@Size(max = 5, message = "sts_header_overrides supports a maximum of 5 headers to override")
24+
private Map<String, String> awsStsHeaderOverrides;
25+
26+
public Region getAwsRegion() {
27+
return awsRegion != null ? Region.of(awsRegion) : null;
28+
}
29+
30+
public String getAwsStsRoleArn() {
31+
return awsStsRoleArn;
32+
}
33+
34+
public String getAwsStsExternalId() {
35+
return awsStsExternalId;
36+
}
37+
38+
public Map<String, String> getAwsStsHeaderOverrides() {
39+
return awsStsHeaderOverrides;
40+
}
41+
42+
}

0 commit comments

Comments
 (0)