Skip to content

Commit

Permalink
Implement Middleware Override in AssetLocation (#1642)
Browse files Browse the repository at this point in the history
* Implement Middleware Override in AssetLocation

* skip assets without hostname

* facility middleware required & location's optional

* fix migration

* update migration
  • Loading branch information
Ashesh3 authored Oct 16, 2023
1 parent 14f58f6 commit 0794d08
Show file tree
Hide file tree
Showing 8 changed files with 92 additions and 8 deletions.
10 changes: 10 additions & 0 deletions care/facility/api/serializers/asset.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,22 @@
from care.utils.assetintegration.ventilator import VentilatorAsset
from care.utils.queryset.facility import get_facility_queryset
from config.serializers import ChoiceField
from config.validators import MiddlewareDomainAddressValidator


class AssetLocationSerializer(ModelSerializer):
facility = FacilityBareMinimumSerializer(read_only=True)
id = UUIDField(source="external_id", read_only=True)

def validate_middleware_address(self, value):
value = (value or "").strip()
if not value:
return value

# Check if the address is valid
MiddlewareDomainAddressValidator()(value)
return value

def validate(self, data):
facility = self.context["facility"]
if "name" in data:
Expand Down
2 changes: 2 additions & 0 deletions care/facility/api/serializers/facility.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,8 @@ class Meta:
read_only_fields = ("modified_date", "created_date")

def validate_middleware_address(self, value):
if not value:
raise serializers.ValidationError("Middleware Address is required")
value = value.strip()
if not value:
return value
Expand Down
9 changes: 8 additions & 1 deletion care/facility/api/viewsets/asset.py
Original file line number Diff line number Diff line change
Expand Up @@ -321,10 +321,17 @@ def operate_assets(self, request, *args, **kwargs):
try:
action = request.data["action"]
asset: Asset = self.get_object()
middleware_hostname = (
asset.meta.get(
"middleware_hostname",
asset.current_location.middleware_address,
)
or asset.current_location.facility.middleware_address
)
asset_class: BaseAssetIntegration = AssetClasses[asset.asset_class].value(
{
**asset.meta,
"middleware_hostname": asset.current_location.facility.middleware_address,
"middleware_hostname": middleware_hostname,
}
)
result = asset_class.handle_action(action)
Expand Down
17 changes: 17 additions & 0 deletions care/facility/migrations/0389_assetlocation_middleware_address.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Generated by Django 4.2.2 on 2023-09-29 06:54

from django.db import migrations, models


class Migration(migrations.Migration):
dependencies = [
("facility", "0388_goal_goalentry_goalproperty_goalpropertyentry"),
]

operations = [
migrations.AddField(
model_name="assetlocation",
name="middleware_address",
field=models.CharField(blank=True, default=None, max_length=200, null=True),
),
]
4 changes: 4 additions & 0 deletions care/facility/models/asset.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ class RoomType(enum.Enum):
Facility, on_delete=models.PROTECT, null=False, blank=False
)

middleware_address = models.CharField(
null=True, blank=True, default=None, max_length=200
)


class AssetType(enum.Enum):
INTERNAL = 50
Expand Down
15 changes: 12 additions & 3 deletions care/facility/tasks/asset_monitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,18 @@ def check_asset_status():
continue
try:
# Fetching middleware hostname
hostname = asset.meta.get(
"middleware_hostname",
asset.current_location.facility.middleware_address,
hostname = (
asset.meta.get(
"middleware_hostname",
asset.current_location.middleware_address,
)
or asset.current_location.facility.middleware_address
)
if not hostname:
logger.warn(
f"Asset {asset.external_id} does not have a middleware hostname"
)
continue
result: Any = None

# Checking if middleware status is already cached
Expand Down Expand Up @@ -62,6 +70,7 @@ def check_asset_status():
asset_class="ONVIF"
).filter(
Q(meta__middleware_hostname=hostname)
| Q(current_location__middleware_address=hostname)
| Q(current_location__facility__middleware_address=hostname)
)
assets_config = []
Expand Down
36 changes: 33 additions & 3 deletions care/facility/tests/test_asset_location_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,21 +27,51 @@ def test_retrieve_asset_location(self):
f"/api/v1/facility/{self.facility.external_id}/asset_location/{self.asset_location.external_id}/"
)
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertContains(response, self.asset_location.external_id)
self.assertEqual(response.data["id"], str(self.asset_location.external_id))
self.assertEqual(
response.data["middleware_address"], self.asset_location.middleware_address
)

def test_create_asset_location(self):
sample_data = {"name": "Test Asset Location"}
sample_data = {
"name": "Test Asset Location",
"middleware_address": "example.com",
}
response = self.client.post(
f"/api/v1/facility/{self.facility.external_id}/asset_location/",
sample_data,
)
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
self.assertEqual(response.data["name"], sample_data["name"])
self.assertEqual(
response.data["middleware_address"], sample_data["middleware_address"]
)

def test_update_asset_location(self):
sample_data = {"name": "Updated Test Asset Location"}
sample_data = {
"name": "Updated Test Asset Location",
"middleware_address": "updated.example.com",
}
response = self.client.patch(
f"/api/v1/facility/{self.facility.external_id}/asset_location/{self.asset_location.external_id}/",
sample_data,
)
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.data["name"], sample_data["name"])
self.assertEqual(
response.data["middleware_address"], sample_data["middleware_address"]
)

def test_create_asset_location_invalid_middleware(self):
sample_data = {
"name": "Test Asset Location",
"middleware_address": "https://invalid.middleware.///",
}
response = self.client.post(
f"/api/v1/facility/{self.facility.external_id}/asset_location/",
sample_data,
)
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
self.assertEqual(
response.data["middleware_address"][0].code, "invalid_domain_name"
)
7 changes: 6 additions & 1 deletion care/utils/tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,12 @@ def create_consultation(

@classmethod
def create_asset_location(cls, facility: Facility, **kwargs) -> AssetLocation:
data = {"name": "asset1 location", "location_type": 1, "facility": facility}
data = {
"name": "asset1 location",
"location_type": 1,
"facility": facility,
"middleware_address": "example.com",
}
data.update(kwargs)
return AssetLocation.objects.create(**data)

Expand Down

0 comments on commit 0794d08

Please sign in to comment.