Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions backend/api/events/sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,7 @@ def _update_datamanager(key: str, data: dict) -> None:

datamanager = DataManager.objects.get(key=key)
datamanager.name = data["name"]
datamanager.archived = data["archived"]
datamanager.save()


Expand Down
19 changes: 19 additions & 0 deletions backend/api/migrations/0041_add_archived_datamanager.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Generated by Django 4.0.7 on 2022-09-27 23:14

from django.db import migrations
from django.db import models


class Migration(migrations.Migration):

dependencies = [
("api", "0040_alter_computeplan_failed_task_category_and_more"),
]

operations = [
migrations.AddField(
model_name="datamanager",
name="archived",
field=models.BooleanField(default=False),
),
]
1 change: 1 addition & 0 deletions backend/api/models/datamanager.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ class DataManager(models.Model, AssetPermissionMixin):
creation_date = models.DateTimeField()
metadata = models.JSONField()
channel = models.CharField(max_length=100)
archived = models.BooleanField(default=False)

def get_train_data_samples(self):
# default ordering is based on an association table `TaskDataSamples`
Expand Down
1 change: 1 addition & 0 deletions backend/api/serializers/datamanager.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class Meta:
"owner",
"permissions",
"type",
"archived",
]

def to_representation(self, instance):
Expand Down
2 changes: 2 additions & 0 deletions backend/api/tests/asset_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,7 @@ def create_datamanager(
owner: str = DEFAULT_OWNER,
channel: str = DEFAULT_CHANNEL,
public: bool = False,
archived: bool = False,
) -> DataManager:
if key is None:
key = uuid.uuid4()
Expand All @@ -285,6 +286,7 @@ def create_datamanager(
creation_date=timezone.now(),
owner=owner,
channel=channel,
archived=archived,
**get_permissions(owner, public),
**get_log_permissions(owner, public),
)
Expand Down
33 changes: 32 additions & 1 deletion backend/api/tests/views/test_views_datamanager.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ def setUp(self):
self.previous_level = self.logger.getEffectiveLevel()
self.logger.setLevel(logging.ERROR)

data_manager_1 = factory.create_datamanager(name="datamanager foo")
data_manager_1 = factory.create_datamanager(name="datamanager foo", archived=True)

train_data_sample = factory.create_datasample([data_manager_1])
test_data_sample = factory.create_datasample([data_manager_1], test_only=True)
# only for retrieve view
Expand Down Expand Up @@ -91,6 +92,7 @@ def setUp(self):
"public": False,
"authorized_ids": ["MyOrg1MSP"],
},
"archived": True,
},
{
"key": str(data_manager_2.key),
Expand Down Expand Up @@ -121,6 +123,7 @@ def setUp(self):
"public": False,
"authorized_ids": ["MyOrg1MSP"],
},
"archived": False,
},
{
"key": str(data_manager_3.key),
Expand Down Expand Up @@ -151,6 +154,7 @@ def setUp(self):
"public": False,
"authorized_ids": ["MyOrg1MSP"],
},
"archived": False,
},
]

Expand Down Expand Up @@ -180,6 +184,28 @@ def test_datamanager_update(self):
response = self.client.put(url, data=data, format="json", **self.extra)
self.assertEqual(response.status_code, status.HTTP_500_INTERNAL_SERVER_ERROR)

def test_datamanager_archive(self):
data_manager = self.expected_results[0]
data = {
"key": data_manager["key"],
"archived": True,
}

url = reverse("api:data_manager-archive", args=[data_manager["key"]])
data_manager["archived"] = data["archived"]

with mock.patch.object(OrchestratorClient, "archive_datamanager", side_effect=data_manager):
response = self.client.put(url, data=data, format="json", **self.extra)

self.assertEqual(response.status_code, status.HTTP_200_OK)

error = OrcError()
error.code = StatusCode.INTERNAL

with mock.patch.object(OrchestratorClient, "archive_datamanager", side_effect=error):
response = self.client.put(url, data=data, format="json", **self.extra)
self.assertEqual(response.status_code, status.HTTP_500_INTERNAL_SERVER_ERROR)

