use std::convert::TryFrom;
use std::fmt::Debug;
use bytes::Bytes;
use tonic::transport::Channel;
use tracing::{instrument, trace};
use crate::data::DamlResult;
use crate::data::package::{
DamlPackageDetails, DamlPriorTopologySerial, DamlUpdateVettedPackagesForceFlag, DamlUpdateVettedPackagesOutcome,
DamlVettedPackages, DamlVettedPackagesChange, DamlVettingChange,
};
use crate::grpc_protobuf::com::daml::ledger::api::v2::admin::package_management_service_client::PackageManagementServiceClient;
use crate::grpc_protobuf::com::daml::ledger::api::v2::admin::upload_dar_file_request::VettingChange as ProtoVettingChange;
use crate::grpc_protobuf::com::daml::ledger::api::v2::admin::{
ListKnownPackagesRequest, UpdateVettedPackagesRequest, UploadDarFileRequest, ValidateDarFileRequest,
VettedPackagesChange,
};
use crate::service::common::make_request;
#[derive(Debug)]
pub struct DamlPackageManagementService<'a> {
channel: Channel,
auth_token: Option<&'a str>,
}
impl<'a> DamlPackageManagementService<'a> {
pub fn new(channel: Channel, auth_token: Option<&'a str>) -> Self {
Self {
channel,
auth_token,
}
}
pub fn with_token(self, auth_token: &'a str) -> Self {
Self {
auth_token: Some(auth_token),
..self
}
}
#[instrument(skip(self))]
pub async fn list_known_packages(&self) -> DamlResult<Vec<DamlPackageDetails>> {
let payload = ListKnownPackagesRequest {};
trace!(payload = ?payload, token = ?self.auth_token);
let response = self.client().list_known_packages(make_request(payload, self.auth_token)?).await?.into_inner();
trace!(?response);
response.package_details.into_iter().map(DamlPackageDetails::try_from).collect()
}
#[instrument(skip(self))]
pub async fn upload_dar_file(
&self,
bytes: impl Into<Bytes> + Debug,
submission_id: impl Into<String> + Debug,
vetting_change: DamlVettingChange,
synchronizer_id: impl Into<String> + Debug,
) -> DamlResult<()> {
let payload = UploadDarFileRequest {
dar_file: bytes.into().to_vec(),
submission_id: submission_id.into(),
vetting_change: ProtoVettingChange::from(vetting_change) as i32,
synchronizer_id: synchronizer_id.into(),
};
trace!(payload = ?payload, token = ?self.auth_token);
self.client().upload_dar_file(make_request(payload, self.auth_token)?).await?;
Ok(())
}
#[instrument(skip(self))]
pub async fn validate_dar_file(
&self,
bytes: impl Into<Bytes> + Debug,
submission_id: impl Into<String> + Debug,
synchronizer_id: impl Into<String> + Debug,
) -> DamlResult<()> {
let payload = ValidateDarFileRequest {
dar_file: bytes.into().to_vec(),
submission_id: submission_id.into(),
synchronizer_id: synchronizer_id.into(),
};
trace!(payload = ?payload, token = ?self.auth_token);
self.client().validate_dar_file(make_request(payload, self.auth_token)?).await?;
Ok(())
}
#[instrument(skip(self, force_flags))]
pub async fn update_vetted_packages(
&self,
changes: Vec<DamlVettedPackagesChange>,
dry_run: bool,
synchronizer_id: impl Into<String> + Debug,
expected_topology_serial: Option<DamlPriorTopologySerial>,
force_flags: impl IntoIterator<Item = DamlUpdateVettedPackagesForceFlag>,
) -> DamlResult<DamlUpdateVettedPackagesOutcome> {
let payload = UpdateVettedPackagesRequest {
changes: changes.into_iter().map(VettedPackagesChange::try_from).collect::<DamlResult<Vec<_>>>()?,
dry_run,
synchronizer_id: synchronizer_id.into(),
expected_topology_serial: expected_topology_serial.map(Into::into),
update_vetted_packages_force_flags: force_flags.into_iter().map(i32::from).collect(),
};
trace!(payload = ?payload, token = ?self.auth_token);
let response =
self.client().update_vetted_packages(make_request(payload, self.auth_token)?).await?.into_inner();
trace!(?response);
Ok(DamlUpdateVettedPackagesOutcome {
past_vetted_packages: response.past_vetted_packages.map(DamlVettedPackages::try_from).transpose()?,
new_vetted_packages: response.new_vetted_packages.map(DamlVettedPackages::try_from).transpose()?,
})
}
fn client(&self) -> PackageManagementServiceClient<Channel> {
PackageManagementServiceClient::new(self.channel.clone())
}
}