blob: a74ff22168bbe818ce8e26aac95c076dbc5db595 [file] [log] [blame]
Copybara854996b2021-09-07 19:36:02 +00001# Copyright 2019 The Chromium Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style
3# license that can be found in the LICENSE file or at
4# https://developers.google.com/open-source/licenses/bsd
5
6"""Task handlers for publishing issue updates onto a pub/sub topic.
7
8The pub/sub topic name is: `projects/{project-id}/topics/issue-updates`.
9"""
10from __future__ import print_function
11from __future__ import division
12from __future__ import absolute_import
13
14import httplib2
15import logging
16import sys
17
18import settings
19
20from googleapiclient.discovery import build
21from apiclient.errors import Error as ApiClientError
22from oauth2client.client import GoogleCredentials
23from oauth2client.client import Error as Oauth2ClientError
24
25from framework import exceptions
26from framework import jsonfeed
27
28
29class PublishPubsubIssueChangeTask(jsonfeed.InternalTask):
30 """JSON servlet that pushes issue update messages onto a pub/sub topic."""
31
32 def HandleRequest(self, mr):
33 """Push a message onto a pub/sub queue.
34
35 Args:
36 mr: common information parsed from the HTTP request.
37 Returns:
38 A dictionary. If an error occurred, the 'error' field will be a string
39 containing the error message.
40 """
41 pubsub_client = set_up_pubsub_api()
42 if not pubsub_client:
43 return {
44 'error': 'Pub/Sub API init failure.',
45 }
46
47 issue_id = mr.GetPositiveIntParam('issue_id')
48 if not issue_id:
49 return {
50 'error': 'Cannot proceed without a valid issue ID.',
51 }
52 try:
53 issue = self.services.issue.GetIssue(mr.cnxn, issue_id, use_cache=False)
54 except exceptions.NoSuchIssueException:
55 return {
56 'error': 'Could not find issue with ID %s' % issue_id,
57 }
58
59 pubsub_client.projects().topics().publish(
60 topic=settings.pubsub_topic_id,
61 body={
62 'messages': [{
63 'attributes': {
64 'local_id': str(issue.local_id),
65 'project_name': str(issue.project_name),
66 },
67 }],
68 },
69 ).execute()
70
71 return {}
72
73
74def set_up_pubsub_api():
75 """Attempts to build and return a pub/sub API client."""
76 try:
77 return build('pubsub', 'v1', http=httplib2.Http(),
78 credentials=GoogleCredentials.get_application_default())
79 except (Oauth2ClientError, ApiClientError):
80 logging.error("Error setting up Pub/Sub API: %s" % sys.exc_info()[0])
81 return None