Skip to content

Commit adb4ff8

Browse files
authored
Merge pull request #1 from zonkyio/configurable-postgres-binaries
Use io.zonky.test.postgres:embedded-postgres-binaries
2 parents 4f64bb8 + 4cd9cd1 commit adb4ff8

File tree

9 files changed

+341
-123
lines changed

9 files changed

+341
-123
lines changed

pom.xml

Lines changed: 25 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,31 @@
7676
</distributionManagement>
7777

7878
<dependencies>
79+
<dependency>
80+
<groupId>io.zonky.test.postgres</groupId>
81+
<artifactId>embedded-postgres-binaries-windows-amd64</artifactId>
82+
<version>${embedded-postgres-binaries.version}</version>
83+
<scope>runtime</scope>
84+
</dependency>
85+
<dependency>
86+
<groupId>io.zonky.test.postgres</groupId>
87+
<artifactId>embedded-postgres-binaries-darwin-amd64</artifactId>
88+
<version>${embedded-postgres-binaries.version}</version>
89+
<scope>runtime</scope>
90+
</dependency>
91+
<dependency>
92+
<groupId>io.zonky.test.postgres</groupId>
93+
<artifactId>embedded-postgres-binaries-linux-amd64</artifactId>
94+
<version>${embedded-postgres-binaries.version}</version>
95+
<scope>runtime</scope>
96+
</dependency>
97+
<dependency>
98+
<groupId>io.zonky.test.postgres</groupId>
99+
<artifactId>embedded-postgres-binaries-linux-amd64-alpine</artifactId>
100+
<version>${embedded-postgres-binaries.version}</version>
101+
<scope>runtime</scope>
102+
</dependency>
103+
79104
<dependency>
80105
<groupId>org.slf4j</groupId>
81106
<artifactId>slf4j-api</artifactId>
@@ -146,11 +171,6 @@
146171
</dependencies>
147172

148173
<build>
149-
<resources>
150-
<resource>
151-
<directory>${basedir}/target/generated-resources</directory>
152-
</resource>
153-
</resources>
154174
<plugins>
155175
<plugin>
156176
<artifactId>maven-pmd-plugin</artifactId>
@@ -186,22 +206,6 @@
186206
<failurePriority>4</failurePriority>
187207
</configuration>
188208
</plugin>
189-
<plugin>
190-
<groupId>org.codehaus.mojo</groupId>
191-
<artifactId>exec-maven-plugin</artifactId>
192-
<version>1.3.2</version>
193-
<executions>
194-
<execution>
195-
<phase>generate-resources</phase>
196-
<goals>
197-
<goal>exec</goal>
198-
</goals>
199-
</execution>
200-
</executions>
201-
<configuration>
202-
<executable>./repack-postgres.sh</executable>
203-
</configuration>
204-
</plugin>
205209
<plugin>
206210
<groupId>org.apache.maven.plugins</groupId>
207211
<artifactId>maven-source-plugin</artifactId>

repack-postgres.sh

Lines changed: 0 additions & 69 deletions
This file was deleted.

src/main/java/io/zonky/test/db/postgres/embedded/BundledPostgresBinaryResolver.java

