Greengrass Implement create_device_definition (#5198)

This commit is contained in:
cm-iwata 2022-06-08 19:17:42 +09:00 committed by GitHub
parent c82b437195
commit 4aa5e4388d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 224 additions and 0 deletions

View File

@ -62,6 +62,57 @@ class FakeCoreDefinitionVersion(BaseModel):
return obj
class FakeDeviceDefinition(BaseModel):
def __init__(self, region_name, name, initial_version):
self.region_name = region_name
self.id = str(uuid.uuid4())
self.arn = f"arn:aws:greengrass:{region_name}:{get_account_id()}:greengrass/definition/devices/{self.id}"
self.created_at_datetime = datetime.utcnow()
self.update_at_datetime = datetime.utcnow()
self.latest_version = ""
self.latest_version_arn = ""
self.name = name
self.initial_version = initial_version
def to_dict(self):
res = {
"Arn": self.arn,
"CreationTimestamp": iso_8601_datetime_with_milliseconds(
self.created_at_datetime
),
"Id": self.id,
"LastUpdatedTimestamp": iso_8601_datetime_with_milliseconds(
self.update_at_datetime
),
"LatestVersion": self.latest_version,
"LatestVersionArn": self.latest_version_arn,
}
if self.name is not None:
res["Name"] = self.name
return res
class FakeDeviceDefinitionVersion(BaseModel):
def __init__(self, region_name, device_definition_id, devices):
self.region_name = region_name
self.device_definition_id = device_definition_id
self.devices = devices
self.version = str(uuid.uuid4())
self.arn = f"arn:aws:greengrass:{region_name}:{get_account_id()}:/greengrass/definition/devices/{self.device_definition_id}/versions/{self.version}"
self.created_at_datetime = datetime.utcnow()
def to_dict(self):
return {
"Arn": self.arn,
"CreationTimestamp": iso_8601_datetime_with_milliseconds(
self.created_at_datetime
),
"Definition": {"Devices": self.devices},
"Id": self.device_definition_id,
"Version": self.version,
}
class GreengrassBackend(BaseBackend):
def __init__(self, region_name, account_id):
super().__init__(region_name, account_id)
@ -155,5 +206,36 @@ class GreengrassBackend(BaseBackend):
core_definition_version_id
]
def create_device_definition(self, name, initial_version):
device_def = FakeDeviceDefinition(self.region_name, name, initial_version)
self.device_definitions[device_def.id] = device_def
init_ver = device_def.initial_version
init_device_def = init_ver.get("Devices", {})
self.create_device_definition_version(device_def.id, init_device_def)
return device_def
def create_device_definition_version(self, device_definition_id, devices):
if device_definition_id not in self.device_definitions:
raise IdNotFoundException("That devices definition does not exist.")
device_ver = FakeDeviceDefinitionVersion(
self.region_name, device_definition_id, devices
)
device_vers = self.device_definition_versions.get(
device_ver.device_definition_id, {}
)
device_vers[device_ver.version] = device_ver
self.device_definition_versions[device_ver.device_definition_id] = device_vers
self.device_definitions[
device_definition_id
].latest_version = device_ver.version
self.device_definitions[
device_definition_id
].latest_version_arn = device_ver.arn
return device_ver
greengrass_backends = BackendDict(GreengrassBackend, "greengrass")

View File

@ -113,3 +113,34 @@ class GreengrassResponse(BaseResponse):
core_definition_version_id=core_definition_version_id,
)
return 200, {"status": 200}, json.dumps(res.to_dict(include_detail=True))
def device_definitions(self, request, full_url, headers):
self.setup_class(request, full_url, headers)
if self.method == "POST":
return self.create_device_definition()
def create_device_definition(self):
name = self._get_param("Name")
initial_version = self._get_param("InitialVersion")
res = self.greengrass_backend.create_device_definition(
name=name, initial_version=initial_version
)
return 201, {"status": 201}, json.dumps(res.to_dict())
def device_definition_versions(self, request, full_url, headers):
self.setup_class(request, full_url, headers)
if self.method == "POST":
return self.create_device_definition_version()
def create_device_definition_version(self):
device_definition_id = self.path.split("/")[-2]
devices = self._get_param("Devices")
res = self.greengrass_backend.create_device_definition_version(
device_definition_id=device_definition_id, devices=devices
)
return 201, {"status": 201}, json.dumps(res.to_dict())

View File

@ -13,4 +13,6 @@ url_paths = {
"{0}/greengrass/definition/cores/(?P<definition_id>[^/]+)/?$": response.core_definition,
"{0}/greengrass/definition/cores/(?P<definition_id>[^/]+)/versions$": response.core_definition_versions,
"{0}/greengrass/definition/cores/(?P<definition_id>[^/]+)/versions/(?P<definition_version_id>[^/]+)/?$": response.core_definition_version,
"{0}/greengrass/definition/devices$": response.device_definitions,
"{0}/greengrass/definition/devices/(?P<definition_id>[^/]+)/versions$": response.device_definition_versions,
}

View File

@ -0,0 +1,109 @@
import boto3
from botocore.client import ClientError
import freezegun
import pytest
from moto import mock_greengrass
from moto.core import get_account_id
from moto.settings import TEST_SERVER_MODE
ACCOUNT_ID = get_account_id()
@freezegun.freeze_time("2022-06-01 12:00:00")
@mock_greengrass
def test_create_device_definition():
client = boto3.client("greengrass", region_name="ap-northeast-1")
init_ver = {
"Devices": [
{
"CertificateArn": f"arn:aws:iot:ap-northeast-1:{ACCOUNT_ID}:cert/36ed61be9c6271ae8da174e29d0e033c06af149d7b21672f3800fe322044554d",
"Id": "123",
"SyncShadow": True,
"ThingArn": f"arn:aws:iot:ap-northeast-1:{ACCOUNT_ID}:thing/CoreThing",
}
]
}
device_name = "TestDevice"
res = client.create_device_definition(InitialVersion=init_ver, Name=device_name)
res.should.have.key("Arn")
res.should.have.key("Id")
res.should.have.key("LatestVersion")
res.should.have.key("LatestVersionArn")
res.should.have.key("Name").equals(device_name)
res["ResponseMetadata"]["HTTPStatusCode"].should.equal(201)
if not TEST_SERVER_MODE:
res.should.have.key("CreationTimestamp").equals("2022-06-01T12:00:00.000Z")
res.should.have.key("LastUpdatedTimestamp").equals("2022-06-01T12:00:00.000Z")
@freezegun.freeze_time("2022-06-01 12:00:00")
@mock_greengrass
def test_create_device_definition_version():
client = boto3.client("greengrass", region_name="ap-northeast-1")
v1_devices = [
{
"CertificateArn": f"arn:aws:iot:ap-northeast-1:{ACCOUNT_ID}:cert/36ed61be9c6271ae8da174e29d0e033c06af149d7b21672f3800fe322044554d",
"Id": "123",
"SyncShadow": True,
"ThingArn": f"arn:aws:iot:ap-northeast-1:{ACCOUNT_ID}:thing/v1Thing",
}
]
initial_version = {"Devices": v1_devices}
device_def_res = client.create_device_definition(
InitialVersion=initial_version, Name="TestDevice"
)
device_def_id = device_def_res["Id"]
v2_devices = [
{
"CertificateArn": f"arn:aws:iot:ap-northeast-1:{ACCOUNT_ID}:cert/277a6a15293c1ed5fa1aa74bae890b1827f80959537bfdcf10f63e661d54ebe1",
"Id": "987654321",
"SyncShadow": False,
"ThingArn": f"arn:aws:iot:ap-northeast-1:{ACCOUNT_ID}:thing/v2Thing",
}
]
device_def_ver_res = client.create_device_definition_version(
DeviceDefinitionId=device_def_id, Devices=v2_devices
)
device_def_ver_res.should.have.key("Arn")
device_def_ver_res.should.have.key("CreationTimestamp")
device_def_ver_res.should.have.key("Id").equals(device_def_id)
device_def_ver_res.should.have.key("Version")
if not TEST_SERVER_MODE:
device_def_ver_res["CreationTimestamp"].should.equal("2022-06-01T12:00:00.000Z")
@freezegun.freeze_time("2022-06-01 12:00:00")
@mock_greengrass
def test_create_device_definition_version_with_invalid_id():
client = boto3.client("greengrass", region_name="ap-northeast-1")
devices = [
{
"CertificateArn": f"arn:aws:iot:ap-northeast-1:{ACCOUNT_ID}:cert/36ed61be9c6271ae8da174e29d0e033c06af149d7b21672f3800fe322044554d",
"Id": "123",
"SyncShadow": True,
"ThingArn": f"arn:aws:iot:ap-northeast-1:{ACCOUNT_ID}:thing/v1Thing",
}
]
client.create_device_definition(
InitialVersion={"Devices": devices}, Name="TestDevice"
)
with pytest.raises(ClientError) as ex:
client.create_device_definition_version(
DeviceDefinitionId="123", Devices=devices
)
ex.value.response["Error"]["Message"].should.equal(
"That devices definition does not exist."
)
ex.value.response["Error"]["Code"].should.equal("IdNotFoundException")