Skip to content

Commit 6d8954d

Browse files
SNAPSHOT: Repo Creation out of ClusterStateTask (#36157)
* Move `createRepository` call out of cluster state tasks * Now only `RepositoriesService#applyClusterState` manipulates `this.repositories` * Closes #9488
1 parent 2b0651d commit 6d8954d

File tree

2 files changed

+24
-37
lines changed

2 files changed

+24
-37
lines changed

server/src/main/java/org/elasticsearch/repositories/RepositoriesService.java

Lines changed: 14 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@
4242
import org.elasticsearch.threadpool.ThreadPool;
4343
import org.elasticsearch.transport.TransportService;
4444

45-
import java.io.IOException;
4645
import java.util.ArrayList;
4746
import java.util.Arrays;
4847
import java.util.Collections;
@@ -102,20 +101,23 @@ public void registerRepository(final RegisterRepositoryRequest request, final Ac
102101
registrationListener = listener;
103102
}
104103

104+
// Trying to create the new repository on master to make sure it works
105+
try {
106+
closeRepository(createRepository(newRepositoryMetaData));
107+
} catch (Exception e) {
108+
registrationListener.onFailure(e);
109+
return;
110+
}
111+
105112
clusterService.submitStateUpdateTask(request.cause, new AckedClusterStateUpdateTask<ClusterStateUpdateResponse>(request, registrationListener) {
106113
@Override
107114
protected ClusterStateUpdateResponse newResponse(boolean acknowledged) {
108115
return new ClusterStateUpdateResponse(acknowledged);
109116
}
110117

111118
@Override
112-
public ClusterState execute(ClusterState currentState) throws IOException {
119+
public ClusterState execute(ClusterState currentState) {
113120
ensureRepositoryNotInUse(currentState, request.name);
114-
// Trying to create the new repository on master to make sure it works
115-
if (!registerRepository(newRepositoryMetaData)) {
116-
// The new repository has the same settings as the old one - ignore
117-
return currentState;
118-
}
119121
MetaData metaData = currentState.metaData();
120122
MetaData.Builder mdBuilder = MetaData.builder(currentState.metaData());
121123
RepositoriesMetaData repositories = metaData.custom(RepositoriesMetaData.TYPE);
@@ -129,6 +131,10 @@ public ClusterState execute(ClusterState currentState) throws IOException {
129131

130132
for (RepositoryMetaData repositoryMetaData : repositories.repositories()) {
131133
if (repositoryMetaData.name().equals(newRepositoryMetaData.name())) {
134+
if (newRepositoryMetaData.equals(repositoryMetaData)) {
135+
// Previous version is the same as this one no update is needed.
136+
return currentState;
137+
}
132138
found = true;
133139
repositoriesMetaData.add(newRepositoryMetaData);
134140
} else {
@@ -355,37 +361,8 @@ public Repository repository(String repositoryName) {
355361
throw new RepositoryMissingException(repositoryName);
356362
}
357363

358-
/**
359-
* Creates a new repository and adds it to the list of registered repositories.
360-
* <p>
361-
* If a repository with the same name but different types or settings already exists, it will be closed and
362-
* replaced with the new repository. If a repository with the same name exists but it has the same type and settings
363-
* the new repository is ignored.
364-
*
365-
* @param repositoryMetaData new repository metadata
366-
* @return {@code true} if new repository was added or {@code false} if it was ignored
367-
*/
368-
private boolean registerRepository(RepositoryMetaData repositoryMetaData) throws IOException {
369-
Repository previous = repositories.get(repositoryMetaData.name());
370-
if (previous != null) {
371-
RepositoryMetaData previousMetadata = previous.getMetadata();
372-
if (previousMetadata.equals(repositoryMetaData)) {
373-
// Previous version is the same as this one - ignore it
374-
return false;
375-
}
376-
}
377-
Repository newRepo = createRepository(repositoryMetaData);
378-
if (previous != null) {
379-
closeRepository(previous);
380-
}
381-
Map<String, Repository> newRepositories = new HashMap<>(repositories);
382-
newRepositories.put(repositoryMetaData.name(), newRepo);
383-
repositories = newRepositories;
384-
return true;
385-
}
386-
387364
/** Closes the given repository. */
388-
private void closeRepository(Repository repository) throws IOException {
365+
private void closeRepository(Repository repository) {
389366
logger.debug("closing repository [{}][{}]", repository.getMetadata().type(), repository.getMetadata().name());
390367
repository.close();
391368
}

server/src/test/java/org/elasticsearch/snapshots/RepositoriesIT.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,16 @@ public void testRepositoryCreation() throws Exception {
9797
assertThat(findRepository(repositoriesResponse.repositories(), "test-repo-1"), notNullValue());
9898
assertThat(findRepository(repositoriesResponse.repositories(), "test-repo-2"), notNullValue());
9999

100+
logger.info("--> check that trying to create a repository with the same settings repeatedly does not update cluster state");
101+
String beforeStateUuid = clusterStateResponse.getState().stateUUID();
102+
assertThat(
103+
client.admin().cluster().preparePutRepository("test-repo-1")
104+
.setType("fs").setSettings(Settings.builder()
105+
.put("location", location)
106+
).get().isAcknowledged(),
107+
equalTo(true));
108+
assertEquals(beforeStateUuid, client.admin().cluster().prepareState().clear().get().getState().stateUUID());
109+
100110
logger.info("--> delete repository test-repo-1");
101111
client.admin().cluster().prepareDeleteRepository("test-repo-1").get();
102112
repositoriesResponse = client.admin().cluster().prepareGetRepositories().get();

0 commit comments

Comments
 (0)