storage(deploy): persist deployed_config_snapshot as JSONB
Wire SELECT_COLS, mapRow deserialization, and saveDeployedConfigSnapshot update method. Adds PostgresDeploymentRepositoryIT with roundtrip, null-default, and clear-to-null tests. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package com.cameleer.server.app.storage;
|
||||
|
||||
import com.cameleer.server.core.runtime.Deployment;
|
||||
import com.cameleer.server.core.runtime.DeploymentConfigSnapshot;
|
||||
import com.cameleer.server.core.runtime.DeploymentRepository;
|
||||
import com.cameleer.server.core.runtime.DeploymentStatus;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
@@ -21,7 +22,7 @@ public class PostgresDeploymentRepository implements DeploymentRepository {
|
||||
private static final String SELECT_COLS =
|
||||
"id, app_id, app_version_id, environment_id, status, target_state, deployment_strategy, " +
|
||||
"replica_states, deploy_stage, container_id, container_name, error_message, " +
|
||||
"resolved_config, deployed_at, stopped_at, created_at";
|
||||
"resolved_config, deployed_config_snapshot, deployed_at, stopped_at, created_at";
|
||||
|
||||
private final JdbcTemplate jdbc;
|
||||
private final ObjectMapper objectMapper;
|
||||
@@ -129,6 +130,15 @@ public class PostgresDeploymentRepository implements DeploymentRepository {
|
||||
}
|
||||
}
|
||||
|
||||
public void saveDeployedConfigSnapshot(UUID id, DeploymentConfigSnapshot snapshot) {
|
||||
try {
|
||||
String json = snapshot != null ? objectMapper.writeValueAsString(snapshot) : null;
|
||||
jdbc.update("UPDATE deployments SET deployed_config_snapshot = ?::jsonb WHERE id = ?", json, id);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Failed to serialize deployed_config_snapshot", e);
|
||||
}
|
||||
}
|
||||
|
||||
public Optional<Deployment> findByContainerId(String containerId) {
|
||||
var results = jdbc.query(
|
||||
"SELECT " + SELECT_COLS + " FROM deployments WHERE replica_states::text LIKE ? " +
|
||||
@@ -158,6 +168,15 @@ public class PostgresDeploymentRepository implements DeploymentRepository {
|
||||
throw new SQLException("Failed to deserialize resolved_config", e);
|
||||
}
|
||||
}
|
||||
DeploymentConfigSnapshot deployedConfigSnapshot = null;
|
||||
String snapshotJson = rs.getString("deployed_config_snapshot");
|
||||
if (snapshotJson != null) {
|
||||
try {
|
||||
deployedConfigSnapshot = objectMapper.readValue(snapshotJson, DeploymentConfigSnapshot.class);
|
||||
} catch (Exception e) {
|
||||
throw new SQLException("Failed to deserialize deployed_config_snapshot", e);
|
||||
}
|
||||
}
|
||||
return new Deployment(
|
||||
UUID.fromString(rs.getString("id")),
|
||||
UUID.fromString(rs.getString("app_id")),
|
||||
@@ -172,7 +191,7 @@ public class PostgresDeploymentRepository implements DeploymentRepository {
|
||||
rs.getString("container_name"),
|
||||
rs.getString("error_message"),
|
||||
resolvedConfig,
|
||||
null, // deployedConfigSnapshot — wired in Task 1.4
|
||||
deployedConfigSnapshot,
|
||||
deployedAt != null ? deployedAt.toInstant() : null,
|
||||
stoppedAt != null ? stoppedAt.toInstant() : null,
|
||||
rs.getTimestamp("created_at").toInstant()
|
||||
|
||||
Reference in New Issue
Block a user