Skip to content

Commit f549ae5

Browse files
committed
Add StorageIntegrity
Problem: Latest version of archivist now allows specifying whether the asset is stored on the DLT or not. Solution: An enumerated StorageIntegrity type added to the assets.create() method to allow specifying either LEDGER or TENANT_STORAGE. If unspecified TENANT_STORAGE is used. Signed-off-by: Paul Hewlett <phewlett76@gmail.com>
1 parent 348e5c5 commit f549ae5

8 files changed

Lines changed: 167 additions & 5 deletions

File tree

archivist/assets.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
import logging
2525
from typing import Dict, List, Optional
2626
from copy import deepcopy
27+
28+
from archivist.storage_integrity import StorageIntegrity
2729
from archivist.type_aliases import NoneOnError
2830

2931
# pylint:disable=unused-import # To prevent cyclical import errors forward referencing is used
@@ -107,15 +109,23 @@ class _AssetsClient:
107109
def __init__(self, archivist: "type_helper.Archivist"):
108110
self._archivist = archivist
109111

110-
def create(self, behaviours: List, attrs: Dict, *, confirm: bool = False) -> Asset:
112+
def create(
113+
self,
114+
behaviours: List,
115+
attrs: Dict,
116+
*,
117+
storage_integrity: StorageIntegrity = StorageIntegrity.TENANT_STORAGE,
118+
confirm: bool = False,
119+
) -> Asset:
111120
"""Create asset
112121
113122
Creates asset with defined behaviours and attributes.
114123
115124
Args:
116125
behaviours (list): list of accepted behaviours for this asset.
117126
attrs (dict): attributes of created asset.
118-
confirm (bool): if True wait for asset to be confirmed on DLT.
127+
storage_integrity (StorageIntegrity): store asset on either ledger or tenant storage
128+
confirm (bool): if True wait for asset to be confirmed.
119129
120130
Returns:
121131
:class:`Asset` instance
@@ -125,6 +135,7 @@ def create(self, behaviours: List, attrs: Dict, *, confirm: bool = False) -> Ass
125135
return self.create_from_data(
126136
{
127137
"behaviours": behaviours,
138+
"storage_integrity": storage_integrity.name,
128139
"attributes": attrs,
129140
},
130141
confirm=confirm,

archivist/storage_integrity.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
"""Archivist Storage integrity
2+
3+
Enumerated type that allows user to select the storage option when
4+
creating an asset.
5+
6+
"""
7+
8+
from enum import Enum
9+
10+
11+
class StorageIntegrity(Enum):
12+
"""Enumerate storage integrity options"""
13+
14+
#: Assets are stored on the DLT
15+
LEDGER = 1
16+
#: Assets are not stored on the DLT
17+
TENANT_STORAGE = 2

docs/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ Jitsuin Archivist
2323
archivist
2424
timestamp
2525
errors
26+
storage_integrity
2627

2728
Indices and tables
2829
==================

docs/storage_integrity.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
2+
.. _storage_integrity:
3+
4+
Storage Integrity
5+
-----------------
6+
7+
8+
.. automodule:: archivist.storage_integrity
9+
:members:
10+

examples/create_asset.py

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
"""
88

99
from archivist.archivist import Archivist
10+
from archivist.storage_integrity import StorageIntegrity
1011

1112

1213
def create_asset(arch):
@@ -39,17 +40,33 @@ def create_asset(arch):
3940
"Attachments",
4041
"RecordEvidence",
4142
]
43+
#
44+
# store asset on the DLT or not. If DLT is not enabled for the user an error will occur if
45+
# StorageIntegrity.LEDGER is specified. If unspecified then TENANT_STORAGE is used
46+
# i.e. not stored on the DLT...
47+
# storage_integrity = StorageIntegrity.TENANT_STORAGE
48+
storage_integrity = StorageIntegrity.LEDGER
4249

4350
# The first argument is the behaviours of the asset
4451
# The second argument is the attributes of the asset
45-
# The third argument is wait for confirmation:
52+
# The third argument indicates whether the asset is stored on the DLT or not.
53+
# If not specifed the asset is not stored on the DLT (TENANT_STORAGE)
54+
# The fourth argument is wait for confirmation:
4655
# If @confirm@ is True then this function will not
4756
# return until the asset is confirmed on the blockchain and ready
4857
# to accept events (or an error occurs)
49-
# After an asset is submitted to the blockchain (submitted),
58+
#
59+
# If storage_integrity = StorageIntegrity.LEDGER:
60+
# After an asset is submitted to the blockchain,
5061
# it will be in the "Pending" status.
5162
# Once it is added to the blockchain, the status will be changed to "Confirmed"
52-
return arch.assets.create(behaviours, attrs=attrs, confirm=True)
63+
#
64+
# If storage_integrity = StorageIntegrity.TENANT_STORAGE:
65+
# The asset is simply stored in the backend (and not on the blockchain)
66+
# and, once stored, the status will be changed to "Confirmed".
67+
return arch.assets.create(
68+
behaviours, attrs, storage_integrity=storage_integrity, confirm=True
69+
)
5370

5471

5572
def main():

functests/execassets.py

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
"""
2+
Test assets creation
3+
"""
4+
5+
from copy import deepcopy
6+
from os import environ
7+
from unittest import TestCase
8+
9+
from archivist.archivist import Archivist
10+
from archivist.storage_integrity import StorageIntegrity
11+
12+
# pylint: disable=fixme
13+
# pylint: disable=missing-docstring
14+
# pylint: disable=unused-variable
15+
16+
BEHAVIOURS = [
17+
"RecordEvidence",
18+
"Attachments",
19+
]
20+
ATTRS = {
21+
"arc_firmware_version": "1.0",
22+
"arc_serial_number": "vtl-x4-07",
23+
"arc_description": "Traffic flow control light at A603 North East",
24+
"arc_home_location_identity": "locations/115340cf-f39e-4d43-a2ee-8017d672c6c6",
25+
"arc_display_type": "Traffic light with violation camera",
26+
"some_custom_attribute": "value",
27+
}
28+
29+
30+
class TestAssetCreate(TestCase):
31+
"""
32+
Test Archivist Asset Create method
33+
"""
34+
35+
maxDiff = None
36+
37+
def setUp(cls):
38+
with open(environ["TEST_AUTHTOKEN"]) as fd:
39+
auth = fd.read().strip()
40+
cls.arch = Archivist(environ["TEST_ARCHIVIST"], auth=auth, verify=False)
41+
cls.attrs = deepcopy(ATTRS)
42+
43+
def test_asset_create_tenant_storage(self):
44+
"""
45+
Test asset creation on tenant storage
46+
"""
47+
asset = self.arch.assets.create(
48+
BEHAVIOURS,
49+
self.attrs,
50+
confirm=True,
51+
)
52+
self.assertEqual(
53+
asset["storage_integrity"],
54+
StorageIntegrity.TENANT_STORAGE.name,
55+
msg="Incorrect asset storage integrity",
56+
)
57+
58+
def test_asset_create_ledger(self):
59+
"""
60+
Test asset creation on ledger
61+
"""
62+
asset = self.arch.assets.create(
63+
BEHAVIOURS,
64+
self.attrs,
65+
storage_integrity=StorageIntegrity.LEDGER,
66+
confirm=True,
67+
)
68+
self.assertEqual(
69+
asset["storage_integrity"],
70+
StorageIntegrity.LEDGER.name,
71+
msg="Incorrect asset storage integrity",
72+
)

unittests/testassets.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
ROOT,
1818
)
1919
from archivist.errors import ArchivistUnconfirmedError
20+
from archivist.storage_integrity import StorageIntegrity
2021

2122
from .mock_response import MockResponse
2223

@@ -78,6 +79,7 @@
7879
# TBD: add properties as well
7980
REQUEST = {
8081
"behaviours": BEHAVIOURS,
82+
"storage_integrity": StorageIntegrity.TENANT_STORAGE.name,
8183
"attributes": ATTRS,
8284
}
8385
REQUEST_DATA = json.dumps(REQUEST)

unittests/teststorage_integrity.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
"""
2+
Test storage integrity
3+
"""
4+
5+
# pylint: disable=attribute-defined-outside-init
6+
# pylint: disable=missing-docstring
7+
# pylint: disable=too-few-public-methods
8+
9+
from unittest import TestCase
10+
11+
from archivist.storage_integrity import StorageIntegrity
12+
13+
14+
class TestStorageIntegrity(TestCase):
15+
"""
16+
Test storage integrity for archivist
17+
"""
18+
19+
def test_storage_integrity(self):
20+
"""
21+
Test storage_integrity
22+
"""
23+
self.assertEqual(StorageIntegrity.LEDGER.value, 1, msg="Incorrect value")
24+
self.assertEqual(StorageIntegrity.LEDGER.name, "LEDGER", msg="Incorrect value")
25+
self.assertEqual(
26+
StorageIntegrity.TENANT_STORAGE.value, 2, msg="Incorrect value"
27+
)
28+
self.assertEqual(
29+
StorageIntegrity.TENANT_STORAGE.name,
30+
"TENANT_STORAGE",
31+
msg="Incorrect value",
32+
)

0 commit comments

Comments
 (0)