Skip to content

Commit

Permalink
SQL: Handle uberjar scenario where the ES jdbc driver file is bundled…
Browse files Browse the repository at this point in the history
… in another jar (#51856)

(cherry picked from commit 6247b07)
  • Loading branch information
astefan committed Feb 7, 2020
1 parent c85edf9 commit 3ccea31
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import java.io.IOException;
import java.net.URL;
import java.net.URLConnection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.LinkedHashSet;
Expand Down Expand Up @@ -86,26 +87,34 @@ static byte[] from(String ver) {
// This is similar to how Elasticsearch's Build class digs up its build information.
// Since version info is not critical, the parsing is lenient
URL url = Version.class.getProtectionDomain().getCodeSource().getLocation();
String urlStr = url.toString();
CURRENT = extractVersion(url);
}

static Version extractVersion(URL url) {
String urlStr = url.toString();
byte maj = 0, min = 0, rev = 0;
String ver = "Unknown";
String hash = ver;

if (urlStr.endsWith(".jar")) {
try (JarInputStream jar = new JarInputStream(url.openStream())) {
Manifest manifest = jar.getManifest();
hash = manifest.getMainAttributes().getValue("Change");
ver = manifest.getMainAttributes().getValue("X-Compile-Elasticsearch-Version");
byte[] vers = from(ver);
maj = vers[0];
min = vers[1];
rev = vers[2];

if (urlStr.endsWith(".jar") || urlStr.endsWith(".jar!/")) {
try {
URLConnection conn = url.openConnection();
conn.setUseCaches(false);

try (JarInputStream jar = new JarInputStream(conn.getInputStream())) {
Manifest manifest = jar.getManifest();
hash = manifest.getMainAttributes().getValue("Change");
ver = manifest.getMainAttributes().getValue("X-Compile-Elasticsearch-Version");
byte[] vers = from(ver);
maj = vers[0];
min = vers[1];
rev = vers[2];
}
} catch (Exception ex) {
throw new IllegalArgumentException("Detected Elasticsearch JDBC jar but cannot retrieve its version", ex);
}
}
CURRENT = new Version(ver, hash, maj, min, rev);
return new Version(ver, hash, maj, min, rev);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,17 @@
package org.elasticsearch.xpack.sql.client;

import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.xpack.sql.client.Version;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.util.jar.Attributes;
import java.util.jar.JarEntry;
import java.util.jar.JarOutputStream;
import java.util.jar.Manifest;

public class VersionTests extends ESTestCase {
public void test70Version() {
Expand Down Expand Up @@ -43,4 +53,47 @@ public void testInvalidVersion() {
IllegalArgumentException err = expectThrows(IllegalArgumentException.class, () -> Version.from("7.1"));
assertEquals("Invalid version 7.1", err.getMessage());
}

public void testVersionFromJarInJar() throws IOException {
final String JDBC_JAR_NAME = "es-sql-jdbc.jar";
final String JAR_PATH_SEPARATOR = "!/";

Path dir = createTempDir();
Path jarPath = dir.resolve("uberjar.jar"); // simulated uberjar containing the jdbc driver
Path innerJarPath = dir.resolve(JDBC_JAR_NAME); // simulated ES JDBC driver file

Manifest jdbcJarManifest = new Manifest();
Attributes attributes = jdbcJarManifest.getMainAttributes();
attributes.put(Attributes.Name.MANIFEST_VERSION, "1.0.0");
attributes.put(new Attributes.Name("Change"), "abc");
attributes.put(new Attributes.Name("X-Compile-Elasticsearch-Version"), "1.2.3");

// create the jdbc driver file
try (JarOutputStream jdbc = new JarOutputStream(Files.newOutputStream(innerJarPath, StandardOpenOption.CREATE), jdbcJarManifest)) {}

// create the uberjar and embed the jdbc driver one into it
try (BufferedInputStream in = new BufferedInputStream(Files.newInputStream(innerJarPath));
JarOutputStream out = new JarOutputStream(Files.newOutputStream(jarPath, StandardOpenOption.CREATE), new Manifest())) {
JarEntry entry = new JarEntry(JDBC_JAR_NAME + JAR_PATH_SEPARATOR);
out.putNextEntry(entry);

byte[] buffer = new byte[1024];
while (true) {
int count = in.read(buffer);
if (count == -1) {
break;
}
out.write(buffer, 0, count);
}
}

URL jarInJar = new URL("jar:" + jarPath.toUri().toURL().toString() + JAR_PATH_SEPARATOR + JDBC_JAR_NAME + JAR_PATH_SEPARATOR);

Version version = Version.extractVersion(jarInJar);
assertEquals(1, version.major);
assertEquals(2, version.minor);
assertEquals(3, version.revision);
assertEquals("abc", version.hash);
assertEquals("1.2.3", version.version);
}
}

0 comments on commit 3ccea31

Please sign in to comment.