[task] Wrap types for Task fields (#284)
diff --git a/services/management/enclave/src/service.rs b/services/management/enclave/src/service.rs
index 7fd767a..fd5fac1 100644
--- a/services/management/enclave/src/service.rs
+++ b/services/management/enclave/src/service.rs
@@ -38,9 +38,9 @@
use teaclave_rpc::Request;
use teaclave_service_enclave_utils::{ensure, teaclave_service};
use teaclave_types::{
- ExternalID, FileCrypto, Function, FunctionInputFile, FunctionOutputFile, OwnerList, StagedTask,
- Storable, Task, TaskStatus, TeaclaveInputFile, TeaclaveOutputFile,
- TeaclaveServiceResponseError, TeaclaveServiceResponseResult, UserID,
+ ExternalID, FileCrypto, Function, OwnerList, StagedTask, Storable, Task, TaskStatus,
+ TeaclaveInputFile, TeaclaveOutputFile, TeaclaveServiceResponseError,
+ TeaclaveServiceResponseResult, UserID,
};
use thiserror::Error;
use url::Url;
@@ -272,8 +272,8 @@
user_id,
request.executor,
request.function_arguments,
- request.input_owners_map,
- request.output_owners_map,
+ request.inputs_ownership,
+ request.outputs_ownership,
function,
)
.map_err(|_| ServiceError::BadTask)?;
@@ -310,12 +310,12 @@
function_id: task.function_id,
function_owner: task.function_owner,
function_arguments: task.function_arguments,
- input_owners_map: task.input_owners_map,
- output_owners_map: task.output_owners_map,
+ inputs_ownership: task.inputs_ownership,
+ outputs_ownership: task.outputs_ownership,
participants: task.participants,
approved_users: task.approved_users,
- input_map: task.input_map,
- output_map: task.output_map,
+ assigned_inputs: task.assigned_inputs.external_ids(),
+ assigned_outputs: task.assigned_outputs.external_ids(),
result: task.result,
status: task.status,
};
@@ -329,7 +329,7 @@
// * input file: user_id == input_file.owner contains user_id
// * output file: output_file.owner contains user_id && output_file.cmac.is_none()
// 4) the data can be assgined to the task:
- // * input_owners_map or output_owners_map contains the data name
+ // * inputs_ownership or outputs_ownership contains the data name
// * input file: OwnerList match input_file.owner
// * output file: OwnerList match output_file.owner
fn assign_data(
@@ -349,19 +349,19 @@
ServiceError::PermissionDenied
);
- for (data_name, data_id) in request.input_map.iter() {
+ for (data_name, data_id) in request.inputs.iter() {
let file: TeaclaveInputFile = self
.read_from_db(&data_id)
.map_err(|_| ServiceError::PermissionDenied)?;
- task.assign_input(&user_id, data_name, &file)
+ task.assign_input(&user_id, data_name, file)
.map_err(|_| ServiceError::PermissionDenied)?;
}
- for (data_name, data_id) in request.output_map.iter() {
+ for (data_name, data_id) in request.outputs.iter() {
let file: TeaclaveOutputFile = self
.read_from_db(&data_id)
.map_err(|_| ServiceError::PermissionDenied)?;
- task.assign_output(&user_id, data_name, &file)
+ task.assign_output(&user_id, data_name, file)
.map_err(|_| ServiceError::PermissionDenied)?;
}
@@ -427,26 +427,7 @@
log::info!("InvokeTask: get function: {:?}", function);
- let mut input_map: HashMap<String, FunctionInputFile> = HashMap::new();
- for (data_name, data_id) in task.input_map.iter() {
- let input_file: TeaclaveInputFile = self
- .read_from_db(&data_id)
- .map_err(|_| ServiceError::PermissionDenied)?;
- let input_data = FunctionInputFile::from_teaclave_input_file(&input_file);
- input_map.insert(data_name.to_string(), input_data);
- }
-
- let mut output_map: HashMap<String, FunctionOutputFile> = HashMap::new();
- for (data_name, data_id) in task.output_map.iter() {
- let output_file: TeaclaveOutputFile = self
- .read_from_db(&data_id)
- .map_err(|_| ServiceError::PermissionDenied)?;
- ensure!(output_file.cmac.is_none(), ServiceError::PermissionDenied);
- let output_data = FunctionOutputFile::from_teaclave_output_file(&output_file);
- output_map.insert(data_name.to_string(), output_data);
- }
-
- let staged_task = task.stage_for_running(&user_id, function, input_map, output_map)?;
+ let staged_task = task.stage_for_running(&user_id, function)?;
log::info!("InvokeTask: staged task: {:?}", staged_task);
@@ -602,7 +583,7 @@
use std::collections::HashMap;
use teaclave_types::{
hashmap, Executor, FileAuthTag, FileCrypto, FunctionArguments, FunctionInput,
- FunctionOutput,
+ FunctionInputFile, FunctionOutput, FunctionOutputFile,
};
use url::Url;
diff --git a/services/proto/src/proto/teaclave_frontend_service.proto b/services/proto/src/proto/teaclave_frontend_service.proto
index 3957b1e..6a3dcb3 100644
--- a/services/proto/src/proto/teaclave_frontend_service.proto
+++ b/services/proto/src/proto/teaclave_frontend_service.proto
@@ -112,8 +112,8 @@
string function_id = 1;
map<string, string> function_arguments = 2;
string executor = 3;
- repeated OwnerList input_owners_map = 10;
- repeated OwnerList output_owners_map = 11;
+ repeated OwnerList inputs_ownership = 10;
+ repeated OwnerList outputs_ownership= 11;
}
message CreateTaskResponse {
@@ -130,20 +130,20 @@
string function_id = 3;
string function_owner = 4;
map<string, string> function_arguments = 5;
- repeated OwnerList input_owners_map = 6;
- repeated OwnerList output_owners_map = 7;
+ repeated OwnerList inputs_ownership = 6;
+ repeated OwnerList outputs_ownership = 7;
repeated string participants = 8;
repeated string approved_users = 9;
- repeated DataMap input_map = 10;
- repeated DataMap output_map = 11;
+ repeated DataMap assigned_inputs = 10;
+ repeated DataMap assigned_outputs = 11;
teaclave_common_proto.TaskStatus status = 20;
teaclave_common_proto.TaskResult result = 21;
}
message AssignDataRequest {
string task_id = 1;
- repeated DataMap input_map = 2;
- repeated DataMap output_map = 3;
+ repeated DataMap inputs = 2;
+ repeated DataMap outputs = 3;
}
message AssignDataResponse { }
diff --git a/services/proto/src/teaclave_frontend_service.rs b/services/proto/src/teaclave_frontend_service.rs
index 9ca53ff..cf36589 100644
--- a/services/proto/src/teaclave_frontend_service.rs
+++ b/services/proto/src/teaclave_frontend_service.rs
@@ -27,7 +27,8 @@
use teaclave_rpc::into_request;
use teaclave_types::{
Executor, ExecutorType, ExternalID, FileAuthTag, FileCrypto, Function, FunctionArguments,
- FunctionInput, FunctionOutput, OwnerList, TaskResult, TaskStatus, UserID, UserList,
+ FunctionInput, FunctionOutput, OwnerList, TaskFileOwners, TaskResult, TaskStatus, UserID,
+ UserList,
};
use url::Url;
use uuid::Uuid;
@@ -342,8 +343,8 @@
pub function_id: ExternalID,
pub function_arguments: FunctionArguments,
pub executor: Executor,
- pub input_owners_map: HashMap<String, OwnerList>,
- pub output_owners_map: HashMap<String, OwnerList>,
+ pub inputs_ownership: TaskFileOwners,
+ pub outputs_ownership: TaskFileOwners,
}
impl CreateTaskRequest {
@@ -372,16 +373,16 @@
}
}
- pub fn input_owners_map(self, map: HashMap<String, OwnerList>) -> Self {
+ pub fn inputs_ownership(self, map: impl Into<TaskFileOwners>) -> Self {
Self {
- input_owners_map: map,
+ inputs_ownership: map.into(),
..self
}
}
- pub fn output_owners_map(self, map: HashMap<String, OwnerList>) -> Self {
+ pub fn outputs_ownership(self, map: impl Into<TaskFileOwners>) -> Self {
Self {
- output_owners_map: map,
+ outputs_ownership: map.into(),
..self
}
}
@@ -420,12 +421,12 @@
pub function_id: ExternalID,
pub function_owner: UserID,
pub function_arguments: FunctionArguments,
- pub input_owners_map: HashMap<String, OwnerList>,
- pub output_owners_map: HashMap<String, OwnerList>,
+ pub inputs_ownership: TaskFileOwners,
+ pub outputs_ownership: TaskFileOwners,
pub participants: UserList,
pub approved_users: UserList,
- pub input_map: HashMap<String, ExternalID>,
- pub output_map: HashMap<String, ExternalID>,
+ pub assigned_inputs: HashMap<String, ExternalID>,
+ pub assigned_outputs: HashMap<String, ExternalID>,
pub status: TaskStatus,
pub result: TaskResult,
}
@@ -435,20 +436,20 @@
#[derive(Debug)]
pub struct AssignDataRequest {
pub task_id: ExternalID,
- pub input_map: HashMap<String, ExternalID>,
- pub output_map: HashMap<String, ExternalID>,
+ pub inputs: HashMap<String, ExternalID>,
+ pub outputs: HashMap<String, ExternalID>,
}
impl AssignDataRequest {
pub fn new(
task_id: ExternalID,
- input_map: HashMap<String, ExternalID>,
- output_map: HashMap<String, ExternalID>,
+ inputs: HashMap<String, ExternalID>,
+ outputs: HashMap<String, ExternalID>,
) -> Self {
Self {
task_id,
- input_map,
- output_map,
+ inputs,
+ outputs,
}
}
}
@@ -936,29 +937,21 @@
}
}
-pub fn data_owner_map_from_proto(
- vector: Vec<proto::OwnerList>,
-) -> Result<HashMap<String, OwnerList>> {
- let mut ret = HashMap::with_capacity(vector.len());
- for item in vector.into_iter() {
- let owner_list = item.uids.into();
- ret.insert(item.data_name, owner_list);
- }
- Ok(ret)
+fn from_proto_ownership(proto: Vec<proto::OwnerList>) -> TaskFileOwners {
+ proto
+ .into_iter()
+ .map(|ol| (ol.data_name, ol.uids))
+ .collect()
}
-pub fn data_owner_map_to_proto<S: std::hash::BuildHasher>(
- map: HashMap<String, OwnerList, S>,
-) -> Vec<proto::OwnerList> {
- let mut ret = Vec::with_capacity(map.len());
- for (data_name, owner_list) in map.into_iter() {
- let owner_list = proto::OwnerList {
- data_name,
- uids: owner_list.into(),
- };
- ret.push(owner_list);
- }
- ret
+fn to_proto_ownership(ownership: TaskFileOwners) -> Vec<proto::OwnerList> {
+ ownership
+ .into_iter()
+ .map(|(name, ol)| proto::OwnerList {
+ data_name: name,
+ uids: ol.into(),
+ })
+ .collect()
}
impl std::convert::TryFrom<proto::CreateTaskRequest> for CreateTaskRequest {
@@ -966,8 +959,8 @@
fn try_from(proto: proto::CreateTaskRequest) -> Result<Self> {
let function_arguments = proto.function_arguments.into();
- let input_owners_map = data_owner_map_from_proto(proto.input_owners_map)?;
- let output_owners_map = data_owner_map_from_proto(proto.output_owners_map)?;
+ let inputs_ownership = from_proto_ownership(proto.inputs_ownership);
+ let outputs_ownership = from_proto_ownership(proto.outputs_ownership);
let function_id = proto.function_id.try_into()?;
let executor = proto.executor.try_into()?;
@@ -975,8 +968,8 @@
function_id,
function_arguments,
executor,
- input_owners_map,
- output_owners_map,
+ inputs_ownership,
+ outputs_ownership,
};
Ok(ret)
}
@@ -985,15 +978,15 @@
impl From<CreateTaskRequest> for proto::CreateTaskRequest {
fn from(request: CreateTaskRequest) -> Self {
let function_arguments = request.function_arguments.into();
- let input_owners_map = data_owner_map_to_proto(request.input_owners_map);
- let output_owners_map = data_owner_map_to_proto(request.output_owners_map);
+ let inputs_ownership = to_proto_ownership(request.inputs_ownership);
+ let outputs_ownership = to_proto_ownership(request.outputs_ownership);
Self {
function_id: request.function_id.to_string(),
function_arguments,
executor: request.executor.to_string(),
- input_owners_map,
- output_owners_map,
+ inputs_ownership,
+ outputs_ownership,
}
}
}
@@ -1017,25 +1010,25 @@
}
}
-fn data_map_to_proto(map: HashMap<String, ExternalID>) -> Vec<proto::DataMap> {
- let mut ret = Vec::with_capacity(map.len());
- for (data_name, data_id) in map.into_iter() {
- let data_map = proto::DataMap {
- data_name,
- data_id: data_id.to_string(),
- };
- ret.push(data_map);
- }
- ret
+fn to_proto_file_ids(map: HashMap<String, ExternalID>) -> Vec<proto::DataMap> {
+ map.into_iter()
+ .map(|(name, ext_id)| proto::DataMap {
+ data_name: name,
+ data_id: ext_id.to_string(),
+ })
+ .collect()
}
-fn data_map_from_proto(vector: Vec<proto::DataMap>) -> Result<HashMap<String, ExternalID>> {
- let mut ret = HashMap::with_capacity(vector.len());
- for item in vector.into_iter() {
- let data_id = item.data_id.try_into()?;
- ret.insert(item.data_name, data_id);
- }
- Ok(ret)
+fn from_proto_file_ids(vector: Vec<proto::DataMap>) -> Result<HashMap<String, ExternalID>> {
+ vector
+ .into_iter()
+ .map(|item| {
+ item.data_id
+ .clone()
+ .try_into()
+ .map(|ext_id| (item.data_name, ext_id))
+ })
+ .collect()
}
impl std::convert::TryFrom<proto::GetTaskRequest> for GetTaskRequest {
@@ -1062,10 +1055,10 @@
fn try_from(proto: proto::GetTaskResponse) -> Result<Self> {
let function_arguments = proto.function_arguments.into();
- let input_owners_map = data_owner_map_from_proto(proto.input_owners_map)?;
- let output_owners_map = data_owner_map_from_proto(proto.output_owners_map)?;
- let input_map = data_map_from_proto(proto.input_map)?;
- let output_map = data_map_from_proto(proto.output_map)?;
+ let inputs_ownership = from_proto_ownership(proto.inputs_ownership);
+ let outputs_ownership = from_proto_ownership(proto.outputs_ownership);
+ let assigned_inputs = from_proto_file_ids(proto.assigned_inputs)?;
+ let assigned_outputs = from_proto_file_ids(proto.assigned_outputs)?;
let status = i32_to_task_status(proto.status)?;
let function_id = proto.function_id.try_into()?;
let task_id = proto.task_id.try_into()?;
@@ -1077,12 +1070,12 @@
function_id,
function_owner: proto.function_owner.into(),
function_arguments,
- input_owners_map,
- output_owners_map,
+ inputs_ownership,
+ outputs_ownership,
participants: UserList::new(proto.participants),
approved_users: UserList::new(proto.approved_users),
- input_map,
- output_map,
+ assigned_inputs,
+ assigned_outputs,
status,
result,
};
@@ -1094,10 +1087,10 @@
impl From<GetTaskResponse> for proto::GetTaskResponse {
fn from(response: GetTaskResponse) -> Self {
let function_arguments = response.function_arguments.into();
- let input_owners_map = data_owner_map_to_proto(response.input_owners_map);
- let output_owners_map = data_owner_map_to_proto(response.output_owners_map);
- let input_map = data_map_to_proto(response.input_map);
- let output_map = data_map_to_proto(response.output_map);
+ let inputs_ownership = to_proto_ownership(response.inputs_ownership);
+ let outputs_ownership = to_proto_ownership(response.outputs_ownership);
+ let assigned_inputs = to_proto_file_ids(response.assigned_inputs);
+ let assigned_outputs = to_proto_file_ids(response.assigned_outputs);
let status = i32_from_task_status(response.status);
Self {
task_id: response.task_id.to_string(),
@@ -1105,12 +1098,12 @@
function_id: response.function_id.to_string(),
function_owner: response.function_owner.to_string(),
function_arguments,
- input_owners_map,
- output_owners_map,
+ inputs_ownership,
+ outputs_ownership,
participants: response.participants.into(),
approved_users: response.approved_users.into(),
- input_map,
- output_map,
+ assigned_inputs,
+ assigned_outputs,
status,
result: Some(response.result.into()),
}
@@ -1121,13 +1114,13 @@
type Error = Error;
fn try_from(proto: proto::AssignDataRequest) -> Result<Self> {
- let input_map = data_map_from_proto(proto.input_map)?;
- let output_map = data_map_from_proto(proto.output_map)?;
+ let inputs = from_proto_file_ids(proto.inputs)?;
+ let outputs = from_proto_file_ids(proto.outputs)?;
let task_id = proto.task_id.try_into()?;
let ret = Self {
task_id,
- input_map,
- output_map,
+ inputs,
+ outputs,
};
Ok(ret)
@@ -1136,12 +1129,12 @@
impl From<AssignDataRequest> for proto::AssignDataRequest {
fn from(request: AssignDataRequest) -> Self {
- let input_map = data_map_to_proto(request.input_map);
- let output_map = data_map_to_proto(request.output_map);
+ let inputs = to_proto_file_ids(request.inputs);
+ let outputs = to_proto_file_ids(request.outputs);
Self {
task_id: request.task_id.to_string(),
- input_map,
- output_map,
+ inputs,
+ outputs,
}
}
}
diff --git a/services/scheduler/enclave/src/service.rs b/services/scheduler/enclave/src/service.rs
index fd8a438..01a88c9 100644
--- a/services/scheduler/enclave/src/service.rs
+++ b/services/scheduler/enclave/src/service.rs
@@ -30,7 +30,7 @@
use teaclave_rpc::Request;
use teaclave_service_enclave_utils::teaclave_service;
use teaclave_types::{
- ExternalID, OutputsTags, StagedTask, Storable, Task, TaskResult, TaskStatus,
+ ExternalID, OutputsTags, StagedTask, Storable, Task, TaskFiles, TaskResult, TaskStatus,
TeaclaveOutputFile, TeaclaveServiceResponseError, TeaclaveServiceResponseResult,
};
use uuid::Uuid;
@@ -127,26 +127,6 @@
.put(put_request)?;
Ok(())
}
-
- fn update_outputs_cmac(
- &self,
- task_output_map: &HashMap<String, ExternalID>,
- tags_map: &OutputsTags,
- ) -> Result<()> {
- anyhow::ensure!(
- task_output_map.len() == tags_map.len(),
- "Error: task result output tags count"
- );
- for (key, id) in task_output_map.iter() {
- let mut outfile: TeaclaveOutputFile = self.get_from_db(id)?;
- let auth_tag = tags_map
- .get(key)
- .ok_or_else(|| anyhow::anyhow!("Missing result in task result outpt tags"))?;
- outfile.assign_cmac(auth_tag)?;
- self.put_into_db(&outfile)?;
- }
- Ok(())
- }
}
impl TeaclaveScheduler for TeaclaveSchedulerService {
@@ -207,7 +187,10 @@
let mut task = self.get_task(&request.task_id)?;
if let TaskResult::Ok(outputs) = &request.task_result {
- self.update_outputs_cmac(&task.output_map, &outputs.tags_map)?;
+ for (key, auth_tag) in outputs.tags_map.iter() {
+ let outfile = task.assigned_outputs.update_cmac(key, auth_tag)?;
+ self.put_into_db(outfile)?;
+ }
};
// Updating task result means we have finished execution
diff --git a/tests/functional/enclave/src/end_to_end/builtin_gbdt_train.rs b/tests/functional/enclave/src/end_to_end/builtin_gbdt_train.rs
index 86258ee..2eae2bf 100644
--- a/tests/functional/enclave/src/end_to_end/builtin_gbdt_train.rs
+++ b/tests/functional/enclave/src/end_to_end/builtin_gbdt_train.rs
@@ -117,8 +117,8 @@
"loss" => "LAD",
"training_optimization_level" => "2"
))
- .input_owners_map(hashmap!("training_data" => vec![USERNAME]))
- .output_owners_map(hashmap!("trained_model" => vec![USERNAME]));
+ .inputs_ownership(hashmap!("training_data" => vec![USERNAME]))
+ .outputs_ownership(hashmap!("trained_model" => vec![USERNAME]));
let response = client.create_task(request).unwrap();
log::info!("Create task: {:?}", response);
diff --git a/tests/functional/enclave/src/end_to_end/mesapy_data_fusion.rs b/tests/functional/enclave/src/end_to_end/mesapy_data_fusion.rs
index 327ffd5..0630ef5 100644
--- a/tests/functional/enclave/src/end_to_end/mesapy_data_fusion.rs
+++ b/tests/functional/enclave/src/end_to_end/mesapy_data_fusion.rs
@@ -97,11 +97,11 @@
) -> ExternalID {
let request = CreateTaskRequest::new()
.function_id(function_id.to_owned())
- .input_owners_map(hashmap!(
+ .inputs_ownership(hashmap!(
"InPartyA" => vec![USERNAME1],
"InPartyB" => vec![USERNAME2]
))
- .output_owners_map(hashmap!("OutFusionData" => vec![USERNAME1, USERNAME2]))
+ .outputs_ownership(hashmap!("OutFusionData" => vec![USERNAME1, USERNAME2]))
.executor(Executor::MesaPy);
let response = client.create_task(request).unwrap();
log::info!("Create task: {:?}", response);
@@ -175,8 +175,8 @@
let task = get_task(&mut c2, &task_id);
assert!(task.status == TaskStatus::Finished);
- let fusion_id = task.output_map.get("OutFusionData").unwrap();
- let fusion_owners = task.output_owners_map.get("OutFusionData").unwrap();
+ let fusion_id = task.assigned_outputs.get("OutFusionData").unwrap();
+ let fusion_owners = task.outputs_ownership.get("OutFusionData").unwrap();
let fusion_input = register_fusion_input_from_output(&mut c2, &fusion_id);
let function_id = register_word_count_function(&mut c2);
@@ -251,7 +251,7 @@
let request = CreateTaskRequest::new()
.function_id(function_id.to_owned())
.function_arguments(hashmap!("query" => "teaclave"))
- .input_owners_map(hashmap!(
+ .inputs_ownership(hashmap!(
"InputData" => owners.to_owned()
))
.executor(Executor::MesaPy);
diff --git a/tests/functional/enclave/src/frontend_service.rs b/tests/functional/enclave/src/frontend_service.rs
index 1508c6d..9ec42bf 100644
--- a/tests/functional/enclave/src/frontend_service.rs
+++ b/tests/functional/enclave/src/frontend_service.rs
@@ -163,7 +163,7 @@
.function_id(function_id.clone())
.function_arguments(hashmap!("arg1" => "arg1_value"))
.executor(Executor::MesaPy)
- .output_owners_map(hashmap!("output" => vec!["frontend_user", "mock_user"]));
+ .outputs_ownership(hashmap!("output" => vec!["frontend_user", "mock_user"]));
let response = authorized_client().create_task(request);
assert!(response.is_ok());
@@ -171,7 +171,7 @@
.function_id(function_id)
.function_arguments(hashmap!("arg1" => "arg1_value"))
.executor(Executor::MesaPy)
- .output_owners_map(hashmap!("output" => vec!["frontend_user", "mock_user"]));
+ .outputs_ownership(hashmap!("output" => vec!["frontend_user", "mock_user"]));
let response = unauthorized_client().create_task(request);
assert!(response.is_err());
}
@@ -186,7 +186,7 @@
.function_id(function_id)
.function_arguments(hashmap!("arg1" => "arg1_value"))
.executor(Executor::MesaPy)
- .output_owners_map(hashmap!("output" => vec!["frontend_user", "mock_user"]));
+ .outputs_ownership(hashmap!("output" => vec!["frontend_user", "mock_user"]));
let response = client.create_task(request).unwrap();
let task_id = response.task_id;
@@ -212,7 +212,7 @@
.function_id(function_id)
.function_arguments(hashmap!("arg1" => "arg1_value"))
.executor(Executor::MesaPy)
- .output_owners_map(hashmap!("output" => vec!["frontend_user"]));
+ .outputs_ownership(hashmap!("output" => vec!["frontend_user"]));
let response = client.create_task(request).unwrap();
let task_id = response.task_id;
@@ -247,7 +247,7 @@
.function_id(function_id)
.function_arguments(hashmap!("arg1" => "arg1_value"))
.executor(Executor::MesaPy)
- .output_owners_map(hashmap!("output" => vec!["frontend_user"]));
+ .outputs_ownership(hashmap!("output" => vec!["frontend_user"]));
let response = client.create_task(request).unwrap();
let task_id = response.task_id;
@@ -281,7 +281,7 @@
.function_id(function_id)
.function_arguments(hashmap!("arg1" => "arg1_value"))
.executor(Executor::MesaPy)
- .output_owners_map(hashmap!("output" => vec!["frontend_user"]));
+ .outputs_ownership(hashmap!("output" => vec!["frontend_user"]));
let response = client.create_task(request).unwrap();
let task_id = response.task_id;
diff --git a/tests/functional/enclave/src/management_service.rs b/tests/functional/enclave/src/management_service.rs
index acb0482..cc95f7f 100644
--- a/tests/functional/enclave/src/management_service.rs
+++ b/tests/functional/enclave/src/management_service.rs
@@ -175,7 +175,7 @@
assert!(response.is_ok());
}
-fn valid_create_task_request() -> CreateTaskRequest {
+fn create_valid_task_request() -> CreateTaskRequest {
let function_id =
ExternalID::try_from("function-00000000-0000-0000-0000-000000000001").unwrap();
let input_owners = hashmap!(
@@ -191,8 +191,8 @@
.function_id(function_id)
.function_arguments(hashmap!("arg1" => "data1", "arg2" => "data2"))
.executor(Executor::MesaPy)
- .input_owners_map(input_owners)
- .output_owners_map(output_owners)
+ .inputs_ownership(input_owners)
+ .outputs_ownership(output_owners)
}
#[test_case]
@@ -203,22 +203,26 @@
let response = client.create_task(request);
assert!(response.is_err());
- let request = valid_create_task_request();
+ let request = create_valid_task_request();
let response = client.create_task(request);
assert!(response.is_ok());
- let mut request = valid_create_task_request();
+ let mut request = create_valid_task_request();
request.function_arguments.inner_mut().remove("arg1");
let response = client.create_task(request);
assert!(response.is_err());
- let mut request = valid_create_task_request();
- request.input_owners_map.remove("input");
+ let mut request = create_valid_task_request();
+ request = request.inputs_ownership(hashmap!(
+ "input2" => vec!["mock_user2", "mock_user3"]
+ ));
let response = client.create_task(request);
assert!(response.is_err());
- let mut request = valid_create_task_request();
- request.output_owners_map.remove("output");
+ let mut request = create_valid_task_request();
+ request = request.outputs_ownership(hashmap!(
+ "output2" => vec!["mock_user2", "mock_user3"]
+ ));
let response = client.create_task(request);
assert!(response.is_err());
}
@@ -227,7 +231,7 @@
fn test_get_task() {
let mut client = authorized_client("mock_user");
- let request = valid_create_task_request();
+ let request = create_valid_task_request();
let response = client.create_task(request).unwrap();
let task_id = response.task_id;
@@ -247,7 +251,7 @@
let mut client1 = authorized_client("mock_user1");
let mut client2 = authorized_client("mock_user2");
let mut client3 = authorized_client("mock_user3");
- let request = valid_create_task_request();
+ let request = create_valid_task_request();
let response = client.create_task(request).unwrap();
let task_id = response.task_id;
@@ -312,7 +316,7 @@
let response = client1.assign_data(request);
assert!(response.is_err());
- // input_owners_map doesn't contain the name
+ // inputs_ownership doesn't contain the name
let request = AssignDataRequest::new(
task_id.clone(),
hashmap!("none" => input_file_id_user2.clone()),
@@ -321,7 +325,7 @@
let response = client2.assign_data(request);
assert!(response.is_err());
- // output_owners_map doesn't contain the name
+ // outputs_ownership doesn't contain the name
let request = AssignDataRequest::new(
task_id.clone(),
hashmap!(),
@@ -422,7 +426,7 @@
let mut client1 = authorized_client("mock_user1");
let mut client2 = authorized_client("mock_user2");
let mut client3 = authorized_client("mock_user3");
- let request = valid_create_task_request();
+ let request = create_valid_task_request();
let response = client.create_task(request).unwrap();
let task_id = response.task_id;
@@ -506,7 +510,7 @@
let mut client1 = authorized_client("mock_user1");
let mut client2 = authorized_client("mock_user2");
let mut client3 = authorized_client("mock_user3");
- let request = valid_create_task_request();
+ let request = create_valid_task_request();
let response = client.create_task(request);
assert!(response.is_ok());
let task_id = response.unwrap().task_id;
diff --git a/types/src/file.rs b/types/src/file.rs
index c2185a1..370b399 100644
--- a/types/src/file.rs
+++ b/types/src/file.rs
@@ -30,7 +30,7 @@
Uuid::new_v4()
}
-#[derive(Debug, Deserialize, Serialize)]
+#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct TeaclaveInputFile {
pub url: Url,
pub cmac: FileAuthTag,
@@ -39,7 +39,7 @@
pub uuid: Uuid,
}
-#[derive(Debug, Deserialize, Serialize)]
+#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct TeaclaveOutputFile {
pub url: Url,
pub cmac: Option<FileAuthTag>,
diff --git a/types/src/staged_task.rs b/types/src/staged_task.rs
index 71369c8..6cb930c 100644
--- a/types/src/staged_task.rs
+++ b/types/src/staged_task.rs
@@ -54,9 +54,20 @@
}
}
+impl<V> std::iter::FromIterator<(String, V)> for FunctionInputFiles
+where
+ V: Into<FunctionInputFile>,
+{
+ fn from_iter<T: IntoIterator<Item = (String, V)>>(iter: T) -> Self {
+ FunctionInputFiles {
+ inner: iter.into_iter().map(|(k, v)| (k, v.into())).collect(),
+ }
+ }
+}
+
impl std::convert::From<HashMap<String, FunctionInputFile>> for FunctionInputFiles {
fn from(entries: HashMap<String, FunctionInputFile>) -> FunctionInputFiles {
- FunctionInputFiles { inner: entries }
+ entries.into_iter().collect()
}
}
@@ -74,6 +85,23 @@
}
}
+impl<V> std::iter::FromIterator<(String, V)> for FunctionOutputFiles
+where
+ V: Into<FunctionOutputFile>,
+{
+ fn from_iter<T: IntoIterator<Item = (String, V)>>(iter: T) -> Self {
+ FunctionOutputFiles {
+ inner: iter.into_iter().map(|(k, v)| (k, v.into())).collect(),
+ }
+ }
+}
+
+impl std::convert::From<HashMap<String, FunctionOutputFile>> for FunctionOutputFiles {
+ fn from(entries: HashMap<String, FunctionOutputFile>) -> FunctionOutputFiles {
+ entries.into_iter().collect()
+ }
+}
+
impl FunctionOutputFiles {
pub fn new(entries: HashMap<String, FunctionOutputFile>) -> Self {
entries.into()
@@ -96,12 +124,6 @@
}
}
-impl std::convert::From<HashMap<String, FunctionOutputFile>> for FunctionOutputFiles {
- fn from(entries: HashMap<String, FunctionOutputFile>) -> FunctionOutputFiles {
- FunctionOutputFiles { inner: entries }
- }
-}
-
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct FunctionInputFile {
pub url: Url,
@@ -117,11 +139,13 @@
crypto_info: crypto.into(),
}
}
+}
- pub fn from_teaclave_input_file(file: &TeaclaveInputFile) -> Self {
+impl From<TeaclaveInputFile> for FunctionInputFile {
+ fn from(file: TeaclaveInputFile) -> Self {
Self {
- url: file.url.to_owned(),
- cmac: file.cmac.to_owned(),
+ url: file.url,
+ cmac: file.cmac,
crypto_info: file.crypto_info,
}
}
@@ -140,10 +164,12 @@
crypto_info: crypto.into(),
}
}
+}
- pub fn from_teaclave_output_file(file: &TeaclaveOutputFile) -> Self {
+impl From<TeaclaveOutputFile> for FunctionOutputFile {
+ fn from(file: TeaclaveOutputFile) -> Self {
Self {
- url: file.url.to_owned(),
+ url: file.url,
crypto_info: file.crypto_info,
}
}
diff --git a/types/src/task.rs b/types/src/task.rs
index 6061d38..eb24b5c 100644
--- a/types/src/task.rs
+++ b/types/src/task.rs
@@ -350,6 +350,153 @@
}
}
+#[derive(Debug, Default, Deserialize, Serialize)]
+pub struct TaskFileOwners {
+ inner: HashMap<String, OwnerList>,
+}
+
+impl TaskFileOwners {
+ pub fn all_owners(&self) -> OwnerList {
+ OwnerList::unions(self.inner.values().cloned())
+ }
+
+ pub fn keys(&self) -> std::collections::hash_map::Keys<String, OwnerList> {
+ self.inner.keys()
+ }
+
+ pub fn is_empty(&self) -> bool {
+ self.inner.is_empty()
+ }
+
+ pub fn get(&self, key: &str) -> Option<&OwnerList> {
+ self.inner.get(key)
+ }
+
+ pub fn check(&self, fkey: &str, fowners: &OwnerList) -> Result<()> {
+ match self.inner.get(fkey) {
+ Some(owner_list) => {
+ ensure!(
+ owner_list == fowners,
+ "Assign: file ownership mismatch. {:?}",
+ fkey
+ );
+ }
+ None => bail!("Assign: file name not exist in ownership spec. {:?}", fkey),
+ };
+ Ok(())
+ }
+}
+
+impl<V> std::iter::FromIterator<(String, V)> for TaskFileOwners
+where
+ V: Into<OwnerList>,
+{
+ fn from_iter<T: IntoIterator<Item = (String, V)>>(iter: T) -> Self {
+ TaskFileOwners {
+ inner: HashMap::from_iter(iter.into_iter().map(|(k, v)| (k, v.into()))),
+ }
+ }
+}
+
+impl IntoIterator for TaskFileOwners {
+ type Item = (String, OwnerList);
+ type IntoIter = std::collections::hash_map::IntoIter<String, OwnerList>;
+
+ fn into_iter(self) -> Self::IntoIter {
+ self.inner.into_iter()
+ }
+}
+
+impl std::convert::From<HashMap<String, OwnerList>> for TaskFileOwners {
+ fn from(input: HashMap<String, OwnerList>) -> Self {
+ input.into_iter().collect()
+ }
+}
+
+#[derive(Debug, Clone, Deserialize, Serialize)]
+pub struct TaskFiles<T: Clone> {
+ inner: HashMap<String, T>,
+}
+
+impl<T> Default for TaskFiles<T>
+where
+ T: Clone,
+{
+ fn default() -> TaskFiles<T> {
+ TaskFiles::<T> {
+ inner: HashMap::new(),
+ }
+ }
+}
+
+impl<T> TaskFiles<T>
+where
+ T: Clone + Storable,
+{
+ pub fn assign(&mut self, fname: &str, file: T) -> Result<()> {
+ ensure!(
+ self.inner.get(fname).is_none(),
+ "Assign: file already assigned. {:?}",
+ fname
+ );
+ self.inner.insert(fname.to_owned(), file);
+ Ok(())
+ }
+
+ pub fn keys(&self) -> std::collections::hash_map::Keys<String, T> {
+ self.inner.keys()
+ }
+
+ pub fn external_ids(&self) -> HashMap<String, ExternalID> {
+ self.inner
+ .iter()
+ .map(|(fname, file)| (fname.to_string(), file.external_id()))
+ .collect()
+ }
+}
+
+impl TaskFiles<TeaclaveOutputFile> {
+ pub fn update_cmac(
+ &mut self,
+ fname: &str,
+ auth_tag: &FileAuthTag,
+ ) -> Result<&TeaclaveOutputFile> {
+ let file = match self.inner.get_mut(fname) {
+ Some(file) => {
+ file.assign_cmac(auth_tag)?;
+ file
+ }
+ _ => bail!("Upadate_cmac: file not found. {:?}", fname),
+ };
+
+ Ok(file)
+ }
+}
+
+impl<T> IntoIterator for TaskFiles<T>
+where
+ T: Clone,
+{
+ type Item = (String, T);
+ type IntoIter = std::collections::hash_map::IntoIter<String, T>;
+
+ fn into_iter(self) -> Self::IntoIter {
+ self.inner.into_iter()
+ }
+}
+
+impl std::convert::From<TaskFiles<TeaclaveInputFile>> for FunctionInputFiles {
+ fn from(files: TaskFiles<TeaclaveInputFile>) -> Self {
+ files.into_iter().collect()
+ }
+}
+
+impl std::convert::From<TaskFiles<TeaclaveOutputFile>> for FunctionOutputFiles {
+ fn from(files: TaskFiles<TeaclaveOutputFile>) -> Self {
+ files.into_iter().collect()
+ }
+}
+
const TASK_PREFIX: &str = "task";
#[derive(Debug, Default, Deserialize, Serialize)]
@@ -359,13 +506,13 @@
pub function_id: ExternalID,
pub function_arguments: FunctionArguments,
pub executor: Executor,
- pub input_owners_map: HashMap<String, OwnerList>,
- pub output_owners_map: HashMap<String, OwnerList>,
+ pub inputs_ownership: TaskFileOwners,
+ pub outputs_ownership: TaskFileOwners,
pub function_owner: UserID,
pub participants: UserList,
pub approved_users: UserList,
- pub input_map: HashMap<String, ExternalID>,
- pub output_map: HashMap<String, ExternalID>,
+ pub assigned_inputs: TaskFiles<TeaclaveInputFile>,
+ pub assigned_outputs: TaskFiles<TeaclaveOutputFile>,
pub result: TaskResult,
pub status: TaskStatus,
}
@@ -385,13 +532,16 @@
requester: UserID,
req_executor: Executor,
req_func_args: FunctionArguments,
- req_input_owners: HashMap<String, OwnerList>,
- req_output_owners: HashMap<String, OwnerList>,
+ req_input_owners: impl Into<TaskFileOwners>,
+ req_output_owners: impl Into<TaskFileOwners>,
function: Function,
) -> Result<Self> {
+ let req_input_owners = req_input_owners.into();
+ let req_output_owners = req_output_owners.into();
+
// gather all participants
- let input_owners = UserList::unions(req_input_owners.values().cloned());
- let output_owners = UserList::unions(req_output_owners.values().cloned());
+ let input_owners = req_input_owners.all_owners();
+ let output_owners = req_output_owners.all_owners();
let mut participants = UserList::unions(vec![input_owners, output_owners]);
participants.insert(requester.clone());
if !function.public {
@@ -427,8 +577,8 @@
function_id: function.external_id(),
function_owner: function.owner.clone(),
function_arguments: req_func_args,
- input_owners_map: req_input_owners,
- output_owners_map: req_output_owners,
+ inputs_ownership: req_input_owners,
+ outputs_ownership: req_output_owners,
participants,
status,
..Default::default()
@@ -483,8 +633,6 @@
&mut self,
requester: &UserID,
function: Function,
- input_map: HashMap<String, FunctionInputFile>,
- output_map: HashMap<String, FunctionOutputFile>,
) -> Result<StagedTask> {
ensure!(
&self.creator == requester,
@@ -505,8 +653,8 @@
function_name: function.name,
function_payload: function.payload,
function_arguments,
- input_data: input_map.into(),
- output_data: output_map.into(),
+ input_data: self.assigned_inputs.clone().into(),
+ output_data: self.assigned_outputs.clone().into(),
};
self.update_status(TaskStatus::Staged);
@@ -517,7 +665,7 @@
&mut self,
requester: &UserID,
fname: &str,
- file: &TeaclaveInputFile,
+ file: TeaclaveInputFile,
) -> Result<()> {
ensure!(
self.status == TaskStatus::Created,
@@ -531,27 +679,9 @@
file.external_id()
);
- match self.input_owners_map.get(fname) {
- Some(owner_list) => {
- ensure!(
- owner_list == &file.owner,
- "Assign: file ownership mismatch. {:?}",
- file.external_id()
- );
- }
- None => bail!(
- "Assign: file name not exist in input_owners_map. {:?}",
- fname
- ),
- };
+ self.inputs_ownership.check(fname, &file.owner)?;
- ensure!(
- self.input_map.get(fname).is_none(),
- "Assign: file already assigned. {:?}",
- fname
- );
-
- self.input_map.insert(fname.to_owned(), file.external_id());
+ self.assigned_inputs.assign(fname, file)?;
if self.all_data_assigned() {
self.update_status(TaskStatus::DataAssigned);
@@ -563,7 +693,7 @@
&mut self,
requester: &UserID,
fname: &str,
- file: &TeaclaveOutputFile,
+ file: TeaclaveOutputFile,
) -> Result<()> {
ensure!(
self.status == TaskStatus::Created,
@@ -577,27 +707,9 @@
file.external_id()
);
- match self.output_owners_map.get(fname) {
- Some(owner_list) => {
- ensure!(
- owner_list == &file.owner,
- "Assign: file ownership mismatch. {:?}",
- file.external_id()
- );
- }
- None => bail!(
- "Assign: file name not exist in output_owners_map. {:?}",
- fname
- ),
- };
+ self.outputs_ownership.check(fname, &file.owner)?;
- ensure!(
- self.output_map.get(fname).is_none(),
- "Assign: file already assigned. {:?}",
- fname
- );
-
- self.output_map.insert(fname.to_owned(), file.external_id());
+ self.assigned_outputs.assign(fname, file)?;
if self.all_data_assigned() {
self.update_status(TaskStatus::DataAssigned);
@@ -610,14 +722,14 @@
}
fn all_data_assigned(&self) -> bool {
- let input_args: HashSet<&String> = self.input_owners_map.keys().collect();
- let assiged_inputs: HashSet<&String> = self.input_map.keys().collect();
+ let input_args: HashSet<&String> = self.inputs_ownership.keys().collect();
+ let assiged_inputs: HashSet<&String> = self.assigned_inputs.keys().collect();
if input_args != assiged_inputs {
return false;
}
- let output_args: HashSet<&String> = self.output_owners_map.keys().collect();
- let assiged_outputs: HashSet<&String> = self.output_map.keys().collect();
+ let output_args: HashSet<&String> = self.outputs_ownership.keys().collect();
+ let assiged_outputs: HashSet<&String> = self.assigned_outputs.keys().collect();
if output_args != assiged_outputs {
return false;
}