Fix p4runtime runtime dependencies when building with Bazel

A convenient macro for packaging together all proto and gRPC libraries
in an OSGi jar is provided. Also re-packaging of gRPC core (to avoid OSGi
split problem) is simplified by depending on a patched fork of grpc-java.

Change-Id: Idb79a5bea8ae0bc57b146bda1fc47a4568d12c60
diff --git a/tools/build/bazel/generate_workspace.bzl b/tools/build/bazel/generate_workspace.bzl
index 5962fb1..afc9768 100644
--- a/tools/build/bazel/generate_workspace.bzl
+++ b/tools/build/bazel/generate_workspace.bzl
@@ -1,4 +1,4 @@
-# ***** This file was auto-generated at Fri, 10 Aug 2018 17:37:35 GMT. Do not edit this file manually. *****
+# ***** This file was auto-generated at Fri, 10 Aug 2018 23:10:39 GMT. Do not edit this file manually. *****
 # ***** Use onos-lib-gen *****
 
 load("//tools/build/bazel:variables.bzl", "ONOS_GROUP_ID", "ONOS_VERSION")
@@ -980,6 +980,36 @@
     )
 
     native.maven_jar(
+        name = "com_google_api_grpc_proto_google_common_protos",
+        artifact = "com.google.api.grpc:proto-google-common-protos:1.0.0",
+        sha1 = "86f070507e28b930e50d218ee5b6788ef0dd05e6",
+    )
+
+    native.maven_jar(
+        name = "com_google_errorprone_error_prone_annotations",
+        artifact = "com.google.errorprone:error_prone_annotations:2.1.2",
+        sha1 = "6dcc08f90f678ac33e5ef78c3c752b6f59e63e0c",
+    )
+
+    native.maven_jar(
+        name = "com_google_auth_google_auth_library_credentials",
+        artifact = "com.google.auth:google-auth-library-credentials:0.9.0",
+        sha1 = "8e2b181feff6005c9cbc6f5c1c1e2d3ec9138d46",
+    )
+
+    native.maven_jar(
+        name = "io_opencensus_opencensus_api",
+        artifact = "io.opencensus:opencensus-api:0.12.3",
+        sha1 = "743f074095f29aa985517299545e72cc99c87de0",
+    )
+
+    native.maven_jar(
+        name = "io_opencensus_opencensus_contrib_grpc_metrics",
+        artifact = "io.opencensus:opencensus-contrib-grpc-metrics:0.12.3",
+        sha1 = "a4c7ff238a91b901c8b459889b6d0d7a9d889b4d",
+    )
+
+    native.maven_jar(
         name = "openstack4j_core",
         artifact = "org.pacesys:openstack4j-core:3.1.0",
         sha1 = "634c2ad6728bb6e4cd91c950dd654aacb6f107a6",
@@ -1160,6 +1190,12 @@
     )
 
     native.maven_jar(
+        name = "runtime_grpc_context",
+        artifact = "io.grpc:grpc-context:1.14.0",
+        sha1 = "77252b5f926875891aaae5629e6ab2ef968cd6c6",
+    )
+
+    native.maven_jar(
         name = "runtime_grpc_stub",
         artifact = "io.grpc:grpc-stub:1.14.0",
         sha1 = "74bfe83c0dc69bf903fff8df3568cbeb8b387d35",
@@ -2121,6 +2157,36 @@
     )
 
     native.java_library(
+        name = "com_google_api_grpc_proto_google_common_protos",
+        visibility = ["//visibility:public"],
+        exports = ["@com_google_api_grpc_proto_google_common_protos//jar"],
+    )
+
+    native.java_library(
+        name = "com_google_errorprone_error_prone_annotations",
+        visibility = ["//visibility:public"],
+        exports = ["@com_google_errorprone_error_prone_annotations//jar"],
+    )
+
+    native.java_library(
+        name = "com_google_auth_google_auth_library_credentials",
+        visibility = ["//visibility:public"],
+        exports = ["@com_google_auth_google_auth_library_credentials//jar"],
+    )
+
+    native.java_library(
+        name = "io_opencensus_opencensus_api",
+        visibility = ["//visibility:public"],
+        exports = ["@io_opencensus_opencensus_api//jar"],
+    )
+
+    native.java_library(
+        name = "io_opencensus_opencensus_contrib_grpc_metrics",
+        visibility = ["//visibility:public"],
+        exports = ["@io_opencensus_opencensus_contrib_grpc_metrics//jar"],
+    )
+
+    native.java_library(
         name = "openstack4j_core",
         visibility = ["//visibility:public"],
         exports = ["@openstack4j_core//jar"],
@@ -2301,6 +2367,12 @@
     )
 
     native.java_library(
+        name = "runtime_grpc_context",
+        visibility = ["//visibility:public"],
+        exports = ["@runtime_grpc_context//jar"],
+    )
+
+    native.java_library(
         name = "runtime_grpc_stub",
         visibility = ["//visibility:public"],
         exports = ["@runtime_grpc_stub//jar"],
@@ -2568,6 +2640,11 @@
 artifact_map["@io_socket_client//jar"] = "mvn:io.socket:socket.io-client:jar:NON-OSGI:0.8.3"
 artifact_map["@json//jar"] = "mvn:org.json:json:jar:NON-OSGI:20090211"
 artifact_map["@engine_io_client//jar"] = "mvn:io.socket:engine.io-client:jar:NON-OSGI:0.8.3"
+artifact_map["@com_google_api_grpc_proto_google_common_protos//jar"] = "mvn:com.google.api.grpc:proto-google-common-protos:jar:NON-OSGI:1.0.0"
+artifact_map["@com_google_errorprone_error_prone_annotations//jar"] = "mvn:com.google.errorprone:error_prone_annotations:jar:NON-OSGI:2.1.2"
+artifact_map["@com_google_auth_google_auth_library_credentials//jar"] = "mvn:com.google.auth:google-auth-library-credentials:jar:NON-OSGI:0.9.0"
+artifact_map["@io_opencensus_opencensus_api//jar"] = "mvn:io.opencensus:opencensus-api:jar:NON-OSGI:0.12.3"
+artifact_map["@io_opencensus_opencensus_contrib_grpc_metrics//jar"] = "mvn:io.opencensus:opencensus-contrib-grpc-metrics:jar:NON-OSGI:0.12.3"
 artifact_map["@openstack4j_core//jar"] = "mvn:org.pacesys:openstack4j-core:jar:3.1.0"
 artifact_map["@openstack4j_http_connector//jar"] = "mvn:org.pacesys.openstack4j.connectors:openstack4j-http-connector:jar:3.1.0"
 artifact_map["@openstack4j_httpclient//jar"] = "mvn:org.pacesys.openstack4j.connectors:openstack4j-httpclient:jar:3.1.0"
@@ -2598,6 +2675,7 @@
 artifact_map["@gnu_idn//jar"] = "mvn:org.gnu.inet:libidn:jar:NON-OSGI:1.15"
 artifact_map["@sigar//jar"] = "mvn:org.knowhowlab.osgi:sigar:jar:1.6.5_01"
 artifact_map["@runtime_grpc_core//jar"] = "mvn:io.grpc:grpc-core:jar:NON-OSGI:1.14.0"
+artifact_map["@runtime_grpc_context//jar"] = "mvn:io.grpc:grpc-context:jar:NON-OSGI:1.14.0"
 artifact_map["@runtime_grpc_stub//jar"] = "mvn:io.grpc:grpc-stub:jar:NON-OSGI:1.14.0"
 artifact_map["@runtime_grpc_netty//jar"] = "mvn:io.grpc:grpc-netty:jar:NON-OSGI:1.14.0"
 artifact_map["@runtime_grpc_auth//jar"] = "mvn:io.grpc:grpc-auth:jar:NON-OSGI:1.14.0"
diff --git a/tools/build/bazel/googleapis_BUILD b/tools/build/bazel/googleapis_BUILD
index 97aea21..98e9e90 100644
--- a/tools/build/bazel/googleapis_BUILD
+++ b/tools/build/bazel/googleapis_BUILD
@@ -1,12 +1,6 @@
-package(default_visibility = [ "//visibility:public" ])
-
 proto_library(
     name = "status_proto",
     srcs = ["google/rpc/status.proto"],
-    deps = ["@com_google_protobuf//:any_proto"]
-)
-
-java_proto_library(
-    name = "status_java_proto_native",
-    deps = [":status_proto"],
+    deps = ["@com_google_protobuf//:any_proto"],
+    visibility = [ "//visibility:public" ],
 )
diff --git a/tools/build/bazel/googleapis_workspace.bzl b/tools/build/bazel/googleapis_workspace.bzl
deleted file mode 100644
index 94c84a9..0000000
--- a/tools/build/bazel/googleapis_workspace.bzl
+++ /dev/null
@@ -1,13 +0,0 @@
-load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
-
-COMMIT = "37cc0e5acae50ee91f00827a7010c3b07dfa5311"
-SHA = "17d023f48ea290f25edaf25a967973b5a42ce6d71b1570862f302d95aa8b9f77"
-
-def generate_googleapis():
-    http_archive(
-        name = "com_github_googleapis",
-        urls = ["https://github.com/googleapis/googleapis/archive/%s.zip" % COMMIT],
-        sha256 = SHA,
-        strip_prefix = "googleapis-" + COMMIT,
-        build_file = "//tools/build/bazel:googleapis_BUILD",
-    )
diff --git a/tools/build/bazel/grpc_core_repkg_BUILD b/tools/build/bazel/grpc_core_repkg_BUILD
deleted file mode 100644
index b5aa554..0000000
--- a/tools/build/bazel/grpc_core_repkg_BUILD
+++ /dev/null
@@ -1,20 +0,0 @@
-package(default_visibility = [ "//visibility:public" ])
-
-java_library(
-    name = "internal",
-    srcs = glob([
-        "src/main/java/io/grpc/internal/*.java",
-    ]),
-    deps = [
-        "@io_grpc_grpc_java//core",
-        "@io_grpc_grpc_java//context",
-        "@com_google_code_findbugs_jsr305//jar",
-        "@com_google_code_gson_gson//jar",
-        "@com_google_errorprone_error_prone_annotations//jar",
-        "@com_google_guava_guava//jar",
-        "@io_opencensus_opencensus_api//jar",
-        "@io_opencensus_opencensus_contrib_grpc_metrics//jar",
-    ],
-)
-
-
diff --git a/tools/build/bazel/grpc_workspace.bzl b/tools/build/bazel/grpc_workspace.bzl
index 331f0a4..27938e0 100644
--- a/tools/build/bazel/grpc_workspace.bzl
+++ b/tools/build/bazel/grpc_workspace.bzl
@@ -1,19 +1,24 @@
 load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
 
 GRPC_VER = "1.14.0"
-SHA = "657ee70cbbc7e8c5aa26d622329f5fc8bfa6ce5e960bcdbff802f785b0eba212"
+GRPC_SHA = "932c6e8a9f4ea26da7dc5cdb0faed53a8bb0821c9d0b43d8ab16c3f89d0cf909"
+
+GAPIS_COMMIT = "37cc0e5acae50ee91f00827a7010c3b07dfa5311"
+GAPIS_SHA = "17d023f48ea290f25edaf25a967973b5a42ce6d71b1570862f302d95aa8b9f77"
 
 def generate_grpc():
+    # Patched grpc-java that fixes the OSGi split problem.
     http_archive(
         name = "io_grpc_grpc_java",
-        urls = ["https://github.com/grpc/grpc-java/archive/v%s.zip" % GRPC_VER],
-        sha256 = SHA,
-        strip_prefix = "grpc-java-" + GRPC_VER,
+        urls = ["https://github.com/ccascone/grpc-java/archive/v%s-patched.zip" % GRPC_VER],
+        sha256 = GRPC_SHA,
+        strip_prefix = "grpc-java-%s-patched" % GRPC_VER,
     )
+    # Google APIs protos (status.proto, etc.)
     http_archive(
-        name = "io_grpc_grpc_java_core_repkg",
-        urls = ["https://github.com/grpc/grpc-java/archive/v%s.zip" % GRPC_VER],
-        sha256 = SHA,
-        strip_prefix = "grpc-java-%s/core" % GRPC_VER,
-        build_file = "//tools/build/bazel:grpc_core_repkg_BUILD",
+        name = "com_github_googleapis",
+        urls = ["https://github.com/googleapis/googleapis/archive/%s.zip" % GAPIS_COMMIT],
+        sha256 = GAPIS_SHA,
+        strip_prefix = "googleapis-" + GAPIS_COMMIT,
+        build_file = "//tools/build/bazel:googleapis_BUILD"
     )
diff --git a/tools/build/bazel/java_sources.bzl b/tools/build/bazel/java_sources.bzl
index 3a47569..734d048 100644
--- a/tools/build/bazel/java_sources.bzl
+++ b/tools/build/bazel/java_sources.bzl
@@ -33,10 +33,58 @@
       command = ";\n".join(cmd)
   )
 
