Search in sources :

Example 71 with FlywayException

use of org.flywaydb.core.api.FlywayException in project flyway by flyway.

the class ClassPathScanner method findResourceNamesAndParentURLs.

private Set<Pair<String, String>> findResourceNamesAndParentURLs() {
    Set<Pair<String, String>> resourceNamesAndParentURLs = new TreeSet<>();
    List<URL> locationUrls = getLocationUrlsForPath(location);
    for (URL locationUrl : locationUrls) {
        LOG.debug("Scanning URL: " + locationUrl.toExternalForm());
        UrlResolver urlResolver = createUrlResolver(locationUrl.getProtocol());
        URL resolvedUrl = urlResolver.toStandardJavaUrl(locationUrl);
        String protocol = resolvedUrl.getProtocol();
        ClassPathLocationScanner classPathLocationScanner = createLocationScanner(protocol);
        if (classPathLocationScanner == null) {
            String scanRoot = UrlUtils.toFilePath(resolvedUrl);
            LOG.warn("Unable to scan location: " + scanRoot + " (unsupported protocol: " + protocol + ")");
        } else {
            Set<String> names = resourceNameCache.get(classPathLocationScanner, resolvedUrl);
            if (names == null) {
                names = classPathLocationScanner.findResourceNames(location.getRootPath(), resolvedUrl);
                resourceNameCache.put(classPathLocationScanner, resolvedUrl, names);
            }
            Set<String> filteredNames = new HashSet<>();
            for (String name : names) {
                if (location.matchesPath(name)) {
                    filteredNames.add(name);
                }
            }
            for (String filteredName : filteredNames) {
                resourceNamesAndParentURLs.add(Pair.of(filteredName, resolvedUrl.getPath()));
            }
        }
    }
    // Make an additional attempt at finding resources in jar files in case the URL scanning method above didn't
    // yield any results.
    boolean locationResolved = !locationUrls.isEmpty();
    // Starting with Java 11, resources at the root of the classpath aren't being found using the URL scanning
    // method above and we need to revert to Jar file walking.
    boolean isClassPathRoot = location.isClassPath() && "".equals(location.getRootPath());
    if (!locationResolved || isClassPathRoot) {
        if (classLoader instanceof URLClassLoader) {
            URLClassLoader urlClassLoader = (URLClassLoader) classLoader;
            for (URL url : urlClassLoader.getURLs()) {
                if ("file".equals(url.getProtocol()) && url.getPath().endsWith(".jar") && !url.getPath().matches(".*" + Pattern.quote("/jre/lib/") + ".*")) {
                    // All non-system jars on disk
                    JarFile jarFile;
                    try {
                        try {
                            jarFile = new JarFile(url.toURI().getSchemeSpecificPart());
                        } catch (URISyntaxException ex) {
                            // Fallback for URLs that are not valid URIs (should hardly ever happen).
                            jarFile = new JarFile(url.getPath().substring("file:".length()));
                        }
                    } catch (IOException | SecurityException e) {
                        LOG.warn("Skipping unloadable jar file: " + url + " (" + e.getMessage() + ")");
                        continue;
                    }
                    try {
                        Enumeration<JarEntry> entries = jarFile.entries();
                        while (entries.hasMoreElements()) {
                            String entryName = entries.nextElement().getName();
                            if (entryName.startsWith(location.getRootPath())) {
                                locationResolved = true;
                                resourceNamesAndParentURLs.add(Pair.of(entryName, url.getPath()));
                            }
                        }
                    } finally {
                        try {
                            jarFile.close();
                        } catch (IOException e) {
                        // Ignore
                        }
                    }
                }
            }
        }
    }
    if (!locationResolved) {
        String message = "Unable to resolve location " + location + ".";
        if (throwOnMissingLocations) {
            throw new FlywayException(message);
        } else {
            LOG.debug(message);
        }
    }
    return resourceNamesAndParentURLs;
}
Also used : FlywayException(org.flywaydb.core.api.FlywayException) URISyntaxException(java.net.URISyntaxException) IOException(java.io.IOException) JBossVFSv3ClassPathLocationScanner(org.flywaydb.core.internal.scanner.classpath.jboss.JBossVFSv3ClassPathLocationScanner) JarFile(java.util.jar.JarFile) JarEntry(java.util.jar.JarEntry) URL(java.net.URL) JBossVFSv2UrlResolver(org.flywaydb.core.internal.scanner.classpath.jboss.JBossVFSv2UrlResolver) URLClassLoader(java.net.URLClassLoader)

Example 72 with FlywayException

use of org.flywaydb.core.api.FlywayException in project flyway by flyway.

the class AwsS3Scanner method scanForResources.

/**
 * Scans S3 for the resources. In AWS SDK v2, only the region that the client is configured with can be used.
 * The format of the path is expected to be {@code s3:{bucketName}/{optional prefix}}.
 *
 * @param location The location in S3 to start searching. Subdirectories are also searched.
 * @return The resources that were found.
 */
@Override
public Collection<LoadableResource> scanForResources(final Location location) {
    String bucketName = getBucketName(location);
    String prefix = getPrefix(bucketName, location.getPath());
    S3Client s3Client = S3ClientFactory.getClient();
    try {
        ListObjectsV2Request.Builder builder = ListObjectsV2Request.builder().bucket(bucketName).prefix(prefix);
        ListObjectsV2Request request = builder.build();
        ListObjectsV2Response listObjectResult = s3Client.listObjectsV2(request);
        return getLoadableResources(bucketName, listObjectResult);
    } catch (SdkClientException e) {
        if (throwOnMissingLocations) {
            throw new FlywayException("Could not access s3 location:" + bucketName + prefix + " due to error: " + e.getMessage());
        }
        LOG.error("Skipping s3 location:" + bucketName + prefix + " due to error: " + e.getMessage());
        return Collections.emptyList();
    }
}
Also used : FlywayException(org.flywaydb.core.api.FlywayException) ListObjectsV2Request(software.amazon.awssdk.services.s3.model.ListObjectsV2Request) SdkClientException(software.amazon.awssdk.core.exception.SdkClientException) S3Client(software.amazon.awssdk.services.s3.S3Client) ListObjectsV2Response(software.amazon.awssdk.services.s3.model.ListObjectsV2Response)

Example 73 with FlywayException

use of org.flywaydb.core.api.FlywayException in project flyway by flyway.

the class CompositeMigrationResolver method checkForIncompatibilities.

/**
 * Checks for incompatible migrations.
 *
 * @param migrations The migrations to check.
 * @throws FlywayException when two different migration with the same version number are found.
 */
static void checkForIncompatibilities(List<ResolvedMigration> migrations) {
    ResolvedMigrationComparator resolvedMigrationComparator = new ResolvedMigrationComparator();
    // check for more than one migration with same version
    for (int i = 0; i < migrations.size() - 1; i++) {
        ResolvedMigration current = migrations.get(i);
        ResolvedMigration next = migrations.get(i + 1);
        if (resolvedMigrationComparator.compare(current, next) == 0) {
            if (current.getVersion() != null) {
                throw new FlywayException(String.format("Found more than one migration with version %s\nOffenders:\n-> %s (%s)\n-> %s (%s)", current.getVersion(), current.getPhysicalLocation(), current.getType(), next.getPhysicalLocation(), next.getType()), ErrorCode.DUPLICATE_VERSIONED_MIGRATION);
            }
            throw new FlywayException(String.format("Found more than one repeatable migration with description %s\nOffenders:\n-> %s (%s)\n-> %s (%s)", current.getDescription(), current.getPhysicalLocation(), current.getType(), next.getPhysicalLocation(), next.getType()), ErrorCode.DUPLICATE_REPEATABLE_MIGRATION);
        }
    }
}
Also used : FlywayException(org.flywaydb.core.api.FlywayException) ResolvedMigration(org.flywaydb.core.api.resolver.ResolvedMigration)

