Skip to content

Commit

Permalink
Add xdsResourceManager
Browse files Browse the repository at this point in the history
  • Loading branch information
minwoox committed Aug 7, 2024
1 parent 35b96ac commit adc7d73
Show file tree
Hide file tree
Showing 12 changed files with 121 additions and 163 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,25 +17,17 @@

import static com.linecorp.centraldogma.server.internal.admin.auth.AuthUtil.currentAuthor;
import static com.linecorp.centraldogma.xds.internal.ControlPlanePlugin.CLUSTERS_DIRECTORY;
import static com.linecorp.centraldogma.xds.internal.ControlPlanePlugin.XDS_CENTRAL_DOGMA_PROJECT;
import static com.linecorp.centraldogma.xds.internal.XdsServiceUtil.RESOURCE_ID_PATTERN;
import static com.linecorp.centraldogma.xds.internal.XdsServiceUtil.RESOURCE_ID_PATTERN_STRING;
import static com.linecorp.centraldogma.xds.internal.XdsServiceUtil.checkGroup;
import static com.linecorp.centraldogma.xds.internal.XdsServiceUtil.delete;
import static com.linecorp.centraldogma.xds.internal.XdsServiceUtil.push;
import static com.linecorp.centraldogma.xds.internal.XdsServiceUtil.removePrefix;
import static com.linecorp.centraldogma.xds.internal.XdsServiceUtil.update;
import static java.util.Objects.requireNonNull;
import static com.linecorp.centraldogma.xds.internal.XdsResourceManager.RESOURCE_ID_PATTERN;
import static com.linecorp.centraldogma.xds.internal.XdsResourceManager.RESOURCE_ID_PATTERN_STRING;
import static com.linecorp.centraldogma.xds.internal.XdsResourceManager.removePrefix;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.google.protobuf.Empty;

import com.linecorp.centraldogma.server.command.CommandExecutor;
import com.linecorp.centraldogma.server.storage.project.Project;
import com.linecorp.centraldogma.server.storage.project.ProjectManager;
import com.linecorp.centraldogma.xds.cluster.v1.XdsClusterServiceGrpc.XdsClusterServiceImplBase;
import com.linecorp.centraldogma.xds.internal.XdsResourceManager;