+def _impl_alt(ctx):
+    ending = "-src.jar"
+    src_files = []
+    out_files = []
+    if len(ctx.files.srcs) == 0:
+        fail("Cannot generate source jars from and empty input")
+    for src in ctx.files.srcs:
+        if src.path.endswith(ending):
+            prefix = src.path[:-len(ending)]
+            src_files.append(src)
+            out_file = ctx.actions.declare_file(prefix + ".srcjar")
+            out_files.append(out_file)
+    if len(src_files) == 0:
+            fail("None of the given input files is a valid source jar (%s)"
+                % ", ".join([s.path for s in ctx.files.srcs]))
+    for i in range(len(src_files)):
+        cmd = "cp %s %s" % (src_files[i].path, out_files[i].path)
+        ctx.actions.run_shell(
+            inputs = [src_files[i]],
+            outputs = [out_files[i]],
+            progress_message = "Generating source jar %s" %  out_files[i].basename,
+            command = cmd
+        )
+    return DefaultInfo(files = depset(out_files))
+
+"""
+Creates a single source jar file from a set of .srcjar files.
+
+Args:
+    srcs: List of source files. Only files ending with .srcjar will be considered.
+"""
+
 java_sources = rule(
     attrs = {
         "srcs": attr.label_list(allow_files = True),
     },
     implementation = _impl,
     outputs = {"jar" : "%{name}.jar"},
-)
\ No newline at end of file
+)
+
+"""
+Returns a collection of source jar files ending with .srcjar from the given list of java_library or file labels.
+Input files are expected to end with "-src.jar".
+
+Args:
+    srcs: List of java_library labels.
+
+"""
+
+java_sources_alt = rule(
+    attrs = {
+        "srcs": attr.label_list(allow_files = True),
+    },
+    implementation = _impl_alt,
+)
diff --git a/tools/build/bazel/osgi_java_library.bzl b/tools/build/bazel/osgi_java_library.bzl
index 03913f4..0c2c21c 100644
--- a/tools/build/bazel/osgi_java_library.bzl
+++ b/tools/build/bazel/osgi_java_library.bzl
@@ -20,7 +20,12 @@
 load("//tools/build/bazel:checkstyle.bzl", "checkstyle_test")
 load("//tools/build/bazel:pom_file.bzl", "pom_file")
 load("//tools/build/bazel:java_sources.bzl", "java_sources")
+load("//tools/build/bazel:java_sources.bzl", "java_sources_alt")
 load("//tools/build/bazel:javadoc.bzl", "javadoc")
+load("@io_grpc_grpc_java//:java_grpc_library.bzl", "java_grpc_library")
+
+def _auto_name():
+    return "onos-" + native.package_name().replace("/", "-")
 
 def _all_java_sources():
     return native.glob(["src/main/java/**/*.java"])
@@ -381,7 +386,7 @@
         import_packages = None,
         bundle_classpath = ""):
     if name == None:
-        name = "onos-" + native.package_name().replace("/", "-")
+        name = _auto_name()
     if srcs == None:
         srcs = _all_java_sources()
     if resources == None:
@@ -573,3 +578,91 @@
         web_context = web_context,
         bundle_classpath = bundle_classpath,
     )
+
+
+"""
+    Creates an OSGI jar file from a set of protobuf and gRPC libraries.
+
+    Args:
+        name: Name of the rule to generate. Optional, defaults to a name based on the location in the source tree.
+              For example apps/mcast/app becomes onos-apps-mcast-app
+        proto_libs: (required) list of proto_library targets which generated Java classes will be included to this OSGi
+            jar. It is important that all the given targets reference to a single proto source files, for example
+            only the first 2 rules are good:
+
+            proto_library(
+                name = "foo_proto",
+                srcs = ["foo.proto"],
+            )
+
+            proto_library(
+                name = "bar_proto",
+                srcs = ["bar.proto"],
+            )
+
+            # THIS WILL NOT WORK
+            proto_library(
+                name = "foo_and_bar_proto",
+                srcs = ["foo.proto", "bar.proto"],
+            )
+
+        grpc_proto_lib: (optional) proto_library target that contains the schema of a gRPC service. If not passed,
+            the produced jar will NOT have any gRPC stub classes.
+        deps: Dependencies of the generated jar file. Expressed as a list of targets
+        group: Maven group ID for the resulting jar file. Optional, defaults to 'org.onosproject'
+        visibility: Visibility of the produced jar file to other BUILDs. Optional, defaults to public
+        version: Version of the generated jar file. Optional, defaults to the current ONOS version
+"""
+
+def osgi_proto_jar(
+        proto_libs,
+        grpc_proto_lib = None,
+        name = None,
+        deps = [],
+        group = "org.onosproject",
+        visibility = ["//visibility:public"],
+        version = ONOS_VERSION
+    ):
+    if name == None:
+        name = _auto_name()
+    native.java_proto_library(
+        name = name + "-java-proto",
+        deps = proto_libs,
+    )
+    java_sources_alt(
+        name = name + "-proto-srcjar",
+        srcs = [":%s-java-proto" % name],
+    )
+    osgi_srcs = [
+        ":%s-proto-srcjar" % name,
+    ]
+    base_deps = [
+        "@com_google_protobuf//:protobuf_java",
+    ]
+    if grpc_proto_lib != None:
+        grpc_java_lib = name + "-java-grpc"
+        java_grpc_library(
+            name = name + "-java-grpc",
+            srcs = [grpc_proto_lib],
+            deps = [":%s-java-proto" % name],
+        )
+        osgi_srcs.append(
+            ":%s-java-grpc__do_not_reference__srcjar" % name
+        )
+        base_deps.extend([
+            "@com_google_guava_guava//jar",
+            "@io_grpc_grpc_java//core",
+            "@io_grpc_grpc_java//stub",
+            "@io_grpc_grpc_java//protobuf",
+        ])
+    osgi_jar(
+        name = name,
+        srcs = osgi_srcs,
+        deps = base_deps + deps,
+        group = group,
+        visibility = visibility,
+        version = version,
+        suppress_errorprone = True,
+        suppress_checkstyle = True,
+        suppress_javadocs = True,
+    )
diff --git a/tools/build/bazel/p4lang_workspace.bzl b/tools/build/bazel/p4lang_workspace.bzl
index 24da166..abf4c5c 100644
--- a/tools/build/bazel/p4lang_workspace.bzl
+++ b/tools/build/bazel/p4lang_workspace.bzl
@@ -3,10 +3,14 @@
 P4RUNTIME_COMMIT = "028552d98b774301c51be0fe5bc97c9e95716759"
 PI_COMMIT = "36ca74fae69c8d0a142f8bfd2487bee72505cf48"
 
+P4RUNTIME_SHA = "f335573ea971c21a1a298954039a27881b7337a03f4523321b6458eb0558644a"
+PI_SHA = "767476cf9232dc39f0115d1ffc38f9b81acec74da078c048f278804f325bf77e"
+
 def generate_p4lang():
     http_archive(
         name = "com_github_p4lang_p4runtime",
         urls = ["https://github.com/p4lang/p4runtime/archive/%s.zip" % P4RUNTIME_COMMIT],
+        sha256 = P4RUNTIME_SHA,
         strip_prefix = "p4runtime-%s/proto" % P4RUNTIME_COMMIT,
         build_file = "//tools/build/bazel:p4runtime_BUILD"
     )
@@ -14,6 +18,7 @@
     http_archive(
         name = "com_github_p4lang_pi",
         urls = ["https://github.com/p4lang/PI/archive/%s.zip" % PI_COMMIT],
+        sha256 = PI_SHA,
         strip_prefix = "PI-%s/proto" % PI_COMMIT,
         build_file = "//tools/build/bazel:pi_BUILD"
     )
diff --git a/tools/build/bazel/p4runtime_BUILD b/tools/build/bazel/p4runtime_BUILD
index 8d1b221..db7598e 100644
--- a/tools/build/bazel/p4runtime_BUILD
+++ b/tools/build/bazel/p4runtime_BUILD
@@ -1,27 +1,3 @@
-package(default_visibility = ["//visibility:public"])
-
-load("@com_google_protobuf//:protobuf.bzl", "internal_copied_filegroup")
-load("@io_grpc_grpc_java//:java_grpc_library.bzl", "java_grpc_library")
-
-proto_library(
-    name = "p4data_proto",
-    srcs = ["p4/v1/p4data.proto"],
-)
-
-proto_library(
-    name = "p4types_proto",
-    srcs = ["p4/config/v1/p4types.proto"],
-)
-
-proto_library(
-    name = "p4info_proto",
-    srcs = ["p4/config/v1/p4info.proto"],
-    deps = [
-        ":p4types_proto",
-        "@com_google_protobuf//:any_proto"
-    ],
-)
-
 proto_library(
     name = "p4runtime_proto",
     srcs = ["p4/v1/p4runtime.proto"],
@@ -31,31 +7,27 @@
         "@com_github_googleapis//:status_proto",
         "@com_google_protobuf//:any_proto",
     ],
+    visibility = ["//visibility:public"],
 )
 
-java_proto_library(
-    name = "p4data_java_proto_native",
-    deps = [":p4data_proto"],
+proto_library(
+    name = "p4data_proto",
+    srcs = ["p4/v1/p4data.proto"],
+    visibility = ["//visibility:public"],
 )
 
-java_proto_library(
-    name = "p4types_java_proto_native",
-    deps = [":p4types_proto"],
+proto_library(
+    name = "p4types_proto",
+    srcs = ["p4/config/v1/p4types.proto"],
+    visibility = ["//visibility:public"],
 )
 
-java_proto_library(
-    name = "p4info_java_proto_native",
-    deps = [":p4info_proto"],
+proto_library(
+    name = "p4info_proto",
+    srcs = ["p4/config/v1/p4info.proto"],
+    deps = [
+        ":p4types_proto",
+        "@com_google_protobuf//:any_proto"
+    ],
+    visibility = ["//visibility:public"],
 )
-
-java_proto_library(
-    name = "p4runtime_java_proto_native",
-    deps = [":p4runtime_proto"],
-)
-
-java_grpc_library(
-    name = "p4runtime_java_grpc_native",
-    srcs = [":p4runtime_proto"],
-    deps = [":p4runtime_java_proto_native"],
-)
-
diff --git a/tools/build/bazel/pi_BUILD b/tools/build/bazel/pi_BUILD
index 307df5e..6735497 100644
--- a/tools/build/bazel/pi_BUILD
+++ b/tools/build/bazel/pi_BUILD
@@ -1,12 +1,5 @@
-package(default_visibility = ["//visibility:public"])
-
 proto_library(
     name = "p4config_proto",
     srcs = ["p4/tmp/p4config.proto"],
-)
-
-java_proto_library(
-    name = "p4config_java_proto_native",
-    deps = [":p4config_proto"],
     visibility = ["//visibility:public"],
 )