Skip to content
Snippets Groups Projects
Commit 5ca1b364 authored by Felix Sidokhine's avatar Felix Sidokhine
Browse files

almost done cleaning the updater hell

parent 0aa9817e
No related branches found
No related tags found
No related merge requests found
Showing
with 92 additions and 127 deletions
......@@ -27,11 +27,6 @@
<artifactId>xbean-classloader</artifactId>
<version>${xbean.version}</version>
</dependency>
<dependency>
<groupId>org.zeromq</groupId>
<artifactId>jeromq</artifactId>
<version>0.5.2</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
......@@ -80,7 +80,6 @@ module jams.common {
requires java.base;
requires java.sql;
requires org.apache.xbean.classloader;
requires jeromq;
requires java.naming;
}
......@@ -2,6 +2,7 @@ package net.jami.jams.common.objects.responses;
import lombok.Getter;
import lombok.Setter;
import net.jami.jams.common.updater.FileDescription;
import net.jami.jams.common.updater.subscription.LicenseInformation;
import java.util.HashMap;
......@@ -14,6 +15,6 @@ public class SubscriptionStatusResponse {
private LicenseInformation licenseInformation;
private Boolean activated;
private HashMap<String,String> versions = checkVersion();
private HashMap<String, FileDescription> versions = checkVersion();
}
......@@ -2,8 +2,8 @@ package net.jami.jams.common.updater;
public interface AppUpdater {
String getCurrentVersion();
String getLatestVersion();
String getLocalVersions();
String getRemoteVersions();
boolean downloadUpdates();
}
package net.jami.jams.common.updater;
import lombok.*;
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode
public class FileDescription {
private String fileName;
private String version;
private String md5hash;
private String mainClass;
}
package net.jami.jams.common.updater;
import java.util.HashMap;
public interface FileRepository {
HashMap<String,FileDescription> getFileVersions();
}
package net.jami.jams.common.utils;
import lombok.extern.slf4j.Slf4j;
import net.jami.jams.common.updater.FileDescription;
import org.bouncycastle.util.encoders.Hex;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.jar.JarFile;
......@@ -14,18 +17,32 @@ import java.util.jar.JarFile;
public class VersioningUtils {
private static final String IMPLEMENTATION_VERSION_FIELD = "Implementation-Version";
private static final String MAIN_CLASS_FIELD = "Main-Class";
private static MessageDigest messageDigest;
public static HashMap<String,String> checkVersion() {
static {
try {
HashMap<String,String> res = new HashMap<>();
messageDigest = MessageDigest.getInstance("MD5");
}
catch (Exception e){
messageDigest = null;
}
}
public static HashMap<String, FileDescription> checkVersion() {
try {
HashMap<String,FileDescription> res = new HashMap<>();
ArrayList<Path> files = new ArrayList<>();
Files.walk(Paths.get(System.getProperty("user.dir"))).filter(Files::isRegularFile).forEach(files::add);
files.forEach( e ->{
if(e.toString().endsWith(".jar")){
try {
String version = new JarFile(e.toFile()).getManifest().getMainAttributes().getValue(IMPLEMENTATION_VERSION_FIELD);
JarFile file = new JarFile(e.toFile());
String version = file.getManifest().getMainAttributes().getValue(IMPLEMENTATION_VERSION_FIELD);
String className = file.getManifest().getMainAttributes().getValue(MAIN_CLASS_FIELD);
String md5 = Hex.toHexString(messageDigest.digest(Files.readAllBytes(e.toAbsolutePath())));
String[] arr = e.toString().split(File.separator);
res.put(arr[arr.length - 1],version);
res.put(arr[arr.length - 1],new FileDescription(arr[arr.length - 1],version,md5,className));
log.info("Found version {} of {}",version,e.toString());
}
catch (Exception e1){
......
package net.jami.jams.common.utils;
import net.jami.jams.common.updater.FileDescription;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
......@@ -11,7 +12,7 @@ class VersioningUtilsTest {
@Test
@Disabled
public void testFileScan(){
HashMap<String,String> res = VersioningUtils.checkVersion();
HashMap<String, FileDescription> res = VersioningUtils.checkVersion();
Assertions.assertEquals(6,res.size(),"Incorrect number of versions detected!");
}
......
......@@ -26,11 +26,6 @@
<artifactId>httpclient</artifactId>
<version>${apache.httpclient.version}</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>${google.guava.version}</version>
</dependency>
<dependency>
<groupId>org.zeromq</groupId>
<artifactId>jeromq</artifactId>
......
......@@ -46,6 +46,7 @@ import java.nio.file.Files;
import java.nio.file.Path;
import java.security.KeyFactory;
import java.security.KeyStore;
import java.security.MessageDigest;
import java.security.PrivateKey;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
......@@ -62,6 +63,10 @@ import java.util.jar.Manifest;
@Slf4j
public class UpdateThread extends Thread {
private static final String IFACE_TCP_RECEIVER = "tcp://localhost:4573";
private static final String IFACE_TCP_PUBLISHER = "tcp://localhost:4572";
private static final String SUBSCRIBER_TOPIC = "UPDATE";
private HashMap<String, String> localVersions = new HashMap<>();
private HashMap<String, String> localExecs = new HashMap<>();
private HashMap<String, String> remoteVersions = new HashMap<>();
......@@ -74,117 +79,31 @@ public class UpdateThread extends Thread {
private static volatile Long UPDATE_INTERVAL;
private SSLContext sslContext = null;
private Process applicationProcess;
private ZMQ.Socket publisher;
private ZMQ.Socket receiver;
private ZMQ.Socket publisher = AppStarter.context.socket(SocketType.PUB);
private ZMQ.Socket receiver = AppStarter.context.socket(SocketType.REP);
private AtomicBoolean doUpdate = new AtomicBoolean(false);
private MessageReceiver messageReceiver;
public UpdateThread() {
}
public UpdateThread(Process applicationProcess, String[] parentArgs) {
try {
//Use this to notify
publisher = AppStarter.context.socket(SocketType.PUB);
publisher.bind("tcp://*:4572");
//Use this to updater.
receiver = AppStarter.context.socket(SocketType.REP);
receiver.bind("tcp://*:4573");
publisher.bind(IFACE_TCP_PUBLISHER);
receiver.bind(IFACE_TCP_RECEIVER);
messageReceiver = new MessageReceiver(receiver,doUpdate);
messageReceiver.start();
} catch (Exception e) {
log.warn("Could not create and bind publisher and/or receiver! Please contact software developer");
System.exit(-1);
}
try {
InputStream input = AppStarter.class.getClassLoader().getResourceAsStream("oem/config.json");
Any any = JsonIterator.deserialize(input.readAllBytes());
CORE_PACKAGE_MAIN_CLASS_NAME = any.get("CORE_PACKAGE_MAIN_CLASS_NAME").toString();
UPDATE_SERVER_URL = any.get("UPDATE_URL").toString();
UPDATE_INTERVAL = any.get("UPDATE_INTERVAL").toLong();
} catch (IOException e) {
log.warn("Missing OEM configuration! Please contact software developer");
System.exit(-1);
}
System.out.println("Update thread created...");
log.info("Update thread created...");
this.parentArgs = parentArgs;
this.applicationProcess = applicationProcess;
}
//It is a VERY bad idea to use version numbers inside file names as this will break at some point and cause MAJOR
//user problems, we can therefore by-pass this by doing the following.
public static String[] unzipJar(String destinationDir, String jarPath) throws IOException {
String[] resp = new String[2];
File file = new File(jarPath);
JarFile jar = new JarFile(file);
// fist get all directories,
// then make those directory on the destination Path
for (Enumeration<JarEntry> enums = jar.entries(); enums.hasMoreElements(); ) {
JarEntry entry = (JarEntry) enums.nextElement();
String fileName = destinationDir + File.separator + entry.getName();
File f = new File(fileName);
if (fileName.endsWith("/")) {
f.mkdirs();
}
}
//now create all files
for (Enumeration<JarEntry> enums = jar.entries(); enums.hasMoreElements(); ) {
JarEntry entry = (JarEntry) enums.nextElement();
if (entry.toString().contains("META-INF/MANIFEST.MF")) {
String fileName = destinationDir + File.separator + entry.getName();
File f = new File(fileName);
if (!fileName.endsWith("/")) {
InputStream is = jar.getInputStream(entry);
FileOutputStream fos = new FileOutputStream(f);
// write contents of 'is' to 'fos'
while (is.available() > 0) {
fos.write(is.read());
}
fos.close();
is.close();
}
}
}
String manifestPath = destinationDir + "/META-INF/MANIFEST.MF";
Manifest manifest = new Manifest(new URL("file:///" + manifestPath).openStream());
resp[0] = manifest.getMainAttributes().getValue("Implementation-Version");
resp[1] = manifest.getMainAttributes().getValue("Main-Class");
return resp;
}
public void detectCurrentVersions(String folder) {
try {
File folderExec = new File(folder.replace("/jams-launcher", ""));
File folderLibs = new File(folder.replace("/jams-launcher", "") + "/libs");
discoverVersions(folderExec);
discoverVersions(folderLibs);
} catch (Exception e) {
log.warn(e.toString());
}
}
private void discoverVersions(File folderLibs) throws IOException {
for (File f : Objects.requireNonNull(folderLibs.listFiles())) {
if (f.isFile() && f.getName().contains(".jar") && !f.getName().contains("jams-launcher")) {
String[] resp = unzipJar(System.getProperty("user.dir") + "/tmpjar/" + f.getName(), f.getAbsolutePath());
localVersions.put(resp[1], resp[0]);
localExecs.put(resp[1], f.getName());
}
}
}
// This reads a file on the server which contains some basic info
// about what new versions of WHAT are available.
private void getLatestVersion() {
......@@ -401,21 +320,12 @@ public class UpdateThread extends Thread {
}
}
private static String checksum(String filepath) throws IOException {
HashCode hash = com.google.common.io.Files
.hash(new File(filepath), Hashing.md5());
log.warn("Calculated md5: " + hash.toString());
return hash.toString();
}
@Override
public void run() {
Timer timer = new Timer();
// check if license is valid, then attempt SSL handshake with update server.
try {
System.out.println("Update timer started");
log.info("Update timer started");
TimerTask pollTask = new TimerTask() {
@Override
public void run() {
......
......@@ -22,8 +22,6 @@
*/
module jams.launcher {
opens com.google.guava;
opens org.zeromq.ZMQ;
requires lombok;
requires org.slf4j;
requires jsoniter;
......@@ -36,5 +34,6 @@ module jams.launcher {
requires org.apache.httpcomponents.httpcore;
requires org.apache.httpcomponents.httpclient;
requires plexus.utils;
requires jams.common;
}
......@@ -52,7 +52,6 @@
<maven.model.version>3.2.5</maven.model.version>
<apache.httpcore.version>4.4.12</apache.httpcore.version>
<apache.httpclient.version>4.5.10</apache.httpclient.version>
<google.guava.version>20.0</google.guava.version>
</properties>
<dependencies>
......
......@@ -17,6 +17,11 @@
<version>${revision}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.zeromq</groupId>
<artifactId>jeromq</artifactId>
<version>${jeromq.version}</version>
</dependency>
</dependencies>
<build>
......
......@@ -27,13 +27,14 @@ public class JAMSUpdater extends Thread implements AppUpdater {
this.start();
}
@Override
public String getCurrentVersion() {
public String getLocalVersions() {
return null;
}
@Override
public String getLatestVersion() {
public String getRemoteVersions() {
return null;
}
......
package net.jami.jams.updater;
import net.jami.jams.common.updater.FileDescription;
import net.jami.jams.common.updater.FileRepository;
import java.util.HashMap;
public class LocalVersionRepository implements FileRepository {
@Override
public HashMap<String, FileDescription> getFileVersions() {
return null;
}
}
package net.jami.jams.updater;
public class RemoteVersionRepository {
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment