Created
June 11, 2018 05:14
-
-
Save mustafaakin/71e4494508311f7764e59b16e9dd3b8e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"log" | |
"encoding/json" | |
"github.com/pkg/errors" | |
"github.com/aws/aws-lambda-go/lambda" | |
) | |
/* | |
#cgo CFLAGS: -I/usr/lib/jvm/java-8-openjdk-amd64/include | |
#cgo CFLAGS: -I/usr/lib/jvm/java-8-openjdk-amd64/include/linux | |
#include <jni.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
static const char* convert_to_cstring(JNIEnv *env, jstring javaString) | |
{ | |
return (*env)->GetStringUTFChars(env, javaString, 0); | |
} | |
static jstring convert_to_jstring(JNIEnv *env, char* buf) | |
{ | |
return (*env)->NewStringUTF(env, buf); | |
} | |
*/ | |
import "C" | |
var ( | |
javaResponse = make(chan string) | |
goRequest = make(chan string) | |
) | |
func communicateJava(input interface{}) (interface{}, error) { | |
inBytes, err := json.Marshal(input) | |
if err != nil { | |
return nil, err | |
} | |
inputStr := string(inBytes) | |
// Write to Go | |
log.Println("Recevied request") | |
goRequest <- inputStr | |
// Read from Java | |
respStr := <-javaResponse | |
var resp interface{} | |
err = json.Unmarshal([]byte(respStr), &resp) | |
if err != nil { | |
return nil, errors.WithStack(err) | |
} | |
return resp, nil | |
} | |
//export Java_Test_start | |
func Java_Test_start(env *C.JNIEnv, clazz C.jclass) { | |
log.SetPrefix("GO - ") | |
go func() { | |
lambda.Start(communicateJava) | |
}() | |
} | |
//export Java_Test_writeResponse | |
func Java_Test_writeResponse(env *C.JNIEnv, clazz C.jclass, input C.jstring) { | |
a := C.convert_to_cstring(env, input) | |
b := C.GoString(a) | |
javaResponse <- b | |
} | |
//export Java_Test_readRequest | |
func Java_Test_readRequest(env *C.JNIEnv, clazz C.jclass) C.jstring { | |
input := <-goRequest | |
cstr := C.CString(input) | |
cjstring := C.convert_to_jstring(env, cstr) | |
return cjstring | |
} | |
func main() {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import org.apache.commons.lang3.time.StopWatch; | |
import org.apache.commons.math3.ml.clustering.CentroidCluster; | |
import org.apache.commons.math3.ml.clustering.Clusterable; | |
import org.apache.commons.math3.ml.clustering.DoublePoint; | |
import org.apache.commons.math3.ml.clustering.KMeansPlusPlusClusterer; | |
import org.apache.commons.math3.random.*; | |
import java.util.ArrayList; | |
import java.util.List; | |
import java.util.Random; | |
import java.util.stream.Collectors; | |
public class KMeans { | |
private int N = 100_000; // Number of points | |
private int K = 10; // Cluster centroids | |
private int seed = 5; // Seed for exact performance | |
private int D = 3; // Dimensions | |
public KMeansResult calculate() { | |
KMeansResult result = new KMeansResult(); | |
StopWatch s = new StopWatch(); | |
s.start(); | |
// Initialize random generators and clusterer | |
Random random = new Random(seed); | |
RandomGenerator randomGenerator = RandomGeneratorFactory.createRandomGenerator(random); | |
RandomVectorGenerator generator = new UncorrelatedRandomVectorGenerator(D, new UniformRandomGenerator(randomGenerator)); | |
KMeansPlusPlusClusterer<DoublePoint> kmeans = new KMeansPlusPlusClusterer<>(K); | |
kmeans.getRandomGenerator().setSeed(seed); | |
// Generate numbers | |
List<DoublePoint> pointList = new ArrayList<>(); | |
for (int i = 0; i < N; i++) { | |
double[] doubles = generator.nextVector(); | |
DoublePoint doublePoint = new DoublePoint(doubles); | |
pointList.add(doublePoint); | |
} | |
s.stop(); | |
result.setGenerationMs(s.getTime()); | |
s.reset(); | |
// Do the actual clustering | |
s.start(); | |
List<CentroidCluster<DoublePoint>> centers = kmeans.cluster(pointList); | |
List<Clusterable> collect = centers | |
.stream() | |
.map(CentroidCluster::getCenter) | |
.collect(Collectors.toList()); | |
s.stop(); | |
return result | |
.setTookMs(s.getTime()) | |
.setCenters(collect); | |
} | |
public int getN() { | |
return N; | |
} | |
public KMeans setN(int n) { | |
N = n; | |
return this; | |
} | |
public int getK() { | |
return K; | |
} | |
public KMeans setK(int k) { | |
K = k; | |
return this; | |
} | |
public int getSeed() { | |
return seed; | |
} | |
public KMeans setSeed(int seed) { | |
this.seed = seed; | |
return this; | |
} | |
public int getD() { | |
return D; | |
} | |
public KMeans setD(int d) { | |
D = d; | |
return this; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import org.apache.commons.math3.ml.clustering.Clusterable; | |
import java.util.List; | |
class KMeansResult { | |
private List<Clusterable> centers; | |
private long tookMs; | |
private long generationMs; | |
public List<Clusterable> getCenters() { | |
return centers; | |
} | |
public KMeansResult setCenters(List<Clusterable> centers) { | |
this.centers = centers; | |
return this; | |
} | |
public long getTookMs() { | |
return tookMs; | |
} | |
public KMeansResult setTookMs(long tookMs) { | |
this.tookMs = tookMs; | |
return this; | |
} | |
public long getGenerationMs() { | |
return generationMs; | |
} | |
public KMeansResult setGenerationMs(long generationMs) { | |
this.generationMs = generationMs; | |
return this; | |
} | |
@Override | |
public String toString() { | |
return "MyKMeansResult{" + | |
"centers=" + centers + | |
", tookMs=" + tookMs + | |
", generationMs=" + generationMs + | |
'}'; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import org.apache.log4j.Logger; | |
import org.json.JSONObject; | |
import org.json.JSONTokener; | |
import java.util.Date; | |
public class MyEntrypointJava { | |
private final static Logger logger = Logger.getLogger(Test.class); | |
public static native void start(); | |
public static native void writeResponse(String input); | |
public static native String readRequest(); | |
public static void main(String[] args) { | |
logger.info("Starting"); | |
System.loadLibrary("Hello"); | |
logger.info("Loaded Hello Golang lib, invoking Go for listening on Lambda Handler"); | |
// Start lambda handler | |
start(); | |
while (true) { | |
String request = readRequest(); | |
logger.info("Java Received Request: " + request); | |
JSONTokener tokener = new JSONTokener(request); | |
JSONObject requestJSON = new JSONObject(tokener); | |
// After parsing the input, do the actual calculation | |
KMeans kMeans = new KMeans() | |
.setK(requestJSON.getInt("k")) | |
.setD(requestJSON.getInt("d")) | |
.setN(requestJSON.getInt("n")) | |
.setSeed(requestJSON.getInt("seed")); | |
logger.info("Calculating in Java"); | |
KMeansResult myKMeansResult = kMeans.calculate(); | |
// Prepare a response JSON Object for response | |
JSONObject responseJSON = new JSONObject() | |
.put("centers", myKMeansResult.getCenters()) | |
.put("input-gen-duration", myKMeansResult.getGenerationMs()) | |
.put("duration", myKMeansResult.getTookMs()) | |
.put("date", new Date()); | |
String response = responseJSON.toString(); | |
writeResponse(response); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
<project xmlns="http://maven.apache.org/POM/4.0.0" | |
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | |
<modelVersion>4.0.0</modelVersion> | |
<groupId>mustafa</groupId> | |
<artifactId>graalvm-java-go-awslambda</artifactId> | |
<version>1.0-SNAPSHOT</version> | |
<properties> | |
<maven.compiler.target>1.8</maven.compiler.target> | |
<maven.compiler.source>1.8</maven.compiler.source> | |
</properties> | |
<dependencies> | |
<dependency> | |
<groupId>org.json</groupId> | |
<artifactId>json</artifactId> | |
<version>20180130</version> | |
</dependency> | |
<dependency> | |
<groupId>org.apache.commons</groupId> | |
<artifactId>commons-math3</artifactId> | |
<version>3.6.1</version> | |
</dependency> | |
<dependency> | |
<groupId>org.apache.commons</groupId> | |
<artifactId>commons-lang3</artifactId> | |
<version>3.7</version> | |
</dependency> | |
<dependency> | |
<groupId>log4j</groupId> | |
<artifactId>log4j</artifactId> | |
<version>1.2.17</version> | |
</dependency> | |
<dependency> | |
<groupId>com.amazonaws</groupId> | |
<artifactId>aws-lambda-java-core</artifactId> | |
<version>1.1.0</version> | |
</dependency> | |
</dependencies> | |
<build> | |
<plugins> | |
<plugin> | |
<groupId>org.apache.maven.plugins</groupId> | |
<artifactId>maven-shade-plugin</artifactId> | |
<version>2.4.3</version> | |
<executions> | |
<!-- Run shade goal on package phase --> | |
<execution> | |
<phase>package</phase> | |
<goals> | |
<goal>shade</goal> | |
</goals> | |
</execution> | |
</executions> | |
</plugin> | |
</plugins> | |
</build> | |
</project> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment