Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
b1e9158
Merge pull request #1 from Azure/dev
vilit1 Jan 11, 2021
98aaa8d
Add etag functionality to device twins
vilit1 Dec 22, 2020
53b944f
adding etag to dps
vilit1 Jan 8, 2021
2e1f656
Update dps etags to no longer validate etag
vilit1 Jan 11, 2021
6b2dfee
Add tests to dt twin commands
vilit1 Jan 27, 2021
796d4c0
Merge branch 'dev' into vilit/addetagtodt
vilit1 Jan 27, 2021
acaf11b
Remove print
vilit1 Jan 27, 2021
6c9960d
Merge pull request #2 from vilit1/vilit/addetagtodt
vilit1 Jan 27, 2021
2f9d07b
extra call
vilit1 Jan 27, 2021
305df84
Merge pull request #3 from vilit1/extracall
vilit1 Jan 27, 2021
58fbc78
Merge branch 'dev' into etagsandunittests
vilit1 Jan 27, 2021
f0b412d
Update with linting
vilit1 Jan 27, 2021
ca49a92
linter fixes
vilit1 Jan 28, 2021
c4f44e8
fix if_none_match
vilit1 Jan 28, 2021
a19874e
Add etag functionality to device twins
vilit1 Dec 22, 2020
cd7c1d5
adding etag to dps
vilit1 Jan 8, 2021
2453eba
Update dps etags to no longer validate etag
vilit1 Jan 11, 2021
1eb2524
Add tests to dt twin commands
vilit1 Jan 27, 2021
4fc9741
Remove print
vilit1 Jan 27, 2021
ec51a90
extra call
vilit1 Jan 27, 2021
0c29f93
Update with linting
vilit1 Jan 27, 2021
55d44cf
linter fixes
vilit1 Jan 28, 2021
c123606
fix if_none_match
vilit1 Jan 28, 2021
9f2c0b6
Merge branch 'etagsandunittests' of https://github.com/vilit1/azure-i…
vilit1 Jan 29, 2021
3712476
Add tests to dt twin commands
vilit1 Jan 27, 2021
944c9c1
linting line fixes
vilit1 Jan 29, 2021
c1ba8d6
Merge pull request #4 from vilit1/etagsandunittests
vilit1 Jan 29, 2021
82c82a3
add data plane fixture
vilit1 Jan 30, 2021
4c5c770
Merge branch 'dev' into etags_unit_tests
vilit1 Feb 3, 2021
b5cce68
Merge branch 'dev' into etags_unit_tests
vilit1 Feb 4, 2021
ad34810
Add replace
vilit1 Feb 4, 2021
8f1eec8
Merge branch 'etags_unit_tests' of https://github.com/vilit1/azure-io…
vilit1 Feb 4, 2021
b44093b
Add dps tests, remove etag from create calls
vilit1 Feb 5, 2021
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
34 changes: 21 additions & 13 deletions azext_iot/digitaltwins/commands_twins.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,17 @@ def query_twins(


def create_twin(
cmd, name_or_hostname, twin_id, model_id, properties=None, resource_group_name=None
cmd,
name_or_hostname,
twin_id,
model_id,
replace=False,
properties=None,
resource_group_name=None
):
twin_provider = TwinProvider(cmd=cmd, name=name_or_hostname, rg=resource_group_name)
return twin_provider.create(
twin_id=twin_id, model_id=model_id, properties=properties
twin_id=twin_id, model_id=model_id, replace=replace, properties=properties
)


Expand All @@ -31,14 +37,14 @@ def show_twin(cmd, name_or_hostname, twin_id, resource_group_name=None):
return twin_provider.get(twin_id)


def update_twin(cmd, name_or_hostname, twin_id, json_patch, resource_group_name=None):
def update_twin(cmd, name_or_hostname, twin_id, json_patch, resource_group_name=None, etag=None):
twin_provider = TwinProvider(cmd=cmd, name=name_or_hostname, rg=resource_group_name)
return twin_provider.update(twin_id=twin_id, json_patch=json_patch)
return twin_provider.update(twin_id=twin_id, json_patch=json_patch, etag=etag)


def delete_twin(cmd, name_or_hostname, twin_id, resource_group_name=None):
def delete_twin(cmd, name_or_hostname, twin_id, resource_group_name=None, etag=None):
twin_provider = TwinProvider(cmd=cmd, name=name_or_hostname, rg=resource_group_name)
return twin_provider.delete(twin_id)
return twin_provider.delete(twin_id, etag=etag)


def create_relationship(
Expand All @@ -48,6 +54,7 @@ def create_relationship(
target_twin_id,
relationship_id,
relationship,
replace=False,
properties=None,
resource_group_name=None,
):
Expand All @@ -57,6 +64,7 @@ def create_relationship(
target_twin_id=target_twin_id,
relationship_id=relationship_id,
relationship=relationship,
replace=replace,
properties=properties,
)

Expand All @@ -77,10 +85,11 @@ def update_relationship(
relationship_id,
json_patch,
resource_group_name=None,
etag=None
):
twin_provider = TwinProvider(cmd=cmd, name=name_or_hostname, rg=resource_group_name)
return twin_provider.update_relationship(
twin_id=twin_id, relationship_id=relationship_id, json_patch=json_patch,
twin_id=twin_id, relationship_id=relationship_id, json_patch=json_patch, etag=etag
)


Expand All @@ -101,11 +110,11 @@ def list_relationships(


def delete_relationship(
cmd, name_or_hostname, twin_id, relationship_id, resource_group_name=None,
cmd, name_or_hostname, twin_id, relationship_id, resource_group_name=None, etag=None
):
twin_provider = TwinProvider(cmd=cmd, name=name_or_hostname, rg=resource_group_name)
return twin_provider.delete_relationship(
twin_id=twin_id, relationship_id=relationship_id
twin_id=twin_id, relationship_id=relationship_id, etag=etag
)


Expand All @@ -132,10 +141,9 @@ def show_component(


def update_component(
cmd, name_or_hostname, twin_id, component_path, json_patch, resource_group_name=None
cmd, name_or_hostname, twin_id, component_path, json_patch, resource_group_name=None, etag=None
):
twin_provider = TwinProvider(cmd=cmd, name=name_or_hostname, rg=resource_group_name)
twin_provider.update_component(
twin_id=twin_id, component_path=component_path, json_patch=json_patch
return twin_provider.update_component(
twin_id=twin_id, component_path=component_path, json_patch=json_patch, etag=etag
)
return
8 changes: 8 additions & 0 deletions azext_iot/digitaltwins/params.py
Original file line number Diff line number Diff line change
Expand Up @@ -278,11 +278,19 @@ def load_digitaltwins_arguments(self, _):
"Updates to property values and $model elements may happen in the same request. "
"Operations are limited to add, replace and remove. Provide file path or inline JSON.",
)
context.argument(
"etag", options_list=["--etag", "-e"], help="Entity tag value."
)
context.argument(
"component_path",
options_list=["--component"],
help="The path to the DTDL component.",
)
context.argument(
"replace",
options_list=["--replace"],
help="Indicates the operation should replace an existing twin if it exists."
)

with self.argument_context("dt twin create") as context:
context.argument(
Expand Down
122 changes: 77 additions & 45 deletions azext_iot/digitaltwins/providers/twin.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,14 @@
logger = get_logger(__name__)


class TwinOptions():
def __init__(self, if_match=None, if_none_match=None):
self.if_match = if_match
self.if_none_match = if_none_match
self.traceparent = None
self.tracestate = None


class TwinProvider(DigitalTwinsProvider):
def __init__(self, cmd, name, rg=None):
super(TwinProvider, self).__init__(
Expand All @@ -31,13 +39,16 @@ def __init__(self, cmd, name, rg=None):
def invoke_query(self, query, show_cost):
from azext_iot.digitaltwins.providers.generic import accumulate_result

accumulated_result, cost = accumulate_result(
self.query_sdk.query_twins,
values_name="value",
token_name="continuationToken",
token_arg_name="continuation_token",
query=query,
)
try:
accumulated_result, cost = accumulate_result(
self.query_sdk.query_twins,
values_name="value",
token_name="continuationToken",
token_arg_name="continuation_token",
query=query,
)
except ErrorResponseException as e:
raise CLIError(unpack_msrest_error(e))

query_result = {}
query_result["result"] = accumulated_result
Expand All @@ -46,11 +57,10 @@ def invoke_query(self, query, show_cost):

return query_result

def create(self, twin_id, model_id, properties=None):
target_model = self.model_provider.get(id=model_id)
def create(self, twin_id, model_id, replace=False, properties=None):
twin_request = {
"$dtId": twin_id,
"$metadata": {"$model": target_model["id"]},
"$metadata": {"$model": model_id},
}

if properties:
Expand All @@ -62,7 +72,8 @@ def create(self, twin_id, model_id, properties=None):
logger.info("Twin payload %s", json.dumps(twin_request))

try:
return self.twins_sdk.add(id=twin_id, twin=twin_request, if_none_match="*")
options = TwinOptions(if_none_match=(None if replace else "*"))
return self.twins_sdk.add(id=twin_id, twin=twin_request, digital_twins_add_options=options)
except ErrorResponseException as e:
raise CLIError(unpack_msrest_error(e))

Expand All @@ -72,7 +83,7 @@ def get(self, twin_id):
except ErrorResponseException as e:
raise CLIError(unpack_msrest_error(e))

def update(self, twin_id, json_patch):
def update(self, twin_id, json_patch, etag=None):
json_patch = process_json_arg(content=json_patch, argument_name="json-patch")

json_patch_collection = []
Expand All @@ -84,17 +95,19 @@ def update(self, twin_id, json_patch):
logger.info("Patch payload %s", json.dumps(json_patch_collection))

try:
options = TwinOptions(if_match=(etag if etag else "*"))
self.twins_sdk.update(
id=twin_id, patch_document=json_patch_collection, if_match="*", raw=True
id=twin_id, patch_document=json_patch_collection, digital_twins_update_options=options, raw=True
)
return self.get(twin_id=twin_id)
except ErrorResponseException as e:
raise CLIError(unpack_msrest_error(e))

def delete(self, twin_id):
def delete(self, twin_id, etag=None):
# Not a json response
try:
self.twins_sdk.delete(id=twin_id, if_match="*", raw=True)
options = TwinOptions(if_match=(etag if etag else "*"))
self.twins_sdk.delete(id=twin_id, digital_twins_delete_options=options, raw=True)
except ErrorResponseException as e:
raise CLIError(unpack_msrest_error(e))

Expand All @@ -104,6 +117,7 @@ def add_relationship(
target_twin_id,
relationship_id,
relationship,
replace=False,
properties=None,
):
relationship_request = {
Expand All @@ -118,18 +132,25 @@ def add_relationship(
relationship_request.update(properties)

logger.info("Relationship payload %s", json.dumps(relationship_request))
return self.twins_sdk.add_relationship(
id=twin_id,
relationship_id=relationship_id,
relationship=relationship_request,
if_none_match="*",
raw=True,
).response.json()
try:
options = TwinOptions(if_none_match=(None if replace else "*"))
return self.twins_sdk.add_relationship(
id=twin_id,
relationship_id=relationship_id,
relationship=relationship_request,
digital_twins_add_relationship_options=options,
raw=True,
).response.json()
except ErrorResponseException as e:
raise CLIError(unpack_msrest_error(e))

def get_relationship(self, twin_id, relationship_id):
return self.twins_sdk.get_relationship_by_id(
id=twin_id, relationship_id=relationship_id, raw=True
).response.json()
try:
return self.twins_sdk.get_relationship_by_id(
id=twin_id, relationship_id=relationship_id, raw=True
).response.json()
except ErrorResponseException as e:
raise CLIError(unpack_msrest_error(e))

def list_relationships(
self, twin_id, incoming_relationships=False, relationship=None
Expand All @@ -147,6 +168,8 @@ def list_relationships(
incoming_result.extend(incoming_pager.advance_page())
except StopIteration:
pass
except ErrorResponseException as e:
raise CLIError(unpack_msrest_error(e))

if relationship:
incoming_result = [
Expand All @@ -157,7 +180,7 @@ def list_relationships(

return incoming_result

def update_relationship(self, twin_id, relationship_id, json_patch):
def update_relationship(self, twin_id, relationship_id, json_patch, etag=None):
json_patch = process_json_arg(content=json_patch, argument_name="json-patch")

json_patch_collection = []
Expand All @@ -169,32 +192,37 @@ def update_relationship(self, twin_id, relationship_id, json_patch):
logger.info("Patch payload %s", json.dumps(json_patch_collection))

try:
options = TwinOptions(if_match=(etag if etag else "*"))
self.twins_sdk.update_relationship(
id=twin_id,
relationship_id=relationship_id,
patch_document=json_patch_collection,
if_match="*",
digital_twins_update_relationship_options=options,
)
return self.get_relationship(
twin_id=twin_id, relationship_id=relationship_id
)
except ErrorResponseException as e:
raise CLIError(unpack_msrest_error(e))

def delete_relationship(self, twin_id, relationship_id):
def delete_relationship(self, twin_id, relationship_id, etag=None):
try:
options = TwinOptions(if_match=(etag if etag else "*"))
self.twins_sdk.delete_relationship(
id=twin_id, relationship_id=relationship_id, if_match="*"
id=twin_id, relationship_id=relationship_id, digital_twins_delete_relationship_options=options
)
except ErrorResponseException as e:
raise CLIError(unpack_msrest_error(e))

def get_component(self, twin_id, component_path):
return self.twins_sdk.get_component(
id=twin_id, component_path=component_path, raw=True
).response.json()
try:
return self.twins_sdk.get_component(
id=twin_id, component_path=component_path, raw=True
).response.json()
except ErrorResponseException as e:
raise CLIError(unpack_msrest_error(e))

def update_component(self, twin_id, component_path, json_patch):
def update_component(self, twin_id, component_path, json_patch, etag=None):
json_patch = process_json_arg(content=json_patch, argument_name="json-patch")

json_patch_collection = []
Expand All @@ -206,13 +234,14 @@ def update_component(self, twin_id, component_path, json_patch):
logger.info("Patch payload %s", json.dumps(json_patch_collection))

try:
# TODO: API does not return response
options = TwinOptions(if_match=(etag if etag else "*"))
self.twins_sdk.update_component(
id=twin_id,
component_path=component_path,
patch_document=json_patch_collection,
if_match="*",
digital_twins_update_component_options=options,
)
return self.get_component(twin_id=twin_id, component_path=component_path)
except ErrorResponseException as e:
raise CLIError(unpack_msrest_error(e))

Expand All @@ -236,18 +265,21 @@ def send_telemetry(self, twin_id, telemetry=None, dt_id=None, component_path=Non
if not dt_id:
dt_id = str(uuid4())

if component_path:
self.twins_sdk.send_component_telemetry(
try:
if component_path:
self.twins_sdk.send_component_telemetry(
id=twin_id,
message_id=dt_id,
dt_timestamp=dt_timestamp,
component_path=component_path,
telemetry=telemetry_request,
)

self.twins_sdk.send_telemetry(
id=twin_id,
message_id=dt_id,
dt_timestamp=dt_timestamp,
component_path=component_path,
telemetry=telemetry_request,
)

self.twins_sdk.send_telemetry(
id=twin_id,
message_id=dt_id,
dt_timestamp=dt_timestamp,
telemetry=telemetry_request,
)
except ErrorResponseException as e:
raise CLIError(unpack_msrest_error(e))
Loading