Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: initial code for integration testing example #223

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions integration_testing/.bazelrc
@@ -0,0 +1 @@
common --enable_bzlmod
1 change: 1 addition & 0 deletions integration_testing/.bazelversion
@@ -0,0 +1 @@
6.2.0
13 changes: 13 additions & 0 deletions integration_testing/BUILD.bazel
@@ -0,0 +1,13 @@
load("@bazel_gazelle//:def.bzl", "gazelle")
load("@npm//:defs.bzl", "npm_link_all_packages")
load("@rules_python//python:pip.bzl", "compile_pip_requirements")

compile_pip_requirements(
name = "requirements",
extra_args = ["--allow-unsafe"],
)

npm_link_all_packages(name = "node_modules")

# gazelle:prefix github.com/aspect-build/bazel-examples/integration_testing
gazelle(name = "gazelle")
116 changes: 116 additions & 0 deletions integration_testing/MODULE.bazel
@@ -0,0 +1,116 @@
"Declare dependencies for bzlmod, see https://bazel.build/build/bzlmod"
module(name = "integration_testing_example")

bazel_dep(name = "aspect_bazel_lib", version = "1.31.2")
bazel_dep(name = "aspect_rules_js", version = "1.13.1")
bazel_dep(name = "aspect_rules_ts", version = "1.0.5")
bazel_dep(name = "container_structure_test", version = "1.15.0")
bazel_dep(name = "gazelle", version = "0.28.0", repo_name = "bazel_gazelle")
bazel_dep(name = "platforms", version = "0.0.6")
bazel_dep(name = "protobuf", version = "3.19.6")
bazel_dep(name = "rules_go", version = "0.37.0", repo_name = "io_bazel_rules_go")
bazel_dep(name = "rules_jvm_external", version = "4.5")
bazel_dep(name = "rules_oci", version = "1.0.0-rc0")
bazel_dep(name = "rules_pkg", version = "0.9.1")
bazel_dep(name = "rules_python", version = "0.21.0")

# Python
# https://github.com/bazelbuild/rules_python/tree/main/examples/bzlmod
pip = use_extension("@rules_python//python:extensions.bzl", "pip")
python = use_extension("@rules_python//python:extensions.bzl", "python")

python.toolchain(
name = "python3",
python_version = "3.11",
)

use_repo(python, "python3_toolchains")

register_toolchains(
"@python3_toolchains//:all",
)

pip.parse(
name = "pip",
requirements_lock = "//:requirements.txt",
)

use_repo(pip, "pip")

# Java and other JVM languages:
# https://github.com/bazelbuild/rules_jvm_external/blob/master/examples/bzlmod/MODULE.bazel
# https://github.com/bazelbuild/rules_jvm_external#pinning-artifacts-and-integration-with-bazels-downloader
maven = use_extension("@rules_jvm_external//:extensions.bzl", "maven")

maven.install(
artifacts = ["io.grpc:grpc-all:1.51.1"],
lock_file = "//:maven_install.json",
)

use_repo(
maven,
"maven",
"unpinned_maven",
)

# JavaScript and TypeScript
# https://github.com/aspect-build/rules_js/tree/main/e2e/bzlmod
# https://github.com/aspect-build/rules_ts/tree/main/e2e/bzlmod
npm = use_extension("@aspect_rules_js//npm:extensions.bzl", "npm")

npm.npm_translate_lock(
name = "npm",

pnpm_lock = "//:pnpm-lock.yaml",
npmrc = "//:.npmrc",
)

use_repo(npm, "npm")

rules_ts_ext = use_extension(
"@aspect_rules_ts//ts:extensions.bzl",
"ext",
dev_dependency = True,
)

rules_ts_ext.deps()

use_repo(rules_ts_ext, "npm_typescript")

# Go
# https://github.com/bazelbuild/rules_go/tree/master/tests/bcr
go_deps = use_extension("@bazel_gazelle//:extensions.bzl", "go_deps")
go_sdk = use_extension("@io_bazel_rules_go//go:extensions.bzl", "go_sdk")

go_sdk.download(name = "go_sdk", version = "1.19.3")
use_repo(go_sdk, "go_sdk")

go_deps.module(
path = "google.golang.org/grpc",
version = "v1.50.1",
sum = "h1:DS/BukOZWp8s6p4Dt/tOaJaTQyPyOoCcrjroHuCeLzY=",
build_file_proto_mode = "disable"
)
go_deps.module(
path = "google.golang.org/protobuf",
sum = "h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=",
version = "v1.28.1",
build_file_proto_mode = "disable"
)
use_repo(go_deps, "org_golang_google_grpc", "org_golang_google_protobuf")

# Docker (OCI) containers
oci = use_extension("@rules_oci//oci:extensions.bzl", "oci")

oci.pull(
name = "distroless_python",
#digest = "sha256:b48e216f7c4adcf24fecd7016f3b8ead76866a19571819f67f47c1ccaf899717",
image = "gcr.io/distroless/python3",
tag = "latest",
)
oci.pull(
name = "distroless_java",
digest = "sha256:161a1d97d592b3f1919801578c3a47c8e932071168a96267698f4b669c24c76d",
image = "gcr.io/distroless/java17",
)
use_repo(oci, "distroless_python", "distroless_java")
5 changes: 5 additions & 0 deletions integration_testing/README.md
@@ -0,0 +1,5 @@
# Integration testing with Bazel

This demonstrates how applications written in several languages can be brought together in a common test fixture, allowing the full stack to be tested at HEAD.

It also shows that the services can be containerized and the containers are managed in the test runner's lifecycle.
13 changes: 13 additions & 0 deletions integration_testing/WORKSPACE.bazel
@@ -0,0 +1,13 @@
# Marker that this is the root of a Bazel workspace.

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")

# TODO(alex): add this module to registry.bazel.build
http_archive(
name = "aspect_rules_py",
sha256 = "c977cadb8703e325f02c1e6a3718e85f52b158e199654b1a28125c420588d720",
strip_prefix = "rules_py-0.2.0",
url = "https://github.com/aspect-build/rules_py/releases/download/v0.2.0/rules_py-v0.2.0.tar.gz",
)
load("@aspect_rules_py//py:repositories.bzl", "rules_py_dependencies")
rules_py_dependencies()
16 changes: 16 additions & 0 deletions integration_testing/go.mod
@@ -0,0 +1,16 @@
module github.com/aspect-build/codelabs

go 1.19

require (
google.golang.org/grpc v1.50.1
google.golang.org/protobuf v1.28.1
)

require (
github.com/golang/protobuf v1.5.2 // indirect
golang.org/x/net v0.0.0-20201021035429-f5854403a974 // indirect
golang.org/x/sys v0.1.0 // indirect
golang.org/x/text v0.3.3 // indirect
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 // indirect
)
83 changes: 83 additions & 0 deletions integration_testing/go.sum
@@ -0,0 +1,83 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20201021035429-f5854403a974 h1:IX6qOQeG5uLjB/hjjwjedwfjND0hgjPMMyO1RoIXQNI=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.50.1 h1:DS/BukOZWp8s6p4Dt/tOaJaTQyPyOoCcrjroHuCeLzY=
google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
63 changes: 63 additions & 0 deletions integration_testing/java/src/main/java/com/example/BUILD.bazel
@@ -0,0 +1,63 @@
load("@rules_oci//oci:defs.bzl", "oci_image", "oci_tarball")
load("@rules_jvm_external//:defs.bzl", "artifact")
load("@rules_pkg//:pkg.bzl", "pkg_tar")

java_library(
name = "logger_java_grpc",
srcs = ["LoggerGrpc.java"],
deps = [
"//schema:logger_java_proto",
artifact("com.google.guava:guava"),
artifact("com.google.protobuf:protobuf-java"),
artifact("io_grpc:grpc-api"),
artifact("io_grpc:grpc-core"),
artifact("io_grpc:grpc-netty-shaded"),
artifact("io_grpc:grpc-protobuf"),
artifact("io_grpc:grpc-stub"),
],
)

java_library(
name = "JavaLoggingClientLibrary",
srcs = ["JavaLoggingClientLibrary.java"],
deps = [
":logger_java_grpc",
"//schema:logger_java_proto",
artifact("io.grpc:grpc-stub"),
artifact("io.grpc:grpc-api"),
],
)

java_binary(
name = "JavaLoggingClient",
srcs = ["JavaLoggingClient.java"],
visibility = ["//visibility:public"],
deps = [":JavaLoggingClientLibrary"],
)

pkg_tar(
name = "tar",
srcs = [":JavaLoggingClient"],
include_runfiles = True,
)

oci_image(
name = "image",
base = "@distroless_java",
entrypoint = ["/app"],
tars = [":tar"],
)

# $ bazel build app:tarball
# $ docker load --input $(bazel cquery --output=files app:tarball)
# $ docker run --rm gcr.io/example:latest
# string(
# - "Hello World",
# + "Hello Go",
# )
oci_tarball(
name = "tarball",
image = ":image",
repo_tags = ["aspect.build/java-service:latest"],
visibility = ["//test:__pkg__"],
)
@@ -0,0 +1,14 @@
package com.example;

import java.util.Arrays;

/** A simple client that sends messages to the server to be stored. */
public class JavaLoggingClient {

public static void main(String[] args) throws Exception {
JavaLoggingClientLibrary client = new JavaLoggingClientLibrary("localhost", 50051);
System.out.println("Sending message to server");
client.sendLogMessageToServer(Arrays.toString(args));
client.shutdown();
}
}
@@ -0,0 +1,47 @@
package com.example;

import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
import io.grpc.StatusRuntimeException;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;

public class JavaLoggingClientLibrary {
private static final Logger logger = Logger.getLogger(JavaLoggingClientLibrary.class.getName());

private final ManagedChannel channel;
private final LoggerGrpc.LoggerBlockingStub blockingStub;

/** Construct client connecting to server at {@code host:port}. */
public JavaLoggingClientLibrary(String host, int port) {
this(
ManagedChannelBuilder.forAddress(host, port)
// Disable TLS to avoid needing certificates.
.usePlaintext()
.build());
}

/** Construct client for accessing the Logging server using the existing channel. */
JavaLoggingClientLibrary(ManagedChannel channel) {
this.channel = channel;
blockingStub = LoggerGrpc.newBlockingStub(channel);
}

public void shutdown() throws InterruptedException {
channel.shutdown().awaitTermination(5, TimeUnit.SECONDS);
}

/** Send log message to the server. */
public void sendLogMessageToServer(String message) {
logger.info("Trying to send message '" + message + "' to server...");
LogMessage logMessage = LogMessage.newBuilder().setMessage(message).build();
try {
blockingStub.sendLogMessage(logMessage);
} catch (StatusRuntimeException e) {
logger.log(Level.WARNING, "RPC failed: {0}", e.getStatus());
return;
}
}

}