1 /* 2 * Copyright 2020 The gRPC Authors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package io.grpc.rls; 18 19 import com.google.auto.value.AutoValue; 20 import com.google.common.collect.ImmutableList; 21 import com.google.common.collect.ImmutableMap; 22 import javax.annotation.Nullable; 23 import javax.annotation.concurrent.Immutable; 24 25 /** RlsProtoData is a collection of internal representation of RouteLookupService proto messages. */ 26 final class RlsProtoData { 27 RlsProtoData()28 private RlsProtoData() {} 29 30 /** A request object sent to route lookup service. */ 31 @AutoValue 32 @Immutable 33 abstract static class RouteLookupRequest { 34 35 /** Returns a map of key values extracted via key builders for the gRPC or HTTP request. */ keyMap()36 abstract ImmutableMap<String, String> keyMap(); 37 create(ImmutableMap<String, String> keyMap)38 static RouteLookupRequest create(ImmutableMap<String, String> keyMap) { 39 return new AutoValue_RlsProtoData_RouteLookupRequest(keyMap); 40 } 41 } 42 43 /** A response from route lookup service. */ 44 @AutoValue 45 @Immutable 46 abstract static class RouteLookupResponse { 47 48 /** 49 * Returns list of targets. Prioritized list (best one first) of addressable entities to use for 50 * routing, using syntax requested by the request target_type. The targets will be tried in 51 * order until a healthy one is found. 52 */ targets()53 abstract ImmutableList<String> targets(); 54 55 /** 56 * Returns optional header data to pass along to AFE in the X-Google-RLS-Data header. Cached 57 * with "target" and sent with all requests that match the request key. Allows the RLS to pass 58 * its work product to the eventual target. 59 */ getHeaderData()60 abstract String getHeaderData(); 61 create(ImmutableList<String> targets, String getHeaderData)62 static RouteLookupResponse create(ImmutableList<String> targets, String getHeaderData) { 63 return new AutoValue_RlsProtoData_RouteLookupResponse(targets, getHeaderData); 64 } 65 } 66 67 /** A config object for gRPC RouteLookupService. */ 68 @AutoValue 69 @Immutable 70 abstract static class RouteLookupConfig { 71 72 /** 73 * Returns unordered specifications for constructing keys for gRPC requests. All GrpcKeyBuilders 74 * on this list must have unique "name" fields so that the client is free to prebuild a hash map 75 * keyed by name. If no GrpcKeyBuilder matches, an empty key_map will be sent to the lookup 76 * service; it should likely reply with a global default route and raise an alert. 77 */ grpcKeybuilders()78 abstract ImmutableList<GrpcKeyBuilder> grpcKeybuilders(); 79 80 /** 81 * Returns the name of the lookup service as a gRPC URI. Typically, this will be a subdomain of 82 * the target, such as "lookup.datastore.googleapis.com". 83 */ lookupService()84 abstract String lookupService(); 85 86 /** Returns the timeout value for lookup service requests. */ lookupServiceTimeoutInNanos()87 abstract long lookupServiceTimeoutInNanos(); 88 89 /** Returns the maximum age the result will be cached. */ maxAgeInNanos()90 abstract long maxAgeInNanos(); 91 92 /** 93 * Returns the time when an entry will be in a staled status. When cache is accessed whgen the 94 * entry is in staled status, it will 95 */ staleAgeInNanos()96 abstract long staleAgeInNanos(); 97 98 /** 99 * Returns a rough indicator of amount of memory to use for the client cache. Some of the data 100 * structure overhead is not accounted for, so actual memory consumed will be somewhat greater 101 * than this value. If this field is omitted or set to zero, a client default will be used. 102 * The value may be capped to a lower amount based on client configuration. 103 */ cacheSizeBytes()104 abstract long cacheSizeBytes(); 105 106 /** 107 * Returns the default target to use if needed. If nonempty (implies request processing 108 * strategy SYNC_LOOKUP_DEFAULT_TARGET_ON_ERROR is set), it will be used if RLS returns an 109 * error. Note that requests can be routed only to a subdomain of the original target, 110 * {@literal e.g.} "us_east_1.cloudbigtable.googleapis.com". 111 */ 112 @Nullable defaultTarget()113 abstract String defaultTarget(); 114 builder()115 static Builder builder() { 116 return new AutoValue_RlsProtoData_RouteLookupConfig.Builder(); 117 } 118 119 @AutoValue.Builder 120 abstract static class Builder { 121 grpcKeybuilders(ImmutableList<GrpcKeyBuilder> grpcKeybuilders)122 abstract Builder grpcKeybuilders(ImmutableList<GrpcKeyBuilder> grpcKeybuilders); 123 lookupService(String lookupService)124 abstract Builder lookupService(String lookupService); 125 lookupServiceTimeoutInNanos(long lookupServiceTimeoutInNanos)126 abstract Builder lookupServiceTimeoutInNanos(long lookupServiceTimeoutInNanos); 127 maxAgeInNanos(long maxAgeInNanos)128 abstract Builder maxAgeInNanos(long maxAgeInNanos); 129 staleAgeInNanos(long staleAgeInNanos)130 abstract Builder staleAgeInNanos(long staleAgeInNanos); 131 cacheSizeBytes(long cacheSizeBytes)132 abstract Builder cacheSizeBytes(long cacheSizeBytes); 133 defaultTarget(@ullable String defaultTarget)134 abstract Builder defaultTarget(@Nullable String defaultTarget); 135 build()136 abstract RouteLookupConfig build(); 137 } 138 } 139 140 /** 141 * NameMatcher extract a key based on a given name (e.g. header name or query parameter name). 142 * The name must match one of the names listed in the "name" field. If the "required_match" field 143 * is true, one of the specified names must be present for the keybuilder to match. 144 */ 145 @AutoValue 146 @Immutable 147 abstract static class NameMatcher { 148 149 /** The name that will be used in the RLS key_map to refer to this value. */ key()150 abstract String key(); 151 152 /** Returns ordered list of names; the first non-empty value will be used. */ names()153 abstract ImmutableList<String> names(); 154 create(String key, ImmutableList<String> names)155 static NameMatcher create(String key, ImmutableList<String> names) { 156 return new AutoValue_RlsProtoData_NameMatcher(key, names); 157 } 158 } 159 160 /** GrpcKeyBuilder is a configuration to construct headers consumed by route lookup service. */ 161 @AutoValue 162 @Immutable 163 abstract static class GrpcKeyBuilder { 164 165 /** 166 * Returns names. To match, one of the given Name fields must match; the service and method 167 * fields are specified as fixed strings. The service name is required and includes the proto 168 * package name. The method name may be omitted, in which case any method on the given service 169 * is matched. 170 */ names()171 abstract ImmutableList<Name> names(); 172 173 /** 174 * Returns a list of NameMatchers for header. Extract keys from all listed headers. For gRPC, it 175 * is an error to specify "required_match" on the NameMatcher protos, and we ignore it if set. 176 */ headers()177 abstract ImmutableList<NameMatcher> headers(); 178 extraKeys()179 abstract ExtraKeys extraKeys(); 180 constantKeys()181 abstract ImmutableMap<String, String> constantKeys(); 182 create( ImmutableList<Name> names, ImmutableList<NameMatcher> headers, ExtraKeys extraKeys, ImmutableMap<String, String> constantKeys)183 static GrpcKeyBuilder create( 184 ImmutableList<Name> names, 185 ImmutableList<NameMatcher> headers, 186 ExtraKeys extraKeys, ImmutableMap<String, String> constantKeys) { 187 return new AutoValue_RlsProtoData_GrpcKeyBuilder(names, headers, extraKeys, constantKeys); 188 } 189 190 /** 191 * Name represents a method for a given service. To match, one of the given Name fields must 192 * match; the service and method fields are specified as fixed strings. The service name is 193 * required and includes the proto package name. The method name may be omitted, in which case 194 * any method on the given service is matched. 195 */ 196 @AutoValue 197 @Immutable 198 abstract static class Name { 199 service()200 abstract String service(); 201 202 @Nullable method()203 abstract String method(); 204 create(String service, @Nullable String method)205 static Name create(String service, @Nullable String method) { 206 return new AutoValue_RlsProtoData_GrpcKeyBuilder_Name(service, method); 207 } 208 } 209 } 210 211 @AutoValue 212 @Immutable 213 abstract static class ExtraKeys { 214 static final ExtraKeys DEFAULT = create(null, null, null); 215 host()216 @Nullable abstract String host(); 217 service()218 @Nullable abstract String service(); 219 method()220 @Nullable abstract String method(); 221 create( @ullable String host, @Nullable String service, @Nullable String method)222 static ExtraKeys create( 223 @Nullable String host, @Nullable String service, @Nullable String method) { 224 return new AutoValue_RlsProtoData_ExtraKeys(host, service, method); 225 } 226 } 227 } 228