Project import generated by Copybara.
GitOrigin-RevId: d9e9e3fb4e31372ec1fb43b178994ca78fa8fe70
diff --git a/features/pubsub.py b/features/pubsub.py
new file mode 100644
index 0000000..a74ff22
--- /dev/null
+++ b/features/pubsub.py
@@ -0,0 +1,81 @@
+# Copyright 2019 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file or at
+# https://developers.google.com/open-source/licenses/bsd
+
+"""Task handlers for publishing issue updates onto a pub/sub topic.
+
+The pub/sub topic name is: `projects/{project-id}/topics/issue-updates`.
+"""
+from __future__ import print_function
+from __future__ import division
+from __future__ import absolute_import
+
+import httplib2
+import logging
+import sys
+
+import settings
+
+from googleapiclient.discovery import build
+from apiclient.errors import Error as ApiClientError
+from oauth2client.client import GoogleCredentials
+from oauth2client.client import Error as Oauth2ClientError
+
+from framework import exceptions
+from framework import jsonfeed
+
+
+class PublishPubsubIssueChangeTask(jsonfeed.InternalTask):
+ """JSON servlet that pushes issue update messages onto a pub/sub topic."""
+
+ def HandleRequest(self, mr):
+ """Push a message onto a pub/sub queue.
+
+ Args:
+ mr: common information parsed from the HTTP request.
+ Returns:
+ A dictionary. If an error occurred, the 'error' field will be a string
+ containing the error message.
+ """
+ pubsub_client = set_up_pubsub_api()
+ if not pubsub_client:
+ return {
+ 'error': 'Pub/Sub API init failure.',
+ }
+
+ issue_id = mr.GetPositiveIntParam('issue_id')
+ if not issue_id:
+ return {
+ 'error': 'Cannot proceed without a valid issue ID.',
+ }
+ try:
+ issue = self.services.issue.GetIssue(mr.cnxn, issue_id, use_cache=False)
+ except exceptions.NoSuchIssueException:
+ return {
+ 'error': 'Could not find issue with ID %s' % issue_id,
+ }
+
+ pubsub_client.projects().topics().publish(
+ topic=settings.pubsub_topic_id,
+ body={
+ 'messages': [{
+ 'attributes': {
+ 'local_id': str(issue.local_id),
+ 'project_name': str(issue.project_name),
+ },
+ }],
+ },
+ ).execute()
+
+ return {}
+
+
+def set_up_pubsub_api():
+ """Attempts to build and return a pub/sub API client."""
+ try:
+ return build('pubsub', 'v1', http=httplib2.Http(),
+ credentials=GoogleCredentials.get_application_default())
+ except (Oauth2ClientError, ApiClientError):
+ logging.error("Error setting up Pub/Sub API: %s" % sys.exc_info()[0])
+ return None