use rpki::ca::idexchange::MyHandle;
use rpki::repository::x509::Time;
use crate::commons::eventsourcing::{AggregateStore, StoredCommandBuilder};
use crate::commons::storage::{Ident, KeyValueStore};
use crate::commons::version::KrillVersion;
use crate::constants::PUBSERVER_NS;
use crate::config::Config;
use crate::server::pubd::access::{
RepositoryAccess, RepositoryAccessEvent, RepositoryAccessInitEvent,
StorableRepositoryCommand,
};
use crate::upgrades::{pre_0_14_0::OldStoredCommand, CommandMigrationEffect};
use crate::upgrades::{
UnconvertedEffect, UpgradeAggregateStorePre0_14, UpgradeMode,
UpgradeResult, UpgradeVersions,
};
use super::old_events::{
Pre0_10RepositoryAccessEventDetails,
Pre0_10RepositoryAccessInitDetails,
};
pub struct PublicationServerRepositoryAccessMigration {
current_kv_store: KeyValueStore,
new_kv_store: KeyValueStore,
new_agg_store: AggregateStore<RepositoryAccess>,
}
impl PublicationServerRepositoryAccessMigration {
pub fn upgrade(
mode: UpgradeMode,
config: &Config,
versions: &UpgradeVersions,
) -> UpgradeResult<()> {
let current_kv_store =
KeyValueStore::create(&config.storage_uri, PUBSERVER_NS)?;
let new_kv_store = KeyValueStore::create_upgrade_store(
&config.storage_uri,
PUBSERVER_NS,
)?;
let new_agg_store = AggregateStore::create_upgrade_store(
&config.storage_uri,
PUBSERVER_NS,
config.use_history_cache,
)?;
let store_migration = PublicationServerRepositoryAccessMigration {
current_kv_store,
new_kv_store,
new_agg_store,
};
if store_migration
.current_kv_store
.has_scope(const { Ident::make("0") })?
&& versions.from >= KrillVersion::release(0, 9, 0)
&& versions.from < KrillVersion::candidate(0, 10, 0, 1)
{
store_migration.upgrade(mode).map(|_| ()) } else {
Ok(())
}
}
}
impl UpgradeAggregateStorePre0_14
for PublicationServerRepositoryAccessMigration
{
type Aggregate = RepositoryAccess;
type OldInitEvent = Pre0_10RepositoryAccessInitDetails;
type OldEvent = Pre0_10RepositoryAccessEventDetails;
type OldStorableDetails = StorableRepositoryCommand;
fn store_name(&self) -> &str {
"Repository Access"
}
fn deployed_store(&self) -> &KeyValueStore {
&self.current_kv_store
}
fn preparation_key_value_store(&self) -> &KeyValueStore {
&self.new_kv_store
}
fn preparation_aggregate_store(
&self,
) -> &AggregateStore<Self::Aggregate> {
&self.new_agg_store
}
fn convert_init_event(
&self,
old_init: Self::OldInitEvent,
handle: MyHandle,
actor: String,
time: Time,
) -> UpgradeResult<
crate::commons::eventsourcing::StoredCommand<Self::Aggregate>,
> {
let details = StorableRepositoryCommand::Init;
let builder = StoredCommandBuilder::<RepositoryAccess>::new(
actor, time, handle, 0, details,
);
let init_event: RepositoryAccessInitEvent = old_init.into();
Ok(builder.finish_with_init_event(init_event))
}
fn convert_old_command(
&self,
old_command: OldStoredCommand<Self::OldStorableDetails>,
old_effect: UnconvertedEffect<Self::OldEvent>,
version: u64,
) -> UpgradeResult<CommandMigrationEffect<Self::Aggregate>> {
let new_command_builder =
StoredCommandBuilder::<RepositoryAccess>::new(
old_command.actor().clone(),
old_command.time(),
old_command.handle().clone(),
version,
old_command.details().clone(),
);
let new_command = match old_effect {
UnconvertedEffect::Error { msg } => {
new_command_builder.finish_with_error(msg)
}
UnconvertedEffect::Success { events } => {
let full_events: Vec<RepositoryAccessEvent> =
events.into_iter().map(|old| old.into()).collect();
new_command_builder.finish_with_events(full_events)
}
};
Ok(CommandMigrationEffect::StoredCommand(new_command))
}
}