ai.h2o.servicebuilder.Util.java Source code

Java tutorial

Introduction

Here is the source code for ai.h2o.servicebuilder.Util.java

Source

/*
  Copyright (C) 2016 H2O.ai, Inc. <http://h2o.ai/>
    
  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU Affero General Public License as
  published by the Free Software Foundation, either version 3 of the
  License, or (at your option) any later version.
    
  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU Affero General Public License for more details.
    
  You should have received a copy of the GNU Affero General Public License
  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

package ai.h2o.servicebuilder;

import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;

import java.io.*;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarOutputStream;
import java.util.jar.Manifest;

/**
 * Util methods for make war servlet and compile pojo servlet
 *
 * Created by magnus on 5/10/16.
 */
public class Util {
    private static final Logger logger = Logging.getLogger(Util.class);

    public static final String JAVA_TEMPLATE_REPLACE_WITH_PREDICTOR_CLASS_NAME = "REPLACE_THIS_WITH_PREDICTOR_CLASS_NAME";
    public static final String JAVA_TEMPLATE_REPLACE_WITH_PYTHON_ENVIRONMENT_FILE = "REPLACE_WITH_PYTHON_ENVIRONMENT_FILE";
    public static final String JAVA_TEMPLATE_REPLACE_WITH_TRANSFORMER_OBJECT = "REPLACE_THIS_WITH_TRANSFORMER_OBJECT";
    public static final String JAVA_TEMPLATE_REPLACE_THIS_WITH_MODEL = "REPLACE_THIS_WITH_MODEL";

    protected static final String MEMORY_FOR_JAVA_PROCESSES = "4g";
    protected static final String JAVA_TARGET_VERSION = "1.6";

    //  public static class Times {
    //    private long count = 0;
    //    private double totalTimeMs = 0;
    //    private double totalTimeSquaredMs = 0;
    //    private double warmupTimeMs = 0;
    //    private double warmupTimeSquaredMs = 0;
    //    private double lastMs = 0;
    //
    //    private Gson gson = new Gson();
    //
    //    public static final int warmUpCount = 5;
    //    public static final Type MapType = new TypeToken<HashMap<String, Object>>(){}.getType();
    ////    public static final Type ROW_DATA_TYPE = new TypeToken<RowData>(){}.getType();
    //
    //
    //    public void add(long startNs, long endNs, int n) {
    //      double elapsed = (endNs - startNs) / 1.0e6;
    //      add(elapsed, n);
    //    }
    //
    //    public void add(long startNs, long endNs) {
    //      add(startNs, endNs, 1);
    //    }
    //
    //    public synchronized void add(double timeMs, int n) {
    //      count += n;
    //      totalTimeMs += timeMs; // n * timeMs/n
    //      double tt = timeMs * timeMs / n; // n * (timeMs/n)^2
    //      totalTimeSquaredMs += tt;
    //      if (count <= warmUpCount) {
    //        warmupTimeMs += timeMs;
    //        warmupTimeSquaredMs += tt;
    //      }
    //      lastMs = timeMs / n;
    //    }
    //
    //    public double avg() {
    //      return count > 0 ? totalTimeMs / count : 0.0;
    //    }
    //
    ////    public double sdev() {
    ////
    ////    }
    //
    //    public double avgAfterWarmup() {
    //      return count > warmUpCount ? (totalTimeMs - warmupTimeMs) / (count - warmUpCount) : 0.0;
    //    }
    //
    //    public String toJson() {
    //      return gson.toJson(toMap());
    //    }
    //
    //    public Map<String, Object> toMap() {
    //      Map<String, Object> map = classToMap();
    //      map.put("averageTime", avg());
    //      map.put("averageAfterWarmupTime", avgAfterWarmup());
    //      return map;
    //    }
    //
    //    private Map<String, Object> classToMap() {
    //      return gson.fromJson(gson.toJson(this), MapType);
    //    }
    //
    //    public String toString() {
    //      return String.format("n %d  last %.3f  avg %.3f after warmup %.3f [ms]", count, lastMs, avg(), avgAfterWarmup());
    //    }
    //  }
    //
    //  public static long startTime = System.currentTimeMillis();
    //  public static long lastTime = 0;
    //  public static Times predictionTimes = new Times();
    //  public static Times getTimes = new Times();
    //  public static Times postTimes = new Times();
    //  public static Times getPythonTimes = new Times();
    //  public static Times postPythonTimes = new Times();
    //

    //  public static synchronized AbstractPrediction predict(EasyPredictModelWrapper model, RowData row)
    //      throws PredictException {
    //    long start = System.nanoTime();
    //    AbstractPrediction p = model.predict(row);
    //    long done = System.nanoTime();
    //    lastTime = System.currentTimeMillis();
    //    predictionTimes.add(start, done);
    //
    ////    if (VERBOSE) System.out.println("Prediction time " + predictionTimes);
    //    return p;
    //  }

