This is an automated email from the ASF dual-hosted git repository.
chenguangsheng 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 3bf4d693e [ISSUE #3553] Add eventmesh-storage-knative module
new 10485b8d6 Merge pull request #3554 from xwm1992/add-storage-knative
3bf4d693e is described below
commit 3bf4d693eb97787f6707f396125c047e5da4e3fe
Author: xwm1992 <[email protected]>
AuthorDate: Wed Mar 29 17:13:03 2023 +0800
[ISSUE #3553] Add eventmesh-storage-knative module
---
.../eventmesh-storage-knative/build.gradle | 40 +++++
.../eventmesh-storage-knative/gradle.properties | 18 +++
.../knative/cloudevent/KnativeMessageFactory.java | 47 ++++++
.../impl/KnativeBinaryMessageReader.java | 57 +++++++
.../knative/cloudevent/impl/KnativeHeaders.java | 31 ++++
.../cloudevent/impl/KnativeMessageWriter.java | 80 ++++++++++
.../knative/config/ClientConfiguration.java | 51 ++++++
.../StorageResourceServiceKnativeImpl.java | 32 ++++
.../storage/knative/consumer/DefaultConsumer.java | 75 +++++++++
.../knative/consumer/KnativeConsumerImpl.java | 105 ++++++++++++
.../storage/knative/consumer/PullConsumerImpl.java | 177 +++++++++++++++++++++
.../storage/knative/domain/NonStandardKeys.java | 27 ++++
.../patch/EventMeshConsumeConcurrentlyContext.java | 30 ++++
.../patch/EventMeshConsumeConcurrentlyStatus.java | 33 ++++
.../EventMeshMessageListenerConcurrently.java | 24 +++
.../storage/knative/producer/AbstractProducer.java | 67 ++++++++
.../knative/producer/KnativeProducerImpl.java | 101 ++++++++++++
.../storage/knative/producer/ProducerImpl.java | 128 +++++++++++++++
.../storage/knative/utils/CloudEventUtils.java | 33 ++++
.../org.apache.eventmesh.api.consumer.Consumer | 16 ++
.../org.apache.eventmesh.api.producer.Producer | 16 ++
...he.eventmesh.api.storage.StorageResourceService | 16 ++
.../src/main/resources/knative-client.properties | 18 +++
.../knative/config/ClientConfigurationTest.java | 51 ++++++
.../knative/consumer/KnativeConsumerImplTest.java | 48 ++++++
.../knative/producer/KnativeProducerImplTest.java | 66 ++++++++
.../src/test/resources/knative-client.properties | 18 +++
settings.gradle | 1 +
28 files changed, 1406 insertions(+)
diff --git a/eventmesh-storage-plugin/eventmesh-storage-knative/build.gradle
b/eventmesh-storage-plugin/eventmesh-storage-knative/build.gradle
new file mode 100644
index 000000000..7bdfac7e7
--- /dev/null
+++ b/eventmesh-storage-plugin/eventmesh-storage-knative/build.gradle
@@ -0,0 +1,40 @@
+/*
+ * 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 'org.asynchttpclient:async-http-client'
+
+ implementation project(":eventmesh-sdk-java")
+ testImplementation project(":eventmesh-sdk-java")
+
+ implementation project(":eventmesh-runtime")
+ testImplementation project(":eventmesh-runtime")
+
+ implementation project(":eventmesh-common")
+ testImplementation project(":eventmesh-common")
+
+ implementation project(":eventmesh-storage-plugin:eventmesh-storage-api")
+ testImplementation
project(":eventmesh-storage-plugin:eventmesh-storage-api")
+
+ testImplementation "org.powermock:powermock-module-junit4"
+
+ compileOnly 'org.projectlombok:lombok:1.18.22'
+ annotationProcessor 'org.projectlombok:lombok:1.18.22'
+
+ testCompileOnly 'org.projectlombok:lombok:1.18.22'
+ testAnnotationProcessor 'org.projectlombok:lombok:1.18.22'
+}
diff --git
a/eventmesh-storage-plugin/eventmesh-storage-knative/gradle.properties
b/eventmesh-storage-plugin/eventmesh-storage-knative/gradle.properties
new file mode 100644
index 000000000..8ba4f21ce
--- /dev/null
+++ b/eventmesh-storage-plugin/eventmesh-storage-knative/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.
+#
+knative_version=1.5
+pluginType=storage
+pluginName=knative
\ No newline at end of file
diff --git
a/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/cloudevent/KnativeMessageFactory.java
b/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/cloudevent/KnativeMessageFactory.java
new file mode 100644
index 000000000..91ed60778
--- /dev/null
+++
b/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/cloudevent/KnativeMessageFactory.java
@@ -0,0 +1,47 @@
+/*
+ * 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.storage.knative.cloudevent;
+
+import
org.apache.eventmesh.storage.knative.cloudevent.impl.KnativeMessageWriter;
+
+import java.nio.charset.StandardCharsets;
+import java.util.Properties;
+
+import io.cloudevents.CloudEvent;
+
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+public final class KnativeMessageFactory {
+
+ private KnativeMessageFactory() {
+ // prevent instantiation
+ }
+
+ public static String createReader(final CloudEvent message) {
+ if (message.getData() == null) {
+ log.warn("CloudEvent message's data is null.");
+ return "";
+ }
+ return new String(message.getData().toBytes(), StandardCharsets.UTF_8);
+ }
+
+ public static KnativeMessageWriter createWriter(final Properties
properties) {
+ return new KnativeMessageWriter(properties);
+ }
+}
diff --git
a/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/cloudevent/impl/KnativeBinaryMessageReader.java
b/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/cloudevent/impl/KnativeBinaryMessageReader.java
new file mode 100644
index 000000000..8a3060cab
--- /dev/null
+++
b/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/cloudevent/impl/KnativeBinaryMessageReader.java
@@ -0,0 +1,57 @@
+/*
+ * 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.storage.knative.cloudevent.impl;
+
+import java.util.Locale;
+import java.util.function.BiConsumer;
+
+import io.cloudevents.SpecVersion;
+import io.cloudevents.core.data.BytesCloudEventData;
+import io.cloudevents.core.message.impl.BaseGenericBinaryMessageReaderImpl;
+
+public class KnativeBinaryMessageReader extends
BaseGenericBinaryMessageReaderImpl<String, String> {
+
+ protected KnativeBinaryMessageReader(SpecVersion version, byte[] body) {
+ super(version, body != null && body.length > 0 ?
BytesCloudEventData.wrap(body) : (BytesCloudEventData) null);
+ }
+
+ @Override
+ protected boolean isContentTypeHeader(String key) {
+ return KnativeHeaders.CONTENT_TYPE.equals(key);
+ }
+
+ @Override
+ protected boolean isCloudEventsHeader(String key) {
+ return true;
+ }
+
+ @Override
+ protected String toCloudEventsKey(String key) {
+ return key.toLowerCase(Locale.getDefault());
+ }
+
+ @Override
+ protected void forEachHeader(BiConsumer<String, String> fn) {
+
+ }
+
+ @Override
+ protected String toCloudEventsValue(String value) {
+ return value;
+ }
+}
diff --git
a/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/cloudevent/impl/KnativeHeaders.java
b/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/cloudevent/impl/KnativeHeaders.java
new file mode 100644
index 000000000..1f998a4b2
--- /dev/null
+++
b/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/cloudevent/impl/KnativeHeaders.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.storage.knative.cloudevent.impl;
+
+public class KnativeHeaders {
+
+ public static final String CONTENT_TYPE = "Content-Type";
+
+ public static final String CE_ID = "Ce-Id";
+
+ public static final String CE_SPECVERSION = "Ce-Specversion";
+
+ public static final String CE_TYPE = "Ce-Type";
+
+ public static final String CE_SOURCE = "Ce-Source";
+}
diff --git
a/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/cloudevent/impl/KnativeMessageWriter.java
b/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/cloudevent/impl/KnativeMessageWriter.java
new file mode 100644
index 000000000..5c8df1b5f
--- /dev/null
+++
b/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/cloudevent/impl/KnativeMessageWriter.java
@@ -0,0 +1,80 @@
+/*
+ * 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.storage.knative.cloudevent.impl;
+
+import java.net.URI;
+import java.nio.charset.StandardCharsets;
+import java.util.Properties;
+
+import io.cloudevents.CloudEvent;
+import io.cloudevents.CloudEventData;
+import io.cloudevents.SpecVersion;
+import io.cloudevents.core.format.EventFormat;
+import io.cloudevents.core.message.MessageWriter;
+import io.cloudevents.core.v1.CloudEventBuilder;
+import io.cloudevents.rw.CloudEventContextWriter;
+import io.cloudevents.rw.CloudEventRWException;
+import io.cloudevents.rw.CloudEventWriter;
+
+public class KnativeMessageWriter implements
MessageWriter<CloudEventWriter<String>, String>, CloudEventWriter<String> {
+
+ private transient CloudEvent message;
+
+ public CloudEvent getMessage() {
+ return this.message;
+ }
+
+ public KnativeMessageWriter(Properties properties) {
+ String s = "{ \"msg\": [\"" + properties.get("data") + "\"]}";
+ this.message = new CloudEventBuilder()
+ .withId(properties.getProperty(KnativeHeaders.CE_ID))
+
.withSource(URI.create(properties.getProperty(KnativeHeaders.CE_SOURCE)))
+ .withType(properties.getProperty(KnativeHeaders.CE_TYPE))
+
.withDataContentType(properties.getProperty(KnativeHeaders.CONTENT_TYPE))
+ .withData(s.getBytes(StandardCharsets.UTF_8))
+ .build();
+ }
+
+ @Override
+ public String end(CloudEventData data) throws CloudEventRWException {
+ return data.toString();
+ }
+
+ @Override
+ public String end() throws CloudEventRWException {
+ if (message != null && message.getData() != null) {
+ return message.getData().toString();
+ }
+ throw CloudEventRWException.newOther(new
IllegalArgumentException("message data is null"));
+ }
+
+ @Override
+ public CloudEventContextWriter withContextAttribute(String name, String
value) throws CloudEventRWException {
+ return null;
+ }
+
+ @Override
+ public String setEvent(EventFormat format, byte[] value) throws
CloudEventRWException {
+ return null;
+ }
+
+ @Override
+ public CloudEventWriter<String> create(SpecVersion version) throws
CloudEventRWException {
+ return null;
+ }
+}
diff --git
a/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/config/ClientConfiguration.java
b/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/config/ClientConfiguration.java
new file mode 100644
index 000000000..5c0630470
--- /dev/null
+++
b/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/config/ClientConfiguration.java
@@ -0,0 +1,51 @@
+/*
+ * 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.storage.knative.config;
+
+import org.apache.eventmesh.common.config.Config;
+import org.apache.eventmesh.common.config.ConfigFiled;
+import
org.apache.eventmesh.common.config.convert.converter.ListConverter.ListConverterSemi;
+
+import java.util.List;
+
+import lombok.Data;
+
+@Data
+@Config(prefix = "eventMesh.server.knative", path =
"classPath://knative-client.properties")
+public class ClientConfiguration {
+
+ @ConfigFiled(field = "service", converter = ListConverterSemi.class)
+ public List<String> service;
+
+ /**
+ * In keeping with the old way of configuration parsing, the value is
taken from the service field [0]
+ */
+ @ConfigFiled(reload = true)
+ public String emurl = "";
+
+ /**
+ * In keeping with the old way of configuration parsing, the value is
taken from the service field [1]
+ */
+ @ConfigFiled(reload = true)
+ public String serviceAddr = "";
+
+ public void reload() {
+ emurl = this.service.get(0);
+ serviceAddr = this.service.get(1);
+ }
+}
diff --git
a/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/connector/StorageResourceServiceKnativeImpl.java
b/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/connector/StorageResourceServiceKnativeImpl.java
new file mode 100644
index 000000000..9fd46e8b6
--- /dev/null
+++
b/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/connector/StorageResourceServiceKnativeImpl.java
@@ -0,0 +1,32 @@
+/*
+ * 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.storage.knative.connector;
+
+import org.apache.eventmesh.api.storage.StorageResourceService;
+
+public class StorageResourceServiceKnativeImpl implements
StorageResourceService {
+ @Override
+ public void init() throws Exception {
+
+ }
+
+ @Override
+ public void release() throws Exception {
+
+ }
+}
diff --git
a/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/consumer/DefaultConsumer.java
b/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/consumer/DefaultConsumer.java
new file mode 100644
index 000000000..2130ed852
--- /dev/null
+++
b/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/consumer/DefaultConsumer.java
@@ -0,0 +1,75 @@
+/*
+ * 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.storage.knative.consumer;
+
+import static org.asynchttpclient.Dsl.asyncHttpClient;
+
+import
org.apache.eventmesh.storage.knative.patch.EventMeshMessageListenerConcurrently;
+
+import java.util.concurrent.TimeUnit;
+
+import org.asynchttpclient.AsyncHttpClient;
+import org.asynchttpclient.ListenableFuture;
+import org.asynchttpclient.Response;
+import org.asynchttpclient.util.HttpConstants;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Preconditions;
+
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+public class DefaultConsumer {
+
+ private static final Logger LOG =
LoggerFactory.getLogger(DefaultConsumer.class);
+
+ private transient AsyncHttpClient asyncHttpClient;
+
+
+ private transient EventMeshMessageListenerConcurrently messageListener;
+
+ public EventMeshMessageListenerConcurrently getMessageListener() {
+ return messageListener;
+ }
+
+ public DefaultConsumer() throws Exception {
+ this.asyncHttpClient = asyncHttpClient();
+ }
+
+ public String pullMessage(String topic, String subscribeUrl) throws
Exception {
+ Preconditions.checkNotNull(topic, "Subscribe item cannot be null");
+ Preconditions.checkNotNull(subscribeUrl, "SubscribeUrl cannot be
null");
+
+ // Get event message via HTTP:
+ String responseBody;
+ ListenableFuture<Response> execute =
asyncHttpClient.prepareGet("http://" + subscribeUrl + "/" + topic).execute();
+ Response response = execute.get(10, TimeUnit.SECONDS);
+
+ if (response.getStatusCode() ==
HttpConstants.ResponseStatusCodes.OK_200) {
+ responseBody = response.getResponseBody();
+ LOG.info(responseBody);
+ return responseBody;
+ }
+ throw new IllegalStateException("HTTP response code error: " +
response.getStatusCode());
+ }
+
+ public void registerMessageListener(EventMeshMessageListenerConcurrently
messageListener) {
+ this.messageListener = messageListener;
+ }
+}
diff --git
a/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/consumer/KnativeConsumerImpl.java
b/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/consumer/KnativeConsumerImpl.java
new file mode 100644
index 000000000..4b820d95f
--- /dev/null
+++
b/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/consumer/KnativeConsumerImpl.java
@@ -0,0 +1,105 @@
+/*
+ * 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.storage.knative.consumer;
+
+import org.apache.eventmesh.api.AbstractContext;
+import org.apache.eventmesh.api.EventListener;
+import org.apache.eventmesh.api.consumer.Consumer;
+import org.apache.eventmesh.common.config.Config;
+import org.apache.eventmesh.storage.knative.config.ClientConfiguration;
+
+import java.util.List;
+import java.util.Properties;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import io.cloudevents.CloudEvent;
+
+@Config(field = "clientConfiguration")
+public class KnativeConsumerImpl implements Consumer {
+
+ private static final Logger LOG =
LoggerFactory.getLogger(KnativeConsumerImpl.class);
+
+ private transient PullConsumerImpl pullConsumer;
+
+
+ /**
+ * Unified configuration class corresponding to knative-client.properties
+ */
+ private ClientConfiguration clientConfiguration;
+
+ private static final Logger logger =
LoggerFactory.getLogger(KnativeConsumerImpl.class);
+
+ @Override
+ public synchronized void init(Properties properties) throws Exception {
+ // Load parameters from properties file:
+ properties.put("emUrl", clientConfiguration.getEmurl());
+ properties.put("serviceAddr", clientConfiguration.getServiceAddr());
+
+ pullConsumer = new PullConsumerImpl(properties);
+ }
+
+ @Override
+ public void subscribe(String topic) {
+ pullConsumer.subscribe(topic);
+ }
+
+ @Override
+ public void unsubscribe(String topic) {
+ try {
+ pullConsumer.unsubscribe(topic);
+ } catch (Exception e) {
+ LOG.error("unsubscribe error", e);
+ }
+ }
+
+ @Override
+ public void registerEventListener(EventListener listener) {
+ pullConsumer.registerEventListener(listener);
+ }
+
+ @Override
+ public void updateOffset(List<CloudEvent> cloudEvents, AbstractContext
context) {
+ pullConsumer.updateOffset(cloudEvents, context);
+ }
+
+ @Override
+ public boolean isStarted() {
+ return pullConsumer.isStarted();
+ }
+
+ @Override
+ public boolean isClosed() {
+ return pullConsumer.isClosed();
+ }
+
+ @Override
+ public void start() {
+ pullConsumer.start();
+ }
+
+ @Override
+ public void shutdown() {
+ pullConsumer.shutdown();
+ }
+
+ public ClientConfiguration getClientConfiguration() {
+ return this.clientConfiguration;
+ }
+}
diff --git
a/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/consumer/PullConsumerImpl.java
b/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/consumer/PullConsumerImpl.java
new file mode 100644
index 000000000..c3378d05f
--- /dev/null
+++
b/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/consumer/PullConsumerImpl.java
@@ -0,0 +1,177 @@
+/*
+ * 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.storage.knative.consumer;
+
+import org.apache.eventmesh.api.AbstractContext;
+import org.apache.eventmesh.api.EventListener;
+import org.apache.eventmesh.api.EventMeshAction;
+import org.apache.eventmesh.api.EventMeshAsyncConsumeContext;
+import org.apache.eventmesh.common.protocol.SubscriptionItem;
+import org.apache.eventmesh.common.protocol.SubscriptionMode;
+import org.apache.eventmesh.common.protocol.SubscriptionType;
+import org.apache.eventmesh.storage.knative.domain.NonStandardKeys;
+import
org.apache.eventmesh.storage.knative.patch.EventMeshConsumeConcurrentlyContext;
+import
org.apache.eventmesh.storage.knative.patch.EventMeshConsumeConcurrentlyStatus;
+import
org.apache.eventmesh.storage.knative.patch.EventMeshMessageListenerConcurrently;
+
+import java.util.List;
+import java.util.Properties;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicLong;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import io.cloudevents.CloudEvent;
+
+import com.google.common.collect.Lists;
+
+public class PullConsumerImpl {
+
+ private static final Logger LOG =
LoggerFactory.getLogger(PullConsumerImpl.class);
+
+ private final transient DefaultConsumer defaultConsumer;
+
+ // Topics to subscribe:
+ private transient List<SubscriptionItem> topicList = null;
+ private final transient ConcurrentHashMap<String, AtomicLong> offsetMap;
+ private final transient AtomicBoolean started = new AtomicBoolean(false);
+ private final transient Properties properties;
+
+ // Store received message:
+ private transient ConcurrentMap<String /* topic */, String /* responseBody
*/> subscriptionInner;
+ private transient EventListener eventListener;
+
+
+
+ public PullConsumerImpl(final Properties properties) throws Exception {
+ this.properties = properties;
+ this.topicList = Lists.newArrayList();
+ this.subscriptionInner = new ConcurrentHashMap<String, String>();
+ this.offsetMap = new ConcurrentHashMap<>();
+ defaultConsumer = new DefaultConsumer();
+
+ // Register listener:
+ defaultConsumer.registerMessageListener(new
ClusteringMessageListener());
+ }
+
+ public void subscribe(String topic) {
+ // Subscribe topics:
+ try {
+ // Add topic to topicList:
+ topicList.add(new SubscriptionItem(topic,
SubscriptionMode.CLUSTERING, SubscriptionType.ASYNC));
+ // Pull event messages iteratively:
+ topicList.forEach(
+ item -> {
+ try {
+ subscriptionInner.put(item.getTopic(),
+
defaultConsumer.pullMessage(item.getTopic(),
properties.getProperty("serviceAddr")));
+ } catch (Exception e) {
+ LOG.error("store received message error", e);
+ }
+ }
+ );
+ } catch (Exception e) {
+ LOG.error("other error", e);
+ }
+ }
+
+ public void unsubscribe(String topic) {
+ try {
+ // Unsubscribe topic:
+ topicList.remove(topic);
+ } catch (Exception e) {
+ LOG.error("unsubscribe topic error", e);
+ }
+ }
+
+ // todo: offset
+ public void updateOffset(List<CloudEvent> cloudEvents, AbstractContext
context) {
+ cloudEvents.forEach(cloudEvent -> this.updateOffset(
+ cloudEvent.getSubject(), (Long)
cloudEvent.getExtension("offset"))
+ );
+ }
+
+ public void updateOffset(String topicMetadata, Long offset) {
+ offsetMap.computeIfPresent(topicMetadata, (k, v) -> {
+ v.set(offset);
+ return v;
+ });
+ }
+
+ public void start() {
+ this.started.set(true);
+ }
+
+ public synchronized void shutdown() {
+ this.started.set(false);
+ }
+
+ public boolean isStarted() {
+ return this.started.get();
+ }
+
+ public boolean isClosed() {
+ return !this.isStarted();
+ }
+
+ public void registerEventListener(EventListener listener) {
+ this.eventListener = listener;
+ }
+
+ // todo: load balancer cluser and broadcast
+ private class ClusteringMessageListener extends
EventMeshMessageListenerConcurrently {
+ @Override
+ public EventMeshConsumeConcurrentlyStatus handleMessage(CloudEvent
cloudEvent, EventMeshConsumeConcurrentlyContext context) {
+ final Properties contextProperties = new Properties();
+ contextProperties.put(NonStandardKeys.MESSAGE_CONSUME_STATUS,
EventMeshConsumeConcurrentlyStatus.RECONSUME_LATER.name());
+
+ EventMeshAsyncConsumeContext eventMeshAsyncConsumeContext = new
EventMeshAsyncConsumeContext() {
+ @Override
+ public void commit(EventMeshAction action) {
+ switch (action) {
+ case CommitMessage:
+
contextProperties.put(NonStandardKeys.MESSAGE_CONSUME_STATUS,
+
EventMeshConsumeConcurrentlyStatus.CONSUME_SUCCESS.name());
+ break;
+ case ReconsumeLater:
+
contextProperties.put(NonStandardKeys.MESSAGE_CONSUME_STATUS,
+
EventMeshConsumeConcurrentlyStatus.RECONSUME_LATER.name());
+ break;
+ case ManualAck:
+
contextProperties.put(NonStandardKeys.MESSAGE_CONSUME_STATUS,
+
EventMeshConsumeConcurrentlyStatus.CONSUME_FINISH.name());
+ break;
+ default:
+ break;
+ }
+ }
+ };
+
+ eventMeshAsyncConsumeContext.setAbstractContext((AbstractContext)
context);
+
+ // Consume received message:
+ eventListener.consume(cloudEvent, eventMeshAsyncConsumeContext);
+
+ return EventMeshConsumeConcurrentlyStatus.valueOf(
+
contextProperties.getProperty(NonStandardKeys.MESSAGE_CONSUME_STATUS));
+ }
+ }
+}
diff --git
a/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/domain/NonStandardKeys.java
b/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/domain/NonStandardKeys.java
new file mode 100644
index 000000000..7c829afb2
--- /dev/null
+++
b/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/domain/NonStandardKeys.java
@@ -0,0 +1,27 @@
+/*
+ * 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.storage.knative.domain;
+
+/**
+ * NonStandardKeys
+ */
+public class NonStandardKeys {
+
+ public static final String MESSAGE_CONSUME_STATUS =
"em.message.consume.status";
+
+}
\ No newline at end of file
diff --git
a/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/patch/EventMeshConsumeConcurrentlyContext.java
b/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/patch/EventMeshConsumeConcurrentlyContext.java
new file mode 100644
index 000000000..0c0fb9b12
--- /dev/null
+++
b/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/patch/EventMeshConsumeConcurrentlyContext.java
@@ -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.
+ */
+
+package org.apache.eventmesh.storage.knative.patch;
+
+public class EventMeshConsumeConcurrentlyContext {
+ private boolean manualAck = true;
+
+ public boolean isManualAck() {
+ return manualAck;
+ }
+
+ public void setManualAck(boolean manualAck) {
+ this.manualAck = manualAck;
+ }
+}
diff --git
a/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/patch/EventMeshConsumeConcurrentlyStatus.java
b/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/patch/EventMeshConsumeConcurrentlyStatus.java
new file mode 100644
index 000000000..3a2e2f30e
--- /dev/null
+++
b/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/patch/EventMeshConsumeConcurrentlyStatus.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.storage.knative.patch;
+
+public enum EventMeshConsumeConcurrentlyStatus {
+ /**
+ * Success consumption
+ */
+ CONSUME_SUCCESS,
+ /**
+ * Failure consumption,later try to consume
+ */
+ RECONSUME_LATER,
+ /**
+ * Success consumption but ack later manually
+ */
+ CONSUME_FINISH
+}
diff --git
a/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/patch/EventMeshMessageListenerConcurrently.java
b/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/patch/EventMeshMessageListenerConcurrently.java
new file mode 100644
index 000000000..6a0512fe3
--- /dev/null
+++
b/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/patch/EventMeshMessageListenerConcurrently.java
@@ -0,0 +1,24 @@
+/*
+ * 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.storage.knative.patch;
+
+import io.cloudevents.CloudEvent;
+
+public abstract class EventMeshMessageListenerConcurrently {
+ public abstract EventMeshConsumeConcurrentlyStatus
handleMessage(CloudEvent cloudEvent, EventMeshConsumeConcurrentlyContext
context);
+}
diff --git
a/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/producer/AbstractProducer.java
b/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/producer/AbstractProducer.java
new file mode 100644
index 000000000..0ef390dcf
--- /dev/null
+++
b/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/producer/AbstractProducer.java
@@ -0,0 +1,67 @@
+/*
+ * 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.storage.knative.producer;
+
+import static org.asynchttpclient.Dsl.asyncHttpClient;
+
+import org.apache.eventmesh.api.exception.StorageRuntimeException;
+import org.apache.eventmesh.api.producer.Producer;
+
+import java.util.Properties;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.asynchttpclient.AsyncHttpClient;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import io.cloudevents.CloudEvent;
+
+public abstract class AbstractProducer implements Producer {
+
+ protected static final Logger LOG =
LoggerFactory.getLogger(AbstractProducer.class);
+
+ protected final transient AtomicBoolean started = new AtomicBoolean(false);
+ protected final transient Properties properties;
+ private transient AsyncHttpClient asyncHttpClient;
+
+ AbstractProducer(final Properties properties) {
+ this.properties = properties;
+ this.asyncHttpClient = asyncHttpClient();
+ }
+
+ StorageRuntimeException checkProducerException(CloudEvent cloudEvent,
Throwable e) {
+ if (cloudEvent.getData() == null) {
+ return new StorageRuntimeException(String.format("CloudEvent
message data does not exist.", e));
+ }
+ return new StorageRuntimeException(String.format("Unknown connector
runtime exception.", e));
+ }
+
+ @Override
+ public boolean isStarted() {
+ return started.get();
+ }
+
+ @Override
+ public boolean isClosed() {
+ return !this.isStarted();
+ }
+
+ public AsyncHttpClient getAsyncHttpClient() {
+ return asyncHttpClient;
+ }
+}
diff --git
a/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/producer/KnativeProducerImpl.java
b/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/producer/KnativeProducerImpl.java
new file mode 100644
index 000000000..7817436e2
--- /dev/null
+++
b/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/producer/KnativeProducerImpl.java
@@ -0,0 +1,101 @@
+/*
+ * 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.storage.knative.producer;
+
+import org.apache.eventmesh.api.RequestReplyCallback;
+import org.apache.eventmesh.api.SendCallback;
+import org.apache.eventmesh.api.exception.StorageRuntimeException;
+import org.apache.eventmesh.api.producer.Producer;
+import org.apache.eventmesh.common.config.Config;
+import org.apache.eventmesh.storage.knative.config.ClientConfiguration;
+
+import java.util.Properties;
+
+import io.cloudevents.CloudEvent;
+
+@Config(field = "clientConfiguration")
+public class KnativeProducerImpl implements Producer {
+
+ private transient ProducerImpl producer;
+
+ /**
+ * Unified configuration class corresponding to knative-client.properties
+ */
+ private ClientConfiguration clientConfiguration;
+
+ @Override
+ public synchronized void init(Properties properties) throws Exception {
+ // Load parameters from properties file:
+ properties.put("url", clientConfiguration.getServiceAddr());
+ producer = new ProducerImpl(properties);
+ }
+
+ @Override
+ public void publish(CloudEvent cloudEvent, SendCallback sendCallback)
throws Exception {
+ producer.sendAsync(cloudEvent, sendCallback);
+ }
+
+ @Override
+ public boolean isStarted() {
+ return producer.isStarted();
+ }
+
+ @Override
+ public boolean isClosed() {
+ return producer.isClosed();
+ }
+
+ @Override
+ public void start() {
+ throw new StorageRuntimeException("Start is not supported");
+ }
+
+ @Override
+ public void shutdown() {
+ throw new StorageRuntimeException("Shutdown is not supported");
+ }
+
+ @Override
+ public void sendOneway(CloudEvent cloudEvent) {
+ throw new StorageRuntimeException("SendOneWay is not supported");
+ }
+
+ @Override
+ public void request(CloudEvent cloudEvent, RequestReplyCallback
rrCallback, long timeout) throws Exception {
+ throw new StorageRuntimeException("Request is not supported");
+ }
+
+ @Override
+ public boolean reply(CloudEvent cloudEvent, SendCallback sendCallback)
throws Exception {
+ throw new StorageRuntimeException("Reply is not supported");
+ }
+
+ @Override
+ public void checkTopicExist(String topic) throws Exception {
+ throw new StorageRuntimeException("CheckTopicExist is not supported");
+ }
+
+ @Override
+ public void setExtFields() {
+ throw new StorageRuntimeException("SetExtFields is not supported");
+ }
+
+ public ClientConfiguration getClientConfiguration() {
+ return this.clientConfiguration;
+ }
+}
diff --git
a/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/producer/ProducerImpl.java
b/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/producer/ProducerImpl.java
new file mode 100644
index 000000000..fce4bf67a
--- /dev/null
+++
b/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/producer/ProducerImpl.java
@@ -0,0 +1,128 @@
+/*
+ * 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.storage.knative.producer;
+
+import org.apache.eventmesh.api.RequestReplyCallback;
+import org.apache.eventmesh.api.SendCallback;
+import org.apache.eventmesh.api.exception.StorageRuntimeException;
+import org.apache.eventmesh.api.exception.OnExceptionContext;
+import org.apache.eventmesh.storage.knative.cloudevent.KnativeMessageFactory;
+import org.apache.eventmesh.storage.knative.cloudevent.impl.KnativeHeaders;
+import org.apache.eventmesh.storage.knative.utils.CloudEventUtils;
+
+import java.io.IOException;
+import java.util.Properties;
+import java.util.concurrent.TimeUnit;
+
+import org.asynchttpclient.ListenableFuture;
+import org.asynchttpclient.Response;
+import org.asynchttpclient.util.HttpConstants;
+
+import io.cloudevents.CloudEvent;
+
+public class ProducerImpl extends AbstractProducer {
+
+ public ProducerImpl(final Properties properties) throws IOException {
+ super(properties);
+ }
+
+ public Properties attributes() {
+ return properties;
+ }
+
+ public void send(CloudEvent cloudEvent, SendCallback sendCallback) {
+ // Set HTTP header, body and send CloudEvent message:
+ try {
+ ListenableFuture<Response> execute =
super.getAsyncHttpClient().preparePost("http://" +
this.attributes().getProperty("url"))
+ .addHeader(KnativeHeaders.CONTENT_TYPE,
cloudEvent.getDataContentType())
+ .addHeader(KnativeHeaders.CE_ID, cloudEvent.getId())
+ .addHeader(KnativeHeaders.CE_SPECVERSION,
String.valueOf(cloudEvent.getSpecVersion()))
+ .addHeader(KnativeHeaders.CE_TYPE, cloudEvent.getType())
+ .addHeader(KnativeHeaders.CE_SOURCE,
String.valueOf(cloudEvent.getSource()))
+ .setBody(KnativeMessageFactory.createReader(cloudEvent))
+ .execute();
+
+ Response response = execute.get(10, TimeUnit.SECONDS);
+ if (response.getStatusCode() ==
HttpConstants.ResponseStatusCodes.OK_200) {
+
sendCallback.onSuccess(CloudEventUtils.convertSendResult(cloudEvent));
+ return;
+ }
+ throw new IllegalStateException("HTTP response code error: " +
response.getStatusCode());
+ } catch (Exception e) {
+ StorageRuntimeException onsEx =
ProducerImpl.this.checkProducerException(cloudEvent, e);
+ OnExceptionContext context = new OnExceptionContext();
+ context.setTopic(KnativeMessageFactory.createReader(cloudEvent));
+ context.setException(onsEx);
+ sendCallback.onException(context);
+ }
+ }
+
+ public void sendAsync(CloudEvent cloudEvent, SendCallback sendCallback) {
+ try {
+ this.send(cloudEvent, sendCallback);
+ } catch (Exception e) {
+ //LOG.error("Send cloudevent message Exception", e);
+ throw new StorageRuntimeException("Send cloudevent message
Exception.", e);
+ }
+ }
+
+ @Override
+ public void init(Properties properties) throws Exception {
+ new ProducerImpl(properties);
+ }
+
+ @Override
+ public void publish(CloudEvent cloudEvent, SendCallback sendCallback)
throws Exception {
+ this.sendAsync(cloudEvent, sendCallback);
+ }
+
+ @Override
+ public void sendOneway(CloudEvent cloudEvent) {
+ throw new StorageRuntimeException("SendOneWay is not supported");
+ }
+
+ @Override
+ public void request(CloudEvent cloudEvent, RequestReplyCallback
rrCallback, long timeout) throws Exception {
+ throw new StorageRuntimeException("Request is not supported");
+ }
+
+ @Override
+ public boolean reply(CloudEvent cloudEvent, SendCallback sendCallback)
throws Exception {
+ throw new StorageRuntimeException("Reply is not supported");
+ }
+
+ @Override
+ public void checkTopicExist(String topic) throws Exception {
+ throw new StorageRuntimeException("CheckTopicExist is not supported");
+ }
+
+ @Override
+ public void setExtFields() {
+ throw new StorageRuntimeException("SetExtFields is not supported");
+ }
+
+ @Override
+ public void start() {
+ started.set(true);
+ }
+
+ @Override
+ public void shutdown() {
+ started.set(false);
+ }
+}
diff --git
a/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/utils/CloudEventUtils.java
b/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/utils/CloudEventUtils.java
new file mode 100644
index 000000000..9b2b4c96a
--- /dev/null
+++
b/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/utils/CloudEventUtils.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.storage.knative.utils;
+
+import org.apache.eventmesh.api.SendResult;
+import org.apache.eventmesh.storage.knative.cloudevent.KnativeMessageFactory;
+
+import io.cloudevents.CloudEvent;
+
+public class CloudEventUtils {
+
+ public static SendResult convertSendResult(CloudEvent cloudEvent) {
+ SendResult sendResult = new SendResult();
+ sendResult.setTopic(KnativeMessageFactory.createReader(cloudEvent));
+ sendResult.setMessageId(cloudEvent.getId());
+ return sendResult;
+ }
+}
diff --git
a/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.consumer.Consumer
b/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.consumer.Consumer
new file mode 100644
index 000000000..6b10bacce
--- /dev/null
+++
b/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.consumer.Consumer
@@ -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.
+
+knative=org.apache.eventmesh.storage.knative.consumer.KnativeConsumerImpl
\ No newline at end of file
diff --git
a/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.producer.Producer
b/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.producer.Producer
new file mode 100644
index 000000000..bc5f8b41e
--- /dev/null
+++
b/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.producer.Producer
@@ -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.
+
+knative=org.apache.eventmesh.storage.knative.producer.KnativeProducerImpl
\ No newline at end of file
diff --git
a/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.storage.StorageResourceService
b/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.storage.StorageResourceService
new file mode 100644
index 000000000..06c107570
--- /dev/null
+++
b/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.storage.StorageResourceService
@@ -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.
+
+knative=org.apache.eventmesh.storage.knative.storage.StorageResourceServiceKnativeImpl
\ No newline at end of file
diff --git
a/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/resources/knative-client.properties
b/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/resources/knative-client.properties
new file mode 100644
index 000000000..8fec1c430
--- /dev/null
+++
b/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/resources/knative-client.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.
+#
+#######################knative-client##################
+eventMesh.server.knative.service=127.0.0.1;cloudevents-player.default.127.0.0.1.sslip.io
diff --git
a/eventmesh-storage-plugin/eventmesh-storage-knative/src/test/java/org/apache/eventmesh/storage/knative/config/ClientConfigurationTest.java
b/eventmesh-storage-plugin/eventmesh-storage-knative/src/test/java/org/apache/eventmesh/storage/knative/config/ClientConfigurationTest.java
new file mode 100644
index 000000000..9ff668a1c
--- /dev/null
+++
b/eventmesh-storage-plugin/eventmesh-storage-knative/src/test/java/org/apache/eventmesh/storage/knative/config/ClientConfigurationTest.java
@@ -0,0 +1,51 @@
+/*
+ * 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.storage.knative.config;
+
+import org.apache.eventmesh.api.factory.StoragePluginFactory;
+import org.apache.eventmesh.storage.knative.consumer.KnativeConsumerImpl;
+import org.apache.eventmesh.storage.knative.producer.KnativeProducerImpl;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class ClientConfigurationTest {
+
+ @Test
+ public void getConfigWhenKnativeConsumerInit() {
+ KnativeConsumerImpl consumer =
+ (KnativeConsumerImpl)
StoragePluginFactory.getMeshMQPushConsumer("knative");
+
+ ClientConfiguration config = consumer.getClientConfiguration();
+ assertConfig(config);
+ }
+
+ @Test
+ public void getConfigWhenKnativeProducerInit() {
+ KnativeProducerImpl producer =
+ (KnativeProducerImpl)
StoragePluginFactory.getMeshMQProducer("knative");
+
+ ClientConfiguration config = producer.getClientConfiguration();
+ assertConfig(config);
+ }
+
+ private void assertConfig(ClientConfiguration config) {
+ Assert.assertEquals(config.getEmurl(), "127.0.0.1");
+ Assert.assertEquals(config.getServiceAddr(),
"cloudevents-player.default.127.0.0.1.sslip.io");
+ }
+}
\ No newline at end of file
diff --git
a/eventmesh-storage-plugin/eventmesh-storage-knative/src/test/java/org/apache/eventmesh/storage/knative/consumer/KnativeConsumerImplTest.java
b/eventmesh-storage-plugin/eventmesh-storage-knative/src/test/java/org/apache/eventmesh/storage/knative/consumer/KnativeConsumerImplTest.java
new file mode 100644
index 000000000..d2888ffb9
--- /dev/null
+++
b/eventmesh-storage-plugin/eventmesh-storage-knative/src/test/java/org/apache/eventmesh/storage/knative/consumer/KnativeConsumerImplTest.java
@@ -0,0 +1,48 @@
+/*
+ * 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.storage.knative.consumer;
+
+import org.apache.eventmesh.api.factory.StoragePluginFactory;
+
+import java.util.Properties;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class KnativeConsumerImplTest {
+
+ @Test
+ public void testSubscribe() throws Exception {
+ Properties properties = new Properties();
+ final String topic = "messages";
+ properties.put("topic", topic);
+
+ // Create a Knative consumer:
+ KnativeConsumerImpl knativeConsumer =
+ (KnativeConsumerImpl)
StoragePluginFactory.getMeshMQPushConsumer("knative");
+
+ try {
+ knativeConsumer.init(properties);
+
+ // Subscribe:
+ knativeConsumer.subscribe(properties.getProperty("topic"));
+ } catch (Exception e) {
+ Assert.fail(e.getMessage());
+ }
+ }
+}
diff --git
a/eventmesh-storage-plugin/eventmesh-storage-knative/src/test/java/org/apache/eventmesh/storage/knative/producer/KnativeProducerImplTest.java
b/eventmesh-storage-plugin/eventmesh-storage-knative/src/test/java/org/apache/eventmesh/storage/knative/producer/KnativeProducerImplTest.java
new file mode 100644
index 000000000..0ae77db30
--- /dev/null
+++
b/eventmesh-storage-plugin/eventmesh-storage-knative/src/test/java/org/apache/eventmesh/storage/knative/producer/KnativeProducerImplTest.java
@@ -0,0 +1,66 @@
+/*
+ * 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.storage.knative.producer;
+
+import org.apache.eventmesh.api.SendCallback;
+import org.apache.eventmesh.api.SendResult;
+import org.apache.eventmesh.api.exception.OnExceptionContext;
+import org.apache.eventmesh.api.factory.StoragePluginFactory;
+import org.apache.eventmesh.storage.knative.cloudevent.KnativeMessageFactory;
+import org.apache.eventmesh.storage.knative.cloudevent.impl.KnativeHeaders;
+
+import java.util.Properties;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class KnativeProducerImplTest {
+
+ @Test
+ public void testPublish() throws Exception {
+ Properties properties = new Properties();
+
+ properties.put(KnativeHeaders.CONTENT_TYPE, "application/json");
+ properties.put(KnativeHeaders.CE_ID, "1234");
+ properties.put(KnativeHeaders.CE_SPECVERSION, "1.0");
+ properties.put(KnativeHeaders.CE_TYPE, "some-type");
+ properties.put(KnativeHeaders.CE_SOURCE, "java-client");
+ properties.put("data", "Hello Knative from EventMesh!");
+
+ // Create a Knative producer:
+ KnativeProducerImpl knativeProducer =
+ (KnativeProducerImpl)
StoragePluginFactory.getMeshMQProducer("knative");
+
+ try {
+ knativeProducer.init(properties);
+
+ // Publish an event message:
+
knativeProducer.publish(KnativeMessageFactory.createWriter(properties).getMessage(),
new SendCallback() {
+ @Override
+ public void onSuccess(SendResult sendResult) {
+ }
+
+ @Override
+ public void onException(OnExceptionContext context) {
+ }
+ });
+ } catch (Exception e) {
+ Assert.fail(e.getMessage());
+ }
+ }
+}
diff --git
a/eventmesh-storage-plugin/eventmesh-storage-knative/src/test/resources/knative-client.properties
b/eventmesh-storage-plugin/eventmesh-storage-knative/src/test/resources/knative-client.properties
new file mode 100644
index 000000000..8fec1c430
--- /dev/null
+++
b/eventmesh-storage-plugin/eventmesh-storage-knative/src/test/resources/knative-client.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.
+#
+#######################knative-client##################
+eventMesh.server.knative.service=127.0.0.1;cloudevents-player.default.127.0.0.1.sslip.io
diff --git a/settings.gradle b/settings.gradle
index 39e84e29a..488af68c3 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -26,6 +26,7 @@ include 'eventmesh-spi'
include 'eventmesh-storage-plugin:eventmesh-storage-api'
include 'eventmesh-storage-plugin:eventmesh-storage-standalone'
include 'eventmesh-storage-plugin:eventmesh-storage-kafka'
+include 'eventmesh-storage-plugin:eventmesh-storage-knative'
include 'eventmesh-storage-plugin:eventmesh-storage-mongodb'
include 'eventmesh-storage-plugin:eventmesh-storage-pulsar'
include 'eventmesh-storage-plugin:eventmesh-storage-pravega'
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]