5
5
6
6
`init` should return a __call__able
7
7
"""
8
+ import logging
8
9
9
10
from src .app .environment import get_settings
10
- from src .jbi .bugzilla import BugzillaWebhookRequest
11
+ from src .jbi .bugzilla import BugzillaBug , BugzillaWebhookRequest
11
12
from src .jbi .errors import ActionError
12
13
from src .jbi .services import get_bugzilla , get_jira , getbug_as_bugzilla_object
13
14
15
+ settings = get_settings ()
16
+
17
+ logger = logging .getLogger (__name__ )
18
+
14
19
15
20
def init (whiteboard_tag , jira_project_key , ** kwargs ):
16
21
"""Function that takes required and optional params and returns a callable object"""
@@ -22,69 +27,116 @@ def init(whiteboard_tag, jira_project_key, **kwargs):
22
27
class DefaultExecutor :
23
28
"""Callable class that encapsulates the default action."""
24
29
25
- def __init__ (self , ** kwargs ):
30
+ def __init__ (self , whiteboard_tag , jira_project_key , ** kwargs ):
26
31
"""Initialize DefaultExecutor Object"""
27
- self .parameters = kwargs
28
- self .whiteboard_tag = kwargs . get ( "whiteboard_tag" )
29
- self . jira_project_key = kwargs . get ( "jira_project_key" )
32
+ self .whiteboard_tag = whiteboard_tag
33
+ self .jira_project_key = jira_project_key
34
+
30
35
self .bugzilla_client = get_bugzilla ()
31
36
self .jira_client = get_jira ()
32
- self .settings = get_settings ()
33
37
34
38
def __call__ ( # pylint: disable=inconsistent-return-statements
35
39
self , payload : BugzillaWebhookRequest
36
40
):
37
41
"""Called from BZ webhook when default action is used. All default-action webhook-events are processed here."""
38
42
target = payload .event .target # type: ignore
39
43
if target == "comment" :
40
- return self .comment_create_or_noop (payload = payload )
44
+ bug_obj = payload .bug
45
+ return self .comment_create_or_noop (payload = payload , bug_obj = bug_obj ) # type: ignore
41
46
if target == "bug" :
42
- return self .bug_create_or_update (payload = payload )
47
+ bug_obj = getbug_as_bugzilla_object (payload )
48
+ return self .bug_create_or_update (payload = payload , bug_obj = bug_obj )
49
+ logger .debug (
50
+ "Ignore event target %r" ,
51
+ target ,
52
+ extra = {
53
+ "request" : payload .json (),
54
+ },
55
+ )
43
56
44
- def comment_create_or_noop (self , payload : BugzillaWebhookRequest ):
57
+ def comment_create_or_noop (
58
+ self , payload : BugzillaWebhookRequest , bug_obj : BugzillaBug
59
+ ):
45
60
"""Confirm issue is already linked, then apply comments; otherwise noop"""
46
- bug_obj = payload .bug
47
- linked_issue_key = bug_obj .extract_from_see_also () # type: ignore
61
+ linked_issue_key = bug_obj .extract_from_see_also ()
48
62
63
+ log_context = {
64
+ "request" : payload .json (),
65
+ "bug" : bug_obj .json (),
66
+ }
49
67
if not linked_issue_key :
50
- # noop
68
+ logger .debug (
69
+ "No Jira issue linked to Bug %s" ,
70
+ bug_obj .id ,
71
+ extra = log_context ,
72
+ )
51
73
return {"status" : "noop" }
52
- # else
74
+
53
75
jira_response = self .jira_client .issue_add_comment (
54
76
issue_key = linked_issue_key ,
55
77
comment = payload .map_as_jira_comment (),
56
78
)
79
+ logger .debug (
80
+ "Comment added to Jira issue %s" ,
81
+ linked_issue_key ,
82
+ extra = log_context ,
83
+ )
57
84
return {"status" : "comment" , "jira_response" : jira_response }
58
85
59
86
def bug_create_or_update (
60
- self , payload : BugzillaWebhookRequest
87
+ self , payload : BugzillaWebhookRequest , bug_obj : BugzillaBug
61
88
): # pylint: disable=too-many-locals
62
89
"""Create and link jira issue with bug, or update; rollback if multiple events fire"""
63
- bug_obj = getbug_as_bugzilla_object (payload )
64
90
linked_issue_key = bug_obj .extract_from_see_also () # type: ignore
65
- if linked_issue_key :
66
- # update
67
- comments = payload .map_as_comments ()
68
- jira_response_update = self .jira_client .update_issue_field (
69
- key = linked_issue_key , fields = bug_obj .map_as_jira_issue ()
91
+ if not linked_issue_key :
92
+ return self .create_and_link_issue (payload , bug_obj )
93
+
94
+ log_context = {
95
+ "request" : payload .json (),
96
+ "bug" : bug_obj .json (),
97
+ }
98
+ logger .debug (
99
+ "Update fields of Jira issue %s for Bug %s" ,
100
+ linked_issue_key ,
101
+ bug_obj .id ,
102
+ extra = log_context ,
103
+ )
104
+ jira_response_update = self .jira_client .update_issue_field (
105
+ key = linked_issue_key , fields = bug_obj .map_as_jira_issue ()
106
+ )
107
+
108
+ comments = payload .map_as_comments ()
109
+ jira_response_comments = []
110
+ for i , comment in enumerate (comments ):
111
+ logger .debug (
112
+ "Create comment #%s on Jira issue %s" ,
113
+ i + 1 ,
114
+ linked_issue_key ,
115
+ extra = log_context ,
70
116
)
71
- # comment
72
- jira_response_comments = []
73
- for comment in comments :
74
- jira_response_comments .append (
75
- self .jira_client .issue_add_comment (
76
- issue_key = linked_issue_key , comment = comment
77
- )
117
+ jira_response_comments .append (
118
+ self .jira_client .issue_add_comment (
119
+ issue_key = linked_issue_key , comment = comment
78
120
)
79
- return {
80
- "status" : "update" ,
81
- "jira_responses" : [jira_response_update , jira_response_comments ],
82
- }
83
- # else: create jira issue
84
- return self .create_and_link_issue (payload , bug_obj )
85
-
86
- def create_and_link_issue (self , payload , bug_obj ):
121
+ )
122
+ return {
123
+ "status" : "update" ,
124
+ "jira_responses" : [jira_response_update , jira_response_comments ],
125
+ }
126
+
127
+ def create_and_link_issue (
128
+ self , payload , bug_obj
129
+ ): # pylint: disable=too-many-locals
87
130
"""create jira issue and establish link between bug and issue; rollback/delete if required"""
131
+ log_context = {
132
+ "request" : payload .json (),
133
+ "bug" : bug_obj .json (),
134
+ }
135
+ logger .debug (
136
+ "Create new Jira issue for Bug %s" ,
137
+ bug_obj .id ,
138
+ extra = log_context ,
139
+ )
88
140
comment_list = self .bugzilla_client .get_comments (idlist = [bug_obj .id ])
89
141
fields = {
90
142
** bug_obj .map_as_jira_issue (), # type: ignore
@@ -116,16 +168,34 @@ def create_and_link_issue(self, payload, bug_obj):
116
168
and jira_key_in_response != jira_key_in_bugzilla
117
169
)
118
170
if _duplicate_creation_event :
171
+ logger .warning (
172
+ "Delete duplicated Jira issue %s from Bug %s" ,
173
+ jira_key_in_response ,
174
+ bug_obj .id ,
175
+ extra = log_context ,
176
+ )
119
177
jira_response_delete = self .jira_client .delete_issue (
120
178
issue_id_or_key = jira_key_in_response
121
179
)
122
180
return {"status" : "duplicate" , "jira_response" : jira_response_delete }
123
- # else:
124
- jira_url = f"{ self .settings .jira_base_url } browse/{ jira_key_in_response } "
181
+
182
+ jira_url = f"{ settings .jira_base_url } browse/{ jira_key_in_response } "
183
+ logger .debug (
184
+ "Link %r on Bug %s" ,
185
+ jira_url ,
186
+ bug_obj .id ,
187
+ extra = log_context ,
188
+ )
125
189
update = self .bugzilla_client .build_update (see_also_add = jira_url )
126
190
bugzilla_response = self .bugzilla_client .update_bugs ([bug_obj .id ], update )
127
191
128
- bugzilla_url = f"{ self .settings .bugzilla_base_url } /show_bug.cgi?id={ bug_obj .id } "
192
+ bugzilla_url = f"{ settings .bugzilla_base_url } /show_bug.cgi?id={ bug_obj .id } "
193
+ logger .debug (
194
+ "Link %r on Jira issue %s" ,
195
+ bugzilla_url ,
196
+ jira_key_in_response ,
197
+ extra = log_context ,
198
+ )
129
199
jira_response = self .jira_client .create_or_update_issue_remote_links (
130
200
issue_key = jira_key_in_response ,
131
201
link_url = bugzilla_url ,
0 commit comments