diff --git a/mobile/bazel/envoy_mobile_dependencies.bzl b/mobile/bazel/envoy_mobile_dependencies.bzl index 031e9b3cfaaf..40a142559dcc 100644 --- a/mobile/bazel/envoy_mobile_dependencies.bzl +++ b/mobile/bazel/envoy_mobile_dependencies.bzl @@ -60,6 +60,8 @@ def kotlin_dependencies(extra_maven_dependencies = []): maven_install( artifacts = [ "com.google.code.findbugs:jsr305:3.0.2", + # Java Proto Lite + "com.google.protobuf:protobuf-javalite:3.24.4", # Kotlin "org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.6.21", "org.jetbrains.kotlin:kotlin-stdlib-common:1.6.21", diff --git a/mobile/library/cc/BUILD b/mobile/library/cc/BUILD index ff53c0ae5576..6caf1455aa2e 100644 --- a/mobile/library/cc/BUILD +++ b/mobile/library/cc/BUILD @@ -22,6 +22,7 @@ envoy_cc_library( deps = [ ":envoy_engine_cc_lib_no_stamp", "@envoy//source/common/common:assert_lib", + "@envoy//source/common/protobuf", "@envoy_api//envoy/config/bootstrap/v3:pkg_cc_proto", "@envoy_api//envoy/config/metrics/v3:pkg_cc_proto", "@envoy_api//envoy/extensions/compression/brotli/decompressor/v3:pkg_cc_proto", diff --git a/mobile/library/cc/engine_builder.cc b/mobile/library/cc/engine_builder.cc index 32b755af28c4..c410f3951c09 100644 --- a/mobile/library/cc/engine_builder.cc +++ b/mobile/library/cc/engine_builder.cc @@ -346,6 +346,11 @@ EngineBuilder& EngineBuilder::setNodeLocality(std::string region, std::string zo return *this; } +EngineBuilder& EngineBuilder::setNodeMetadata(ProtobufWkt::Struct node_metadata) { + node_metadata_ = std::move(node_metadata); + return *this; +} + #ifdef ENVOY_GOOGLE_GRPC EngineBuilder& EngineBuilder::setXds(XdsBuilder xds_builder) { xds_builder_ = std::move(xds_builder); @@ -873,6 +878,9 @@ std::unique_ptr EngineBuilder::generate node->mutable_locality()->set_sub_zone(node_locality_->sub_zone); } ProtobufWkt::Struct& metadata = *node->mutable_metadata(); + if (node_metadata_.has_value()) { + *node->mutable_metadata() = *node_metadata_; + } (*metadata.mutable_fields())["app_id"].set_string_value(app_id_); (*metadata.mutable_fields())["app_version"].set_string_value(app_version_); (*metadata.mutable_fields())["device_os"].set_string_value(device_os_); diff --git a/mobile/library/cc/engine_builder.h b/mobile/library/cc/engine_builder.h index 20fbb9978f06..e51aa730f085 100644 --- a/mobile/library/cc/engine_builder.h +++ b/mobile/library/cc/engine_builder.h @@ -7,6 +7,8 @@ #include "envoy/config/bootstrap/v3/bootstrap.pb.h" +#include "source/common/protobuf/protobuf.h" + #include "absl/container/flat_hash_map.h" #include "absl/types/optional.h" #include "direct_response_testing.h" @@ -182,6 +184,8 @@ class EngineBuilder { EngineBuilder& setNodeId(std::string node_id); // Sets the node.locality field in the Bootstrap configuration. EngineBuilder& setNodeLocality(std::string region, std::string zone, std::string sub_zone); + // Sets the node.metadata field in the Bootstrap configuration. + EngineBuilder& setNodeMetadata(ProtobufWkt::Struct node_metadata); #ifdef ENVOY_GOOGLE_GRPC // Sets the xDS configuration for the Envoy Mobile engine. // @@ -244,6 +248,7 @@ class EngineBuilder { bool platform_certificates_validation_on_ = false; std::string node_id_; absl::optional node_locality_ = absl::nullopt; + absl::optional node_metadata_ = absl::nullopt; bool dns_cache_on_ = false; int dns_cache_save_interval_seconds_ = 1; diff --git a/mobile/library/common/jni/BUILD b/mobile/library/common/jni/BUILD index b28b52f2c0ee..6dfa3a14842a 100644 --- a/mobile/library/common/jni/BUILD +++ b/mobile/library/common/jni/BUILD @@ -43,6 +43,7 @@ cc_library( "//library/common/types:managed_types_lib", "//library/common/types:matcher_data_lib", "@envoy//source/common/common:assert_lib", + "@envoy//source/common/protobuf", ], ) @@ -68,6 +69,7 @@ cc_library( "//library/common/jni/types:jni_exception_lib", "//library/common/jni/types:jni_javavm_lib", "//library/common/types:managed_types_lib", + "@envoy//source/common/protobuf", ], # We need this to ensure that we link this into the .so even though there are no code references. alwayslink = True, diff --git a/mobile/library/common/jni/jni_interface.cc b/mobile/library/common/jni/jni_interface.cc index 6f8e2ce03f92..5acf15822514 100644 --- a/mobile/library/common/jni/jni_interface.cc +++ b/mobile/library/common/jni/jni_interface.cc @@ -2,6 +2,8 @@ #include #include +#include "source/common/protobuf/protobuf.h" + #include "library/cc/engine_builder.h" #include "library/common/api/c_types.h" #include "library/common/data/utility.h" @@ -1219,7 +1221,7 @@ void configureBuilder(JNIEnv* env, jstring grpc_stats_domain, jlong connect_time jboolean trust_chain_verification, jobjectArray filter_chain, jobjectArray stat_sinks, jboolean enable_platform_certificates_validation, jobjectArray runtime_guards, jstring node_id, jstring node_region, - jstring node_zone, jstring node_sub_zone, + jstring node_zone, jstring node_sub_zone, jbyteArray serialized_node_metadata, Envoy::Platform::EngineBuilder& builder) { builder.addConnectTimeoutSeconds((connect_timeout_seconds)); builder.addDnsRefreshSeconds((dns_refresh_seconds)); @@ -1286,6 +1288,9 @@ void configureBuilder(JNIEnv* env, jstring grpc_stats_domain, jlong connect_time builder.setNodeLocality(native_node_region, getCppString(env, node_zone), getCppString(env, node_sub_zone)); } + Envoy::ProtobufWkt::Struct node_metadata; + javaByteArrayToProto(env, serialized_node_metadata, &node_metadata); + builder.setNodeMetadata(node_metadata); } extern "C" JNIEXPORT jlong JNICALL Java_io_envoyproxy_envoymobile_engine_JniLibrary_createBootstrap( @@ -1307,22 +1312,24 @@ extern "C" JNIEXPORT jlong JNICALL Java_io_envoyproxy_envoymobile_engine_JniLibr jstring rtds_resource_name, jlong rtds_timeout_seconds, jstring xds_address, jlong xds_port, jstring xds_auth_header, jstring xds_auth_token, jstring xds_jwt_token, jlong xds_jwt_token_lifetime, jstring xds_root_certs, jstring xds_sni, jstring node_id, - jstring node_region, jstring node_zone, jstring node_sub_zone, jstring cds_resources_locator, - jlong cds_timeout_seconds, jboolean enable_cds) { + jstring node_region, jstring node_zone, jstring node_sub_zone, + jbyteArray serialized_node_metadata, jstring cds_resources_locator, jlong cds_timeout_seconds, + jboolean enable_cds) { Envoy::Platform::EngineBuilder builder; - configureBuilder( - env, grpc_stats_domain, connect_timeout_seconds, dns_refresh_seconds, - dns_failure_refresh_seconds_base, dns_failure_refresh_seconds_max, dns_query_timeout_seconds, - dns_min_refresh_seconds, dns_preresolve_hostnames, enable_dns_cache, - dns_cache_save_interval_seconds, enable_drain_post_dns_refresh, enable_http3, - http3_connection_options, http3_client_connection_options, quic_hints, - enable_gzip_decompression, enable_brotli_decompression, enable_socket_tagging, - enable_interface_binding, h2_connection_keepalive_idle_interval_milliseconds, - h2_connection_keepalive_timeout_seconds, max_connections_per_host, stats_flush_seconds, - stream_idle_timeout_seconds, per_try_idle_timeout_seconds, app_version, app_id, - trust_chain_verification, filter_chain, stat_sinks, enable_platform_certificates_validation, - runtime_guards, node_id, node_region, node_zone, node_sub_zone, builder); + configureBuilder(env, grpc_stats_domain, connect_timeout_seconds, dns_refresh_seconds, + dns_failure_refresh_seconds_base, dns_failure_refresh_seconds_max, + dns_query_timeout_seconds, dns_min_refresh_seconds, dns_preresolve_hostnames, + enable_dns_cache, dns_cache_save_interval_seconds, enable_drain_post_dns_refresh, + enable_http3, http3_connection_options, http3_client_connection_options, + quic_hints, enable_gzip_decompression, enable_brotli_decompression, + enable_socket_tagging, enable_interface_binding, + h2_connection_keepalive_idle_interval_milliseconds, + h2_connection_keepalive_timeout_seconds, max_connections_per_host, + stats_flush_seconds, stream_idle_timeout_seconds, per_try_idle_timeout_seconds, + app_version, app_id, trust_chain_verification, filter_chain, stat_sinks, + enable_platform_certificates_validation, runtime_guards, node_id, node_region, + node_zone, node_sub_zone, serialized_node_metadata, builder); #ifdef ENVOY_GOOGLE_GRPC std::string native_xds_address = getCppString(env, xds_address); diff --git a/mobile/library/common/jni/jni_utility.cc b/mobile/library/common/jni/jni_utility.cc index 1f90de4dd3dc..fae87ed70aff 100644 --- a/mobile/library/common/jni/jni_utility.cc +++ b/mobile/library/common/jni/jni_utility.cc @@ -385,6 +385,13 @@ std::vector javaObjectArrayToMatcherData(JNIEnv* env, jobjectArray return ret; } +void javaByteArrayToProto(JNIEnv* env, jbyteArray source, Envoy::Protobuf::MessageLite* dest) { + jbyte* bytes = env->GetByteArrayElements(source, /* isCopy= */ nullptr); + jsize size = env->GetArrayLength(source); + ASSERT(dest->ParseFromArray(bytes, size)); + env->ReleaseByteArrayElements(source, bytes, 0); +} + #define DEFINE_CALL_METHOD(JAVA_TYPE, JNI_TYPE) \ JNI_TYPE call##JAVA_TYPE##Method(JNIEnv* env, jobject object, jmethodID method_id, ...) { \ va_list args; \ diff --git a/mobile/library/common/jni/jni_utility.h b/mobile/library/common/jni/jni_utility.h index 14ce777e7f4d..e0628dcdc83f 100644 --- a/mobile/library/common/jni/jni_utility.h +++ b/mobile/library/common/jni/jni_utility.h @@ -3,6 +3,8 @@ #include #include +#include "source/common/protobuf/protobuf.h" + #include "library/common/jni/import/jni_import.h" #include "library/common/types/c_types.h" #include "library/common/types/managed_envoy_headers.h" @@ -119,6 +121,9 @@ void JavaArrayOfByteToString(JNIEnv* env, jbyteArray jbytes, std::string* out); std::vector javaObjectArrayToMatcherData(JNIEnv* env, jobjectArray array, std::string& cluster_out); +/** Parses the proto from Java's byte array and stores the output into `dest` proto. */ +void javaByteArrayToProto(JNIEnv* env, jbyteArray source, Envoy::Protobuf::MessageLite* dest); + // Helper functions for JNI's `CallMethod` with proper exception handling in order to satisfy // -Xcheck:jni. // See diff --git a/mobile/library/java/io/envoyproxy/envoymobile/engine/BUILD b/mobile/library/java/io/envoyproxy/envoymobile/engine/BUILD index c23318d4c075..b638e6deea9d 100644 --- a/mobile/library/java/io/envoyproxy/envoymobile/engine/BUILD +++ b/mobile/library/java/io/envoyproxy/envoymobile/engine/BUILD @@ -52,6 +52,7 @@ java_library( deps = [ "//library/java/io/envoyproxy/envoymobile/engine/types:envoy_c_types_lib", "@maven//:com_google_code_findbugs_jsr305", + "@maven//:com_google_protobuf_protobuf_javalite", ], ) diff --git a/mobile/library/java/io/envoyproxy/envoymobile/engine/EnvoyConfiguration.java b/mobile/library/java/io/envoyproxy/envoymobile/engine/EnvoyConfiguration.java index 520f08f95f38..ac03d3184406 100644 --- a/mobile/library/java/io/envoyproxy/envoymobile/engine/EnvoyConfiguration.java +++ b/mobile/library/java/io/envoyproxy/envoymobile/engine/EnvoyConfiguration.java @@ -1,19 +1,16 @@ package io.envoyproxy.envoymobile.engine; +import com.google.protobuf.Struct; import java.util.Collections; import java.util.List; import java.util.ArrayList; import java.util.Map; import java.util.HashMap; import java.util.regex.Pattern; -import java.util.regex.Matcher; -import java.lang.StringBuilder; -import javax.annotation.Nullable; import io.envoyproxy.envoymobile.engine.types.EnvoyHTTPFilterFactory; import io.envoyproxy.envoymobile.engine.types.EnvoyStringAccessor; import io.envoyproxy.envoymobile.engine.types.EnvoyKeyValueStore; -import io.envoyproxy.envoymobile.engine.JniLibrary; /* Typed configuration that may be used for starting Envoy. */ public class EnvoyConfiguration { @@ -77,6 +74,7 @@ public enum TrustChainVerification { public final String nodeRegion; public final String nodeZone; public final String nodeSubZone; + public final Struct nodeMetadata; public final String cdsResourcesLocator; public final Integer cdsTimeoutSeconds; public final Boolean enableCds; @@ -151,7 +149,7 @@ public enum TrustChainVerification { * xDS server. * @param xdsJwtToken the JWT token to use for authenticating * with the xDS server. - * @param xdsTokenLifetime the lifetime of the JWT token. + * @param xdsJwtTokenLifetime the lifetime of the JWT token. * @param xdsRootCerts the root certificates to use for the TLS * handshake during connection establishment * with the xDS management server. @@ -161,6 +159,7 @@ public enum TrustChainVerification { * @param nodeRegion the node region in the Node metadata. * @param nodeZone the node zone in the Node metadata. * @param nodeSubZone the node sub-zone in the Node metadata. + * @param nodeMetadata the node metadata. * @param cdsResourcesLocator the resources locator for CDS. * @param cdsTimeoutSeconds the timeout for CDS fetches. * @param enableCds enables CDS, used because all CDS params @@ -186,8 +185,8 @@ public EnvoyConfiguration( String rtdsResourceName, Integer rtdsTimeoutSeconds, String xdsAddress, Integer xdsPort, String xdsAuthHeader, String xdsAuthToken, String xdsJwtToken, Integer xdsJwtTokenLifetime, String xdsRootCerts, String xdsSni, String nodeId, String nodeRegion, String nodeZone, - String nodeSubZone, String cdsResourcesLocator, Integer cdsTimeoutSeconds, - boolean enableCds) { + String nodeSubZone, Struct nodeMetadata, String cdsResourcesLocator, + Integer cdsTimeoutSeconds, boolean enableCds) { JniLibrary.load(); this.grpcStatsDomain = grpcStatsDomain; this.connectTimeoutSeconds = connectTimeoutSeconds; @@ -257,6 +256,7 @@ public EnvoyConfiguration( this.nodeRegion = nodeRegion; this.nodeZone = nodeZone; this.nodeSubZone = nodeSubZone; + this.nodeMetadata = nodeMetadata; this.cdsResourcesLocator = cdsResourcesLocator; this.cdsTimeoutSeconds = cdsTimeoutSeconds; this.enableCds = enableCds; @@ -268,25 +268,25 @@ public long createBootstrap() { List reverseFilterChain = new ArrayList<>(nativeFilterChain); Collections.reverse(reverseFilterChain); - byte[][] filter_chain = JniBridgeUtility.toJniBytes(reverseFilterChain); - byte[][] stats_sinks = JniBridgeUtility.stringsToJniBytes(statSinks); - byte[][] dns_preresolve = JniBridgeUtility.stringsToJniBytes(dnsPreresolveHostnames); - byte[][] runtime_guards = JniBridgeUtility.mapToJniBytes(runtimeGuards); - byte[][] quic_hints = JniBridgeUtility.mapToJniBytes(quicHints); + byte[][] filterChain = JniBridgeUtility.toJniBytes(reverseFilterChain); + byte[][] statsSinks = JniBridgeUtility.stringsToJniBytes(statSinks); + byte[][] dnsPreresolve = JniBridgeUtility.stringsToJniBytes(dnsPreresolveHostnames); + byte[][] runtimeGuards = JniBridgeUtility.mapToJniBytes(this.runtimeGuards); + byte[][] quicHints = JniBridgeUtility.mapToJniBytes(this.quicHints); return JniLibrary.createBootstrap( grpcStatsDomain, connectTimeoutSeconds, dnsRefreshSeconds, dnsFailureRefreshSecondsBase, - dnsFailureRefreshSecondsMax, dnsQueryTimeoutSeconds, dnsMinRefreshSeconds, dns_preresolve, + dnsFailureRefreshSecondsMax, dnsQueryTimeoutSeconds, dnsMinRefreshSeconds, dnsPreresolve, enableDNSCache, dnsCacheSaveIntervalSeconds, enableDrainPostDnsRefresh, enableHttp3, - http3ConnectionOptions, http3ClientConnectionOptions, quic_hints, enableGzipDecompression, + http3ConnectionOptions, http3ClientConnectionOptions, quicHints, enableGzipDecompression, enableBrotliDecompression, enableSocketTagging, enableInterfaceBinding, h2ConnectionKeepaliveIdleIntervalMilliseconds, h2ConnectionKeepaliveTimeoutSeconds, maxConnectionsPerHost, statsFlushSeconds, streamIdleTimeoutSeconds, - perTryIdleTimeoutSeconds, appVersion, appId, enforceTrustChainVerification, filter_chain, - stats_sinks, enablePlatformCertificatesValidation, runtime_guards, rtdsResourceName, + perTryIdleTimeoutSeconds, appVersion, appId, enforceTrustChainVerification, filterChain, + statsSinks, enablePlatformCertificatesValidation, runtimeGuards, rtdsResourceName, rtdsTimeoutSeconds, xdsAddress, xdsPort, xdsAuthHeader, xdsAuthToken, xdsJwtToken, xdsJwtTokenLifetime, xdsRootCerts, xdsSni, nodeId, nodeRegion, nodeZone, nodeSubZone, - cdsResourcesLocator, cdsTimeoutSeconds, enableCds); + nodeMetadata.toByteArray(), cdsResourcesLocator, cdsTimeoutSeconds, enableCds); } static class ConfigurationException extends RuntimeException { diff --git a/mobile/library/java/io/envoyproxy/envoymobile/engine/JniLibrary.java b/mobile/library/java/io/envoyproxy/envoymobile/engine/JniLibrary.java index 4bda63f72edc..5535346c5bb3 100644 --- a/mobile/library/java/io/envoyproxy/envoymobile/engine/JniLibrary.java +++ b/mobile/library/java/io/envoyproxy/envoymobile/engine/JniLibrary.java @@ -3,7 +3,6 @@ import io.envoyproxy.envoymobile.engine.types.EnvoyEventTracker; import io.envoyproxy.envoymobile.engine.types.EnvoyLogger; import io.envoyproxy.envoymobile.engine.types.EnvoyOnEngineRunning; - import java.nio.ByteBuffer; public class JniLibrary { @@ -322,5 +321,6 @@ public static native long createBootstrap( long rtdsTimeoutSeconds, String xdsAddress, long xdsPort, String xdsAuthenticationHeader, String xdsAuthenticationToken, String xdsJwtToken, long xdsJwtTokenLifetime, String xdsRootCerts, String xdsSni, String nodeId, String nodeRegion, String nodeZone, - String nodeSubZone, String cdsResourcesLocator, long cdsTimeoutSeconds, boolean enableCds); + String nodeSubZone, byte[] nodeMetadata, String cdsResourcesLocator, long cdsTimeoutSeconds, + boolean enableCds); } diff --git a/mobile/library/java/org/chromium/net/impl/BUILD b/mobile/library/java/org/chromium/net/impl/BUILD index 1bde5cf9677d..5a3fbfe704fc 100644 --- a/mobile/library/java/org/chromium/net/impl/BUILD +++ b/mobile/library/java/org/chromium/net/impl/BUILD @@ -51,6 +51,7 @@ android_library( "//library/java/io/envoyproxy/envoymobile/utilities", "//library/java/org/chromium/net", "//library/java/org/chromium/net/urlconnection", + "@maven//:com_google_protobuf_protobuf_javalite", artifact("androidx.annotation:annotation"), ], ) diff --git a/mobile/library/java/org/chromium/net/impl/NativeCronvoyEngineBuilderImpl.java b/mobile/library/java/org/chromium/net/impl/NativeCronvoyEngineBuilderImpl.java index 68943535c077..2d45070f23e5 100644 --- a/mobile/library/java/org/chromium/net/impl/NativeCronvoyEngineBuilderImpl.java +++ b/mobile/library/java/org/chromium/net/impl/NativeCronvoyEngineBuilderImpl.java @@ -4,6 +4,7 @@ import android.content.Context; import androidx.annotation.VisibleForTesting; +import com.google.protobuf.Struct; import io.envoyproxy.envoymobile.engine.AndroidEngineImpl; import io.envoyproxy.envoymobile.engine.AndroidJniLibrary; import io.envoyproxy.envoymobile.engine.AndroidNetworkMonitor; @@ -135,7 +136,8 @@ mEnableDrainPostDnsRefresh, quicEnabled(), quicConnectionOptions(), /*rtdsResourceName=*/"", /*rtdsTimeoutSeconds=*/0, /*xdsAddress=*/"", /*xdsPort=*/0, /*xdsAuthenticationHeader=*/"", /*xdsAuthenticationToken=*/"", /*xdsJwtToken=*/"", /*xdsJwtTokenLifetime=*/0, /*xdsSslRootCerts=*/"", - /*xdsSni=*/"", mNodeId, mNodeRegion, mNodeZone, mNodeSubZone, /*cdsResourcesLocator=*/"", + /*xdsSni=*/"", mNodeId, mNodeRegion, mNodeZone, mNodeSubZone, Struct.getDefaultInstance(), + /*cdsResourcesLocator=*/"", /*cdsTimeoutSeconds=*/0, /*enableCds=*/false); } } diff --git a/mobile/library/kotlin/io/envoyproxy/envoymobile/EngineBuilder.kt b/mobile/library/kotlin/io/envoyproxy/envoymobile/EngineBuilder.kt index b7cfbe5cc3e4..2fe601d87168 100644 --- a/mobile/library/kotlin/io/envoyproxy/envoymobile/EngineBuilder.kt +++ b/mobile/library/kotlin/io/envoyproxy/envoymobile/EngineBuilder.kt @@ -1,5 +1,6 @@ package io.envoyproxy.envoymobile +import com.google.protobuf.Struct import io.envoyproxy.envoymobile.engine.EnvoyConfiguration import io.envoyproxy.envoymobile.engine.EnvoyConfiguration.TrustChainVerification import io.envoyproxy.envoymobile.engine.EnvoyEngine @@ -205,6 +206,7 @@ open class EngineBuilder(private val configuration: BaseConfiguration = Standard private var nodeRegion: String = "" private var nodeZone: String = "" private var nodeSubZone: String = "" + private var nodeMetadata: Struct = Struct.getDefaultInstance() private var xdsBuilder: XdsBuilder? = null /** @@ -636,6 +638,17 @@ open class EngineBuilder(private val configuration: BaseConfiguration = Standard return this } + /** + * Sets the node.metadata field in the Bootstrap configuration. + * + * @param metadata the metadata of the node. + * @return this builder. + */ + fun setNodeMetadata(metadata: Struct): EngineBuilder { + this.nodeMetadata = metadata + return this + } + /** * Sets the xDS configuration for the Envoy Mobile engine. * @@ -729,6 +742,7 @@ open class EngineBuilder(private val configuration: BaseConfiguration = Standard nodeRegion, nodeZone, nodeSubZone, + nodeMetadata, xdsBuilder?.cdsResourcesLocator, xdsBuilder?.cdsTimeoutInSeconds ?: 0, xdsBuilder?.enableCds ?: false, diff --git a/mobile/test/cc/unit/envoy_config_test.cc b/mobile/test/cc/unit/envoy_config_test.cc index 8c57c8acd1c0..f5291baf20a3 100644 --- a/mobile/test/cc/unit/envoy_config_test.cc +++ b/mobile/test/cc/unit/envoy_config_test.cc @@ -503,6 +503,19 @@ TEST(TestConfig, SetNodeLocality) { EXPECT_EQ(bootstrap->node().locality().sub_zone(), sub_zone); } +TEST(TestConfig, SetNodeMetadata) { + ProtobufWkt::Struct node_metadata; + (*node_metadata.mutable_fields())["string_field"].set_string_value("some_string"); + (*node_metadata.mutable_fields())["bool_field"].set_bool_value(true); + (*node_metadata.mutable_fields())["number_field"].set_number_value(3.14); + EngineBuilder engine_builder; + engine_builder.setNodeMetadata(node_metadata); + std::unique_ptr bootstrap = engine_builder.generateBootstrap(); + EXPECT_EQ(bootstrap->node().metadata().fields().at("string_field").string_value(), "some_string"); + EXPECT_EQ(bootstrap->node().metadata().fields().at("bool_field").bool_value(), true); + EXPECT_EQ(bootstrap->node().metadata().fields().at("number_field").number_value(), 3.14); +} + #ifdef ENVOY_GOOGLE_GRPC TEST(TestConfig, AddCdsLayer) { XdsBuilder xds_builder(/*xds_server_address=*/"fake-xds-server", /*xds_server_port=*/12345); diff --git a/mobile/test/java/io/envoyproxy/envoymobile/engine/BUILD b/mobile/test/java/io/envoyproxy/envoymobile/engine/BUILD index 69211f0c623e..c748f8d51ea4 100644 --- a/mobile/test/java/io/envoyproxy/envoymobile/engine/BUILD +++ b/mobile/test/java/io/envoyproxy/envoymobile/engine/BUILD @@ -19,6 +19,7 @@ envoy_mobile_jni_kt_test( deps = [ "//library/kotlin/io/envoyproxy/envoymobile:envoy_interfaces_lib", "//test/java/io/envoyproxy/envoymobile/engine/testing", + "@maven//:com_google_protobuf_protobuf_javalite", ], ) diff --git a/mobile/test/java/io/envoyproxy/envoymobile/engine/EnvoyConfigurationTest.kt b/mobile/test/java/io/envoyproxy/envoymobile/engine/EnvoyConfigurationTest.kt index 93cd14529d58..b3d6c05cea97 100644 --- a/mobile/test/java/io/envoyproxy/envoymobile/engine/EnvoyConfigurationTest.kt +++ b/mobile/test/java/io/envoyproxy/envoymobile/engine/EnvoyConfigurationTest.kt @@ -1,18 +1,16 @@ package io.envoyproxy.envoymobile.engine +import com.google.protobuf.Struct +import com.google.protobuf.Value import io.envoyproxy.envoymobile.engine.types.EnvoyHTTPFilter import io.envoyproxy.envoymobile.engine.types.EnvoyHTTPFilterFactory import io.envoyproxy.envoymobile.engine.EnvoyConfiguration.TrustChainVerification -import io.envoyproxy.envoymobile.engine.JniLibrary -import io.envoyproxy.envoymobile.engine.HeaderMatchConfig -import io.envoyproxy.envoymobile.engine.HeaderMatchConfig.Type import io.envoyproxy.envoymobile.engine.types.EnvoyStreamIntel import io.envoyproxy.envoymobile.engine.types.EnvoyFinalStreamIntel import io.envoyproxy.envoymobile.engine.types.EnvoyHTTPFilterCallbacks import io.envoyproxy.envoymobile.engine.testing.TestJni import java.nio.ByteBuffer import org.assertj.core.api.Assertions.assertThat -import org.junit.Assert.fail import org.junit.Test import java.util.regex.Pattern @@ -115,6 +113,7 @@ class EnvoyConfigurationTest { nodeRegion: String = "", nodeZone: String = "", nodeSubZone: String = "", + nodeMetadata: Struct = Struct.getDefaultInstance(), cdsResourcesLocator: String = "", cdsTimeoutSeconds: Int = 0, enableCds: Boolean = false, @@ -170,6 +169,7 @@ class EnvoyConfigurationTest { nodeRegion, nodeZone, nodeSubZone, + nodeMetadata, cdsResourcesLocator, cdsTimeoutSeconds, enableCds @@ -427,4 +427,19 @@ class EnvoyConfigurationTest { assertThat(resolvedTemplate).contains("envoy.stat_sinks.statsd"); assertThat(resolvedTemplate).contains("stats.example.com"); } + + @Test + fun `test node metadata`() { + JniLibrary.loadTestLibrary() + val envoyConfiguration = buildTestEnvoyConfiguration( + nodeMetadata = Struct.newBuilder() + .putFields("metadata_field", Value.newBuilder().setStringValue("metadata_value").build()) + .build() + ) + + val resolvedTemplate = TestJni.createYaml(envoyConfiguration) + + assertThat(resolvedTemplate).contains("metadata_field") + assertThat(resolvedTemplate).contains("metadata_value") + } } diff --git a/mobile/test/kotlin/integration/EngineApiTest.kt b/mobile/test/kotlin/integration/EngineApiTest.kt index e62b9bd4dc0b..48346e84dd67 100644 --- a/mobile/test/kotlin/integration/EngineApiTest.kt +++ b/mobile/test/kotlin/integration/EngineApiTest.kt @@ -1,5 +1,8 @@ package test.kotlin.integration +import com.google.protobuf.NullValue +import com.google.protobuf.Struct +import com.google.protobuf.Value import io.envoyproxy.envoymobile.Element import io.envoyproxy.envoymobile.EngineBuilder import io.envoyproxy.envoymobile.LogLevel @@ -21,6 +24,29 @@ class EngineApiTest { EngineBuilder() .addLogLevel(LogLevel.INFO) .addStatsFlushSeconds(1) + .setNodeId("node-id") + .setNodeLocality("region", "zone", "subzone") + .setNodeMetadata( + Struct.newBuilder() + .putFields("string_value", Value.newBuilder().setStringValue("string").build()) + .putFields("number_value", Value.newBuilder().setNumberValue(123.0).build()) + .putFields("bool_value", Value.newBuilder().setBoolValue(true).build()) + .putFields("null_value", Value.newBuilder().setNullValue(NullValue.NULL_VALUE).build()) + .putFields( + "struct_value", + Value.newBuilder() + .setStructValue( + Struct.newBuilder() + .putFields( + "nested_value", + Value.newBuilder().setStringValue("nested_string").build() + ) + .build() + ) + .build() + ) + .build() + ) .setOnEngineRunning { countDownLatch.countDown() } .build()