Uploader can handle local maven repo

Change-Id: If835c6c98f90a0ac4cc2e1f9fe1c9dd46d98574a
diff --git a/tools/build/bazel/upload-maven-artifacts.py b/tools/build/bazel/upload-maven-artifacts.py
new file mode 100755
index 0000000..d20e41d
--- /dev/null
+++ b/tools/build/bazel/upload-maven-artifacts.py
@@ -0,0 +1,181 @@
+#!/usr/bin/env python
+"""
+ Copyright 2018-present Open Networking Foundation
+
+ Licensed 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 subprocess import call
+import tempfile
+import hashlib
+import requests, os
+import xml.etree.ElementTree, shutil
+
+SONATYPE_USER=os.environ.get("SONATYPE_USER")
+SONATYPE_PASSWORD=os.environ.get("SONATYPE_PASSWORD")
+SONATYPE_PROFILE=os.environ.get("SONATYPE_PROFILE")
+
+CREATE_REPO_REQUEST_TEMPLATE = '''\
+<promoteRequest>
+    <data>
+      <description>%(description)</description>
+    </data>
+</promoteRequest>
+'''
+
+CLOSE_REPO_REQUEST_TEMPLATE = '''\
+<promoteRequest>
+    <data>
+      <description>%(description)</description>
+      <stagedRepositoryId>%(repo_id)</stagedRepositoryId>
+    </data>
+</promoteRequest>
+'''
+
+def hashlib_compute(hash, input_file, output_file):
+    with open(input_file, 'rb') as f:
+        for block in iter(lambda: f.read(100000), b''):
+            hash.update(block)
+        md5_string = hash.hexdigest()
+        output = open(output_file, "w")
+        output.write(md5_string + "\n")
+        f.close()
+        output.close()
+
+
+def generate_metadata_files(input_file):
+    # create a temporary directory to hold the metadata files
+    global tempdir
+    base_metadata_filename = tempdir + "/" + os.path.basename(input_file)
+
+    files = []
+
+    # generate the signature file
+    signature_filename = base_metadata_filename + ".asc"
+    call(["gpg", "--armor", "--detach-sig", "--output", signature_filename,  input_file])
+    files.append(signature_filename)
+
+    # generate the md5 checksum file
+    md5_filename = base_metadata_filename + ".md5"
+    md5 = hashlib.md5()
+    hashlib_compute(md5, input_file, md5_filename)
+    files.append(md5_filename)
+
+    # generate the SHA checksum file
+    sha1_filename = base_metadata_filename + ".sha1"
+    sha1 = hashlib.sha1()
+    hashlib_compute(sha1, input_file, sha1_filename)
+    files.append(sha1_filename)
+
+    return files
+
+
+def create_staging_repo(description):
+    if destination_repo_url is None:
+        return None
+    create_request = CREATE_REPO_REQUEST_TEMPLATE.replace("%(description)", description)
+    url = "https://" + destination_repo_url + "/service/local/staging/profiles" + "/" + SONATYPE_PROFILE + "/start"
+    headers = {'Content-Type': 'application/xml'}
+    r = requests.post(url, create_request, headers=headers, auth=(SONATYPE_USER, SONATYPE_PASSWORD))
+    root = xml.etree.ElementTree.fromstring(r.text)
+    repo_id = root.find("data").find("stagedRepositoryId").text
+    return repo_id
+
+
+def close_staging_repo(description, repo_id):
+    if repo_id is None:
+        return
+    close_request = CLOSE_REPO_REQUEST_TEMPLATE.replace("%(description)", description).replace("%(repo_id)", repo_id)
+    url = "https://" + destination_repo_url + "/service/local/staging/profiles" + "/" + SONATYPE_PROFILE + "/finish"
+    headers = {'Content-Type': 'application/xml'}
+    r = requests.post(url, close_request, headers=headers, auth=(SONATYPE_USER, SONATYPE_PASSWORD))
+
+
+def stage_file(file, repo_id, dest):
+    if destination_repo_url is not None:
+        # deploy to Nexus repo
+        upload_base = "https://" + destination_repo_url + "/service/local/staging/deployByRepositoryId"
+        url = upload_base + "/" + repo_id + "/" + os.path.dirname(dest) + "/" + os.path.basename(file)
+        headers = {'Content-Type': 'application/xml'}
+        with open(file, 'rb') as f:
+            r = requests.post(url, files={file: f}, headers=headers, auth=(SONATYPE_USER, SONATYPE_PASSWORD))
+    else:
+        # deploy to local repo
+        dest_local_repo = os.path.expanduser(local_maven_repo + "/" + dest)
+        dest_local_repo_dir = os.path.dirname(dest_local_repo)
+        if not os.path.isdir(dest_local_repo_dir):
+            os.makedirs(dest_local_repo_dir)
+        shutil.copyfile(src, dest_local_repo)
+
+
+def stage_files(files, dest):
+    for file in files:
+        stage_file(file=file, repo_id=repo_id, dest=dest)
+
+
+def upload_file(src, dest):
+    files = generate_metadata_files(src)
+    files.append(src)
+    stage_files(files, dest)
+
+
+if __name__ == '__main__':
+    import sys
+
+    if len(sys.argv) < 2:
+        print 'USAGE: upload-maven-artifacts catalog-file-name [nexus root url]'
+        sys.exit(1)
+
+    input_list_file = sys.argv[1]
+
+    local_maven_repo = None
+    destination_repo_url = None
+
+    if len(sys.argv) == 3:
+        destination_repo_url = sys.argv[2]
+    else:
+        local_maven_repo = os.environ.get("MAVEN_REPO")
+        if local_maven_repo is None:
+            local_maven_repo = "~/.m2/repository"
+
+    if destination_repo_url is not None:
+        if SONATYPE_USER is None:
+            print "Environment variable SONATYPE_USER must be set"
+            sys.exit(1)
+
+        if SONATYPE_PASSWORD is None:
+            print "Environment variable SONATYPE_PASSWORD must be set"
+            sys.exit(1)
+
+        if SONATYPE_PROFILE is None:
+            print "Environment variable SONATYPE_PROFILE must be set"
+            sys.exit(1)
+
+        print ("Uploading to remote repo: " + destination_repo_url)
+    else:
+        print ("Installing in local repo: " + local_maven_repo)
+
+    list_file = open(input_list_file, "r")
+    lines = list_file.readlines()
+    list_file.close()
+
+    tempdir = tempfile.mkdtemp(prefix="upload-maven-artifacts-")
+    description = "test repo"
+    repo_id = create_staging_repo(description)
+    for line in lines:
+        s = line.split()
+        src = s[0]
+        dest = s[1]
+        upload_file(src, dest)
+    close_staging_repo(repo_id=repo_id, description=description)
+    shutil.rmtree(tempdir)