Lines changed: 0 additions & 31 deletions
This file was deleted.
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
/*
2+
* Licensed under the Apache License, Version 2.0 (the "License");
3+
* you may not use this file except in compliance with the License.
4+
* You may obtain a copy of the License at
5+
*
6+
* http://www.apache.org/licenses/LICENSE-2.0
7+
*
8+
* Unless required by applicable law or agreed to in writing, software
9+
* distributed under the License is distributed on an "AS IS" BASIS,
10+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
* See the License for the specific language governing permissions and
12+
* limitations under the License.
13+
*/
14+
package io.zonky.test.db.postgres.embedded;
15+
16+
import io.zonky.test.db.postgres.util.ArchUtils;
17+
import io.zonky.test.db.postgres.util.LinuxUtils;
18+
import org.apache.commons.io.FilenameUtils;
19+
import org.apache.commons.lang3.StringUtils;
20+
import org.slf4j.Logger;
21+
import org.slf4j.LoggerFactory;
22+
23+
import java.io.IOException;
24+
import java.io.InputStream;
25+
import java.net.HttpURLConnection;
26+
import java.net.URL;
27+
import java.net.URLConnection;
28+
import java.util.Collections;
29+
import java.util.List;
30+
import java.util.Optional;
31+
32+
import static java.lang.String.format;
33+
import static org.apache.commons.lang3.StringUtils.lowerCase;
34+
35+
public class DefaultPostgresBinaryResolver implements PgBinaryResolver {
36+
37+
private static final Logger logger = LoggerFactory.getLogger(DefaultPostgresBinaryResolver.class);
38+
39+
public static final DefaultPostgresBinaryResolver INSTANCE = new DefaultPostgresBinaryResolver();
40+
41+
private DefaultPostgresBinaryResolver() {}
42+
43+
@Override
44+
public InputStream getPgBinary(String system, String machineHardware) throws IOException {
45+
String architecture = ArchUtils.normalize(machineHardware);
46+
String distribution = LinuxUtils.getDistributionName();
47+
48+
logger.info("Detected distribution: '{}'", Optional.ofNullable(distribution).orElse("Unknown"));
49+
50+
if (distribution != null) {
51+
Resource resource = findPgBinary(normalize(format("postgres-%s-%s-%s.txz", system, architecture, distribution)));
52+
if (resource != null) {
53+
logger.info("Distribution specific postgres binaries found: {}", resource.getFilename());
54+
return resource.getInputStream();
55+
} else {
56+
logger.debug("Distribution specific postgres binaries not found");
57+
}
58+
}
59+
60+
Resource resource = findPgBinary(normalize(format("postgres-%s-%s.txz", system, architecture)));
61+
if (resource != null) {
62+
logger.info("System specific postgres binaries found: {}", resource.getFilename());
63+
return resource.getInputStream();
64+
}
65+
66+
logger.error("No postgres binaries were found, you must add an appropriate maven dependency " +
67+
"that meets the following parameters - system: {}, architecture: {}", system, architecture);
68+
throw new IllegalStateException("Missing postgres binaries");
69+
}
70+
71+
private static Resource findPgBinary(String resourceLocation) throws IOException {
72+
logger.trace("Searching for postgres binaries - location: '{}'", resourceLocation);
73+
ClassLoader classLoader = DefaultPostgresBinaryResolver.class.getClassLoader();
74+
List<URL> urls = Collections.list(classLoader.getResources(resourceLocation));
75+
76+
if (urls.size() > 1) {
77+
logger.error("Detected multiple binaries of the same architecture: {}", urls);
78+
throw new IllegalStateException("Duplicate postgres binaries");
79+
}
80+
if (urls.size() == 1) {
81+
return new Resource(urls.get(0));
82+
}
83+
84+
return null;
85+
}
86+
87+
private static String normalize(String input) {
88+
if (StringUtils.isBlank(input)) {
89+
return input;
90+
}
91+
return lowerCase(input.replace(' ', '_'));
92+
}
93+
94+
private static class Resource {
95+
96+
private final URL url;
97+
98+
public Resource(URL url) {
99+
this.url = url;
100+
}
101+
102+
public String getFilename() {
103+
return FilenameUtils.getName(url.getPath());
104+
}
105+
106+
public InputStream getInputStream() throws IOException {
107+
URLConnection con = this.url.openConnection();
108+
try {
109+
return con.getInputStream();
110+
}
111+
catch (IOException ex) {
112+
// Close the HTTP connection (if applicable).
113+
if (con instanceof HttpURLConnection) {
114+
((HttpURLConnection) con).disconnect();
115+
}
116+
throw ex;
117+
}
118+
}
119+
}
120+
}

