Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Disallow changes to previously successfully applied scripts #156

Merged
merged 5 commits into from
Oct 11, 2022
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@ Elasticsearch-Evolution can be configured to your needs:
- **placeholderSuffix** (default=}): Suffix of placeholders in migration scripts.
- **historyIndex** (default=es_evolution): Name of the history index that will be used by Elasticsearch-Evolution. In this index Elasticsearch-Evolution will persist his internal state and tracks which migration script has already been executed.
- **historyMaxQuerySize** (default=1000): The maximum query size while validating already executed scripts. This query size have to be higher than the total count of your migration scripts.
- **validateOnMigrate** (default=true): Whether to fail when a previously applied migration script has been modified after it was applied.

### 5.1 Spring Boot

Expand Down Expand Up @@ -288,7 +289,7 @@ ElasticsearchEvolution.configure()

### v0.4.1-SNAPSHOT

- ...
- Previously applied migration scripts are now checked for modifications and rejected if they've been modified after they were applied. The old behaviour can be restored by setting the new configuration parameter `validateOnMigrate` to false (default true).

### v0.4.0

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ protected MigrationService createMigrationService() {
10_000,
getRestClient(),
ContentType.parse(getConfig().getDefaultContentType()),
getConfig().getEncoding());
getConfig().getEncoding(),
getConfig().getValidateOnMigrate());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,11 @@ public class ElasticsearchEvolutionConfig {
*/
private int historyMaxQuerySize = 1_000;

/**
* Whether to fail when a previously applied migration script has been modified after it was applied.
*/
private boolean validateOnMigrate = true;

/**
* Loads this configuration into a new ElasticsearchEvolution instance.
*
Expand Down Expand Up @@ -236,6 +241,15 @@ public ElasticsearchEvolutionConfig setHistoryMaxQuerySize(int historyMaxQuerySi
return this;
}

public boolean getValidateOnMigrate() {
return validateOnMigrate;
}

public ElasticsearchEvolutionConfig setValidateOnMigrate(boolean validateOnMigrate) {
this.validateOnMigrate = validateOnMigrate;
return this;
}

@Override
public String toString() {
return "ElasticsearchEvolutionConfig{" +
Expand All @@ -251,6 +265,7 @@ public String toString() {
", placeholderReplacement=" + placeholderReplacement +
", historyIndex='" + historyIndex + '\'' +
", historyMaxQuerySize=" + historyMaxQuerySize +
", validateOnMigrate=" + validateOnMigrate +
'}';
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,20 @@ public class MigrationServiceImpl implements MigrationService {
private final RestClient restClient;
private final ContentType defaultContentType;
private final Charset encoding;
private final boolean validateOnMigrate;

public MigrationServiceImpl(HistoryRepository historyRepository,
int waitUntilUnlockedMinTimeInMillis,
int waitUntilUnlockedMaxTimeInMillis,
RestClient restClient,
ContentType defaultContentType,
Charset encoding) {
Charset encoding,
boolean validateOnMigrate) {
this.historyRepository = requireNonNull(historyRepository, "historyRepository must not be null");
this.restClient = requireNonNull(restClient, "restClient must not be null");
this.defaultContentType = requireNonNull(defaultContentType);
this.encoding = requireNonNull(encoding);
this.validateOnMigrate = validateOnMigrate;
this.waitUntilUnlockedMinTimeInMillis = requireCondition(waitUntilUnlockedMinTimeInMillis,
min -> min >= 0 && min <= waitUntilUnlockedMaxTimeInMillis,
"waitUntilUnlockedMinTimeInMillis (%s) must not be negative and must not be greater than waitUntilUnlockedMaxTimeInMillis (%s)",
Expand Down Expand Up @@ -185,9 +188,20 @@ List<ParsedMigrationScript> getPendingScriptsToBeExecuted(Collection<ParsedMigra
ParsedMigrationScript parsedMigrationScript = orderedScripts.get(i);
if (!protocol.getVersion().equals(parsedMigrationScript.getFileNameInfo().getVersion())) {
throw new MigrationException(String.format(
"The logged execution in the Elasticsearch-Evolution history index at position %s is version %s and in the same position in the given migration scripts is version %s! Out of order execution is not supported. Or maybe you have added new migration scripts in between or have to cleanup the Elasticsearch-Evolution history index manually",
"The logged execution in the Elasticsearch-Evolution history index at position %s " +
"is version %s and in the same position in the given migration scripts is version %s! " +
"Out of order execution is not supported. Or maybe you have added new migration scripts " +
"in between or have to cleanup the Elasticsearch-Evolution history index manually",
i, protocol.getVersion(), parsedMigrationScript.getFileNameInfo().getVersion()));
}
// failed scripts can be edited and retried, but successfully executed scripts may not be modified afterwards
if (validateOnMigrate && protocol.isSuccess() && protocol.getChecksum() != parsedMigrationScript.getChecksum()) {
throw new MigrationException(String.format(
"The logged execution for the migration script at position %s (%s) " +
"has a different checksum from the given migration script! " +
"Modifying already-executed scripts is not supported.",
i, protocol.getScriptName()));
}

if (protocol.isSuccess()) {
res.remove(parsedMigrationScript);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ void OK_indexDocumentIsWrittenToElasticsearch(String versionInfo, EsUtils esUtil

MigrationServiceImpl underTest = new MigrationServiceImpl(historyRepositoryMock,
0, 0, restHighLevelClient.getLowLevelClient(),
defaultContentType, encoding);
defaultContentType, encoding, true);

MigrationScriptProtocol res = underTest.executeScript(script).getProtocol();

Expand Down
Loading