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

Added Baseline functionality. #17

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 6 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,12 @@
<version>1.7.13</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.13</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package com.contrastsecurity.cassandra.migration;

import com.contrastsecurity.cassandra.migration.action.Baseline;
import com.contrastsecurity.cassandra.migration.action.Initialize;
import com.contrastsecurity.cassandra.migration.action.Migrate;
import com.contrastsecurity.cassandra.migration.action.Validate;
import com.contrastsecurity.cassandra.migration.config.Keyspace;
import com.contrastsecurity.cassandra.migration.config.MigrationConfigs;
import com.contrastsecurity.cassandra.migration.config.ScriptsLocations;
Expand All @@ -17,7 +19,6 @@
import com.datastax.driver.core.KeyspaceMetadata;
import com.datastax.driver.core.Metadata;
import com.datastax.driver.core.Session;
import sun.reflect.generics.reflectiveObjects.NotImplementedException;

import java.util.List;

Expand All @@ -28,6 +29,8 @@ public class CassandraMigration {
private ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
private Keyspace keyspace;
private MigrationConfigs configs;
private MigrationVersion baselineVersion = MigrationVersion.fromVersion("1");
private String baselineDescription = "<< Cassandra Baseline >>";

public CassandraMigration() {
this.keyspace = new Keyspace();
Expand Down Expand Up @@ -59,7 +62,7 @@ public MigrationConfigs getConfigs() {
return configs;
}

private MigrationResolver createMigrationResolver() {
protected MigrationResolver createMigrationResolver() {
return new CompositeMigrationResolver(classLoader, new ScriptsLocations(configs.getScriptsLocations()), configs.getEncoding());
}

Expand Down Expand Up @@ -92,9 +95,33 @@ public MigrationInfoService execute(Session session) {
});
}

public void validate() {
String validationError = execute(new Action<String>() {
@Override
public String execute(Session session) {
MigrationResolver migrationResolver = createMigrationResolver();
SchemaVersionDAO schemaVersionDao = new SchemaVersionDAO(session, keyspace, MigrationVersion.CURRENT.getTable());
Validate validate = new Validate(migrationResolver, schemaVersionDao, configs.getTarget(), true, false);
return validate.run();
}
});

if (validationError != null) {
throw new CassandraMigrationException("Validation failed. " + validationError);
}
}

public void baseline() {
//TODO
throw new NotImplementedException();
execute(new Action<Void>() {
@Override
public Void execute(Session session) {
MigrationResolver migrationResolver = createMigrationResolver();
SchemaVersionDAO schemaVersionDao = new SchemaVersionDAO(session, keyspace, MigrationVersion.CURRENT.getTable());
Baseline baseLine = new Baseline(schemaVersionDao, migrationResolver, baselineVersion, baselineDescription );
baseLine.run();
return null;
}
});
}

private String getConnectionInfo(Metadata metadata) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,21 @@
import java.util.List;

public class CommandLine {
/**
* command to trigger migrate action
*/
public static final String MIGRATE = "migrate";

/**
* command to trigger validate action
*/
public static final String VALIDATE = "validate";

/**
* command to trigger baseline action
*/
public static final String BASELINE = "baseline";

private static Log LOG;

public static void main(String[] args) {
Expand All @@ -22,10 +37,18 @@ public static void main(String[] args) {
return;
}

String operation = operations.get(0);

CassandraMigration cm = new CassandraMigration();
Keyspace ks = new Keyspace();
cm.setKeyspace(ks);
cm.migrate();
if (MIGRATE.equalsIgnoreCase(operation)) {
cm.migrate();
} else if (VALIDATE.equalsIgnoreCase(operation)) {
cm.validate();
}else if(BASELINE.equalsIgnoreCase(operation)){
cm.baseline();
}
}

private static List<String> determineOperations(String[] args) {
Expand Down Expand Up @@ -67,6 +90,8 @@ private static void printUsage() {
LOG.info("Commands");
LOG.info("========");
LOG.info("migrate : Migrates the database");
LOG.info("validate : Validates the applied migrations against the available ones");
LOG.info("baseline : Baselines an existing database, excluding all migrations upto and including baselineVersion");
LOG.info("");
LOG.info("Add -X to print debug output");
LOG.info("Add -q to suppress all output, except for errors and warnings");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package com.contrastsecurity.cassandra.migration.action;

import com.contrastsecurity.cassandra.migration.CassandraMigrationException;
import com.contrastsecurity.cassandra.migration.dao.SchemaVersionDAO;
import com.contrastsecurity.cassandra.migration.info.AppliedMigration;
import com.contrastsecurity.cassandra.migration.info.MigrationVersion;
import com.contrastsecurity.cassandra.migration.resolver.MigrationResolver;

public class Baseline {

private SchemaVersionDAO schemaVersionDao;
private MigrationResolver migrationResolver;
private MigrationVersion baselineVersion;
private String baselineDescription;

public Baseline(SchemaVersionDAO schemaVersionDao, MigrationResolver migrationResolver, MigrationVersion baselineVersion, String baselineDescription) {
this.schemaVersionDao = schemaVersionDao;
this.migrationResolver = migrationResolver;
this.baselineVersion = baselineVersion;
this.baselineDescription = baselineDescription;
}

public void run() {
AppliedMigration baselineMigration = schemaVersionDao.getBaselineMarker();
if (schemaVersionDao.hasAppliedMigrations()) {
throw new CassandraMigrationException("Unable to baseline metadata table " + schemaVersionDao.getTableName() + " as it already contains migrations");
}
if (schemaVersionDao.hasBaselineMarker()) {
if (!baselineMigration.getVersion().equals(baselineVersion) || !baselineMigration.getDescription().equals(baselineDescription)) {
throw new CassandraMigrationException("Unable to baseline metadata table " + schemaVersionDao.getTableName() + " with (" + baselineVersion +
"," + baselineDescription + ") as it has already been initialized with (" + baselineMigration.getVersion() + "," + baselineMigration
.getDescription() + ")");
}
} else {
if (baselineVersion.equals(MigrationVersion.fromVersion("0"))) {
throw new CassandraMigrationException("Unable to baseline metadata table " + schemaVersionDao.getTableName() + " with version 0 as this " +
"version was used for schema creation");
}
schemaVersionDao.addBaselineMarker(baselineVersion, baselineDescription);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@

import com.contrastsecurity.cassandra.migration.CassandraMigrationException;
import com.contrastsecurity.cassandra.migration.dao.SchemaVersionDAO;
import com.contrastsecurity.cassandra.migration.info.*;
import com.contrastsecurity.cassandra.migration.info.AppliedMigration;
import com.contrastsecurity.cassandra.migration.info.MigrationInfo;
import com.contrastsecurity.cassandra.migration.info.MigrationInfoService;
import com.contrastsecurity.cassandra.migration.info.MigrationState;
import com.contrastsecurity.cassandra.migration.info.MigrationVersion;
import com.contrastsecurity.cassandra.migration.logging.Log;
import com.contrastsecurity.cassandra.migration.logging.LogFactory;
import com.contrastsecurity.cassandra.migration.resolver.MigrationExecutor;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package com.contrastsecurity.cassandra.migration.action;

import com.contrastsecurity.cassandra.migration.dao.SchemaVersionDAO;
import com.contrastsecurity.cassandra.migration.info.MigrationInfoService;
import com.contrastsecurity.cassandra.migration.info.MigrationVersion;
import com.contrastsecurity.cassandra.migration.logging.Log;
import com.contrastsecurity.cassandra.migration.logging.LogFactory;
import com.contrastsecurity.cassandra.migration.resolver.MigrationResolver;
import com.contrastsecurity.cassandra.migration.utils.StopWatch;
import com.contrastsecurity.cassandra.migration.utils.TimeFormat;

/**
* Validates the applied migrations against the available ones.
*/
public class Validate {

/**
* logging support
*/
private static final Log LOG = LogFactory.getLog(Validate.class);

private SchemaVersionDAO schemaVersionDao;

/**
* migration resolver
*/
private MigrationResolver migrationResolver;

/**
* migration target
*/
private MigrationVersion migrationTarget;

private boolean outOfOrder;

private boolean pendingOrFuture;

public Validate(MigrationResolver migrationResolver, SchemaVersionDAO schemaVersionDao, MigrationVersion migrationTarget, boolean outOfOrder, boolean pendingOrFuture) {
this.schemaVersionDao = schemaVersionDao;
this.migrationResolver = migrationResolver;
this.migrationTarget = migrationTarget;
this.outOfOrder = outOfOrder;
this.pendingOrFuture = pendingOrFuture;
}

public String run() {
StopWatch stopWatch = new StopWatch();
stopWatch.start();

MigrationInfoService infoService = new MigrationInfoService(migrationResolver, schemaVersionDao, migrationTarget, outOfOrder, pendingOrFuture);
infoService.refresh();
int count = infoService.all().length;
String validationError = infoService.validate();

stopWatch.stop();

LOG.info(String.format("Validated %d migrations (execution time %s)", count, TimeFormat.format(stopWatch.getTotalTimeMillis())));

return validationError;
}
}