Skip to content

Commit 6e7fe6e

Browse files
committed
feat: Trigger task status
1 parent 0634a4f commit 6e7fe6e

File tree

1 file changed

+142
-98
lines changed

1 file changed

+142
-98
lines changed

apps/trigger/serializers/trigger.py

Lines changed: 142 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -101,84 +101,23 @@ def validate_input_field_list(self, value):
101101
return value
102102

103103

104-
class TriggerTaskCreateRequest(serializers.Serializer):
105-
source_type = serializers.ChoiceField(required=True, choices=TriggerTaskTypeChoices)
106-
source_id = serializers.CharField(required=True, label=_('source_id'))
107-
is_active = serializers.BooleanField(required=False, label=_('Is active'))
108-
meta = serializers.DictField(default=dict, required=False)
109-
parameter = serializers.DictField(default=dict, required=False)
104+
class TriggerValidationMixin:
110105

111106
def validate(self, attrs):
112-
source_type = attrs.get('source_type')
113-
parameter = attrs.get('parameter')
114-
if source_type == TriggerTaskTypeChoices.APPLICATION:
115-
serializer = ApplicationTaskParameterSerializer(data=parameter)
116-
serializer.is_valid(raise_exception=True)
117-
attrs['parameter'] = serializer.validated_data
118-
if source_type == TriggerTaskTypeChoices.TOOL:
119-
serializer = ToolTaskParameterSerializer(data=parameter)
120-
serializer.is_valid(raise_exception=True)
121-
attrs['parameter'] = serializer.validated_data
122-
123-
return attrs
124-
125-
126-
class TriggerTaskEditRequest(serializers.Serializer):
127-
source_type = serializers.ChoiceField(required=False, choices=TriggerTaskTypeChoices)
128-
source_id = serializers.CharField(required=False, label=_('source_id'))
129-
is_active = serializers.BooleanField(required=False, label=_('Is active'))
130-
meta = serializers.DictField(default=dict, required=False)
131-
parameter = serializers.DictField(default=dict, required=False)
132-
133-
def validate(self, attrs):
134-
source_type = attrs.get('source_type')
135-
parameter = attrs.get('parameter')
136-
if source_type == TriggerTaskTypeChoices.APPLICATION:
137-
serializer = ApplicationTaskParameterSerializer(data=parameter)
138-
serializer.is_valid(raise_exception=True)
139-
attrs['parameter'] = serializer.validated_data
140-
if source_type == TriggerTaskTypeChoices.TOOL:
141-
serializer = ToolTaskParameterSerializer(data=parameter)
142-
serializer.is_valid(raise_exception=True)
143-
attrs['parameter'] = serializer.validated_data
107+
# trigger_setting 校验
108+
trigger_type = attrs.get('trigger_type')
109+
trigger_setting = attrs.get('trigger_setting')
110+
111+
if trigger_type and trigger_setting:
112+
if trigger_type == TriggerTypeChoices.SCHEDULED:
113+
self._validate_scheduled_setting(trigger_setting)
114+
elif trigger_type == TriggerTypeChoices.EVENT:
115+
self._validate_event_setting(trigger_setting)
116+
else:
117+
raise AppApiException(500, _('Error trigger type'))
144118

145119
return attrs
146120

147-
148-
class TriggerEditRequest(serializers.Serializer):
149-
name = serializers.CharField(required=False, label=_('trigger name'))
150-
desc = serializers.CharField(required=False, allow_null=True, allow_blank=True, label=_('trigger description'))
151-
trigger_type = serializers.ChoiceField(required=False, choices=TriggerTypeChoices)
152-
trigger_setting = serializers.DictField(required=False, label=_("trigger setting"))
153-
meta = serializers.DictField(default=dict, required=False)
154-
trigger_task = TriggerTaskEditRequest(many=True, required=False)
155-
156-
157-
class TriggerCreateRequest(serializers.Serializer):
158-
id = serializers.UUIDField(required=True, label=_("Trigger ID"))
159-
name = serializers.CharField(required=True, label=_('trigger name'))
160-
desc = serializers.CharField(required=False, allow_null=True, allow_blank=True, label=_('trigger description'))
161-
trigger_type = serializers.ChoiceField(required=True, choices=TriggerTypeChoices)
162-
trigger_setting = serializers.DictField(required=True, label=_("trigger setting"))
163-
meta = serializers.DictField(default=dict, required=False)
164-
is_active = serializers.BooleanField(required=False, label=_('Is active'))
165-
trigger_task = TriggerTaskCreateRequest(many=True)
166-
167-
def is_valid(self, *, raise_exception=False):
168-
super().is_valid(raise_exception=True)
169-
trigger_type = self.data.get('trigger_type')
170-
trigger_setting = self.data.get('trigger_setting', {})
171-
172-
if trigger_type == TriggerTypeChoices.SCHEDULED:
173-
self._validate_scheduled_setting(trigger_setting)
174-
175-
elif trigger_type == TriggerTypeChoices.EVENT:
176-
self._validate_event_setting(trigger_setting)
177-
else:
178-
raise AppApiException(500, _('Error trigger type'))
179-
180-
return True
181-
182121
@staticmethod
183122
def _validate_required_field(setting, field_name, trigger_type):
184123
if field_name not in setting:
@@ -288,6 +227,70 @@ def _validate_event_setting(setting):
288227
})
289228

