feat: update PostgresDeploymentRepository for orchestration columns

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
hsiegeln
2026-04-08 20:16:57 +02:00
parent 6eff271238
commit fef0239b1d
2 changed files with 61 additions and 8 deletions

View File

@@ -44,8 +44,8 @@ public class RuntimeBeanConfig {
}
@Bean
public DeploymentRepository deploymentRepository(JdbcTemplate jdbc) {
return new PostgresDeploymentRepository(jdbc);
public DeploymentRepository deploymentRepository(JdbcTemplate jdbc, ObjectMapper objectMapper) {
return new PostgresDeploymentRepository(jdbc, objectMapper);
}
@Bean

View File

@@ -3,6 +3,8 @@ package com.cameleer3.server.app.storage;
import com.cameleer3.server.core.runtime.Deployment;
import com.cameleer3.server.core.runtime.DeploymentRepository;
import com.cameleer3.server.core.runtime.DeploymentStatus;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import java.sql.ResultSet;
@@ -10,35 +12,43 @@ import java.sql.SQLException;
import java.sql.Timestamp;
import java.time.Instant;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
public class PostgresDeploymentRepository implements DeploymentRepository {
private final JdbcTemplate jdbc;
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, " +
"deployed_at, stopped_at, created_at";
public PostgresDeploymentRepository(JdbcTemplate jdbc) {
private final JdbcTemplate jdbc;
private final ObjectMapper objectMapper;
public PostgresDeploymentRepository(JdbcTemplate jdbc, ObjectMapper objectMapper) {
this.jdbc = jdbc;
this.objectMapper = objectMapper;
}
@Override
public List<Deployment> findByAppId(UUID appId) {
return jdbc.query(
"SELECT id, app_id, app_version_id, environment_id, status, container_id, container_name, error_message, deployed_at, stopped_at, created_at FROM deployments WHERE app_id = ? ORDER BY created_at DESC",
"SELECT " + SELECT_COLS + " FROM deployments WHERE app_id = ? ORDER BY created_at DESC",
(rs, rowNum) -> mapRow(rs), appId);
}
@Override
public List<Deployment> findByEnvironmentId(UUID environmentId) {
return jdbc.query(
"SELECT id, app_id, app_version_id, environment_id, status, container_id, container_name, error_message, deployed_at, stopped_at, created_at FROM deployments WHERE environment_id = ? ORDER BY created_at DESC",
"SELECT " + SELECT_COLS + " FROM deployments WHERE environment_id = ? ORDER BY created_at DESC",
(rs, rowNum) -> mapRow(rs), environmentId);
}
@Override
public Optional<Deployment> findById(UUID id) {
var results = jdbc.query(
"SELECT id, app_id, app_version_id, environment_id, status, container_id, container_name, error_message, deployed_at, stopped_at, created_at FROM deployments WHERE id = ?",
"SELECT " + SELECT_COLS + " FROM deployments WHERE id = ?",
(rs, rowNum) -> mapRow(rs), id);
return results.isEmpty() ? Optional.empty() : Optional.of(results.get(0));
}
@@ -46,7 +56,8 @@ public class PostgresDeploymentRepository implements DeploymentRepository {
@Override
public Optional<Deployment> findActiveByAppIdAndEnvironmentId(UUID appId, UUID environmentId) {
var results = jdbc.query(
"SELECT id, app_id, app_version_id, environment_id, status, container_id, container_name, error_message, deployed_at, stopped_at, created_at FROM deployments WHERE app_id = ? AND environment_id = ? AND status IN ('STARTING', 'RUNNING') ORDER BY created_at DESC LIMIT 1",
"SELECT " + SELECT_COLS + " FROM deployments WHERE app_id = ? AND environment_id = ? " +
"AND status IN ('STARTING', 'RUNNING', 'DEGRADED') ORDER BY created_at DESC LIMIT 1",
(rs, rowNum) -> mapRow(rs), appId, environmentId);
return results.isEmpty() ? Optional.empty() : Optional.of(results.get(0));
}
@@ -75,15 +86,57 @@ public class PostgresDeploymentRepository implements DeploymentRepository {
jdbc.update("UPDATE deployments SET stopped_at = now() WHERE id = ?", id);
}
public void updateReplicaStates(UUID id, List<Map<String, Object>> replicaStates) {
try {
String json = objectMapper.writeValueAsString(replicaStates);
jdbc.update("UPDATE deployments SET replica_states = ?::jsonb WHERE id = ?", json, id);
} catch (Exception e) {
throw new RuntimeException("Failed to serialize replicaStates", e);
}
}
public void updateDeployStage(UUID id, String stage) {
jdbc.update("UPDATE deployments SET deploy_stage = ? WHERE id = ?", stage, id);
}
public void updateTargetState(UUID id, String targetState) {
jdbc.update("UPDATE deployments SET target_state = ? WHERE id = ?", targetState, id);
}
public void updateDeploymentStrategy(UUID id, String strategy) {
jdbc.update("UPDATE deployments SET deployment_strategy = ? WHERE id = ?", strategy, id);
}
public Optional<Deployment> findByContainerId(String containerId) {
var results = jdbc.query(
"SELECT " + SELECT_COLS + " FROM deployments WHERE replica_states::text LIKE ? " +
"AND status IN ('STARTING', 'RUNNING', 'DEGRADED') ORDER BY created_at DESC LIMIT 1",
(rs, rowNum) -> mapRow(rs), "%" + containerId + "%");
return results.isEmpty() ? Optional.empty() : Optional.of(results.get(0));
}
private Deployment mapRow(ResultSet rs) throws SQLException {
Timestamp deployedAt = rs.getTimestamp("deployed_at");
Timestamp stoppedAt = rs.getTimestamp("stopped_at");
String replicaStatesJson = rs.getString("replica_states");
List<Map<String, Object>> replicaStates = null;
if (replicaStatesJson != null) {
try {
replicaStates = objectMapper.readValue(replicaStatesJson, new TypeReference<>() {});
} catch (Exception e) {
throw new SQLException("Failed to deserialize replica_states", e);
}
}
return new Deployment(
UUID.fromString(rs.getString("id")),
UUID.fromString(rs.getString("app_id")),
UUID.fromString(rs.getString("app_version_id")),
UUID.fromString(rs.getString("environment_id")),
DeploymentStatus.valueOf(rs.getString("status")),
rs.getString("target_state"),
rs.getString("deployment_strategy"),
replicaStates,
rs.getString("deploy_stage"),
rs.getString("container_id"),
rs.getString("container_name"),
rs.getString("error_message"),