feat: add wasm-rust sdk with say-hello simple extension (#350)

This commit is contained in:
纪卓志
2023-06-19 10:40:53 +08:00
committed by GitHub
parent ea7b581e26
commit 32c2acefda
17 changed files with 1332 additions and 0 deletions

View File

@@ -0,0 +1,112 @@
// Copyright (c) 2023 Alibaba Group Holding Ltd.
//
// 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.
use higress_wasm_rust::log::Log;
use higress_wasm_rust::rule_matcher::RuleMatcher;
use proxy_wasm::traits::{Context, HttpContext, RootContext};
use proxy_wasm::types::{Action, ContextType, LogLevel};
use serde::Deserialize;
use serde_json::{from_slice, Value};
use std::cell::RefCell;
use std::rc::Rc;
proxy_wasm::main! {{
proxy_wasm::set_log_level(LogLevel::Trace);
proxy_wasm::set_root_context(|_|Box::new(SayHelloRoot::new()));
}}
struct SayHelloRoot {
log: Log,
rule_matcher: Rc<RefCell<RuleMatcher<SayHelloConfig>>>,
}
struct SayHello {
rule_matcher: Rc<RefCell<RuleMatcher<SayHelloConfig>>>,
}
#[derive(Default, Debug, Deserialize)]
struct SayHelloConfig {
name: String,
}
impl SayHelloRoot {
fn new() -> Self {
SayHelloRoot {
log: Log::new("say_hello".to_string()),
rule_matcher: Rc::new(RefCell::new(RuleMatcher::default())),
}
}
}
impl Context for SayHelloRoot {}
impl RootContext for SayHelloRoot {
fn on_configure(&mut self, _plugin_configuration_size: usize) -> bool {
let config_buffer = match self.get_plugin_configuration() {
None => {
self.log
.error("Error when configuring RootContext, no configuration supplied");
return false;
}
Some(bytes) => bytes,
};
let value = match from_slice::<Value>(config_buffer.as_slice()) {
Err(error) => {
self.log.error(
format!("cannot parse plugin configuration JSON string: {}", error).as_str(),
);
return false;
}
Ok(value) => value,
};
self.rule_matcher
.borrow_mut()
.parse_rule_config(&value)
.is_ok()
}
fn create_http_context(&self, _context_id: u32) -> Option<Box<dyn HttpContext>> {
Some(Box::new(SayHello {
rule_matcher: self.rule_matcher.clone(),
}))
}
fn get_type(&self) -> Option<ContextType> {
Some(ContextType::HttpContext)
}
}
impl Context for SayHello {}
impl HttpContext for SayHello {
fn on_http_request_headers(&mut self, _num_headers: usize, _end_of_stream: bool) -> Action {
let binding = self.rule_matcher.borrow();
let config = match binding.get_match_config() {
None => {
self.send_http_response(200, vec![], Some("Hello, World!".as_bytes()));
return Action::Continue;
}
Some(config) => config,
};
self.send_http_response(
200,
vec![],
Some(format!("Hello, {}!", config.name).as_bytes()),
);
Action::Continue
}
}