This is an automated email from the ASF dual-hosted git repository.
Aias00 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shenyu.git
The following commit(s) were added to refs/heads/master by this push:
new d671076d90 fix(wasm): forward discovery upstream deletion events
(#7568)
d671076d90 is described below
commit d671076d905e4d13acff40ea44d8646f5ca421f1
Author: redyyang <[email protected]>
AuthorDate: Mon Oct 12 22:49:27 2026 +0800
fix(wasm): forward discovery upstream deletion events (#7568)
---
.../shenyu/plugin/wasm/api/loader/WasmLoader.java | 12 +-
.../plugin/wasm/api/AbstractWasmPluginTest.java | 18 +++
shenyu-plugin/shenyu-plugin-wasm-base/README.md | 35 ++++
.../base/handler/AbstractWasmDiscoveryHandler.java | 53 ++++--
.../src/test/go-discovery-handler/main.go | 9 +-
.../handler/AbstractWasmDiscoveryHandlerTest.java | 179 +++++++++++++++------
...ndlerTest$TestGoWasmPluginDiscoveryHandler.wasm | Bin 4327 -> 4261 bytes
...Test$TestLegacyWasmPluginDiscoveryHandler.wasm} | Bin
...HandlerTest$TestWasmPluginDiscoveryHandler.wasm | Bin 60991 -> 64328 bytes
.../src/test/rust-discovery-handler/src/lib.rs | 11 +-
10 files changed, 250 insertions(+), 67 deletions(-)
diff --git
a/shenyu-plugin/shenyu-plugin-wasm-api/src/main/java/org/apache/shenyu/plugin/wasm/api/loader/WasmLoader.java
b/shenyu-plugin/shenyu-plugin-wasm-api/src/main/java/org/apache/shenyu/plugin/wasm/api/loader/WasmLoader.java
index 66c0772263..e3f1f7140b 100644
---
a/shenyu-plugin/shenyu-plugin-wasm-api/src/main/java/org/apache/shenyu/plugin/wasm/api/loader/WasmLoader.java
+++
b/shenyu-plugin/shenyu-plugin-wasm-api/src/main/java/org/apache/shenyu/plugin/wasm/api/loader/WasmLoader.java
@@ -25,6 +25,7 @@ import com.dylibso.chicory.runtime.Memory;
import com.dylibso.chicory.runtime.Store;
import com.dylibso.chicory.wasm.Parser;
import com.dylibso.chicory.wasm.WasmModule;
+import com.dylibso.chicory.wasm.types.ExportSection;
import com.dylibso.chicory.wasm.types.FunctionType;
import com.dylibso.chicory.wasm.types.ValType;
import org.apache.shenyu.plugin.wasm.api.exception.ShenyuWasmException;
@@ -275,11 +276,14 @@ public class WasmLoader implements AutoCloseable {
* @return an Optional containing the ExportFunction if found, otherwise
empty
*/
public Optional<ExportFunction> getWasmExtern(final String funcName) {
- ExportFunction fn = instance.export(funcName);
- if (Objects.isNull(fn)) {
- LOG.debug("WASM export function '{}' not found in {}", funcName,
wasmName);
+ ExportSection exports = instance.module().exportSection();
+ for (int index = 0; index < exports.exportCount(); index++) {
+ if (funcName.equals(exports.getExport(index).name())) {
+ return Optional.of(instance.export(funcName));
+ }
}
- return Optional.ofNullable(fn);
+ LOG.debug("WASM export function '{}' not found in {}", funcName,
wasmName);
+ return Optional.empty();
}
/**
diff --git
a/shenyu-plugin/shenyu-plugin-wasm-api/src/test/java/org/apache/shenyu/plugin/wasm/api/AbstractWasmPluginTest.java
b/shenyu-plugin/shenyu-plugin-wasm-api/src/test/java/org/apache/shenyu/plugin/wasm/api/AbstractWasmPluginTest.java
index 40d501ca5b..8534678bad 100644
---
a/shenyu-plugin/shenyu-plugin-wasm-api/src/test/java/org/apache/shenyu/plugin/wasm/api/AbstractWasmPluginTest.java
+++
b/shenyu-plugin/shenyu-plugin-wasm-api/src/test/java/org/apache/shenyu/plugin/wasm/api/AbstractWasmPluginTest.java
@@ -18,9 +18,11 @@
package org.apache.shenyu.plugin.wasm.api;
import com.dylibso.chicory.runtime.Memory;
+import com.dylibso.chicory.wasm.InvalidException;
import org.apache.shenyu.common.config.ShenyuConfig;
import org.apache.shenyu.plugin.api.ShenyuPluginChain;
import org.apache.shenyu.plugin.api.utils.SpringBeanUtils;
+import org.apache.shenyu.plugin.wasm.api.loader.WasmLoader;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.context.ConfigurableApplicationContext;
@@ -35,6 +37,7 @@ import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
@@ -74,6 +77,21 @@ public class AbstractWasmPluginTest {
StepVerifier.create(rustPlugin.execute(exchange,
shenyuPluginChain)).expectSubscription().verifyComplete();
verify(shenyuPluginChain).execute(exchange);
}
+
+ @Test
+ public void missingExportReturnsEmptyTest() {
+ try (WasmLoader loader = new WasmLoader(RustWasmPlugin.class, null)) {
+ assertTrue(loader.getWasmExtern("missingCallback").isEmpty());
+ assertTrue(loader.getWasmExtern("execute").isPresent());
+ }
+ }
+
+ @Test
+ public void nonFunctionExportStillFailsTest() {
+ try (WasmLoader loader = new WasmLoader(RustWasmPlugin.class, null)) {
+ assertThrows(InvalidException.class, () ->
loader.getWasmExtern("memory"));
+ }
+ }
private void mockShenyuConfig() {
ConfigurableApplicationContext context =
mock(ConfigurableApplicationContext.class);
diff --git a/shenyu-plugin/shenyu-plugin-wasm-base/README.md
b/shenyu-plugin/shenyu-plugin-wasm-base/README.md
new file mode 100644
index 0000000000..84c35ee41f
--- /dev/null
+++ b/shenyu-plugin/shenyu-plugin-wasm-base/README.md
@@ -0,0 +1,35 @@
+# WASM discovery callbacks
+
+`AbstractWasmDiscoveryHandler` forwards discovery updates to the required guest
+export `handlerDiscoveryUpstreamData(argId: i64) -> ()` and deletions to the
+optional export `removeDiscoveryUpstreamData(argId: i64) -> ()`.
+
+Both callbacks use the existing Java argument bridge. `getArgumentId` supplies
+the ID, and `ARGUMENTS.get(argId)` exposes a `DiscoverySyncData` for the
duration
+of the callback. A Java subclass can serialize this object from `onGetArgs`,
+which serves the guest's `shenyu.get_args` import.
+
+For deletion, the object contains exactly the identity from
`DiscoveryUpstreamKey`:
+
+- `pluginName`: the plugin owning the discovery state.
+- `selectorId`: the selector to remove.
+- `selectorName`: the optional selector name, which can be null.
+
+The remaining fields, including `upstreamDataList`, are null. The guest should
+remove the state identified by this key when the deletion callback runs. For a
+subclass using JSON serialization, a deletion payload can look like:
+
+```json
+{"pluginName":"divide","selectorId":"selector-id","selectorName":"my-selector"}
+```
+
+Guests that omit the deletion export receive no callback, preserving the legacy
+no-op behavior. Existing Java subclasses do not need a new argument-ID method.
+Callback failures propagate to the caller, and the temporary argument is
removed
+whether the callback succeeds or fails.
+
+The Go and Rust test guests read the deletion payload and echo it through
+`shenyu.put_result`. Their build instructions are in
`src/test/go-discovery-handler`
+and `src/test/rust-discovery-handler`. The
`TestLegacyWasmPluginDiscoveryHandler`
+fixture preserves the original Go binary without the deletion export to test
+compatibility with existing guests.
diff --git
a/shenyu-plugin/shenyu-plugin-wasm-base/src/main/java/org/apache/shenyu/plugin/wasm/base/handler/AbstractWasmDiscoveryHandler.java
b/shenyu-plugin/shenyu-plugin-wasm-base/src/main/java/org/apache/shenyu/plugin/wasm/base/handler/AbstractWasmDiscoveryHandler.java
index 91b6057a7e..bc33c25e97 100644
---
a/shenyu-plugin/shenyu-plugin-wasm-base/src/main/java/org/apache/shenyu/plugin/wasm/base/handler/AbstractWasmDiscoveryHandler.java
+++
b/shenyu-plugin/shenyu-plugin-wasm-base/src/main/java/org/apache/shenyu/plugin/wasm/base/handler/AbstractWasmDiscoveryHandler.java
@@ -17,10 +17,12 @@
package org.apache.shenyu.plugin.wasm.base.handler;
+import com.dylibso.chicory.runtime.ExportFunction;
import org.apache.shenyu.common.dto.DiscoverySyncData;
import org.apache.shenyu.plugin.base.handler.DiscoveryUpstreamDataHandler;
import org.apache.shenyu.plugin.wasm.api.exception.ShenyuWasmInitException;
import org.apache.shenyu.plugin.wasm.api.loader.WasmLoader;
+import org.apache.shenyu.sync.data.api.DiscoveryUpstreamKey;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@@ -33,23 +35,48 @@ public abstract class AbstractWasmDiscoveryHandler extends
WasmLoader implements
protected static final Map<Long, DiscoverySyncData> ARGUMENTS = new
ConcurrentHashMap<>();
protected static final String METHOD_NAME = "handlerDiscoveryUpstreamData";
+
+ protected static final String REMOVE_METHOD_NAME =
"removeDiscoveryUpstreamData";
@Override
public void handlerDiscoveryUpstreamData(final DiscoverySyncData
discoverySyncData) {
super.getWasmExtern(METHOD_NAME)
- .map(handlerDiscoveryUpstreamData -> {
- // WASI cannot easily pass Java objects like JNI, here we
pass Long as arg
- // then we can get the argument by Long
- final Long argumentId = getArgumentId(discoverySyncData);
- ARGUMENTS.put(argumentId, discoverySyncData);
- // call WASI function
- try {
- handlerDiscoveryUpstreamData.apply(argumentId);
- } finally {
- ARGUMENTS.remove(argumentId);
- }
- return argumentId;
- }).orElseThrow(() -> new ShenyuWasmInitException(METHOD_NAME +
" function not find in wasm file: " + getWasmName()));
+ .map(handlerDiscoveryUpstreamData ->
callWASI(discoverySyncData, handlerDiscoveryUpstreamData))
+ .orElseThrow(() -> new ShenyuWasmInitException(METHOD_NAME + "
function not find in wasm file: " + getWasmName()));
+ }
+
+ /**
+ * Forward deletion to the optional guest export {@code
removeDiscoveryUpstreamData(i64) -> ()}.
+ *
+ * <p>The argument id uses the same {@link
#getArgumentId(DiscoverySyncData)} and {@link #ARGUMENTS}
+ * bridge as updates. During the callback, the argument is a {@link
DiscoverySyncData} containing
+ * the key's plugin name, selector id and optional selector name; all
other fields are null.
+ * Subclasses can serialize it through {@code shenyu.get_args} as they do
for updates.
+ * The argument is removed after the callback, including when the guest
throws.
+ * Guests without this export keep the default no-op deletion behavior.
+ *
+ * @param key discovery upstream selector identity
+ */
+ @Override
+ public void removeDiscoveryUpstreamData(final DiscoveryUpstreamKey key) {
+ super.getWasmExtern(REMOVE_METHOD_NAME).ifPresent(remove -> {
+ DiscoverySyncData data = new DiscoverySyncData();
+ data.setPluginName(key.pluginName());
+ data.setSelectorId(key.selectorId());
+ data.setSelectorName(key.selectorName());
+ callWASI(data, remove);
+ });
+ }
+
+ private Long callWASI(final DiscoverySyncData discoverySyncData, final
ExportFunction execute) {
+ final Long argumentId = getArgumentId(discoverySyncData);
+ ARGUMENTS.put(argumentId, discoverySyncData);
+ try {
+ execute.apply(argumentId);
+ } finally {
+ ARGUMENTS.remove(argumentId);
+ }
+ return argumentId;
}
protected abstract Long getArgumentId(DiscoverySyncData discoverySyncData);
diff --git
a/shenyu-plugin/shenyu-plugin-wasm-base/src/test/go-discovery-handler/main.go
b/shenyu-plugin/shenyu-plugin-wasm-base/src/test/go-discovery-handler/main.go
index 2665713c37..c7e1dad1db 100644
---
a/shenyu-plugin/shenyu-plugin-wasm-base/src/test/go-discovery-handler/main.go
+++
b/shenyu-plugin/shenyu-plugin-wasm-base/src/test/go-discovery-handler/main.go
@@ -16,7 +16,7 @@
*/
// Go WASM handler for AbstractWasmDiscoveryHandler.
-// Exports handlerDiscoveryUpstreamData — (i64) -> ().
+// Exports update and optional deletion callbacks — (i64) -> ().
// Compile with: tinygo build -target wasm-unknown -opt=2 -no-debug
-panic=trap -o plugin.wasm main.go
package main
@@ -36,5 +36,12 @@ func handlerDiscoveryUpstreamData(argId int64) {
wasmabi.PutResult(argId, []byte("go result"))
}
+//go:wasmexport removeDiscoveryUpstreamData
+func removeDiscoveryUpstreamData(argId int64) {
+ buf := make([]byte, 1024)
+ input := wasmabi.GetArgs(argId, buf)
+ wasmabi.PutResult(argId, append([]byte("removed:"), input...))
+}
+
// main is required by TinyGo's WASI target but is never called.
func main() {}
diff --git
a/shenyu-plugin/shenyu-plugin-wasm-base/src/test/java/org/apache/shenyu/plugin/wasm/base/handler/AbstractWasmDiscoveryHandlerTest.java
b/shenyu-plugin/shenyu-plugin-wasm-base/src/test/java/org/apache/shenyu/plugin/wasm/base/handler/AbstractWasmDiscoveryHandlerTest.java
index 25e946264a..2e6369289a 100644
---
a/shenyu-plugin/shenyu-plugin-wasm-base/src/test/java/org/apache/shenyu/plugin/wasm/base/handler/AbstractWasmDiscoveryHandlerTest.java
+++
b/shenyu-plugin/shenyu-plugin-wasm-base/src/test/java/org/apache/shenyu/plugin/wasm/base/handler/AbstractWasmDiscoveryHandlerTest.java
@@ -19,81 +19,164 @@ package org.apache.shenyu.plugin.wasm.base.handler;
import com.dylibso.chicory.runtime.Memory;
import org.apache.shenyu.common.dto.DiscoverySyncData;
+import org.apache.shenyu.common.dto.DiscoveryUpstreamData;
+import org.apache.shenyu.common.utils.GsonUtils;
+import
org.apache.shenyu.plugin.base.cache.CommonDiscoveryUpstreamDataSubscriber;
+import org.apache.shenyu.sync.data.api.DiscoveryUpstreamKey;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.mockito.junit.jupiter.MockitoExtension;
-import org.mockito.junit.jupiter.MockitoSettings;
-import org.mockito.quality.Strictness;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
import java.nio.charset.StandardCharsets;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicLong;
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertSame;
+import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-@ExtendWith(MockitoExtension.class)
-@MockitoSettings(strictness = Strictness.LENIENT)
class AbstractWasmDiscoveryHandlerTest {
private DiscoverySyncData discoverySyncData;
@BeforeEach
public void setUp() {
- this.discoverySyncData = mock(DiscoverySyncData.class);
- when(discoverySyncData.getSelectorId()).thenReturn("SHENYU");
+ discoverySyncData = new DiscoverySyncData();
+ discoverySyncData.setPluginName("SHENYU_TEST");
+ discoverySyncData.setSelectorId("selector-id");
+ discoverySyncData.setSelectorName("upstream-测试");
+ discoverySyncData.setUpstreamDataList(List.of(new
DiscoveryUpstreamData()));
}
- /** Go WASM test. */
- @Test
- public void goHandlerDiscoveryUpstreamDataTest() {
- final TestGoWasmPluginDiscoveryHandler goHandler = new
TestGoWasmPluginDiscoveryHandler("go result");
- goHandler.handlerDiscoveryUpstreamData(discoverySyncData);
- assertEquals("SHENYU_TEST", goHandler.pluginName());
+ @ParameterizedTest
+ @ValueSource(booleans = {true, false})
+ void handlerDiscoveryUpstreamDataTest(final boolean go) {
+ try (WasmTestHandler handler = newHandler(go)) {
+ handler.handlerDiscoveryUpstreamData(discoverySyncData);
+ assertEquals(List.of(go ? "go result" : "rust result"),
handler.results);
+ assertSame(discoverySyncData, handler.arguments.get(0));
+ assertArgumentsRemoved(handler);
+ }
+ }
+
+ @ParameterizedTest
+ @ValueSource(booleans = {true, false})
+ void removeDiscoveryUpstreamDataTest(final boolean go) {
+ try (WasmTestHandler handler = newHandler(go)) {
+ DiscoveryUpstreamKey key =
DiscoveryUpstreamKey.from(discoverySyncData);
+ handler.removeDiscoveryUpstreamData(key);
+ assertEquals(1, handler.results.size());
+ assertDeletionResult(handler, key, 0);
+ DiscoveryUpstreamKey unnamedKey = new
DiscoveryUpstreamKey("SHENYU_TEST", "another-selector-id", null);
+ handler.removeDiscoveryUpstreamData(unnamedKey);
+ assertEquals(2, handler.results.size());
+ assertDeletionResult(handler, unnamedKey, 1);
+ assertArgumentsRemoved(handler);
+ }
+ }
+
+ @ParameterizedTest
+ @ValueSource(booleans = {true, false})
+ void subscriberForwardsUpdateAndDeletionTest(final boolean go) {
+ try (WasmTestHandler handler = newHandler(go)) {
+ CommonDiscoveryUpstreamDataSubscriber subscriber = new
CommonDiscoveryUpstreamDataSubscriber(List.of(handler));
+ subscriber.onSubscribe(discoverySyncData);
+ DiscoveryUpstreamKey key =
DiscoveryUpstreamKey.from(discoverySyncData);
+ subscriber.unSubscribe(key);
+ assertEquals(2, handler.results.size());
+ assertEquals(go ? "go result" : "rust result",
handler.results.get(0));
+ assertDeletionResult(handler, key, 1);
+ assertArgumentsRemoved(handler);
+ }
+ }
+
+ @ParameterizedTest
+ @ValueSource(booleans = {true, false})
+ void deletionFailureRemovesArgumentsTest(final boolean go) {
+ try (WasmTestHandler handler = newHandler(go)) {
+ handler.failOnResult = true;
+ DiscoveryUpstreamKey key =
DiscoveryUpstreamKey.from(discoverySyncData);
+ assertThrows(RuntimeException.class, () ->
handler.removeDiscoveryUpstreamData(key));
+ assertEquals(1, handler.results.size());
+ assertDeletionResult(handler, key, 0);
+ assertArgumentsRemoved(handler);
+ }
}
- /** Rust WASM test. */
@Test
- public void rustHandlerDiscoveryUpstreamDataTest() {
- final TestWasmPluginDiscoveryHandler rustHandler = new
TestWasmPluginDiscoveryHandler("rust result");
- rustHandler.handlerDiscoveryUpstreamData(discoverySyncData);
- assertEquals("SHENYU_TEST", rustHandler.pluginName());
+ void missingOptionalDeletionExportTest() {
+ try (WasmTestHandler handler = new
TestLegacyWasmPluginDiscoveryHandler()) {
+
assertTrue(handler.getWasmExtern("removeDiscoveryUpstreamData").isEmpty());
+ DiscoveryUpstreamKey key =
DiscoveryUpstreamKey.from(discoverySyncData);
+ assertDoesNotThrow(() -> handler.removeDiscoveryUpstreamData(key));
+ CommonDiscoveryUpstreamDataSubscriber subscriber = new
CommonDiscoveryUpstreamDataSubscriber(List.of(handler));
+ assertDoesNotThrow(() -> subscriber.unSubscribe(key));
+ assertTrue(handler.arguments.isEmpty());
+ assertTrue(handler.argumentIds.isEmpty());
+ assertTrue(handler.results.isEmpty());
+ subscriber.onSubscribe(discoverySyncData);
+ assertEquals(List.of("go result"), handler.results);
+ assertArgumentsRemoved(handler);
+ }
+ }
+
+ private static WasmTestHandler newHandler(final boolean go) {
+ return go ? new TestGoWasmPluginDiscoveryHandler() : new
TestWasmPluginDiscoveryHandler();
+ }
+
+ private static void assertDeletionResult(final WasmTestHandler handler,
final DiscoveryUpstreamKey key, final int index) {
+ String result = handler.results.get(index);
+ assertTrue(result.startsWith("removed:"));
+ DiscoverySyncData guestData =
GsonUtils.getInstance().fromJson(result.substring("removed:".length()),
DiscoverySyncData.class);
+ assertEquals(key, DiscoveryUpstreamKey.from(guestData));
+ assertNull(guestData.getUpstreamDataList());
+ assertNull(guestData.getNamespaceId());
+ assertNull(guestData.getDiscoveryHandlerId());
+ assertEquals(key,
DiscoveryUpstreamKey.from(handler.arguments.get(index)));
+ }
+
+ private static void assertArgumentsRemoved(final WasmTestHandler handler) {
+ assertTrue(AbstractWasmDiscoveryHandler.ARGUMENTS.isEmpty());
+ handler.argumentIds.forEach(id ->
assertNull(AbstractWasmDiscoveryHandler.ARGUMENTS.get(id)));
}
abstract static class WasmTestHandler extends AbstractWasmDiscoveryHandler
{
- private static final java.util.concurrent.atomic.AtomicLong ID =
- new java.util.concurrent.atomic.AtomicLong();
+ private static final AtomicLong ID = new AtomicLong();
- private final Map<Long, String> results = new ConcurrentHashMap<>();
+ private final List<String> results = new ArrayList<>();
- private final String expectedResult;
+ private final List<DiscoverySyncData> arguments = new ArrayList<>();
- WasmTestHandler(final String expectedResult) {
- this.expectedResult = expectedResult;
- }
+ private final List<Long> argumentIds = new ArrayList<>();
+
+ private boolean failOnResult;
@Override
protected long onGetArgs(final long argId, final long addr, final int
len) {
- String config = "hello from java " + argId;
- assertTrue(config.startsWith("hello from java "));
+ DiscoverySyncData argument = ARGUMENTS.get(argId);
+ assertNotNull(argument);
+ arguments.add(argument);
+ byte[] data =
GsonUtils.getInstance().toJson(argument).getBytes(StandardCharsets.UTF_8);
+ assertTrue(data.length <= len);
Memory memory = super.getMemory();
- byte[] data = config.getBytes(StandardCharsets.UTF_8);
- int writeLen = Math.min(len, data.length);
- memory.write((int) addr, data, 0, writeLen);
- return writeLen;
+ memory.write((int) addr, data, 0, data.length);
+ return data.length;
}
@Override
protected long onPutResult(final long argId, final long addr, final
int len) {
- Memory memory = super.getMemory();
- byte[] bytes = memory.readBytes((int) addr, len);
- String result = new String(bytes, StandardCharsets.UTF_8);
- assertEquals(expectedResult, result);
- results.put(argId, result);
+ byte[] bytes = super.getMemory().readBytes((int) addr, len);
+ results.add(new String(bytes, StandardCharsets.UTF_8));
+ if (failOnResult) {
+ throw new IllegalStateException("discovery callback failed");
+ }
return 0;
}
@@ -104,21 +187,21 @@ class AbstractWasmDiscoveryHandlerTest {
@Override
protected Long getArgumentId(final DiscoverySyncData
discoverySyncData) {
- return ID.incrementAndGet();
+ long argumentId = ID.incrementAndGet();
+ argumentIds.add(argumentId);
+ return argumentId;
}
}
/** Loads $TestGoWasmPluginDiscoveryHandler.wasm. */
static class TestGoWasmPluginDiscoveryHandler extends WasmTestHandler {
- TestGoWasmPluginDiscoveryHandler(final String expected) {
- super(expected);
- }
}
/** Loads $TestWasmPluginDiscoveryHandler.wasm. */
static class TestWasmPluginDiscoveryHandler extends WasmTestHandler {
- TestWasmPluginDiscoveryHandler(final String expected) {
- super(expected);
- }
+ }
+
+ /** Loads the original Go guest, which only exports the update callback. */
+ static class TestLegacyWasmPluginDiscoveryHandler extends WasmTestHandler {
}
}
diff --git
a/shenyu-plugin/shenyu-plugin-wasm-base/src/test/resources/org.apache.shenyu.plugin.wasm.base.handler.AbstractWasmDiscoveryHandlerTest$TestGoWasmPluginDiscoveryHandler.wasm
b/shenyu-plugin/shenyu-plugin-wasm-base/src/test/resources/org.apache.shenyu.plugin.wasm.base.handler.AbstractWasmDiscoveryHandlerTest$TestGoWasmPluginDiscoveryHandler.wasm
index 81cf164a6e..5572618565 100644
Binary files
a/shenyu-plugin/shenyu-plugin-wasm-base/src/test/resources/org.apache.shenyu.plugin.wasm.base.handler.AbstractWasmDiscoveryHandlerTest$TestGoWasmPluginDiscoveryHandler.wasm
and
b/shenyu-plugin/shenyu-plugin-wasm-base/src/test/resources/org.apache.shenyu.plugin.wasm.base.handler.AbstractWasmDiscoveryHandlerTest$TestGoWasmPluginDiscoveryHandler.wasm
differ
diff --git
a/shenyu-plugin/shenyu-plugin-wasm-base/src/test/resources/org.apache.shenyu.plugin.wasm.base.handler.AbstractWasmDiscoveryHandlerTest$TestGoWasmPluginDiscoveryHandler.wasm
b/shenyu-plugin/shenyu-plugin-wasm-base/src/test/resources/org.apache.shenyu.plugin.wasm.base.handler.AbstractWasmDiscoveryHandlerTest$TestLegacyWasmPluginDiscoveryHandler.wasm
similarity index 100%
copy from
shenyu-plugin/shenyu-plugin-wasm-base/src/test/resources/org.apache.shenyu.plugin.wasm.base.handler.AbstractWasmDiscoveryHandlerTest$TestGoWasmPluginDiscoveryHandler.wasm
copy to
shenyu-plugin/shenyu-plugin-wasm-base/src/test/resources/org.apache.shenyu.plugin.wasm.base.handler.AbstractWasmDiscoveryHandlerTest$TestLegacyWasmPluginDiscoveryHandler.wasm
diff --git
a/shenyu-plugin/shenyu-plugin-wasm-base/src/test/resources/org.apache.shenyu.plugin.wasm.base.handler.AbstractWasmDiscoveryHandlerTest$TestWasmPluginDiscoveryHandler.wasm
b/shenyu-plugin/shenyu-plugin-wasm-base/src/test/resources/org.apache.shenyu.plugin.wasm.base.handler.AbstractWasmDiscoveryHandlerTest$TestWasmPluginDiscoveryHandler.wasm
index 4746d9fae0..3db70c65f0 100755
Binary files
a/shenyu-plugin/shenyu-plugin-wasm-base/src/test/resources/org.apache.shenyu.plugin.wasm.base.handler.AbstractWasmDiscoveryHandlerTest$TestWasmPluginDiscoveryHandler.wasm
and
b/shenyu-plugin/shenyu-plugin-wasm-base/src/test/resources/org.apache.shenyu.plugin.wasm.base.handler.AbstractWasmDiscoveryHandlerTest$TestWasmPluginDiscoveryHandler.wasm
differ
diff --git
a/shenyu-plugin/shenyu-plugin-wasm-base/src/test/rust-discovery-handler/src/lib.rs
b/shenyu-plugin/shenyu-plugin-wasm-base/src/test/rust-discovery-handler/src/lib.rs
index caad200cc3..ad36792773 100644
---
a/shenyu-plugin/shenyu-plugin-wasm-base/src/test/rust-discovery-handler/src/lib.rs
+++
b/shenyu-plugin/shenyu-plugin-wasm-base/src/test/rust-discovery-handler/src/lib.rs
@@ -24,7 +24,7 @@ extern "C" {
#[no_mangle]
pub unsafe extern "C" fn handlerDiscoveryUpstreamData(arg_id: i64) {
- let mut buf = [0u8; 32];
+ let mut buf = [0u8; 1024];
let buf_ptr = buf.as_mut_ptr() as i64;
eprintln!("rust side-> buffer base address: {}", buf_ptr);
// get arg from java
@@ -36,3 +36,12 @@ pub unsafe extern "C" fn
handlerDiscoveryUpstreamData(arg_id: i64) {
let result_ptr = rust_result.as_ptr() as i64;
_ = put_result(arg_id, result_ptr, rust_result.len() as i32);
}
+
+#[no_mangle]
+pub unsafe extern "C" fn removeDiscoveryUpstreamData(arg_id: i64) {
+ let mut buf = [0u8; 1024];
+ let len = get_args(arg_id, buf.as_mut_ptr() as i64, buf.len() as i32);
+ let input = std::str::from_utf8(&buf[..len as usize]).unwrap();
+ let result = format!("removed:{}", input);
+ _ = put_result(arg_id, result.as_ptr() as i64, result.len() as i32);
+}