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]

Reply via email to