Skip to content

Commit d52f912

Browse files
committed
Implement gRPC ABI, add rust hello_world example and test.
Signed-off-by: Hiram Chirino <hiram@hiramchirino.com>
1 parent b10984c commit d52f912

File tree

11 files changed

+767
-16
lines changed

11 files changed

+767
-16
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,6 @@ build/
3333

3434
### Mac OS ###
3535
.DS_Store
36+
37+
### Rust ###
38+
target/

Makefile

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,24 @@
33
#
44
# $ make build-go-examples
55
#
6+
# To build the Rust examples, install rustup and cargo install the wasm target with run `rustup target add wasm32-wasip1`
7+
# and then run:
8+
#
9+
# $ make build-rust-examples
10+
#
11+
12+
.PHONY: all
13+
all: build-go-examples build-rust-examples
614

715
.PHONY: build-go-examples
816
build-go-examples:
917
@find ./src/test/go-examples -mindepth 1 -type f -name "main.go" \
1018
| xargs -I {} bash -c 'dirname {}' \
1119
| xargs -I {} bash -c 'cd {} && env GOOS=wasip1 GOARCH=wasm go build -buildmode=c-shared -o main.wasm ./main.go'
20+
21+
22+
.PHONY: build-rust-examples
23+
build-rust-examples:
24+
@find ./src/test/rust-examples -mindepth 1 -type f -name "Cargo.toml" \
25+
| xargs -I {} bash -c 'dirname {}' \
26+
| xargs -I {} bash -c 'cd {} && cargo build --target wasm32-wasip1 --release; cp ./target/wasm32-wasip1/release/*.wasm ./main.wasm'

src/main/java/io/roastedroot/proxywasm/ABI.java

Lines changed: 141 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1107,10 +1107,24 @@ int proxyContinueStream(int arg) {
11071107
return result.getValue();
11081108
}
11091109

1110-
// TODO: implement
1111-
// https://github.com/proxy-wasm/spec/tree/main/abi-versions/v0.2.1#proxy_close_stream
1112-
// TODO: implement
1113-
// https://github.com/proxy-wasm/spec/tree/main/abi-versions/v0.2.1#proxy_get_status
1110+
/**
1111+
* implements: https://github.com/proxy-wasm/spec/tree/main/abi-versions/v0.2.1#proxy_close_stream
1112+
*/
1113+
@WasmExport
1114+
int proxyCloseStream(int proxyStreamType) {
1115+
// TODO: implement
1116+
return WasmResult.UNIMPLEMENTED.getValue();
1117+
}
1118+
1119+
/**
1120+
* implements: https://github.com/proxy-wasm/spec/tree/main/abi-versions/v0.2.1#proxy_get_status
1121+
*/
1122+
@WasmExport
1123+
int proxyGetStatus(
1124+
int returnStatusCode, int returnStatusMessageData, int returnStatusMessageSize) {
1125+
// TODO: implement
1126+
return WasmResult.UNIMPLEMENTED.getValue();
1127+
}
11141128