def test_datamanager_list_empty(self):
DataManager.objects.all().delete()
response = self.client.get(self.url, **self.extra)
Expand Down Expand Up @@ -260,6 +286,11 @@ def test_datamanager_list_cross_assets_filters(self):
response = self.client.get(f"{self.url}?{params}", **self.extra)
self.assertEqual(response.json().get("results"), self.expected_results[:1])

def test_datamanager_archived_filters(self):
params = urlencode({"archived": True})
response = self.client.get(f"{self.url}?{params}", **self.extra)
self.assertEqual(response.json().get("results"), self.expected_results[:1])

def test_datamanager_match(self):
"""Match datamanager on part of the name."""
params = urlencode({"match": "manager fo"})
Expand Down
24 changes: 22 additions & 2 deletions backend/api/views/datamanager.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from django.db import models
from django.urls import reverse
from django_filters.rest_framework import BaseInFilter
from django_filters.rest_framework import BooleanFilter
from django_filters.rest_framework import CharFilter
from django_filters.rest_framework import DateTimeFromToRangeFilter
from django_filters.rest_framework import DjangoFilterBackend
Expand All @@ -26,6 +27,7 @@
from api.views.utils import ValidationExceptionError
from api.views.utils import get_channel_name
from api.views.utils import validate_metadata
from backend.settings.common import to_bool
from libs.pagination import DefaultPageNumberPagination
from substrapp.models import DataManager as DataManagerFiles
from substrapp.orchestrator import get_orchestrator_client
Expand Down Expand Up @@ -139,6 +141,7 @@ class DataManagerFilter(FilterSet):
data_sample_key = CharInFilter(
field_name="compute_tasks__data_samples__key", distinct=True, label="data_sample_key"
)
archived = BooleanFilter(field_name="archived", distinct=True, label="archived")

class Meta:
model = DataManager
Expand Down Expand Up @@ -191,15 +194,32 @@ def update(self, request, *args, **kwargs):
datamanager = self.get_object()
name = request.data.get("name")

orc_algo = {
orc_datamanager = {
"key": str(datamanager.key),
"name": name,
}

# send update to orchestrator
# the modification in local db will be done upon corresponding event reception
with get_orchestrator_client(get_channel_name(request)) as client:
client.update_datamanager(orc_algo)
client.update_datamanager(orc_datamanager)

return ApiResponse({}, status=status.HTTP_200_OK)

@action(detail=True, methods=["PUT"])
def archive(self, request, *args, **kwargs):
datamanager = self.get_object()
archived = request.data.get("archived")

orc_algo = {
"key": str(datamanager.key),
"archived": to_bool(archived),
}

# send archiving message to orchestrator
# the modification in local db will be done upon corresponding event reception
with get_orchestrator_client(get_channel_name(request)) as client:
client.archive_datamanager(orc_algo)

return ApiResponse({}, status=status.HTTP_200_OK)

Expand Down
2 changes: 2 additions & 0 deletions backend/api/views/filters_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
from rest_framework.filters import BaseFilterBackend
from rest_framework.filters import SearchFilter

from backend.settings.common import to_bool

logger = structlog.get_logger(__name__)


Expand Down
7 changes: 7 additions & 0 deletions backend/orchestrator/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,13 @@ def update_datamanager(self, args):
)
return MessageToDict(data, **CONVERT_SETTINGS)

@grpc_retry
def archive_datamanager(self, args):
data = self._datamanager_client.ArchiveDataManager(
datamanager_pb2.ArchiveDataManagerParam(**args), metadata=self._metadata
)
return MessageToDict(data, **CONVERT_SETTINGS)

def _get_task_input(self, input: dict) -> computetask_pb2.ComputeTaskInput:
"""Convert a dict into a computetask_pb2.ComputeTaskInput"""

Expand Down
60 changes: 40 additions & 20 deletions backend/orchestrator/datamanager_pb2.py

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading