Skip to content

Commit 2559e28

Browse files
authored
Support per-project client for GCS repository (#131899)
Similar to #127631, this PR adds per project client support for GCS repository.
1 parent 5c09aa4 commit 2559e28

File tree

12 files changed

+842
-91
lines changed

12 files changed

+842
-91
lines changed

modules/repository-gcs/src/internalClusterTest/java/org/elasticsearch/repositories/gcs/GoogleCloudStorageBlobStoreRepositoryTests.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import org.apache.lucene.util.BytesRef;
2424
import org.apache.lucene.util.BytesRefBuilder;
2525
import org.elasticsearch.cluster.metadata.RepositoryMetadata;
26+
import org.elasticsearch.cluster.project.ProjectResolver;
2627
import org.elasticsearch.cluster.service.ClusterService;
2728
import org.elasticsearch.common.BackoffPolicy;
2829
import org.elasticsearch.common.blobstore.BlobContainer;
@@ -235,8 +236,8 @@ public TestGoogleCloudStoragePlugin(Settings settings) {
235236
}
236237

237238
@Override
238-
protected GoogleCloudStorageService createStorageService(boolean isServerless) {
239-
return new GoogleCloudStorageService() {
239+
protected GoogleCloudStorageService createStorageService(ClusterService clusterService, ProjectResolver projectResolver) {
240+
return new GoogleCloudStorageService(clusterService, projectResolver) {
240241
@Override
241242
StorageOptions createStorageOptions(
242243
final GoogleCloudStorageClientSettings gcsClientSettings,
@@ -280,7 +281,7 @@ public Map<String, Repository.Factory> getRepositories(
280281
projectId,
281282
metadata,
282283
registry,
283-
this.storageService,
284+
this.storageService.get(),
284285
clusterService,
285286
bigArrays,
286287
recoverySettings,
@@ -289,10 +290,11 @@ public Map<String, Repository.Factory> getRepositories(
289290
@Override
290291
protected GoogleCloudStorageBlobStore createBlobStore() {
291292
return new GoogleCloudStorageBlobStore(
293+
getProjectId(),
292294
metadata.settings().get("bucket"),
293295
"test",
294296
metadata.name(),
295-
storageService,
297+
storageService.get(),
296298
bigArrays,
297299
randomIntBetween(1, 8) * 1024,
298300
BackoffPolicy.noBackoff(),

modules/repository-gcs/src/main/java/org/elasticsearch/repositories/gcs/GoogleCloudStorageBlobStore.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import org.apache.logging.log4j.LogManager;
2424
import org.apache.logging.log4j.Logger;
2525
import org.elasticsearch.ExceptionsHelper;
26+
import org.elasticsearch.cluster.metadata.ProjectId;
2627
import org.elasticsearch.common.BackoffPolicy;
2728
import org.elasticsearch.common.blobstore.BlobContainer;
2829
import org.elasticsearch.common.blobstore.BlobPath;
@@ -40,6 +41,7 @@
4041
import org.elasticsearch.common.unit.ByteSizeValue;
4142
import org.elasticsearch.common.util.BigArrays;
4243
import org.elasticsearch.core.CheckedConsumer;
44+
import org.elasticsearch.core.Nullable;
4345
import org.elasticsearch.core.Streams;
4446
import org.elasticsearch.core.SuppressForbidden;
4547
import org.elasticsearch.core.TimeValue;
@@ -104,6 +106,8 @@ class GoogleCloudStorageBlobStore implements BlobStore {
104106
}
105107
}
106108

109+
@Nullable // for cluster level object store in MP
110+
private final ProjectId projectId;
107111
private final String bucketName;
108112
private final String clientName;
109113
private final String repositoryName;
@@ -114,6 +118,7 @@ class GoogleCloudStorageBlobStore implements BlobStore {
114118
private final BackoffPolicy casBackoffPolicy;
115119

116120
GoogleCloudStorageBlobStore(
121+
ProjectId projectId,
117122
String bucketName,
118123
String clientName,
119124
String repositoryName,
@@ -123,6 +128,7 @@ class GoogleCloudStorageBlobStore implements BlobStore {
123128
BackoffPolicy casBackoffPolicy,
124129
GcsRepositoryStatsCollector statsCollector
125130
) {
131+
this.projectId = projectId;
126132
this.bucketName = bucketName;
127133
this.clientName = clientName;
128134
this.repositoryName = repositoryName;
@@ -134,7 +140,7 @@ class GoogleCloudStorageBlobStore implements BlobStore {
134140
}
135141

136142
private MeteredStorage client() throws IOException {
137-
return storageService.client(clientName, repositoryName, statsCollector);
143+
return storageService.client(projectId, clientName, repositoryName, statsCollector);
138144
}
139145

140146
@Override
@@ -144,7 +150,7 @@ public BlobContainer blobContainer(BlobPath path) {
144150

145151
@Override
146152
public void close() {
147-
storageService.closeRepositoryClients(repositoryName);
153+
storageService.closeRepositoryClients(projectId, repositoryName);
148154
}
149155

150156
/**

modules/repository-gcs/src/main/java/org/elasticsearch/repositories/gcs/GoogleCloudStorageClientSettings.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import java.util.HashMap;
3232
import java.util.Locale;
3333
import java.util.Map;
34+
import java.util.Objects;
3435

3536
import static org.elasticsearch.common.settings.Setting.timeSetting;
3637

@@ -196,6 +197,25 @@ public Proxy getProxy() {
196197
return proxy;
197198
}
198199

200+
@Override
201+
public boolean equals(Object o) {
202+
if (o == null || getClass() != o.getClass()) return false;
203+
GoogleCloudStorageClientSettings that = (GoogleCloudStorageClientSettings) o;
204+
return Objects.equals(credential, that.credential)
205+
&& Objects.equals(endpoint, that.endpoint)
206+
&& Objects.equals(projectId, that.projectId)
207+
&& Objects.equals(connectTimeout, that.connectTimeout)
208+
&& Objects.equals(readTimeout, that.readTimeout)
209+
&& Objects.equals(applicationName, that.applicationName)
210+
&& Objects.equals(tokenUri, that.tokenUri)
211+
&& Objects.equals(proxy, that.proxy);
212+
}
213+
214+
@Override
215+
public int hashCode() {
216+
return Objects.hash(credential, endpoint, projectId, connectTimeout, readTimeout, applicationName, tokenUri, proxy);
217+
}
218+
199219
public static Map<String, GoogleCloudStorageClientSettings> load(final Settings settings) {
200220
final Map<String, GoogleCloudStorageClientSettings> clients = new HashMap<>();
201221
for (final String clientName : settings.getGroups(PREFIX).keySet()) {

modules/repository-gcs/src/main/java/org/elasticsearch/repositories/gcs/GoogleCloudStoragePlugin.java

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99

1010
package org.elasticsearch.repositories.gcs;
1111

12-
import org.elasticsearch.cluster.node.DiscoveryNode;
12+
import org.apache.lucene.util.SetOnce;
13+
import org.elasticsearch.cluster.project.ProjectResolver;
1314
import org.elasticsearch.cluster.service.ClusterService;
1415
import org.elasticsearch.common.settings.Setting;
1516
import org.elasticsearch.common.settings.Settings;
@@ -24,26 +25,24 @@
2425
import org.elasticsearch.xcontent.NamedXContentRegistry;
2526

2627
import java.util.Arrays;
28+
import java.util.Collection;
2729
import java.util.Collections;
2830
import java.util.List;
2931
import java.util.Map;
3032

3133
public class GoogleCloudStoragePlugin extends Plugin implements RepositoryPlugin, ReloadablePlugin {
3234

35+
private final Settings settings;
3336
// package-private for tests
34-
final GoogleCloudStorageService storageService;
37+
final SetOnce<GoogleCloudStorageService> storageService = new SetOnce<>();
3538

36-
@SuppressWarnings("this-escape")
3739
public GoogleCloudStoragePlugin(final Settings settings) {
38-
var isServerless = DiscoveryNode.isStateless(settings);
39-
this.storageService = createStorageService(isServerless);
40-
// eagerly load client settings so that secure settings are readable (not closed)
41-
reload(settings);
40+
this.settings = settings;
4241
}
4342

4443
// overridable for tests
45-
protected GoogleCloudStorageService createStorageService(boolean isServerless) {
46-
return new GoogleCloudStorageService(isServerless);
44+
protected GoogleCloudStorageService createStorageService(ClusterService clusterService, ProjectResolver projectResolver) {
45+
return new GoogleCloudStorageService(clusterService, projectResolver);
4746
}
4847

4948
@Override
@@ -61,7 +60,7 @@ public Map<String, Repository.Factory> getRepositories(
6160
projectId,
6261
metadata,
6362
namedXContentRegistry,
64-
this.storageService,
63+
this.storageService.get(),
6564
clusterService,
6665
bigArrays,
6766
recoverySettings,
@@ -70,6 +69,15 @@ public Map<String, Repository.Factory> getRepositories(
7069
);
7170
}
7271

72+
@Override
73+
public Collection<?> createComponents(PluginServices services) {
74+
final ClusterService clusterService = services.clusterService();
75+
storageService.set(createStorageService(clusterService, services.projectResolver()));
76+
// eagerly load client settings so that secure settings are readable (not closed)
77+
reload(settings);
78+
return List.of(storageService.get());
79+
}
80+
7381
@Override
7482
public List<Setting<?>> getSettings() {
7583
return Arrays.asList(
@@ -94,6 +102,6 @@ public void reload(Settings settings) {
94102
// `GoogleCloudStorageClientSettings` instance) instead of the `Settings`
95103
// instance.
96104
final Map<String, GoogleCloudStorageClientSettings> clientsSettings = GoogleCloudStorageClientSettings.load(settings);
97-
this.storageService.refreshAndClearCache(clientsSettings);
105+
this.storageService.get().refreshAndClearCache(clientsSettings);
98106
}
99107
}

modules/repository-gcs/src/main/java/org/elasticsearch/repositories/gcs/GoogleCloudStorageRepository.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ private static Map<String, String> buildLocation(RepositoryMetadata metadata) {
139139
@Override
140140
protected GoogleCloudStorageBlobStore createBlobStore() {
141141
return new GoogleCloudStorageBlobStore(
142+
getProjectId(),
142143
bucket,
143144
clientName,
144145
metadata.name(),

0 commit comments

Comments
 (0)