11151129
// //////////////////////////////////////////////////////////////////////
11161130
// TCP streams
@@ -1421,16 +1435,109 @@ void proxyOnHttpCallResponse(int arg0, int arg1, int arg2, int arg3, int arg4) {
14211435
// gRPC calls
14221436
// //////////////////////////////////////////////////////////////////////
14231437

1424-
// TODO: implement
1425-
// https://github.com/proxy-wasm/spec/tree/main/abi-versions/vNEXT#proxy_grpc_call
1426-
// TODO: implement
1427-
// https://github.com/proxy-wasm/spec/tree/main/abi-versions/vNEXT#proxy_grpc_stream
1428-
// TODO: implement
1429-
// https://github.com/proxy-wasm/spec/tree/main/abi-versions/vNEXT#proxy_grpc_send
1430-
// TODO: implement
1431-
// https://github.com/proxy-wasm/spec/tree/main/abi-versions/vNEXT#proxy_grpc_cancel
1432-
// TODO: implement
1433-
// https://github.com/proxy-wasm/spec/tree/main/abi-versions/vNEXT#proxy_grpc_close
1438+
/**
1439+
* implements https://github.com/proxy-wasm/spec/tree/main/abi-versions/vNEXT#proxy_grpc_call
1440+
*/
1441+
@WasmExport
1442+
int proxyGrpcCall(
1443+
int upstreamNameData,
1444+
int upstreamNameSize,
1445+
int serviceNameData,
1446+
int serviceNameSize,
1447+
int methodNameData,
1448+
int methodNameSize,
1449+
int serialized_initial_metadataData,
1450+
int serialized_initial_metadataSize,
1451+
int messageData,
1452+
int messageSize,
1453+
int timeout,
1454+
int returnCalloutID) {
1455+
1456+
try {
1457+
var upstreamName = string(readMemory(upstreamNameData, upstreamNameSize));
1458+
var serviceName = string(readMemory(serviceNameData, serviceNameSize));
1459+
var methodName = string(readMemory(methodNameData, methodNameSize));
1460+
var initialMetadata =
1461+
decodeMap(serialized_initial_metadataData, serialized_initial_metadataSize);
1462+
var message = readMemory(messageData, messageSize);
1463+
1464+
int callId =
1465+
handler.grpcCall(
1466+
upstreamName,
1467+
serviceName,
1468+
methodName,
1469+
initialMetadata,
1470+
message,
1471+
timeout);
1472+
putUint32(returnCalloutID, callId);
1473+
return callId;
1474+
} catch (WasmException e) {
1475+
return e.result().getValue();
1476+
}
1477+
}
1478+
1479+
/**
1480+
* implements https://github.com/proxy-wasm/spec/tree/main/abi-versions/vNEXT#proxy_grpc_stream
1481+
*/
1482+
@WasmExport
1483+
int proxyGrpcStream(
1484+
int upstreamNameData,
1485+
int upstreamNameSize,
1486+
int serviceNameData,
1487+
int serviceNameSize,
1488+
int methodNameData,
1489+
int methodNameSize,
1490+
int serialized_initial_metadataData,
1491+
int serialized_initial_metadataSize,
1492+
int returnStreamId) {
1493+
1494+
try {
1495+
var upstreamName = string(readMemory(upstreamNameData, upstreamNameSize));
1496+
var serviceName = string(readMemory(serviceNameData, serviceNameSize));
1497+
var methodName = string(readMemory(methodNameData, methodNameSize));
1498+
var initialMetadata =
1499+
decodeMap(serialized_initial_metadataData, serialized_initial_metadataSize);
1500+
1501+
int streamId =
1502+
handler.grpcStream(upstreamName, serviceName, methodName, initialMetadata);
1503+
putUint32(returnStreamId, streamId);
1504+
return streamId;
1505+
} catch (WasmException e) {
1506+
return e.result().getValue();
1507+
}
1508+
}
1509+
1510+
/**
1511+
* https://github.com/proxy-wasm/spec/tree/main/abi-versions/vNEXT#proxy_grpc_send
1512+
*/
1513+
@WasmExport
1514+
int proxyGrpcSend(int streamId, int messageData, int messageSize, int endStream) {
1515+
try {
1516+
byte[] message = readMemory(messageData, messageSize);
1517+
WasmResult result = handler.grpcSend(streamId, message, endStream);
1518+
return result.getValue();
1519+
} catch (WasmException e) {
1520+
return e.result().getValue();
1521+
}
1522+
}
1523+
1524+
/**
1525+
* https://github.com/proxy-wasm/spec/tree/main/abi-versions/vNEXT#proxy_grpc_cancel
1526+
*/
1527+
@WasmExport
1528+
int proxyGrpcCancel(int callOrstreamId) {
1529+
WasmResult result = handler.grpcCancel(callOrstreamId);
1530+
return result.getValue();
1531+
}
1532+
1533+
/**
1534+
* https://github.com/proxy-wasm/spec/tree/main/abi-versions/vNEXT#proxy_grpc_close
1535+
*/
1536+
@WasmExport
1537+
int proxyGrpcClose(int callOrstreamId) {
1538+
WasmResult result = handler.grpcClose(callOrstreamId);
1539+
return result.getValue();
1540+
}
14341541

14351542
/**
14361543
* implements https://github.com/proxy-wasm/spec/tree/main/abi-versions/vNEXT#proxy_on_grpc_receive_initial_metadata
@@ -1720,8 +1827,26 @@ int proxyGetProperty(int keyPtr, int keySize, int returnValueData, int returnVal
17201827
}
17211828
}
17221829

1723-
// TODO: implement
1724-
// https://github.com/proxy-wasm/spec/tree/main/abi-versions/vNEXT#proxy_set_property
1830+
/**
1831+
* https://github.com/proxy-wasm/spec/tree/main/abi-versions/vNEXT#proxy_set_property
1832+
*/
1833+
@WasmExport
1834+
int proxySetProperty(int pathDataPtr, int pathSize, int valueDataPtr, int valueSize) {
1835+
try {
1836+
// Get key from memory
1837+
String path = string(readMemory(pathDataPtr, pathSize));
1838+
1839+
// Get value from memory
1840+
String value = string(readMemory(valueDataPtr, valueSize));
1841+
1842+
// Set property value using handler
1843+
WasmResult result = handler.setProperty(path, value);
1844+
return result.getValue();
1845+
1846+
} catch (WasmException e) {
1847+
return e.result().getValue();
1848+
}
1849+
}
17251850

17261851
// //////////////////////////////////////////////////////////////////////
17271852
// Foreign function interface (FFI)

src/main/java/io/roastedroot/proxywasm/ChainedHandler.java

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,4 +318,49 @@ public byte[] dequeueSharedQueue(int queueId) throws WasmException {
318318
public WasmResult enqueueSharedQueue(int queueId, byte[] value) {
319319
return next().enqueueSharedQueue(queueId, value);
320320
}
321+
322+
@Override
323+
public LogLevel getLogLevel() throws WasmException {
324+
return next().getLogLevel();
325+
}
326+
327+
@Override
328+
public WasmResult setProperty(String path, String value) {
329+
return next().setProperty(path, value);
330+
}
331+
332+
@Override
333+
public int grpcCall(
334+
String upstreamName,
335+
String serviceName,
336+
String methodName,
337+
ProxyMap initialMetadata,
338+
byte[] message,
339+
int timeout)
340+
throws WasmException {
341+
return next().grpcCall(
342+
upstreamName, serviceName, methodName, initialMetadata, message, timeout);
343+
}
344+
345+
@Override
346+
public int grpcStream(
347+
String upstreamName, String serviceName, String methodName, ProxyMap initialMetadata)
348+
throws WasmException {
349+
return next().grpcStream(upstreamName, serviceName, methodName, initialMetadata);
350+
}
351+
352+
@Override
353+
public WasmResult grpcSend(int streamId, byte[] message, int endStream) {
354+
return next().grpcSend(streamId, message, endStream);
355+
}
356+
357+
@Override
358+
public WasmResult grpcCancel(int callOrstreamId) {
359+
return next().grpcCancel(callOrstreamId);
360+
}
361+
362+
@Override
363+
public WasmResult grpcClose(int callOrstreamId) {
364+
return next().grpcClose(callOrstreamId);
365+
}
321366
}

src/main/java/io/roastedroot/proxywasm/Handler.java

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@ default String getProperty(String key) throws WasmException {
4949
return null;
5050
}
5151

52+
default WasmResult setProperty(String path, String value) {
53+
return WasmResult.UNIMPLEMENTED;
54+
}
55+
5256
/**
5357
* Get the HTTP request body.
5458
*
@@ -420,6 +424,35 @@ default long getMetric(int metricId) throws WasmException {
420424
throw new WasmException(WasmResult.UNIMPLEMENTED);
421425
}
422426

427+
default int grpcCall(
428+
String upstreamName,
429+
String serviceName,
430+
String methodName,
431+
ProxyMap initialMetadata,
432+
byte[] message,
433+
int timeout)
434+
throws WasmException {
435+
throw new WasmException(WasmResult.UNIMPLEMENTED);
436+
}
437+
438+
default int grpcStream(
439+
String upstreamName, String serviceName, String methodName, ProxyMap initialMetadata)
440+
throws WasmException {
441+
throw new WasmException(WasmResult.UNIMPLEMENTED);
442+
}
443+
444+
default WasmResult grpcSend(int streamId, byte[] message, int endStream) {
445+
return WasmResult.UNIMPLEMENTED;
446+
}
447+
448+
default WasmResult grpcCancel(int callOrstreamId) {
449+
return WasmResult.UNIMPLEMENTED;
450+
}
451+
452+
default WasmResult grpcClose(int callOrstreamId) {
453+
return WasmResult.UNIMPLEMENTED;
454+
}
455+
423456
class SharedData {
424457
public byte[] data;
425458
public int cas;
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package io.roastedroot.proxywasm.examples;
2+
3+
import static org.junit.jupiter.api.Assertions.assertTrue;
4+
5+
import com.dylibso.chicory.wasm.Parser;
6+
import io.roastedroot.proxywasm.ProxyWasm;
7+
import io.roastedroot.proxywasm.StartException;
8+
import java.nio.file.Path;
9+
import org.junit.jupiter.api.Test;
10+
11+
/**
12+
* Test loading https://github.com/proxy-wasm/proxy-wasm-rust-sdk/tree/c8b2335df66a569a6306c58e346dd0cf9dbc0f3a/examples/hello_world
13+
*/
14+
public class RustHelloWorldTest {
15+
16+
@Test
17+
public void pauseUntilEOS() throws StartException {
18+
var handler = new MockHandler();
19+
var module = Parser.parse(Path.of("./src/test/rust-examples/hello_world/main.wasm"));
20+
try (var host = ProxyWasm.builder().withPluginHandler(handler).build(module)) {
21+
22+
handler.assertLogsEqual("Hello, World!");
23+
host.tick();
24+
25+
assertTrue(handler.loggedMessages().get(1).contains("your lucky number is"));
26+
}
27+
}
28+
}

0 commit comments

Comments
 (0)