Skip to content

Commit f5f0377

Browse files
committed
Simplify the plugin builder api. Add some javadoc.
Signed-off-by: Hiram Chirino <hiram@hiramchirino.com>
1 parent 2f28113 commit f5f0377

File tree

11 files changed

+229
-81
lines changed

11 files changed

+229
-81
lines changed

proxy-wasm-java-host/src/main/java/io/roastedroot/proxywasm/StartException.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,8 @@ public class StartException extends Exception {
44
public StartException(String message) {
55
super(message);
66
}
7+
8+
public StartException(String message, Throwable cause) {
9+
super(message, cause);
10+
}
711
}

proxy-wasm-java-host/src/main/java/io/roastedroot/proxywasm/plugin/Plugin.java

Lines changed: 178 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import io.roastedroot.proxywasm.WasmException;
3333
import io.roastedroot.proxywasm.WasmResult;
3434
import java.net.URI;
35+
import java.net.URISyntaxException;
3536
import java.util.HashMap;
3637
import java.util.List;
3738
import java.util.Map;
@@ -40,6 +41,9 @@
4041
import java.util.concurrent.locks.ReentrantLock;
4142
import java.util.function.Function;
4243

44+
/**
45+
* Plugin is an instance of a Proxy-Wasm plugin.
46+
*/
4347
public final class Plugin {
4448

4549
private final ReentrantLock lock = new ReentrantLock();
@@ -81,10 +85,6 @@ public String name() {
8185
return name;
8286
}
8387

84-
public static Plugin.Builder builder() {
85-
return new Plugin.Builder();
86-
}
87-
8888
public void lock() {
8989
lock.lock();
9090
}
@@ -135,13 +135,26 @@ public void close() {
135135
}
136136
}
137137

