This is an automated email from the ASF dual-hosted git repository.

chamikara pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/beam.git


The following commit(s) were added to refs/heads/master by this push:
     new f831030  [Beam-4687]Automate JIRA for Dependency check (#6060)
f831030 is described below

commit f831030e7c92e7263b98e3ff4307aca4a324a0dd
Author: yifanzou <[email protected]>
AuthorDate: Fri Aug 3 09:30:27 2018 -0700

    [Beam-4687]Automate JIRA for Dependency check (#6060)
    
    * [BEAM-4687] create Jira client
    
    * complete the Jira client
    
    * [BEAM-4687] add jira manager to handle the auto jira generation
    
    * complete the Jira manager
---
 .test-infra/jenkins/dependency_check/__init__.py   |  16 ++
 .../dependency_check_report_generator.py           |  56 +++--
 .../dependency_check_report_generator_test.py      |  78 +++----
 .../jenkins/dependency_check/generate_report.sh    |  31 +--
 .../dependency_check/report_generator_config.py    |  82 +++++++
 .test-infra/jenkins/jira_utils/__init__.py         |  16 ++
 .test-infra/jenkins/jira_utils/jira_client.py      | 132 +++++++++++
 .test-infra/jenkins/jira_utils/jira_manager.py     | 215 ++++++++++++++++++
 .../jenkins/jira_utils/jira_manager_test.py        | 243 +++++++++++++++++++++
 .test-infra/jenkins/job_Dependency_Check.groovy    |   6 +
 ownership/JAVA_DEPENDENCY_OWNERS.yaml              |   7 +-
 ownership/PYTHON_DEPENDENCY_OWNERS.yaml            |   2 +-
 12 files changed, 794 insertions(+), 90 deletions(-)

diff --git a/.test-infra/jenkins/dependency_check/__init__.py 
b/.test-infra/jenkins/dependency_check/__init__.py
new file mode 100644
index 0000000..cce3aca
--- /dev/null
+++ b/.test-infra/jenkins/dependency_check/__init__.py
@@ -0,0 +1,16 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
diff --git 
a/.test-infra/jenkins/dependency_check/dependency_check_report_generator.py 
b/.test-infra/jenkins/dependency_check/dependency_check_report_generator.py
index 981d9eb..6171ad1 100644
--- a/.test-infra/jenkins/dependency_check/dependency_check_report_generator.py
+++ b/.test-infra/jenkins/dependency_check/dependency_check_report_generator.py
@@ -22,7 +22,9 @@ import re
 import traceback
 import logging
 from datetime import datetime
-from bigquery_client_utils import BigQueryClientUtils
+from dependency_check.bigquery_client_utils import BigQueryClientUtils
+from jira_utils.jira_manager import JiraManager
+from dependency_check.report_generator_config import ReportGeneratorConfig
 
 
 _MAX_STALE_DAYS = 360
@@ -56,7 +58,7 @@ def extract_results(file_path):
           see_oudated_deps = True
     raw_report.close()
     return outdated_deps
-  except Exception as e:
+  except:
     raise
 
 
@@ -64,7 +66,7 @@ def extract_single_dep(dep):
   """
   Extract a single dependency check record from Java and Python reports.
   Args:
-    dep: e.g "- org.assertj:assertj-core [2.5.0 -> 3.10.0]".
+    dep: e.g " - org.assertj:assertj-core [2.5.0 -> 3.10.0]".
   Return:
     dependency name, current version, latest version.
   """
@@ -75,7 +77,7 @@ def extract_single_dep(dep):
   return match.group(1).strip(), match.group(2).strip(), match.group(3).strip()
 
 
-def prioritize_dependencies(deps, sdk_type, project_id, dataset_id, table_id):
+def prioritize_dependencies(deps, sdk_type):
   """
   Extracts and analyze dependency versions and release dates.
   Returns a collection of dependencies which is "high priority" in html format:
@@ -88,17 +90,26 @@ def prioritize_dependencies(deps, sdk_type, project_id, 
dataset_id, table_id):
   Return:
     high_priority_deps: A collection of dependencies which need to be taken 
care of before next release.
   """
+
+  project_id = ReportGeneratorConfig.GCLOUD_PROJECT_ID
+  dataset_id = ReportGeneratorConfig.DATASET_ID
+  table_id = ReportGeneratorConfig.get_bigquery_table_id(sdk_type)
   high_priority_deps = []
   bigquery_client = BigQueryClientUtils(project_id, dataset_id, table_id)
+  jira_manager = JiraManager(ReportGeneratorConfig.BEAM_JIRA_HOST,
+                             ReportGeneratorConfig.BEAM_JIRA_BOT_USRENAME,
+                             ReportGeneratorConfig.BEAM_JIRA_BOT_PASSWORD,
+                             ReportGeneratorConfig.get_owners_file(sdk_type))
 
   for dep in deps:
     try:
-      logging.info("Start processing: %s", dep)
+      logging.info("\n\nStart processing: " + dep)
       dep_name, curr_ver, latest_ver = extract_single_dep(dep)
       curr_release_date, latest_release_date = 
query_dependency_release_dates(bigquery_client,
                                                                               
dep_name,
                                                                               
curr_ver,
                                                                               
latest_ver)
+      group_id = None
       if sdk_type == 'Java':
         # extract the groupid and artifactid
         group_id, artifact_id = dep_name.split(":")
@@ -120,8 +131,10 @@ def prioritize_dependencies(deps, sdk_type, project_id, 
dataset_id, table_id):
                           latest_release_date)
       if compare_dependency_versions(curr_ver, latest_ver):
         high_priority_deps.append(dep_info)
+        jira_manager.run(dep_name, latest_ver, sdk_type, group_id = group_id)
       elif compare_dependency_release_dates(curr_release_date, 
latest_release_date):
         high_priority_deps.append(dep_info)
+        jira_manager.run(dep_name, latest_ver, sdk_type, group_id = group_id)
     except:
       traceback.print_exc()
       continue
@@ -159,7 +172,7 @@ def compare_dependency_versions(curr_ver, latest_ver):
           return True
         elif int(curr_minor_ver) + _MAX_MINOR_VERSION_DIFF <= 
int(latest_minor_ver):
           return True
-     # TODO: Comparing patch versions if needed.
+    # TODO: Comparing patch versions if needed.
   return False
 
 
@@ -209,25 +222,22 @@ def compare_dependency_release_dates(curr_release_date, 
latest_release_date):
   Return:
     boolean
   """
-  if curr_release_date is None or latest_release_date is None:
-    return True
+  if not curr_release_date or not latest_release_date:
+    return False
   else:
     if (latest_release_date - curr_release_date).days >= _MAX_STALE_DAYS:
       return True
   return False
 
 
-def generate_report(file_path, sdk_type, project_id, dataset_id, table_id):
+def generate_report(sdk_type):
   """
   Write SDK dependency check results into a html report.
   Args:
-    file_path: the path that report will be write into.
     sdk_type: String [Java, Python, TODO: Go]
-    project_id: the gcloud project ID that is used for BigQuery API requests.
-    dataset_id: the BigQuery dataset ID.
-    table_id: the BigQuery table ID.
   """
-  report_name = 'build/dependencyUpdates/beam-dependency-check-report.html'
+  report_name = ReportGeneratorConfig.FINAL_REPORT
+  raw_report = ReportGeneratorConfig.get_raw_report(sdk_type)
 
   if os.path.exists(report_name):
     append_write = 'a'
@@ -237,15 +247,15 @@ def generate_report(file_path, sdk_type, project_id, 
dataset_id, table_id):
   try:
     # Extract dependency check results from build/dependencyUpdate
     report = open(report_name, append_write)
-    if os.path.isfile(file_path):
-      outdated_deps = extract_results(file_path)
+    if os.path.isfile(raw_report):
+      outdated_deps = extract_results(raw_report)
     else:
-      report.write("Did not find the raw report of dependency check: 
{}".format(file_path))
+      report.write("Did not find the raw report of dependency check: 
{}".format(raw_report))
       report.close()
       return
 
     # Prioritize dependencies by comparing versions and release dates.
-    high_priority_deps = prioritize_dependencies(outdated_deps, sdk_type, 
project_id, dataset_id, table_id)
+    high_priority_deps = prioritize_dependencies(outdated_deps, sdk_type)
 
     # Write results to a report
     subtitle = "<h2>High Priority Dependency Updates Of Beam {} 
SDK:</h2>\n".format(sdk_type)
@@ -267,6 +277,8 @@ def generate_report(file_path, sdk_type, project_id, 
dataset_id, table_id):
       report.write("%s" % dep)
     report.write("</table>\n")
   except Exception as e:
+    traceback.print_exc()
+    logging.error("Failed generate the dependency report. " + str(e))
     report.write('<p> {0} </p>'.format(str(e)))
 
   report.close()
@@ -276,13 +288,9 @@ def main(args):
   """
   Main method.
   Args:
-    args[0]: path of the raw report generated by Java/Python dependency check. 
Typically in build/dependencyUpdates
-    args[1]: type of the check [Java, Python]
-    args[2]: google cloud project id
-    args[3]: BQ dataset id
-    args[4]: BQ table id
+    args[0]: type of the check [Java, Python]
   """
-  generate_report(args[0], args[1], args[2], args[3], args[4])
+  generate_report(args[0])
 
 
 if __name__ == '__main__':
diff --git 
a/.test-infra/jenkins/dependency_check/dependency_check_report_generator_test.py
 
b/.test-infra/jenkins/dependency_check/dependency_check_report_generator_test.py
index 770527a..b899075 100644
--- 
a/.test-infra/jenkins/dependency_check/dependency_check_report_generator_test.py
+++ 
b/.test-infra/jenkins/dependency_check/dependency_check_report_generator_test.py
@@ -19,9 +19,8 @@
 #   This script performs testing of scenarios from 
verify_performance_test_results.py
 #
 
-from __future__ import print_function
 import unittest, mock
-from mock import patch
+from mock import patch, mock_open
 from datetime import datetime
 from dependency_check_report_generator import prioritize_dependencies
 
@@ -35,27 +34,31 @@ _SDK_TYPE = 'JAVA'
 _LP_CURR_VERSION_DATE = datetime.strptime('2000-01-01', '%Y-%m-%d')
 _LATEST_VERSION_DATE = datetime.strptime('2000-01-02', '%Y-%m-%d')
 _HP_CURR_VERSION_DATE = datetime.strptime('1999-01-01', '%Y-%m-%d')
+_MOCKED_OWNERS_FILE = "deps: "
 
+@patch('google.cloud.bigquery.Client')
+@patch('jira_utils.jira_manager.JiraManager')
+@patch('jira_utils.jira_manager.JiraClient')
+@patch('jira_utils.jira_manager.JiraManager.run')
 class DependencyCheckReportGeneratorTest(unittest.TestCase):
   """Tests for `dependency_check_report_generator.py`."""
 
   def setUp(self):
-    print("Test name:", self._testMethodName)
+    print "\n\nTest : " + self._testMethodName
 
 
-  @patch('google.cloud.bigquery.Client')
-  @patch('bigquery_client_utils.BigQueryClientUtils')
+  @patch('dependency_check.bigquery_client_utils.BigQueryClientUtils')
   def test_empty_dep_input(self, *args):
     """
     Test on empty outdated dependencies.
-    Except: empty report
+    Expect: empty report
     """
-    report = prioritize_dependencies([], _SDK_TYPE, _PROJECT_ID, _DATASET_ID, 
_TABLE_ID)
-    self.assertEqual(len(report), 0)
+    with patch('__builtin__.open', mock_open(read_data=_MOCKED_OWNERS_FILE)):
+      report = prioritize_dependencies([], _SDK_TYPE)
+      self.assertEqual(len(report), 0)
 
 
-  @patch('google.cloud.bigquery.Client')
-  @patch('bigquery_client_utils.BigQueryClientUtils.query_dep_info_by_version',
+  
@patch('dependency_check.bigquery_client_utils.BigQueryClientUtils.query_dep_info_by_version',
          side_effect = [(_LP_CURR_VERSION_DATE, True), (_LATEST_VERSION_DATE, 
False),
                         (_LP_CURR_VERSION_DATE, True), (_LATEST_VERSION_DATE, 
False),
                         (_HP_CURR_VERSION_DATE, True), (_LATEST_VERSION_DATE, 
False),
@@ -63,7 +66,7 @@ class DependencyCheckReportGeneratorTest(unittest.TestCase):
   def test_normal_dep_input(self, *args):
     """
     Test on a normal outdated dependencies set.
-    Except: group1:artifact1, group2:artifact2, and group3:artifact3
+    Expect: group1:artifact1, group2:artifact2, and group3:artifact3
     """
     deps = [
       " - group1:artifact1 [1.0.0 -> 3.0.0]",
@@ -71,61 +74,62 @@ class DependencyCheckReportGeneratorTest(unittest.TestCase):
       " - group3:artifact3 [1.0.0 -> 1.1.0]",
       " - group4:artifact4 [1.0.0 -> 1.1.0]"
     ]
-    report = prioritize_dependencies(deps, _SDK_TYPE, _PROJECT_ID, 
_DATASET_ID, _TABLE_ID)
-    self.assertEqual(len(report), 3)
-    self.assertIn('group1:artifact1', report[0])
-    self.assertIn('group2:artifact2', report[1])
-    self.assertIn('group3:artifact3', report[2])
+    with patch('__builtin__.open', mock_open(read_data=_MOCKED_OWNERS_FILE)):
+      report = prioritize_dependencies(deps, _SDK_TYPE)
+      self.assertEqual(len(report), 3)
+      self.assertIn('group1:artifact1', report[0])
+      self.assertIn('group2:artifact2', report[1])
+      self.assertIn('group3:artifact3', report[2])
 
 
-  @patch('google.cloud.bigquery.Client')
-  @patch('bigquery_client_utils.BigQueryClientUtils.query_dep_info_by_version',
+  
@patch('dependency_check.bigquery_client_utils.BigQueryClientUtils.query_dep_info_by_version',
          side_effect = [(_LP_CURR_VERSION_DATE, True),
                         (_LATEST_VERSION_DATE, False),])
   def test_dep_with_nondigit_major_versions(self, *args):
     """
     Test on a outdated dependency with non-digit major number.
-    Except: group1:artifact1
+    Expect: group1:artifact1
     """
     deps = [" - group1:artifact1 [Release1-123 -> Release2-456]"]
-    report = prioritize_dependencies(deps, _SDK_TYPE, _PROJECT_ID, 
_DATASET_ID, _TABLE_ID)
-    self.assertEqual(len(report), 1)
-    self.assertIn('group1:artifact1', report[0])
+    with patch('__builtin__.open', mock_open(read_data=_MOCKED_OWNERS_FILE)):
+      report = prioritize_dependencies(deps, _SDK_TYPE)
+      self.assertEqual(len(report), 1)
+      self.assertIn('group1:artifact1', report[0])
 
 
-  @patch('google.cloud.bigquery.Client')
-  @patch('bigquery_client_utils.BigQueryClientUtils.query_dep_info_by_version',
+  
@patch('dependency_check.bigquery_client_utils.BigQueryClientUtils.query_dep_info_by_version',
          side_effect = [(_LP_CURR_VERSION_DATE, True),
                         (_LATEST_VERSION_DATE, False),])
   def test_dep_with_nondigit_minor_versions(self, *args):
     """
     Test on a outdated dependency with non-digit minor number.
-    Except: group1:artifact1
+    Expect: group1:artifact1
     """
     deps = [" - group1:artifact1 [0.rc1.0 -> 0.rc2.0]"]
-    report = prioritize_dependencies(deps, _SDK_TYPE, _PROJECT_ID, 
_DATASET_ID, _TABLE_ID)
-    self.assertEqual(len(report), 1)
-    self.assertIn('group1:artifact1', report[0])
+    with patch('__builtin__.open', mock_open(read_data=_MOCKED_OWNERS_FILE)):
+      report = prioritize_dependencies(deps, _SDK_TYPE)
+      self.assertEqual(len(report), 1)
+      self.assertIn('group1:artifact1', report[0])
 
 
-  @patch('google.cloud.bigquery.Client')
-  @patch('bigquery_client_utils.BigQueryClientUtils.insert_dep_to_table')
-  @patch('bigquery_client_utils.BigQueryClientUtils.delete_dep_from_table')
-  
@patch('bigquery_client_utils.BigQueryClientUtils.query_currently_used_dep_info_in_db',
 side_effect = [(None, None)])
-  @patch('bigquery_client_utils.BigQueryClientUtils.query_dep_info_by_version',
+  
@patch('dependency_check.bigquery_client_utils.BigQueryClientUtils.insert_dep_to_table')
+  
@patch('dependency_check.bigquery_client_utils.BigQueryClientUtils.delete_dep_from_table')
+  
@patch('dependency_check.bigquery_client_utils.BigQueryClientUtils.query_currently_used_dep_info_in_db',
 side_effect = [(None, None)])
+  
@patch('dependency_check.bigquery_client_utils.BigQueryClientUtils.query_dep_info_by_version',
          side_effect = [(_HP_CURR_VERSION_DATE, True), (_LATEST_VERSION_DATE, 
False),])
   def test_invalid_dep_input(self, *args):
     """
     Test on a invalid outdated dependencies format.
-    Except: Exception through out. And group2:artifact2 is picked.
+    Expect: Exception through out. And group2:artifact2 is picked.
     """
     deps = [
       "- group1:artifact1 (1.0.0, 2.0.0)",
       " - group2:artifact2 [1.0.0 -> 2.0.0]"
     ]
-    report = prioritize_dependencies(deps, _SDK_TYPE, _PROJECT_ID, 
_DATASET_ID, _TABLE_ID)
-    self.assertEqual(len(report), 1)
-    self.assertIn('group2:artifact2', report[0])
+    with patch('__builtin__.open', mock_open(read_data=_MOCKED_OWNERS_FILE)):
+      report = prioritize_dependencies(deps, _SDK_TYPE)
+      self.assertEqual(len(report), 1)
+      self.assertIn('group2:artifact2', report[0])
 
 
 if __name__ == '__main__':
diff --git a/.test-infra/jenkins/dependency_check/generate_report.sh 
b/.test-infra/jenkins/dependency_check/generate_report.sh
index 7e7ff2f..644fa81 100755
--- a/.test-infra/jenkins/dependency_check/generate_report.sh
+++ b/.test-infra/jenkins/dependency_check/generate_report.sh
@@ -20,10 +20,6 @@
 set -e
 set -v
 
-PROJECT_ID='apache-beam-testing'
-DATASET_ID='beam_dependency_states'
-PYTHON_DEP_TABLE_ID='python_dependency_states'
-JAVA_DEP_TABLE_ID='java_dependency_states'
 REPORT_DESCRIPTION="
 <h4> A dependency update is high priority if it satisfies one of following 
criteria: </h4>
 <ul>
@@ -39,34 +35,25 @@ REPORT_DESCRIPTION="
      In the future, issues will be filed and tracked for these automatically,
      but in the meantime you can search for existing issues or open a new one.
 </h4>
-<h4> For more information: <a 
href=\"https://docs.google.com/document/d/15m1MziZ5TNd9rh_XN0YYBJfYkt0Oj-Ou9g0KFDPL2aA/edit#\";>
 Beam Dependency Update Policy </a></h4>"
+<h4> For more information: <a 
href=\"https://beam.apache.org/contribute/dependencies/\";> Beam Dependency 
Guide </a></h4>"
 
 
 # Virtualenv for the rest of the script to run setup
 /usr/bin/virtualenv dependency/check
 . dependency/check/bin/activate
 pip install --upgrade google-cloud-bigquery
-
-# Run the unit tests of the report generator
-pip install mock
-python 
$WORKSPACE/src/.test-infra/jenkins/dependency_check/dependency_check_report_generator_test.py
 \
-
 rm -f build/dependencyUpdates/beam-dependency-check-report.txt
 
+# Insall packages and run the unit tests of the report generator and the jira 
manager
+pip install mock jira pyyaml
+cd $WORKSPACE/src/.test-infra/jenkins
+python -m dependency_check.dependency_check_report_generator_test
+python -m jira_utils.jira_manager_test
+
 echo "<html><body>" > 
$WORKSPACE/src/build/dependencyUpdates/beam-dependency-check-report.html
 
-python 
$WORKSPACE/src/.test-infra/jenkins/dependency_check/dependency_check_report_generator.py
 \
-build/dependencyUpdates/python_dependency_report.txt \
-Python \
-$PROJECT_ID \
-$DATASET_ID \
-$PYTHON_DEP_TABLE_ID
+python -m dependency_check/dependency_check_report_generator Python
 
-python 
$WORKSPACE/src/.test-infra/jenkins/dependency_check/dependency_check_report_generator.py
 \
-build/dependencyUpdates/report.txt \
-Java \
-$PROJECT_ID \
-$DATASET_ID \
-$JAVA_DEP_TABLE_ID
+python -m dependency_check.dependency_check_report_generator Java
 
 echo "$REPORT_DESCRIPTION </body></html>" >> 
$WORKSPACE/src/build/dependencyUpdates/beam-dependency-check-report.html
diff --git a/.test-infra/jenkins/dependency_check/report_generator_config.py 
b/.test-infra/jenkins/dependency_check/report_generator_config.py
new file mode 100644
index 0000000..c99c76e
--- /dev/null
+++ b/.test-infra/jenkins/dependency_check/report_generator_config.py
@@ -0,0 +1,82 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Defines constants and helper methods used by the dependency_report_generator
+
+import os
+
+class ReportGeneratorConfig:
+
+  # Jenkins Working Space
+  WORKING_SPACE = os.environ['WORKSPACE']
+
+  # Constants for dependency prioritization
+  GCLOUD_PROJECT_ID     = 'apache-beam-testing'
+  DATASET_ID            = 'beam_dependency_states'
+  PYTHON_DEP_TABLE_ID   = 'python_dependency_states'
+  JAVA_DEP_TABLE_ID     = 'java_dependency_states'
+  PYTHON_DEP_RAW_REPORT = WORKING_SPACE + 
'/src/build/dependencyUpdates/python_dependency_report.txt'
+  JAVA_DEP_RAW_REPORT   = WORKING_SPACE + 
'/src/build/dependencyUpdates/report.txt'
+  FINAL_REPORT          = WORKING_SPACE + 
'/src/build/dependencyUpdates/beam-dependency-check-report.html'
+
+  # Constants for JIRA automation
+  BEAM_JIRA_HOST        = 'https://issues.apache.org/jira/'
+  BEAM_JIRA_BOT_USRENAME= os.environ['BEAM_JIRA_BOT_USERNAME']
+  BEAM_JIRA_BOT_PASSWORD= os.environ['BEAM_JIRA_BOT_PASSWORD']
+
+  # Dependency Owners
+  JAVA_DEP_OWNERS       = WORKING_SPACE + 
'/src/ownership/JAVA_DEPENDENCY_OWNERS.yaml'
+  PYTHON_DEP_OWNERS     = WORKING_SPACE + 
'/src/ownership/PYTHON_DEPENDENCY_OWNERS.yaml'
+
+
+  @classmethod
+  def get_bigquery_table_id(cls, sdk_type):
+    if sdk_type.lower() == 'java':
+      return cls.JAVA_DEP_TABLE_ID
+    elif sdk_type.lower() == 'python':
+      return cls.PYTHON_DEP_TABLE_ID
+    else:
+      raise UndefinedSDKTypeException("""Undefined SDK Type: {0}. 
+        Could not find the BigQuery table for {1} 
dependencies.""".format(sdk_type, sdk_type))
+
+
+  @classmethod
+  def get_raw_report(cls, sdk_type):
+    if sdk_type.lower() == 'java':
+      return cls.JAVA_DEP_RAW_REPORT
+    elif sdk_type.lower() == 'python':
+      return cls.PYTHON_DEP_RAW_REPORT
+    else:
+      raise UndefinedSDKTypeException("""Undefined SDK Type: {0}. 
+        Could not find the dependency reports for the {1} 
SDK.""".format(sdk_type, sdk_type))
+
+
+  @classmethod
+  def get_owners_file(cls, sdk_type):
+    if sdk_type.lower() == 'java':
+      return cls.JAVA_DEP_OWNERS
+    elif sdk_type.lower() == 'python':
+      return cls.PYTHON_DEP_OWNERS
+    else:
+      raise UndefinedSDKTypeException("""Undefined SDK Type: {0}. 
+        Could not find the Owners file for the {1} SDK.""".format(sdk_type, 
sdk_type))
+
+
+class UndefinedSDKTypeException(Exception):
+  """Indicates an error has occurred in while reading constants."""
+
+  def __init__(self, msg):
+    super(UndefinedSDKTypeException, self).__init__(msg)
diff --git a/.test-infra/jenkins/jira_utils/__init__.py 
b/.test-infra/jenkins/jira_utils/__init__.py
new file mode 100644
index 0000000..cce3aca
--- /dev/null
+++ b/.test-infra/jenkins/jira_utils/__init__.py
@@ -0,0 +1,16 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
diff --git a/.test-infra/jenkins/jira_utils/jira_client.py 
b/.test-infra/jenkins/jira_utils/jira_client.py
new file mode 100644
index 0000000..0c6c126
--- /dev/null
+++ b/.test-infra/jenkins/jira_utils/jira_client.py
@@ -0,0 +1,132 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+
+from jira import JIRA
+
+class JiraClient:
+
+  def __init__(self, options, basic_auth, project):
+    self.jira = JIRA(options, basic_auth=basic_auth)
+    self.project = project
+
+
+  def get_issues_by_summary(self, summary):
+    """
+    Find issues by using the summary (issue title)
+    Args:
+      summary
+    Return:
+      A list of issues
+    """
+    try:
+      issues = self.jira.search_issues("project={0} AND summary ~ 
'{1}'".format(self.project, summary))
+    except Exception:
+      raise
+    return issues
+
+
+  def get_issue_by_key(self, key):
+    """
+    Find issue by using the key (e.g BEAM-1234)
+    Args:
+      key
+    Return:
+      issue
+    """
+    try:
+      issue = self.jira.issue(key)
+    except Exception:
+      raise
+    return issue
+
+
+  def create_issue(self, summary, components, description, issuetype='Bug', 
assignee=None, parent_key=None):
+    """
+    Create a new issue
+    Args:
+      summary - Issue title
+      components - A list of components
+      description (optional) - A string that describes the issue
+      issuetype (optional) - Bug, Improvement, New Feature, Sub-task, Task, 
Wish, etc.
+      assignee (optional) - A string of JIRA user name
+      parent_key (optional) - The parent issue key is required when creating a 
subtask.
+    Return:
+      Issue created
+    """
+    fields = {
+      'project': {'key': self.project},
+      'summary': summary,
+      'description': description,
+      'issuetype': {'name': issuetype},
+      'components': [],
+    }
+    for component in components:
+      fields['components'].append({'name': component})
+    if assignee is not None:
+      fields['assignee'] = {'name': assignee}
+    if parent_key is not None:
+      fields['parent'] = {'key': parent_key}
+      fields['issuetype'] = {'name': 'Sub-task'}
+    try:
+      new_issue = self.jira.create_issue(fields = fields)
+    except Exception:
+      raise
+    return new_issue
+
+
+  def update_issue(self, issue, summary=None, components=None, 
description=None, assignee=None, notify=True):
+    """
+    Create a new issue
+    Args:
+      issue - Jira issue object
+      summary (optional) - Issue title
+      components (optional) - A list of components
+      description (optional) - A string that describes the issue
+      assignee (optional) - A string of JIRA user name
+      notify - Query parameter notifyUsers. If true send the email with 
notification that the issue was updated to users that watch it.
+               Admin or project admin permissions are required to disable the 
notification.
+    Return:
+      Issue created
+    """
+    fields={}
+    if summary:
+      fields['summary'] = summary
+    if description:
+      fields['description'] = description
+    if assignee:
+      fields['assignee'] = {'name': assignee}
+    if components:
+      fields['components'] = []
+      for component in components:
+        fields['components'].append({'name': component})
+    try:
+      issue.update(fields=fields, notify=notify)
+    except Exception:
+      raise
+
+
+  def reopen_issue(self, issue):
+    """
+    Reopen an issue
+    Args:
+      issue - Jira issue object
+    """
+    try:
+      self.jira.transition_issue(issue.key, 3)
+    except:
+      raise
diff --git a/.test-infra/jenkins/jira_utils/jira_manager.py 
b/.test-infra/jenkins/jira_utils/jira_manager.py
new file mode 100644
index 0000000..cdc4450
--- /dev/null
+++ b/.test-infra/jenkins/jira_utils/jira_manager.py
@@ -0,0 +1,215 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+import logging
+import yaml
+import traceback
+from datetime import datetime
+from jira_client import JiraClient
+
+_JIRA_PROJECT_NAME = 'BEAM'
+_JIRA_COMPONENT = 'dependencies'
+_ISSUE_SUMMARY_PREFIX = 'Beam Dependency Update Request: '
+
+class JiraManager:
+
+  def __init__(self, jira_url, jira_username, jira_password, owners_file):
+    options = {
+      'server': jira_url
+    }
+    basic_auth = (jira_username, jira_password)
+    self.jira = JiraClient(options, basic_auth, _JIRA_PROJECT_NAME)
+    with open(owners_file) as f:
+      owners = yaml.load(f)
+    self.owners_map = owners['deps']
+    logging.getLogger().setLevel(logging.INFO)
+
+
+  def run(self, dep_name, dep_latest_version, sdk_type, group_id=None):
+    """
+    Manage the jira issue for a dependency
+    Args:
+      dep_name,
+      dep_latest_version,
+      sdk_type: Java, Python
+      group_id (optional): only required for Java dependencies
+    """
+    logging.info("Start handling the JIRA issues for {0} dependency: {1} 
{2}".format(
+        sdk_type, dep_name, dep_latest_version))
+    try:
+      # find the parent issue for Java deps base on the groupID
+      parent_issue = None
+      if sdk_type == 'Java':
+        summary = _ISSUE_SUMMARY_PREFIX + group_id
+        parent_issues = self._search_issues(summary)
+        for i in parent_issues:
+          if i.fields.summary == summary:
+            parent_issue = i
+            break
+        # Create a new parent issue if no existing found
+        if not parent_issue:
+          logging.info("""Did not find existing issue with name {0}. \n 
+            Created a parent issue for {1}""".format(summary, group_id))
+          try:
+            parent_issue = self._create_issue(group_id, None)
+            print parent_issue.key
+          except:
+            logging.error("""Failed creating a parent issue for {0}.
+              Stop handling the JIRA issue for {1}, {2}""".format(group_id, 
dep_name, dep_latest_version))
+            return
+        # Reopen the existing parent issue if it was closed
+        elif (parent_issue.fields.status.name != 'Open' and
+          parent_issue.fields.status.name != 'Reopened'):
+          logging.info("""The parent issue {0} is not opening. Attempt 
reopening the issue""".format(parent_issue.key))
+          try:
+            self.jira.reopen_issue(parent_issue)
+          except:
+            traceback.print_exc()
+            logging.error("""Failed reopening the parent issue {0}.
+              Stop handling the JIRA issue for {1}, 
{2}""".format(parent_issue.key, dep_name, dep_latest_version))
+            return
+        logging.info("Found the parent issue {0}. Continuous to create or 
update the sub-task for {1}".format(parent_issue.key, dep_name))
+      # creating a new issue/sub-task or updating on the existing issue of the 
dep
+      summary =  _ISSUE_SUMMARY_PREFIX + dep_name + " " + dep_latest_version
+      issues = self._search_issues(summary)
+      issue = None
+      for i in issues:
+        if i.fields.summary == summary:
+          issue = i
+          break
+      if not issue:
+        if sdk_type == 'Java':
+          issue = self._create_issue(dep_name, dep_latest_version, 
is_subtask=True, parent_key=parent_issue.key)
+        else:
+          issue = self._create_issue(dep_name, dep_latest_version)
+        logging.info('Created a new issue {0} of {1} {2}'.format(issue.key, 
dep_name, dep_latest_version))
+      elif issue.fields.status.name == 'Open' or issue.fields.status.name == 
'Reopened':
+        self._append_descriptions(issue, dep_name, dep_latest_version)
+        logging.info('Updated the existing issue {0} of {1} 
{2}'.format(issue.key, dep_name, dep_latest_version))
+    except:
+      raise
+
+
+  def _create_issue(self, dep_name, dep_latest_version, is_subtask=False, 
parent_key=None):
+    """
+    Create a new issue or subtask
+    Args:
+      dep_name,
+      dep_latest_version,
+      is_subtask,
+      parent_key: only required if the 'is_subtask'is true.
+    """
+    logging.info("Creating a new JIRA issue to track {0} upgrade 
process".format(dep_name))
+    assignee, owners = self._find_owners(dep_name)
+    summary =  _ISSUE_SUMMARY_PREFIX + dep_name
+    if dep_latest_version:
+      summary = summary + " " + dep_latest_version
+    description = """\n\n{0}\n
+        Please review and upgrade the {1} to the latest version {2} \n 
+        cc: """.format(
+        datetime.today(),
+        dep_name,
+        dep_latest_version
+    )
+    for owner in owners:
+      description += "[~{0}], ".format(owner)
+    try:
+      if not is_subtask:
+        issue = self.jira.create_issue(summary, [_JIRA_COMPONENT], 
description, assignee=assignee)
+      else:
+        issue = self.jira.create_issue(summary, [_JIRA_COMPONENT], 
description, assignee=assignee, parent_key=parent_key)
+    except Exception as e:
+      logging.error("Failed creating issue: "+ str(e))
+      raise e
+    return issue
+
+
+  def _search_issues(self, summary):
+    """
+    Search issues by using issues' summary.
+    Args:
+      summary: a string
+    Return:
+      A list of issues
+    """
+    try:
+      issues = self.jira.get_issues_by_summary(summary)
+    except Exception as e:
+      logging.error("Failed searching issues: "+ str(e))
+      return []
+    return issues
+
+
+  def _append_descriptions(self, issue, dep_name, dep_latest_version):
+    """
+    Add descriptions on an existing issue.
+    Args:
+      issue: Jira issue
+      dep_name
+      dep_latest_version
+    """
+    logging.info("Updating JIRA issue {0} to track {1} upgrade process".format(
+        issue.key,
+        dep_name))
+    description = issue.fields.description + """\n\n{0}\n
+        Please review and upgrade the {1} to the latest version {2} \n 
+        cc: """.format(
+        datetime.today(),
+        dep_name,
+        dep_latest_version
+    )
+    _, owners = self._find_owners(dep_name)
+    for owner in owners:
+      description += "[~{0}], ".format(owner)
+    try:
+      self.jira.update_issue(issue, description=description)
+    except Exception as e:
+      traceback.print_exc()
+      logging.error("Failed updating issue: "+ str(e))
+
+
+  def _find_owners(self, dep_name):
+    """
+    Find owners for a dependency/
+    Args:
+      dep_name
+    Return:
+      primary: The primary owner of the dep. The Jira issue will be assigned 
to the primary owner.
+      others: A list of other owners of the dep. Owners will be cc'ed in the 
description.
+    """
+    try:
+      dep_info = self.owners_map[dep_name]
+      owners = dep_info['owners']
+      if not owners:
+        logging.warning("Could not find owners for " + dep_name)
+        return None, []
+    except KeyError:
+      traceback.print_exc()
+      logging.warning("Could not find the dependency info of {0} in the OWNERS 
configurations.".format(dep_name))
+      return None, []
+    except Exception as e:
+      traceback.print_exc()
+      logging.error("Failed finding dependency owners: "+ str(e))
+      return None, None
+
+    logging.info("Found owners of {0}: {1}".format(dep_name, owners))
+    owners = owners.split(',')
+    owners = map(str.strip, owners)
+    owners = list(filter(None, owners))
+    primary = owners[0]
+    del owners[0]
+    return primary, owners
diff --git a/.test-infra/jenkins/jira_utils/jira_manager_test.py 
b/.test-infra/jenkins/jira_utils/jira_manager_test.py
new file mode 100644
index 0000000..15677d0
--- /dev/null
+++ b/.test-infra/jenkins/jira_utils/jira_manager_test.py
@@ -0,0 +1,243 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+import unittest, mock
+from mock import patch, mock_open, Mock
+from jira_manager import JiraManager
+from datetime import datetime
+
+
+class MockedJiraIssue:
+  def __init__(self, key, summary, description, status):
+    self.key = key
+    self.fields = self.MockedJiraIssueFields(summary, description, status)
+
+  class MockedJiraIssueFields:
+    def __init__(self, summary, description, status):
+      self.summary = summary
+      self.description = description
+      self.status = self.MockedJiraIssueStatus(status)
+
+    class MockedJiraIssueStatus:
+      def __init__(self, status):
+        self.name = status
+
+
+@patch('jira_utils.jira_manager.JiraClient')
+class JiraManagerTest(unittest.TestCase):
+  """Tests for `jira_manager.py`."""
+
+  def setUp(self):
+    print "\n\nTest : " + self._testMethodName
+
+
+  def test_find_owners_with_single_owner(self, *args):
+    """
+    Test on _find_owners with single owner
+    Expect: the primary owner is 'owner0', an empty list of other owners.
+    """
+    owners_yaml = """
+                  deps:
+                    dep0:
+                      owners: owner0,
+                  """
+    with patch('__builtin__.open', mock_open(read_data=owners_yaml)):
+      manager = JiraManager('url', 'username', 'password', owners_yaml)
+      primary, owners = manager._find_owners('dep0')
+      self.assertEqual(primary, 'owner0')
+      self.assertEqual(len(owners), 0)
+
+
+  def test_find_owners_with_multi_owners(self, *args):
+    """
+    Test on _find_owners with multiple owners.
+    Expect: the primary owner is 'owner0', a list contains 'owner1' and 
'owner2'.
+    """
+    owners_yaml = """
+                  deps:
+                    dep0:
+                      owners: owner0, owner1 , owner2,
+                  """
+    with patch('__builtin__.open', mock_open(read_data=owners_yaml)):
+      manager = JiraManager('url', 'username', 'password', owners_yaml)
+      primary, owners = manager._find_owners('dep0')
+      self.assertEqual(primary, 'owner0')
+      self.assertEqual(len(owners), 2)
+      self.assertIn('owner1', owners)
+      self.assertIn('owner2', owners)
+
+
+  def test_find_owners_with_no_owners_defined(self, *args):
+    """
+    Test on _find_owners without owner.
+    Expect: the primary owner is None, an empty list of other owners.
+    """
+    owners_yaml = """
+                  deps:
+                    dep0:
+                      owners:
+                  """
+    with patch('__builtin__.open', mock_open(read_data=owners_yaml)):
+      manager = JiraManager('url', 'username', 'password', owners_yaml)
+      primary, owners = manager._find_owners('dep0')
+      self.assertIsNone(primary)
+      self.assertEqual(len(owners), 0)
+
+
+  def test_find_owners_with_no_dep_defined(self, *args):
+    """
+    Test on _find_owners with non-defined dep.
+    Expect: through out KeyErrors. The primary owner is None, an empty list of 
other owners.
+    """
+    owners_yaml = """
+                  deps:
+                    dep0:
+                      owners:
+                  """
+    with patch('__builtin__.open', mock_open(read_data=owners_yaml)):
+      manager = JiraManager('url', 'username', 'password', owners_yaml)
+      primary, owners = manager._find_owners('dep1')
+      self.assertIsNone(primary)
+      self.assertEqual(len(owners), 0)
+
+
+  @patch('jira_utils.jira_manager.datetime', 
Mock(today=Mock(return_value=datetime.strptime('2000-01-01', '%Y-%m-%d'))))
+  def test_run_with_creating_new_issue(self, *args):
+    """
+    Test JiraManager.run on creating a new issue.
+    Expect: jira.create_issue is called once with certain parameters.
+    """
+    owners_yaml = """
+                  deps:
+                    dep0:
+                      owners: owner0, owner1 , owner2,
+                  """
+    with patch('__builtin__.open', mock_open(read_data=owners_yaml)):
+      manager = JiraManager('url', 'username', 'password', owners_yaml)
+      manager.run('dep0', '1.0', 'Python')
+      
manager.jira.create_issue.assert_called_once_with(self._get_experct_summary('dep0',
 '1.0'),
+                                                        ['dependencies'],
+                                                        
self._get_expected_description('dep0', '1.0', ['owner1', 'owner2']),
+                                                        assignee='owner0')
+
+
+  @patch('jira_utils.jira_manager.datetime', 
Mock(today=Mock(return_value=datetime.strptime('2000-01-01', '%Y-%m-%d'))))
+  def test_run_with_updating_existing_task(self, *args):
+    """
+    Test JiraManager.run on updating an existing issue.
+    Expect: jira.update_issue is called once.
+    """
+    dep_name = 'dep0'
+    dep_latest_version = '1.0'
+    owners_yaml = """
+                  deps:
+                    dep0:
+                      owners:
+                  """
+    summary = self._get_experct_summary(dep_name, dep_latest_version)
+    description = self._get_expected_description(dep_name, dep_latest_version, 
[])
+
+    with patch('__builtin__.open', mock_open(read_data=owners_yaml)):
+      with patch('jira_utils.jira_manager.JiraManager._search_issues',
+        return_value=[MockedJiraIssue('BEAM-1000', summary, description, 
'Open')]):
+        manager = JiraManager('url', 'username', 'password', owners_yaml)
+        manager.run(dep_name, dep_latest_version, 'Python')
+        manager.jira.update_issue.assert_called_once()
+
+
+  @patch('jira_utils.jira_manager.datetime', 
Mock(today=Mock(return_value=datetime.strptime('2000-01-01', '%Y-%m-%d'))))
+  def test_run_with_creating_new_subtask(self, *args):
+    """
+    Test JiraManager.run on creating a new sub-task.
+    Expect: jira.create_issue is called once with certain parameters.
+    """
+    dep_name = 'group0:artifact0'
+    dep_latest_version = '1.0'
+    owners_yaml = """
+                  deps:
+                    group0:artifact0:
+                      group: group0
+                      artifact: artifact0
+                      owners: owner0
+                  """
+    summary = self._get_experct_summary('group0', None)
+    description = self._get_expected_description(dep_name, dep_latest_version, 
[])
+
+    with patch('__builtin__.open', mock_open(read_data=owners_yaml)):
+      with patch('jira_utils.jira_manager.JiraManager._search_issues',
+        side_effect = [[MockedJiraIssue('BEAM-1000', summary, description, 
'Open')],
+                      []]):
+        manager = JiraManager('url', 'username', 'password', owners_yaml)
+        manager.run(dep_name, dep_latest_version, 'Java', group_id='group0')
+        
manager.jira.create_issue.assert_called_once_with(self._get_experct_summary(dep_name,
 dep_latest_version),
+                                                          ['dependencies'],
+                                                          
self._get_expected_description(dep_name, dep_latest_version, []),
+                                                          assignee='owner0',
+                                                          
parent_key='BEAM-1000',
+                                                          )
+
+
+  @patch('jira_utils.jira_manager.datetime', 
Mock(today=Mock(return_value=datetime.strptime('2000-01-01', '%Y-%m-%d'))))
+  @patch('jira_utils.jira_manager.JiraClient.create_issue', side_effect = 
[MockedJiraIssue('BEAM-2000', 'summary', 'description', 'Open')])
+  def test_run_with_reopening_existing_parent_issue(self, *args):
+    """
+    Test JiraManager.run on reopening a parent issue.
+    Expect: jira.reopen_issue is called once.
+    """
+    dep_name = 'group0:artifact0'
+    dep_latest_version = '1.0'
+    owners_yaml = """
+                  deps:
+                    group0:artifact0:
+                      group: group0
+                      artifact: artifact0
+                      owners: owner0
+                  """
+    summary = self._get_experct_summary('group0', None)
+    description = self._get_expected_description(dep_name, dep_latest_version, 
[])
+    with patch('__builtin__.open', mock_open(read_data=owners_yaml)):
+      with patch('jira_utils.jira_manager.JiraManager._search_issues',
+        side_effect = [[MockedJiraIssue('BEAM-1000', summary, description, 
'Closed')],
+                      []]):
+        manager = JiraManager('url', 'username', 'password', owners_yaml)
+        manager.run(dep_name, dep_latest_version, sdk_type='Java', 
group_id='group0')
+        manager.jira.reopen_issue.assert_called_once()
+
+
+  def _get_experct_summary(self, dep_name, dep_latest_version):
+    summary =  'Beam Dependency Update Request: ' + dep_name
+    if dep_latest_version:
+      summary = summary + " " + dep_latest_version
+    return summary
+
+
+  def _get_expected_description(self, dep_name, dep_latest_version, owners):
+    description = """\n\n{0}\n
+        Please review and upgrade the {1} to the latest version {2} \n 
+        cc: """.format(
+      datetime.strptime('2000-01-01', '%Y-%m-%d'),
+      dep_name,
+      dep_latest_version
+    )
+    for owner in owners:
+      description += "[~{0}], ".format(owner)
+    return description
+
+
+if __name__ == '__main__':
+  unittest.main()
+
diff --git a/.test-infra/jenkins/job_Dependency_Check.groovy 
b/.test-infra/jenkins/job_Dependency_Check.groovy
index 06041de..ac66881 100644
--- a/.test-infra/jenkins/job_Dependency_Check.groovy
+++ b/.test-infra/jenkins/job_Dependency_Check.groovy
@@ -47,6 +47,12 @@ job('beam_Dependency_Check') {
             ' && bash .test-infra/jenkins/dependency_check/generate_report.sh')
   }
 
+  wrappers{
+    credentialsBinding {
+        usernamePassword('BEAM_JIRA_BOT_USERNAME', 'BEAM_JIRA_BOT_PASSWORD', 
'beam-jira-bot')
+    }
+  }
+    
   def date = new Date().format('yyyy-MM-dd')
   publishers {
     extendedEmail {
diff --git a/ownership/JAVA_DEPENDENCY_OWNERS.yaml 
b/ownership/JAVA_DEPENDENCY_OWNERS.yaml
index b01cc99..1c8a613 100644
--- a/ownership/JAVA_DEPENDENCY_OWNERS.yaml
+++ b/ownership/JAVA_DEPENDENCY_OWNERS.yaml
@@ -18,7 +18,7 @@
 
 # Beam Java SDK dependency ownership
 # Please update if new dependencies are introduced to the Beam.
-# Sign up with you JIRA username to take the owership of a package.
+# Sign up with you JIRA username to take the ownership of a package.
 # Separate names by comma.
 
 ---
@@ -819,11 +819,6 @@ deps:
     artifact: httpcore-nio
     owners:
 
-  org.apache.httpcomponents:httpcore-nio:
-    group: org.apache.httpcomponents
-    artifact: httpcore-nio
-    owners:
-
   org.apache.kafka:kafka_2.11:
     group: org.apache.kafka
     artifact: kafka_2.11
diff --git a/ownership/PYTHON_DEPENDENCY_OWNERS.yaml 
b/ownership/PYTHON_DEPENDENCY_OWNERS.yaml
index a67a4e6..b94f1c8 100644
--- a/ownership/PYTHON_DEPENDENCY_OWNERS.yaml
+++ b/ownership/PYTHON_DEPENDENCY_OWNERS.yaml
@@ -18,7 +18,7 @@
 
 # Beam Python SDK dependency ownership
 # Please update if new dependencies are introduced to the Beam.
-# Sign up with you JIRA username to take the owership of a package.
+# Sign up with you JIRA username to take the ownership of a package.
 # Separate names by comma.
 
 ---

Reply via email to