Skip to content

Commit 3c54b41

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 c007a42 commit 3c54b41

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
@@ -41,7 +41,6 @@
4141
import org.elasticsearch.threadpool.ThreadPool;
4242
import org.elasticsearch.transport.TransportService;
4343

44-
import java.io.IOException;
4544
import java.util.ArrayList;
4645
import java.util.Arrays;
4746
import java.util.Collections;
@@ -100,20 +99,23 @@ public void registerRepository(final RegisterRepositoryRequest request, final Ac
10099
registrationListener = listener;
101100
}
102101

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

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

128130
for (RepositoryMetaData repositoryMetaData : repositories.repositories()) {
129131
if (repositoryMetaData.name().equals(newRepositoryMetaData.name())) {
132+
if (newRepositoryMetaData.equals(repositoryMetaData)) {
133+
// Previous version is the same as this one no update is needed.
134+
return currentState;
135+
}
130136
found = true;
131137
repositoriesMetaData.add(newRepositoryMetaData);
132138
} else {
@@ -352,37 +358,8 @@ public Repository repository(String repositoryName) {
352358
throw new RepositoryMissingException(repositoryName);
353359
}
354360

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

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)