Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into release
Browse files Browse the repository at this point in the history
  • Loading branch information
xtermi2 committed Nov 16, 2023
2 parents 9018898 + ec554bd commit d5e4726
Show file tree
Hide file tree
Showing 19 changed files with 124 additions and 117 deletions.
13 changes: 11 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ First add the latest version of Elasticsearch-Evolution spring boot starter as a
<dependency>
<groupId>com.senacor.elasticsearch.evolution</groupId>
<artifactId>spring-boot-starter-elasticsearch-evolution</artifactId>
<version>0.4.2</version>
<version>0.4.3</version>
</dependency>
```

Expand All @@ -77,7 +77,7 @@ First add the latest version of Elasticsearch-Evolution core as a dependency:
<dependency>
<groupId>com.senacor.elasticsearch.evolution</groupId>
<artifactId>elasticsearch-evolution-core</artifactId>
<version>0.4.2</version>
<version>0.4.3</version>
</dependency>
```

Expand Down Expand Up @@ -291,6 +291,11 @@ ElasticsearchEvolution.configure()

## 6 changelog

### v0.5.0

- added spring boot configuration metadata [#240](https://github.com/senacor/elasticsearch-evolution/pull/240)
- replaces unmaintained [org.reflections](https://github.com/ronmamo/reflections) library with [classgraph](https://github.com/classgraph/classgraph) to scan the classpath for migration files. Fixes [#239](https://github.com/senacor/elasticsearch-evolution/issues/239)

### v0.4.3

- support out of order migration execution.
Expand All @@ -300,6 +305,10 @@ ElasticsearchEvolution.configure()
- added regression tests on JDK 21
- added regression tests for spring boot 3.1
- update org.reflections:reflections from 0.9.12 to 0.10.2 [#233](https://github.com/senacor/elasticsearch-evolution/pull/233) thanks @RiVogel
- **KNOWN ISSUES**:
- [#239](https://github.com/senacor/elasticsearch-evolution/issues/239): Migration files not found in Spring Boot jar
- Workaround 1: downgrade `org.reflections:reflections` to `0.10.1`
- Workaround 2: downgrade `elasticsearch-evolution` to `0.4.2`

### v0.4.2

Expand Down
11 changes: 8 additions & 3 deletions elasticsearch-evolution-core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<parent>
<groupId>com.senacor.elasticsearch.evolution</groupId>
<artifactId>elasticsearch-evolution-parent</artifactId>
<version>0.4.3</version>
<version>0.5.0</version>
<relativePath>../</relativePath>
</parent>
<artifactId>elasticsearch-evolution-core</artifactId>
Expand All @@ -22,6 +22,11 @@
<artifactId>spring-boot</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>

<!--Elasticsearch-->
<dependency>
Expand All @@ -45,8 +50,8 @@
</dependency>

<dependency>
<groupId>org.reflections</groupId>
<artifactId>reflections</artifactId>
<groupId>io.github.classgraph</groupId>
<artifactId>classgraph</artifactId>
</dependency>

<dependency>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ public class ElasticsearchEvolutionConfig {

/**
* Locations of migrations scripts. Supported is classpath:some/path and file:/some/path
* The location is scanned recursive.
* NOTE: all scripts in all locations / subdirectories will be flatted and only the version number will be used to
* order them.
*/
private List<String> locations = new ArrayList<>(
Collections.singletonList("classpath:es/migration"));
Expand Down Expand Up @@ -283,14 +286,6 @@ public ElasticsearchEvolutionConfig setHistoryMaxQuerySize(int historyMaxQuerySi
return this;
}

/**
* @deprecated use {@link #isValidateOnMigrate()} instead
*/
@Deprecated
public boolean getValidateOnMigrate() {
return isValidateOnMigrate();
}

public boolean isValidateOnMigrate() {
return validateOnMigrate;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,34 +3,26 @@
import com.senacor.elasticsearch.evolution.core.api.MigrationException;
import com.senacor.elasticsearch.evolution.core.api.migration.MigrationScriptReader;
import com.senacor.elasticsearch.evolution.core.internal.model.migration.RawMigrationScript;
import java.util.regex.Pattern;
import org.reflections.Reflections;
import org.reflections.scanners.Scanners;
import org.reflections.util.ClasspathHelper;
import org.reflections.util.ConfigurationBuilder;
import org.reflections.util.FilterBuilder;
import io.github.classgraph.ClassGraph;
import io.github.classgraph.ScanResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collection;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static java.util.Collections.emptySet;

/**
* @author Andreas Keefer
*/
Expand Down Expand Up @@ -137,35 +129,26 @@ private Stream<RawMigrationScript> readScriptsFromClassPath(String location) {
// otherwise e.g. "...location_some_suffix" will also be found when search for "...location".
location = location + "/";
}
final String locationWithoutPrefixAsPackageNotation = location.substring(CLASSPATH_PREFIX.length())
.replace("/", ".");

final Collection<URL> urls = ClasspathHelper.forPackage(locationWithoutPrefixAsPackageNotation);
final Set<String> resources;
if (urls.isEmpty()) {
// https://github.com/senacor/elasticsearch-evolution/issues/27
// when the package is empty or does not exist, Reflections can't find any URLs to scan for
resources = emptySet();
} else {
Reflections reflections = new Reflections(new ConfigurationBuilder()
.setScanners(Scanners.Resources)
.filterInputsBy(new FilterBuilder().includePackage(locationWithoutPrefixAsPackageNotation))
.setUrls(urls));
resources = reflections.getResources(Pattern.compile(esMigrationPrefix + ".*"))
.stream()
.filter(path -> isValidFilename(Paths.get(path).getFileName().toString()))
.collect(Collectors.toSet());
}

return resources.stream().flatMap(resource -> {
logger.debug("reading migration script '{}' from classpath...", resource);
try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(getInputStream(resource), encoding))) {
Path p = Paths.get(resource);
return read(bufferedReader, p.getFileName().toString());
} catch (IOException e) {
throw new MigrationException("can't read script from classpath: " + resource, e);
}
});
final String locationWithoutPrefix = location.substring(CLASSPATH_PREFIX.length());

List<RawMigrationScript> res = new ArrayList<>();
try (ScanResult scanResult = new ClassGraph()
.acceptPaths(locationWithoutPrefix)
.scan()) {
scanResult.getAllResources()
.filter(resource -> isValidFilename(Paths.get(resource.getPath()).getFileName().toString()))
.forEach(resource -> {
logger.debug("reading migration script '{}' from classpath...", resource);
try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(resource.load()), encoding))) {
Path p = Paths.get(resource.getPath());
res.addAll(read(bufferedReader, p.getFileName().toString()).collect(Collectors.toList()));
} catch (IOException e) {
throw new MigrationException("can't read script from classpath: " + resource, e);
}
});
}
return res.stream();
}

