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 5a8cd37eb [ISSUE #4420] Add Feishu Sink connector (#4522)
5a8cd37eb is described below
commit 5a8cd37eb3944b0ea7aad2478ab4c5ebb39e2c85
Author: SunnyBoy-WYH <[email protected]>
AuthorDate: Sun Nov 19 12:47:01 2023 +0800
[ISSUE #4420] Add Feishu Sink connector (#4522)
* [ISSUE #4420] Add Feishu Sink connector
* [ISSUE #4420] Add Feishu Sink connector
* [ISSUE #4420] Add Feishu Sink connector
* [ISSUE #4420] Add Feishu Sink connector
* [ISSUE #4420] Add Feishu Sink connector,code style
* [ISSUE #4420] Add Feishu Sink connector,check style
* [ISSUE #4420] Add Feishu Sink connector,mock test
* [ISSUE #4420] Add Feishu Sink connector,mock test
* [ISSUE #4420] Add Feishu Sink connector,mock test
---
.../org/apache/eventmesh/common/Constants.java | 10 ++
.../eventmesh-connector-feishu/build.gradle | 33 +++++
.../eventmesh-connector-feishu/gradle.properties | 18 +++
.../feishu/server/FeishuConnectServer.java | 33 +++++
.../feishu/sink/config/FeishuSinkConfig.java | 31 +++++
.../feishu/sink/config/SinkConnectorConfig.java | 34 +++++
.../feishu/sink/connector/FeishuSinkConnector.java | 149 +++++++++++++++++++++
.../src/main/resources/sink-config.yml | 30 +++++
.../s3/source/FeishuSinkConnectorTest.java | 110 +++++++++++++++
settings.gradle | 2 +
10 files changed, 450 insertions(+)
diff --git
a/eventmesh-common/src/main/java/org/apache/eventmesh/common/Constants.java
b/eventmesh-common/src/main/java/org/apache/eventmesh/common/Constants.java
index 3bc3cbd7e..f60ba0f26 100644
--- a/eventmesh-common/src/main/java/org/apache/eventmesh/common/Constants.java
+++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/Constants.java
@@ -206,4 +206,14 @@ public class Constants {
public static final String DEFAULT = "default";
+ public static final String FEISHU_SEND_MESSAGE_API =
"https://open.feishu.cn/open-apis/im/v1/messages?receive_id_type=";
+
+ public static final String FEISHU_RECEIVE_ID = "receive_id";
+
+ public static final String FEISHU_MSG_TYPE = "msg_type";
+
+ public static final String FEISHU_CONTENT = "content";
+
+ public static final String FEISHU_UUID = "uuid";
+
}
diff --git a/eventmesh-connectors/eventmesh-connector-feishu/build.gradle
b/eventmesh-connectors/eventmesh-connector-feishu/build.gradle
new file mode 100644
index 000000000..b5bd61258
--- /dev/null
+++ b/eventmesh-connectors/eventmesh-connector-feishu/build.gradle
@@ -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.
+ */
+
+List feishu = [
+ "com.larksuite.oapi:oapi-sdk:$feishu_version",
+ "com.github.rholder:guava-retrying:$guava_retrying_version",
+ "org.apache.httpcomponents:httpclient",
+ project(":eventmesh-common")
+]
+
+dependencies {
+ api project(":eventmesh-openconnect:eventmesh-openconnect-java")
+ implementation feishu
+ compileOnly 'org.projectlombok:lombok'
+ annotationProcessor 'org.projectlombok:lombok'
+
+ testImplementation "org.mockito:mockito-core"
+ testImplementation "org.mockito:mockito-junit-jupiter"
+}
\ No newline at end of file
diff --git a/eventmesh-connectors/eventmesh-connector-feishu/gradle.properties
b/eventmesh-connectors/eventmesh-connector-feishu/gradle.properties
new file mode 100644
index 000000000..d2238bfc9
--- /dev/null
+++ b/eventmesh-connectors/eventmesh-connector-feishu/gradle.properties
@@ -0,0 +1,18 @@
+#
+# 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.
+#
+feishu_version=2.0.28
+guava_retrying_version=2.0.0
\ No newline at end of file
diff --git
a/eventmesh-connectors/eventmesh-connector-feishu/src/main/java/org/apache/eventmesh/connector/feishu/server/FeishuConnectServer.java
b/eventmesh-connectors/eventmesh-connector-feishu/src/main/java/org/apache/eventmesh/connector/feishu/server/FeishuConnectServer.java
new file mode 100644
index 000000000..996ccdd31
--- /dev/null
+++
b/eventmesh-connectors/eventmesh-connector-feishu/src/main/java/org/apache/eventmesh/connector/feishu/server/FeishuConnectServer.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.feishu.server;
+
+import
org.apache.eventmesh.connector.feishu.sink.connector.FeishuSinkConnector;
+import org.apache.eventmesh.openconnect.Application;
+
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+public class FeishuConnectServer {
+
+ public static void main(String[] args) throws Exception {
+
+ Application feishuSinkApp = new Application();
+ feishuSinkApp.run(FeishuSinkConnector.class);
+ }
+}
diff --git
a/eventmesh-connectors/eventmesh-connector-feishu/src/main/java/org/apache/eventmesh/connector/feishu/sink/config/FeishuSinkConfig.java
b/eventmesh-connectors/eventmesh-connector-feishu/src/main/java/org/apache/eventmesh/connector/feishu/sink/config/FeishuSinkConfig.java
new file mode 100644
index 000000000..0fcc3d42c
--- /dev/null
+++
b/eventmesh-connectors/eventmesh-connector-feishu/src/main/java/org/apache/eventmesh/connector/feishu/sink/config/FeishuSinkConfig.java
@@ -0,0 +1,31 @@
+/*
+ * 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.feishu.sink.config;
+
+import org.apache.eventmesh.openconnect.api.config.SinkConfig;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class FeishuSinkConfig extends SinkConfig {
+
+ public SinkConnectorConfig connectorConfig;
+
+}
diff --git
a/eventmesh-connectors/eventmesh-connector-feishu/src/main/java/org/apache/eventmesh/connector/feishu/sink/config/SinkConnectorConfig.java
b/eventmesh-connectors/eventmesh-connector-feishu/src/main/java/org/apache/eventmesh/connector/feishu/sink/config/SinkConnectorConfig.java
new file mode 100644
index 000000000..8bb76533a
--- /dev/null
+++
b/eventmesh-connectors/eventmesh-connector-feishu/src/main/java/org/apache/eventmesh/connector/feishu/sink/config/SinkConnectorConfig.java
@@ -0,0 +1,34 @@
+/*
+ * 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.feishu.sink.config;
+
+import lombok.Data;
+
+@Data
+public class SinkConnectorConfig {
+
+ private String connectorName;
+
+ private String receiveId;
+
+ private String appId;
+
+ private String appSecret;
+
+ private String receiveIdType;
+}
diff --git
a/eventmesh-connectors/eventmesh-connector-feishu/src/main/java/org/apache/eventmesh/connector/feishu/sink/connector/FeishuSinkConnector.java
b/eventmesh-connectors/eventmesh-connector-feishu/src/main/java/org/apache/eventmesh/connector/feishu/sink/connector/FeishuSinkConnector.java
new file mode 100644
index 000000000..ea4032ebc
--- /dev/null
+++
b/eventmesh-connectors/eventmesh-connector-feishu/src/main/java/org/apache/eventmesh/connector/feishu/sink/connector/FeishuSinkConnector.java
@@ -0,0 +1,149 @@
+/*
+ * 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.feishu.sink.connector;
+
+import static org.apache.eventmesh.common.Constants.FEISHU_CONTENT;
+import static org.apache.eventmesh.common.Constants.FEISHU_MSG_TYPE;
+import static org.apache.eventmesh.common.Constants.FEISHU_RECEIVE_ID;
+import static org.apache.eventmesh.common.Constants.FEISHU_SEND_MESSAGE_API;
+import static org.apache.eventmesh.common.Constants.FEISHU_UUID;
+
+import org.apache.eventmesh.connector.feishu.sink.config.FeishuSinkConfig;
+import org.apache.eventmesh.connector.feishu.sink.config.SinkConnectorConfig;
+import org.apache.eventmesh.openconnect.api.config.Config;
+import org.apache.eventmesh.openconnect.api.connector.ConnectorContext;
+import org.apache.eventmesh.openconnect.api.connector.SinkConnectorContext;
+import org.apache.eventmesh.openconnect.api.sink.Sink;
+import org.apache.eventmesh.openconnect.offsetmgmt.api.data.ConnectRecord;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
+
+import com.github.rholder.retry.Attempt;
+import com.github.rholder.retry.RetryListener;
+import com.github.rholder.retry.Retryer;
+import com.github.rholder.retry.RetryerBuilder;
+import com.github.rholder.retry.StopStrategies;
+import com.github.rholder.retry.WaitStrategies;
+import com.lark.oapi.Client;
+import com.lark.oapi.core.response.RawResponse;
+import com.lark.oapi.core.token.AccessTokenType;
+import com.lark.oapi.service.im.v1.enums.MsgTypeEnum;
+import com.lark.oapi.service.im.v1.model.ext.MessageText;
+
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+public class FeishuSinkConnector implements Sink {
+
+ private FeishuSinkConfig sinkConfig;
+
+ private Client feishuClient;
+
+ private static final int MAX_RETRY_TIME = 3;
+
+ private static final int FIXED_WAIT_SECOND = 1;
+
+ private final Retryer<Boolean> retryer =
RetryerBuilder.<Boolean>newBuilder().retryIfException().retryIfResult(res ->
!res)
+ .withWaitStrategy(WaitStrategies.fixedWait(FIXED_WAIT_SECOND,
TimeUnit.SECONDS))
+
.withStopStrategy(StopStrategies.stopAfterAttempt(MAX_RETRY_TIME)).withRetryListener(new
RetryListener() {
+
+ @Override
+ public <V> void onRetry(Attempt<V> attempt) {
+ long times = attempt.getAttemptNumber();
+ log.warn("retry invoke http,times={}", times);
+ }
+ }).build();
+
+ @Override
+ public Class<? extends Config> configClass() {
+ return FeishuSinkConfig.class;
+ }
+
+ @Override
+ public void init(Config config) throws Exception {
+ // init config for feishu sink connector
+ this.sinkConfig = (FeishuSinkConfig) config;
+ doInit();
+ }
+
+ @Override
+ public void init(ConnectorContext connectorContext) throws Exception {
+ // init config for feishu sink connector
+ SinkConnectorContext sinkConnectorContext = (SinkConnectorContext)
connectorContext;
+ this.sinkConfig = (FeishuSinkConfig)
sinkConnectorContext.getSinkConfig();
+ doInit();
+ }
+
+ private void doInit() {
+ this.feishuClient = Client.newBuilder(this.getConfig().getAppId(),
this.getConfig().getAppSecret()).requestTimeout(3, TimeUnit.SECONDS)
+ .build();
+ }
+
+ @Override
+ public void start() {
+ }
+
+ @Override
+ public void commit(ConnectRecord record) {
+
+ }
+
+ @Override
+ public String name() {
+ return this.sinkConfig.getConnectorConfig().getConnectorName();
+ }
+
+ @Override
+ public void stop() {
+ }
+
+ @Override
+ public void put(List<ConnectRecord> sinkRecords) {
+ SinkConnectorConfig connectorConfig = getConfig();
+ try {
+ for (ConnectRecord connectRecord : sinkRecords) {
+ AtomicReference<RawResponse> response = new
AtomicReference<>();
+ retryer.call(() -> {
+ Map<String, Object> body = new HashMap<>();
+ body.put(FEISHU_RECEIVE_ID,
connectorConfig.getReceiveId());
+ body.put(FEISHU_CONTENT,
MessageText.newBuilder().text(connectRecord.getData().toString()).build());
+ body.put(FEISHU_MSG_TYPE,
MsgTypeEnum.MSG_TYPE_TEXT.getValue());
+ body.put(FEISHU_UUID, UUID.randomUUID().toString());
+ response.set(feishuClient.post(FEISHU_SEND_MESSAGE_API +
connectorConfig.getReceiveIdType(), body, AccessTokenType.Tenant));
+ if (response.get().getStatusCode() != 200) {
+ log.error("request feishu open api err{}", new
String(response.get().getBody()));
+ return false;
+ }
+ return true;
+ });
+ }
+ } catch (Exception e) {
+ log.error("failed to put message to feishu", e);
+ }
+ }
+
+ public SinkConnectorConfig getConfig() {
+ return this.sinkConfig.getConnectorConfig();
+ }
+
+}
diff --git
a/eventmesh-connectors/eventmesh-connector-feishu/src/main/resources/sink-config.yml
b/eventmesh-connectors/eventmesh-connector-feishu/src/main/resources/sink-config.yml
new file mode 100644
index 000000000..01cb95335
--- /dev/null
+++
b/eventmesh-connectors/eventmesh-connector-feishu/src/main/resources/sink-config.yml
@@ -0,0 +1,30 @@
+#
+# 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.
+#
+
+pubSubConfig:
+ meshAddress: 127.0.0.1:10000
+ subject: TopicTest
+ idc: FT
+ env: PRD
+ group: feishuSink
+ appId: 5031
+ userName: feishuSinkUser
+ passWord: feishuPassWord
+connectorConfig:
+ connectorName: feishuSink
+ reciveId: reciveIdValue
+ reciveType: open_id
diff --git
a/eventmesh-connectors/eventmesh-connector-feishu/src/test/java/org/apache/eventmesh/connector/s3/source/FeishuSinkConnectorTest.java
b/eventmesh-connectors/eventmesh-connector-feishu/src/test/java/org/apache/eventmesh/connector/s3/source/FeishuSinkConnectorTest.java
new file mode 100644
index 000000000..40f6db500
--- /dev/null
+++
b/eventmesh-connectors/eventmesh-connector-feishu/src/test/java/org/apache/eventmesh/connector/s3/source/FeishuSinkConnectorTest.java
@@ -0,0 +1,110 @@
+/*
+ * 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 static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import org.apache.eventmesh.connector.feishu.sink.config.FeishuSinkConfig;
+import org.apache.eventmesh.connector.feishu.sink.config.SinkConnectorConfig;
+import
org.apache.eventmesh.connector.feishu.sink.connector.FeishuSinkConnector;
+import org.apache.eventmesh.openconnect.offsetmgmt.api.data.ConnectRecord;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.platform.commons.support.HierarchyTraversalMode;
+import org.junit.platform.commons.support.ReflectionSupport;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import com.lark.oapi.Client;
+import com.lark.oapi.core.response.RawResponse;
+
+@ExtendWith(MockitoExtension.class)
+public class FeishuSinkConnectorTest {
+
+ private static final FeishuSinkConfig sinkConfig;
+
+ private static final SinkConnectorConfig SINK_CONNECTOR_CONFIG;
+
+ static {
+ sinkConfig = new FeishuSinkConfig();
+ SINK_CONNECTOR_CONFIG = new SinkConnectorConfig();
+ SINK_CONNECTOR_CONFIG.setConnectorName("FeishuSinkConnector");
+ SINK_CONNECTOR_CONFIG.setAppId("xxx");
+ SINK_CONNECTOR_CONFIG.setAppSecret("xxx");
+ SINK_CONNECTOR_CONFIG.setReceiveId("xxx");
+ SINK_CONNECTOR_CONFIG.setReceiveIdType("open_id");
+ sinkConfig.setConnectorConfig(SINK_CONNECTOR_CONFIG);
+ }
+
+ private FeishuSinkConnector feishuSinkConnector;
+
+ @Mock
+ private Client feishuClient;
+
+ @BeforeEach
+ public void setup() throws Exception {
+ feishuSinkConnector = new FeishuSinkConnector();
+ RawResponse response = new RawResponse();
+ response.setStatusCode(200);
+ Mockito.doReturn(response).when(feishuClient).post(Mockito.any(),
Mockito.any(), Mockito.any());
+
+ Field feishuClientField =
ReflectionSupport.findFields(feishuSinkConnector.getClass(),
+ (f) -> f.getName().equals("feishuClient"),
+ HierarchyTraversalMode.BOTTOM_UP).get(0);
+
+ feishuClientField.setAccessible(true);
+ feishuClientField.set(feishuSinkConnector, feishuClient);
+
+ Field sinkConfigField =
ReflectionSupport.findFields(feishuSinkConnector.getClass(),
+ (f) -> f.getName().equals("sinkConfig"),
+ HierarchyTraversalMode.BOTTOM_UP).get(0);
+
+ sinkConfigField.setAccessible(true);
+ sinkConfigField.set(feishuSinkConnector, sinkConfig);
+ }
+
+ @Test
+ public void testFeishuSinkConnector() throws Exception {
+ feishuSinkConnector.start();
+ final int times = 3;
+ List<ConnectRecord> connectRecords = new ArrayList<>();
+ for (int i = 0; i < times; i++) {
+ connectRecords.add(new ConnectRecord(null, null, 0L, "test"));
+ }
+ feishuSinkConnector.put(connectRecords);
+
+ verify(feishuClient, times(times)).post(any(), any(), any());
+
+ }
+
+ @AfterEach
+ public void tearDown() {
+ feishuSinkConnector.stop();
+ }
+
+}
diff --git a/settings.gradle b/settings.gradle
index 6ce44c1d6..414b086ab 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -45,6 +45,7 @@ include 'eventmesh-connectors:eventmesh-connector-file'
include 'eventmesh-connectors:eventmesh-connector-spring'
include 'eventmesh-connectors:eventmesh-connector-prometheus'
include 'eventmesh-connectors:eventmesh-connector-dingding'
+include 'eventmesh-connectors:eventmesh-connector-feishu'
include 'eventmesh-storage-plugin:eventmesh-storage-api'
include 'eventmesh-storage-plugin:eventmesh-storage-standalone'
@@ -94,3 +95,4 @@ include 'eventmesh-webhook:eventmesh-webhook-receive'
include 'eventmesh-retry'
include 'eventmesh-retry:eventmesh-retry-api'
include 'eventmesh-retry:eventmesh-retry-rocketmq'
+
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]