Example 74 with FlywayException

use of org.flywaydb.core.api.FlywayException in project flyway by flyway.

the class ResourceNameValidator method validateSQLMigrationNaming.

/**
 * Validates the names of all SQL resources returned by the ResourceProvider
 *
 * @param provider The ResourceProvider to validate
 * @param configuration The configuration to use
 */
public void validateSQLMigrationNaming(ResourceProvider provider, Configuration configuration) {
    List<String> errorsFound = new ArrayList<>();
    ResourceNameParser resourceNameParser = new ResourceNameParser(configuration);
    for (Resource resource : getAllSqlResources(provider, configuration)) {
        String filename = resource.getFilename();
        LOG.debug("Validating " + filename);
        // Filter out special purpose files that the parser will not identify.
        if (isSpecialResourceFile(configuration, filename)) {
            continue;
        }
        ResourceName result = resourceNameParser.parse(filename);
        if (!result.isValid()) {
            errorsFound.add(result.getValidityMessage());
        }
    }
    if (!errorsFound.isEmpty()) {
        if (configuration.isValidateMigrationNaming()) {
            throw new FlywayException("Invalid SQL filenames found:\r\n" + StringUtils.collectionToDelimitedString(errorsFound, "\r\n"));
        } else {
            LOG.info(errorsFound.size() + " SQL migrations were detected but not run because they did not follow the filename convention.");
            LOG.info("If this is in error, enable debug logging or 'validateMigrationNaming' to fail fast and see a list of the invalid file names.");
        }
    }
}
Also used : FlywayException(org.flywaydb.core.api.FlywayException) ArrayList(java.util.ArrayList) Resource(org.flywaydb.core.api.resource.Resource) LoadableResource(org.flywaydb.core.api.resource.LoadableResource)

Example 75 with FlywayException

use of org.flywaydb.core.api.FlywayException in project flyway by flyway.

the class ChecksumCalculator method calculateChecksumForResource.

private static int calculateChecksumForResource(LoadableResource resource) {
    final CRC32 crc32 = new CRC32();
    BufferedReader bufferedReader = null;
    try {
        bufferedReader = new BufferedReader(resource.read(), 4096);
        String line = bufferedReader.readLine();
        if (line != null) {
            line = BomFilter.FilterBomFromString(line);
            do {
                // noinspection Since15
                crc32.update(line.getBytes(StandardCharsets.UTF_8));
            } while ((line = bufferedReader.readLine()) != null);
        }
    } catch (IOException e) {
        throw new FlywayException("Unable to calculate checksum of " + resource.getFilename() + "\r\n" + e.getMessage(), e);
    } finally {
        IOUtils.close(bufferedReader);
    }
    return (int) crc32.getValue();
}
Also used : FlywayException(org.flywaydb.core.api.FlywayException) CRC32(java.util.zip.CRC32) BufferedReader(java.io.BufferedReader) IOException(java.io.IOException)

Aggregations

FlywayException (org.flywaydb.core.api.FlywayException)82 SQLException (java.sql.SQLException)22 IOException (java.io.IOException)17 ArrayList (java.util.ArrayList)14 PreparedStatement (java.sql.PreparedStatement)8 HashMap (java.util.HashMap)8 URL (java.net.URL)7 ResultSet (java.sql.ResultSet)7 Statement (java.sql.Statement)7 File (java.io.File)6 MigrationVersion (org.flywaydb.core.api.MigrationVersion)6 ResolvedMigrationImpl (org.flywaydb.core.internal.resolver.ResolvedMigrationImpl)6 Test (org.junit.Test)6 InputStreamReader (java.io.InputStreamReader)5 Method (java.lang.reflect.Method)5 BufferedReader (java.io.BufferedReader)4 FileInputStream (java.io.FileInputStream)4 Reader (java.io.Reader)4 StringReader (java.io.StringReader)4 URLClassLoader (java.net.URLClassLoader)4