private Stream<RawMigrationScript> read(BufferedReader reader, String filename) {
Expand All @@ -178,46 +161,12 @@ private Stream<RawMigrationScript> read(BufferedReader reader, String filename)
return Stream.of(new RawMigrationScript().setFileName(filename).setContent(content));
}

public static InputStream getInputStream(String path) {
ClassLoader classLoader = getDefaultClassLoader();
if (classLoader != null) {
return classLoader.getResourceAsStream(path);
} else {
return ClassLoader.getSystemResourceAsStream(path);
}
}

private boolean hasValidSuffix(String path) {
return this.esMigrationSuffixes
.stream()
.anyMatch(suffix -> path.toLowerCase().endsWith(suffix.toLowerCase()));
}

static ClassLoader getDefaultClassLoader() {
ClassLoader cl = null;
try {
cl = Thread.currentThread().getContextClassLoader();
logger.trace("getDefaultClassLoader - Thread.currentThread().getContextClassLoader()='{}'", cl);
} catch (Throwable ex) {
// Cannot access thread context ClassLoader - falling back...
}
if (cl == null) {
// No thread context class loader -> use class loader of this class.
cl = MigrationScriptReaderImpl.class.getClassLoader();
logger.trace("getDefaultClassLoader - MigrationScriptReaderImpl.class.getClassLoader()='{}'", cl);
if (cl == null) {
// getClassLoader() returning null indicates the bootstrap ClassLoader
try {
cl = ClassLoader.getSystemClassLoader();
logger.trace("getDefaultClassLoader - ClassLoader.getSystemClassLoader()='{}'", cl);
} catch (Throwable ex) {
// Cannot access system ClassLoader - oh well, maybe the caller can live with null...
}
}
}
return cl;
}

