use of liquibase.precondition.ErrorPrecondition in project liquibase by liquibase.
the class PreconditionContainer method check.
@Override
public void check(Database database, DatabaseChangeLog changeLog, ChangeSet changeSet) throws PreconditionFailedException, PreconditionErrorException {
String ranOn = String.valueOf(changeLog);
if (changeSet != null) {
ranOn = String.valueOf(changeSet);
}
Executor executor = ExecutorService.getInstance().getExecutor(database);
try {
// Three cases for preConditions onUpdateSQL:
// 1. TEST: preConditions should be run, as in regular update mode
// 2. FAIL: the preConditions should fail if there are any
// 3. IGNORE: act as if preConditions don't exist
boolean testPrecondition = false;
if (executor.updatesDatabase()) {
testPrecondition = true;
} else {
if (this.getOnSqlOutput().equals(PreconditionContainer.OnSqlOutputOption.TEST)) {
testPrecondition = true;
} else if (this.getOnSqlOutput().equals(PreconditionContainer.OnSqlOutputOption.FAIL)) {
throw new PreconditionFailedException("Unexpected precondition in updateSQL mode with onUpdateSQL value: " + this.getOnSqlOutput(), changeLog, this);
} else if (this.getOnSqlOutput().equals(PreconditionContainer.OnSqlOutputOption.IGNORE)) {
testPrecondition = false;
}
}
if (testPrecondition) {
super.check(database, changeLog, changeSet);
}
} catch (PreconditionFailedException e) {
StringBuffer message = new StringBuffer();
message.append(" ").append(e.getFailedPreconditions().size()).append(" preconditions failed").append(StreamUtil.getLineSeparator());
for (FailedPrecondition invalid : e.getFailedPreconditions()) {
message.append(" ").append(invalid.toString());
message.append(StreamUtil.getLineSeparator());
}
if (getOnFailMessage() != null) {
message = new StringBuffer(getOnFailMessage());
}
if (this.getOnFail().equals(PreconditionContainer.FailOption.WARN)) {
LogFactory.getLogger().info("Executing: " + ranOn + " despite precondition failure due to onFail='WARN':\n " + message);
} else {
if (getOnFailMessage() == null) {
throw e;
} else {
throw new PreconditionFailedException(getOnFailMessage(), changeLog, this);
}
}
} catch (PreconditionErrorException e) {
StringBuffer message = new StringBuffer();
message.append(" ").append(e.getErrorPreconditions().size()).append(" preconditions failed").append(StreamUtil.getLineSeparator());
for (ErrorPrecondition invalid : e.getErrorPreconditions()) {
message.append(" ").append(invalid.toString());
message.append(StreamUtil.getLineSeparator());
}
if (this.getOnError().equals(PreconditionContainer.ErrorOption.CONTINUE)) {
LogFactory.getLogger().info("Continuing past: " + toString() + " despite precondition error:\n " + message);
throw e;
} else if (this.getOnError().equals(PreconditionContainer.ErrorOption.WARN)) {
LogFactory.getLogger().warning("Continuing past: " + toString() + " despite precondition error:\n " + message);
} else {
if (getOnErrorMessage() == null) {
throw e;
} else {
throw new PreconditionErrorException(getOnErrorMessage(), e.getErrorPreconditions());
}
}
}
}
use of liquibase.precondition.ErrorPrecondition in project liquibase by liquibase.
the class ValidationFailedException method getMessage.
@Override
public String getMessage() {
StringBuilder message = new StringBuilder();
String separator = StreamUtil.getLineSeparator();
message.append(coreBundle.getString("validation.failed")).append(separator);
if (!invalidMD5Sums.isEmpty()) {
message.append(INDENT_SPACES).append(String.format(coreBundle.getString("check.sum.changed"), invalidMD5Sums.size())).append(separator);
for (int i = 0; i < invalidMD5Sums.size(); i++) {
if (i > 25) {
break;
}
message.append(" ").append(invalidMD5Sums.get(i));
message.append(separator);
}
}
if (!failedPreconditions.isEmpty()) {
message.append(INDENT_SPACES).append(String.format(coreBundle.getString("preconditions.failed"), failedPreconditions.size())).append(separator);
for (FailedPrecondition invalid : failedPreconditions) {
message.append(INDENT_SPACES).append(invalid.toString());
message.append(separator);
}
}
if (!errorPreconditions.isEmpty()) {
message.append(INDENT_SPACES).append(String.format(coreBundle.getString("preconditions.generated.error"), errorPreconditions.size())).append(separator);
for (ErrorPrecondition invalid : errorPreconditions) {
message.append(INDENT_SPACES).append(invalid.toString());
message.append(separator);
}
}
if (!duplicateChangeSets.isEmpty()) {
message.append(INDENT_SPACES).append(String.format(coreBundle.getString("change.sets.duplicate.identifiers"), duplicateChangeSets.size())).append(separator);
for (ChangeSet invalid : duplicateChangeSets) {
message.append(" ").append(invalid.toString(false));
message.append(separator);
}
}
if (!setupExceptions.isEmpty()) {
message.append(INDENT_SPACES).append(String.format(coreBundle.getString("changes.have.failures"), setupExceptions.size())).append(separator);
for (SetupException invalid : setupExceptions) {
message.append(" ").append(invalid.toString());
message.append(separator);
}
}
if (!changeValidationExceptions.isEmpty()) {
message.append(INDENT_SPACES).append(String.format(coreBundle.getString("changes.have.validation.errors"), changeValidationExceptions.size())).append(separator);
for (Throwable invalid : changeValidationExceptions) {
Scope.getCurrentScope().getLog(getClass()).fine(coreBundle.getString("validation.exception"), invalid);
message.append(" ").append(invalid.toString());
message.append(separator);
}
}
if (validationErrors.hasErrors()) {
message.append(INDENT_SPACES).append(String.format(coreBundle.getString("changes.have.validation.failures"), validationErrors.getErrorMessages().size())).append(separator);
for (String invalid : validationErrors.getErrorMessages()) {
message.append(" ").append(invalid);
message.append(separator);
}
}
return message.toString();
}
use of liquibase.precondition.ErrorPrecondition in project liquibase by liquibase.
the class ChangeSet method execute.
/**
* This method will actually execute each of the changes in the list against the
* specified database.
*
* @return should change set be marked as ran
*/
public ExecType execute(DatabaseChangeLog databaseChangeLog, ChangeExecListener listener, Database database) throws MigrationFailedException {
Logger log = Scope.getCurrentScope().getLog(getClass());
if (validationFailed) {
return ExecType.MARK_RAN;
}
long startTime = new Date().getTime();
ExecType execType = null;
boolean skipChange = false;
Executor originalExecutor = setupCustomExecutorIfNecessary(database);
try {
Executor executor = Scope.getCurrentScope().getSingleton(ExecutorService.class).getExecutor("jdbc", database);
// set object quoting strategy
database.setObjectQuotingStrategy(objectQuotingStrategy);
if (database.supportsDDLInTransaction()) {
database.setAutoCommit(!runInTransaction);
}
executor.comment("Changeset " + toString(false));
if (StringUtil.trimToNull(getComments()) != null) {
String comments = getComments();
String[] lines = comments.split("\\n");
for (int i = 0; i < lines.length; i++) {
if (i > 0) {
lines[i] = database.getLineComment() + " " + lines[i];
}
}
executor.comment(StringUtil.join(Arrays.asList(lines), "\n"));
}
try {
if (preconditions != null) {
preconditions.check(database, databaseChangeLog, this, listener);
}
} catch (PreconditionFailedException e) {
if (listener != null) {
listener.preconditionFailed(e, preconditions.getOnFail());
}
StringBuilder message = new StringBuilder();
message.append(StreamUtil.getLineSeparator());
for (FailedPrecondition invalid : e.getFailedPreconditions()) {
message.append(" ").append(invalid.toString());
message.append(StreamUtil.getLineSeparator());
}
if (preconditions.getOnFail().equals(PreconditionContainer.FailOption.HALT)) {
throw new MigrationFailedException(this, message.toString(), e);
} else if (preconditions.getOnFail().equals(PreconditionContainer.FailOption.CONTINUE)) {
skipChange = true;
execType = ExecType.SKIPPED;
Scope.getCurrentScope().getLog(getClass()).info("Continuing past: " + toString() + " despite precondition failure due to onFail='CONTINUE': " + message);
} else if (preconditions.getOnFail().equals(PreconditionContainer.FailOption.MARK_RAN)) {
execType = ExecType.MARK_RAN;
skipChange = true;
log.info("Marking ChangeSet: " + toString() + " ran despite precondition failure due to onFail='MARK_RAN': " + message);
} else if (preconditions.getOnFail().equals(PreconditionContainer.FailOption.WARN)) {
// already warned
execType = null;
} else {
throw new UnexpectedLiquibaseException("Unexpected precondition onFail attribute: " + preconditions.getOnFail(), e);
}
} catch (PreconditionErrorException e) {
if (listener != null) {
listener.preconditionErrored(e, preconditions.getOnError());
}
StringBuilder message = new StringBuilder();
message.append(StreamUtil.getLineSeparator());
for (ErrorPrecondition invalid : e.getErrorPreconditions()) {
message.append(" ").append(invalid.toString());
message.append(StreamUtil.getLineSeparator());
}
if (preconditions.getOnError().equals(PreconditionContainer.ErrorOption.HALT)) {
throw new MigrationFailedException(this, message.toString(), e);
} else if (preconditions.getOnError().equals(PreconditionContainer.ErrorOption.CONTINUE)) {
skipChange = true;
execType = ExecType.SKIPPED;
} else if (preconditions.getOnError().equals(PreconditionContainer.ErrorOption.MARK_RAN)) {
execType = ExecType.MARK_RAN;
skipChange = true;
log.info("Marking ChangeSet: " + toString() + " ran despite precondition error: " + message);
} else if (preconditions.getOnError().equals(PreconditionContainer.ErrorOption.WARN)) {
// already logged
execType = null;
} else {
throw new UnexpectedLiquibaseException("Unexpected precondition onError attribute: " + preconditions.getOnError(), e);
}
database.rollback();
} finally {
database.rollback();
}
if (!skipChange) {
for (Change change : changes) {
try {
change.finishInitialization();
} catch (SetupException se) {
throw new MigrationFailedException(this, se);
}
}
log.fine("Reading ChangeSet: " + toString());
for (Change change : getChanges()) {
if ((!(change instanceof DbmsTargetedChange)) || DatabaseList.definitionMatches(((DbmsTargetedChange) change).getDbms(), database, true)) {
if (listener != null) {
listener.willRun(change, this, changeLog, database);
}
if (change.generateStatementsVolatile(database)) {
executor.comment("WARNING The following SQL may change each run and therefore is possibly incorrect and/or invalid:");
}
database.executeStatements(change, databaseChangeLog, sqlVisitors);
log.info(change.getConfirmationMessage());
if (listener != null) {
listener.ran(change, this, changeLog, database);
}
} else {
log.fine("Change " + change.getSerializedObjectName() + " not included for database " + database.getShortName());
}
}
if (runInTransaction) {
database.commit();
}
log.info("ChangeSet " + toString(false) + " ran successfully in " + (new Date().getTime() - startTime + "ms"));
if (execType == null) {
execType = ExecType.EXECUTED;
}
} else {
log.fine("Skipping ChangeSet: " + toString());
}
} catch (Exception e) {
try {
database.rollback();
} catch (Exception e1) {
throw new MigrationFailedException(this, e);
}
if ((getFailOnError() != null) && !getFailOnError()) {
log.info("Change set " + toString(false) + " failed, but failOnError was false. Error: " + e.getMessage());
log.fine("Failure Stacktrace", e);
execType = ExecType.FAILED;
} else {
if (e instanceof MigrationFailedException) {
throw ((MigrationFailedException) e);
} else {
throw new MigrationFailedException(this, e);
}
}
} finally {
Scope.getCurrentScope().getSingleton(ExecutorService.class).setExecutor("jdbc", database, originalExecutor);
// but only if the database supports DDL in transactions
if (!runInTransaction && database.supportsDDLInTransaction()) {
try {
database.setAutoCommit(false);
} catch (DatabaseException e) {
Scope.getCurrentScope().getLog(getClass()).warning("Could not resetInternalState autocommit", e);
}
}
}
return execType;
}
use of liquibase.precondition.ErrorPrecondition in project liquibase by liquibase.
the class PreconditionContainer method check.
@Override
public void check(Database database, DatabaseChangeLog changeLog, ChangeSet changeSet, ChangeExecListener changeExecListener) throws PreconditionFailedException, PreconditionErrorException {
String ranOn = String.valueOf(changeLog);
if (changeSet != null) {
ranOn = String.valueOf(changeSet);
}
Executor executor = Scope.getCurrentScope().getSingleton(ExecutorService.class).getExecutor("jdbc", database);
try {
// Three cases for preConditions onUpdateSQL:
// 1. TEST: preConditions should be run, as in regular update mode
// 2. FAIL: the preConditions should fail if there are any
// 3. IGNORE: act as if preConditions don't exist
boolean testPrecondition = false;
if (executor.updatesDatabase()) {
testPrecondition = true;
} else {
if (this.getOnSqlOutput().equals(PreconditionContainer.OnSqlOutputOption.TEST)) {
testPrecondition = true;
} else if (this.getOnSqlOutput().equals(PreconditionContainer.OnSqlOutputOption.FAIL)) {
throw new PreconditionFailedException("Unexpected precondition in updateSQL mode with onUpdateSQL value: " + this.getOnSqlOutput(), changeLog, this);
} else if (this.getOnSqlOutput().equals(PreconditionContainer.OnSqlOutputOption.IGNORE)) {
testPrecondition = false;
}
}
if (testPrecondition) {
super.check(database, changeLog, changeSet, changeExecListener);
}
} catch (PreconditionFailedException e) {
StringBuilder message = new StringBuilder();
message.append(" ").append(e.getFailedPreconditions().size()).append(" preconditions failed").append(StreamUtil.getLineSeparator());
for (FailedPrecondition invalid : e.getFailedPreconditions()) {
message.append(" ").append(invalid.toString());
message.append(StreamUtil.getLineSeparator());
}
if (getOnFailMessage() != null) {
message = new StringBuilder(getOnFailMessage());
}
if (this.getOnFail().equals(PreconditionContainer.FailOption.WARN)) {
final String exceptionMessage = "Executing " + ranOn + " despite precondition failure due to onFail='WARN':\n " + message;
Scope.getCurrentScope().getUI().sendMessage("WARNING: " + exceptionMessage);
Scope.getCurrentScope().getLog(getClass()).warning(exceptionMessage);
if (changeExecListener != null) {
changeExecListener.preconditionFailed(e, FailOption.WARN);
}
} else {
if (getOnFailMessage() == null) {
throw e;
} else {
throw new PreconditionFailedException(getOnFailMessage(), changeLog, this);
}
}
} catch (PreconditionErrorException e) {
StringBuilder message = new StringBuilder();
message.append(" ").append(e.getErrorPreconditions().size()).append(" preconditions failed").append(StreamUtil.getLineSeparator());
for (ErrorPrecondition invalid : e.getErrorPreconditions()) {
message.append(" ").append(invalid.toString());
message.append(StreamUtil.getLineSeparator());
}
if (this.getOnError().equals(PreconditionContainer.ErrorOption.CONTINUE)) {
Scope.getCurrentScope().getLog(getClass()).info("Continuing past: " + toString() + " despite precondition error:\n " + message);
throw e;
} else if (this.getOnError().equals(PreconditionContainer.ErrorOption.WARN)) {
Scope.getCurrentScope().getLog(getClass()).warning("Continuing past: " + toString() + " despite precondition error:\n " + message);
if (changeExecListener != null) {
changeExecListener.preconditionErrored(e, ErrorOption.WARN);
}
} else {
if (getOnErrorMessage() == null) {
throw e;
} else {
throw new PreconditionErrorException(getOnErrorMessage(), e.getErrorPreconditions());
}
}
}
}
Aggregations