forked from StrafesNET/maps-service
validator: convert to gRPC
This commit is contained in:
@@ -4,7 +4,7 @@ use crate::rbx_util::{get_mapinfo,get_root_instance,read_dom,ReadDomError,GameID
|
||||
|
||||
use heck::{ToSnakeCase,ToTitleCase};
|
||||
use rbx_dom_weak::Instance;
|
||||
use submissions_api::types::Check;
|
||||
use rust_grpc::validator::Check;
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(Debug)]
|
||||
@@ -640,27 +640,27 @@ impl<D:std::fmt::Display> std::fmt::Display for Duplicates<D>{
|
||||
macro_rules! passed{
|
||||
($name:literal)=>{
|
||||
Check{
|
||||
Name:$name,
|
||||
Summary:String::new(),
|
||||
Passed:true,
|
||||
name:$name.to_owned(),
|
||||
summary:String::new(),
|
||||
passed:true,
|
||||
}
|
||||
}
|
||||
}
|
||||
macro_rules! summary{
|
||||
($name:literal,$summary:expr)=>{
|
||||
Check{
|
||||
Name:$name,
|
||||
Summary:$summary,
|
||||
Passed:false,
|
||||
name:$name.to_owned(),
|
||||
summary:$summary,
|
||||
passed:false,
|
||||
}
|
||||
};
|
||||
}
|
||||
macro_rules! summary_format{
|
||||
($name:literal,$fmt:literal)=>{
|
||||
Check{
|
||||
Name:$name,
|
||||
Summary:format!($fmt),
|
||||
Passed:false,
|
||||
name:$name.to_owned(),
|
||||
summary:format!($fmt),
|
||||
passed:false,
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -813,7 +813,7 @@ impl MapCheck<'_>{
|
||||
summary_format!("UnanchoredParts","{count} unanchored {plural}: {context}")
|
||||
}
|
||||
};
|
||||
Ok(MapCheckList{checks:Box::new([
|
||||
Ok(MapCheckList{checks:vec![
|
||||
model_class,
|
||||
model_name,
|
||||
display_name,
|
||||
@@ -831,13 +831,13 @@ impl MapCheck<'_>{
|
||||
missing_wormhole_in,
|
||||
duplicate_wormhole_out,
|
||||
unanchored_parts,
|
||||
])})
|
||||
]})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(serde::Serialize)]
|
||||
pub struct MapCheckList{
|
||||
pub checks:Box<[Check;17]>,
|
||||
pub checks:Vec<Check>,
|
||||
}
|
||||
|
||||
pub struct CheckListAndVersion{
|
||||
|
||||
@@ -5,7 +5,7 @@ use crate::nats_types::CheckMapfixRequest;
|
||||
#[derive(Debug)]
|
||||
pub enum Error{
|
||||
Check(crate::check::Error),
|
||||
ApiActionMapfixCheck(submissions_api::Error),
|
||||
ApiActionMapfixCheck(tonic::Status),
|
||||
}
|
||||
impl std::fmt::Display for Error{
|
||||
fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{
|
||||
@@ -22,13 +22,13 @@ impl crate::message_handler::MessageHandler{
|
||||
// update the mapfix depending on the result
|
||||
match check_result{
|
||||
Ok(CheckListAndVersion{status:Ok(map_info),version})=>{
|
||||
self.api.action_mapfix_submitted(
|
||||
submissions_api::types::ActionMapfixSubmittedRequest{
|
||||
MapfixID:mapfix_id,
|
||||
ModelVersion:version,
|
||||
DisplayName:map_info.display_name,
|
||||
Creator:map_info.creator,
|
||||
GameID:map_info.game_id.into(),
|
||||
self.mapfixes.set_status_submitted(
|
||||
rust_grpc::validator::SubmittedRequest{
|
||||
id:mapfix_id,
|
||||
model_version:version,
|
||||
display_name:map_info.display_name,
|
||||
creator:map_info.creator,
|
||||
game_id:map_info.game_id as u32,
|
||||
}
|
||||
).await.map_err(Error::ApiActionMapfixCheck)?;
|
||||
|
||||
@@ -36,29 +36,31 @@ impl crate::message_handler::MessageHandler{
|
||||
return Ok(());
|
||||
},
|
||||
// update the mapfix model status to request changes
|
||||
Ok(CheckListAndVersion{status:Err(check_list),..})=>self.api.create_mapfix_audit_check_list(
|
||||
submissions_api::types::CreateMapfixAuditCheckListRequest{
|
||||
MapfixID:mapfix_id,
|
||||
CheckList:check_list.checks.as_slice(),
|
||||
}
|
||||
).await.map_err(Error::ApiActionMapfixCheck)?,
|
||||
Ok(CheckListAndVersion{status:Err(check_list),..})=>{
|
||||
self.mapfixes.create_audit_checklist(
|
||||
rust_grpc::validator::AuditChecklistRequest{
|
||||
id:mapfix_id,
|
||||
check_list:check_list.checks,
|
||||
}
|
||||
).await.map_err(Error::ApiActionMapfixCheck)?;
|
||||
},
|
||||
// update the mapfix model status to request changes
|
||||
Err(e)=>{
|
||||
// log error
|
||||
println!("[check_mapfix] Error: {e}");
|
||||
|
||||
self.api.create_mapfix_audit_error(
|
||||
submissions_api::types::CreateMapfixAuditErrorRequest{
|
||||
MapfixID:mapfix_id,
|
||||
ErrorMessage:e.to_string(),
|
||||
self.mapfixes.create_audit_error(
|
||||
rust_grpc::validator::AuditErrorRequest{
|
||||
id:mapfix_id,
|
||||
error_message:e.to_string(),
|
||||
}
|
||||
).await.map_err(Error::ApiActionMapfixCheck)?;
|
||||
},
|
||||
}
|
||||
|
||||
self.api.action_mapfix_request_changes(
|
||||
submissions_api::types::ActionMapfixRequestChangesRequest{
|
||||
MapfixID:mapfix_id,
|
||||
self.mapfixes.set_status_request_changes(
|
||||
rust_grpc::validator::MapfixId{
|
||||
id:mapfix_id,
|
||||
}
|
||||
).await.map_err(Error::ApiActionMapfixCheck)?;
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ use crate::nats_types::CheckSubmissionRequest;
|
||||
#[derive(Debug)]
|
||||
pub enum Error{
|
||||
Check(crate::check::Error),
|
||||
ApiActionSubmissionCheck(submissions_api::Error),
|
||||
ApiActionSubmissionCheck(tonic::Status),
|
||||
}
|
||||
impl std::fmt::Display for Error{
|
||||
fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{
|
||||
@@ -23,13 +23,13 @@ impl crate::message_handler::MessageHandler{
|
||||
match check_result{
|
||||
// update the submission model status to submitted
|
||||
Ok(CheckListAndVersion{status:Ok(map_info),version})=>{
|
||||
self.api.action_submission_submitted(
|
||||
submissions_api::types::ActionSubmissionSubmittedRequest{
|
||||
SubmissionID:submission_id,
|
||||
ModelVersion:version,
|
||||
DisplayName:map_info.display_name,
|
||||
Creator:map_info.creator,
|
||||
GameID:map_info.game_id.into(),
|
||||
self.submissions.set_status_submitted(
|
||||
rust_grpc::validator::SubmittedRequest{
|
||||
id:submission_id,
|
||||
model_version:version,
|
||||
display_name:map_info.display_name,
|
||||
creator:map_info.creator,
|
||||
game_id:map_info.game_id as u32,
|
||||
}
|
||||
).await.map_err(Error::ApiActionSubmissionCheck)?;
|
||||
|
||||
@@ -37,29 +37,31 @@ impl crate::message_handler::MessageHandler{
|
||||
return Ok(());
|
||||
},
|
||||
// update the submission model status to request changes
|
||||
Ok(CheckListAndVersion{status:Err(check_list),..})=>self.api.create_submission_audit_check_list(
|
||||
submissions_api::types::CreateSubmissionAuditCheckListRequest{
|
||||
SubmissionID:submission_id,
|
||||
CheckList:check_list.checks.as_slice(),
|
||||
Ok(CheckListAndVersion{status:Err(check_list),..})=>{
|
||||
self.submissions.create_audit_checklist(
|
||||
rust_grpc::validator::AuditChecklistRequest{
|
||||
id:submission_id,
|
||||
check_list:check_list.checks,
|
||||
}
|
||||
).await.map_err(Error::ApiActionSubmissionCheck)?,
|
||||
).await.map_err(Error::ApiActionSubmissionCheck)?;
|
||||
},
|
||||
// update the submission model status to request changes
|
||||
Err(e)=>{
|
||||
// log error
|
||||
println!("[check_submission] Error: {e}");
|
||||
|
||||
self.api.create_submission_audit_error(
|
||||
submissions_api::types::CreateSubmissionAuditErrorRequest{
|
||||
SubmissionID:submission_id,
|
||||
ErrorMessage:e.to_string(),
|
||||
self.submissions.create_audit_error(
|
||||
rust_grpc::validator::AuditErrorRequest{
|
||||
id:submission_id,
|
||||
error_message:e.to_string(),
|
||||
}
|
||||
).await.map_err(Error::ApiActionSubmissionCheck)?;
|
||||
},
|
||||
}
|
||||
|
||||
self.api.action_submission_request_changes(
|
||||
submissions_api::types::ActionSubmissionRequestChangesRequest{
|
||||
SubmissionID:submission_id,
|
||||
self.submissions.set_status_request_changes(
|
||||
rust_grpc::validator::SubmissionId{
|
||||
id:submission_id,
|
||||
}
|
||||
).await.map_err(Error::ApiActionSubmissionCheck)?;
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ use crate::create::CreateRequest;
|
||||
#[derive(Debug)]
|
||||
pub enum Error{
|
||||
Create(crate::create::Error),
|
||||
ApiActionMapfixCreate(submissions_api::Error),
|
||||
ApiActionMapfixCreate(tonic::Status),
|
||||
}
|
||||
impl std::fmt::Display for Error{
|
||||
fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{
|
||||
@@ -22,22 +22,22 @@ impl crate::message_handler::MessageHandler{
|
||||
}).await.map_err(Error::Create)?;
|
||||
|
||||
// call create on api
|
||||
self.api.create_mapfix(submissions_api::types::CreateMapfixRequest{
|
||||
OperationID:create_info.OperationID,
|
||||
AssetOwner:create_request.AssetOwner as i64,
|
||||
DisplayName:create_request.DisplayName.as_deref().unwrap_or_default(),
|
||||
Creator:create_request.Creator.as_deref().unwrap_or_default(),
|
||||
self.mapfixes.create(rust_grpc::validator::MapfixCreate{
|
||||
operation_id:create_info.OperationID,
|
||||
asset_owner:create_request.AssetOwner,
|
||||
display_name:create_request.DisplayName.unwrap_or_default(),
|
||||
creator:create_request.Creator.unwrap_or_default(),
|
||||
// not great TODO: make this great
|
||||
GameID:create_request.GameID.unwrap_or(crate::rbx_util::GameID::Bhop).into(),
|
||||
AssetID:create_info.ModelID,
|
||||
AssetVersion:create_request.AssetVersion,
|
||||
TargetAssetID:create_info.TargetAssetID,
|
||||
Description:create_info.Description.as_str(),
|
||||
game_id:create_request.GameID.unwrap_or(crate::rbx_util::GameID::Bhop) as u32,
|
||||
asset_id:create_info.ModelID,
|
||||
asset_version:create_request.AssetVersion,
|
||||
target_asset_id:create_info.TargetAssetID,
|
||||
description:create_info.Description,
|
||||
}).await.map_err(Error::ApiActionMapfixCreate)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
pub async fn create_mapfix(&self,create_info:CreateMapfixRequest)->Result<(),submissions_api::Error>{
|
||||
pub async fn create_mapfix(&self,create_info:CreateMapfixRequest)->Result<(),tonic::Status>{
|
||||
let operation_id=create_info.OperationID;
|
||||
|
||||
let create_result=self.create_mapfix_inner(create_info).await;
|
||||
@@ -46,9 +46,9 @@ impl crate::message_handler::MessageHandler{
|
||||
// log error
|
||||
println!("[create_mapfix] Error: {e}");
|
||||
|
||||
self.api.action_operation_failed(submissions_api::types::ActionOperationFailedRequest{
|
||||
OperationID:operation_id,
|
||||
StatusMessage:e.to_string(),
|
||||
self.operations.fail(rust_grpc::validator::OperationFailRequest{
|
||||
operation_id,
|
||||
status_message:e.to_string(),
|
||||
}).await?;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ use crate::rbx_util::GameID;
|
||||
#[derive(Debug)]
|
||||
pub enum Error{
|
||||
Create(crate::create::Error),
|
||||
ApiActionSubmissionCreate(submissions_api::Error),
|
||||
ApiActionSubmissionCreate(tonic::Status),
|
||||
}
|
||||
impl std::fmt::Display for Error{
|
||||
fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{
|
||||
@@ -23,35 +23,35 @@ impl crate::message_handler::MessageHandler{
|
||||
|
||||
// grab values from submission form, otherwise try to fill blanks from map data
|
||||
let display_name=if create_info.DisplayName.is_empty(){
|
||||
create_request.DisplayName.as_deref().unwrap_or_default()
|
||||
create_request.DisplayName.unwrap_or_default()
|
||||
}else{
|
||||
create_info.DisplayName.as_str()
|
||||
create_info.DisplayName
|
||||
};
|
||||
|
||||
let creator=if create_info.Creator.is_empty(){
|
||||
create_request.Creator.as_deref().unwrap_or_default()
|
||||
create_request.Creator.unwrap_or_default()
|
||||
}else{
|
||||
create_info.Creator.as_str()
|
||||
create_info.Creator
|
||||
};
|
||||
|
||||
let game_id=create_info.GameID.try_into().ok().or(create_request.GameID).unwrap_or(GameID::Bhop);
|
||||
|
||||
// call create on api
|
||||
self.api.create_submission(submissions_api::types::CreateSubmissionRequest{
|
||||
OperationID:create_info.OperationID,
|
||||
AssetOwner:create_request.AssetOwner as i64,
|
||||
DisplayName:display_name,
|
||||
Creator:creator,
|
||||
GameID:game_id.into(),
|
||||
AssetID:create_info.ModelID,
|
||||
AssetVersion:create_request.AssetVersion,
|
||||
Status:create_info.Status,
|
||||
Roles:create_info.Roles,
|
||||
self.submissions.create(rust_grpc::validator::SubmissionCreate{
|
||||
operation_id:create_info.OperationID,
|
||||
asset_owner:create_request.AssetOwner,
|
||||
display_name:display_name,
|
||||
creator:creator,
|
||||
game_id:game_id as u32,
|
||||
asset_id:create_info.ModelID,
|
||||
asset_version:create_request.AssetVersion,
|
||||
status:create_info.Status,
|
||||
roles:create_info.Roles,
|
||||
}).await.map_err(Error::ApiActionSubmissionCreate)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
pub async fn create_submission(&self,create_info:CreateSubmissionRequest)->Result<(),submissions_api::Error>{
|
||||
pub async fn create_submission(&self,create_info:CreateSubmissionRequest)->Result<(),tonic::Status>{
|
||||
let operation_id=create_info.OperationID;
|
||||
|
||||
let create_result=self.create_submission_inner(create_info).await;
|
||||
@@ -60,9 +60,9 @@ impl crate::message_handler::MessageHandler{
|
||||
// log error
|
||||
println!("[create_submission] Error: {e}");
|
||||
|
||||
self.api.action_operation_failed(submissions_api::types::ActionOperationFailedRequest{
|
||||
OperationID:operation_id,
|
||||
StatusMessage:e.to_string(),
|
||||
self.operations.fail(rust_grpc::validator::OperationFailRequest{
|
||||
operation_id:operation_id,
|
||||
status_message:e.to_string(),
|
||||
}).await?;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
use futures::StreamExt;
|
||||
|
||||
mod download;
|
||||
mod grpc;
|
||||
mod rbx_util;
|
||||
mod message_handler;
|
||||
mod nats_types;
|
||||
mod download;
|
||||
mod types;
|
||||
|
||||
mod check;
|
||||
mod check_mapfix;
|
||||
mod check_submission;
|
||||
@@ -20,7 +22,7 @@ mod validate_submission;
|
||||
#[allow(dead_code)]
|
||||
#[derive(Debug)]
|
||||
pub enum StartupError{
|
||||
API(submissions_api::ReqwestError),
|
||||
API(tonic::transport::Error),
|
||||
NatsConnect(async_nats::ConnectError),
|
||||
NatsGetStream(async_nats::jetstream::context::GetStreamError),
|
||||
NatsConsumer(async_nats::jetstream::stream::ConsumerError),
|
||||
@@ -55,7 +57,14 @@ async fn main()->Result<(),StartupError>{
|
||||
|
||||
// maps-service api
|
||||
let api_host_internal=std::env::var("API_HOST_INTERNAL").expect("API_HOST_INTERNAL env required");
|
||||
let api=submissions_api::internal::Context::new(api_host_internal).map_err(StartupError::API)?;
|
||||
let (mapfixes,operations,scripts,script_policy,submissions)=tokio::try_join!(
|
||||
crate::grpc::mapfixes::ValidatorMapfixesServiceClient::connect(api_host_internal.clone()),
|
||||
crate::grpc::operations::ValidatorOperationsServiceClient::connect(api_host_internal.clone()),
|
||||
crate::grpc::scripts::ValidatorScriptsServiceClient::connect(api_host_internal.clone()),
|
||||
crate::grpc::script_policy::ValidatorScriptPolicyServiceClient::connect(api_host_internal.clone()),
|
||||
crate::grpc::submissions::ValidatorSubmissionsServiceClient::connect(api_host_internal.clone()),
|
||||
).map_err(StartupError::API)?;
|
||||
let message_handler=message_handler::MessageHandler::new(cloud_context,cookie_context,group_id,mapfixes,operations,scripts,script_policy,submissions);
|
||||
|
||||
// nats
|
||||
let nats_host=std::env::var("NATS_HOST").expect("NATS_HOST env required");
|
||||
@@ -88,14 +97,12 @@ async fn main()->Result<(),StartupError>{
|
||||
consumer.messages().await.map_err(StartupError::NatsStream)
|
||||
};
|
||||
|
||||
let message_handler=message_handler::MessageHandler::new(cloud_context,cookie_context,group_id,api);
|
||||
// run futures
|
||||
let mut messages=nats_fut.await?;
|
||||
|
||||
// Create a signal listener for SIGTERM
|
||||
let mut sig_term=tokio::signal::unix::signal(tokio::signal::unix::SignalKind::terminate()).expect("Failed to create SIGTERM signal listener");
|
||||
|
||||
// run futures
|
||||
let mut messages=nats_fut.await?;
|
||||
|
||||
// process up to PARALLEL_REQUESTS in parallel
|
||||
let main_loop=async move{
|
||||
static SEM:tokio::sync::Semaphore=tokio::sync::Semaphore::const_new(PARALLEL_REQUESTS);
|
||||
|
||||
@@ -5,8 +5,8 @@ pub enum HandleMessageError{
|
||||
DoubleAck(async_nats::Error),
|
||||
Json(serde_json::Error),
|
||||
UnknownSubject(String),
|
||||
CreateMapfix(submissions_api::Error),
|
||||
CreateSubmission(submissions_api::Error),
|
||||
CreateMapfix(tonic::Status),
|
||||
CreateSubmission(tonic::Status),
|
||||
CheckMapfix(crate::check_mapfix::Error),
|
||||
CheckSubmission(crate::check_submission::Error),
|
||||
UploadMapfix(crate::upload_mapfix::Error),
|
||||
@@ -31,7 +31,11 @@ pub struct MessageHandler{
|
||||
pub(crate) cloud_context:rbx_asset::cloud::Context,
|
||||
pub(crate) cookie_context:rbx_asset::cookie::Context,
|
||||
pub(crate) group_id:Option<u64>,
|
||||
pub(crate) api:submissions_api::internal::Context,
|
||||
pub(crate) mapfixes:crate::grpc::mapfixes::Service,
|
||||
pub(crate) operations:crate::grpc::operations::Service,
|
||||
pub(crate) scripts:crate::grpc::scripts::Service,
|
||||
pub(crate) script_policy:crate::grpc::script_policy::Service,
|
||||
pub(crate) submissions:crate::grpc::submissions::Service,
|
||||
}
|
||||
|
||||
impl MessageHandler{
|
||||
@@ -39,13 +43,21 @@ impl MessageHandler{
|
||||
cloud_context:rbx_asset::cloud::Context,
|
||||
cookie_context:rbx_asset::cookie::Context,
|
||||
group_id:Option<u64>,
|
||||
api:submissions_api::internal::Context,
|
||||
mapfixes:crate::grpc::mapfixes::ValidatorMapfixesServiceClient,
|
||||
operations:crate::grpc::operations::ValidatorOperationsServiceClient,
|
||||
scripts:crate::grpc::scripts::ValidatorScriptsServiceClient,
|
||||
script_policy:crate::grpc::script_policy::ValidatorScriptPolicyServiceClient,
|
||||
submissions:crate::grpc::submissions::ValidatorSubmissionsServiceClient,
|
||||
)->Self{
|
||||
Self{
|
||||
cloud_context,
|
||||
cookie_context,
|
||||
group_id,
|
||||
api,
|
||||
mapfixes:crate::grpc::mapfixes::Service::new(mapfixes),
|
||||
operations:crate::grpc::operations::Service::new(operations),
|
||||
scripts:crate::grpc::scripts::Service::new(scripts),
|
||||
script_policy:crate::grpc::script_policy::Service::new(script_policy),
|
||||
submissions:crate::grpc::submissions::Service::new(submissions),
|
||||
}
|
||||
}
|
||||
pub async fn handle_message_result(&self,message_result:MessageResult)->Result<(),HandleMessageError>{
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
use submissions_api::types::{SubmissionID,MapfixID,OperationID};
|
||||
|
||||
// These represent the information needed in the nats message
|
||||
// to perform the operation, not necessarily the over-the-wire format
|
||||
|
||||
@@ -10,7 +8,7 @@ use submissions_api::types::{SubmissionID,MapfixID,OperationID};
|
||||
#[derive(serde::Deserialize)]
|
||||
pub struct CreateSubmissionRequest{
|
||||
// operation_id is passed back in the response message
|
||||
pub OperationID:OperationID,
|
||||
pub OperationID:u32,
|
||||
pub ModelID:u64,
|
||||
pub DisplayName:String,
|
||||
pub Creator:String,
|
||||
@@ -23,7 +21,7 @@ pub struct CreateSubmissionRequest{
|
||||
#[allow(nonstandard_style)]
|
||||
#[derive(serde::Deserialize)]
|
||||
pub struct CreateMapfixRequest{
|
||||
pub OperationID:OperationID,
|
||||
pub OperationID:u32,
|
||||
pub ModelID:u64,
|
||||
pub TargetAssetID:u64,
|
||||
pub Description:String,
|
||||
@@ -32,7 +30,7 @@ pub struct CreateMapfixRequest{
|
||||
#[allow(nonstandard_style)]
|
||||
#[derive(serde::Deserialize)]
|
||||
pub struct CheckSubmissionRequest{
|
||||
pub SubmissionID:SubmissionID,
|
||||
pub SubmissionID:u64,
|
||||
pub ModelID:u64,
|
||||
pub SkipChecks:bool,
|
||||
}
|
||||
@@ -40,7 +38,7 @@ pub struct CheckSubmissionRequest{
|
||||
#[allow(nonstandard_style)]
|
||||
#[derive(serde::Deserialize)]
|
||||
pub struct CheckMapfixRequest{
|
||||
pub MapfixID:MapfixID,
|
||||
pub MapfixID:u64,
|
||||
pub ModelID:u64,
|
||||
pub SkipChecks:bool,
|
||||
}
|
||||
@@ -49,7 +47,7 @@ pub struct CheckMapfixRequest{
|
||||
#[derive(serde::Deserialize)]
|
||||
pub struct ValidateSubmissionRequest{
|
||||
// submission_id is passed back in the response message
|
||||
pub SubmissionID:SubmissionID,
|
||||
pub SubmissionID:u64,
|
||||
pub ModelID:u64,
|
||||
pub ModelVersion:u64,
|
||||
pub ValidatedModelID:Option<u64>,
|
||||
@@ -59,7 +57,7 @@ pub struct ValidateSubmissionRequest{
|
||||
#[derive(serde::Deserialize)]
|
||||
pub struct ValidateMapfixRequest{
|
||||
// submission_id is passed back in the response message
|
||||
pub MapfixID:MapfixID,
|
||||
pub MapfixID:u64,
|
||||
pub ModelID:u64,
|
||||
pub ModelVersion:u64,
|
||||
pub ValidatedModelID:Option<u64>,
|
||||
@@ -69,7 +67,7 @@ pub struct ValidateMapfixRequest{
|
||||
#[allow(nonstandard_style)]
|
||||
#[derive(serde::Deserialize)]
|
||||
pub struct UploadSubmissionRequest{
|
||||
pub SubmissionID:SubmissionID,
|
||||
pub SubmissionID:u64,
|
||||
pub ModelID:u64,
|
||||
pub ModelVersion:u64,
|
||||
pub ModelName:String,
|
||||
@@ -78,7 +76,7 @@ pub struct UploadSubmissionRequest{
|
||||
#[allow(nonstandard_style)]
|
||||
#[derive(serde::Deserialize)]
|
||||
pub struct UploadMapfixRequest{
|
||||
pub MapfixID:MapfixID,
|
||||
pub MapfixID:u64,
|
||||
pub ModelID:u64,
|
||||
pub ModelVersion:u64,
|
||||
pub TargetAssetID:u64,
|
||||
|
||||
@@ -37,15 +37,7 @@ pub enum GameID{
|
||||
Surf=2,
|
||||
FlyTrials=5,
|
||||
}
|
||||
impl From<GameID> for submissions_api::types::GameID{
|
||||
fn from(value:GameID)->Self{
|
||||
match value{
|
||||
GameID::Bhop=>submissions_api::types::GameID::Bhop,
|
||||
GameID::Surf=>submissions_api::types::GameID::Surf,
|
||||
GameID::FlyTrials=>submissions_api::types::GameID::FlyTrials,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ParseGameIDError;
|
||||
impl std::str::FromStr for GameID{
|
||||
|
||||
43
validation/src/types.rs
Normal file
43
validation/src/types.rs
Normal file
@@ -0,0 +1,43 @@
|
||||
use rust_grpc::validator::ResourceType;
|
||||
|
||||
#[derive(Clone,Copy,Debug,Hash,Eq,PartialEq,serde::Serialize,serde::Deserialize)]
|
||||
pub struct MapfixID(pub(crate)u64);
|
||||
#[derive(Clone,Copy,Debug,Hash,Eq,PartialEq,serde::Serialize,serde::Deserialize)]
|
||||
pub struct SubmissionID(pub(crate)u64);
|
||||
#[derive(Clone,Copy,Debug,Hash,Eq,PartialEq,serde::Serialize,serde::Deserialize)]
|
||||
pub struct OperationID(pub(crate)u64);
|
||||
#[derive(Clone,Copy,Debug,Hash,Eq,PartialEq,serde::Serialize,serde::Deserialize)]
|
||||
pub struct ResourceID(pub(crate)u64);
|
||||
#[derive(Clone,Copy,Debug,Hash,Eq,PartialEq,serde::Serialize,serde::Deserialize)]
|
||||
pub struct ScriptID(pub(crate)u64);
|
||||
|
||||
pub struct StupidPolicy(pub(crate)rust_grpc::validator::Policy);
|
||||
#[derive(Debug)]
|
||||
pub struct StupidPolicyError;
|
||||
impl TryFrom<i32> for StupidPolicy{
|
||||
type Error=StupidPolicyError;
|
||||
fn try_from(value:i32)->Result<Self,Self::Error>{
|
||||
Ok(Self(match value{
|
||||
0=>rust_grpc::validator::Policy::None,
|
||||
1=>rust_grpc::validator::Policy::Allowed,
|
||||
2=>rust_grpc::validator::Policy::Blocked,
|
||||
3=>rust_grpc::validator::Policy::Delete,
|
||||
4=>rust_grpc::validator::Policy::Replace,
|
||||
_=>return Err(StupidPolicyError),
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone,Copy,Debug)]
|
||||
pub enum Resource{
|
||||
Submission(SubmissionID),
|
||||
Mapfix(MapfixID),
|
||||
}
|
||||
impl Resource{
|
||||
pub fn split(self)->(ResourceType,ResourceID){
|
||||
match self{
|
||||
Resource::Mapfix(MapfixID(mapfix_id))=>(ResourceType::Mapfix,ResourceID(mapfix_id)),
|
||||
Resource::Submission(SubmissionID(submission_id))=>(ResourceType::Submission,ResourceID(submission_id)),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,7 @@ pub enum Error{
|
||||
IO(std::io::Error),
|
||||
Json(serde_json::Error),
|
||||
Upload(rbx_asset::cookie::UploadError),
|
||||
ApiActionMapfixUploaded(submissions_api::Error),
|
||||
ApiActionMapfixUploaded(tonic::Status),
|
||||
}
|
||||
impl std::fmt::Display for Error{
|
||||
fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{
|
||||
@@ -41,8 +41,8 @@ impl crate::message_handler::MessageHandler{
|
||||
// that's it, the database entry does not need to be changed.
|
||||
|
||||
// mark mapfix as uploaded, TargetAssetID is unchanged
|
||||
self.api.action_mapfix_uploaded(submissions_api::types::ActionMapfixUploadedRequest{
|
||||
MapfixID:upload_info.MapfixID,
|
||||
self.mapfixes.set_status_uploaded(rust_grpc::validator::MapfixId{
|
||||
id:upload_info.MapfixID,
|
||||
}).await.map_err(Error::ApiActionMapfixUploaded)?;
|
||||
|
||||
Ok(())
|
||||
|
||||
@@ -9,7 +9,7 @@ pub enum Error{
|
||||
Json(serde_json::Error),
|
||||
Create(rbx_asset::cookie::CreateError),
|
||||
SystemTime(std::time::SystemTimeError),
|
||||
ApiActionSubmissionUploaded(submissions_api::Error),
|
||||
ApiActionSubmissionUploaded(tonic::Status),
|
||||
}
|
||||
impl std::fmt::Display for Error{
|
||||
fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{
|
||||
@@ -39,9 +39,9 @@ impl crate::message_handler::MessageHandler{
|
||||
},model_data).await.map_err(Error::Create)?;
|
||||
|
||||
// note the asset id of the created model for later release, and mark the submission as uploaded
|
||||
self.api.action_submission_uploaded(submissions_api::types::ActionSubmissionUploadedRequest{
|
||||
SubmissionID:upload_info.SubmissionID,
|
||||
UploadedAssetID:upload_response.AssetId,
|
||||
self.submissions.set_status_uploaded(rust_grpc::validator::StatusUploadedRequest{
|
||||
id:upload_info.SubmissionID,
|
||||
uploaded_asset_id:upload_response.AssetId,
|
||||
}).await.map_err(Error::ApiActionSubmissionUploaded)?;
|
||||
|
||||
Ok(())
|
||||
|
||||
@@ -3,7 +3,7 @@ use crate::nats_types::ValidateMapfixRequest;
|
||||
#[allow(dead_code)]
|
||||
#[derive(Debug)]
|
||||
pub enum Error{
|
||||
ApiActionMapfixValidate(submissions_api::Error),
|
||||
ApiActionMapfixValidate(tonic::Status),
|
||||
}
|
||||
impl std::fmt::Display for Error{
|
||||
fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{
|
||||
@@ -21,24 +21,24 @@ impl crate::message_handler::MessageHandler{
|
||||
match &validate_result{
|
||||
Ok(())=>{
|
||||
// update the mapfix model status to validated
|
||||
self.api.action_mapfix_validated(
|
||||
mapfix_id
|
||||
).await.map_err(Error::ApiActionMapfixValidate)?;
|
||||
self.mapfixes.set_status_validated(rust_grpc::validator::MapfixId{
|
||||
id:mapfix_id,
|
||||
}).await.map_err(Error::ApiActionMapfixValidate)?;
|
||||
},
|
||||
Err(e)=>{
|
||||
// log error
|
||||
println!("[validate_mapfix] Error: {e}");
|
||||
|
||||
self.api.create_mapfix_audit_error(
|
||||
submissions_api::types::CreateMapfixAuditErrorRequest{
|
||||
MapfixID:mapfix_id,
|
||||
ErrorMessage:e.to_string(),
|
||||
self.mapfixes.create_audit_error(
|
||||
rust_grpc::validator::AuditErrorRequest{
|
||||
id:mapfix_id,
|
||||
error_message:e.to_string(),
|
||||
}
|
||||
).await.map_err(Error::ApiActionMapfixValidate)?;
|
||||
|
||||
// update the mapfix model status to accepted
|
||||
self.api.action_mapfix_accepted(submissions_api::types::ActionMapfixAcceptedRequest{
|
||||
MapfixID:mapfix_id,
|
||||
self.mapfixes.set_status_failed(rust_grpc::validator::MapfixId{
|
||||
id:mapfix_id,
|
||||
}).await.map_err(Error::ApiActionMapfixValidate)?;
|
||||
},
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ use crate::nats_types::ValidateSubmissionRequest;
|
||||
#[allow(dead_code)]
|
||||
#[derive(Debug)]
|
||||
pub enum Error{
|
||||
ApiActionSubmissionValidate(submissions_api::Error),
|
||||
ApiActionSubmissionValidate(tonic::Status),
|
||||
}
|
||||
impl std::fmt::Display for Error{
|
||||
fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{
|
||||
@@ -21,24 +21,24 @@ impl crate::message_handler::MessageHandler{
|
||||
match &validate_result{
|
||||
Ok(())=>{
|
||||
// update the submission model status to validated
|
||||
self.api.action_submission_validated(
|
||||
submission_id
|
||||
).await.map_err(Error::ApiActionSubmissionValidate)?;
|
||||
self.submissions.set_status_validated(rust_grpc::validator::SubmissionId{
|
||||
id:submission_id,
|
||||
}).await.map_err(Error::ApiActionSubmissionValidate)?;
|
||||
},
|
||||
Err(e)=>{
|
||||
// log error
|
||||
println!("[validate_submission] Error: {e}");
|
||||
|
||||
self.api.create_submission_audit_error(
|
||||
submissions_api::types::CreateSubmissionAuditErrorRequest{
|
||||
SubmissionID:submission_id,
|
||||
ErrorMessage:e.to_string(),
|
||||
self.submissions.create_audit_error(
|
||||
rust_grpc::validator::AuditErrorRequest{
|
||||
id:submission_id,
|
||||
error_message:e.to_string(),
|
||||
}
|
||||
).await.map_err(Error::ApiActionSubmissionValidate)?;
|
||||
|
||||
// update the submission model status to accepted
|
||||
self.api.action_submission_accepted(submissions_api::types::ActionSubmissionAcceptedRequest{
|
||||
SubmissionID:submission_id,
|
||||
self.submissions.set_status_failed(rust_grpc::validator::SubmissionId{
|
||||
id:submission_id,
|
||||
}).await.map_err(Error::ApiActionSubmissionValidate)?;
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1,33 +1,20 @@
|
||||
use futures::TryStreamExt;
|
||||
use submissions_api::types::Resource;
|
||||
use rust_grpc::validator::Policy;
|
||||
|
||||
use crate::download::download_asset_version;
|
||||
use crate::rbx_util::{read_dom,static_ustr,ReadDomError};
|
||||
use crate::types::{MapfixID,ScriptID,StupidPolicy,StupidPolicyError,SubmissionID,Resource,ResourceID};
|
||||
|
||||
const SCRIPT_CONCURRENCY:usize=16;
|
||||
|
||||
enum Policy{
|
||||
None,
|
||||
Allowed,
|
||||
Blocked,
|
||||
Delete,
|
||||
Replace(String),
|
||||
}
|
||||
|
||||
struct NamePolicy{
|
||||
name:String,
|
||||
policy:Policy,
|
||||
}
|
||||
|
||||
fn source_has_illegal_keywords(source:&str)->bool{
|
||||
source.contains("getfenv")||source.contains("require")
|
||||
}
|
||||
|
||||
fn hash_source(source:&str)->String{
|
||||
fn hash_source(source:&str)->u64{
|
||||
let mut hasher=siphasher::sip::SipHasher::new();
|
||||
std::hash::Hasher::write(&mut hasher,source.as_bytes());
|
||||
let hash=std::hash::Hasher::finish(&hasher);
|
||||
format!("{:016x}",hash)
|
||||
std::hash::Hasher::finish(&hasher)
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
@@ -40,17 +27,18 @@ pub enum Error{
|
||||
submitted:u64,
|
||||
},
|
||||
ScriptFlaggedIllegalKeyword(String),
|
||||
ScriptBlocked(Option<submissions_api::types::ScriptID>),
|
||||
ScriptNotYetReviewed(Option<submissions_api::types::ScriptID>),
|
||||
ScriptBlocked(Option<ScriptID>),
|
||||
ScriptNotYetReviewed(Option<ScriptID>),
|
||||
Download(crate::download::Error),
|
||||
ModelFileDecode(ReadDomError),
|
||||
ApiGetScriptPolicyFromHash(submissions_api::types::ScriptPolicySingleItemError),
|
||||
ApiGetScript(submissions_api::Error),
|
||||
ApiCreateScript(submissions_api::Error),
|
||||
ApiCreateScriptPolicy(submissions_api::Error),
|
||||
ApiGetScriptFromHash(submissions_api::types::ScriptSingleItemError),
|
||||
ApiUpdateMapfixModel(submissions_api::Error),
|
||||
ApiUpdateSubmissionModel(submissions_api::Error),
|
||||
ApiGetScriptPolicyFromHash(crate::grpc::error::ScriptPolicySingleItemError),
|
||||
ApiGetScript(tonic::Status),
|
||||
StupidPolicy(StupidPolicyError),
|
||||
ApiCreateScript(tonic::Status),
|
||||
ApiCreateScriptPolicy(tonic::Status),
|
||||
ApiGetScriptFromHash(crate::grpc::error::ScriptSingleItemError),
|
||||
ApiUpdateMapfixModel(tonic::Status),
|
||||
ApiUpdateSubmissionModel(tonic::Status),
|
||||
ModelFileRootMustHaveOneChild,
|
||||
ModelFileChildRefIsNil,
|
||||
ModelFileEncode(rbx_binary::EncodeError),
|
||||
@@ -78,7 +66,7 @@ impl From<crate::nats_types::ValidateMapfixRequest> for ValidateRequest{
|
||||
ModelID:value.ModelID,
|
||||
ModelVersion:value.ModelVersion,
|
||||
ValidatedModelID:value.ValidatedModelID,
|
||||
Resource:Resource::Mapfix(value.MapfixID),
|
||||
Resource:Resource::Mapfix(MapfixID(value.MapfixID)),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -88,13 +76,27 @@ impl From<crate::nats_types::ValidateSubmissionRequest> for ValidateRequest{
|
||||
ModelID:value.ModelID,
|
||||
ModelVersion:value.ModelVersion,
|
||||
ValidatedModelID:value.ValidatedModelID,
|
||||
Resource:Resource::Submission(value.SubmissionID),
|
||||
Resource:Resource::Submission(SubmissionID(value.SubmissionID)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl crate::message_handler::MessageHandler{
|
||||
pub async fn validate_inner(&self,validate_info:ValidateRequest)->Result<(),Error>{
|
||||
|
||||
enum OwnedPolicy{
|
||||
None,
|
||||
Allowed,
|
||||
Blocked,
|
||||
Delete,
|
||||
Replace(String),
|
||||
}
|
||||
|
||||
struct NamePolicy{
|
||||
name:String,
|
||||
policy:OwnedPolicy,
|
||||
}
|
||||
|
||||
// discover asset creator and latest version
|
||||
let info=self.cloud_context.get_asset_info(
|
||||
rbx_asset::cloud::GetAssetLatestRequest{asset_id:validate_info.ModelID}
|
||||
@@ -144,7 +146,7 @@ impl crate::message_handler::MessageHandler{
|
||||
// policy will be fetched from the database to replace the default policy
|
||||
script_map.insert(source.clone(),NamePolicy{
|
||||
name:get_partial_path(&dom,script),
|
||||
policy:Policy::None,
|
||||
policy:OwnedPolicy::None,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -157,40 +159,42 @@ impl crate::message_handler::MessageHandler{
|
||||
let hash=hash_source(source.as_str());
|
||||
|
||||
// fetch the script policy
|
||||
let script_policy=self.api.get_script_policy_from_hash(submissions_api::types::HashRequest{
|
||||
hash:hash.as_str(),
|
||||
}).await.map_err(Error::ApiGetScriptPolicyFromHash)?;
|
||||
let script_policy=self.script_policy.get_from_hash(
|
||||
hash,
|
||||
).await.map_err(Error::ApiGetScriptPolicyFromHash)?;
|
||||
|
||||
// write the policy to the script_map, fetching the replacement code if necessary
|
||||
if let Some(script_policy)=script_policy{
|
||||
*policy=match script_policy.Policy{
|
||||
submissions_api::types::Policy::None=>Policy::None,
|
||||
submissions_api::types::Policy::Allowed=>Policy::Allowed,
|
||||
submissions_api::types::Policy::Blocked=>Policy::Blocked,
|
||||
submissions_api::types::Policy::Delete=>Policy::Delete,
|
||||
submissions_api::types::Policy::Replace=>{
|
||||
let script=self.api.get_script(submissions_api::types::GetScriptRequest{
|
||||
ScriptID:script_policy.ToScriptID,
|
||||
*policy=match script_policy.policy.try_into(){
|
||||
Ok(StupidPolicy(Policy::None))=>OwnedPolicy::None,
|
||||
Ok(StupidPolicy(Policy::Allowed))=>OwnedPolicy::Allowed,
|
||||
Ok(StupidPolicy(Policy::Blocked))=>OwnedPolicy::Blocked,
|
||||
Ok(StupidPolicy(Policy::Delete))=>OwnedPolicy::Delete,
|
||||
Ok(StupidPolicy(Policy::Replace))=>{
|
||||
let script=self.scripts.get(rust_grpc::validator::ScriptId{
|
||||
id:script_policy.to_script_id,
|
||||
}).await.map_err(Error::ApiGetScript)?;
|
||||
Policy::Replace(script.Source)
|
||||
OwnedPolicy::Replace(script.source)
|
||||
},
|
||||
// WHY DOES PROTOBUF NOT HAVE EMBEDDED ENUMS
|
||||
Err(e)=>return Err(Error::StupidPolicy(e)),
|
||||
};
|
||||
}else{
|
||||
let (resource_type,resource_id)=validate_info.Resource.split();
|
||||
let (resource_type,ResourceID(resource_id))=validate_info.Resource.split();
|
||||
|
||||
// upload the script
|
||||
let script=self.api.create_script(submissions_api::types::CreateScriptRequest{
|
||||
Name:name.as_str(),
|
||||
Source:source.as_str(),
|
||||
ResourceType:resource_type,
|
||||
ResourceID:Some(resource_id),
|
||||
let script=self.scripts.create(rust_grpc::validator::ScriptCreate{
|
||||
name:name.clone(),
|
||||
source:source.clone(),
|
||||
resource_type:resource_type as i32,
|
||||
resource_id:Some(resource_id),
|
||||
}).await.map_err(Error::ApiCreateScript)?;
|
||||
|
||||
// create a None policy (pending review by yours truly)
|
||||
self.api.create_script_policy(submissions_api::types::CreateScriptPolicyRequest{
|
||||
ToScriptID:script.ScriptID,
|
||||
FromScriptID:script.ScriptID,
|
||||
Policy:submissions_api::types::Policy::None,
|
||||
self.script_policy.create(rust_grpc::validator::ScriptPolicyCreate{
|
||||
to_script_id:script.id,
|
||||
from_script_id:script.id,
|
||||
policy:rust_grpc::validator::Policy::None as i32,
|
||||
}).await.map_err(Error::ApiCreateScriptPolicy)?;
|
||||
}
|
||||
|
||||
@@ -204,29 +208,29 @@ impl crate::message_handler::MessageHandler{
|
||||
if let Some(script)=dom.get_by_ref_mut(script_ref){
|
||||
if let Some(rbx_dom_weak::types::Variant::String(source))=script.properties.get_mut(&source_property){
|
||||
match script_map.get(source.as_str()).map(|p|&p.policy){
|
||||
Some(Policy::Blocked)=>{
|
||||
Some(OwnedPolicy::Blocked)=>{
|
||||
let hash=hash_source(source.as_str());
|
||||
let script=self.api.get_script_from_hash(submissions_api::types::HashRequest{
|
||||
hash:hash.as_str(),
|
||||
}).await.map_err(Error::ApiGetScriptFromHash)?;
|
||||
return Err(Error::ScriptBlocked(script.map(|s|s.ID)));
|
||||
let script=self.scripts.get_from_hash(
|
||||
hash,
|
||||
).await.map_err(Error::ApiGetScriptFromHash)?;
|
||||
return Err(Error::ScriptBlocked(script.map(|s|ScriptID(s.id))));
|
||||
},
|
||||
None
|
||||
|Some(Policy::None)
|
||||
|Some(OwnedPolicy::None)
|
||||
=>{
|
||||
let hash=hash_source(source.as_str());
|
||||
let script=self.api.get_script_from_hash(submissions_api::types::HashRequest{
|
||||
hash:hash.as_str(),
|
||||
}).await.map_err(Error::ApiGetScriptFromHash)?;
|
||||
return Err(Error::ScriptNotYetReviewed(script.map(|s|s.ID)));
|
||||
let script=self.scripts.get_from_hash(
|
||||
hash,
|
||||
).await.map_err(Error::ApiGetScriptFromHash)?;
|
||||
return Err(Error::ScriptNotYetReviewed(script.map(|s|ScriptID(s.id))));
|
||||
},
|
||||
Some(Policy::Allowed)=>(),
|
||||
Some(Policy::Delete)=>{
|
||||
Some(OwnedPolicy::Allowed)=>(),
|
||||
Some(OwnedPolicy::Delete)=>{
|
||||
modified=true;
|
||||
// delete script
|
||||
dom.destroy(script_ref);
|
||||
},
|
||||
Some(Policy::Replace(replacement))=>{
|
||||
Some(OwnedPolicy::Replace(replacement))=>{
|
||||
modified=true;
|
||||
*source=replacement.clone();
|
||||
},
|
||||
@@ -278,20 +282,20 @@ impl crate::message_handler::MessageHandler{
|
||||
};
|
||||
|
||||
match validate_info.Resource{
|
||||
Resource::Mapfix(mapfix_id)=>{
|
||||
Resource::Mapfix(MapfixID(mapfix_id))=>{
|
||||
// update the mapfix to use the validated model
|
||||
self.api.update_mapfix_validated_model(submissions_api::types::UpdateMapfixModelRequest{
|
||||
MapfixID:mapfix_id,
|
||||
ModelID:validated_model_id,
|
||||
ModelVersion:validated_model_version,
|
||||
self.mapfixes.set_validated_model(rust_grpc::validator::ValidatedModelRequest{
|
||||
id:mapfix_id,
|
||||
validated_model_id,
|
||||
validated_model_version,
|
||||
}).await.map_err(Error::ApiUpdateMapfixModel)?;
|
||||
},
|
||||
Resource::Submission(submission_id)=>{
|
||||
Resource::Submission(SubmissionID(submission_id))=>{
|
||||
// update the submission to use the validated model
|
||||
self.api.update_submission_validated_model(submissions_api::types::UpdateSubmissionModelRequest{
|
||||
SubmissionID:submission_id,
|
||||
ModelID:validated_model_id,
|
||||
ModelVersion:validated_model_version,
|
||||
self.submissions.set_validated_model(rust_grpc::validator::ValidatedModelRequest{
|
||||
id:submission_id,
|
||||
validated_model_id,
|
||||
validated_model_version,
|
||||
}).await.map_err(Error::ApiUpdateSubmissionModel)?;
|
||||
},
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user