dataminer-algorithm-importer/src/main/java/org/gcube/dataanalysis/wps/mapper/DataMinerUpdater.java

562 lines
20 KiB
Java

package org.gcube.dataanalysis.wps.mapper;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.EOFException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.net.URLConnection;
import java.util.Arrays;
import java.util.Base64;
import java.util.List;
import java.util.UUID;
import java.util.jar.Attributes;
import java.util.jar.JarEntry;
import java.util.jar.JarOutputStream;
import java.util.jar.Manifest;
import javax.tools.Diagnostic;
import javax.tools.Diagnostic.Kind;
import javax.tools.DiagnosticCollector;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
import org.gcube.common.resources.gcore.GenericResource;
import org.gcube.common.scope.api.ScopeProvider;
import org.gcube.contentmanagement.lexicalmatcher.utils.FileTools;
import org.gcube.informationsystem.publisher.RegistryPublisher;
import org.gcube.informationsystem.publisher.RegistryPublisherFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.ls.DOMImplementationLS;
import org.w3c.dom.ls.LSSerializer;
public class DataMinerUpdater {
// Example of call with modifications for private users
// ./addAlgorithm.sh NETCDF_SUPPORT_JAVA_13
// BLACK_BOX-[gianpaolo.coro,giancarlo.panichi]
// org.gcube.dataanalysis.executor.rscripts.NetCDFSupportJava
// /gcube/devNext/NextNext transducerers N
// http://data-d.d4science.org/ZGZSUHlQODRZY3pBQVZxNlVOK0xzUVZKc0dZczBKaEpHbWJQNStIS0N6Yz0
// "NetCDF Support Java" dev/software/
public static void main(String args[]) throws Exception {
System.out.println("Algorithm installer v 1.2.1");
String algorithmName = null;
String implementation = null;
String category = null;
String configPath = null;
String libPath = null;
String scope = null;
String description = null;
String atype = null;
String skipJava = null;
String url = null;
String privateusers = null;
int i = 0;
for (String arg : args) {
if (arg.startsWith("-c")) {
configPath = arg.substring(2);
}
if (arg.startsWith("-i")) {
implementation = arg.substring(2);
}
if (arg.startsWith("-a")) {
algorithmName = arg.substring(2);
}
if (arg.startsWith("-t")) {
category = arg.substring(2);
//int idxprivusers = category.indexOf("-[");
int idxprivusers = category.indexOf("-#");
if (idxprivusers > 1) {
privateusers = category.substring(idxprivusers + 2, category.length() - 1);
category = category.substring(0,idxprivusers);
System.out.println("Found private Users " + privateusers);
System.out.println("Category for these users " + category);
}
}
if (arg.startsWith("-l")) {
libPath = arg.substring(2);
}
if (arg.startsWith("-s")) {
scope = arg.substring(2);
}
if (arg.startsWith("-e")) {
atype = arg.substring(2);
}
if (arg.startsWith("-k")) {
skipJava = arg.substring(2);
if (skipJava.equals("Y"))
skipJava = null;
}
if (arg.startsWith("-u")) {
url = arg.substring(2);
}
if (arg.startsWith("-d")) {
description = arg.substring(2);
for (int j = i + 1; j < args.length; j++) {
description = description + " " + args[j];
}
System.out.println("DESCRIPTION " + description);
break;
}
i++;
}
if (libPath == null || category == null || implementation == null || configPath == null || algorithmName == null || scope == null) {
System.out.println("Wrong parameters");
System.out.println("Usage example: ");
System.exit(0);
}
Update(algorithmName, implementation, category, configPath, libPath, scope, description, atype, skipJava, url, privateusers);
}
public static void UpdateFiles(String configPath, String atype, String algorithmName, String implementation, String category) throws Exception {
File transducers = new File(configPath, atype + ".properties");
File userpersp = new File(configPath, "userperspective.properties");
// UPDATING TRANDUCERERS FILES
System.out.println("*******Modifying transducerer file");
BufferedReader br = new BufferedReader(new FileReader(transducers));
String entry = algorithmName + "=" + implementation;
String line = br.readLine();
boolean found = false;
boolean endline = false;
String lastline = "";
StringBuffer sbb = new StringBuffer();
while (line != null) {
lastline = line;
if (line.trim().equalsIgnoreCase(entry)) {
found = true;
break;
}
sbb.append(line.trim() + System.lineSeparator());
line = br.readLine();
}
br.close();
if (!found) {
FileWriter fw = new FileWriter(transducers, false);
sbb.append(entry + System.lineSeparator());
fw.write(sbb.toString());
fw.close();
System.out.println("*******Modified transducerer file");
} else
System.out.println("*******Transducerer file was not modified, since it already contains the algorithm");
// UPDATING USER PERSPECTIVE FILE
System.out.println("*******Modifying user perspective file");
br = new BufferedReader(new FileReader(userpersp));
line = br.readLine();
found = false;
StringBuffer sb = new StringBuffer();
boolean foundCategory = false;
while (line != null) {
String cat = line.substring(0, line.indexOf("="));
if (cat.equalsIgnoreCase(category)) {
foundCategory = true;
String arguments = line.substring(line.indexOf("=") + 1).trim();
String argums[] = arguments.split(",");
List valid = Arrays.asList(argums);
// if (!line.contains(algorithmName)){
if (!valid.contains(algorithmName)) {
if (line.substring(line.indexOf("=") + 1).trim().length() == 0)
line = line + algorithmName;
else
line = line + "," + algorithmName;
} else
found = true;
}
if (line.trim().length() > 0)
sb.append(line + System.lineSeparator());
line = br.readLine();
}
br.close();
if (!foundCategory) {
sb.append(category + "=" + algorithmName + System.lineSeparator());
FileWriter fw = new FileWriter(userpersp, false);
fw.write(sb.toString());
fw.close();
System.out.println("*******Modified user perspective file");
} else {
if (!found) {
FileWriter fw = new FileWriter(userpersp, false);
fw.write(sb.toString());
fw.close();
System.out.println("*******Modified user perspective file");
} else
System.out.println("*******Perspective file was not modified, since it already contains the algorithm");
}
if (atype.equals("models"))
atype = "modellers";
if (atype.equals("nodealgorithms"))
atype = "generators";
if (atype.equals("algorithms"))
atype = "generators";
}
public static void Update(String algorithmName, String implementation, String category, String configPath, String applicationlibs, String scope, String description, String atype, String skipJava, String url, String privateusers) throws Exception {
BufferedReader br;
String line;
if (atype == null || atype.trim().length() == 0)
atype = "transducerers";
System.out.println("Running updater 1.2");
System.out.println("*****Parameters");
System.out.println("*****algorithmName:" + algorithmName);
System.out.println("*****implementation:" + implementation);
System.out.println("*****category:" + category);
System.out.println("*****configPath:" + configPath);
System.out.println("*****applicationlibs:" + applicationlibs);
System.out.println("*****scope:" + scope);
System.out.println("*****description:" + description);
System.out.println("*****atype:" + atype);
System.out.println("*****skipJava:" + ((skipJava == null) ? true : false));
System.out.println("*****url:" + url);
System.out.println("*******1 - Downloading file");
if (url != null && url.length() > 1 && skipJava != null) {
File jarfile = new File(applicationlibs, algorithmName + ".jar");
System.out.println("*******Downloading to " + jarfile.getAbsolutePath());
downloadFromUrl(url, jarfile.getAbsolutePath());
System.out.println("*******Download OK - check " + jarfile.exists());
System.out.println("*******Updating classpath");
// load the jar into the classpath
URLClassLoader sysloader = (URLClassLoader) Thread.currentThread().getContextClassLoader();
Class sysclass = URLClassLoader.class;
Class[] parameters = new Class[] { URL.class };
try {
Method method = sysclass.getDeclaredMethod("addURL", parameters);
method.setAccessible(true);
method.invoke(sysloader, new Object[] { jarfile.toURI().toURL() });
} catch (Throwable t) {
t.printStackTrace();
throw new IOException("Error, could not add URL to system classloader");
}// end try catch
} else
System.out.println("*******1 - Nothing to download");
System.out.println("*******2 - Updating files");
UpdateFiles(configPath, atype, algorithmName, implementation, category);
if (atype.equals("nodealgorithms")) {
System.out.println("*******2 - Updating also algorithms file");
UpdateFiles(configPath, "algorithms", algorithmName, implementation, category);
}
System.out.println("*******2 - Files updated!");
// GENERATING CLASS
if (skipJava != null) {
System.out.println("*******3 - Generating classes");
String generationPath = "./org/gcube/dataanalysis/wps/statisticalmanager/synchserver/mappedclasses/";
ClassGenerator classGenerator = new ClassGenerator(algorithmName, implementation, generationPath, configPath);
System.out.println("*******3 - Classes generated! " + classGenerator.getJavaFileName());
// PREPARING JAR FILE
File dataminerjar = new File(applicationlibs, algorithmName + "_interface.jar");
dataminerjar.delete();
// COMPILING JAR
System.out.println("*******4 - Compiling the Jar");
compileJava(classGenerator.getJavaFileName());
System.out.println("*******->creating jar");
createJar(dataminerjar, classGenerator.getPackageString(), algorithmName);
// command(classes);
// command(createjar);
System.out.println("*******Size " + dataminerjar.length());
System.out.println("*******4 - Jar compiled!! " + dataminerjar);
} else {
System.out.println("*******3 - Generating classes skipped");
System.out.println("*******4 - Compiling the Jar skipped");
}
// INDEX ON THE IS
System.out.println("*******5 - Indexing on the IS");
System.out.println("Indexing on IS in scope " + scope);
indexOnIS(algorithmName, description, scope, privateusers);
System.out.println("*******5 - Finished indexing on the IS");
System.out.println("*******All done!");
System.out.println("*******Table entry:");
System.out.println("| " + algorithmName + " | " + "system" + " | " + category + "| Prod | <notextile>./addAlgorithm.sh " + algorithmName + " " + category + " " + implementation + " " + scope + " " + atype + " " + (skipJava != null ? "N" : "Y") + " " + ((url != null && url.length() > 1) ? url : "k") + " \"" + description + "\"" + " </notextile> | none |");
}
private static void compileJava(String javaFileName) throws Exception {
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
Iterable<? extends JavaFileObject> compilationUnits1 = fileManager.getJavaFileObjectsFromFiles(Arrays.asList(new File(javaFileName)));
DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();
boolean success = compiler.getTask(null, fileManager, diagnostics, null, null, compilationUnits1).call();
for (Diagnostic<? extends JavaFileObject> diagnostic : diagnostics.getDiagnostics())
if (diagnostic.getKind() == Kind.ERROR)
System.out.format("Error on line %d in %s%n", diagnostic.getLineNumber(), diagnostic.getSource().toUri());
if (!success)
throw new Exception("error compiling generated class");
}
private static void createJar(File dataminerjar, String packageString, String algorithmName) throws Exception {
Manifest manifest = new Manifest();
manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0");
try (JarOutputStream target = new JarOutputStream(new FileOutputStream(dataminerjar), manifest)) {
target.putNextEntry(new JarEntry("org/gcube/dataanalysis/wps/statisticalmanager/synchserver/mappedclasses/" + packageString + "/"));
String source = "org/gcube/dataanalysis/wps/statisticalmanager/synchserver/mappedclasses/" + packageString + "/" + algorithmName + ".class";
File fileSource = new File(source);
JarEntry entry = new JarEntry(source);
target.putNextEntry(entry);
try (BufferedInputStream in = new BufferedInputStream(new FileInputStream(fileSource));) {
byte[] buffer = new byte[1024];
while (true) {
int count = in.read(buffer);
if (count == -1)
break;
target.write(buffer, 0, count);
}
}
target.closeEntry();
target.close();
}
}
public static String ExecuteGetLineOld(String cmd) {
Process process = null;
String lastline = "";
StringBuffer sb = new StringBuffer();
try {
System.out.println("ExecuteScript-> OSCommand-> Executing Control ->" + cmd);
process = Runtime.getRuntime().exec(cmd);
BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line = br.readLine();
System.out.println("ExecuteScript-> OSCommand-> line->" + line);
while (line != null) {
try {
lastline = line;
System.out.println("ExecuteScript-> OSCommand-> line->" + line);
line = br.readLine();
if (line != null)
sb.append(line + System.lineSeparator());
} catch (EOFException e) {
System.out.println("ExecuteScript-> OSCommand -> Process Finished with EOF");
break;
} catch (Exception e) {
line = "ERROR";
break;
}
}
System.out.println("ExecuteScript-> OSCommand -> Process Finished");
} catch (Throwable e) {
System.out.println("ExecuteScript-> OSCommand-> error ");
e.printStackTrace();
lastline = "ERROR";
}
process.destroy();
System.out.println("ExecuteScript-> OSCommand-> Process destroyed ");
return sb.toString();
}
public static void indexOnIS(String algorithmName, String algorithmDescription, String scope, String privateusers) throws Exception {
System.out.println("setting scope to " + scope);
String secondaryTypePublic = "StatisticalManagerAlgorithm";
String secondaryTypePrivate = "StatisticalManagerAlgorithmPrivate";
String secondaryType = secondaryTypePublic;
if (privateusers != null)
secondaryType = secondaryTypePrivate;
InfrastructureDialoguer id = new InfrastructureDialoguer(scope);
if (privateusers != null) {
System.out.println("Transforming Algorithm " + algorithmName + " into private algorithm");
ScopeProvider.instance.set(scope);
System.out.println("Deleting previous algorithm " + algorithmName + " from private algorithms");
id.deleteAlgorithmInScope(algorithmName, secondaryTypePrivate);
System.out.println("Deleting previous algorithm " + algorithmName + " from public algorithms");
id.deleteAlgorithmInScope(algorithmName, secondaryTypePublic);
} else {
ScopeProvider.instance.set(scope);
List<String> algorithms = id.getAlgorithmsInScope(secondaryType);
System.out.println("Deleting previous algorithm " + algorithmName + " from private algorithms");
id.deleteAlgorithmInScope(algorithmName, secondaryTypePrivate);
boolean found = false;
for (String alg : algorithms) {
System.out.println("Algorithm in scope " + alg);
if (alg.equals(algorithmName)) {
System.out.println("Found Match! ");
found = true;
break;
}
}
if (found) {
return;
}
}
String xml = FileTools.loadString("algorithmTemplate", "UTF-8");
xml = xml.replace("#UUID#", UUID.randomUUID().toString());
xml = xml.replace("#SCOPE#", scope);
xml = xml.replace("#NAME#", algorithmName);
xml = xml.replace("#DESCRIPTION#", algorithmDescription);
// patch to add private users property - GP
if (privateusers != null) {
ScopeProvider.instance.set(scope);
/* encryption using d4science */
/*
* InputStream privateusersstream = new
* ByteArrayInputStream(privateusers
* .getBytes(StandardCharsets.UTF_8.name())); ByteArrayOutputStream
* baos = new ByteArrayOutputStream(); new
* EncryptionUtil().encrypt(privateusersstream, baos); String
* privateusersencr = new String( baos.toByteArray());
*/
String privateuserencr = privateusers;//encrypt(privateusers);
xml = xml.replace("</inputs>", "</inputs><privateusers>" + privateuserencr + "</privateusers>");
}
xml = xml.trim();
System.out.println("XML:" + xml);
ScopeProvider.instance.set(scope);
GenericResource toPublish = new GenericResource();
Document document = toPublish.newProfile().description(algorithmDescription.replace("\"", "")).name(algorithmName).type(secondaryType).newBody().getOwnerDocument();
toPublish.profile().newBody(xml);
Node n = toPublish.profile().body();
DOMImplementationLS lsImpl = (DOMImplementationLS) n.getOwnerDocument().getImplementation().getFeature("LS", "3.0");
LSSerializer serializer = lsImpl.createLSSerializer();
serializer.getDomConfig().setParameter("xml-declaration", false); // by
// default
// its
// true,
// so
// set
// it
// to
// false
// to
// get
// String
// without
// xml-declaration
String str = serializer.writeToString(n);
System.out.println("STRING:" + str);
System.out.println(toPublish.profile().body());
RegistryPublisher rp = RegistryPublisherFactory.create();
toPublish = rp.create(toPublish);
System.out.println("PUBLISHED");
}
public static String encrypt(String text) {
return new String(Base64.getEncoder().encode(xor(text.getBytes())));
}
public static String decrypt(String hash) {
try {
return new String(xor(Base64.getDecoder().decode(hash.getBytes())), "UTF-8");
} catch (java.io.UnsupportedEncodingException ex) {
throw new IllegalStateException(ex);
}
}
private static byte[] xor(final byte[] input) {
final byte[] output = new byte[input.length];
final byte[] secret = "dminstall".getBytes();
int spos = 0;
for (int pos = 0; pos < input.length; ++pos) {
output[pos] = (byte) (input[pos] ^ secret[spos]);
spos += 1;
if (spos >= secret.length) {
spos = 0;
}
}
return output;
}
static void downloadFromUrl(String urlString, String localFilename) throws IOException {
InputStream is = null;
FileOutputStream fos = null;
System.out.println("Downloading :" + urlString);
URL url = new URL(urlString);
try {
URLConnection urlConn = url.openConnection();// connect
is = urlConn.getInputStream(); // get connection inputstream
fos = new FileOutputStream(localFilename); // open outputstream to
// local file
byte[] buffer = new byte[4096]; // declare 4KB buffer
int len;
// while we have availble data, continue downloading and storing to
// local file
while ((len = is.read(buffer)) > 0) {
fos.write(buffer, 0, len);
}
} finally {
try {
if (is != null) {
is.close();
}
} finally {
if (fos != null) {
fos.close();
}
}
}
}
}