plugins/experimental/wasm/lib/include/proxy-wasm/wasm_api_impl.h (223 lines of code) (raw):
// Copyright 2016-2019 Envoy Project Authors
// Copyright 2020 Google LLC
//
// Licensed 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.
#pragma once
// Required by "proxy_wasm_api.h" included within null_plugin namespace.
#ifdef PROXY_WASM_PROTOBUF
#include "google/protobuf/message_lite.h"
#endif
#include <cstring>
#include <functional>
#include <memory>
#include <string>
#include <tuple>
#include <unordered_map>
#include <utility>
#include <vector>
#include "include/proxy-wasm/exports.h"
#include "include/proxy-wasm/word.h"
namespace proxy_wasm {
namespace null_plugin {
#include "proxy_wasm_enums.h"
#include "proxy_wasm_common.h"
#define WS(_x) Word(static_cast<uint64_t>(_x))
#define WR(_x) Word(reinterpret_cast<uint64_t>(_x))
inline WasmResult wordToWasmResult(Word w) { return static_cast<WasmResult>(w.u64_); }
// Configuration and Status
inline WasmResult proxy_get_configuration(const char **configuration_ptr,
size_t *configuration_size) {
return wordToWasmResult(
exports::get_configuration(WR(configuration_ptr), WR(configuration_size)));
}
inline WasmResult proxy_get_status(uint32_t *code_ptr, const char **ptr, size_t *size) {
return wordToWasmResult(exports::get_status(WR(code_ptr), WR(ptr), WR(size)));
}
// Logging
inline WasmResult proxy_log(LogLevel level, const char *logMessage, size_t messageSize) {
return wordToWasmResult(exports::log(WS(level), WR(logMessage), WS(messageSize)));
}
inline WasmResult proxy_get_log_level(LogLevel *level) {
return wordToWasmResult(exports::get_log_level(WR(level)));
}
// Timer
inline WasmResult proxy_set_tick_period_milliseconds(uint64_t millisecond) {
return wordToWasmResult(exports::set_tick_period_milliseconds(Word(millisecond)));
}
inline WasmResult proxy_get_current_time_nanoseconds(uint64_t *result) {
return wordToWasmResult(exports::get_current_time_nanoseconds(WR(result)));
}
// State accessors
inline WasmResult proxy_get_property(const char *path_ptr, size_t path_size,
const char **value_ptr_ptr, size_t *value_size_ptr) {
return wordToWasmResult(
exports::get_property(WR(path_ptr), WS(path_size), WR(value_ptr_ptr), WR(value_size_ptr)));
}
inline WasmResult proxy_set_property(const char *key_ptr, size_t key_size, const char *value_ptr,
size_t value_size) {
return wordToWasmResult(
exports::set_property(WR(key_ptr), WS(key_size), WR(value_ptr), WS(value_size)));
}
// Continue
inline WasmResult proxy_continue_request() { return wordToWasmResult(exports::continue_request()); }
inline WasmResult proxy_continue_response() {
return wordToWasmResult(exports::continue_response());
}
inline WasmResult proxy_continue_stream(WasmStreamType stream_type) {
return wordToWasmResult(exports::continue_stream(WS(stream_type)));
}
inline WasmResult proxy_close_stream(WasmStreamType stream_type) {
return wordToWasmResult(exports::close_stream(WS(stream_type)));
}
inline WasmResult
proxy_send_local_response(uint32_t response_code, const char *response_code_details_ptr,
size_t response_code_details_size, const char *body_ptr, size_t body_size,
const char *additional_response_header_pairs_ptr,
size_t additional_response_header_pairs_size, uint32_t grpc_status) {
return wordToWasmResult(exports::send_local_response(
WS(response_code), WR(response_code_details_ptr), WS(response_code_details_size),
WR(body_ptr), WS(body_size), WR(additional_response_header_pairs_ptr),
WS(additional_response_header_pairs_size), WS(grpc_status)));
}
inline WasmResult proxy_clear_route_cache() {
return wordToWasmResult(exports::clear_route_cache());
}
// SharedData
inline WasmResult proxy_get_shared_data(const char *key_ptr, size_t key_size,
const char **value_ptr, size_t *value_size, uint32_t *cas) {
return wordToWasmResult(
exports::get_shared_data(WR(key_ptr), WS(key_size), WR(value_ptr), WR(value_size), WR(cas)));
}
// If cas != 0 and cas != the current cas for 'key' return false, otherwise set the value and
// return true.
inline WasmResult proxy_set_shared_data(const char *key_ptr, size_t key_size, const char *value_ptr,
size_t value_size, uint64_t cas) {
return wordToWasmResult(
exports::set_shared_data(WR(key_ptr), WS(key_size), WR(value_ptr), WS(value_size), WS(cas)));
}
// SharedQueue
// Note: Registering the same queue_name will overwrite the old registration while preseving any
// pending data. Consequently it should typically be followed by a call to
// proxy_dequeue_shared_queue. Returns unique token for the queue.
inline WasmResult proxy_register_shared_queue(const char *queue_name_ptr, size_t queue_name_size,
uint32_t *token) {
return wordToWasmResult(
exports::register_shared_queue(WR(queue_name_ptr), WS(queue_name_size), WR(token)));
}
// Returns unique token for the queue.
inline WasmResult proxy_resolve_shared_queue(const char *vm_id_ptr, size_t vm_id_size,
const char *queue_name_ptr, size_t queue_name_size,
uint32_t *token) {
return wordToWasmResult(exports::resolve_shared_queue(
WR(vm_id_ptr), WS(vm_id_size), WR(queue_name_ptr), WS(queue_name_size), WR(token)));
}
// Returns true on end-of-stream (no more data available).
inline WasmResult proxy_dequeue_shared_queue(uint32_t token, const char **data_ptr,
size_t *data_size) {
return wordToWasmResult(exports::dequeue_shared_queue(WS(token), WR(data_ptr), WR(data_size)));
}
// Returns false if the queue was not found and the data was not enqueued.
inline WasmResult proxy_enqueue_shared_queue(uint32_t token, const char *data_ptr,
size_t data_size) {
return wordToWasmResult(exports::enqueue_shared_queue(WS(token), WR(data_ptr), WS(data_size)));
}
// Buffer
inline WasmResult proxy_get_buffer_bytes(WasmBufferType type, uint64_t start, uint64_t length,
const char **ptr, size_t *size) {
return wordToWasmResult(
exports::get_buffer_bytes(WS(type), WS(start), WS(length), WR(ptr), WR(size)));
}
inline WasmResult proxy_get_buffer_status(WasmBufferType type, size_t *length_ptr,
uint32_t *flags_ptr) {
return wordToWasmResult(exports::get_buffer_status(WS(type), WR(length_ptr), WR(flags_ptr)));
}
inline WasmResult proxy_set_buffer_bytes(WasmBufferType type, uint64_t start, uint64_t length,
const char *data, size_t size) {
return wordToWasmResult(
exports::set_buffer_bytes(WS(type), WS(start), WS(length), WR(data), WS(size)));
}
// Headers/Trailers/Metadata Maps
inline WasmResult proxy_add_header_map_value(WasmHeaderMapType type, const char *key_ptr,
size_t key_size, const char *value_ptr,
size_t value_size) {
return wordToWasmResult(exports::add_header_map_value(WS(type), WR(key_ptr), WS(key_size),
WR(value_ptr), WS(value_size)));
}
inline WasmResult proxy_get_header_map_value(WasmHeaderMapType type, const char *key_ptr,
size_t key_size, const char **value_ptr,
size_t *value_size) {
return wordToWasmResult(exports::get_header_map_value(WS(type), WR(key_ptr), WS(key_size),
WR(value_ptr), WR(value_size)));
}
inline WasmResult proxy_get_header_map_pairs(WasmHeaderMapType type, const char **ptr,
size_t *size) {
return wordToWasmResult(exports::get_header_map_pairs(WS(type), WR(ptr), WR(size)));
}
inline WasmResult proxy_set_header_map_pairs(WasmHeaderMapType type, const char *ptr, size_t size) {
return wordToWasmResult(exports::set_header_map_pairs(WS(type), WR(ptr), WS(size)));
}
inline WasmResult proxy_replace_header_map_value(WasmHeaderMapType type, const char *key_ptr,
size_t key_size, const char *value_ptr,
size_t value_size) {
return wordToWasmResult(exports::replace_header_map_value(WS(type), WR(key_ptr), WS(key_size),
WR(value_ptr), WS(value_size)));
}
inline WasmResult proxy_remove_header_map_value(WasmHeaderMapType type, const char *key_ptr,
size_t key_size) {
return wordToWasmResult(exports::remove_header_map_value(WS(type), WR(key_ptr), WS(key_size)));
}
inline WasmResult proxy_get_header_map_size(WasmHeaderMapType type, size_t *size) {
return wordToWasmResult(exports::get_header_map_size(WS(type), WR(size)));
}
// HTTP
// Returns token, used in callback onHttpCallResponse
inline WasmResult proxy_http_call(const char *uri_ptr, size_t uri_size, void *header_pairs_ptr,
size_t header_pairs_size, const char *body_ptr, size_t body_size,
void *trailer_pairs_ptr, size_t trailer_pairs_size,
uint64_t timeout_milliseconds, uint32_t *token_ptr) {
return wordToWasmResult(exports::http_call(WR(uri_ptr), WS(uri_size), WR(header_pairs_ptr),
WS(header_pairs_size), WR(body_ptr), WS(body_size),
WR(trailer_pairs_ptr), WS(trailer_pairs_size),
WS(timeout_milliseconds), WR(token_ptr)));
}
// gRPC
// Returns token, used in gRPC callbacks (onGrpc...)
inline WasmResult proxy_grpc_call(const char *service_ptr, size_t service_size,
const char *service_name_ptr, size_t service_name_size,
const char *method_name_ptr, size_t method_name_size,
void *initial_metadata_ptr, size_t initial_metadata_size,
const char *request_ptr, size_t request_size,
uint64_t timeout_milliseconds, uint32_t *token_ptr) {
return wordToWasmResult(
exports::grpc_call(WR(service_ptr), WS(service_size), WR(service_name_ptr),
WS(service_name_size), WR(method_name_ptr), WS(method_name_size),
WR(initial_metadata_ptr), WS(initial_metadata_size), WR(request_ptr),
WS(request_size), WS(timeout_milliseconds), WR(token_ptr)));
}
inline WasmResult proxy_grpc_stream(const char *service_ptr, size_t service_size,
const char *service_name_ptr, size_t service_name_size,
const char *method_name_ptr, size_t method_name_size,
void *initial_metadata_ptr, size_t initial_metadata_size,
uint32_t *token_ptr) {
return wordToWasmResult(
exports::grpc_stream(WR(service_ptr), WS(service_size), WR(service_name_ptr),
WS(service_name_size), WR(method_name_ptr), WS(method_name_size),
WR(initial_metadata_ptr), WS(initial_metadata_size), WR(token_ptr)));
}
inline WasmResult proxy_grpc_cancel(uint64_t token) {
return wordToWasmResult(exports::grpc_cancel(WS(token)));
}
inline WasmResult proxy_grpc_close(uint64_t token) {
return wordToWasmResult(exports::grpc_close(WS(token)));
}
inline WasmResult proxy_grpc_send(uint64_t token, const char *message_ptr, size_t message_size,
uint64_t end_stream) {
return wordToWasmResult(
exports::grpc_send(WS(token), WR(message_ptr), WS(message_size), WS(end_stream)));
}
// Metrics
// Returns a metric_id which can be used to report a metric. On error returns 0.
inline WasmResult proxy_define_metric(MetricType type, const char *name_ptr, size_t name_size,
uint32_t *metric_id) {
return wordToWasmResult(
exports::define_metric(WS(type), WR(name_ptr), WS(name_size), WR(metric_id)));
}
inline WasmResult proxy_increment_metric(uint32_t metric_id, int64_t offset) {
return wordToWasmResult(exports::increment_metric(WS(metric_id), offset));
}
inline WasmResult proxy_record_metric(uint32_t metric_id, uint64_t value) {
return wordToWasmResult(exports::record_metric(WS(metric_id), value));
}
inline WasmResult proxy_get_metric(uint32_t metric_id, uint64_t *value) {
return wordToWasmResult(exports::get_metric(WS(metric_id), WR(value)));
}
// System
inline WasmResult proxy_set_effective_context(uint64_t context_id) {
return wordToWasmResult(exports::set_effective_context(WS(context_id)));
}
inline WasmResult proxy_done() { return wordToWasmResult(exports::done()); }
inline WasmResult proxy_call_foreign_function(const char *function_name, size_t function_name_size,
const char *arguments, size_t arguments_size,
char **results, size_t *results_size) {
return wordToWasmResult(exports::call_foreign_function(WR(function_name), WS(function_name_size),
WR(arguments), WS(arguments_size),
WR(results), WR(results_size)));
}
#undef WS
#undef WR
#include "proxy_wasm_api.h"
RootContext *getRoot(std::string_view root_id);
Context *getContext(uint32_t context_id);
} // namespace null_plugin
} // namespace proxy_wasm