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 f6297308f [ISSUE #4414] Add spring sink connector. (#4491)
f6297308f is described below
commit f6297308fc9df28fed22e186a2ac1e6b45b1e712
Author: yanrongzhen <[email protected]>
AuthorDate: Tue Oct 17 16:53:11 2023 +0800
[ISSUE #4414] Add spring sink connector. (#4491)
* Add spring sink connector.
* Restructuring consumption logic.
* Optimize create extension logic.
* Fix naming
---
.../org/apache/eventmesh/common/Constants.java | 4 +
.../apache/eventmesh/common/utils/JsonUtils.java | 19 +++
.../common/SpringApplicationContextHolder.java | 15 ++-
.../spring/config/EventMeshAutoConfiguration.java | 17 +++
.../spring/server/SpringConnectServer.java | 12 +-
.../spring/sink/EventMeshConsumerMetadata.java | 23 ++--
.../connector/spring/sink/EventMeshListener.java | 26 ++--
.../sink/EventMeshListenerBeanPostProcessor.java | 143 +++++++++++++++++++++
.../spring/sink/config/SpringSinkConfig.java | 19 +--
.../spring/sink/connector/SinkConnectorConfig.java | 15 +--
.../spring/sink/connector/SpringSinkConnector.java | 106 +++++++++++++++
.../SpringSinkConnectorCreateServiceImpl.java} | 12 +-
.../SpringSourceConnectorCreateServiceImpl.java | 4 +-
...entmesh.openconnect.api.ConnectorCreateService} | 3 +-
.../{source-config.yml => sink-config.yml} | 7 +-
.../src/main/resources/source-config.yml | 1 -
.../apache/eventmesh/openconnect/Application.java | 27 +++-
...ateService.java => ConnectorCreateService.java} | 9 +-
.../apache/eventmesh/runtime/demo/CCSubClient.java | 1 -
19 files changed, 394 insertions(+), 69 deletions(-)
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 9a1dc0686..41fe8dfa9 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
@@ -173,6 +173,10 @@ public class Constants {
public static final int SUCCESS_CODE = 200;
+ public static final String SINK = "Sink";
+
+ public static final String SOURCE = "Source";
+
// protocol desc
public static final String PROTOCOL_DESC_GRPC_CLOUD_EVENT =
"grpc-cloud-event";
diff --git
a/eventmesh-common/src/main/java/org/apache/eventmesh/common/utils/JsonUtils.java
b/eventmesh-common/src/main/java/org/apache/eventmesh/common/utils/JsonUtils.java
index 487ecb9b7..19614714f 100644
---
a/eventmesh-common/src/main/java/org/apache/eventmesh/common/utils/JsonUtils.java
+++
b/eventmesh-common/src/main/java/org/apache/eventmesh/common/utils/JsonUtils.java
@@ -24,6 +24,7 @@ import org.apache.eventmesh.common.exception.JsonException;
import org.apache.commons.lang3.StringUtils;
import java.io.IOException;
+import java.lang.reflect.Type;
import java.util.Objects;
import com.fasterxml.jackson.annotation.JsonInclude;
@@ -98,6 +99,24 @@ public class JsonUtils {
}
}
+ public static <T> T parseObject(String text, Type type) {
+ if (StringUtils.isEmpty(text)) {
+ return null;
+ }
+ try {
+ TypeReference<T> typeReference = new TypeReference<T>() {
+
+ @Override
+ public Type getType() {
+ return type;
+ }
+ };
+ return OBJECT_MAPPER.readValue(text, typeReference);
+ } catch (JsonProcessingException e) {
+ throw new JsonException("deserialize json string to object error",
e);
+ }
+ }
+
public static <T> T parseObject(byte[] bytes, Class<T> clazz) {
if (bytes == null || bytes.length == 0) {
return null;
diff --git
a/eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/common/SpringApplicationContextHolder.java
b/eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/common/SpringApplicationContextHolder.java
index aa110b2aa..bb07baa94 100644
---
a/eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/common/SpringApplicationContextHolder.java
+++
b/eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/common/SpringApplicationContextHolder.java
@@ -25,20 +25,21 @@ public class SpringApplicationContextHolder implements
ApplicationContextAware {
private static ApplicationContext applicationContext;
+ public static boolean isStarted() {
+ return applicationContext != null;
+ }
+
@Override
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
SpringApplicationContextHolder.applicationContext = applicationContext;
}
- public static Object getBean(String beanName) {
- return applicationContext.getBean(beanName);
+ public static <T> T getBean(Class<T> clazz) {
+ return applicationContext.getBean(clazz);
}
- public static Object getBean(Class<?> beanClass) {
- return applicationContext.getBean(beanClass);
+ public static Object getBean(String beanName) {
+ return applicationContext.getBean(beanName);
}
- public static boolean isStarted() {
- return applicationContext != null;
- }
}
diff --git
a/eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/config/EventMeshAutoConfiguration.java
b/eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/config/EventMeshAutoConfiguration.java
index 008efef8f..12f56a501 100644
---
a/eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/config/EventMeshAutoConfiguration.java
+++
b/eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/config/EventMeshAutoConfiguration.java
@@ -19,6 +19,8 @@ package org.apache.eventmesh.connector.spring.config;
import
org.apache.eventmesh.connector.spring.common.SpringApplicationContextHolder;
import org.apache.eventmesh.connector.spring.server.SpringConnectServer;
+import
org.apache.eventmesh.connector.spring.sink.EventMeshListenerBeanPostProcessor;
+import
org.apache.eventmesh.connector.spring.sink.connector.SpringSinkConnector;
import
org.apache.eventmesh.connector.spring.source.connector.SpringSourceConnector;
import
org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
@@ -32,8 +34,10 @@ import org.springframework.context.annotation.Configuration;
public class EventMeshAutoConfiguration {
public static final String SPRING_SOURCE_CONNECTOR_BEAN_NAME =
"springSourceConnector";
+ public static final String SPRING_SINK_CONNECTOR_BEAN_NAME =
"springSinkConnector";
public static final String SPRING_CONNECT_SERVER_BEAN_NAME =
"springConnectServer";
public static final String SPRING_APPLICATION_CONTEXT_HOLDER =
"springApplicationContextHolder";
+ public static final String EVENTMESH_LISTENER_BEAN_POST_PROCESSOR =
"eventMeshListenerBeanPostProcessor";
@Bean(name = SPRING_SOURCE_CONNECTOR_BEAN_NAME)
@ConditionalOnMissingBean(name = SPRING_SOURCE_CONNECTOR_BEAN_NAME)
@@ -41,6 +45,12 @@ public class EventMeshAutoConfiguration {
return new SpringSourceConnector();
}
+ @Bean(name = SPRING_SINK_CONNECTOR_BEAN_NAME)
+ @ConditionalOnMissingBean(name = SPRING_SINK_CONNECTOR_BEAN_NAME)
+ public SpringSinkConnector springSinkConnector() {
+ return new SpringSinkConnector();
+ }
+
@Bean(name = SPRING_CONNECT_SERVER_BEAN_NAME)
@ConditionalOnMissingBean(name = SPRING_CONNECT_SERVER_BEAN_NAME)
public SpringConnectServer springConnectServer() {
@@ -52,4 +62,11 @@ public class EventMeshAutoConfiguration {
public SpringApplicationContextHolder springApplicationContextHolder() {
return new SpringApplicationContextHolder();
}
+
+ @Bean(name = EVENTMESH_LISTENER_BEAN_POST_PROCESSOR)
+ @ConditionalOnMissingBean(name = EVENTMESH_LISTENER_BEAN_POST_PROCESSOR)
+ public EventMeshListenerBeanPostProcessor
eventMeshListenerBeanPostProcessor() {
+ return new EventMeshListenerBeanPostProcessor();
+ }
+
}
diff --git
a/eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/server/SpringConnectServer.java
b/eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/server/SpringConnectServer.java
index 2c79b4b46..f176200ae 100644
---
a/eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/server/SpringConnectServer.java
+++
b/eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/server/SpringConnectServer.java
@@ -23,17 +23,27 @@ import
org.apache.eventmesh.connector.spring.source.connector.SpringSourceConnec
import org.apache.eventmesh.openconnect.Application;
import org.apache.eventmesh.openconnect.util.ConfigUtil;
+import java.util.HashMap;
+import java.util.Map;
+
import org.springframework.boot.CommandLineRunner;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
public class SpringConnectServer implements CommandLineRunner {
+ private static final String SPRING_SOURCE = "springSource";
+
@Override
public void run(String... args) throws Exception {
SpringConnectServerConfig springConnectServerConfig =
ConfigUtil.parse(SpringConnectServerConfig.class,
Constants.CONNECT_SERVER_CONFIG_FILE_NAME);
if (springConnectServerConfig.isSourceEnable()) {
- Application application = new Application();
+ Map<String, String> extensions = new HashMap<>();
+ extensions.put(Application.CREATE_EXTENSION_KEY, SPRING_SOURCE);
+ Application application = new Application(extensions);
application.run(SpringSourceConnector.class);
}
}
diff --git
a/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/api/source/SourceCreateService.java
b/eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/sink/EventMeshConsumerMetadata.java
similarity index 70%
copy from
eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/api/source/SourceCreateService.java
copy to
eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/sink/EventMeshConsumerMetadata.java
index 8ffc0bb5d..1585480c8 100644
---
a/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/api/source/SourceCreateService.java
+++
b/eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/sink/EventMeshConsumerMetadata.java
@@ -15,16 +15,21 @@
* limitations under the License.
*/
-package org.apache.eventmesh.openconnect.api.source;
+package org.apache.eventmesh.connector.spring.sink;
-import org.apache.eventmesh.spi.EventMeshExtensionType;
-import org.apache.eventmesh.spi.EventMeshSPI;
+import java.lang.reflect.Method;
-/**
- * SPI interface for source connector creation.
- */
-@EventMeshSPI(eventMeshExtensionType = EventMeshExtensionType.CONNECTOR)
-public interface SourceCreateService {
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+@Data
+@AllArgsConstructor
+public class EventMeshConsumerMetadata {
+
+ private Object bean;
+
+ private Method method;
+
+ private EventMeshListener annotation;
- Source create();
}
diff --git
a/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/api/source/SourceCreateService.java
b/eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/sink/EventMeshListener.java
similarity index 60%
copy from
eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/api/source/SourceCreateService.java
copy to
eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/sink/EventMeshListener.java
index 8ffc0bb5d..e2a850a21 100644
---
a/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/api/source/SourceCreateService.java
+++
b/eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/sink/EventMeshListener.java
@@ -15,16 +15,24 @@
* limitations under the License.
*/
-package org.apache.eventmesh.openconnect.api.source;
+package org.apache.eventmesh.connector.spring.sink;
-import org.apache.eventmesh.spi.EventMeshExtensionType;
-import org.apache.eventmesh.spi.EventMeshSPI;
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
-/**
- * SPI interface for source connector creation.
- */
-@EventMeshSPI(eventMeshExtensionType = EventMeshExtensionType.CONNECTOR)
-public interface SourceCreateService {
+import org.springframework.stereotype.Component;
+
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@Component
+public @interface EventMeshListener {
- Source create();
+ /**
+ * The requestTimeout of client,it is 5s by default.
+ */
+ int requestTimeout() default 5;
}
diff --git
a/eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/sink/EventMeshListenerBeanPostProcessor.java
b/eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/sink/EventMeshListenerBeanPostProcessor.java
new file mode 100644
index 000000000..b36e30841
--- /dev/null
+++
b/eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/sink/EventMeshListenerBeanPostProcessor.java
@@ -0,0 +1,143 @@
+/*
+ * 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.spring.sink;
+
+import org.apache.eventmesh.common.Constants;
+import org.apache.eventmesh.common.ThreadPoolFactory;
+import org.apache.eventmesh.common.utils.JsonUtils;
+import org.apache.eventmesh.connector.spring.config.SpringConnectServerConfig;
+import
org.apache.eventmesh.connector.spring.sink.connector.SpringSinkConnector;
+import org.apache.eventmesh.openconnect.Application;
+import org.apache.eventmesh.openconnect.offsetmgmt.api.data.ConnectRecord;
+import org.apache.eventmesh.openconnect.util.ConfigUtil;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+import org.springframework.aop.support.AopUtils;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.config.BeanPostProcessor;
+import org.springframework.boot.CommandLineRunner;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.core.annotation.AnnotatedElementUtils;
+import org.springframework.util.ReflectionUtils;
+
+import lombok.SneakyThrows;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+public class EventMeshListenerBeanPostProcessor implements
ApplicationContextAware,
+ CommandLineRunner, BeanPostProcessor {
+
+ private static final String SPRING_SINK = "springSink";
+
+ private static final ThreadPoolExecutor executor =
ThreadPoolFactory.createThreadPoolExecutor(
+ Runtime.getRuntime().availableProcessors() * 2,
+ Runtime.getRuntime().availableProcessors() * 2,
+ "EventMesh-MessageListenerBeanPostProcessor-");
+
+ private ApplicationContext applicationContext;
+
+ private List<EventMeshConsumerMetadata> metadataList = new ArrayList<>();
+
+ @Override
+ public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
+ this.applicationContext = applicationContext;
+ }
+
+ @Override
+ public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
+ Class<?> targetClass = AopUtils.isAopProxy(bean) ?
AopUtils.getTargetClass(bean) : bean.getClass();
+ ReflectionUtils.doWithMethods(targetClass, new
ReflectionUtils.MethodCallback() {
+
+ @Override
+ public void doWith(final Method method) throws
IllegalArgumentException, IllegalAccessException {
+ EventMeshListener annotation =
AnnotatedElementUtils.findMergedAnnotation(method, EventMeshListener.class);
+ if (annotation == null || method.isBridge()) {
+ return;
+ }
+ metadataList.add(new EventMeshConsumerMetadata(bean, method,
annotation));
+ }
+ });
+ return bean;
+ }
+
+ @Override
+ public void run(String... args) throws Exception {
+ runSinkConnector();
+ metadataList.forEach(metadata -> {
+ Object bean = metadata.getBean();
+ Method method = metadata.getMethod();
+ EventMeshListener annotation = metadata.getAnnotation();
+ SpringSinkConnector sinkConnector =
applicationContext.getBean(SpringSinkConnector.class);
+ executor.execute(() -> {
+ ConnectRecord poll;
+ while (sinkConnector.isRunning()) {
+ try {
+ poll =
sinkConnector.getQueue().poll(annotation.requestTimeout(), TimeUnit.SECONDS);
+ if (null == poll || null == poll.getData()) {
+ continue;
+ }
+ String messageBody = new String((byte[])
poll.getData());
+ Type[] parameterizedTypes =
method.getGenericParameterTypes();
+ if (parameterizedTypes.length == 0) {
+ throw new IllegalStateException("There has not any
arguments for consumer method.");
+ }
+ if (parameterizedTypes.length > 1) {
+ throw new IllegalStateException("There has more
than one arguments for consumer method.");
+ }
+ Class<?> rawType;
+ if (parameterizedTypes[0] instanceof Class) {
+ rawType = (Class<?>) parameterizedTypes[0];
+ } else {
+ throw new IllegalStateException(
+ "The arguments type for consumer method can't
cast to be Class and ParameterizedTypeImpl");
+ }
+ if (rawType == String.class) {
+ metadata.getMethod().invoke(bean, messageBody);
+ } else {
+ metadata.getMethod().invoke(bean,
JsonUtils.parseObject(messageBody, parameterizedTypes[0]));
+ }
+ } catch (Exception e) {
+ log.warn("Consume snapshot event error", e);
+ }
+ }
+ });
+ });
+ }
+
+ @SneakyThrows
+ public void runSinkConnector() {
+ SpringConnectServerConfig springConnectServerConfig =
ConfigUtil.parse(SpringConnectServerConfig.class,
+ Constants.CONNECT_SERVER_CONFIG_FILE_NAME);
+
+ if (springConnectServerConfig.isSinkEnable()) {
+ Map<String, String> extensions = new HashMap<>();
+ extensions.put(Application.CREATE_EXTENSION_KEY, SPRING_SINK);
+ Application application = new Application(extensions);
+ application.run(SpringSinkConnector.class);
+ }
+ }
+}
diff --git
a/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/api/source/SourceCreateService.java
b/eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/sink/config/SpringSinkConfig.java
similarity index 66%
copy from
eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/api/source/SourceCreateService.java
copy to
eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/sink/config/SpringSinkConfig.java
index 8ffc0bb5d..aff0d8a0f 100644
---
a/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/api/source/SourceCreateService.java
+++
b/eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/sink/config/SpringSinkConfig.java
@@ -15,16 +15,17 @@
* limitations under the License.
*/
-package org.apache.eventmesh.openconnect.api.source;
+package org.apache.eventmesh.connector.spring.sink.config;
-import org.apache.eventmesh.spi.EventMeshExtensionType;
-import org.apache.eventmesh.spi.EventMeshSPI;
+import
org.apache.eventmesh.connector.spring.sink.connector.SinkConnectorConfig;
+import org.apache.eventmesh.openconnect.api.config.SinkConfig;
-/**
- * SPI interface for source connector creation.
- */
-@EventMeshSPI(eventMeshExtensionType = EventMeshExtensionType.CONNECTOR)
-public interface SourceCreateService {
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class SpringSinkConfig extends SinkConfig {
- Source create();
+ private SinkConnectorConfig sinkConnectorConfig;
}
diff --git
a/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/api/source/SourceCreateService.java
b/eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/sink/connector/SinkConnectorConfig.java
similarity index 70%
copy from
eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/api/source/SourceCreateService.java
copy to
eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/sink/connector/SinkConnectorConfig.java
index 8ffc0bb5d..a71c4ab66 100644
---
a/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/api/source/SourceCreateService.java
+++
b/eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/sink/connector/SinkConnectorConfig.java
@@ -15,16 +15,13 @@
* limitations under the License.
*/
-package org.apache.eventmesh.openconnect.api.source;
+package org.apache.eventmesh.connector.spring.sink.connector;
-import org.apache.eventmesh.spi.EventMeshExtensionType;
-import org.apache.eventmesh.spi.EventMeshSPI;
+import lombok.Data;
-/**
- * SPI interface for source connector creation.
- */
-@EventMeshSPI(eventMeshExtensionType = EventMeshExtensionType.CONNECTOR)
-public interface SourceCreateService {
+@Data
+public class SinkConnectorConfig {
+
+ private String connectorName;
- Source create();
}
diff --git
a/eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/sink/connector/SpringSinkConnector.java
b/eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/sink/connector/SpringSinkConnector.java
new file mode 100644
index 000000000..648e1f807
--- /dev/null
+++
b/eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/sink/connector/SpringSinkConnector.java
@@ -0,0 +1,106 @@
+/*
+ * 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.spring.sink.connector;
+
+import org.apache.eventmesh.connector.spring.sink.config.SpringSinkConfig;
+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.List;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * Spring sink connector
+ */
+@Slf4j
+public class SpringSinkConnector implements Sink {
+
+ private SpringSinkConfig sinkConfig;
+
+ private BlockingQueue<ConnectRecord> queue;
+
+ private volatile boolean isRunning = false;
+
+ @Override
+ public Class<? extends Config> configClass() {
+ return SpringSinkConfig.class;
+ }
+
+ @Override
+ public void init(Config config) throws Exception {
+ // init config for spring sink connector
+ this.sinkConfig = (SpringSinkConfig) config;
+ this.queue = new LinkedBlockingQueue<>(1000);
+ }
+
+ @Override
+ public void init(ConnectorContext connectorContext) throws Exception {
+ // init config for openfunction source connector
+ SinkConnectorContext sinkConnectorContext = (SinkConnectorContext)
connectorContext;
+ this.sinkConfig = (SpringSinkConfig)
sinkConnectorContext.getSinkConfig();
+ this.queue = new LinkedBlockingQueue<>(1000);
+ }
+
+ @Override
+ public void start() throws Exception {
+ isRunning = true;
+ }
+
+ @Override
+ public void commit(ConnectRecord record) {
+
+ }
+
+ @Override
+ public String name() {
+ return this.sinkConfig.getSinkConnectorConfig().getConnectorName();
+ }
+
+ @Override
+ public void stop() throws Exception {
+
+ }
+
+ public boolean isRunning() {
+ return isRunning;
+ }
+
+ public BlockingQueue<ConnectRecord> getQueue() {
+ return queue;
+ }
+
+ @Override
+ public void put(List<ConnectRecord> sinkRecords) {
+ for (ConnectRecord connectRecord : sinkRecords) {
+ try {
+ queue.put(connectRecord);
+ } catch (InterruptedException e) {
+ Thread currentThread = Thread.currentThread();
+ log.warn("[SpringSinkConnector] Interrupting thread {} due to
exception {}",
+ currentThread.getName(), e.getMessage());
+ currentThread.interrupt();
+ }
+ }
+ }
+}
diff --git
a/eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/source/connector/SpringSourceConnectorCreateServiceImpl.java
b/eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/sink/connector/SpringSinkConnectorCreateServiceImpl.java
similarity index 71%
copy from
eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/source/connector/SpringSourceConnectorCreateServiceImpl.java
copy to
eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/sink/connector/SpringSinkConnectorCreateServiceImpl.java
index 0f61caebc..e7e7b2554 100644
---
a/eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/source/connector/SpringSourceConnectorCreateServiceImpl.java
+++
b/eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/sink/connector/SpringSinkConnectorCreateServiceImpl.java
@@ -15,19 +15,19 @@
* limitations under the License.
*/
-package org.apache.eventmesh.connector.spring.source.connector;
+package org.apache.eventmesh.connector.spring.sink.connector;
import
org.apache.eventmesh.connector.spring.common.SpringApplicationContextHolder;
import org.apache.eventmesh.connector.spring.config.EventMeshAutoConfiguration;
-import org.apache.eventmesh.openconnect.api.source.Source;
-import org.apache.eventmesh.openconnect.api.source.SourceCreateService;
+import org.apache.eventmesh.openconnect.api.ConnectorCreateService;
+import org.apache.eventmesh.openconnect.api.sink.Sink;
-public class SpringSourceConnectorCreateServiceImpl implements
SourceCreateService {
+public class SpringSinkConnectorCreateServiceImpl implements
ConnectorCreateService<Sink> {
@Override
- public Source create() {
+ public Sink create() {
if (SpringApplicationContextHolder.isStarted()) {
- return (Source)
SpringApplicationContextHolder.getBean(EventMeshAutoConfiguration.SPRING_SOURCE_CONNECTOR_BEAN_NAME);
+ return (Sink)
SpringApplicationContextHolder.getBean(EventMeshAutoConfiguration.SPRING_SINK_CONNECTOR_BEAN_NAME);
}
return null;
}
diff --git
a/eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/source/connector/SpringSourceConnectorCreateServiceImpl.java
b/eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/source/connector/SpringSourceConnectorCreateServiceImpl.java
index 0f61caebc..573ff9ed7 100644
---
a/eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/source/connector/SpringSourceConnectorCreateServiceImpl.java
+++
b/eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/source/connector/SpringSourceConnectorCreateServiceImpl.java
@@ -19,10 +19,10 @@ package
org.apache.eventmesh.connector.spring.source.connector;
import
org.apache.eventmesh.connector.spring.common.SpringApplicationContextHolder;
import org.apache.eventmesh.connector.spring.config.EventMeshAutoConfiguration;
+import org.apache.eventmesh.openconnect.api.ConnectorCreateService;
import org.apache.eventmesh.openconnect.api.source.Source;
-import org.apache.eventmesh.openconnect.api.source.SourceCreateService;
-public class SpringSourceConnectorCreateServiceImpl implements
SourceCreateService {
+public class SpringSourceConnectorCreateServiceImpl implements
ConnectorCreateService<Source> {
@Override
public Source create() {
diff --git
a/eventmesh-connectors/eventmesh-connector-spring/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.openconnect.api.source.SourceCreateService
b/eventmesh-connectors/eventmesh-connector-spring/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.openconnect.api.ConnectorCreateService
similarity index 79%
rename from
eventmesh-connectors/eventmesh-connector-spring/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.openconnect.api.source.SourceCreateService
rename to
eventmesh-connectors/eventmesh-connector-spring/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.openconnect.api.ConnectorCreateService
index b79216363..1daf7796f 100644
---
a/eventmesh-connectors/eventmesh-connector-spring/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.openconnect.api.source.SourceCreateService
+++
b/eventmesh-connectors/eventmesh-connector-spring/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.openconnect.api.ConnectorCreateService
@@ -15,4 +15,5 @@
# limitations under the License.
#
-spring=org.apache.eventmesh.connector.spring.source.connector.SpringSourceConnectorCreateServiceImpl
\ No newline at end of file
+springSink=org.apache.eventmesh.connector.spring.sink.connector.SpringSinkConnectorCreateServiceImpl
+springSource=org.apache.eventmesh.connector.spring.source.connector.SpringSourceConnectorCreateServiceImpl
\ No newline at end of file
diff --git
a/eventmesh-connectors/eventmesh-connector-spring/src/main/resources/source-config.yml
b/eventmesh-connectors/eventmesh-connector-spring/src/main/resources/sink-config.yml
similarity index 89%
copy from
eventmesh-connectors/eventmesh-connector-spring/src/main/resources/source-config.yml
copy to
eventmesh-connectors/eventmesh-connector-spring/src/main/resources/sink-config.yml
index a0de4f218..dd5c081af 100644
---
a/eventmesh-connectors/eventmesh-connector-spring/src/main/resources/source-config.yml
+++
b/eventmesh-connectors/eventmesh-connector-spring/src/main/resources/sink-config.yml
@@ -20,10 +20,9 @@ pubSubConfig:
subject: TEST-TOPIC-SPRING
idc: FT
env: PRD
- group: springSource
+ group: springSink
appId: 5033
- userName: springSourceUser
+ userName: springSinkUser
passWord: springPassWord
connectorConfig:
- connectorName: springSource
- topic: SourceTopic
+ connectorName: springSink
\ No newline at end of file
diff --git
a/eventmesh-connectors/eventmesh-connector-spring/src/main/resources/source-config.yml
b/eventmesh-connectors/eventmesh-connector-spring/src/main/resources/source-config.yml
index a0de4f218..4559cd670 100644
---
a/eventmesh-connectors/eventmesh-connector-spring/src/main/resources/source-config.yml
+++
b/eventmesh-connectors/eventmesh-connector-spring/src/main/resources/source-config.yml
@@ -26,4 +26,3 @@ pubSubConfig:
passWord: springPassWord
connectorConfig:
connectorName: springSource
- topic: SourceTopic
diff --git
a/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/Application.java
b/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/Application.java
index 740bd1226..3252a52e3 100644
---
a/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/Application.java
+++
b/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/Application.java
@@ -17,16 +17,18 @@
package org.apache.eventmesh.openconnect;
+import org.apache.eventmesh.openconnect.api.ConnectorCreateService;
import org.apache.eventmesh.openconnect.api.config.Config;
import org.apache.eventmesh.openconnect.api.config.SinkConfig;
import org.apache.eventmesh.openconnect.api.config.SourceConfig;
import org.apache.eventmesh.openconnect.api.connector.Connector;
import org.apache.eventmesh.openconnect.api.sink.Sink;
import org.apache.eventmesh.openconnect.api.source.Source;
-import org.apache.eventmesh.openconnect.api.source.SourceCreateService;
import org.apache.eventmesh.openconnect.util.ConfigUtil;
import org.apache.eventmesh.spi.EventMeshExtensionFactory;
+import org.apache.commons.collections4.MapUtils;
+
import java.util.HashMap;
import java.util.Map;
@@ -37,16 +39,29 @@ public class Application {
public static final Map<String, Connector> CONNECTOR_MAP = new HashMap<>();
- private static final String SPRING = "spring";
+ public static final String CREATE_EXTENSION_KEY = "createExtension";
+
+ private Map<String, String> extensions;
+
+ public Application() {
+
+ }
+
+ public Application(Map<String, String> extensions) {
+ this.extensions = extensions;
+ }
public void run(Class<? extends Connector> clazz) throws Exception {
Connector connector = null;
try {
- SourceCreateService createService =
-
EventMeshExtensionFactory.getExtension(SourceCreateService.class, SPRING);
- if (createService != null) {
- connector = createService.create();
+ if (MapUtils.isNotEmpty(extensions) &&
extensions.containsKey(CREATE_EXTENSION_KEY)) {
+ String spiKey = extensions.get(CREATE_EXTENSION_KEY);
+ ConnectorCreateService<?> createService =
+
EventMeshExtensionFactory.getExtension(ConnectorCreateService.class, spiKey);
+ if (createService != null) {
+ connector = createService.create();
+ }
}
if (connector == null) {
connector = clazz.getDeclaredConstructor().newInstance();
diff --git
a/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/api/source/SourceCreateService.java
b/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/api/ConnectorCreateService.java
similarity index 81%
rename from
eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/api/source/SourceCreateService.java
rename to
eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/api/ConnectorCreateService.java
index 8ffc0bb5d..15e645474 100644
---
a/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/api/source/SourceCreateService.java
+++
b/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/api/ConnectorCreateService.java
@@ -15,16 +15,17 @@
* limitations under the License.
*/
-package org.apache.eventmesh.openconnect.api.source;
+package org.apache.eventmesh.openconnect.api;
+import org.apache.eventmesh.openconnect.api.connector.Connector;
import org.apache.eventmesh.spi.EventMeshExtensionType;
import org.apache.eventmesh.spi.EventMeshSPI;
/**
- * SPI interface for source connector creation.
+ * SPI interface for connector creation.
*/
@EventMeshSPI(eventMeshExtensionType = EventMeshExtensionType.CONNECTOR)
-public interface SourceCreateService {
+public interface ConnectorCreateService<T extends Connector> {
- Source create();
+ T create();
}
diff --git
a/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/demo/CCSubClient.java
b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/demo/CCSubClient.java
index e16108a7b..e7cba1d22 100644
---
a/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/demo/CCSubClient.java
+++
b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/demo/CCSubClient.java
@@ -25,7 +25,6 @@ import
org.apache.eventmesh.runtime.client.common.MessageUtils;
import org.apache.eventmesh.runtime.client.common.UserAgentUtils;
import org.apache.eventmesh.runtime.client.impl.SubClientImpl;
-
import lombok.extern.slf4j.Slf4j;
@Slf4j
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]