This repository has been archived by the owner on Dec 15, 2021. It is now read-only.
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
7de2447
commit 78ab79f
Showing
27 changed files
with
580 additions
and
0 deletions.
There are no files selected for viewing
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
FROM openjdk:8-jre-alpine | ||
|
||
CMD ["java", "-cp", "/kubeless/*", "io.kubeless.Handler"] |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
FROM openjdk:8-jdk-alpine | ||
|
||
COPY ./runtime /usr/src/myapp | ||
WORKDIR /usr/src/myapp | ||
ENV GRADLE_HOME /opt/gradle | ||
ENV GRADLE_VERSION 4.8 | ||
|
||
ARG GRADLE_DOWNLOAD_SHA256=f3e29692a8faa94eb0b02ebf36fa263a642b3ae8694ef806c45c345b8683f1ba | ||
RUN set -o errexit -o nounset \ | ||
&& echo "Installing build dependencies" \ | ||
&& apk add --no-cache --virtual .build-deps \ | ||
ca-certificates \ | ||
openssl \ | ||
unzip \ | ||
\ | ||
&& echo "Downloading Gradle" \ | ||
&& wget -O gradle.zip "https://services.gradle.org/distributions/gradle-${GRADLE_VERSION}-bin.zip" \ | ||
\ | ||
&& echo "Checking download hash" \ | ||
&& echo "${GRADLE_DOWNLOAD_SHA256} *gradle.zip" | sha256sum -c - \ | ||
\ | ||
&& echo "Installing Gradle" \ | ||
&& unzip gradle.zip \ | ||
&& rm gradle.zip \ | ||
&& mkdir /opt \ | ||
&& mv "gradle-${GRADLE_VERSION}" "${GRADLE_HOME}/" \ | ||
&& ln -s "${GRADLE_HOME}/bin/gradle" /usr/bin/gradle \ | ||
\ | ||
&& apk del .build-deps \ | ||
&& gradle shadowJar && cp build/libs/runtime-0.1-all.jar /opt \ | ||
&& rm -rf /opt/gradle && rm -rf /usr/src/myapp | ||
|
||
|
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
.PHONY: build-all | ||
init-image: | ||
docker build -f Dockerfile.init -t kubeless/jvm-init:1.8 . | ||
|
||
runtime-image: | ||
docker build -f Dockerfile -t kubeless/jvm:1.8 . | ||
|
||
push-init: | ||
docker push kubeless/jvm-init:1.8 | ||
|
||
push-runtime: | ||
docker push kubeless/jvm:1.8 | ||
|
||
build-all: init-image runtime-image | ||
push-all: push-init push-runtime |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
# Generic Runtime for JVM base languages |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
.gradle | ||
/build/ |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
buildscript { | ||
repositories { | ||
jcenter() | ||
} | ||
dependencies { | ||
classpath 'com.github.jengelman.gradle.plugins:shadow:2.0.4' | ||
} | ||
} | ||
|
||
apply plugin: 'java' | ||
apply plugin: 'com.github.johnrengelman.shadow' | ||
version = '0.1' | ||
jar { | ||
manifest { | ||
attributes 'Implementation-Title': 'JVM-Runtime', | ||
'Implementation-Version': version | ||
} | ||
} | ||
|
||
|
||
repositories { | ||
mavenCentral() | ||
} | ||
|
||
dependencies { | ||
compile group: 'io.prometheus', name: 'simpleclient', version: '0.3.0' | ||
compile group: 'io.prometheus', name: 'simpleclient_hotspot', version: '0.3.0' | ||
compile group: 'io.prometheus', name: 'simpleclient_httpserver', version: '0.3.0' | ||
compile group: 'io.prometheus', name: 'simpleclient_pushgateway', version: '0.3.0' | ||
compile group: 'log4j', name: 'log4j', version: '1.2.17' | ||
|
||
testCompile group: 'junit', name: 'junit', version: '4.+' | ||
} |
34 changes: 34 additions & 0 deletions
34
docker/runtime/jvm/runtime/src/main/java/io/kubeless/Context.java
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
/* | ||
Copyright (c) 2016-2017 Bitnami | ||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
|
||
package io.kubeless; | ||
|
||
/** | ||
* Context includes information about the function environment | ||
*/ | ||
public class Context { | ||
String functionName; | ||
String timeout; | ||
String runtime; | ||
String memoryLimit; | ||
|
||
public Context(String functionName, String timeout, String runtime, String memoryLimit) { | ||
this.functionName = functionName; | ||
this.timeout = timeout; | ||
this.runtime = runtime; | ||
this.memoryLimit = memoryLimit; | ||
} | ||
} |
36 changes: 36 additions & 0 deletions
36
docker/runtime/jvm/runtime/src/main/java/io/kubeless/Event.java
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
/* | ||
Copyright (c) 2016-2017 Bitnami | ||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
|
||
package io.kubeless; | ||
|
||
/** | ||
* Event includes information about the event source | ||
*/ | ||
public class Event { | ||
String Data; | ||
String EventID; | ||
String EventType; | ||
String EventTime; | ||
String EventNamespace; | ||
|
||
public Event(String data, String eventId, String eventType, String eventTime, String eventNamespace) { | ||
this.Data = data; | ||
this.EventID = eventId; | ||
this.EventType = eventType; | ||
this.EventTime = eventTime; | ||
this.EventNamespace = eventNamespace; | ||
} | ||
} |
182 changes: 182 additions & 0 deletions
182
docker/runtime/jvm/runtime/src/main/java/io/kubeless/Handler.java
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,182 @@ | ||
/* | ||
Copyright (c) 2016-2017 Bitnami | ||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
package io.kubeless; | ||
|
||
import com.sun.net.httpserver.HttpExchange; | ||
import com.sun.net.httpserver.HttpHandler; | ||
import com.sun.net.httpserver.HttpServer; | ||
import com.sun.net.httpserver.Headers; | ||
|
||
import java.io.IOException; | ||
import java.io.OutputStream; | ||
import java.io.InputStreamReader; | ||
import java.io.BufferedReader; | ||
import java.lang.reflect.Method; | ||
import java.lang.reflect.InvocationTargetException; | ||
import java.net.InetSocketAddress; | ||
import java.nio.charset.StandardCharsets; | ||
import java.util.List; | ||
import java.util.stream.Collectors; | ||
import io.prometheus.client.Counter; | ||
import io.prometheus.client.Histogram; | ||
import io.kubeless.Event; | ||
import io.kubeless.Context; | ||
import org.apache.log4j.Logger; | ||
import org.apache.log4j.BasicConfigurator; | ||
|
||
public class Handler { | ||
|
||
static String className = System.getenv("MOD_NAME").replaceAll("_","."); | ||
static String methodName = System.getenv("FUNC_HANDLER"); | ||
static String timeout = System.getenv("FUNC_TIMEOUT"); | ||
static String runtime = System.getenv("FUNC_RUNTIME"); | ||
static String memoryLimit = System.getenv("FUNC_MEMORY_LIMIT"); | ||
static Method method; | ||
static Object obj; | ||
static Logger logger = Logger.getLogger(Handler.class.getName()); | ||
|
||
static final Counter requests = Counter.build().name("function_calls_total").help("Total function calls.").register(); | ||
static final Counter failures = Counter.build().name("function_failures_total").help("Total function call failuress.").register(); | ||
static final Histogram requestLatency = Histogram.build().name("function_duration_seconds").help("Duration of time user function ran in seconds.").register(); | ||
|
||
public static void main(String[] args) { | ||
logger.info("Start Function Handler: "); | ||
logger.info("className:"+className); | ||
logger.info("methodName:"+methodName); | ||
logger.info("timeout:"+timeout); | ||
logger.info("memoryLimit:"+memoryLimit); | ||
|
||
|
||
|
||
BasicConfigurator.configure(); | ||
|
||
String funcPort = System.getenv("FUNC_PORT"); | ||
if(funcPort == null || funcPort.isEmpty()) { | ||
funcPort = "8080"; | ||
} | ||
int port = Integer.parseInt(funcPort); | ||
try { | ||
HttpServer server = HttpServer.create(new InetSocketAddress(port), 0); | ||
server.createContext("/", new FunctionHandler()); | ||
server.createContext("/healthz", new HealthHandler()); | ||
server.setExecutor(java.util.concurrent.Executors.newFixedThreadPool(50)); | ||
server.start(); | ||
|
||
Class<?> c = Class.forName(className); | ||
obj = c.newInstance(); | ||
method = c.getMethod(methodName, io.kubeless.Event.class, io.kubeless.Context.class); | ||
} catch (Exception e) { | ||
failures.inc(); | ||
if (e instanceof ClassNotFoundException) { | ||
logger.error("Class: " + className + " not found"); | ||
} else if (e instanceof NoSuchMethodException) { | ||
logger.error("Method: " + methodName + " not found"); | ||
} else if (e instanceof java.io.IOException) { | ||
logger.error("Failed to starting listener."); | ||
} else { | ||
logger.error("An exception occured running Class: " + className + " method: " + methodName); | ||
e.printStackTrace(); | ||
} | ||
} | ||
} | ||
|
||
static class FunctionHandler implements HttpHandler { | ||
|
||
@Override | ||
public void handle(HttpExchange he) throws IOException { | ||
Histogram.Timer requestTimer = requestLatency.startTimer(); | ||
try { | ||
requests.inc(); | ||
|
||
InputStreamReader reader = new InputStreamReader(he.getRequestBody(), StandardCharsets.UTF_8.name()); | ||
BufferedReader br = new BufferedReader(reader); | ||
String requestBody = br.lines().collect(Collectors.joining()); | ||
br.close(); | ||
reader.close(); | ||
|
||
Headers headers = he.getRequestHeaders(); | ||
String eventId = getEventId(headers); | ||
String eventType = getEventType(headers); | ||
String eventTime = getEventTime(headers); | ||
String eventNamespace = getEventNamespace(headers); | ||
|
||
Event event = new Event(requestBody, eventId, eventType, eventTime, eventNamespace); | ||
Context context = new Context(methodName, timeout, runtime, memoryLimit); | ||
|
||
Object returnValue = Handler.method.invoke(Handler.obj, event, context); | ||
String response = (String)returnValue; | ||
logger.info("Response: " + response); | ||
he.sendResponseHeaders(200, response.length()); | ||
OutputStream os = he.getResponseBody(); | ||
os.write(response.getBytes()); | ||
os.close(); | ||
} catch (Exception e) { | ||
failures.inc(); | ||
if (e instanceof ClassNotFoundException) { | ||
logger.error("Class: " + className + " not found"); | ||
} else if (e instanceof NoSuchMethodException) { | ||
logger.error("Method: " + methodName + " not found"); | ||
} else if (e instanceof InvocationTargetException) { | ||
logger.error("Failed to Invoke Method: " + methodName); | ||
} else if (e instanceof InstantiationException) { | ||
logger.error("Failed to instantiate method: " + methodName); | ||
} else { | ||
logger.error("An exception occured running Class: " + className + " method: " + methodName); | ||
e.printStackTrace(); | ||
} | ||
} finally { | ||
requestTimer.observeDuration(); | ||
} | ||
} | ||
|
||
private String getEventType(Headers headers) { | ||
return getByName(headers,"event-type"); | ||
} | ||
|
||
private String getEventTime(Headers headers) { | ||
return getByName(headers,"event-time"); | ||
} | ||
|
||
private String getEventNamespace(Headers headers) { | ||
return getByName(headers,"event-namespace"); | ||
} | ||
|
||
private String getEventId(Headers headers) { | ||
return getByName(headers,"event-id"); | ||
} | ||
|
||
private String getByName(Headers headers, String name) { | ||
if (headers.containsKey(name)) { | ||
List<String> values = headers.get(name); | ||
if (values != null) { | ||
return values.get(0); | ||
} | ||
} | ||
return ""; | ||
} | ||
} | ||
|
||
static class HealthHandler implements HttpHandler { | ||
@Override | ||
public void handle(HttpExchange t) throws IOException { | ||
String response = "OK"; | ||
t.sendResponseHeaders(200, response.length()); | ||
OutputStream os = t.getResponseBody(); | ||
os.write(response.getBytes()); | ||
os.close(); | ||
} | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
# Root logger option | ||
log4j.rootLogger=INFO, stdout | ||
|
||
# Redirect log messages to console | ||
log4j.appender.stdout=org.apache.log4j.ConsoleAppender | ||
log4j.appender.stdout.Target=System.out | ||
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout | ||
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n |
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# Java on runtime JVM | ||
|
||
`gradle shadowJar` Build the jar with all deps | ||
|
||
`kubeless function deploy test --runtime jvm1.8 --from-file build/libs/jvm-test-0.1-all.jar --handler io_ino_Handler.sayHello` The package name use `_` instead of `.` for the path. |
Oops, something went wrong.