Skip to content

Commit

Permalink
Upsert report recipe in REST API (#3968)
Browse files Browse the repository at this point in the history
Co-authored-by: Jan Klopper <[email protected]>
  • Loading branch information
dekkers and underdarknl authored Dec 19, 2024
1 parent 7fe6287 commit 945ba6e
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 20 deletions.
2 changes: 1 addition & 1 deletion rocky/reports/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def to_representation(self, instance):


class ReportRecipeSerializer(serializers.Serializer):
id = serializers.UUIDField(source="recipe_id", read_only=True)
id = serializers.UUIDField(source="recipe_id", required=False)
report_name_format = serializers.CharField()
subreport_name_format = serializers.CharField(required=False, allow_blank=True)

Expand Down
66 changes: 47 additions & 19 deletions rocky/reports/viewsets.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,7 @@ def get_object(self) -> ReportRecipe:

return recipe

def get_schedule_id(self) -> str | None:
pk = self.kwargs["pk"]

def get_schedule_id(self, pk: str) -> str | None:
filters = {"filters": [{"column": "data", "field": "report_recipe_id", "operator": "eq", "value": pk}]}

response = self.scheduler_client.post_schedule_search(filters)
Expand All @@ -103,10 +101,25 @@ def get_schedule_id(self) -> str | None:
return str(response.results[0].id)

def perform_create(self, serializer: ReportRecipeSerializer) -> None:
deadline_at = serializer.validated_data.pop("start_date", datetime.now(timezone.utc).date().isoformat())
recipe_id = uuid4()
data = serializer.validated_data

deadline_at = data.pop("start_date", None)

update = False
if "recipe_id" in data:
# Update the already existing recipe if a recipe with this id already exists.
try:
self.octopoes_api_connector.get(
Reference.from_str(f"ReportRecipe|{data['recipe_id']}"), valid_time=self.valid_time
)
except ObjectNotFoundException:
pass
else:
update = True
else:
data["recipe_id"] = uuid4()

report_recipe = ReportRecipe.model_validate({"recipe_id": recipe_id, **serializer.validated_data})
report_recipe = ReportRecipe.model_validate(data)

create_ooi(
api_connector=self.octopoes_api_connector,
Expand All @@ -115,24 +128,39 @@ def perform_create(self, serializer: ReportRecipeSerializer) -> None:
observed_at=self.valid_time,
)

report_task = ReportTask(
organisation_id=self.organization.code, report_recipe_id=str(report_recipe.recipe_id)
).model_dump()

schedule_request = ScheduleRequest(
scheduler_id=f"report-{self.organization.code}",
data=report_task,
schedule=report_recipe.cron_expression,
deadline_at=deadline_at,
)
if update:
schedule_id = self.get_schedule_id(str(data["recipe_id"]))
if not schedule_id:
raise APIException("Schedule for recipe does not exist")

if deadline_at:
self.scheduler_client.patch_schedule(
schedule_id, params={"schedule": report_recipe.cron_expression, "deadline_at": deadline_at}
)
else:
self.scheduler_client.patch_schedule(schedule_id, params={"schedule": report_recipe.cron_expression})
else:
report_task = ReportTask(
organisation_id=self.organization.code, report_recipe_id=str(report_recipe.recipe_id)
).model_dump()

if not deadline_at:
deadline_at = datetime.now(timezone.utc).date().isoformat()

schedule_request = ScheduleRequest(
scheduler_id=f"report-{self.organization.code}",
data=report_task,
schedule=report_recipe.cron_expression,
deadline_at=deadline_at,
)

self.scheduler_client.post_schedule(schedule=schedule_request)
self.scheduler_client.post_schedule(schedule=schedule_request)

# This will make DRF return the new instance with the generated id
serializer.instance = report_recipe

def perform_update(self, serializer: ReportRecipeSerializer) -> None:
schedule_id = self.get_schedule_id()
schedule_id = self.get_schedule_id(self.kwargs["pk"])
if not schedule_id:
raise APIException("Schedule for recipe does not exist")

Expand All @@ -154,7 +182,7 @@ def perform_update(self, serializer: ReportRecipeSerializer) -> None:
serializer.instance = report_recipe

def perform_destroy(self, instance: ReportRecipe) -> None:
schedule_id = self.get_schedule_id()
schedule_id = self.get_schedule_id(self.kwargs["pk"])

# If we would return an error here this would mean we can never delete a
# recipe in octopoes that doesn't have a schedule anymore. This could
Expand Down

0 comments on commit 945ba6e

Please sign in to comment.