Skip to content

Feat/version2.0 feature merges#97

Merged
lfbrehm merged 44 commits intofeat/version2.0reworkfrom
feat/version2.0_feature_merges
Aug 3, 2023
Merged

Feat/version2.0 feature merges#97
lfbrehm merged 44 commits intofeat/version2.0reworkfrom
feat/version2.0_feature_merges

Conversation

@lfbrehm
Copy link
Copy Markdown
Member

@lfbrehm lfbrehm commented Jul 31, 2023

Summary

This PR contains delete, relations and archive requests.

Delete

  • Resources are updated with object_status = DELETED

Relations

  • The API request ModifyRelations is now implemented

Archive/Snapshot

  • Projects and all resources belonging to the object are updated to dynamic = false
  • Collections/Datasets are cloned with a persistent copy

@lfbrehm lfbrehm requested review from St4NNi and das-Abroxas July 31, 2023 12:31
Copy link
Copy Markdown
Member

@St4NNi St4NNi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good work, one thing i really do not like is iterating over DB requests. We should add get / update requests that take a list and process them all at once.

Vec<InternalRelation>, // outbound relations
Vec<InternalRelation>, // inbound relations
)> {
let outbound = "SELECT * FROM internal_relations
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not a fan, we should combine outbound and inbound to one request:

`SELECT * FROM internal_relations WHERE target_pid = $1 OR origin_pid = $1;

And separate the afterwards, especially since you are iterating over them anyway.

Iterator::partition can be used to get two vectors.

Comment thread src/grpc/collections.rs
"Internal database error"
);

for o in updates {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a fan either, would prefer updating them all at once, with one db request.

Comment thread src/grpc/collections.rs
self.database_handler.snapshot(request).await,
"Internal database error."
);
for resource in &resources {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, for loop for updating sounds not like a good idea.

Comment thread src/grpc/datasets.rs
"Internal database error"
);

for o in updates {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as col.

Comment thread src/grpc/object.rs
"Internal database error"
);

for o in updates {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again updating them all separately is a bad idea

Comment thread src/middlelayer/relations_db_handler.rs Outdated
.remove_external_relation(&transaction_client, external_to_remove)
.await?;
}
for internal_to_remove in labels_to_remove.internal {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for...

client: &Client,
) -> Result<Vec<ObjectWithRelations>> {
let mut result: Vec<ObjectWithRelations> = Vec::new();
for relation in &project.relation_ids {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for ...

for relation in &project.relation_ids {
InternalRelation::archive(relation, client).await?;
}
for resource in &project.resource_ids {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for...

}
for resource in &project.resource_ids {
Object::archive(resource, client).await?;
result.push(Object::get_object_with_relations(resource, client).await?);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updating AND retrieving with two requests in a for loop is really bad

let (mut ids, mut init_in) = InternalRelation::get_all_by_id(project_id, client).await?;
ids.append(&mut init_in);
for id in ids.iter().map(|i| i.id) {
let (outs, ins) = InternalRelation::get_all_by_id(id, client).await?;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

get_all in for loop ?

Copy link
Copy Markdown
Contributor

@das-Abroxas das-Abroxas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some copy & paste things that should be smoothed out before merge.

Comment thread src/grpc/projects.rs Outdated
Comment on lines +136 to +151
let collection_id = tonic_invalid!(request.get_id(), "Invalid project id");
let ctx = Context::res_ctx(collection_id, DbPermissionLevel::WRITE, true);

tonic_auth!(
self.authorizer.check_permissions(&token, vec![ctx]).await,
"Unauthorized"
);

let project = tonic_internal!(
self.database_handler.update_name(request).await,
"Internal database error."
);
self.cache
.update_object(&project.object.id, project.clone());
let project: generic_resource::Resource =
tonic_internal!(project.try_into(), "Collection conversion error");
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy & paste only partially adapted.

Suggested change
let collection_id = tonic_invalid!(request.get_id(), "Invalid project id");
let ctx = Context::res_ctx(collection_id, DbPermissionLevel::WRITE, true);
tonic_auth!(
self.authorizer.check_permissions(&token, vec![ctx]).await,
"Unauthorized"
);
let project = tonic_internal!(
self.database_handler.update_name(request).await,
"Internal database error."
);
self.cache
.update_object(&project.object.id, project.clone());
let project: generic_resource::Resource =
tonic_internal!(project.try_into(), "Collection conversion error");
let project_id = tonic_invalid!(request.get_id(), "Invalid project id");
let ctx = Context::res_ctx(project_id, DbPermissionLevel::WRITE, true);
tonic_auth!(
self.authorizer.check_permissions(&token, vec![ctx]).await,
"Unauthorized"
);
let project = tonic_internal!(
self.database_handler.update_name(request).await,
"Internal database error."
);
self.cache
.update_object(&project.object.id, project.clone());
let project: generic_resource::Resource =
tonic_internal!(project.try_into(), "Project conversion error");

Comment thread src/grpc/projects.rs Outdated
Comment on lines +168 to +184
let request = DescriptionUpdate::Project(request.into_inner());
let collection_id = tonic_invalid!(request.get_id(), "Invalid project id");
let ctx = Context::res_ctx(collection_id, DbPermissionLevel::WRITE, true);

tonic_auth!(
self.authorizer.check_permissions(&token, vec![ctx]).await,
"Unauthorized"
);

let project = tonic_internal!(
self.database_handler.update_description(request).await,
"Internal database error."
);
self.cache
.update_object(&project.object.id, project.clone());
let project: generic_resource::Resource =
tonic_internal!(project.try_into(), "Collection conversion error");
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy & paste only partially adapted.

Suggested change
let request = DescriptionUpdate::Project(request.into_inner());
let collection_id = tonic_invalid!(request.get_id(), "Invalid project id");
let ctx = Context::res_ctx(collection_id, DbPermissionLevel::WRITE, true);
tonic_auth!(
self.authorizer.check_permissions(&token, vec![ctx]).await,
"Unauthorized"
);
let project = tonic_internal!(
self.database_handler.update_description(request).await,
"Internal database error."
);
self.cache
.update_object(&project.object.id, project.clone());
let project: generic_resource::Resource =
tonic_internal!(project.try_into(), "Collection conversion error");
let request = DescriptionUpdate::Project(request.into_inner());
let project_id = tonic_invalid!(request.get_id(), "Invalid project id");
let ctx = Context::res_ctx(project_id, DbPermissionLevel::WRITE, true);
tonic_auth!(
self.authorizer.check_permissions(&token, vec![ctx]).await,
"Unauthorized"
);
let project = tonic_internal!(
self.database_handler.update_description(request).await,
"Internal database error."
);
self.cache
.update_object(&project.object.id, project.clone());
let project: generic_resource::Resource =
tonic_internal!(project.try_into(), "Project conversion error");

Comment thread src/grpc/projects.rs Outdated
Comment on lines +203 to +218
let collection_id = tonic_invalid!(request.get_id(), "Invalid project id");
let ctx = Context::res_ctx(collection_id, DbPermissionLevel::WRITE, true);

tonic_auth!(
self.authorizer.check_permissions(&token, vec![ctx]).await,
"Unauthorized"
);

let project = tonic_internal!(
self.database_handler.update_keyvals(request).await,
"Internal database error."
);
self.cache
.update_object(&project.object.id, project.clone());
let project: generic_resource::Resource =
tonic_internal!(project.try_into(), "Collection conversion error");
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy & paste only partially adapted.

Suggested change
let collection_id = tonic_invalid!(request.get_id(), "Invalid project id");
let ctx = Context::res_ctx(collection_id, DbPermissionLevel::WRITE, true);
tonic_auth!(
self.authorizer.check_permissions(&token, vec![ctx]).await,
"Unauthorized"
);
let project = tonic_internal!(
self.database_handler.update_keyvals(request).await,
"Internal database error."
);
self.cache
.update_object(&project.object.id, project.clone());
let project: generic_resource::Resource =
tonic_internal!(project.try_into(), "Collection conversion error");
let project_id = tonic_invalid!(request.get_id(), "Invalid project id");
let ctx = Context::res_ctx(project_id, DbPermissionLevel::WRITE, true);
tonic_auth!(
self.authorizer.check_permissions(&token, vec![ctx]).await,
"Unauthorized"
);
let project = tonic_internal!(
self.database_handler.update_keyvals(request).await,
"Internal database error."
);
self.cache
.update_object(&project.object.id, project.clone());
let project: generic_resource::Resource =
tonic_internal!(project.try_into(), "Project conversion error");

Comment thread src/grpc/projects.rs Outdated
Comment on lines +237 to +252
let collection_id = tonic_invalid!(request.get_id(), "Invalid project id");
let ctx = Context::res_ctx(collection_id, DbPermissionLevel::WRITE, true);

tonic_auth!(
self.authorizer.check_permissions(&token, vec![ctx]).await,
"Unauthorized"
);

let project = tonic_internal!(
self.database_handler.update_dataclass(request).await,
"Internal database error."
);
self.cache
.update_object(&project.object.id, project.clone());
let project: generic_resource::Resource =
tonic_internal!(project.try_into(), "Collection conversion error");
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy & paste only partially adapted.

Suggested change
let collection_id = tonic_invalid!(request.get_id(), "Invalid project id");
let ctx = Context::res_ctx(collection_id, DbPermissionLevel::WRITE, true);
tonic_auth!(
self.authorizer.check_permissions(&token, vec![ctx]).await,
"Unauthorized"
);
let project = tonic_internal!(
self.database_handler.update_dataclass(request).await,
"Internal database error."
);
self.cache
.update_object(&project.object.id, project.clone());
let project: generic_resource::Resource =
tonic_internal!(project.try_into(), "Collection conversion error");
let project_id = tonic_invalid!(request.get_id(), "Invalid project id");
let ctx = Context::res_ctx(project_id, DbPermissionLevel::WRITE, true);
tonic_auth!(
self.authorizer.check_permissions(&token, vec![ctx]).await,
"Unauthorized"
);
let project = tonic_internal!(
self.database_handler.update_dataclass(request).await,
"Internal database error."
);
self.cache
.update_object(&project.object.id, project.clone());
let project: generic_resource::Resource =
tonic_internal!(project.try_into(), "Project conversion error");

Comment thread src/grpc/projects.rs Outdated
Comment on lines +270 to +289
let project_id = tonic_invalid!(request.get_id(), "Invalid dataset id.");
let ctx = Context::res_ctx(project_id, DbPermissionLevel::ADMIN, true);

tonic_auth!(
self.authorizer.check_permissions(&token, vec![ctx]).await,
"Unauthorized"
);

// this only contains one entry with a dataset
let resources = tonic_internal!(
self.database_handler.snapshot(request).await,
"Internal database error."
);
for resource in &resources {
self.cache
.update_object(&resource.object.id, resource.clone());
}
let project: generic_resource::Resource =
// First entry is always the archived project
tonic_internal!(resources[0].clone().try_into(), "Dataset conversion error");
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy & paste only partially adapted.

Suggested change
let project_id = tonic_invalid!(request.get_id(), "Invalid dataset id.");
let ctx = Context::res_ctx(project_id, DbPermissionLevel::ADMIN, true);
tonic_auth!(
self.authorizer.check_permissions(&token, vec![ctx]).await,
"Unauthorized"
);
// this only contains one entry with a dataset
let resources = tonic_internal!(
self.database_handler.snapshot(request).await,
"Internal database error."
);
for resource in &resources {
self.cache
.update_object(&resource.object.id, resource.clone());
}
let project: generic_resource::Resource =
// First entry is always the archived project
tonic_internal!(resources[0].clone().try_into(), "Dataset conversion error");
let project_id = tonic_invalid!(request.get_id(), "Invalid project id");
let ctx = Context::res_ctx(project_id, DbPermissionLevel::ADMIN, true);
tonic_auth!(
self.authorizer.check_permissions(&token, vec![ctx]).await,
"Unauthorized"
);
// This contains all the resources the snapshot includes below the project
let resources = tonic_internal!(
self.database_handler.snapshot(request).await,
"Internal database error."
);
for resource in &resources {
self.cache
.update_object(&resource.object.id, resource.clone());
}
let project: generic_resource::Resource =
// First entry is always the archived project
tonic_internal!(resources[0].clone().try_into(), "Project conversion error");

Comment thread src/grpc/collections.rs Outdated
Comment on lines +314 to +333
let collection_id = tonic_invalid!(request.get_id(), "Invalid dataset id.");
let ctx = Context::res_ctx(collection_id, DbPermissionLevel::ADMIN, true);

tonic_auth!(
self.authorizer.check_permissions(&token, vec![ctx]).await,
"Unauthorized"
);

// this only contains one entry with a dataset
let resources = tonic_internal!(
self.database_handler.snapshot(request).await,
"Internal database error."
);
for resource in &resources {
self.cache
.update_object(&resource.object.id, resource.clone());
}
let collection: generic_resource::Resource =
// First entry is always the snapshot collection
tonic_internal!(resources[0].clone().try_into(), "Dataset conversion error");
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy & paste only partially adapted.

Suggested change
let collection_id = tonic_invalid!(request.get_id(), "Invalid dataset id.");
let ctx = Context::res_ctx(collection_id, DbPermissionLevel::ADMIN, true);
tonic_auth!(
self.authorizer.check_permissions(&token, vec![ctx]).await,
"Unauthorized"
);
// this only contains one entry with a dataset
let resources = tonic_internal!(
self.database_handler.snapshot(request).await,
"Internal database error."
);
for resource in &resources {
self.cache
.update_object(&resource.object.id, resource.clone());
}
let collection: generic_resource::Resource =
// First entry is always the snapshot collection
tonic_internal!(resources[0].clone().try_into(), "Dataset conversion error");
let collection_id = tonic_invalid!(request.get_id(), "Invalid collection id.");
let ctx = Context::res_ctx(collection_id, DbPermissionLevel::ADMIN, true);
tonic_auth!(
self.authorizer.check_permissions(&token, vec![ctx]).await,
"Unauthorized"
);
// This contains all resources the snapshot includes below the collection
let resources = tonic_internal!(
self.database_handler.snapshot(request).await,
"Internal database error."
);
for resource in &resources {
self.cache
.update_object(&resource.object.id, resource.clone());
}
let collection: generic_resource::Resource =
// First entry is always the snapshot collection
tonic_internal!(resources[0].clone().try_into(), "Collection conversion error");

@codecov
Copy link
Copy Markdown

codecov Bot commented Jul 31, 2023

Codecov Report

Patch coverage: 20.92% and project coverage change: +3.26% 🎉

Comparison is base (b3377d2) 17.96% compared to head (83a30b6) 21.23%.
Report is 1 commits behind head on feat/version2.0rework.

Additional details and impacted files
@@                    Coverage Diff                    @@
##           feat/version2.0rework      #97      +/-   ##
=========================================================
+ Coverage                  17.96%   21.23%   +3.26%     
=========================================================
  Files                         36       43       +7     
  Lines                       3022     3758     +736     
=========================================================
+ Hits                         543      798     +255     
- Misses                      2479     2960     +481     
Files Changed Coverage Δ
src/auth/permission_handler.rs 0.00% <0.00%> (ø)
src/auth/structs.rs 0.00% <0.00%> (ø)
src/auth/token_handler.rs 0.00% <0.00%> (ø)
src/grpc/collections.rs 0.00% <0.00%> (ø)
src/grpc/datasets.rs 0.00% <0.00%> (ø)
src/grpc/notification.rs 0.00% <0.00%> (ø)
src/grpc/object.rs 0.00% <0.00%> (ø)
src/grpc/projects.rs 0.00% <0.00%> (ø)
src/grpc/relations.rs 0.00% <0.00%> (ø)
src/macros.rs 14.28% <ø> (ø)
... and 18 more

... and 2 files with indirect coverage changes

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@St4NNi St4NNi requested review from St4NNi and das-Abroxas August 3, 2023 08:47
Copy link
Copy Markdown
Member

@St4NNi St4NNi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, additions for now LGTM. This will surely be modified in further developments.

@lfbrehm lfbrehm merged commit 931b4c9 into feat/version2.0rework Aug 3, 2023
@lfbrehm lfbrehm deleted the feat/version2.0_feature_merges branch August 3, 2023 09:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants