Skip to content

Commit

Permalink
source/collection | removed active_concepts/mappings and last_concept…
Browse files Browse the repository at this point in the history
…/mapping/child_update attributes
  • Loading branch information
snyaggarwal committed Jan 19, 2021
1 parent 6a62059 commit f303e83
Show file tree
Hide file tree
Showing 8 changed files with 140 additions and 81 deletions.
33 changes: 33 additions & 0 deletions core/collections/migrations/0014_auto_20210119_1439.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Generated by Django 3.0.9 on 2021-01-19 14:39

from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
('collections', '0013_auto_20210115_0823'),
]

operations = [
migrations.RemoveField(
model_name='collection',
name='active_concepts',
),
migrations.RemoveField(
model_name='collection',
name='active_mappings',
),
migrations.RemoveField(
model_name='collection',
name='last_child_update',
),
migrations.RemoveField(
model_name='collection',
name='last_concept_update',
),
migrations.RemoveField(
model_name='collection',
name='last_mapping_update',
),
]
26 changes: 26 additions & 0 deletions core/collections/tests/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,32 @@ def test_parent_id(self):
self.assertEqual(Collection(user_id=1).parent_id, 1)
self.assertEqual(Collection(organization_id=1).parent_id, 1)

def test_last_concept_update(self):
collection = OrganizationCollectionFactory()
self.assertIsNone(collection.last_concept_update)
concept = ConceptFactory()
collection.concepts.add(concept)
self.assertEqual(collection.last_concept_update, concept.updated_at)

def test_last_mapping_update(self):
collection = OrganizationCollectionFactory()
self.assertIsNone(collection.last_mapping_update)
mapping = MappingFactory()
collection.mappings.add(mapping)
self.assertEqual(collection.last_mapping_update, mapping.updated_at)

def test_last_child_update(self):
collection = OrganizationCollectionFactory()
self.assertEqual(collection.last_child_update, collection.updated_at)

mapping = MappingFactory()
collection.mappings.add(mapping)
self.assertEqual(collection.last_child_update, mapping.updated_at)

concept = ConceptFactory()
collection.concepts.add(concept)
self.assertEqual(collection.last_child_update, concept.updated_at)


class CollectionReferenceTest(OCLTestCase):
def test_invalid_expression(self):
Expand Down
69 changes: 30 additions & 39 deletions core/common/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -320,11 +320,6 @@ class ConceptContainerModel(VersionedModel):
"""
organization = models.ForeignKey('orgs.Organization', on_delete=models.CASCADE, blank=True, null=True)
user = models.ForeignKey('users.UserProfile', on_delete=models.CASCADE, blank=True, null=True)
active_concepts = models.IntegerField(default=0)
active_mappings = models.IntegerField(default=0)
last_concept_update = models.DateTimeField(default=timezone.now, null=True, blank=True)
last_mapping_update = models.DateTimeField(default=timezone.now, null=True, blank=True)
last_child_update = models.DateTimeField(default=timezone.now)
_background_process_ids = ArrayField(models.CharField(max_length=255), default=list, null=True, blank=True)

canonical_url = models.URLField(null=True, blank=True)
Expand All @@ -339,6 +334,36 @@ class ConceptContainerModel(VersionedModel):
class Meta:
abstract = True

@property
def active_concepts(self):
return self.concepts.filter(retired=False, is_active=True).distinct('versioned_object_id').count()

@property
def active_mappings(self):
return self.mappings.filter(retired=False, is_active=True).distinct('versioned_object_id').count()

@property
def last_concept_update(self):
updated_at = None
if self.concepts.exists():
updated_at = self.concepts.latest('updated_at').updated_at
return updated_at

@property
def last_mapping_update(self):
updated_at = None
if self.mappings.exists():
updated_at = self.mappings.latest('updated_at').updated_at
return updated_at

@property
def last_child_update(self):
last_concept_update = self.last_concept_update
last_mapping_update = self.last_mapping_update
if last_concept_update and last_mapping_update:
return max(last_concept_update, last_mapping_update)
return last_concept_update or last_mapping_update or self.updated_at or timezone.now()

@classmethod
def get_base_queryset(cls, params):
username = params.get('user', None)
Expand Down Expand Up @@ -556,40 +581,6 @@ def validate_child_concepts(self):

return failed_concept_validations

def update_active_counts(self):
self.active_concepts = self.concepts.filter(retired=False).distinct('versioned_object_id').count()
self.active_mappings = self.mappings.filter(retired=False).distinct('versioned_object_id').count()

def update_last_updates(self):
self.last_concept_update = self.__get_last_concept_updated_at()
self.last_mapping_update = self.__get_last_mapping_updated_at()
self.last_child_update = self.__get_last_child_updated_at()

def __get_last_concept_updated_at(self):
concepts = self.concepts
if not concepts.exists():
return None
return concepts.latest('updated_at').updated_at

def __get_last_mapping_updated_at(self):
mappings = self.mappings
if not mappings.exists():
return None
return mappings.latest('updated_at').updated_at

def __get_last_child_updated_at(self):
last_concept_update = self.last_concept_update
last_mapping_update = self.last_mapping_update
if last_concept_update and last_mapping_update:
return max(last_concept_update, last_mapping_update)
return last_concept_update or last_mapping_update or self.updated_at or timezone.now()

def save(self, force_insert=False, force_update=False, using=None, update_fields=None):
if self.id:
self.update_active_counts()
self.update_last_updates()
super().save(force_insert, force_update, using, update_fields)

def update_version_data(self, obj=None):
if obj:
self.description = obj.description
Expand Down
5 changes: 0 additions & 5 deletions core/concepts/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -436,10 +436,7 @@ def persist_new(cls, data, user=None, create_initial_version=True):
initial_version.sources.set([parent_resource, parent_resource_head])

concept.sources.set([parent_resource, parent_resource_head])

concept.update_mappings()
parent_resource.save()
parent_resource_head.save()
except ValidationError as ex:
concept.errors.update(ex.message_dict)
except IntegrityError as ex:
Expand Down Expand Up @@ -494,8 +491,6 @@ def persist_clone(cls, obj, user=None, **kwargs): # pylint: disable=too-many-st
cls.resume_indexing()

def index_all():
parent.save()
parent_head.save()
if latest_version:
latest_version.save()
obj.save()
Expand Down
24 changes: 8 additions & 16 deletions core/integration_tests/tests_collections.py
Original file line number Diff line number Diff line change
Expand Up @@ -767,6 +767,7 @@ def setUp(self):
self.token = self.user.get_token()
self.collection = UserCollectionFactory(mnemonic='coll', user=self.user)
self.collection_v1 = UserCollectionFactory(version='v1', mnemonic='coll', user=self.user)
self.v1_updated_at = self.collection_v1.updated_at.strftime('%Y%m%d%H%M%S')

def test_get_404(self):
response = self.client.get(
Expand All @@ -779,8 +780,6 @@ def test_get_404(self):

@patch('core.common.services.S3.url_for')
def test_get_204(self, s3_url_for_mock):
Collection.objects.filter(id=self.collection_v1.id).update(last_child_update='2020-01-01 10:00:00')

s3_url_for_mock.return_value = None

response = self.client.get(
Expand All @@ -790,13 +789,11 @@ def test_get_204(self, s3_url_for_mock):
)

self.assertEqual(response.status_code, 204)
s3_url_for_mock.assert_called_once_with("username/coll_v1.20200101100000.zip")
s3_url_for_mock.assert_called_once_with("username/coll_v1.{}.zip".format(self.v1_updated_at))

@patch('core.common.services.S3.url_for')
def test_get_303(self, s3_url_for_mock):
Collection.objects.filter(id=self.collection_v1.id).update(last_child_update='2020-01-01 10:00:00')

s3_url = 'https://s3/username/coll_v1.20200101100000.zip'
s3_url = "https://s3/username/coll_v1.{}.zip".format(self.v1_updated_at)
s3_url_for_mock.return_value = s3_url

response = self.client.get(
Expand All @@ -807,9 +804,9 @@ def test_get_303(self, s3_url_for_mock):

self.assertEqual(response.status_code, 303)
self.assertEqual(response['Location'], s3_url)
self.assertEqual(response['Last-Updated'], '2020-01-01T10:00:00+00:00')
self.assertEqual(response['Last-Updated'], str(self.collection_v1.last_child_update.isoformat()))
self.assertEqual(response['Last-Updated-Timezone'], 'America/New_York')
s3_url_for_mock.assert_called_once_with("username/coll_v1.20200101100000.zip")
s3_url_for_mock.assert_called_once_with("username/coll_v1.{}.zip".format(self.v1_updated_at))

def test_get_405(self):
response = self.client.get(
Expand All @@ -831,7 +828,6 @@ def test_post_405(self):

@patch('core.common.services.S3.exists')
def test_post_303(self, s3_exists_mock):
Collection.objects.filter(id=self.collection_v1.id).update(last_child_update='2020-01-01 10:00:00')
s3_exists_mock.return_value = True
response = self.client.post(
'/collections/coll/v1/export/',
Expand All @@ -841,13 +837,11 @@ def test_post_303(self, s3_exists_mock):

self.assertEqual(response.status_code, 303)
self.assertEqual(response['URL'], self.collection_v1.uri + 'export/')
s3_exists_mock.assert_called_once_with("username/coll_v1.20200101100000.zip")
s3_exists_mock.assert_called_once_with("username/coll_v1.{}.zip".format(self.v1_updated_at))

@patch('core.collections.views.export_collection')
@patch('core.common.services.S3.exists')
def test_post_202(self, s3_exists_mock, export_collection_mock):
Collection.objects.filter(id=self.collection_v1.id).update(last_child_update='2020-01-01 10:00:00')

s3_exists_mock.return_value = False
export_collection_mock.delay = Mock()
response = self.client.post(
Expand All @@ -857,14 +851,12 @@ def test_post_202(self, s3_exists_mock, export_collection_mock):
)

self.assertEqual(response.status_code, 202)
s3_exists_mock.assert_called_once_with("username/coll_v1.20200101100000.zip")
s3_exists_mock.assert_called_once_with("username/coll_v1.{}.zip".format(self.v1_updated_at))
export_collection_mock.delay.assert_called_once_with(self.collection_v1.id)

@patch('core.collections.views.export_collection')
@patch('core.common.services.S3.exists')
def test_post_409(self, s3_exists_mock, export_collection_mock):
Collection.objects.filter(id=self.collection_v1.id).update(last_child_update='2020-01-01 10:00:00')

s3_exists_mock.return_value = False
export_collection_mock.delay.side_effect = AlreadyQueued('already-queued')
response = self.client.post(
Expand All @@ -874,7 +866,7 @@ def test_post_409(self, s3_exists_mock, export_collection_mock):
)

self.assertEqual(response.status_code, 409)
s3_exists_mock.assert_called_once_with("username/coll_v1.20200101100000.zip")
s3_exists_mock.assert_called_once_with("username/coll_v1.{}.zip".format(self.v1_updated_at))
export_collection_mock.delay.assert_called_once_with(self.collection_v1.id)


Expand Down
24 changes: 8 additions & 16 deletions core/integration_tests/tests_sources.py
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,7 @@ def setUp(self):
self.token = self.user.get_token()
self.source = UserSourceFactory(mnemonic='source1', user=self.user)
self.source_v1 = UserSourceFactory(version='v1', mnemonic='source1', user=self.user)
self.v1_updated_at = self.source_v1.updated_at.strftime('%Y%m%d%H%M%S')

def test_get_404(self):
response = self.client.get(
Expand All @@ -518,8 +519,6 @@ def test_get_404(self):

@patch('core.common.services.S3.url_for')
def test_get_204(self, s3_url_for_mock):
Source.objects.filter(id=self.source_v1.id).update(last_child_update='2020-01-01 10:00:00')

s3_url_for_mock.return_value = None

response = self.client.get(
Expand All @@ -529,13 +528,11 @@ def test_get_204(self, s3_url_for_mock):
)

self.assertEqual(response.status_code, 204)
s3_url_for_mock.assert_called_once_with("username/source1_v1.20200101100000.zip")
s3_url_for_mock.assert_called_once_with("username/source1_v1.{}.zip".format(self.v1_updated_at))

@patch('core.common.services.S3.url_for')
def test_get_303(self, s3_url_for_mock):
Source.objects.filter(id=self.source_v1.id).update(last_child_update='2020-01-01 10:00:00')

s3_url = 'https://s3/username/source1_v1.20200101100000.zip'
s3_url = 'https://s3/username/source1_v1.{}.zip'.format(self.v1_updated_at)
s3_url_for_mock.return_value = s3_url

response = self.client.get(
Expand All @@ -546,9 +543,9 @@ def test_get_303(self, s3_url_for_mock):

self.assertEqual(response.status_code, 303)
self.assertEqual(response['Location'], s3_url)
self.assertEqual(response['Last-Updated'], '2020-01-01T10:00:00+00:00')
self.assertEqual(response['Last-Updated'], self.source_v1.last_child_update.isoformat())
self.assertEqual(response['Last-Updated-Timezone'], 'America/New_York')
s3_url_for_mock.assert_called_once_with("username/source1_v1.20200101100000.zip")
s3_url_for_mock.assert_called_once_with("username/source1_v1.{}.zip".format(self.v1_updated_at))

def test_get_405(self):
response = self.client.get(
Expand All @@ -570,7 +567,6 @@ def test_post_405(self):

@patch('core.common.services.S3.exists')
def test_post_303(self, s3_exists_mock):
Source.objects.filter(id=self.source_v1.id).update(last_child_update='2020-01-01 10:00:00')
s3_exists_mock.return_value = True
response = self.client.post(
'/sources/source1/v1/export/',
Expand All @@ -580,13 +576,11 @@ def test_post_303(self, s3_exists_mock):

self.assertEqual(response.status_code, 303)
self.assertEqual(response['URL'], self.source_v1.uri + 'export/')
s3_exists_mock.assert_called_once_with("username/source1_v1.20200101100000.zip")
s3_exists_mock.assert_called_once_with("username/source1_v1.{}.zip".format(self.v1_updated_at))

@patch('core.sources.views.export_source')
@patch('core.common.services.S3.exists')
def test_post_202(self, s3_exists_mock, export_source_mock):
Source.objects.filter(id=self.source_v1.id).update(last_child_update='2020-01-01 10:00:00')

s3_exists_mock.return_value = False
export_source_mock.delay = Mock()
response = self.client.post(
Expand All @@ -596,14 +590,12 @@ def test_post_202(self, s3_exists_mock, export_source_mock):
)

self.assertEqual(response.status_code, 202)
s3_exists_mock.assert_called_once_with("username/source1_v1.20200101100000.zip")
s3_exists_mock.assert_called_once_with("username/source1_v1.{}.zip".format(self.v1_updated_at))
export_source_mock.delay.assert_called_once_with(self.source_v1.id)

@patch('core.sources.views.export_source')
@patch('core.common.services.S3.exists')
def test_post_409(self, s3_exists_mock, export_source_mock):
Source.objects.filter(id=self.source_v1.id).update(last_child_update='2020-01-01 10:00:00')

s3_exists_mock.return_value = False
export_source_mock.delay.side_effect = AlreadyQueued('already-queued')
response = self.client.post(
Expand All @@ -613,7 +605,7 @@ def test_post_409(self, s3_exists_mock, export_source_mock):
)

self.assertEqual(response.status_code, 409)
s3_exists_mock.assert_called_once_with("username/source1_v1.20200101100000.zip")
s3_exists_mock.assert_called_once_with("username/source1_v1.{}.zip".format(self.v1_updated_at))
export_source_mock.delay.assert_called_once_with(self.source_v1.id)


Expand Down
7 changes: 2 additions & 5 deletions core/mappings/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -303,8 +303,6 @@ def persist_new(cls, data, user):
initial_version = cls.create_initial_version(mapping)
initial_version.sources.set([parent, parent_head])
mapping.sources.set([parent, parent_head])
parent.save()
parent_head.save()
except ValidationError as ex:
mapping.errors.update(ex.message_dict)
except IntegrityError as ex:
Expand Down Expand Up @@ -369,9 +367,8 @@ def persist_clone(cls, obj, user=None, **kwargs):
cls.resume_indexing()

def index_all():
parent.save()
parent_head.save()
latest_version.save()
if latest_version:
latest_version.save()
obj.save()

transaction.on_commit(index_all)
Expand Down
Loading

0 comments on commit f303e83

Please sign in to comment.