Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.akto.hybrid_runtime;

import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.akto.dto.deployment.DeploymentConfig;
import com.akto.dto.deployment.EnvVariable;

public final class EnvConfig {

private static final Map<String, String> envMap = new HashMap<>();

private EnvConfig() {}

public static void hydrate(DeploymentConfig deploymentConfig) {
envMap.clear();
if (deploymentConfig == null) return;
List<EnvVariable> vars = deploymentConfig.getEnvVars();
if (vars == null) return;
for (EnvVariable v : vars) {
if (v == null || v.getKey() == null) continue;
envMap.put(v.getKey(), v.getValue());
}
}

public static String get(String key, String defaultValue) {
String v = envMap.get(key);
if (v != null) return v;
String sys = System.getenv(key);
return sys != null ? sys : defaultValue;
}

public static Map<String, String> snapshot() {
return Collections.unmodifiableMap(envMap);
}
Comment on lines +35 to +37
Copy link

Copilot AI Sep 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The envMap is not thread-safe and could cause race conditions when accessed concurrently with hydrate() method. Consider using ConcurrentHashMap or adding synchronization.

Copilot uses AI. Check for mistakes.
}
18 changes: 18 additions & 0 deletions apps/mini-runtime/src/main/java/com/akto/hybrid_runtime/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,23 @@ private static void printL(Object o) {

static boolean isDashboardInstance = false;

private static void initEnvConfig() {
try {
String deploymentId = System.getenv("DEPLOYMENT_ID");
if (deploymentId == null || deploymentId.isEmpty()) return;
com.akto.dto.deployment.DeploymentConfig dc = dataActor.fetchDeploymentConfig(deploymentId);
EnvConfig.hydrate(dc);
try {
Map<String, String> snapshot = EnvConfig.snapshot();
dataActor.sendDeploymentConfig(deploymentId, snapshot);
} catch (Exception e) {
loggerMaker.errorAndAddToDb(e, "Failed to send deployment config after hydrate");
}
} catch (Exception e) {
loggerMaker.errorAndAddToDb(e, "initEnvConfig failed: " + e.getMessage());
}
}

public static boolean tryForCollectionName(String message) {
boolean ret = false;
try {
Expand Down Expand Up @@ -253,6 +270,7 @@ public static String getLogTopicName() {

// REFERENCE: https://www.oreilly.com/library/view/kafka-the-definitive/9781491936153/ch04.html (But how do we Exit?)
public static void main(String[] args) {
Copy link

Copilot AI Sep 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

initEnvConfig() is called before dataActor initialization. The dataActor variable is used inside initEnvConfig() but may not be initialized at this point in the main method.

Suggested change
public static void main(String[] args) {
public static void main(String[] args) {
// Initialize dataActor before calling initEnvConfig
dataActor = DataActorFactory.createDataActor();

Copilot uses AI. Check for mistakes.
initEnvConfig();
//String mongoURI = System.getenv("AKTO_MONGO_CONN");;
String configName = System.getenv("AKTO_CONFIG_NAME");
String topicName = getTopicName();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.akto.dto.deployment;

import org.bson.codecs.pojo.annotations.BsonId;
import com.akto.dao.context.Context;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import java.util.List;

@Getter
@Setter
@NoArgsConstructor
public class DeploymentConfig {

@BsonId
private String id;
private String name;
private String type;
private List<EnvVariable> envVars;
private int createdTs;
private int lastUpdatedTs;

public static final String ID = "_id";
public static final String NAME = "name";
public static final String TYPE = "type";
public static final String ENV_VARS = "envVars";
public static final String CREATED_TS = "createdTs";
public static final String LAST_UPDATED_TS = "lastUpdatedTs";

public DeploymentConfig(String id, String name, String type, List<EnvVariable> envVars) {
this.id = id;
this.name = name;
this.type = type;
this.envVars = envVars;
this.createdTs = Context.now();
this.lastUpdatedTs = Context.now();
}
}
16 changes: 16 additions & 0 deletions libs/dao/src/main/java/com/akto/dto/deployment/EnvVariable.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.akto.dto.deployment;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class EnvVariable {
private String key;
private String value;
private boolean editable;
}
38 changes: 38 additions & 0 deletions libs/utils/src/main/java/com/akto/data_actor/ClientActor.java
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,44 @@ public static String buildDbAbstractorUrl() {
return dbAbsHost + "/api";
}

@Override
public DeploymentConfig fetchDeploymentConfig(String deploymentId) {
Map<String, List<String>> headers = buildHeaders();
String endpoint = url + "/fetchDeploymentConfig?deploymentId=" + deploymentId;
Copy link

Copilot AI Sep 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

URL parameter concatenation without encoding could lead to injection issues. Use URL encoding for the deploymentId parameter.

Copilot uses AI. Check for mistakes.
OriginalHttpRequest request = new OriginalHttpRequest(endpoint, "", "GET", null, headers, "");
try {
OriginalHttpResponse response = ApiExecutor.sendRequestBackOff(request, true, null, false, null);
if (response.getStatusCode() != 200 || response.getBody() == null) {
loggerMaker.errorAndAddToDb("non 2xx in fetchDeploymentConfig", LoggerMaker.LogDb.RUNTIME);
return null;
}
BasicDBObject payloadObj = BasicDBObject.parse(response.getBody());
BasicDBObject dcObj = (BasicDBObject) payloadObj.get("deploymentConfig");
if (dcObj == null) return null;
return objectMapper.readValue(dcObj.toJson(), DeploymentConfig.class);
} catch (Exception e) {
loggerMaker.errorAndAddToDb("error in fetchDeploymentConfig " + e, LoggerMaker.LogDb.RUNTIME);
return null;
}
}

@Override
public void sendDeploymentConfig(String deploymentId, Map<String, String> envVars) {
Map<String, List<String>> headers = buildHeaders();
BasicDBObject obj = new BasicDBObject();
obj.put("deploymentId", deploymentId);
obj.put("envVars", envVars);
OriginalHttpRequest request = new OriginalHttpRequest(url + "/sendDeploymentConfig", "", "POST", obj.toString(), headers, "");
try {
OriginalHttpResponse response = ApiExecutor.sendRequestBackOff(request, true, null, false, null);
if (response.getStatusCode() != 200) {
loggerMaker.errorAndAddToDb("non 2xx in sendDeploymentConfig", LoggerMaker.LogDb.RUNTIME);
}
} catch (Exception e) {
loggerMaker.errorAndAddToDb("error in sendDeploymentConfig " + e, LoggerMaker.LogDb.RUNTIME);
}
}

public AccountSettings fetchAccountSettings() {
AccountSettings acc = null;
for (int i=0; i < 5; i++) {
Expand Down
6 changes: 6 additions & 0 deletions libs/utils/src/main/java/com/akto/data_actor/DataActor.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.akto.dto.billing.Organization;
import com.akto.dto.billing.Tokens;
import com.akto.dto.dependency_flow.Node;
import com.akto.dto.deployment.DeploymentConfig;
import com.akto.dto.filter.MergedUrls;
import com.akto.dto.jobs.JobExecutorType;
import com.akto.dto.jobs.JobParams;
Expand Down Expand Up @@ -313,4 +314,9 @@ public abstract class DataActor {
public abstract void updateMcpReconRequestStatus(String requestId, String status, int serversFound);

public abstract void storeMcpReconResultsBatch(List<McpReconResult> serverDataList);

// Deployment configuration
public abstract DeploymentConfig fetchDeploymentConfig(String deploymentId);

public abstract void sendDeploymentConfig(String deploymentId, Map<String, String> envVars);
}