Skip to content

Commit 9b2c48f

Browse files
committed
feat: reattach event streams when rulebook changes
Perform source swapping at activation editing when event source mapping is provided, no matter a new rulebook is selected or not. Clear existing event stream maaping if a new rulebook is selected but no event source mapping is provided. AAP-37298: Reattach event streams when rulebook has changed
1 parent 1a8adb6 commit 9b2c48f

File tree

2 files changed

+93
-24
lines changed

2 files changed

+93
-24
lines changed

src/aap_eda/api/serializers/activation.py

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -585,9 +585,20 @@ def prepare_update(self, activation: models.Activation):
585585
else:
586586
vault_data = VaultData()
587587
if self.validated_data.get("source_mappings", []):
588+
if not rulebook_id:
589+
# load the original ruleset
590+
self.validated_data[
591+
"rulebook_rulesets"
592+
] = activation.rulebook.rulesets
593+
594+
# update with new event streams
588595
self.validated_data[
589596
"rulebook_rulesets"
590597
] = _update_event_stream_source(self.validated_data, vault_data)
598+
elif rulebook_id:
599+
# user selects a rulebook but no mapping, clear existing mappings
600+
self.validated_data["source_mappings"] = ""
601+
self.validated_data["event_streams"] = []
591602

592603
if self.validated_data.get("eda_credentials"):
593604
_update_extra_vars_from_eda_credentials(
@@ -611,8 +622,8 @@ def update(
611622
self, instance: models.Activation, validated_data: dict
612623
) -> None:
613624
update_fields = []
614-
eda_credentials = []
615-
event_streams = []
625+
eda_credentials = None
626+
event_streams = None
616627
for key, value in validated_data.items():
617628
if key == "eda_credentials":
618629
eda_credentials = value
@@ -624,10 +635,16 @@ def update(
624635
update_fields.append(key)
625636

626637
instance.save(update_fields=update_fields)
627-
if eda_credentials:
628-
instance.eda_credentials.set(eda_credentials)
629-
if event_streams:
630-
instance.event_streams.set(event_streams)
638+
if eda_credentials is not None:
639+
if eda_credentials:
640+
instance.eda_credentials.set(eda_credentials)
641+
else:
642+
instance.eda_credentials.clear()
643+
if event_streams is not None:
644+
if event_streams:
645+
instance.event_streams.set(event_streams)
646+
else:
647+
instance.event_streams.clear()
631648

632649
def to_representation(self, activation):
633650
extra_var = (
@@ -1193,7 +1210,7 @@ def _validate_sources_with_event_streams(data: dict) -> None:
11931210
if source_map["rulebook_hash"] != rulebook_hash:
11941211
msg = (
11951212
"Rulebook has changed since the sources were mapped. "
1196-
"Please reattach Event streams again"
1213+
"Please reattach event streams"
11971214
)
11981215

11991216
raise serializers.ValidationError(

tests/integration/api/test_activation_with_event_stream.py

Lines changed: 69 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -558,7 +558,7 @@ def test_create_activation_with_bad_rulebook_hash(
558558
assert response.status_code == status.HTTP_400_BAD_REQUEST
559559
assert str(response.data[SOURCE_MAPPING_ERROR_KEY][0]) == (
560560
"Rulebook has changed since the sources were mapped."
561-
" Please reattach Event streams again"
561+
" Please reattach event streams"
562562
)
563563

564564

@@ -811,25 +811,20 @@ def test_update_activation_with_everything(
811811
"source_name": f"{DEFAULT_SOURCE_NAME_PREFIX}1",
812812
}
813813
)
814-
# to be enabled in another PR
815-
"""
816814
test_activation2["source_mappings"] = yaml.dump(source_mappings2)
817-
"""
815+
818816
response = admin_client.patch(
819817
f"{api_url_v1}/activations/{activation_id}/", data=test_activation2
820818
)
821-
assert response.status_code == status.HTTP_200_OK
822-
data = response.data
823-
activation = models.Activation.objects.filter(id=data["id"]).first()
824-
assert activation.rulebook_name == f"{TEST_RULEBOOK['name']}2"
825-
"""
826-
swapped_ruleset = yaml.safe_load(activation.rulebook_rulesets)
827-
assert sorted(swapped_ruleset[0]["sources"][0].keys()) == [
828-
"ansible.eda.pg_listener",
829-
"name",
830-
]
831-
assert data["event_streams"][0]["name"] == "demo-2"
832-
"""
819+
assert_updated_event_stream_mapping(
820+
response,
821+
["ansible.eda.pg_listener", "name"],
822+
test_activation2["source_mappings"],
823+
"demo-2",
824+
)
825+
activation = models.Activation.objects.filter(
826+
id=response.data["id"]
827+
).first()
833828
for key, val in test_activation2.items():
834829
if key == "extra_var":
835830
assert activation.extra_var == (
@@ -842,6 +837,63 @@ def test_update_activation_with_everything(
842837
assert activation.eda_credentials.all()[0].id == val[0]
843838
continue
844839
if key == "source_mappings":
845-
assert activation.source_mappings.strip() == val.strip()
846840
continue
847841
assert getattr(activation, key) == val
842+
843+
# test unchanged event stream mapping
844+
test_activation3 = {"name": "name3"}
845+
response = admin_client.patch(
846+
f"{api_url_v1}/activations/{activation_id}/", data=test_activation3
847+
)
848+
assert_updated_event_stream_mapping(
849+
response,
850+
["ansible.eda.pg_listener", "name"],
851+
test_activation2["source_mappings"],
852+
"demo-2",
853+
)
854+
855+
# test only changing event stream mapping
856+
source_mappings = []
857+
for event_stream in fks["event_streams"]:
858+
source_mappings.append(
859+
{
860+
"event_stream_name": event_stream.name,
861+
"event_stream_id": event_stream.id,
862+
"rulebook_hash": get_rulebook_hash(LEGACY_TEST_RULESETS),
863+
"source_name": f"{DEFAULT_SOURCE_NAME_PREFIX}1",
864+
}
865+
)
866+
test_activation4 = {"source_mappings": yaml.dump(source_mappings)}
867+
response = admin_client.patch(
868+
f"{api_url_v1}/activations/{activation_id}/", data=test_activation4
869+
)
870+
assert_updated_event_stream_mapping(
871+
response,
872+
["ansible.eda.pg_listener", "name"],
873+
test_activation4["source_mappings"],
874+
"demo",
875+
)
876+
877+
# test clearing event stream mapping
878+
test_activation5 = {"rulebook_id": fks2["rulebook_id"]}
879+
response = admin_client.patch(
880+
f"{api_url_v1}/activations/{activation_id}/", data=test_activation5
881+
)
882+
assert_updated_event_stream_mapping(
883+
response, ["ansible.eda.range"], "", ""
884+
)
885+
886+
887+
def assert_updated_event_stream_mapping(
888+
response, sources: list, source_mappings: str, event_stream_name: str
889+
):
890+
assert response.status_code == status.HTTP_200_OK
891+
data = response.data
892+
activation = models.Activation.objects.filter(id=data["id"]).first()
893+
swapped_ruleset = yaml.safe_load(activation.rulebook_rulesets)
894+
assert sorted(swapped_ruleset[0]["sources"][0].keys()) == sources
895+
assert data["source_mappings"].strip() == source_mappings.strip()
896+
if event_stream_name:
897+
assert data["event_streams"][0]["name"] == "demo-2"
898+
else:
899+
assert data["event_streams"] == []

0 commit comments

Comments
 (0)