Line data Source code
1 : #include "source/extensions/bootstrap/wasm/config.h" 2 : 3 : #include "envoy/registry/registry.h" 4 : #include "envoy/server/factory_context.h" 5 : 6 : #include "source/common/common/empty_string.h" 7 : #include "source/common/config/datasource.h" 8 : #include "source/common/protobuf/utility.h" 9 : #include "source/extensions/common/wasm/wasm.h" 10 : 11 : namespace Envoy { 12 : namespace Extensions { 13 : namespace Bootstrap { 14 : namespace Wasm { 15 : 16 0 : void WasmServiceExtension::onServerInitialized() { createWasm(context_); } 17 : 18 0 : void WasmServiceExtension::createWasm(Server::Configuration::ServerFactoryContext& context) { 19 0 : auto plugin = std::make_shared<Common::Wasm::Plugin>( 20 0 : config_.config(), envoy::config::core::v3::TrafficDirection::UNSPECIFIED, context.localInfo(), 21 0 : nullptr); 22 : 23 0 : auto callback = [this, &context, plugin](Common::Wasm::WasmHandleSharedPtr base_wasm) { 24 0 : if (!base_wasm) { 25 0 : if (plugin->fail_open_) { 26 0 : ENVOY_LOG(error, "Unable to create Wasm service {}", plugin->name_); 27 0 : } else { 28 0 : ENVOY_LOG(critical, "Unable to create Wasm service {}", plugin->name_); 29 0 : } 30 0 : return; 31 0 : } 32 0 : if (config_.singleton()) { 33 : // Return a Wasm VM which will be stored as a singleton by the Server. 34 0 : wasm_service_ = std::make_unique<WasmService>( 35 0 : plugin, Common::Wasm::getOrCreateThreadLocalPlugin(base_wasm, plugin, 36 0 : context.mainThreadDispatcher())); 37 0 : return; 38 0 : } 39 : // Per-thread WASM VM. 40 : // NB: the Slot set() call doesn't complete inline, so all arguments must outlive this call. 41 0 : auto tls_slot = 42 0 : ThreadLocal::TypedSlot<Common::Wasm::PluginHandleSharedPtrThreadLocal>::makeUnique( 43 0 : context.threadLocal()); 44 0 : tls_slot->set([base_wasm, plugin](Event::Dispatcher& dispatcher) { 45 0 : return std::make_shared<Common::Wasm::PluginHandleSharedPtrThreadLocal>( 46 0 : Common::Wasm::getOrCreateThreadLocalPlugin(base_wasm, plugin, dispatcher)); 47 0 : }); 48 0 : wasm_service_ = std::make_unique<WasmService>(plugin, std::move(tls_slot)); 49 0 : }; 50 : 51 0 : if (!Common::Wasm::createWasm(plugin, context.scope().createScope(""), context.clusterManager(), 52 0 : context.initManager(), context.mainThreadDispatcher(), 53 0 : context.api(), context.lifecycleNotifier(), remote_data_provider_, 54 0 : std::move(callback))) { 55 : // NB: throw if we get a synchronous configuration failures as this is how such failures are 56 : // reported to xDS. 57 0 : throw Common::Wasm::WasmException( 58 0 : fmt::format("Unable to create Wasm service {}", plugin->name_)); 59 0 : } 60 0 : } 61 : 62 : Server::BootstrapExtensionPtr 63 : WasmFactory::createBootstrapExtension(const Protobuf::Message& config, 64 0 : Server::Configuration::ServerFactoryContext& context) { 65 0 : auto typed_config = 66 0 : MessageUtil::downcastAndValidate<const envoy::extensions::wasm::v3::WasmService&>( 67 0 : config, context.messageValidationContext().staticValidationVisitor()); 68 0 : context.api().customStatNamespaces().registerStatNamespace( 69 0 : Extensions::Common::Wasm::CustomStatNamespace); 70 0 : return std::make_unique<WasmServiceExtension>(typed_config, context); 71 0 : } 72 : 73 : // /** 74 : // * Static registration for the wasm factory. @see RegistryFactory. 75 : // */ 76 : REGISTER_FACTORY(WasmFactory, Server::Configuration::BootstrapExtensionFactory); 77 : 78 : } // namespace Wasm 79 : } // namespace Bootstrap 80 : } // namespace Extensions 81 : } // namespace Envoy