diff --git a/pom.xml b/pom.xml
index 636812f..fd114c1 100644
--- a/pom.xml
+++ b/pom.xml
@@ -80,6 +80,26 @@
spring-boot-starter-actuator
+
+
+ com.github.docker-java
+ docker-java-core
+ 3.4.1
+
+
+ com.github.docker-java
+ docker-java-transport-httpclient5
+ 3.4.1
+
+
+
+
+ com.clickhouse
+ clickhouse-jdbc
+ 0.7.1
+ all
+
+
org.springframework.boot
diff --git a/src/main/java/net/siegeln/cameleer/saas/config/AsyncConfig.java b/src/main/java/net/siegeln/cameleer/saas/config/AsyncConfig.java
new file mode 100644
index 0000000..4d95aee
--- /dev/null
+++ b/src/main/java/net/siegeln/cameleer/saas/config/AsyncConfig.java
@@ -0,0 +1,31 @@
+package net.siegeln.cameleer.saas.config;
+
+import net.siegeln.cameleer.saas.runtime.RuntimeConfig;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.annotation.EnableAsync;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
+
+import java.util.concurrent.Executor;
+
+@Configuration
+@EnableAsync
+public class AsyncConfig {
+
+ private final RuntimeConfig runtimeConfig;
+
+ public AsyncConfig(RuntimeConfig runtimeConfig) {
+ this.runtimeConfig = runtimeConfig;
+ }
+
+ @Bean(name = "deploymentExecutor")
+ public Executor deploymentExecutor() {
+ var executor = new ThreadPoolTaskExecutor();
+ executor.setCorePoolSize(runtimeConfig.getDeploymentThreadPoolSize());
+ executor.setMaxPoolSize(runtimeConfig.getDeploymentThreadPoolSize());
+ executor.setQueueCapacity(25);
+ executor.setThreadNamePrefix("deploy-");
+ executor.initialize();
+ return executor;
+ }
+}
diff --git a/src/main/java/net/siegeln/cameleer/saas/log/ClickHouseConfig.java b/src/main/java/net/siegeln/cameleer/saas/log/ClickHouseConfig.java
new file mode 100644
index 0000000..78cdaee
--- /dev/null
+++ b/src/main/java/net/siegeln/cameleer/saas/log/ClickHouseConfig.java
@@ -0,0 +1,22 @@
+package net.siegeln.cameleer.saas.log;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import javax.sql.DataSource;
+import com.clickhouse.jdbc.ClickHouseDataSource;
+import java.util.Properties;
+
+@Configuration
+public class ClickHouseConfig {
+
+ @Value("${cameleer.clickhouse.url:jdbc:clickhouse://clickhouse:8123/cameleer}")
+ private String url;
+
+ @Bean(name = "clickHouseDataSource")
+ public DataSource clickHouseDataSource() throws Exception {
+ var properties = new Properties();
+ return new ClickHouseDataSource(url, properties);
+ }
+}
diff --git a/src/main/java/net/siegeln/cameleer/saas/runtime/RuntimeConfig.java b/src/main/java/net/siegeln/cameleer/saas/runtime/RuntimeConfig.java
new file mode 100644
index 0000000..5dbfe0d
--- /dev/null
+++ b/src/main/java/net/siegeln/cameleer/saas/runtime/RuntimeConfig.java
@@ -0,0 +1,63 @@
+package net.siegeln.cameleer.saas.runtime;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+@Component
+public class RuntimeConfig {
+
+ @Value("${cameleer.runtime.max-jar-size:209715200}")
+ private long maxJarSize;
+
+ @Value("${cameleer.runtime.jar-storage-path:/data/jars}")
+ private String jarStoragePath;
+
+ @Value("${cameleer.runtime.base-image:cameleer-runtime-base:latest}")
+ private String baseImage;
+
+ @Value("${cameleer.runtime.docker-network:cameleer}")
+ private String dockerNetwork;
+
+ @Value("${cameleer.runtime.agent-health-port:9464}")
+ private int agentHealthPort;
+
+ @Value("${cameleer.runtime.health-check-timeout:60}")
+ private int healthCheckTimeout;
+
+ @Value("${cameleer.runtime.deployment-thread-pool-size:4}")
+ private int deploymentThreadPoolSize;
+
+ @Value("${cameleer.runtime.container-memory-limit:512m}")
+ private String containerMemoryLimit;
+
+ @Value("${cameleer.runtime.container-cpu-shares:512}")
+ private int containerCpuShares;
+
+ @Value("${cameleer.runtime.bootstrap-token:${CAMELEER_AUTH_TOKEN:}}")
+ private String bootstrapToken;
+
+ @Value("${cameleer.runtime.cameleer3-server-endpoint:http://cameleer3-server:8081}")
+ private String cameleer3ServerEndpoint;
+
+ public long getMaxJarSize() { return maxJarSize; }
+ public String getJarStoragePath() { return jarStoragePath; }
+ public String getBaseImage() { return baseImage; }
+ public String getDockerNetwork() { return dockerNetwork; }
+ public int getAgentHealthPort() { return agentHealthPort; }
+ public int getHealthCheckTimeout() { return healthCheckTimeout; }
+ public int getDeploymentThreadPoolSize() { return deploymentThreadPoolSize; }
+ public String getContainerMemoryLimit() { return containerMemoryLimit; }
+ public int getContainerCpuShares() { return containerCpuShares; }
+ public String getBootstrapToken() { return bootstrapToken; }
+ public String getCameleer3ServerEndpoint() { return cameleer3ServerEndpoint; }
+
+ public long parseMemoryLimitBytes() {
+ var limit = containerMemoryLimit.trim().toLowerCase();
+ if (limit.endsWith("g")) {
+ return Long.parseLong(limit.substring(0, limit.length() - 1)) * 1024 * 1024 * 1024;
+ } else if (limit.endsWith("m")) {
+ return Long.parseLong(limit.substring(0, limit.length() - 1)) * 1024 * 1024;
+ }
+ return Long.parseLong(limit);
+ }
+}
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
index 8de3917..04b48fc 100644
--- a/src/main/resources/application.yml
+++ b/src/main/resources/application.yml
@@ -33,3 +33,17 @@ cameleer:
logto-endpoint: ${LOGTO_ENDPOINT:}
m2m-client-id: ${LOGTO_M2M_CLIENT_ID:}
m2m-client-secret: ${LOGTO_M2M_CLIENT_SECRET:}
+ runtime:
+ max-jar-size: 209715200
+ jar-storage-path: ${CAMELEER_JAR_STORAGE_PATH:/data/jars}
+ base-image: ${CAMELEER_RUNTIME_BASE_IMAGE:cameleer-runtime-base:latest}
+ docker-network: ${CAMELEER_DOCKER_NETWORK:cameleer}
+ agent-health-port: 9464
+ health-check-timeout: 60
+ deployment-thread-pool-size: 4
+ container-memory-limit: ${CAMELEER_CONTAINER_MEMORY_LIMIT:512m}
+ container-cpu-shares: ${CAMELEER_CONTAINER_CPU_SHARES:512}
+ bootstrap-token: ${CAMELEER_AUTH_TOKEN:}
+ cameleer3-server-endpoint: ${CAMELEER3_SERVER_ENDPOINT:http://cameleer3-server:8081}
+ clickhouse:
+ url: ${CLICKHOUSE_URL:jdbc:clickhouse://clickhouse:8123/cameleer}