private boolean isValidFilename(String fileName) {
return hasValidSuffix(fileName)
&& fileName.startsWith(this.esMigrationPrefix);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
package com.senacor.elasticsearch.evolution.core.api.config;

import io.github.classgraph.ClassGraph;
import io.github.classgraph.ScanResult;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;

import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
Expand All @@ -13,6 +18,26 @@
*/
class ElasticsearchEvolutionConfigTest {

@Test
void springConfigurationMmetadataJson_should_have_been_generated_by_springBootConfigurationProcessor() {
final List<String> springConfigMetadata;
try (ScanResult scanResult = new ClassGraph().acceptPathsNonRecursive("META-INF/").scan()) {
springConfigMetadata = scanResult.getResourcesWithLeafName("spring-configuration-metadata.json")
.stream()
.map(resource -> {
try {
return resource.getContentAsString();
} catch (IOException e) {
throw new IllegalStateException(e);
}
})
.collect(Collectors.toList());
}

assertThat(springConfigMetadata)
.anySatisfy(metadataContent -> assertThat(metadataContent).contains(ElasticsearchEvolutionConfig.class.getName()));
}

@Nested
class validate {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,10 @@ void inJarFile() {

List<RawMigrationScript> res = reader.read();

assertThat(res).hasSize(1);
assertThat(res.get(0).getFileName()).isEqualTo("MANIFEST.MF");
assertThat(res).isNotEmpty()
.allSatisfy(rawMigrationScript -> assertThat(rawMigrationScript.getFileName())
.as("fileName")
.isEqualTo("MANIFEST.MF"));
}

@Test
Expand Down Expand Up @@ -248,11 +250,33 @@ void validPathButNoFiles() throws URISyntaxException {
}

private URL resolveURL(String path) {
ClassLoader classLoader = MigrationScriptReaderImpl.getDefaultClassLoader();
ClassLoader classLoader = getDefaultClassLoader();
if (classLoader != null) {
return classLoader.getResource(path);
} else {
return ClassLoader.getSystemResource(path);
}
}

static ClassLoader getDefaultClassLoader() {
ClassLoader cl = null;
try {
cl = Thread.currentThread().getContextClassLoader();
} catch (Throwable ex) {
// Cannot access thread context ClassLoader - falling back...
}
if (cl == null) {
// No thread context class loader -> use class loader of this class.
cl = MigrationScriptReaderImpl.class.getClassLoader();
if (cl == null) {
// getClassLoader() returning null indicates the bootstrap ClassLoader
try {
cl = ClassLoader.getSystemClassLoader();
} catch (Throwable ex) {
// Cannot access system ClassLoader - oh well, maybe the caller can live with null...
}
}
}
return cl;
}
}
12 changes: 6 additions & 6 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

<groupId>com.senacor.elasticsearch.evolution</groupId>
<artifactId>elasticsearch-evolution-parent</artifactId>
<version>0.4.3</version>
<version>0.5.0</version>
<packaging>pom</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
Expand Down Expand Up @@ -102,8 +102,8 @@
<commons-io.version>2.15.0</commons-io.version>
<!--when updating elasticsearch versions, also update "ElasticsearchContainer" version in EmbeddedElasticsearchExtension-->
<elasticsearch.version>7.5.2</elasticsearch.version>
<reflections.version>0.10.2</reflections.version>
<testcontainers.elasticsearch.version>1.19.1</testcontainers.elasticsearch.version>
<classgraph.version>4.8.164</classgraph.version>
<testcontainers.elasticsearch.version>1.19.2</testcontainers.elasticsearch.version>
<lombok.version>1.18.30</lombok.version>
<!-- newer byte-buddy version to support JDK 21 -->
<byte-buddy.version>1.14.9</byte-buddy.version>
Expand All @@ -112,9 +112,9 @@
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.reflections</groupId>
<artifactId>reflections</artifactId>
<version>${reflections.version}</version>
<groupId>io.github.classgraph</groupId>
<artifactId>classgraph</artifactId>
<version>${classgraph.version}</version>
</dependency>

<!-- Elasticsearch -->
Expand Down
2 changes: 1 addition & 1 deletion spring-boot-starter-elasticsearch-evolution/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<parent>
<groupId>com.senacor.elasticsearch.evolution</groupId>
<artifactId>elasticsearch-evolution-parent</artifactId>
<version>0.4.3</version>
<version>0.5.0</version>
<relativePath>../</relativePath>
</parent>
<artifactId>spring-boot-starter-elasticsearch-evolution</artifactId>
Expand Down
2 changes: 1 addition & 1 deletion tests/migration-scripts/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.senacor.elasticsearch.evolution</groupId>
<artifactId>migration-scripts</artifactId>
<version>0.4.3</version>
<version>0.5.0</version>
<description>jar containing migration files</description>

<packaging>jar</packaging>
Expand Down
2 changes: 1 addition & 1 deletion tests/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<parent>
<groupId>com.senacor.elasticsearch.evolution</groupId>
<artifactId>elasticsearch-evolution-parent</artifactId>
<version>0.4.3</version>
<version>0.5.0</version>
<relativePath>../</relativePath>
</parent>
<artifactId>tests</artifactId>
Expand Down
Loading

0 comments on commit d5e4726

Please sign in to comment.