    /**
     * Run command cmd in separate process in directory
     *
     * @param directory    run in this directory
     * @param cmd          command to run
     * @param errorMessage error message if process didn't finish with exit value 0
     * @return stdout combined with stderr
     * @throws Exception
     */
    public static String runCmd(File directory, List<String> cmd, String errorMessage) throws Exception {
        ProcessBuilder pb = new ProcessBuilder(cmd);
        pb.directory(directory);
        pb.redirectErrorStream(true); // error sent to output stream
        Process p = pb.start();

        // get output stream to string
        String s;
        StringBuilder sb = new StringBuilder();
        BufferedReader stdout = new BufferedReader(new InputStreamReader(p.getInputStream()));
        while ((s = stdout.readLine()) != null) {
            logger.info(s);
            sb.append(s);
            sb.append('\n');
        }
        String sbs = sb.toString();
        int exitValue = p.waitFor();
        if (exitValue != 0)
            throw new Exception(errorMessage + " exit value " + exitValue + "  " + sbs);
        return sbs;
    }

    /**
     * Create jar archive out of files list. Names in archive have paths starting from relativeToDir
     *
     * @param tobeJared     list of files
     * @param relativeToDir starting directory for paths
     * @return jar as byte array
     * @throws IOException
     */
    public static byte[] createJarArchiveByteArray(File[] tobeJared, String relativeToDir) throws IOException {
        int BUFFER_SIZE = 10240;
        byte buffer[] = new byte[BUFFER_SIZE];
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        JarOutputStream out = new JarOutputStream(stream, new Manifest());

        for (File t : tobeJared) {
            if (t == null || !t.exists() || t.isDirectory()) {
                if (t != null && !t.isDirectory())
                    logger.error("Can't add to jar {}", t);
                continue;
            }
            // Create jar entry
            String filename = t.getPath().replace(relativeToDir, "").replace("\\", "/");
            //      if (filename.endsWith("MANIFEST.MF")) { // skip to avoid duplicates
            //        continue;
            //      }
            JarEntry jarAdd = new JarEntry(filename);
            jarAdd.setTime(t.lastModified());
            out.putNextEntry(jarAdd);

            // Write file to archive
            FileInputStream in = new FileInputStream(t);
            while (true) {
                int nRead = in.read(buffer, 0, buffer.length);
                if (nRead <= 0)
                    break;
                out.write(buffer, 0, nRead);
            }
            in.close();
        }

        out.close();
        stream.close();
        return stream.toByteArray();
    }

    static File createTempDirectory(String prefix) throws IOException {
        File temp = File.createTempFile(prefix, Long.toString(System.nanoTime()));
        if (!(temp.delete())) {
            throw new IOException("Could not delete temp file: " + temp.getAbsolutePath());
        }
        if (!(temp.mkdir())) {
            throw new IOException("Could not create temp directory: " + temp.getAbsolutePath());
        }
        return temp;
    }

    static void copyExtraFile(File servletPath, String extraPath, File toDir, String fromFileName,
            String toFileName) throws IOException {
        FileUtils.copyFile(new File(servletPath, extraPath + fromFileName), new File(toDir, toFileName));
    }

    /**
     * The Java template file has a placeholder for the model name -- we replace that here
     *
     * @param tmpDir            run in this directory
     * @param javaClassName     model name
     * @param templateFileName  template file
     * @param resultFileName    restult file
     * @throws IOException
     */
    public static void InstantiateJavaTemplateFile(File tmpDir, String modelCode, String javaClassName,
            String replaceTransform, String pythonEnvironment, String templateFileName, String resultFileName)
            throws IOException {
        byte[] templateJava = FileUtils.readFileToByteArray(new File(tmpDir, templateFileName));
        String java = new String(templateJava).replace(JAVA_TEMPLATE_REPLACE_WITH_PREDICTOR_CLASS_NAME,
                javaClassName);
        if (replaceTransform != null)
            java = java.replace(JAVA_TEMPLATE_REPLACE_WITH_TRANSFORMER_OBJECT, replaceTransform);
        if (pythonEnvironment != null)
            java = java.replace(JAVA_TEMPLATE_REPLACE_WITH_PYTHON_ENVIRONMENT_FILE, pythonEnvironment);
        if (modelCode != null)
            java = java.replace(JAVA_TEMPLATE_REPLACE_THIS_WITH_MODEL, modelCode);
        FileUtils.writeStringToFile(new File(tmpDir, resultFileName), java);
    }

}