src/main/java/io/zonky/test/db/postgres/embedded/EmbeddedPostgres.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -486,7 +486,7 @@ public static class Builder
486486
private boolean builderCleanDataDirectory = true;
487487
private int builderPort = 0;
488488
private final Map<String, String> connectConfig = new HashMap<>();
489-
private PgBinaryResolver pgBinaryResolver = new BundledPostgresBinaryResolver();
489+
private PgBinaryResolver pgBinaryResolver = DefaultPostgresBinaryResolver.INSTANCE;
490490
private Duration pgStartupWait = DEFAULT_PG_STARTUP_WAIT;
491491

492492
private ProcessBuilder.Redirect errRedirector = ProcessBuilder.Redirect.PIPE;

src/main/java/io/zonky/test/db/postgres/embedded/PgBinaryResolver.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
/**
2121
* A strategy for resolving PostgreSQL binaries.
2222
*
23-
* @see BundledPostgresBinaryResolver
23+
* @see DefaultPostgresBinaryResolver
2424
*/
2525
public interface PgBinaryResolver {
2626

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
/*
2+
* Licensed under the Apache License, Version 2.0 (the "License");
3+
* you may not use this file except in compliance with the License.
4+
* You may obtain a copy of the License at
5+
*
6+
* http://www.apache.org/licenses/LICENSE-2.0
7+
*
8+
* Unless required by applicable law or agreed to in writing, software
9+
* distributed under the License is distributed on an "AS IS" BASIS,
10+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
* See the License for the specific language governing permissions and
12+
* limitations under the License.
13+
*/
14+
package io.zonky.test.db.postgres.util;
15+
16+
import org.apache.commons.lang3.StringUtils;
17+
18+
import static org.apache.commons.lang3.StringUtils.lowerCase;
19+
20+
public class ArchUtils {
21+
22+
private ArchUtils() {}
23+
24+
public static String normalize(String archName) {
25+
if (StringUtils.isBlank(archName)) {
26+
throw new IllegalStateException("No architecture detected");
27+
}
28+
29+
String arch = lowerCase(archName).replaceAll("[^a-z0-9]+", "");
30+
31+
if (arch.matches("^(x8664|amd64|ia32e|em64t|x64)$")) {
32+
return "x86_64";
33+
}
34+
if (arch.matches("^(x8632|x86|i[3-6]86|ia32|x32)$")) {
35+
return "x86_32";
36+
}
37+
if (arch.matches("^(ia64w?|itanium64)$")) {
38+
return "itanium_64";
39+
}
40+
if ("ia64n".equals(arch)) {
41+
return "itanium_32";
42+
}
43+
if (arch.matches("^(sparcv9|sparc64)$")) {
44+
return "sparc_64";
45+
}
46+
if (arch.matches("^(sparc|sparc32)$")) {
47+
return "sparc_32";
48+
}
49+
if (arch.matches("^(aarch64|armv8|arm64).*$")) {
50+
return "arm_64";
51+
}
52+
if (arch.matches("^(arm|arm32).*$")) {
53+
return "arm_32";
54+
}
55+
if (arch.matches("^(mips|mips32)$")) {
56+
return "mips_32";
57+
}
58+
if (arch.matches("^(mipsel|mips32el)$")) {
59+
return "mipsel_32";
60+
}
61+
if ("mips64".equals(arch)) {
62+
return "mips_64";
63+
}
64+
if ("mips64el".equals(arch)) {
65+
return "mipsel_64";
66+
}
67+
if (arch.matches("^(ppc|ppc32)$")) {
68+
return "ppc_32";
69+
}
70+
if (arch.matches("^(ppcle|ppc32le)$")) {
71+
return "ppcle_32";
72+
}
73+
if ("ppc64".equals(arch)) {
74+
return "ppc_64";
75+
}
76+
if ("ppc64le".equals(arch)) {
77+
return "ppcle_64";
78+
}
79+
if ("s390".equals(arch)) {
80+
return "s390_32";
81+
}
82+
if ("s390x".equals(arch)) {
83+
return "s390_64";
84+
}
85+
86+
throw new IllegalStateException("Unsupported architecture: " + archName);
87+
}
88+
}

0 commit comments

Comments
 (0)