138-
public static class Builder implements Cloneable {
138+
/**
139+
* Creates a new Plugin builder.
140+
*
141+
* @return a new Plugin builder
142+
*/
143+
public static Plugin.Builder builder(WasmModule module) {
144+
return new Plugin.Builder(module);
145+
}
146+
147+
/**
148+
* Builder for creating a Plugin instance.
149+
*/
150+
public static final class Builder {
139151

140-
private ProxyWasm.Builder proxyWasmBuilder = ProxyWasm.builder().withStart(false);
152+
private final WasmModule module;
153+
private final ProxyWasm.Builder proxyWasmBuilder = ProxyWasm.builder().withStart(false);
141154
private boolean shared = true;
142155
private String name;
143156
private HashMap<String, ForeignFunction> foreignFunctions;
144-
private HashMap<String, String> upstreams;
157+
private HashMap<String, URI> upstreams;
145158
private boolean strictUpstreams;
146159
private int minTickPeriodMilliseconds;
147160
private LogHandler logger;
@@ -151,105 +164,230 @@ public static class Builder implements Cloneable {
151164
private SharedQueueHandler sharedQueueHandler;
152165
private SharedDataHandler sharedDataHandler;
153166

167+
/**
168+
* Set the WASM module of the plugin. The module contains the plugin instructions.
169+
*
170+
* @param module the WASM module of the plugin
171+
* @return this builder
172+
*/
173+
private Builder(WasmModule module) {
174+
this.module = module;
175+
}
176+
177+
/**
178+
* Set the name of the plugin.
179+
*
180+
* @param name the name of the plugin
181+
* @return this builder
182+
*/
154183
public Plugin.Builder withName(String name) {
155184
this.name = name;
156185
return this;
157186
}
158187

188+
/**
189+
* Set the foreign functions of that can be called from the plugin.
190+
*
191+
* @param functions the foreign functions of the plugin
192+
* @return this builder
193+
*/
159194
public Builder withForeignFunctions(Map<String, ForeignFunction> functions) {
160195
this.foreignFunctions = new HashMap<>(functions);
161196
return this;
162197
}
163198

164-
public Builder withUpstreams(Map<String, String> upstreams) {
199+
/**
200+
* Set the upstream server URL
201+
*
202+
* @param upstreams the upstream URI mappings. When a http or grpc call is made
203+
* from the plugin, the upstream name is used to lookup the URL.
204+
* @return this builder
205+
*/
206+
public Builder withUpstreams(Map<String, URI> upstreams) {
165207
this.upstreams = new HashMap<>(upstreams);
166208
return this;
167209
}
168210

211+
/**
212+
* Set the strict upstreams mode of the plugin. If strict upstreams is enabled,
213+
* then the plugin will throw an error if an upstream is not found. If disabled,
214+
* then the upstream name is used as the URL.
215+
*
216+
* @param strictUpstreams the strict upstreams of the plugin
217+
* @return this builder
218+
*/
169219
public Builder withStrictUpstreams(boolean strictUpstreams) {
170220
this.strictUpstreams = strictUpstreams;
171221
return this;
172222
}
173223

224+
/**
225+
* Set the minimum tick period of the plugin. A pluign that requests
226+
* a very small tick period will be ticked very frequently. Use this
227+
* to protect the host from being overwhelmed by the plugin.
228+
*
229+
* @param minTickPeriodMilliseconds the minimum tick period of the plugin
230+
* @return this builder
231+
*/
174232
public Builder withMinTickPeriodMilliseconds(int minTickPeriodMilliseconds) {
175233
this.minTickPeriodMilliseconds = minTickPeriodMilliseconds;
176234
return this;
177235
}
178236

237+
/**
238+
* Set the logger of the plugin.
239+
*
240+
* @param logger the logger of the plugin
241+
* @return this builder
242+
*/
179243
public Builder withLogger(LogHandler logger) {
180244
this.logger = logger;
181245
return this;
182246
}
183247

248+
/**
249+
* Set the metrics handler of the plugin. If the metrics handler is not set,
250+
* then calls by the guest to define/use metrics will result in UNIMPLEMENTED errors
251+
* reported to the guest.
252+
*
253+
* @param metricsHandler the metrics handler of the plugin
254+
* @return this builder
255+
*/
184256
public Builder withMetricsHandler(MetricsHandler metricsHandler) {
185257
this.metricsHandler = metricsHandler;
186258
return this;
187259
}
188260

261+
/**
262+
* Set the shared queue handler of the plugin. If the sahred queue handler is not set,
263+
* then calls by the guest to define/use shared queues will result in UNIMPLEMENTED errors
264+
* reported to the guest.
265+
*
266+
* @param sharedQueueHandler the shared queue handler of the plugin
267+
* @return this builder
268+
*/
189269
public Builder withSharedQueueHandler(SharedQueueHandler sharedQueueHandler) {
190270
this.sharedQueueHandler = sharedQueueHandler;
191271
return this;
192272
}
193273

274+
/**
275+
* Set the shared data handler of the plugin. If the shared data handler is not set,
276+
* then calls by the guest to define/use shared data will result in UNIMPLEMENTED errors
277+
* reported to the guest.
278+
*
279+
* @param sharedDataHandler the shared data handler of the plugin
280+
* @return this builder
281+
*/
194282
public Builder withSharedDataHandler(SharedDataHandler sharedDataHandler) {
195283
this.sharedDataHandler = sharedDataHandler;
196284
return this;
197285
}
198286

287+
/**
288+
* Set whether the plugin is shared between host requests. If the plugin is shared,
289+
* then the plugin will be created once and reused for each host request. If the plugin
290+
* is not shared, then a new plugin MAY be use for each concurrent host request.
291+
*
292+
* @param shared whether the plugin is shared
293+
* @return this builder
294+
*/
199295
public Builder withShared(boolean shared) {
200296
this.shared = shared;
201297
return this;
202298
}
203299

300+
/**
301+
* Set the VM config of the plugin.
302+
*
303+
* @param vmConfig the VM config of the plugin
304+
* @return this builder
305+
*/
204306
public Builder withVmConfig(byte[] vmConfig) {
205307
this.vmConfig = vmConfig;
206308
return this;
207309
}
208310

311+
/**
312+
* Set the VM config of the plugin.
313+
*
314+
* @param vmConfig the VM config of the plugin
315+
* @return this builder
316+
*/
209317
public Builder withVmConfig(String vmConfig) {
210318
this.vmConfig = bytes(vmConfig);
211319
return this;
212320
}
213321

322+
/**
323+
* Set the plugin config of the plugin.
324+
*
325+
* @param pluginConfig the plugin config of the plugin
326+
* @return this builder
327+
*/
214328
public Builder withPluginConfig(byte[] pluginConfig) {
215329
this.pluginConfig = pluginConfig;
216330
return this;
217331
}
218332

333+
/**
334+
* Set the plugin config of the plugin.
335+
*
336+
* @param pluginConfig the plugin config of the plugin
337+
* @return this builder
338+
*/
219339
public Builder withPluginConfig(String pluginConfig) {
220340
this.pluginConfig = bytes(pluginConfig);
221341
return this;
222342
}
223343

344+
/**
345+
* Set the import memory of the plugin.
346+
*
347+
* @param memory the import memory of the plugin
348+
* @return this builder
349+
*/
224350
public Builder withImportMemory(ImportMemory memory) {
225-
proxyWasmBuilder = proxyWasmBuilder.withImportMemory(memory);
351+
proxyWasmBuilder.withImportMemory(memory);
226352
return this;
227353
}
228354

355+
/**
356+
* Set the machine factory of the plugin. The machine factory is used to control
357+
* how instructions are executed. By default instructions are executed in a
358+
* by an interpreter. To increase performance, you can use compile the
359+
* was instructions to bytecode at runtime or at build time. For more information
360+
* see https://chicory.dev/docs/experimental/aot
361+
*
362+
* @param machineFactory the machine factory of the plugin
363+
* @return this builder
364+
*/
229365
public Builder withMachineFactory(Function<Instance, Machine> machineFactory) {
230366
proxyWasmBuilder.withMachineFactory(machineFactory);
231367
return this;
232368
}
233369

370+
/**
371+
* Set the WASI options of the plugin. A default WASI enviroment will be provided
372+
* to the pluign. You can use this method to customize the WASI environment,
373+
* for example to provide it access to some file system resources.
374+
*
375+
* @param options the WASI options of the plugin
376+
* @return this builder
377+
*/
234378
public Builder withWasiOptions(WasiOptions options) {
235379
proxyWasmBuilder.withWasiOptions(options);
236380
return this;
237381
}
238382

239-
public Plugin build(WasmModule module) throws StartException {
240-
return build(proxyWasmBuilder.build(module));
241-
}
242-
243-
public Plugin build(Instance.Builder instanceBuilder) throws StartException {
244-
return build(proxyWasmBuilder.build(instanceBuilder));
245-
}
246-
247-
public Plugin build(Instance instance) throws StartException {
248-
return build(proxyWasmBuilder.build(instance));
249-
}
250-
251-
public Plugin build(ProxyWasm proxyWasm) throws StartException {
252-
return new Plugin(this, proxyWasm);
383+
/**
384+
* Build the plugin.
385+
*
386+
* @return the plugin
387+
* @throws StartException if the plugin fails to start
388+
*/
389+
public Plugin build() throws StartException {
390+
return new Plugin(this, proxyWasmBuilder.build(module));
253391
}
254392
}
255393

@@ -260,7 +398,7 @@ public Plugin build(ProxyWasm proxyWasm) throws StartException {
260398
private final AtomicInteger lastCallId = new AtomicInteger(0);
261399
private final HashMap<Integer, Runnable> httpCalls = new HashMap<>();
262400
private final HashMap<Integer, Runnable> grpcCalls = new HashMap<>();
263-
private final HashMap<String, String> upstreams;
401+
private final HashMap<String, URI> upstreams;
264402
boolean strictUpstreams;
265403
int minTickPeriodMilliseconds;
266404
private int tickPeriodMilliseconds;
@@ -406,19 +544,16 @@ public int httpCall(
406544
}
407545
headers.put("Host", authority);
408546

409-
var connectHostPort = upstreams.get(upstreamName);
410-
if (connectHostPort == null && strictUpstreams) {
547+
var connectUri = upstreams.get(upstreamName);
548+
if (connectUri == null && strictUpstreams) {
411549
throw new WasmException(WasmResult.BAD_ARGUMENT);
412550
}
413-
if (connectHostPort == null) {
414-
connectHostPort = authority;
415-
}
416-
417-
URI connectUri = null;
418-
try {
419-
connectUri = URI.create(scheme + "://" + connectHostPort);
420-
} catch (IllegalArgumentException e) {
421-
throw new WasmException(WasmResult.BAD_ARGUMENT);
551+
if (connectUri == null) {
552+
try {
553+
connectUri = new URI(upstreamName);
554+
} catch (URISyntaxException e) {
555+
throw new WasmException(WasmResult.BAD_ARGUMENT);
556+
}
422557
}
423558

424559
var connectHost = connectUri.getHost();
@@ -507,19 +642,17 @@ public int grpcCall(
507642
int timeoutMilliseconds)
508643
throws WasmException {
509644

510-
var connectHostPort = upstreams.get(upstreamName);
511-
if (connectHostPort == null && strictUpstreams) {
645+
var connectUri = upstreams.get(upstreamName);
646+
if (connectUri == null && strictUpstreams) {
512647
throw new WasmException(WasmResult.BAD_ARGUMENT);
513648
}
514-
if (connectHostPort == null) {
515-
connectHostPort = upstreamName;
516-
}
517649

518-
URI connectUri = null;
519-
try {
520-
connectUri = URI.create(connectHostPort);
521-
} catch (IllegalArgumentException e) {
522-
throw new WasmException(WasmResult.BAD_ARGUMENT);
650+
if (connectUri == null) {
651+
try {
652+
connectUri = new URI(upstreamName);
653+
} catch (URISyntaxException e) {
654+
throw new WasmException(WasmResult.BAD_ARGUMENT);
655+
}
523656
}
524657

525658
if (!("http".equals(connectUri.getScheme())
Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
package io.roastedroot.proxywasm.plugin;
22

3-
import io.roastedroot.proxywasm.StartException;
4-
53
public interface PluginFactory {
6-
Plugin create() throws StartException;
4+
Plugin create() throws Exception;
75
}

0 commit comments

Comments
 (0)