Skip to content
This repository has been archived by the owner on Apr 7, 2019. It is now read-only.

Commit

Permalink
Merge branch 'develop' of https://github.com/h2oai/steam into deepwater
Browse files Browse the repository at this point in the history
  • Loading branch information
mstensmo committed Oct 20, 2016
2 parents 50ed1a7 + e3712d7 commit e548875
Show file tree
Hide file tree
Showing 13 changed files with 234 additions and 4 deletions.
17 changes: 17 additions & 0 deletions prediction-service-builder/examples/deepwater/example.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/usr/bin/env bash

rm -f example.war

curl -X POST \
--form [email protected] \
--form [email protected] \
localhost:55000/makewar > example.war

if [ -s example.war ]
then
echo "Created example.war"
echo "Run with run-example.sh"
else
echo "Failed to build example.war"
exit 1
fi
1 change: 1 addition & 0 deletions prediction-service-builder/examples/deepwater/run-debug.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
java -Dorg.slf4j.simpleLogger.defaultLogLevel=DEBUG -jar ../jetty-runner-8.1.14.v20131031.jar --port 55001 example.war
7 changes: 7 additions & 0 deletions prediction-service-builder/examples/deepwater/run-example.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/usr/bin/env bash

echo "Starting prediction service on port 55001"
echo ""

java -jar ../jetty-runner-8.1.14.v20131031.jar --port 55001 example.war

26 changes: 26 additions & 0 deletions prediction-service-builder/examples/deepwater/test-example.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#!/usr/bin/env bash


curl -X POST \
--form [email protected] \
--form abc=def \
--form data='{Dest: SFO, Orig: JFK}' \
http://localhost:55001/predictbinary

echo "test1 bird"

curl -X POST \
--form [email protected] \
http://localhost:55001/predictbinary

echo "test2 dog"

curl -X POST \
--form [email protected] \
http://localhost:55001/predictbinary

echo "url of dog"

#curl -X POST \
#--form C1="https://c1.staticflickr.com/1/225/515776742_bce2e6dbea_d.jpg" \
#http://localhost:55001/predictbinary
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ else if (!rawfiles.isEmpty()) {
InstantiateJavaTemplateFile(tmpDir, modelCode, predictorClassName, replaceTransform, srcPath + "ServletUtil-TEMPLATE.java", "ServletUtil.java");

copyExtraFile(servletPath, srcPath, tmpDir, "PredictServlet.java", "PredictServlet.java");
copyExtraFile(servletPath, srcPath, tmpDir, "PredictBinaryServlet.java", "PredictBinaryServlet.java");
copyExtraFile(servletPath, srcPath, tmpDir, "InfoServlet.java", "InfoServlet.java");
copyExtraFile(servletPath, srcPath, tmpDir, "StatsServlet.java", "StatsServlet.java");
copyExtraFile(servletPath, srcPath, tmpDir, "PingServlet.java", "PingServlet.java");
Expand All @@ -195,7 +196,8 @@ else if (!rawfiles.isEmpty()) {
// compile extra
List<String> cmd = Arrays.asList("javac", "-target", JAVA_TARGET_VERSION, "-source", JAVA_TARGET_VERSION, "-J-Xmx" + MEMORY_FOR_JAVA_PROCESSES,
"-cp", "WEB-INF/lib/*:WEB-INF/classes:extra/WEB-INF/lib/*", "-d", outDir.getPath(),
"PredictServlet.java", "InfoServlet.java", "StatsServlet.java", "ServletUtil.java", "PingServlet.java", "Transform.java", "Logging.java");
"PredictServlet.java", "PredictBinaryServlet.java", "InfoServlet.java", "StatsServlet.java", "ServletUtil.java",
"PingServlet.java", "Transform.java", "Logging.java");
runCmd(tmpDir, cmd, "Compilation of extra failed");

// create the war jar file
Expand Down
20 changes: 17 additions & 3 deletions prediction-service-builder/src/main/webapp/extra/H2OPredictor.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import hex.genmodel.easy.prediction.AbstractPrediction;
import hex.genmodel.easy.EasyPredictModelWrapper;
import hex.genmodel.easy.RowData;
import hex.genmodel.MojoModel;

import java.io.File;
import java.io.FileNotFoundException;
Expand Down Expand Up @@ -51,12 +52,18 @@ private GenModel loadClassFromJar(String jarFileName, String modelName) throws E
}
}

private void load(String jarFileName, String modelName)
private void loadPojo(String jarFileName, String modelName)
throws Exception {
GenModel rawModel = loadClassFromJar(jarFileName, modelName);
model = new EasyPredictModelWrapper(rawModel);
}

private void loadMojo(String zipFileName)
throws Exception {
GenModel rawModel = MojoModel.load(zipFileName);
model = new EasyPredictModelWrapper(rawModel);
}

private RowData jsonToRowData(String json) {
try {
return gson.fromJson(json, RowData.class);
Expand All @@ -77,10 +84,17 @@ private String predict2(RowData row) throws PredictException {
return gson.toJson(pr);
}

public static String predict(String jarFileName, String modelName, String jsonArgs) {
public static String predict(String ojoFileName, String modelName, String jsonArgs) {
try {
H2OPredictor p = new H2OPredictor();
p.load(jarFileName, modelName);
if (ojoFileName == null)
throw new Exception("file name can't be null");
else if (ojoFileName.endsWith(".jar"))
p.loadPojo(ojoFileName, modelName);
else if (ojoFileName.endsWith(".zip"))
p.loadMojo(ojoFileName);
else
throw new Exception("unknown model archive type");
return p.predict2(p.jsonToRowData(jsonArgs));
}
catch (Exception e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
<servlet-name>Predict</servlet-name>
<servlet-class>PredictServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>PredictBinary</servlet-name>
<servlet-class>PredictBinaryServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>Info</servlet-name>
<servlet-class>InfoServlet</servlet-class>
Expand All @@ -24,6 +28,10 @@ http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
<servlet-name>Predict</servlet-name>
<url-pattern>/predict/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>PredictBinary</servlet-name>
<url-pattern>/predictbinary</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Info</servlet-name>
<url-pattern>/info/*</url-pattern>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ public void init(ServletConfig servletConfig) throws ServletException {
}

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setHeader("Access-Control-Allow-Origin", "*");
try {
String pathInfo = request.getPathInfo();
logger.debug("pathInfo {}", pathInfo);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import hex.genmodel.*;
import hex.genmodel.easy.*;
import hex.genmodel.easy.prediction.AbstractPrediction;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.InputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.List;

public class PredictBinaryServlet extends HttpServlet {
private final Logger logger = Logging.getLogger(this.getClass());

private static final Gson gson = new GsonBuilder().serializeSpecialFloatingPointValues().create();

private static GenModel rawModel = null;
private static EasyPredictModelWrapper model = null;
private static Transform transform = ServletUtil.transform;

private File servletPath = null;

public void init(ServletConfig servletConfig) throws ServletException {
super.init(servletConfig);
try {
servletPath = new File(servletConfig.getServletContext().getResource("/").getPath());
logger.debug("servletPath {}", servletPath);
ServletUtil.loadModels(servletPath);
model = ServletUtil.model;
logger.debug("model {}", model);
}
catch (MalformedURLException e) {
logger.error("init failed", e);
}
}

public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setHeader("Access-Control-Allow-Origin", "*");
long start = System.nanoTime();
File tmpDir = null;
try {
if (model == null)
throw new Exception("No predictor model");

// fill row with parameters, some of which are binary, like images
RowData row = new RowData();
List<FileItem> items = new ServletFileUpload(new DiskFileItemFactory()).parseRequest(request);
for (FileItem i : items) {
String field = i.getFieldName();
String value = i.getString();
if (field.startsWith("binary_")) {
String binFieldName = field.substring("binary_".length());
if (binFieldName == null || binFieldName.length() == 0)
throw new Exception("empty binary field name for " + field);
InputStream inputStream = i.getInputStream();
if (inputStream == null)
throw new Exception("null input stream for " + field);
byte[] bindata = IOUtils.toByteArray(inputStream);
if (bindata.length == 0)
throw new Exception("empty binary field value for " + field);
logger.debug("binary field {} size {}", binFieldName, bindata.length);
row.put(binFieldName, bindata);
}
else if (field.equals("data")) {
RowData r = gson.fromJson(value, ServletUtil.ROW_DATA_TYPE);
logger.debug("data {}", r);
row.putAll(r);
}
else {
logger.debug("text field {} value {}", field, value);
row.put(field, value);
}
}
// now have parameters in row
logger.debug("row size {} keys {}", row.size(), row.keySet());

AbstractPrediction pr;
String prJson;

if (transform == null) { // no jar transformation
logger.debug("no transformation of input data");
}
else {
logger.debug("transformation of input data");
}

if (row != null) {
// do the prediction
pr = ServletUtil.predict(row);

// assemble json result
prJson = gson.toJson(pr);
logger.debug(prJson);

// Emit the prediction to the servlet response.
response.getWriter().write(prJson);
}

response.setStatus(HttpServletResponse.SC_OK);
}
catch (Exception e) {
// Prediction failed.
logger.error("post failed", e);
response.sendError(HttpServletResponse.SC_NOT_ACCEPTABLE, e.getMessage());
}
finally {
// if the temp directory is still there we delete it
if (tmpDir != null && tmpDir.exists()) {
try {
FileUtils.deleteDirectory(tmpDir);
}
catch (IOException e) {
logger.error("Can't delete tmp directory");
}
}
}
long done = System.nanoTime();
ServletUtil.postTimes.add(start, done);
logger.debug("Post time {}", ServletUtil.postTimes);
}

}

Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ public class StatsServlet extends HttpServlet {
public static final Gson gson = new GsonBuilder().serializeSpecialFloatingPointValues().create();

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setHeader("Access-Control-Allow-Origin", "*");
try {
final long now = System.currentTimeMillis();
final long upTimeMs = now - ServletUtil.startTime;
Expand Down
10 changes: 10 additions & 0 deletions scoring-service-builder/examples/image-classifier/test-example.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/usr/bin/env bash

curl -X POST \
--form [email protected] \
--form abc=def \
--form data='{Dest: SFO, Orig: JFK}' \
http://localhost:55001/predictbinary



1 change: 1 addition & 0 deletions scoring-service-builder/examples/run-debug.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
java -Dorg.slf4j.simpleLogger.defaultLogLevel=DEBUG -jar ../jetty-runner-8.1.14.v20131031.jar --port 55001 example.war
7 changes: 7 additions & 0 deletions scoring-service-builder/examples/run-example.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/usr/bin/env bash

echo "Starting prediction service on port 55001"
echo ""

java -jar ../jetty-runner-8.1.14.v20131031.jar --port 55001 example.war

0 comments on commit e548875

Please sign in to comment.