
io.envoyproxy.controlplane.cache.Resources Maven / Gradle / Ivy
package io.envoyproxy.controlplane.cache;
import static com.google.common.base.Strings.isNullOrEmpty;
import static envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManagerOuterClass.HttpConnectionManager.RouteSpecifierCase.RDS;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.protobuf.InvalidProtocolBufferException;
import com.google.protobuf.Message;
import com.google.protobuf.Struct;
import com.google.protobuf.util.JsonFormat;
import envoy.api.v2.Cds.Cluster;
import envoy.api.v2.Cds.Cluster.DiscoveryType;
import envoy.api.v2.Eds.ClusterLoadAssignment;
import envoy.api.v2.Lds.Listener;
import envoy.api.v2.Rds.RouteConfiguration;
import envoy.api.v2.listener.Listener.Filter;
import envoy.api.v2.listener.Listener.FilterChain;
import envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManagerOuterClass.HttpConnectionManager;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Resources {
private static final Logger LOGGER = LoggerFactory.getLogger(Resources.class);
static final String FILTER_ENVOY_ROUTER = "envoy.router";
static final String FILTER_HTTP_CONNECTION_MANAGER = "envoy.http_connection_manager";
private static final String TYPE_URL_PREFIX = "type.googleapis.com/envoy.api.v2.";
public static final String CLUSTER_TYPE_URL = TYPE_URL_PREFIX + "Cluster";
public static final String ENDPOINT_TYPE_URL = TYPE_URL_PREFIX + "ClusterLoadAssignment";
public static final String LISTENER_TYPE_URL = TYPE_URL_PREFIX + "Listener";
public static final String ROUTE_TYPE_URL = TYPE_URL_PREFIX + "RouteConfiguration";
public static final List TYPE_URLS = ImmutableList.of(
CLUSTER_TYPE_URL,
ENDPOINT_TYPE_URL,
LISTENER_TYPE_URL,
ROUTE_TYPE_URL);
/**
* Returns the name of the given resource message.
*
* @param resource the resource message
*/
public static String getResourceName(Message resource) {
if (resource instanceof Cluster) {
return ((Cluster) resource).getName();
}
if (resource instanceof ClusterLoadAssignment) {
return ((ClusterLoadAssignment) resource).getClusterName();
}
if (resource instanceof Listener) {
return ((Listener) resource).getName();
}
if (resource instanceof RouteConfiguration) {
return ((RouteConfiguration) resource).getName();
}
return "";
}
/**
* Returns all resource names that are referenced by the given collection of resources.
*
* @param resources the resource whose dependencies we are calculating
*/
public static Set getResourceReferences(Collection extends Message> resources) {
final ImmutableSet.Builder refs = ImmutableSet.builder();
for (Message r : resources) {
if (r instanceof ClusterLoadAssignment || r instanceof RouteConfiguration) {
// Endpoints have no dependencies.
// References to clusters in routes (and listeners) are not included in the result, because the clusters are
// currently retrieved in bulk, and not by name.
continue;
}
if (r instanceof Cluster) {
Cluster c = (Cluster) r;
// For EDS clusters, use the cluster name or the service name override.
if (c.getType() == DiscoveryType.EDS) {
if (!isNullOrEmpty(c.getEdsClusterConfig().getServiceName())) {
refs.add(c.getEdsClusterConfig().getServiceName());
} else {
refs.add(c.getName());
}
}
} else if (r instanceof Listener) {
Listener l = (Listener) r;
// Extract the route configuration names from the HTTP connection manager.
for (FilterChain chain : l.getFilterChainsList()) {
for (Filter filter : chain.getFiltersList()) {
if (!filter.getName().equals(FILTER_HTTP_CONNECTION_MANAGER)) {
continue;
}
try {
HttpConnectionManager.Builder config = HttpConnectionManager.newBuilder();
structAsMessage(filter.getConfig(), config);
if (config.getRouteSpecifierCase() == RDS && !isNullOrEmpty(config.getRds().getRouteConfigName())) {
refs.add(config.getRds().getRouteConfigName());
}
} catch (InvalidProtocolBufferException e) {
LOGGER.error(
"Failed to convert HTTP connection manager config struct into protobuf message for listener {}",
getResourceName(l),
e);
}
}
}
}
}
return refs.build();
}
private static void structAsMessage(Struct struct, Message.Builder messageBuilder)
throws InvalidProtocolBufferException {
String json = JsonFormat.printer()
.preservingProtoFieldNames()
.print(struct);
JsonFormat.parser().merge(json, messageBuilder);
}
private Resources() { }
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy