Adding build tools for gRPC compilation.
ONOS-6095

Change-Id: I80687eb2a91ad60c4dbec0bb966e917555d46151
diff --git a/buck-tools/BUCK b/buck-tools/BUCK
index 6d05f9e..9548e41 100644
--- a/buck-tools/BUCK
+++ b/buck-tools/BUCK
@@ -52,3 +52,9 @@
   src = 'yang-schema',
   visibility = [ 'PUBLIC' ],
 )
+
+export_file(
+  name = 'grpc',
+  src = 'grpc',
+  visibility = [ 'PUBLIC' ],
+)
diff --git a/buck-tools/default.defs b/buck-tools/default.defs
index d70cc37..ad9f8aa 100644
--- a/buck-tools/default.defs
+++ b/buck-tools/default.defs
@@ -4,6 +4,7 @@
 include_defs('//bucklets/onos_app.bucklet')
 include_defs('//bucklets/yang.bucklet')
 include_defs('//bucklets/remote_jar.bucklet')
+include_defs('//bucklets/grpc.bucklet')
 
 BASE_DEPS = [
     '//lib:junit',
diff --git a/buck-tools/grpc b/buck-tools/grpc
new file mode 100755
index 0000000..6eb5af3
--- /dev/null
+++ b/buck-tools/grpc
@@ -0,0 +1,27 @@
+#!/bin/bash
+# -----------------------------------------------------------------------------
+# Generates the gRPC java artifacts from protobuf models.
+# -----------------------------------------------------------------------------
+out=$1
+shift
+proto_paths=$1
+shift
+protoc=$1
+shift
+plugin=$1
+shift
+
+#set -x
+
+dir=$(dirname $out)
+mkdir -p $dir
+
+$protoc \
+    --plugin=protoc-gen-grpc-java=$plugin \
+    --grpc-java_out=$dir \
+    --java_out=$dir \
+    $proto_paths \
+    $*
+
+cd $dir
+jar -cf $out *
diff --git a/bucklets/grpc.bucklet b/bucklets/grpc.bucklet
new file mode 100644
index 0000000..276586e
--- /dev/null
+++ b/bucklets/grpc.bucklet
@@ -0,0 +1,122 @@
+include_defs('//onos.defs')
+include_defs('//bucklets/onos.bucklet')
+
+
+PROTOC_VERSION = '3.2.0'
+GRPC_PLUGIN_VERSION = '1.3.0'
+
+PROTOC_EXECUTABLE_BASE_URL = "https://repo1.maven.org/maven2/com/google/protobuf/protoc"
+GRPC_PLUGIN_BASE_URL = "https://repo1.maven.org/maven2/io/grpc/protoc-gen-grpc-java"
+
+PROTOC_SHA1S = {
+    "protoc-3.3.0-osx-x86_64.exe":"3070e439f9557bb72fb04df631f29d7556c9029c",
+    "protoc-3.3.0-linux-x86_64.exe":"e6a95fc7477c602cc402ed976d3edbd82c841879",
+    "protoc-3.2.0-linux-x86_64.exe":"086893ffdc1023e503ccd0ee522ca1e6046b12a7",
+    "protoc-3.2.0-osx-x86_64.exe":"87f532ef51bb314d2c5d2ba7842b39cbbdb60323"
+}
+
+GRPC_JAVA_SHA1S = {
+    "protoc-gen-grpc-java-1.3.0-linux-x86_64.exe":"44a0fa3e6074852ea84f93d258233b3f4f6d9e53",
+    "protoc-gen-grpc-java-1.3.0-osx-x86_64.exe":"61a1b81b9f0af7d0900c314a4201972b52fb5f12"
+}
+
+#Returns the string for the OS and architecture of the system of the form 'OS-ARCH'
+def get_system_arch():
+    import platform
+    os = platform.system().lower()
+    arch = platform.machine()
+    if os == "darwin":
+        os = "osx"
+    return "%s-%s" % ( os, arch)
+
+def fetch_protoc_binary(
+        protoc_version = PROTOC_VERSION
+    ):
+    file_name = "protoc-%s-%s.exe" % (protoc_version, get_system_arch())
+    if file_name not in PROTOC_SHA1S:
+        raise Exception('Cannot download %s, architecture not supported' % file_name)
+    remote_file(
+        name = 'fetch-protoc-binary-' + protoc_version,
+        out = 'protoc-binary',
+        url = PROTOC_EXECUTABLE_BASE_URL + '/' + protoc_version + '/' + file_name,
+        sha1 = PROTOC_SHA1S[file_name],
+    )
+    genrule(
+        name = 'prepare-protoc-executable-' + protoc_version,
+        srcs = [ ':fetch-protoc-binary-' + protoc_version ],
+        bash = 'cp $(location :fetch-protoc-binary-' + protoc_version +') $OUT && chmod +x $OUT',
+        executable = True,
+        visibility = [ "PUBLIC" ],
+        out = 'protoc.exe',
+    )
+
+def fetch_grpc_plugin_binary(
+        grpc_plugin_version = GRPC_PLUGIN_VERSION
+):
+    file_name = "protoc-gen-grpc-java-%s-%s.exe" % (grpc_plugin_version, get_system_arch())
+    if file_name not in GRPC_JAVA_SHA1S:
+        raise Exception('Cannot download %s, architecture not supported' % file_name)
+    remote_file(
+        name = 'fetch-grpc-plugin-binary-' + grpc_plugin_version,
+        out = 'grpc-plugin-binary',
+        url = GRPC_PLUGIN_BASE_URL + '/' + grpc_plugin_version + '/' + file_name,
+        sha1 = GRPC_JAVA_SHA1S[file_name],
+    )
+    genrule(
+        name = 'prepare-grpc-plugin-executable-' + grpc_plugin_version,
+        srcs = [ ':fetch-grpc-plugin-binary-' + grpc_plugin_version ],
+        bash = 'cp $(location :fetch-grpc-plugin-binary-' + grpc_plugin_version + ') $OUT && chmod +x $OUT',
+        executable = True,
+        visibility = [ "PUBLIC" ],
+        out = 'grpc-plugin.exe',
+    )
+
+def _get_name():
+    base_path = get_base_path()
+    return ONOS_ARTIFACT_BASE + base_path.replace('/', '-') #TODO Unix-separator
+
+def grpc_jar(
+    name = None,
+    deps = [],
+    #NOTE: if targeting a directory also built with maven this path MUST end in
+        # /proto because maven plugin interprets imports relative to the proto
+        # directory and BUCK interprets imports relative to the last directory
+        # listed in the first listed proto_path which contains the specified
+        # file
+    proto_paths = [],
+    proto_match_patterns = [ "**/proto/**/*.proto" ],
+    protoc_version = PROTOC_VERSION,
+    plugin_version = GRPC_PLUGIN_VERSION,
+    **kwargs
+    ):
+
+    #Get the correct name for the protoc compilation call
+    if name is None:
+        name = _get_name()
+
+    #Create the string for the proto_path arguments (order matters, similar to classpath)
+    if len(proto_paths) != 0:
+        proto_paths_string = "-I=" + reduce(lambda a,b:  a +" -I=" + b, proto_paths)
+    else:
+        proto_paths_string = ""
+    protoc = name + '-protoc'
+
+    genrule(
+        name = protoc,
+        srcs = glob(proto_match_patterns),
+        out = 'grpc.src.zip',
+        cmd = '$(location //buck-tools:grpc) $OUT '
+              + '\"' + proto_paths_string + '\" '
+              + '$(location //incubator/protobuf-dependencies:prepare-protoc-executable-'+ protoc_version + ') '
+              + '$(location //incubator/grpc-dependencies:prepare-grpc-plugin-executable-' + plugin_version + ') '
+              + '$SRCS',
+    )
+
+    osgi_jar_with_tests(
+        name = name,
+        srcs = [ ':' + protoc ],
+        deps = deps + [ ':' + protoc ],
+        do_javadocs = False,
+        do_checkstyle = False,
+        **kwargs
+    )
diff --git a/incubator/grpc-dependencies/BUCK b/incubator/grpc-dependencies/BUCK
new file mode 100644
index 0000000..393524a
--- /dev/null
+++ b/incubator/grpc-dependencies/BUCK
@@ -0,0 +1,3 @@
+include_defs('//bucklets/grpc.bucklet')
+
+fetch_grpc_plugin_binary()
\ No newline at end of file
diff --git a/incubator/protobuf-dependencies/BUCK b/incubator/protobuf-dependencies/BUCK
new file mode 100644
index 0000000..825a324
--- /dev/null
+++ b/incubator/protobuf-dependencies/BUCK
@@ -0,0 +1,3 @@
+include_defs('//bucklets/grpc.bucklet')
+
+fetch_protoc_binary()
\ No newline at end of file
diff --git a/incubator/protobuf/BUCK b/incubator/protobuf/BUCK
new file mode 100644
index 0000000..3422455
--- /dev/null
+++ b/incubator/protobuf/BUCK
@@ -0,0 +1,25 @@
+
+COMPILE_DEPS = [
+    '//lib:CORE_DEPS',
+    ':onos-incubator-grpc',
+    '//lib:protobuf-java-3.2.0',
+]
+
+GRPC_DEPS = [
+    '//lib:GRPC_1.3',
+    '//lib:protobuf-java-3.2.0',
+    '//lib:guava'
+]
+
+grpc_jar(
+    name = 'onos-incubator-grpc',
+    deps = GRPC_DEPS,
+    proto_paths = ["$ONOS_ROOT/incubator/protobuf/src/main/proto"]
+)
+
+osgi_jar_with_tests(
+    deps = COMPILE_DEPS,
+    visibility = ['PUBLIC'],
+)
+
+
diff --git a/incubator/protobuf/src/main/proto/Device.proto b/incubator/protobuf/src/main/proto/models/Device.proto
similarity index 100%
rename from incubator/protobuf/src/main/proto/Device.proto
rename to incubator/protobuf/src/main/proto/models/Device.proto
diff --git a/incubator/protobuf/src/main/proto/DeviceEvent.proto b/incubator/protobuf/src/main/proto/models/DeviceEvent.proto
similarity index 90%
rename from incubator/protobuf/src/main/proto/DeviceEvent.proto
rename to incubator/protobuf/src/main/proto/models/DeviceEvent.proto
index 6a88768..f834aa1 100644
--- a/incubator/protobuf/src/main/proto/DeviceEvent.proto
+++ b/incubator/protobuf/src/main/proto/models/DeviceEvent.proto
@@ -2,8 +2,8 @@
 option java_package = "org.onosproject.grpc.net";
 
 
-import "Device.proto";
-import "Port.proto";
+import "models/Device.proto";
+import "models/Port.proto";
 
 package DeviceEvent;
 
diff --git a/incubator/protobuf/src/main/proto/Link.proto b/incubator/protobuf/src/main/proto/models/Link.proto
similarity index 100%
rename from incubator/protobuf/src/main/proto/Link.proto
rename to incubator/protobuf/src/main/proto/models/Link.proto
diff --git a/incubator/protobuf/src/main/proto/LinkEvent.proto b/incubator/protobuf/src/main/proto/models/LinkEvent.proto
similarity index 92%
rename from incubator/protobuf/src/main/proto/LinkEvent.proto
rename to incubator/protobuf/src/main/proto/models/LinkEvent.proto
index fdd6580..fcd13fb 100644
--- a/incubator/protobuf/src/main/proto/LinkEvent.proto
+++ b/incubator/protobuf/src/main/proto/models/LinkEvent.proto
@@ -3,7 +3,7 @@
 
 package LinkEvent;
 
-import "Link.proto";
+import "models/Link.proto";
 
 // Corresponds to org.onosproject.net.link.LinkEvent.
 message LinkNotification {
diff --git a/incubator/protobuf/src/main/proto/Port.proto b/incubator/protobuf/src/main/proto/models/Port.proto
similarity index 100%
rename from incubator/protobuf/src/main/proto/Port.proto
rename to incubator/protobuf/src/main/proto/models/Port.proto
diff --git a/incubator/rpc-grpc/src/main/proto/DeviceService.proto b/incubator/rpc-grpc/src/main/proto/DeviceService.proto
index 7ac8489..5ae7cd6 100644
--- a/incubator/rpc-grpc/src/main/proto/DeviceService.proto
+++ b/incubator/rpc-grpc/src/main/proto/DeviceService.proto
@@ -1,8 +1,8 @@
 syntax = "proto3";
 option java_package = "org.onosproject.grpc.net.device";
 
-import "Device.proto";
-import "Port.proto";
+import "models/Device.proto";
+import "models/Port.proto";
 
 package Device;
 
diff --git a/incubator/rpc-grpc/src/main/proto/LinkService.proto b/incubator/rpc-grpc/src/main/proto/LinkService.proto
index 99e0f22..ee32453 100644
--- a/incubator/rpc-grpc/src/main/proto/LinkService.proto
+++ b/incubator/rpc-grpc/src/main/proto/LinkService.proto
@@ -1,7 +1,7 @@
 syntax = "proto3";
 option java_package = "org.onosproject.grpc.net.link";
 
-import "Link.proto";
+import "models/Link.proto";
 
 package Link;
 
diff --git a/lib/BUCK b/lib/BUCK
index 43f0aa8..df51368 100644
--- a/lib/BUCK
+++ b/lib/BUCK
@@ -1,4 +1,4 @@
-# ***** This file was auto-generated at Tue, 30 May 2017 21:23:13 GMT. Do not edit this file manually. *****
+# ***** This file was auto-generated at Wed, 31 May 2017 18:05:22 GMT. Do not edit this file manually. *****
 # ***** Use onos-lib-gen *****
 
 pass_thru_pom(
@@ -121,6 +121,18 @@
   ],
 )
 
+osgi_feature_group(
+  name = 'GRPC_1.3',
+  visibility = ['PUBLIC'],
+  exported_deps = [
+    ':grpc-core-1.3.0',
+    ':grpc-protobuf-1.3.0',
+    ':grpc-stub-1.3.0',
+    ':grpc-netty-1.3.0',
+    ':grpc-auth-1.3.0',
+  ],
+)
+
 remote_jar (
   name = 'aopalliance-repackaged',
   out = 'aopalliance-repackaged-2.5.0-b32.jar',
@@ -1271,3 +1283,66 @@
   visibility = [ 'PUBLIC' ],
 )
 
+remote_jar (
+  name = 'grpc-core-1.3.0',
+  out = 'grpc-core-1.3.0.jar',
+  url = 'mvn:io.grpc:grpc-core:jar:1.3.0',
+  sha1 = 'c44f8c1d9561f5ad0212cb4ee5e035bc03d47700',
+  maven_coords = 'io.grpc:grpc-core:jar:NON-OSGI:1.3.0',
+  visibility = [ 'PUBLIC' ],
+)
+
+remote_jar (
+  name = 'grpc-protobuf-1.3.0',
+  out = 'grpc-protobuf-1.3.0.jar',
+  url = 'mvn:io.grpc:grpc-protobuf:jar:1.3.0',
+  sha1 = 'ab950b38b67a3b22c8d709970bef053304b13b31',
+  maven_coords = 'io.grpc:grpc-protobuf:jar:NON-OSGI:1.3.0',
+  visibility = [ 'PUBLIC' ],
+)
+
+remote_jar (
+  name = 'grpc-stub-1.3.0',
+  out = 'grpc-stub-1.3.0.jar',
+  url = 'mvn:io.grpc:grpc-stub:jar:1.3.0',
+  sha1 = 'ec6514126b1e4b460491b29df11a365880359d8c',
+  maven_coords = 'io.grpc:grpc-stub:jar:NON-OSGI:1.3.0',
+  visibility = [ 'PUBLIC' ],
+)
+
+remote_jar (
+  name = 'grpc-netty-1.3.0',
+  out = 'grpc-netty-1.3.0.jar',
+  url = 'mvn:io.grpc:grpc-netty:jar:1.3.0',
+  sha1 = 'a81c3f104c51302fbb972fdc1957dc5b3091d89a',
+  maven_coords = 'io.grpc:grpc-netty:jar:NON-OSGI:1.3.0',
+  visibility = [ 'PUBLIC' ],
+)
+
+remote_jar (
+  name = 'grpc-auth-1.3.0',
+  out = 'grpc-auth-1.3.0.jar',
+  url = 'mvn:io.grpc:grpc-auth:jar:1.3.0',
+  sha1 = '11e3062f80979d1c6b3e7b4225c10c5d854ffd90',
+  maven_coords = 'io.grpc:grpc-auth:jar:NON-OSGI:1.3.0',
+  visibility = [ 'PUBLIC' ],
+)
+
+remote_jar (
+  name = 'protobuf-java-3.3.0',
+  out = 'protobuf-java-3.3.0.jar',
+  url = 'mvn:com.google.protobuf:protobuf-java:jar:3.3.0',
+  sha1 = '9f301d1a27501b1afcb2ed16aad428337dabf9e4',
+  maven_coords = 'com.google.protobuf:protobuf-java:3.3.0',
+  visibility = [ 'PUBLIC' ],
+)
+
+remote_jar (
+  name = 'protobuf-java-3.2.0',
+  out = 'protobuf-java-3.2.0.jar',
+  url = 'mvn:com.google.protobuf:protobuf-java:jar:3.2.0',
+  sha1 = '62ccf171a106ff6791507f2d5364c275f9a3131d',
+  maven_coords = 'com.google.protobuf:protobuf-java:3.2.0',
+  visibility = [ 'PUBLIC' ],
+)
+
diff --git a/lib/deps.json b/lib/deps.json
index bc384ea..c51ef16 100644
--- a/lib/deps.json
+++ b/lib/deps.json
@@ -87,6 +87,13 @@
       "//core/api:onos-api-tests",
       "//core/common:onos-core-common-tests",
       "//utils/osgi:onlab-osgi-tests"
+    ],
+    "GRPC_1.3": [
+      "grpc-core-1.3.0",
+      "grpc-protobuf-1.3.0",
+      "grpc-stub-1.3.0",
+      "grpc-netty-1.3.0",
+      "grpc-auth-1.3.0"
     ]
   },
 
@@ -225,6 +232,13 @@
       "repo": "https://oss.sonatype.org/content/repositories/snapshots"
     },
     "plexus-utils": "mvn:org.codehaus.plexus:plexus-utils:3.0.24",
-    "sshd-core": "mvn:org.apache.sshd:sshd-core:1.4.0"
+    "sshd-core": "mvn:org.apache.sshd:sshd-core:1.4.0",
+    "grpc-core-1.3.0": "mvn:io.grpc:grpc-core:1.3.0",
+    "grpc-protobuf-1.3.0": "mvn:io.grpc:grpc-protobuf:1.3.0",
+    "grpc-stub-1.3.0": "mvn:io.grpc:grpc-stub:1.3.0",
+    "grpc-netty-1.3.0": "mvn:io.grpc:grpc-netty:1.3.0",
+    "grpc-auth-1.3.0": "mvn:io.grpc:grpc-auth:1.3.0",
+    "protobuf-java-3.3.0": "mvn:com.google.protobuf:protobuf-java:3.3.0",
+    "protobuf-java-3.2.0": "mvn:com.google.protobuf:protobuf-java:3.2.0"
   }
 }
diff --git a/modules.defs b/modules.defs
index 9d0b53e..13cd632 100644
--- a/modules.defs
+++ b/modules.defs
@@ -9,6 +9,7 @@
 API = [
     '//core/api:onos-api',
     '//incubator/api:onos-incubator-api',
+    '//incubator/protobuf:onos-incubator-grpc',
 ]
 
 CORE = UTILS + API + [