From 72d742c21cd785303e72424dce4374aa79d17b16 Mon Sep 17 00:00:00 2001 From: Seweryn Walendzik Date: Wed, 8 Mar 2017 16:55:06 +0100 Subject: [PATCH 1/7] Support escaped keyspace names #26 --- .../cassandra/migration/CassandraMigration.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/contrastsecurity/cassandra/migration/CassandraMigration.java b/src/main/java/com/contrastsecurity/cassandra/migration/CassandraMigration.java index 043b956..9e2adac 100644 --- a/src/main/java/com/contrastsecurity/cassandra/migration/CassandraMigration.java +++ b/src/main/java/com/contrastsecurity/cassandra/migration/CassandraMigration.java @@ -162,8 +162,9 @@ T execute(Action action) { throw new IllegalArgumentException("Keyspace not specified."); List keyspaces = metadata.getKeyspaces(); boolean keyspaceExists = false; + String keyspaceName = keyspace.getName().replace("\"", ""); //remove quotation marks for (KeyspaceMetadata keyspaceMetadata : keyspaces) { - if (keyspaceMetadata.getName().equalsIgnoreCase(keyspace.getName())) + if (keyspaceMetadata.getName().equalsIgnoreCase(keyspaceName)) keyspaceExists = true; } if (keyspaceExists) From 6b1d7237d9690713ec7385a038f55b2c5700846d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20Kr=C3=B3l?= Date: Thu, 6 Apr 2017 13:10:56 +0200 Subject: [PATCH 2/7] Added External Java Resolver. --- .../resolver/CompositeMigrationResolver.java | 10 +++ .../resolver/java/CommonJavaResolver.java | 84 +++++++++++++++++++ .../java/ExternalJavaMigrationResolver.java | 65 ++++++++++++++ .../resolver/java/JavaMigrationResolver.java | 68 +-------------- 4 files changed, 161 insertions(+), 66 deletions(-) create mode 100644 src/main/java/com/contrastsecurity/cassandra/migration/resolver/java/CommonJavaResolver.java create mode 100644 src/main/java/com/contrastsecurity/cassandra/migration/resolver/java/ExternalJavaMigrationResolver.java diff --git a/src/main/java/com/contrastsecurity/cassandra/migration/resolver/CompositeMigrationResolver.java b/src/main/java/com/contrastsecurity/cassandra/migration/resolver/CompositeMigrationResolver.java index 2177a0b..d4295dc 100644 --- a/src/main/java/com/contrastsecurity/cassandra/migration/resolver/CompositeMigrationResolver.java +++ b/src/main/java/com/contrastsecurity/cassandra/migration/resolver/CompositeMigrationResolver.java @@ -20,8 +20,13 @@ import com.contrastsecurity.cassandra.migration.config.ScriptsLocations; import com.contrastsecurity.cassandra.migration.info.ResolvedMigration; import com.contrastsecurity.cassandra.migration.resolver.cql.CqlMigrationResolver; +import com.contrastsecurity.cassandra.migration.resolver.java.ExternalJavaMigrationResolver; import com.contrastsecurity.cassandra.migration.resolver.java.JavaMigrationResolver; +import java.io.File; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; import java.util.*; /** @@ -54,6 +59,11 @@ public CompositeMigrationResolver(ClassLoader classLoader, ScriptsLocations loca for (ScriptsLocation location : locations.getLocations()) { migrationResolvers.add(new CqlMigrationResolver(classLoader, location, encoding)); migrationResolvers.add(new JavaMigrationResolver(classLoader, location)); + try { + migrationResolvers.add(new ExternalJavaMigrationResolver(new URLClassLoader(new URL[]{new File(location.getPath()).toURI().toURL()}, this.getClass().getClassLoader()), location)); + } catch (MalformedURLException e) { + throw new CassandraMigrationException("Unable to add external url for classes migrations in location: " + location, e); + } } migrationResolvers.addAll(Arrays.asList(customMigrationResolvers)); diff --git a/src/main/java/com/contrastsecurity/cassandra/migration/resolver/java/CommonJavaResolver.java b/src/main/java/com/contrastsecurity/cassandra/migration/resolver/java/CommonJavaResolver.java new file mode 100644 index 0000000..3504bfa --- /dev/null +++ b/src/main/java/com/contrastsecurity/cassandra/migration/resolver/java/CommonJavaResolver.java @@ -0,0 +1,84 @@ +package com.contrastsecurity.cassandra.migration.resolver.java; + +import com.contrastsecurity.cassandra.migration.CassandraMigrationException; +import com.contrastsecurity.cassandra.migration.api.JavaMigration; +import com.contrastsecurity.cassandra.migration.api.MigrationChecksumProvider; +import com.contrastsecurity.cassandra.migration.api.MigrationInfoProvider; +import com.contrastsecurity.cassandra.migration.config.MigrationType; +import com.contrastsecurity.cassandra.migration.config.ScriptsLocation; +import com.contrastsecurity.cassandra.migration.info.MigrationVersion; +import com.contrastsecurity.cassandra.migration.info.ResolvedMigration; +import com.contrastsecurity.cassandra.migration.resolver.MigrationInfoHelper; +import com.contrastsecurity.cassandra.migration.utils.ClassUtils; +import com.contrastsecurity.cassandra.migration.utils.Pair; +import com.contrastsecurity.cassandra.migration.utils.StringUtils; +import com.contrastsecurity.cassandra.migration.utils.scanner.Scanner; + +import java.util.List; + +/** + * Created by Adam Król on 06.04.2017. + * + * @author Adam Król + */ +public class CommonJavaResolver { + + public void loadJavaMigrationFiles(ClassLoader classLoader, ScriptsLocation location, List migrations) { + try { + Class[] classes = new Scanner(classLoader).scanForClasses(location, JavaMigration.class); + for (Class clazz : classes) { + JavaMigration javaMigration = ClassUtils.instantiate(clazz.getName(), classLoader); + + ResolvedMigration migrationInfo = extractMigrationInfo(javaMigration); + migrationInfo.setPhysicalLocation(ClassUtils.getLocationOnDisk(clazz)); + migrationInfo.setExecutor(new JavaMigrationExecutor(javaMigration)); + + migrations.add(migrationInfo); + } + } catch (Exception e) { + throw new CassandraMigrationException("Unable to resolve Java migrations in location: " + location, e); + } + } + + /** + * Extracts the migration info from this migration. + * + * @param javaMigration The migration to analyse. + * @return The migration info. + */ + public ResolvedMigration extractMigrationInfo(JavaMigration javaMigration) { + Integer checksum = null; + if (javaMigration instanceof MigrationChecksumProvider) { + MigrationChecksumProvider checksumProvider = (MigrationChecksumProvider) javaMigration; + checksum = checksumProvider.getChecksum(); + } + + MigrationVersion version; + String description; + if (javaMigration instanceof MigrationInfoProvider) { + MigrationInfoProvider infoProvider = (MigrationInfoProvider) javaMigration; + version = infoProvider.getVersion(); + description = infoProvider.getDescription(); + if (!StringUtils.hasText(description)) { + throw new CassandraMigrationException("Missing description for migration " + version); + } + } else { + Pair info = + MigrationInfoHelper.extractVersionAndDescription( + ClassUtils.getShortName(javaMigration.getClass()), "V", "__", ""); + version = info.getLeft(); + description = info.getRight(); + } + + String script = javaMigration.getClass().getName(); + + + ResolvedMigration resolvedMigration = new ResolvedMigration(); + resolvedMigration.setVersion(version); + resolvedMigration.setDescription(description); + resolvedMigration.setScript(script); + resolvedMigration.setChecksum(checksum); + resolvedMigration.setType(MigrationType.JAVA_DRIVER); + return resolvedMigration; + } +} diff --git a/src/main/java/com/contrastsecurity/cassandra/migration/resolver/java/ExternalJavaMigrationResolver.java b/src/main/java/com/contrastsecurity/cassandra/migration/resolver/java/ExternalJavaMigrationResolver.java new file mode 100644 index 0000000..3526361 --- /dev/null +++ b/src/main/java/com/contrastsecurity/cassandra/migration/resolver/java/ExternalJavaMigrationResolver.java @@ -0,0 +1,65 @@ +/** + * Copyright 2010-2015 Axel Fontaine + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.contrastsecurity.cassandra.migration.resolver.java; + +import com.contrastsecurity.cassandra.migration.config.ScriptsLocation; +import com.contrastsecurity.cassandra.migration.info.ResolvedMigration; +import com.contrastsecurity.cassandra.migration.resolver.MigrationResolver; +import com.contrastsecurity.cassandra.migration.resolver.ResolvedMigrationComparator; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * Migration resolver for Java migrations. The classes must have a name like V1 or V1_1_3 or V1__Description + * or V1_1_3__Description. + */ +public class ExternalJavaMigrationResolver extends CommonJavaResolver implements MigrationResolver { + /** + * The base package on the classpath where to migrations are located. + */ + private final ScriptsLocation location; + + /** + * The ClassLoader to use. + */ + private ClassLoader classLoader; + + /** + * Creates a new instance. + * + * @param location The base package on the classpath where to migrations are located. + * @param classLoader The ClassLoader for loading migrations on the classpath. + */ + public ExternalJavaMigrationResolver(ClassLoader classLoader, ScriptsLocation location) { + this.location = location; + this.classLoader = classLoader; + } + + public List resolveMigrations() { + List migrations = new ArrayList(); + + if (!location.isFileSystem()) { + return migrations; + } + + loadJavaMigrationFiles(classLoader, new ScriptsLocation(""), migrations); + + Collections.sort(migrations, new ResolvedMigrationComparator()); + return migrations; + } +} diff --git a/src/main/java/com/contrastsecurity/cassandra/migration/resolver/java/JavaMigrationResolver.java b/src/main/java/com/contrastsecurity/cassandra/migration/resolver/java/JavaMigrationResolver.java index c85c430..f64f0fe 100644 --- a/src/main/java/com/contrastsecurity/cassandra/migration/resolver/java/JavaMigrationResolver.java +++ b/src/main/java/com/contrastsecurity/cassandra/migration/resolver/java/JavaMigrationResolver.java @@ -15,21 +15,10 @@ */ package com.contrastsecurity.cassandra.migration.resolver.java; -import com.contrastsecurity.cassandra.migration.CassandraMigrationException; -import com.contrastsecurity.cassandra.migration.api.MigrationChecksumProvider; -import com.contrastsecurity.cassandra.migration.api.MigrationInfoProvider; -import com.contrastsecurity.cassandra.migration.api.JavaMigration; -import com.contrastsecurity.cassandra.migration.config.MigrationType; import com.contrastsecurity.cassandra.migration.config.ScriptsLocation; -import com.contrastsecurity.cassandra.migration.info.MigrationVersion; import com.contrastsecurity.cassandra.migration.info.ResolvedMigration; -import com.contrastsecurity.cassandra.migration.resolver.MigrationInfoHelper; import com.contrastsecurity.cassandra.migration.resolver.MigrationResolver; import com.contrastsecurity.cassandra.migration.resolver.ResolvedMigrationComparator; -import com.contrastsecurity.cassandra.migration.utils.ClassUtils; -import com.contrastsecurity.cassandra.migration.utils.Pair; -import com.contrastsecurity.cassandra.migration.utils.StringUtils; -import com.contrastsecurity.cassandra.migration.utils.scanner.Scanner; import java.util.ArrayList; import java.util.Collections; @@ -39,7 +28,7 @@ * Migration resolver for Java migrations. The classes must have a name like V1 or V1_1_3 or V1__Description * or V1_1_3__Description. */ -public class JavaMigrationResolver implements MigrationResolver { +public class JavaMigrationResolver extends CommonJavaResolver implements MigrationResolver { /** * The base package on the classpath where to migrations are located. */ @@ -68,64 +57,11 @@ public List resolveMigrations() { return migrations; } - try { - Class[] classes = new Scanner(classLoader).scanForClasses(location, JavaMigration.class); - for (Class clazz : classes) { - JavaMigration javaMigration = ClassUtils.instantiate(clazz.getName(), classLoader); - - ResolvedMigration migrationInfo = extractMigrationInfo(javaMigration); - migrationInfo.setPhysicalLocation(ClassUtils.getLocationOnDisk(clazz)); - migrationInfo.setExecutor(new JavaMigrationExecutor(javaMigration)); - - migrations.add(migrationInfo); - } - } catch (Exception e) { - throw new CassandraMigrationException("Unable to resolve Java migrations in location: " + location, e); - } + loadJavaMigrationFiles(classLoader, location, migrations); Collections.sort(migrations, new ResolvedMigrationComparator()); return migrations; } - /** - * Extracts the migration info from this migration. - * - * @param javaMigration The migration to analyse. - * @return The migration info. - */ - ResolvedMigration extractMigrationInfo(JavaMigration javaMigration) { - Integer checksum = null; - if (javaMigration instanceof MigrationChecksumProvider) { - MigrationChecksumProvider checksumProvider = (MigrationChecksumProvider) javaMigration; - checksum = checksumProvider.getChecksum(); - } - - MigrationVersion version; - String description; - if (javaMigration instanceof MigrationInfoProvider) { - MigrationInfoProvider infoProvider = (MigrationInfoProvider) javaMigration; - version = infoProvider.getVersion(); - description = infoProvider.getDescription(); - if (!StringUtils.hasText(description)) { - throw new CassandraMigrationException("Missing description for migration " + version); - } - } else { - Pair info = - MigrationInfoHelper.extractVersionAndDescription( - ClassUtils.getShortName(javaMigration.getClass()), "V", "__", ""); - version = info.getLeft(); - description = info.getRight(); - } - - String script = javaMigration.getClass().getName(); - - ResolvedMigration resolvedMigration = new ResolvedMigration(); - resolvedMigration.setVersion(version); - resolvedMigration.setDescription(description); - resolvedMigration.setScript(script); - resolvedMigration.setChecksum(checksum); - resolvedMigration.setType(MigrationType.JAVA_DRIVER); - return resolvedMigration; - } } From d6b7f536f6ab6f6e37273a6503c5853c78f13c00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20Kr=C3=B3l?= Date: Thu, 6 Apr 2017 20:27:28 +0200 Subject: [PATCH 3/7] Removed unnecessary list initializations. --- .../migration/resolver/java/CommonJavaResolver.java | 9 ++++++--- .../resolver/java/ExternalJavaMigrationResolver.java | 5 ++--- .../migration/resolver/java/JavaMigrationResolver.java | 6 ++---- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/contrastsecurity/cassandra/migration/resolver/java/CommonJavaResolver.java b/src/main/java/com/contrastsecurity/cassandra/migration/resolver/java/CommonJavaResolver.java index 3504bfa..ef0ff42 100644 --- a/src/main/java/com/contrastsecurity/cassandra/migration/resolver/java/CommonJavaResolver.java +++ b/src/main/java/com/contrastsecurity/cassandra/migration/resolver/java/CommonJavaResolver.java @@ -14,6 +14,7 @@ import com.contrastsecurity.cassandra.migration.utils.StringUtils; import com.contrastsecurity.cassandra.migration.utils.scanner.Scanner; +import java.util.LinkedList; import java.util.List; /** @@ -21,11 +22,12 @@ * * @author Adam Król */ -public class CommonJavaResolver { +class CommonJavaResolver { - public void loadJavaMigrationFiles(ClassLoader classLoader, ScriptsLocation location, List migrations) { + List loadJavaMigrationFiles(ClassLoader classLoader, ScriptsLocation location) { try { Class[] classes = new Scanner(classLoader).scanForClasses(location, JavaMigration.class); + List migrations = new LinkedList<>(); for (Class clazz : classes) { JavaMigration javaMigration = ClassUtils.instantiate(clazz.getName(), classLoader); @@ -35,6 +37,7 @@ public void loadJavaMigrationFiles(ClassLoader classLoader, ScriptsLocation loca migrations.add(migrationInfo); } + return migrations; } catch (Exception e) { throw new CassandraMigrationException("Unable to resolve Java migrations in location: " + location, e); } @@ -46,7 +49,7 @@ public void loadJavaMigrationFiles(ClassLoader classLoader, ScriptsLocation loca * @param javaMigration The migration to analyse. * @return The migration info. */ - public ResolvedMigration extractMigrationInfo(JavaMigration javaMigration) { + ResolvedMigration extractMigrationInfo(JavaMigration javaMigration) { Integer checksum = null; if (javaMigration instanceof MigrationChecksumProvider) { MigrationChecksumProvider checksumProvider = (MigrationChecksumProvider) javaMigration; diff --git a/src/main/java/com/contrastsecurity/cassandra/migration/resolver/java/ExternalJavaMigrationResolver.java b/src/main/java/com/contrastsecurity/cassandra/migration/resolver/java/ExternalJavaMigrationResolver.java index 3526361..df140c7 100644 --- a/src/main/java/com/contrastsecurity/cassandra/migration/resolver/java/ExternalJavaMigrationResolver.java +++ b/src/main/java/com/contrastsecurity/cassandra/migration/resolver/java/ExternalJavaMigrationResolver.java @@ -51,13 +51,12 @@ public ExternalJavaMigrationResolver(ClassLoader classLoader, ScriptsLocation lo } public List resolveMigrations() { - List migrations = new ArrayList(); if (!location.isFileSystem()) { - return migrations; + return Collections.emptyList(); } - loadJavaMigrationFiles(classLoader, new ScriptsLocation(""), migrations); + List migrations = loadJavaMigrationFiles(classLoader, new ScriptsLocation("")); Collections.sort(migrations, new ResolvedMigrationComparator()); return migrations; diff --git a/src/main/java/com/contrastsecurity/cassandra/migration/resolver/java/JavaMigrationResolver.java b/src/main/java/com/contrastsecurity/cassandra/migration/resolver/java/JavaMigrationResolver.java index f64f0fe..ab50ba4 100644 --- a/src/main/java/com/contrastsecurity/cassandra/migration/resolver/java/JavaMigrationResolver.java +++ b/src/main/java/com/contrastsecurity/cassandra/migration/resolver/java/JavaMigrationResolver.java @@ -51,13 +51,11 @@ public JavaMigrationResolver(ClassLoader classLoader, ScriptsLocation location) } public List resolveMigrations() { - List migrations = new ArrayList(); - if (!location.isClassPath()) { - return migrations; + return Collections.emptyList(); } - loadJavaMigrationFiles(classLoader, location, migrations); + List migrations = loadJavaMigrationFiles(classLoader, location); Collections.sort(migrations, new ResolvedMigrationComparator()); return migrations; From 137679fb7a188ff9fce56e625321e997d6e5940b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20Kr=C3=B3l?= Date: Tue, 25 Apr 2017 16:03:13 +0200 Subject: [PATCH 4/7] Added clear task. --- .../migration/CassandraMigration.java | 10 +++ .../cassandra/migration/CommandLine.java | 20 ++++- .../cassandra/migration/action/Clear.java | 77 +++++++++++++++++++ 3 files changed, 103 insertions(+), 4 deletions(-) create mode 100644 src/main/java/com/contrastsecurity/cassandra/migration/action/Clear.java diff --git a/src/main/java/com/contrastsecurity/cassandra/migration/CassandraMigration.java b/src/main/java/com/contrastsecurity/cassandra/migration/CassandraMigration.java index 9e2adac..e7c1043 100644 --- a/src/main/java/com/contrastsecurity/cassandra/migration/CassandraMigration.java +++ b/src/main/java/com/contrastsecurity/cassandra/migration/CassandraMigration.java @@ -1,5 +1,6 @@ package com.contrastsecurity.cassandra.migration; +import com.contrastsecurity.cassandra.migration.action.Clear; import com.contrastsecurity.cassandra.migration.action.Initialize; import com.contrastsecurity.cassandra.migration.action.Migrate; import com.contrastsecurity.cassandra.migration.action.Validate; @@ -108,6 +109,15 @@ public String execute(Session session) { throw new CassandraMigrationException("Validation failed. " + validationError); } } + + public Boolean clear() { + return execute(new Action() { + public Boolean execute(Session session) { + Clear clear = new Clear(session, keyspace); + return clear.run(); + } + }); + } public void baseline() { //TODO diff --git a/src/main/java/com/contrastsecurity/cassandra/migration/CommandLine.java b/src/main/java/com/contrastsecurity/cassandra/migration/CommandLine.java index 782b526..4ff4523 100644 --- a/src/main/java/com/contrastsecurity/cassandra/migration/CommandLine.java +++ b/src/main/java/com/contrastsecurity/cassandra/migration/CommandLine.java @@ -21,6 +21,11 @@ public class CommandLine { */ public static final String VALIDATE = "validate"; + /** + * command to trigger clear action + */ + public static final String CLEAR = "clear"; + /** * logging support */ @@ -45,10 +50,16 @@ public static void main(String[] args) { CassandraMigration cm = new CassandraMigration(); Keyspace ks = new Keyspace(); cm.setKeyspace(ks); - if (MIGRATE.equalsIgnoreCase(operation)) { - cm.migrate(); - } else if (VALIDATE.equalsIgnoreCase(operation)) { - cm.validate(); + switch (operation.toLowerCase()) { + case MIGRATE: + cm.migrate(); + break; + case VALIDATE: + cm.validate(); + break; + case CLEAR: + cm.clear(); + break; } } @@ -92,6 +103,7 @@ private static void printUsage() { LOG.info("========"); LOG.info("migrate : Migrates the database"); LOG.info("validate : Validates the applied migrations against the available ones"); + LOG.info("clear : Clears the whole database"); LOG.info(""); LOG.info("Add -X to print debug output"); LOG.info("Add -q to suppress all output, except for errors and warnings"); diff --git a/src/main/java/com/contrastsecurity/cassandra/migration/action/Clear.java b/src/main/java/com/contrastsecurity/cassandra/migration/action/Clear.java new file mode 100644 index 0000000..568fd69 --- /dev/null +++ b/src/main/java/com/contrastsecurity/cassandra/migration/action/Clear.java @@ -0,0 +1,77 @@ +package com.contrastsecurity.cassandra.migration.action; + +import com.contrastsecurity.cassandra.migration.config.Keyspace; +import com.contrastsecurity.cassandra.migration.logging.Log; +import com.contrastsecurity.cassandra.migration.logging.LogFactory; +import com.contrastsecurity.cassandra.migration.utils.StopWatch; +import com.datastax.driver.core.ResultSet; +import com.datastax.driver.core.Row; +import com.datastax.driver.core.Session; +import com.datastax.driver.core.querybuilder.QueryBuilder; +import com.datastax.driver.core.querybuilder.Select; + +import static com.datastax.driver.core.querybuilder.QueryBuilder.eq; + +public class Clear { + private static final Log LOG = LogFactory.getLog(Clear.class); + + private final Session session; + private final Keyspace keyspace; + + public Clear(Session session, Keyspace keyspace) { + this.session = session; + this.keyspace = keyspace; + } + + public boolean run() { + StopWatch stopWatch = new StopWatch(); + stopWatch.start(); + + for (ObjectType objectType : ObjectType.values()) { + clearObjects(objectType); + } + + stopWatch.stop(); + LOG.info("CLEARED ALL OBJECTS"); + LOG.info(String.format("CLEARING TOOK %d ms", stopWatch.getTotalTimeMillis())); + + return true; + } + + public void clearObjects(ObjectType objectType) { + Select.Where objectsQuery = QueryBuilder.select(objectType.getSchemaColumnName()).from("system_schema", objectType.getSchemaTable()).where(eq("keyspace_name", keyspace.getName())); + ResultSet objects = session.execute(objectsQuery); + for (Row object : objects) { + LOG.info(String.format("Clearing %s of type %s", object.getString(objectType.getSchemaColumnName()), objectType.queryFormat())); + session.execute(String.format("DROP %s IF EXISTS %s", + objectType.queryFormat(), + object.getString(objectType.getSchemaColumnName()))); + } + + } + + public enum ObjectType { + MATERIALIZED_VIEW("views", "view_name"), + TABLE("tables", "table_name"); + + private final String schemaTable; + private final String schemaColumnName; + + ObjectType(String schemaTable, String schemaColumnName) { + this.schemaTable = schemaTable; + this.schemaColumnName = schemaColumnName; + } + + public String queryFormat() { + return name().replace("_", " ").toUpperCase(); + } + + public String getSchemaTable() { + return schemaTable; + } + + public String getSchemaColumnName() { + return schemaColumnName; + } + } +} From 8768ab1984a1f72b050df71bc8a02a79634e8ac2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Szafra=C5=84ski?= Date: Thu, 4 May 2017 15:32:14 +0200 Subject: [PATCH 5/7] Revert "Added External Java Resolver." This change breaks tests and changes the CLI behavior. There should be no "external Java source". Situations like this should be handled by configuring your classpath or classpath loader instead. This reverts commit 6b1d7237d9690713ec7385a038f55b2c5700846d and 6b1d7237d9690713ec7385a038f55b2c5700846d. --- .../resolver/CompositeMigrationResolver.java | 10 --- .../resolver/java/CommonJavaResolver.java | 87 ------------------- .../java/ExternalJavaMigrationResolver.java | 64 -------------- .../resolver/java/JavaMigrationResolver.java | 72 ++++++++++++++- 4 files changed, 69 insertions(+), 164 deletions(-) delete mode 100644 src/main/java/com/contrastsecurity/cassandra/migration/resolver/java/CommonJavaResolver.java delete mode 100644 src/main/java/com/contrastsecurity/cassandra/migration/resolver/java/ExternalJavaMigrationResolver.java diff --git a/src/main/java/com/contrastsecurity/cassandra/migration/resolver/CompositeMigrationResolver.java b/src/main/java/com/contrastsecurity/cassandra/migration/resolver/CompositeMigrationResolver.java index d4295dc..2177a0b 100644 --- a/src/main/java/com/contrastsecurity/cassandra/migration/resolver/CompositeMigrationResolver.java +++ b/src/main/java/com/contrastsecurity/cassandra/migration/resolver/CompositeMigrationResolver.java @@ -20,13 +20,8 @@ import com.contrastsecurity.cassandra.migration.config.ScriptsLocations; import com.contrastsecurity.cassandra.migration.info.ResolvedMigration; import com.contrastsecurity.cassandra.migration.resolver.cql.CqlMigrationResolver; -import com.contrastsecurity.cassandra.migration.resolver.java.ExternalJavaMigrationResolver; import com.contrastsecurity.cassandra.migration.resolver.java.JavaMigrationResolver; -import java.io.File; -import java.net.MalformedURLException; -import java.net.URL; -import java.net.URLClassLoader; import java.util.*; /** @@ -59,11 +54,6 @@ public CompositeMigrationResolver(ClassLoader classLoader, ScriptsLocations loca for (ScriptsLocation location : locations.getLocations()) { migrationResolvers.add(new CqlMigrationResolver(classLoader, location, encoding)); migrationResolvers.add(new JavaMigrationResolver(classLoader, location)); - try { - migrationResolvers.add(new ExternalJavaMigrationResolver(new URLClassLoader(new URL[]{new File(location.getPath()).toURI().toURL()}, this.getClass().getClassLoader()), location)); - } catch (MalformedURLException e) { - throw new CassandraMigrationException("Unable to add external url for classes migrations in location: " + location, e); - } } migrationResolvers.addAll(Arrays.asList(customMigrationResolvers)); diff --git a/src/main/java/com/contrastsecurity/cassandra/migration/resolver/java/CommonJavaResolver.java b/src/main/java/com/contrastsecurity/cassandra/migration/resolver/java/CommonJavaResolver.java deleted file mode 100644 index ef0ff42..0000000 --- a/src/main/java/com/contrastsecurity/cassandra/migration/resolver/java/CommonJavaResolver.java +++ /dev/null @@ -1,87 +0,0 @@ -package com.contrastsecurity.cassandra.migration.resolver.java; - -import com.contrastsecurity.cassandra.migration.CassandraMigrationException; -import com.contrastsecurity.cassandra.migration.api.JavaMigration; -import com.contrastsecurity.cassandra.migration.api.MigrationChecksumProvider; -import com.contrastsecurity.cassandra.migration.api.MigrationInfoProvider; -import com.contrastsecurity.cassandra.migration.config.MigrationType; -import com.contrastsecurity.cassandra.migration.config.ScriptsLocation; -import com.contrastsecurity.cassandra.migration.info.MigrationVersion; -import com.contrastsecurity.cassandra.migration.info.ResolvedMigration; -import com.contrastsecurity.cassandra.migration.resolver.MigrationInfoHelper; -import com.contrastsecurity.cassandra.migration.utils.ClassUtils; -import com.contrastsecurity.cassandra.migration.utils.Pair; -import com.contrastsecurity.cassandra.migration.utils.StringUtils; -import com.contrastsecurity.cassandra.migration.utils.scanner.Scanner; - -import java.util.LinkedList; -import java.util.List; - -/** - * Created by Adam Król on 06.04.2017. - * - * @author Adam Król - */ -class CommonJavaResolver { - - List loadJavaMigrationFiles(ClassLoader classLoader, ScriptsLocation location) { - try { - Class[] classes = new Scanner(classLoader).scanForClasses(location, JavaMigration.class); - List migrations = new LinkedList<>(); - for (Class clazz : classes) { - JavaMigration javaMigration = ClassUtils.instantiate(clazz.getName(), classLoader); - - ResolvedMigration migrationInfo = extractMigrationInfo(javaMigration); - migrationInfo.setPhysicalLocation(ClassUtils.getLocationOnDisk(clazz)); - migrationInfo.setExecutor(new JavaMigrationExecutor(javaMigration)); - - migrations.add(migrationInfo); - } - return migrations; - } catch (Exception e) { - throw new CassandraMigrationException("Unable to resolve Java migrations in location: " + location, e); - } - } - - /** - * Extracts the migration info from this migration. - * - * @param javaMigration The migration to analyse. - * @return The migration info. - */ - ResolvedMigration extractMigrationInfo(JavaMigration javaMigration) { - Integer checksum = null; - if (javaMigration instanceof MigrationChecksumProvider) { - MigrationChecksumProvider checksumProvider = (MigrationChecksumProvider) javaMigration; - checksum = checksumProvider.getChecksum(); - } - - MigrationVersion version; - String description; - if (javaMigration instanceof MigrationInfoProvider) { - MigrationInfoProvider infoProvider = (MigrationInfoProvider) javaMigration; - version = infoProvider.getVersion(); - description = infoProvider.getDescription(); - if (!StringUtils.hasText(description)) { - throw new CassandraMigrationException("Missing description for migration " + version); - } - } else { - Pair info = - MigrationInfoHelper.extractVersionAndDescription( - ClassUtils.getShortName(javaMigration.getClass()), "V", "__", ""); - version = info.getLeft(); - description = info.getRight(); - } - - String script = javaMigration.getClass().getName(); - - - ResolvedMigration resolvedMigration = new ResolvedMigration(); - resolvedMigration.setVersion(version); - resolvedMigration.setDescription(description); - resolvedMigration.setScript(script); - resolvedMigration.setChecksum(checksum); - resolvedMigration.setType(MigrationType.JAVA_DRIVER); - return resolvedMigration; - } -} diff --git a/src/main/java/com/contrastsecurity/cassandra/migration/resolver/java/ExternalJavaMigrationResolver.java b/src/main/java/com/contrastsecurity/cassandra/migration/resolver/java/ExternalJavaMigrationResolver.java deleted file mode 100644 index df140c7..0000000 --- a/src/main/java/com/contrastsecurity/cassandra/migration/resolver/java/ExternalJavaMigrationResolver.java +++ /dev/null @@ -1,64 +0,0 @@ -/** - * Copyright 2010-2015 Axel Fontaine - *

- * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.contrastsecurity.cassandra.migration.resolver.java; - -import com.contrastsecurity.cassandra.migration.config.ScriptsLocation; -import com.contrastsecurity.cassandra.migration.info.ResolvedMigration; -import com.contrastsecurity.cassandra.migration.resolver.MigrationResolver; -import com.contrastsecurity.cassandra.migration.resolver.ResolvedMigrationComparator; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -/** - * Migration resolver for Java migrations. The classes must have a name like V1 or V1_1_3 or V1__Description - * or V1_1_3__Description. - */ -public class ExternalJavaMigrationResolver extends CommonJavaResolver implements MigrationResolver { - /** - * The base package on the classpath where to migrations are located. - */ - private final ScriptsLocation location; - - /** - * The ClassLoader to use. - */ - private ClassLoader classLoader; - - /** - * Creates a new instance. - * - * @param location The base package on the classpath where to migrations are located. - * @param classLoader The ClassLoader for loading migrations on the classpath. - */ - public ExternalJavaMigrationResolver(ClassLoader classLoader, ScriptsLocation location) { - this.location = location; - this.classLoader = classLoader; - } - - public List resolveMigrations() { - - if (!location.isFileSystem()) { - return Collections.emptyList(); - } - - List migrations = loadJavaMigrationFiles(classLoader, new ScriptsLocation("")); - - Collections.sort(migrations, new ResolvedMigrationComparator()); - return migrations; - } -} diff --git a/src/main/java/com/contrastsecurity/cassandra/migration/resolver/java/JavaMigrationResolver.java b/src/main/java/com/contrastsecurity/cassandra/migration/resolver/java/JavaMigrationResolver.java index ab50ba4..c85c430 100644 --- a/src/main/java/com/contrastsecurity/cassandra/migration/resolver/java/JavaMigrationResolver.java +++ b/src/main/java/com/contrastsecurity/cassandra/migration/resolver/java/JavaMigrationResolver.java @@ -15,10 +15,21 @@ */ package com.contrastsecurity.cassandra.migration.resolver.java; +import com.contrastsecurity.cassandra.migration.CassandraMigrationException; +import com.contrastsecurity.cassandra.migration.api.MigrationChecksumProvider; +import com.contrastsecurity.cassandra.migration.api.MigrationInfoProvider; +import com.contrastsecurity.cassandra.migration.api.JavaMigration; +import com.contrastsecurity.cassandra.migration.config.MigrationType; import com.contrastsecurity.cassandra.migration.config.ScriptsLocation; +import com.contrastsecurity.cassandra.migration.info.MigrationVersion; import com.contrastsecurity.cassandra.migration.info.ResolvedMigration; +import com.contrastsecurity.cassandra.migration.resolver.MigrationInfoHelper; import com.contrastsecurity.cassandra.migration.resolver.MigrationResolver; import com.contrastsecurity.cassandra.migration.resolver.ResolvedMigrationComparator; +import com.contrastsecurity.cassandra.migration.utils.ClassUtils; +import com.contrastsecurity.cassandra.migration.utils.Pair; +import com.contrastsecurity.cassandra.migration.utils.StringUtils; +import com.contrastsecurity.cassandra.migration.utils.scanner.Scanner; import java.util.ArrayList; import java.util.Collections; @@ -28,7 +39,7 @@ * Migration resolver for Java migrations. The classes must have a name like V1 or V1_1_3 or V1__Description * or V1_1_3__Description. */ -public class JavaMigrationResolver extends CommonJavaResolver implements MigrationResolver { +public class JavaMigrationResolver implements MigrationResolver { /** * The base package on the classpath where to migrations are located. */ @@ -51,15 +62,70 @@ public JavaMigrationResolver(ClassLoader classLoader, ScriptsLocation location) } public List resolveMigrations() { + List migrations = new ArrayList(); + if (!location.isClassPath()) { - return Collections.emptyList(); + return migrations; } - List migrations = loadJavaMigrationFiles(classLoader, location); + try { + Class[] classes = new Scanner(classLoader).scanForClasses(location, JavaMigration.class); + for (Class clazz : classes) { + JavaMigration javaMigration = ClassUtils.instantiate(clazz.getName(), classLoader); + + ResolvedMigration migrationInfo = extractMigrationInfo(javaMigration); + migrationInfo.setPhysicalLocation(ClassUtils.getLocationOnDisk(clazz)); + migrationInfo.setExecutor(new JavaMigrationExecutor(javaMigration)); + + migrations.add(migrationInfo); + } + } catch (Exception e) { + throw new CassandraMigrationException("Unable to resolve Java migrations in location: " + location, e); + } Collections.sort(migrations, new ResolvedMigrationComparator()); return migrations; } + /** + * Extracts the migration info from this migration. + * + * @param javaMigration The migration to analyse. + * @return The migration info. + */ + ResolvedMigration extractMigrationInfo(JavaMigration javaMigration) { + Integer checksum = null; + if (javaMigration instanceof MigrationChecksumProvider) { + MigrationChecksumProvider checksumProvider = (MigrationChecksumProvider) javaMigration; + checksum = checksumProvider.getChecksum(); + } + + MigrationVersion version; + String description; + if (javaMigration instanceof MigrationInfoProvider) { + MigrationInfoProvider infoProvider = (MigrationInfoProvider) javaMigration; + version = infoProvider.getVersion(); + description = infoProvider.getDescription(); + if (!StringUtils.hasText(description)) { + throw new CassandraMigrationException("Missing description for migration " + version); + } + } else { + Pair info = + MigrationInfoHelper.extractVersionAndDescription( + ClassUtils.getShortName(javaMigration.getClass()), "V", "__", ""); + version = info.getLeft(); + description = info.getRight(); + } + String script = javaMigration.getClass().getName(); + + + ResolvedMigration resolvedMigration = new ResolvedMigration(); + resolvedMigration.setVersion(version); + resolvedMigration.setDescription(description); + resolvedMigration.setScript(script); + resolvedMigration.setChecksum(checksum); + resolvedMigration.setType(MigrationType.JAVA_DRIVER); + return resolvedMigration; + } } From 66aca18119a87ef75ad23608ead7c0d72aea6f5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Szafra=C5=84ski?= Date: Thu, 4 May 2017 15:41:01 +0200 Subject: [PATCH 6/7] Upgraded Guava version. JAR-with-dependencies had Guava 16.0.1 packed inside (transitive dependency of cassandra-driver-core). --- pom.xml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 3579563..41edfdd 100755 --- a/pom.xml +++ b/pom.xml @@ -82,6 +82,12 @@ com.datastax.cassandra cassandra-driver-core 3.0.0 + + + com.google.guava + guava + + junit @@ -124,8 +130,7 @@ com.google.guava guava - 18.0 - test + 19.0 From 346948eb610e19d5061eb0093d69ef057620e0a2 Mon Sep 17 00:00:00 2001 From: Seweryn Walendzik Date: Wed, 17 Apr 2019 14:59:11 +0200 Subject: [PATCH 7/7] fixed installed rank statement --- .../cassandra/migration/dao/SchemaVersionDAO.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/contrastsecurity/cassandra/migration/dao/SchemaVersionDAO.java b/src/main/java/com/contrastsecurity/cassandra/migration/dao/SchemaVersionDAO.java index 9027474..bae1797 100755 --- a/src/main/java/com/contrastsecurity/cassandra/migration/dao/SchemaVersionDAO.java +++ b/src/main/java/com/contrastsecurity/cassandra/migration/dao/SchemaVersionDAO.java @@ -203,7 +203,7 @@ private int calculateInstalledRank() { Statement statement = new SimpleStatement( "UPDATE " + keyspace.getName() + "." + tableName + COUNTS_TABLE_NAME_SUFFIX + " SET count = count + 1" + - "WHERE name = 'installed_rank';"); + " WHERE name = 'installed_rank';"); session.execute(statement); Select select = QueryBuilder .select("count")