290229

230+
class TriggerTaskCreateRequest(serializers.Serializer):
231+
source_type = serializers.ChoiceField(required=True, choices=TriggerTaskTypeChoices)
232+
source_id = serializers.CharField(required=True, label=_('source_id'))
233+
is_active = serializers.BooleanField(required=False, label=_('Is active'))
234+
meta = serializers.DictField(default=dict, required=False)
235+
parameter = serializers.DictField(default=dict, required=False)
236+
237+
def validate(self, attrs):
238+
source_type = attrs.get('source_type')
239+
parameter = attrs.get('parameter')
240+
if source_type == TriggerTaskTypeChoices.APPLICATION:
241+
serializer = ApplicationTaskParameterSerializer(data=parameter)
242+
serializer.is_valid(raise_exception=True)
243+
attrs['parameter'] = serializer.validated_data
244+
if source_type == TriggerTaskTypeChoices.TOOL:
245+
serializer = ToolTaskParameterSerializer(data=parameter)
246+
serializer.is_valid(raise_exception=True)
247+
attrs['parameter'] = serializer.validated_data
248+
249+
return attrs
250+
251+
252+
class TriggerTaskEditRequest(serializers.Serializer):
253+
source_type = serializers.ChoiceField(required=False, choices=TriggerTaskTypeChoices)
254+
source_id = serializers.CharField(required=False, label=_('source_id'))
255+
is_active = serializers.BooleanField(required=False, label=_('Is active'))
256+
meta = serializers.DictField(default=dict, required=False)
257+
parameter = serializers.DictField(default=dict, required=False)
258+
259+
def validate(self, attrs):
260+
source_type = attrs.get('source_type')
261+
parameter = attrs.get('parameter')
262+
if source_type == TriggerTaskTypeChoices.APPLICATION:
263+
serializer = ApplicationTaskParameterSerializer(data=parameter)
264+
serializer.is_valid(raise_exception=True)
265+
attrs['parameter'] = serializer.validated_data
266+
if source_type == TriggerTaskTypeChoices.TOOL:
267+
serializer = ToolTaskParameterSerializer(data=parameter)
268+
serializer.is_valid(raise_exception=True)
269+
attrs['parameter'] = serializer.validated_data
270+
271+
return attrs
272+
273+
274+
class TriggerEditRequest(TriggerValidationMixin, serializers.Serializer):
275+
name = serializers.CharField(required=False, label=_('trigger name'))
276+
desc = serializers.CharField(required=False, allow_null=True, allow_blank=True, label=_('trigger description'))
277+
trigger_type = serializers.ChoiceField(required=False, choices=TriggerTypeChoices)
278+
trigger_setting = serializers.DictField(required=False, label=_("trigger setting"))
279+
meta = serializers.DictField(default=dict, required=False)
280+
trigger_task = TriggerTaskEditRequest(many=True, required=False)
281+
282+
283+
class TriggerCreateRequest(TriggerValidationMixin, serializers.Serializer):
284+
id = serializers.UUIDField(required=True, label=_("Trigger ID"))
285+
name = serializers.CharField(required=True, label=_('trigger name'))
286+
desc = serializers.CharField(required=False, allow_null=True, allow_blank=True, label=_('trigger description'))
287+
trigger_type = serializers.ChoiceField(required=True, choices=TriggerTypeChoices)
288+
trigger_setting = serializers.DictField(required=True, label=_("trigger setting"))
289+
meta = serializers.DictField(default=dict, required=False)
290+
is_active = serializers.BooleanField(required=False, label=_('Is active'))
291+
trigger_task = TriggerTaskCreateRequest(many=True)
292+
293+
291294
class TriggerModelSerializer(serializers.ModelSerializer):
292295
class Meta:
293296
model = Trigger
@@ -347,29 +350,60 @@ def insert(self, instance, with_valid=True):
347350

348351
trigger_tasks = valid_data.get('trigger_task')
349352
if trigger_tasks:
353+
354+
is_active_map = self.batch_get_source_active_status(trigger_tasks)
355+
350356
trigger_task_models = [
351-
self.to_trigger_task_model(trigger_id, task) for task in
352-
trigger_tasks
357+
TriggerTask(
358+
id=uuid.uuid7(),
359+
trigger_id=trigger_id,
360+
source_type=task_data.get('source_type'),
361+
source_id=task_data.get('source_id'),
362+
is_active=is_active_map.get((task_data.get('source_type'), task_data.get('source_id'))) or False,
363+
parameter=task_data.get('parameter', {}),
364+
meta=task_data.get('meta', {})
365+
)
366+
for task_data in trigger_tasks
353367
]
368+
354369
TriggerTask.objects.bulk_create(trigger_task_models)
355370
else:
356371
raise AppApiException(500, _('Trigger task can not be empty'))
357372

358373
return TriggerResponse(trigger_model).data
359374

360-
def to_trigger_task_model(self, trigger_id: str, task_data: dict):
361-
source_type = task_data.get('source_type')
362-
source_id = task_data.get('source_id')
363-
is_active = self.is_active_source(source_type, source_id)
364-
return TriggerTask(
365-
id=uuid.uuid7(),
366-
trigger_id=trigger_id,
367-
source_type=source_type,
368-
source_id=source_id,
369-
is_active=is_active,
370-
parameter=task_data.get('parameter', {}),
371-
meta=task_data.get('meta', {})
372-
)
375+
@staticmethod
376+
def batch_get_source_active_status(trigger_tasks: list) -> Dict[tuple, bool]:
377+
"""
378+
批量查询所有 source 的 is_active 状态
379+
返回: {(source_type, source_id): is_active}
380+
"""
381+
config = {
382+
TriggerTaskTypeChoices.APPLICATION: (Application, 'is_publish'),
383+
TriggerTaskTypeChoices.TOOL: (Tool, 'is_active'),
384+
}
385+
source_ids_by_type = {}
386+
387+
for task_data in trigger_tasks:
388+
source_type = task_data.get('source_type')
389+
source_id = task_data.get('source_id')
390+
391+
if source_type not in config:
392+
raise AppApiException(500, _('Error source type'))
393+
394+
if source_type not in source_ids_by_type:
395+
source_ids_by_type[source_type] = []
396+
source_ids_by_type[source_type].append(source_id)
397+
398+
is_active_map = {}
399+
for source_type, source_ids in source_ids_by_type.items():
400+
source_model, field = config[source_type]
401+
source_query_set = QuerySet(source_model).filter(id__in=source_ids).values('id', field)
402+
403+
for source in source_query_set:
404+
is_active_map[(source_type, str(source['id']))] = source[field]
405+
406+
return is_active_map
373407

374408
@staticmethod
375409
def is_active_source(source_type: str, source_id: str):
@@ -459,36 +493,46 @@ def edit(self, instance: Dict, with_valid=True):
459493
self.is_valid()
460494
TriggerEditRequest(data=instance).is_valid(raise_exception=True)
461495
trigger_id = self.data.get('trigger_id')
462-
trigger = Trigger.objects.filter(workspace_id=self.data.get('workspace_id'), id=trigger_id).first()
496+
workspace_id = self.data.get('workspace_id')
497+
trigger = Trigger.objects.filter(workspace_id=workspace_id, id=trigger_id).first()
463498
if not trigger:
464499
raise serializers.ValidationError(_('Trigger not found'))
465500

466-
trigger_edit_field_list = ['name', 'desc', 'trigger_type', 'trigger_setting', 'meta', 'is_active']
501+
trigger_direct_edit_field_list = ['name', 'desc', 'trigger_type', 'trigger_setting', 'meta', 'is_active']
502+
trigger_deploy_edit_field_list = ['trigger_type', 'trigger_setting', 'is_active']
503+
# is need to redeploy
504+
need_redeploy = any(field in instance for field in trigger_deploy_edit_field_list)
467505

468-
for field in trigger_edit_field_list:
506+
for field in trigger_direct_edit_field_list:
469507
if field in instance:
470508
trigger.__setattr__(field, instance.get(field))
471509
trigger.save()
472510
# 处理trigger task
473511
trigger_tasks = instance.get('trigger_task')
474-
if trigger_tasks:
475-
TriggerTask.objects.filter(trigger_id=trigger_id).delete()
512+
513+
if trigger_tasks is not None:
514+
is_active_map = TriggerSerializer.batch_get_source_active_status(trigger_tasks)
515+
476516
trigger_task_model_list = [TriggerTask(
477517
id=task_data.get('id') or uuid.uuid7(),
478518
trigger_id=trigger_id,
479519
source_type=task_data.get('source_type'),
480520
source_id=task_data.get('source_id'),
481-
is_active=task_data.get('is_active', False),
521+
is_active=is_active_map.get((task_data.get('source_type'), task_data.get('source_id'))) or False,
482522
parameter=task_data.get('parameter', []),
483523
meta=task_data.get('meta', {})
484524
) for task_data in trigger_tasks]
525+
526+
TriggerTask.objects.filter(trigger_id=trigger_id).delete()
527+
485528
TriggerTask.objects.bulk_create(trigger_task_model_list)
486529

487530
# 重新部署触发器任务
488-
if trigger.is_active:
489-
deploy(TriggerModelSerializer(trigger).data, **{})
490-
else:
491-
undeploy(TriggerModelSerializer(trigger).data, **{})
531+
if need_redeploy:
532+
if trigger.is_active:
533+
deploy(TriggerModelSerializer(trigger).data, **{})
534+
else:
535+
undeploy(TriggerModelSerializer(trigger).data, **{})
492536

493537
return self.one(with_valid=False)
494538

0 commit comments

Comments
 (0)