This is an automated email from the ASF dual-hosted git repository.
mikexue pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/eventmesh.git
The following commit(s) were added to refs/heads/master by this push:
new c29ada62f [ISSUE #4082][Task1] Support S3 file source connector (#4132)
c29ada62f is described below
commit c29ada62fcdd12750b683b65b57079eb5316ac53
Author: TheR1sing3un <[email protected]>
AuthorDate: Tue Aug 15 09:44:47 2023 +0800
[ISSUE #4082][Task1] Support S3 file source connector (#4132)
* feat(connector): add S3 file source connector with specified format
1. add S3 file source connector with specified format
Closes https://github.com/apache/eventmesh/issues/4082
* test(connector): add S3SourceConnectorTest to verify
1. add S3SourceConnectorTest to verify
Closes https://github.com/apache/eventmesh/issues/4082
* feat(connector): add S3SourceWorker
1. add S3SourceWorker
Closes https://github.com/apache/eventmesh/issues/4082
* style(connector): add header license
1. add header license
Closes https://github.com/apache/eventmesh/issues/4082
* refactor(connector): refactor S3 source connector
1. refactor S3 source connector
Closes https://github.com/apache/eventmesh/issues/4082
---
build.gradle | 2 +
.../eventmesh-connector-s3/build.gradle | 23 +++
.../eventmesh-connector-s3/gradle.properties | 16 ++
.../connector/s3/config/S3ServerConfig.java | 33 +++++
.../connector/s3/server/S3ConnectServer.java | 41 ++++++
.../connector/s3/source/config/S3SourceConfig.java | 29 ++++
.../s3/source/config/SourceConnectorConfig.java | 54 +++++++
.../s3/source/connector/S3SourceConnector.java | 161 +++++++++++++++++++++
.../connector/s3/source/S3SourceConnectorTest.java | 136 +++++++++++++++++
settings.gradle | 1 +
10 files changed, 496 insertions(+)
diff --git a/build.gradle b/build.gradle
index a30f89c3b..e368eb58c 100644
--- a/build.gradle
+++ b/build.gradle
@@ -527,6 +527,8 @@ subprojects {
dependency "com.github.seancfoley:ipaddress:5.3.3"
dependency "javax.annotation:javax.annotation-api:1.3.2"
dependency "com.alibaba:fastjson:1.2.83"
+
+ dependency "software.amazon.awssdk:s3:2.20.29"
}
}
}
diff --git a/eventmesh-connectors/eventmesh-connector-s3/build.gradle
b/eventmesh-connectors/eventmesh-connector-s3/build.gradle
new file mode 100644
index 000000000..9d004b2f1
--- /dev/null
+++ b/eventmesh-connectors/eventmesh-connector-s3/build.gradle
@@ -0,0 +1,23 @@
+/*
+ * 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.
+ */
+
+dependencies {
+ implementation project(":eventmesh-openconnect:eventmesh-openconnect-java")
+ implementation 'software.amazon.awssdk:s3'
+ compileOnly 'org.projectlombok:lombok'
+ annotationProcessor 'org.projectlombok:lombok'
+}
\ No newline at end of file
diff --git a/eventmesh-connectors/eventmesh-connector-s3/gradle.properties
b/eventmesh-connectors/eventmesh-connector-s3/gradle.properties
new file mode 100644
index 000000000..a9fd83fea
--- /dev/null
+++ b/eventmesh-connectors/eventmesh-connector-s3/gradle.properties
@@ -0,0 +1,16 @@
+#
+# 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.
+#
\ No newline at end of file
diff --git
a/eventmesh-connectors/eventmesh-connector-s3/src/main/java/org/apache/eventmesh/connector/s3/config/S3ServerConfig.java
b/eventmesh-connectors/eventmesh-connector-s3/src/main/java/org/apache/eventmesh/connector/s3/config/S3ServerConfig.java
new file mode 100644
index 000000000..f5c4371d4
--- /dev/null
+++
b/eventmesh-connectors/eventmesh-connector-s3/src/main/java/org/apache/eventmesh/connector/s3/config/S3ServerConfig.java
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+
+package org.apache.eventmesh.connector.s3.config;
+
+import org.apache.eventmesh.openconnect.api.config.Config;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class S3ServerConfig extends Config {
+
+ private boolean sourceEnable;
+
+ private boolean sinkEnable;
+
+}
diff --git
a/eventmesh-connectors/eventmesh-connector-s3/src/main/java/org/apache/eventmesh/connector/s3/server/S3ConnectServer.java
b/eventmesh-connectors/eventmesh-connector-s3/src/main/java/org/apache/eventmesh/connector/s3/server/S3ConnectServer.java
new file mode 100644
index 000000000..e1b485801
--- /dev/null
+++
b/eventmesh-connectors/eventmesh-connector-s3/src/main/java/org/apache/eventmesh/connector/s3/server/S3ConnectServer.java
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+
+package org.apache.eventmesh.connector.s3.server;
+
+import org.apache.eventmesh.connector.s3.config.S3ServerConfig;
+import org.apache.eventmesh.connector.s3.source.connector.S3SourceConnector;
+import org.apache.eventmesh.openconnect.Application;
+import org.apache.eventmesh.openconnect.util.ConfigUtil;
+
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+public class S3ConnectServer {
+
+ public static void main(String[] args) throws Exception {
+ S3ServerConfig s3ServerConfig = ConfigUtil.parse(S3ServerConfig.class,
"server-config.yml");
+ if (s3ServerConfig.isSourceEnable()) {
+ Application application = new Application();
+ application.run(S3SourceConnector.class);
+ }
+
+ if (s3ServerConfig.isSinkEnable()) {
+ log.error("S3 sink is not supported yet.");
+ }
+ }
+}
diff --git
a/eventmesh-connectors/eventmesh-connector-s3/src/main/java/org/apache/eventmesh/connector/s3/source/config/S3SourceConfig.java
b/eventmesh-connectors/eventmesh-connector-s3/src/main/java/org/apache/eventmesh/connector/s3/source/config/S3SourceConfig.java
new file mode 100644
index 000000000..3355e8438
--- /dev/null
+++
b/eventmesh-connectors/eventmesh-connector-s3/src/main/java/org/apache/eventmesh/connector/s3/source/config/S3SourceConfig.java
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ */
+
+
+package org.apache.eventmesh.connector.s3.source.config;
+
+import org.apache.eventmesh.openconnect.api.config.SourceConfig;
+
+import lombok.Data;
+
+
+@Data
+public class S3SourceConfig extends SourceConfig {
+ private SourceConnectorConfig sourceConnectorConfig;
+}
diff --git
a/eventmesh-connectors/eventmesh-connector-s3/src/main/java/org/apache/eventmesh/connector/s3/source/config/SourceConnectorConfig.java
b/eventmesh-connectors/eventmesh-connector-s3/src/main/java/org/apache/eventmesh/connector/s3/source/config/SourceConnectorConfig.java
new file mode 100644
index 000000000..314ae4b1f
--- /dev/null
+++
b/eventmesh-connectors/eventmesh-connector-s3/src/main/java/org/apache/eventmesh/connector/s3/source/config/SourceConnectorConfig.java
@@ -0,0 +1,54 @@
+/*
+ * 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.
+ */
+
+
+package org.apache.eventmesh.connector.s3.source.config;
+
+import java.util.Map;
+
+import lombok.Data;
+
+@Data
+public class SourceConnectorConfig {
+
+ private String connectorName;
+
+ private String region;
+
+ private String bucket;
+
+ private String accessKey;
+
+ private String secretKey;
+
+ private String fileName;
+
+ /**
+ * The schema for the data to be read from S3.
+ */
+ private Map<String/*column name*/, Integer/*bytes*/> schema;
+
+ /**
+ * The maximum number of records that should be returned in each batch
poll.
+ */
+ private Integer batchSize = 20;
+
+ /**
+ * The maximum ms to wait for request futures to complete.
+ */
+ private long timeout = 3000;
+}
diff --git
a/eventmesh-connectors/eventmesh-connector-s3/src/main/java/org/apache/eventmesh/connector/s3/source/connector/S3SourceConnector.java
b/eventmesh-connectors/eventmesh-connector-s3/src/main/java/org/apache/eventmesh/connector/s3/source/connector/S3SourceConnector.java
new file mode 100644
index 000000000..43b757d08
--- /dev/null
+++
b/eventmesh-connectors/eventmesh-connector-s3/src/main/java/org/apache/eventmesh/connector/s3/source/connector/S3SourceConnector.java
@@ -0,0 +1,161 @@
+/*
+ * 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.
+ */
+
+package org.apache.eventmesh.connector.s3.source.connector;
+
+
+import org.apache.eventmesh.connector.s3.source.config.S3SourceConfig;
+import org.apache.eventmesh.connector.s3.source.config.SourceConnectorConfig;
+import org.apache.eventmesh.openconnect.api.config.Config;
+import org.apache.eventmesh.openconnect.api.source.Source;
+import org.apache.eventmesh.openconnect.offsetmgmt.api.data.ConnectRecord;
+import org.apache.eventmesh.openconnect.offsetmgmt.api.data.RecordOffset;
+import org.apache.eventmesh.openconnect.offsetmgmt.api.data.RecordPartition;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.TimeUnit;
+
+import lombok.extern.slf4j.Slf4j;
+
+import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
+import software.amazon.awssdk.core.ResponseBytes;
+import software.amazon.awssdk.core.async.AsyncResponseTransformer;
+import software.amazon.awssdk.regions.Region;
+import software.amazon.awssdk.services.s3.S3AsyncClient;
+import software.amazon.awssdk.services.s3.model.GetObjectRequest;
+import software.amazon.awssdk.services.s3.model.GetObjectResponse;
+import software.amazon.awssdk.services.s3.model.HeadObjectResponse;
+
+@Slf4j
+public class S3SourceConnector implements Source {
+
+ public static final String REGION = "region";
+
+ public static final String BUCKET = "bucket";
+
+ public static final String FILE_NAME = "fileName";
+
+ public static final String POSITION = "position";
+
+ private S3SourceConfig sourceConfig;
+
+ private SourceConnectorConfig sourceConnectorConfig;
+
+ private int eachRecordSize;
+
+ private long fileSize;
+
+ private S3AsyncClient s3Client;
+
+ private long position;
+
+
+ @Override
+ public Class<? extends Config> configClass() {
+ return S3SourceConfig.class;
+ }
+
+ @Override
+ public void init(Config config) throws Exception {
+ // init config for s3 source connector
+ this.sourceConfig = (S3SourceConfig) config;
+ this.sourceConnectorConfig =
this.sourceConfig.getSourceConnectorConfig();
+ this.eachRecordSize = calculateEachRecordSize();
+ AwsBasicCredentials basicCredentials =
AwsBasicCredentials.create(this.sourceConnectorConfig.getAccessKey(),
+ this.sourceConnectorConfig.getSecretKey());
+ this.s3Client = S3AsyncClient.builder().credentialsProvider(() ->
basicCredentials)
+ .region(Region.of(this.sourceConnectorConfig.getRegion())).build();
+ }
+
+ private int calculateEachRecordSize() {
+ Optional<Integer> sum =
this.sourceConnectorConfig.getSchema().values().stream().reduce((x, y) -> x +
y);
+ return sum.orElse(0);
+ }
+
+ @Override
+ public void start() throws Exception {
+ CompletableFuture<HeadObjectResponse>
headObjectResponseCompletableFuture = this.s3Client.headObject(
+ builder ->
builder.bucket(this.sourceConnectorConfig.getBucket()).key(this.sourceConnectorConfig.getFileName()));
+
headObjectResponseCompletableFuture.get(this.sourceConnectorConfig.getTimeout(),
TimeUnit.MILLISECONDS);
+ this.fileSize =
headObjectResponseCompletableFuture.get().contentLength();
+ }
+
+ @Override
+ public void commit(ConnectRecord record) {
+
+ }
+
+ @Override
+ public String name() {
+ return this.sourceConfig.getSourceConnectorConfig().getConnectorName();
+ }
+
+ @Override
+ public void stop() throws Exception {
+
+ }
+
+ @Override
+ public List<ConnectRecord> poll() {
+ if (this.position >= this.fileSize) {
+ return Collections.EMPTY_LIST;
+ }
+ long startPosition = this.position;
+ long endPosition = Math.min(this.fileSize, this.position +
this.eachRecordSize * this.sourceConnectorConfig.getBatchSize()) - 1;
+ GetObjectRequest request =
GetObjectRequest.builder().bucket(this.sourceConnectorConfig.getBucket())
+ .key(this.sourceConnectorConfig.getFileName())
+ .range("bytes=" + startPosition + "-" + endPosition).build();
+ ResponseBytes<GetObjectResponse> resp;
+ try {
+ resp = this.s3Client.getObject(request,
AsyncResponseTransformer.toBytes())
+ .get(this.sourceConnectorConfig.getTimeout(),
TimeUnit.MILLISECONDS);
+ } catch (Exception e) {
+ log.error("poll records from S3 file, poll range {}-{}, but
failed", startPosition, endPosition, e);
+ return Collections.EMPTY_LIST;
+ }
+ byte[] bytes = resp.asByteArray();
+ List<ConnectRecord> records = new ArrayList<>(bytes.length /
this.eachRecordSize);
+ for (int i = 0; i < bytes.length; i += this.eachRecordSize) {
+ byte[] body = new byte[this.eachRecordSize];
+ System.arraycopy(bytes, i, body, 0, this.eachRecordSize);
+ this.position += this.eachRecordSize;
+ ConnectRecord record = new ConnectRecord(getRecordPartition(),
getRecordOffset(), System.currentTimeMillis(), body);
+ records.add(record);
+ }
+ return records;
+ }
+
+ private RecordPartition getRecordPartition() {
+ Map<String, String> map = new HashMap<>();
+ map.put(REGION, this.sourceConnectorConfig.getRegion());
+ map.put(BUCKET, this.sourceConnectorConfig.getBucket());
+ map.put(FILE_NAME, this.sourceConnectorConfig.getFileName());
+ return new RecordPartition(map);
+ }
+
+ private RecordOffset getRecordOffset() {
+ Map<String, String> map = new HashMap<>();
+ map.put(POSITION, String.valueOf(this.position));
+ return new RecordOffset(map);
+ }
+}
diff --git
a/eventmesh-connectors/eventmesh-connector-s3/src/test/java/org/apache/eventmesh/connector/s3/source/S3SourceConnectorTest.java
b/eventmesh-connectors/eventmesh-connector-s3/src/test/java/org/apache/eventmesh/connector/s3/source/S3SourceConnectorTest.java
new file mode 100644
index 000000000..27ab9d96e
--- /dev/null
+++
b/eventmesh-connectors/eventmesh-connector-s3/src/test/java/org/apache/eventmesh/connector/s3/source/S3SourceConnectorTest.java
@@ -0,0 +1,136 @@
+/*
+ * 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.
+ */
+
+package org.apache.eventmesh.connector.s3.source;
+
+import org.apache.eventmesh.connector.s3.source.config.S3SourceConfig;
+import org.apache.eventmesh.connector.s3.source.config.SourceConnectorConfig;
+import org.apache.eventmesh.connector.s3.source.connector.S3SourceConnector;
+import org.apache.eventmesh.openconnect.offsetmgmt.api.data.ConnectRecord;
+
+import java.nio.ByteBuffer;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
+import software.amazon.awssdk.core.async.AsyncRequestBody;
+import software.amazon.awssdk.regions.Region;
+import software.amazon.awssdk.services.s3.S3AsyncClient;
+import software.amazon.awssdk.services.s3.model.PutObjectRequest;
+
+
+@Ignore
+public class S3SourceConnectorTest {
+
+ private static final S3SourceConfig sourceConfig;
+
+ private static final SourceConnectorConfig SOURCE_CONNECTOR_CONFIG;
+
+ private static final Map<String, Integer> schema;
+
+ private static final int eachRecordSize;
+
+ static {
+ sourceConfig = new S3SourceConfig();
+ SOURCE_CONNECTOR_CONFIG = new SourceConnectorConfig();
+ SOURCE_CONNECTOR_CONFIG.setConnectorName("S3SourceConnector");
+ SOURCE_CONNECTOR_CONFIG.setRegion("ap-southeast-1");
+ SOURCE_CONNECTOR_CONFIG.setBucket("event-mesh-bucket");
+ SOURCE_CONNECTOR_CONFIG.setAccessKey("access-key");
+ SOURCE_CONNECTOR_CONFIG.setSecretKey("secret-key");
+
+ SOURCE_CONNECTOR_CONFIG.setFileName("test-file");
+
+ schema = new HashMap<>();
+ schema.put("id", 4);
+ schema.put("body", 16);
+ schema.put("time", 8);
+
+ eachRecordSize = schema.values().stream().reduce((x, y) -> x +
y).orElse(0);
+ SOURCE_CONNECTOR_CONFIG.setSchema(schema);
+ sourceConfig.setSourceConnectorConfig(SOURCE_CONNECTOR_CONFIG);
+ }
+
+ private S3AsyncClient s3Client;
+
+ @Before
+ public void setUp() throws Exception {
+ AwsBasicCredentials basicCredentials =
AwsBasicCredentials.create(this.SOURCE_CONNECTOR_CONFIG.getAccessKey(),
+ this.SOURCE_CONNECTOR_CONFIG.getSecretKey());
+ this.s3Client = S3AsyncClient.builder().credentialsProvider(() ->
basicCredentials)
+
.region(Region.of(this.SOURCE_CONNECTOR_CONFIG.getRegion())).build();
+
+ // write mocked data
+ this.writeMockedRecords(200);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ // clear file
+ this.s3Client.deleteObject(builder ->
builder.bucket(this.SOURCE_CONNECTOR_CONFIG.getBucket())
+ .key(this.SOURCE_CONNECTOR_CONFIG.getFileName()).build()).get();
+ }
+
+ @Test
+ public void testS3SourceConnector() throws Exception {
+ S3SourceConnector s3SourceConnector = new S3SourceConnector();
+ s3SourceConnector.init(sourceConfig);
+ s3SourceConnector.start();
+ int expectedId = 0;
+ while (true) {
+ List<ConnectRecord> connectRecords = s3SourceConnector.poll();
+ if (connectRecords.isEmpty()) {
+ break;
+ }
+ Assert.assertEquals(20, connectRecords.size());
+ for (ConnectRecord connectRecord : connectRecords) {
+ byte[] data = (byte[]) connectRecord.getData();
+ Assert.assertEquals(eachRecordSize, data.length);
+ ByteBuffer byteBuffer = ByteBuffer.wrap(data);
+ int id = byteBuffer.getInt();
+ Assert.assertEquals(expectedId++, id);
+ }
+ }
+
+ }
+
+ private void writeMockedRecords(int count) throws Exception {
+ ByteBuffer bytes = ByteBuffer.allocate(count * eachRecordSize);
+ ByteBuffer body = ByteBuffer.allocate(16);
+ body.putLong(13L);
+ body.putLong(13L);
+ body.flip();
+ for (int i = 0; i < count; i++) {
+ bytes.putInt(i);
+ bytes.put(body);
+ body.flip();
+ bytes.putLong(System.currentTimeMillis());
+ }
+ PutObjectRequest putObjectRequest = PutObjectRequest.builder()
+
.bucket(SOURCE_CONNECTOR_CONFIG.getBucket()).key(SOURCE_CONNECTOR_CONFIG.getFileName()).build();
+ AsyncRequestBody requestBody =
AsyncRequestBody.fromBytes(bytes.array());
+ this.s3Client.putObject(putObjectRequest, requestBody).get();
+ }
+
+}
diff --git a/settings.gradle b/settings.gradle
index fe42d4030..588cbddc5 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -81,3 +81,4 @@ include 'eventmesh-webhook:eventmesh-webhook-receive'
include 'eventmesh-security-plugin'
include 'eventmesh-security-plugin:eventmesh-security-api'
include 'eventmesh-security-plugin:eventmesh-security-auth-token'
+include 'eventmesh-connectors:eventmesh-connector-s3'
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]