import io.envoyproxy.envoy.config.cluster.v3.Cluster;
import io.grpc.Status;
Expand All @@ -49,23 +41,20 @@ public final class XdsClusterService extends XdsClusterServiceImplBase {
private static final Pattern CLUSTER_NAME_PATTERN =
Pattern.compile("^groups/([^/]+)/clusters/" + RESOURCE_ID_PATTERN_STRING + '$');

private final Project xdsCentralDogmaProject;
private final CommandExecutor commandExecutor;
private final XdsResourceManager xdsResourceManager;

/**
* Creates a new instance.
*/
public XdsClusterService(ProjectManager projectManager, CommandExecutor commandExecutor) {
xdsCentralDogmaProject = requireNonNull(projectManager, "projectManager")
.get(XDS_CENTRAL_DOGMA_PROJECT);
this.commandExecutor = requireNonNull(commandExecutor, "commandExecutor");
public XdsClusterService(XdsResourceManager xdsResourceManager) {
this.xdsResourceManager = xdsResourceManager;
}

@Override
public void createCluster(CreateClusterRequest request, StreamObserver<Cluster> responseObserver) {
final String parent = request.getParent();
final String group = removePrefix("groups/", parent);
checkGroup(xdsCentralDogmaProject, group);
xdsResourceManager.checkGroup(group);

final String clusterId = request.getClusterId();
if (!RESOURCE_ID_PATTERN.matcher(clusterId).matches()) {
Expand All @@ -79,25 +68,24 @@ public void createCluster(CreateClusterRequest request, StreamObserver<Cluster>
// with the format of "groups/{group}/clusters/{cluster}".
// https://github.com/aip-dev/google.aip.dev/blob/master/aip/general/0133.md#user-specified-ids
final Cluster cluster = request.getCluster().toBuilder().setName(clusterName).build();
push(commandExecutor, responseObserver, group, CLUSTERS_DIRECTORY + clusterId + ".json",
"Create cluster: " + clusterName, cluster, currentAuthor());
xdsResourceManager.push(responseObserver, group, CLUSTERS_DIRECTORY + clusterId + ".json",
"Create cluster: " + clusterName, cluster, currentAuthor());
}

@Override
public void updateCluster(UpdateClusterRequest request, StreamObserver<Cluster> responseObserver) {
final Cluster cluster = request.getCluster();
final String clusterName = cluster.getName();
final Matcher matcher = checkClusterName(clusterName);
update(commandExecutor, xdsCentralDogmaProject, matcher.group(1),
responseObserver, clusterName, "Update cluster: " + clusterName, cluster);
final String group = checkClusterName(clusterName).group(1);
xdsResourceManager.update(responseObserver, group, clusterName,
"Update cluster: " + clusterName, cluster);
}

@Override
public void deleteCluster(DeleteClusterRequest request, StreamObserver<Empty> responseObserver) {
final String clusterName = request.getName();
final Matcher matcher = checkClusterName(clusterName);
delete(commandExecutor, xdsCentralDogmaProject, matcher.group(1), responseObserver,
clusterName, "Delete cluster: " + clusterName);
final String group = checkClusterName(clusterName).group(1);
xdsResourceManager.delete(responseObserver, group, clusterName, "Delete cluster: " + clusterName);
}

private static Matcher checkClusterName(String clusterName) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,25 +18,17 @@
import static com.linecorp.centraldogma.server.internal.admin.auth.AuthUtil.currentAuthor;
import static com.linecorp.centraldogma.xds.internal.ControlPlanePlugin.CLUSTERS_DIRECTORY;
import static com.linecorp.centraldogma.xds.internal.ControlPlanePlugin.ENDPOINTS_DIRECTORY;
import static com.linecorp.centraldogma.xds.internal.ControlPlanePlugin.XDS_CENTRAL_DOGMA_PROJECT;
import static com.linecorp.centraldogma.xds.internal.XdsServiceUtil.RESOURCE_ID_PATTERN;
import static com.linecorp.centraldogma.xds.internal.XdsServiceUtil.RESOURCE_ID_PATTERN_STRING;
import static com.linecorp.centraldogma.xds.internal.XdsServiceUtil.checkGroup;
import static com.linecorp.centraldogma.xds.internal.XdsServiceUtil.delete;
import static com.linecorp.centraldogma.xds.internal.XdsServiceUtil.push;
import static com.linecorp.centraldogma.xds.internal.XdsServiceUtil.removePrefix;
import static com.linecorp.centraldogma.xds.internal.XdsServiceUtil.update;
import static java.util.Objects.requireNonNull;
import static com.linecorp.centraldogma.xds.internal.XdsResourceManager.RESOURCE_ID_PATTERN;
import static com.linecorp.centraldogma.xds.internal.XdsResourceManager.RESOURCE_ID_PATTERN_STRING;
import static com.linecorp.centraldogma.xds.internal.XdsResourceManager.removePrefix;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.google.protobuf.Empty;

import com.linecorp.centraldogma.server.command.CommandExecutor;
import com.linecorp.centraldogma.server.storage.project.Project;
import com.linecorp.centraldogma.server.storage.project.ProjectManager;
import com.linecorp.centraldogma.xds.endpoint.v1.XdsEndpointServiceGrpc.XdsEndpointServiceImplBase;
import com.linecorp.centraldogma.xds.internal.XdsResourceManager;

import io.envoyproxy.envoy.config.endpoint.v3.ClusterLoadAssignment;
import io.grpc.Status;
Expand All @@ -50,24 +42,21 @@ public final class XdsEndpointService extends XdsEndpointServiceImplBase {
private static final Pattern ENDPONT_NAME_PATTERN =
Pattern.compile("^groups/([^/]+)/endpoints/(" + RESOURCE_ID_PATTERN_STRING + ")$");

private final Project xdsCentralDogmaProject;
private final CommandExecutor commandExecutor;
private final XdsResourceManager xdsResourceManager;

/**
* Creates a new instance.
*/
public XdsEndpointService(ProjectManager projectManager, CommandExecutor commandExecutor) {
xdsCentralDogmaProject = requireNonNull(projectManager, "projectManager")
.get(XDS_CENTRAL_DOGMA_PROJECT);
this.commandExecutor = requireNonNull(commandExecutor, "commandExecutor");
public XdsEndpointService(XdsResourceManager xdsResourceManager) {
this.xdsResourceManager = xdsResourceManager;
}

@Override
public void createEndpoint(CreateEndpointRequest request,
StreamObserver<ClusterLoadAssignment> responseObserver) {
final String parent = request.getParent();
final String group = removePrefix("groups/", parent);
checkGroup(xdsCentralDogmaProject, group);
xdsResourceManager.checkGroup(group);

final String endpointId = request.getEndpointId();
if (!RESOURCE_ID_PATTERN.matcher(endpointId).matches()) {
Expand All @@ -84,8 +73,8 @@ public void createEndpoint(CreateEndpointRequest request,
.toBuilder()
.setClusterName(clusterName)
.build();
push(commandExecutor, responseObserver, group, fileName(endpointId),
"Create endpoint: " + clusterName, endpoint, currentAuthor());
xdsResourceManager.push(responseObserver, group, fileName(endpointId),
"Create endpoint: " + clusterName, endpoint, currentAuthor());
}

private static String clusterName(String parent, String endpointId) {
Expand All @@ -103,20 +92,20 @@ public void updateEndpoint(UpdateEndpointRequest request,

final ClusterLoadAssignment endpoint = request.getEndpoint();
final String endpointId = matcher.group(2);
update(commandExecutor, xdsCentralDogmaProject, group, responseObserver, endpointName,
fileName(endpointId), "Update endpoint: " + endpointName,
endpoint.toBuilder()
.setClusterName(clusterName("groups/" + group, endpointId))
.build());
xdsResourceManager.update(responseObserver, group, endpointName,
fileName(endpointId), "Update endpoint: " + endpointName,
endpoint.toBuilder()
.setClusterName(clusterName("groups/" + group, endpointId))
.build());
}

@Override
public void deleteEndpoint(DeleteEndpointRequest request, StreamObserver<Empty> responseObserver) {
final String endpointName = request.getName();
final Matcher matcher = checkEndpointName(endpointName);
final String group = matcher.group(1);
delete(commandExecutor, xdsCentralDogmaProject, group, responseObserver,
endpointName, fileName(matcher.group(2)), "Delete endpoint: " + endpointName);
xdsResourceManager.delete(responseObserver, group, endpointName,
fileName(matcher.group(2)), "Delete endpoint: " + endpointName);
}

private static Matcher checkEndpointName(String endpointName) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import static com.linecorp.centraldogma.server.internal.api.RepositoryServiceUtil.createRepository;
import static com.linecorp.centraldogma.server.internal.api.RepositoryServiceUtil.removeRepository;
import static com.linecorp.centraldogma.xds.internal.ControlPlanePlugin.XDS_CENTRAL_DOGMA_PROJECT;
import static com.linecorp.centraldogma.xds.internal.XdsResourceManager.removePrefix;

import com.google.protobuf.Empty;

Expand All @@ -30,7 +31,6 @@
import com.linecorp.centraldogma.xds.group.v1.XdsGroupServiceGrpc.XdsGroupServiceImplBase;

import io.grpc.Status;
import io.grpc.StatusRuntimeException;
import io.grpc.stub.StreamObserver;

/**
Expand Down Expand Up @@ -76,14 +76,6 @@ public void createGroup(CreateGroupRequest request,
});
}

private static String removePrefix(String prefix, String name) {
if (!name.startsWith(prefix)) {
throw new StatusRuntimeException(
Status.INVALID_ARGUMENT.withDescription(name + " does not start with prefix: " + prefix));
}
return name.substring(prefix.length());
}

private static RuntimeException alreadyExistsException(String groupName) {
return Status.ALREADY_EXISTS.withDescription("Group already exists: " + groupName)
.asRuntimeException();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

package com.linecorp.centraldogma.xds.internal;

import static com.linecorp.centraldogma.xds.internal.XdsServiceUtil.JSON_MESSAGE_MARSHALLER;
import static com.linecorp.centraldogma.xds.internal.XdsResourceManager.JSON_MESSAGE_MARSHALLER;

import java.io.IOException;
import java.util.HashSet;
Expand Down Expand Up @@ -71,6 +71,8 @@
import io.envoyproxy.envoy.config.route.v3.RouteConfiguration;
import io.envoyproxy.envoy.extensions.filters.http.router.v3.Router;
import io.envoyproxy.envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager;
import io.envoyproxy.envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext;
import io.envoyproxy.envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext;
import io.envoyproxy.envoy.service.discovery.v3.DeltaDiscoveryRequest;
import io.envoyproxy.envoy.service.discovery.v3.DiscoveryRequest;
import io.envoyproxy.envoy.service.discovery.v3.DiscoveryResponse;
Expand Down Expand Up @@ -161,20 +163,23 @@ private void init0(PluginInitContext pluginInitContext) {
.build();
sb.route().build(grpcService);
final CommandExecutor commandExecutor = pluginInitContext.commandExecutor();
final XdsResourceManager xdsResourceManager = new XdsResourceManager(projectManager, commandExecutor);
final GrpcService xdsApplicationService =
GrpcService.builder()
.addService(new XdsGroupService(projectManager, commandExecutor))
.addService(new XdsListenerService(projectManager, commandExecutor))
.addService(new XdsRouteService(projectManager, commandExecutor))
.addService(new XdsClusterService(projectManager, commandExecutor))
.addService(new XdsEndpointService(projectManager, commandExecutor))
.addService(new XdsListenerService(xdsResourceManager))
.addService(new XdsRouteService(xdsResourceManager))
.addService(new XdsClusterService(xdsResourceManager))
.addService(new XdsEndpointService(xdsResourceManager))
.jsonMarshallerFactory(
serviceDescriptor -> GrpcJsonMarshaller
.builder()
//TODO(minwoox): Automate the registration of the extension messages.
.jsonMarshallerCustomizer(builder -> {
builder.register(HttpConnectionManager.getDefaultInstance())
.register(Router.getDefaultInstance());
.register(Router.getDefaultInstance())
.register(UpstreamTlsContext.getDefaultInstance())
.register(DownstreamTlsContext.getDefaultInstance());
})
.build(serviceDescriptor))
.enableHttpJsonTranscoding(true).build();
Expand Down
Loading

0 comments on commit adc7d73

Please sign in to comment.