add grpcbox instrumentation library (#70)
* add grpcbox instrumentation library * grpcbox: fix .app file license and deps * lock grpcbox
This commit is contained in:
parent
db5193be45
commit
74172effcd
|
@ -0,0 +1,19 @@
|
|||
.rebar3
|
||||
_*
|
||||
.eunit
|
||||
*.o
|
||||
*.beam
|
||||
*.plt
|
||||
*.swp
|
||||
*.swo
|
||||
.erlang.cookie
|
||||
ebin
|
||||
log
|
||||
erl_crash.dump
|
||||
.rebar
|
||||
logs
|
||||
_build
|
||||
.idea
|
||||
*.iml
|
||||
rebar3.crashdump
|
||||
*~
|
|
@ -0,0 +1,191 @@
|
|||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
Copyright 2022, Tristan Sloughter <t@crashfast.com>.
|
||||
|
||||
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.
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
opentelemetry_grpcbox
|
||||
=====
|
||||
|
||||
This [grpcbox](https://github.com/tsloughter/grpcbox) interceptor uses the
|
||||
[OpenTelemetry](http://opentelemetry.io/) API to create Spans for outgoing and
|
||||
incoming requests and propagates them as part of the gRPC metadata.
|
||||
|
||||
### Server
|
||||
|
||||
Configure as an interceptor:
|
||||
|
||||
```erlang
|
||||
#{service_protos => [route_guide_pb],
|
||||
unary_interceptor => {otel_grpcbox_interceptor, unary}}
|
||||
```
|
||||
|
||||
Or as a middleware in the chain interceptor:
|
||||
|
||||
```erlang
|
||||
#{service_protos => [route_guide_pb],
|
||||
unary_interceptor =>
|
||||
grpcbox_chain_interceptor:unary([...,
|
||||
fun otel_grpcbox_interceptor:unary/4,
|
||||
...])}
|
||||
```
|
||||
|
||||
### Client
|
||||
|
||||
Example in `sys.config` for setting up a [client
|
||||
channel](https://grpc.io/docs/what-is-grpc/core-concepts/#channels):
|
||||
|
||||
``` erlang
|
||||
{client, #{channels => [{default_channel, [{http, "localhost", 8080, []}],
|
||||
#{unary_interceptor => fun otel_grpcbox_interceptor:unary_client/7}}]}}
|
||||
```
|
|
@ -0,0 +1,26 @@
|
|||
{erl_opts, [debug_info]}.
|
||||
|
||||
{deps, [grpcbox,
|
||||
{opentelemetry_api, "~> 1.0"}]}.
|
||||
|
||||
{project_plugins, [{rebar_covertool, "1.1.0"},
|
||||
{grpcbox_plugin, "~> 0.7.0"}]}.
|
||||
|
||||
{profiles,
|
||||
[{test, [{erl_opts, [nowarn_export_all]},
|
||||
|
||||
{grpc, [{protos, "test/otel_interceptor_SUITE_data"},
|
||||
{out_dir, "test"},
|
||||
{gpb_opts, [{o, "test"},
|
||||
{descriptor, true},
|
||||
{module_name_suffix, "_pb"}]}]},
|
||||
|
||||
{deps, [{opentelemetry, "~> 1.0"},
|
||||
jsx]}]}]}.
|
||||
|
||||
{cover_enabled, true}.
|
||||
{cover_opts, [verbose]}.
|
||||
{cover_export_enabled, true}.
|
||||
{covertool, [{coverdata_files, ["ct.coverdata"]}]}.
|
||||
|
||||
{ct_opts, [{ct_hooks, [cth_surefire]}]}.
|
|
@ -0,0 +1,26 @@
|
|||
{"1.2.0",
|
||||
[{<<"acceptor_pool">>,{pkg,<<"acceptor_pool">>,<<"1.0.0">>},1},
|
||||
{<<"chatterbox">>,{pkg,<<"ts_chatterbox">>,<<"0.11.0">>},1},
|
||||
{<<"ctx">>,{pkg,<<"ctx">>,<<"0.6.0">>},1},
|
||||
{<<"gproc">>,{pkg,<<"gproc">>,<<"0.8.0">>},1},
|
||||
{<<"grpcbox">>,{pkg,<<"grpcbox">>,<<"0.14.0">>},0},
|
||||
{<<"hpack">>,{pkg,<<"hpack_erl">>,<<"0.2.3">>},2},
|
||||
{<<"opentelemetry_api">>,{pkg,<<"opentelemetry_api">>,<<"1.0.2">>},0}]}.
|
||||
[
|
||||
{pkg_hash,[
|
||||
{<<"acceptor_pool">>, <<"43C20D2ACAE35F0C2BCD64F9D2BDE267E459F0F3FD23DAB26485BF518C281B21">>},
|
||||
{<<"chatterbox">>, <<"B8F372C706023EB0DE5BF2976764EDB27C70FE67052C88C1F6A66B3A5626847F">>},
|
||||
{<<"ctx">>, <<"8FF88B70E6400C4DF90142E7F130625B82086077A45364A78D208ED3ED53C7FE">>},
|
||||
{<<"gproc">>, <<"CEA02C578589C61E5341FCE149EA36CCEF236CC2ECAC8691FBA408E7EA77EC2F">>},
|
||||
{<<"grpcbox">>, <<"3EB321BCD2275BAF8B54CF381FEB7B0559A50C02544DE28FDA039C7F2F9D1A7A">>},
|
||||
{<<"hpack">>, <<"17670F83FF984AE6CD74B1C456EDDE906D27FF013740EE4D9EFAA4F1BF999633">>},
|
||||
{<<"opentelemetry_api">>, <<"91353EE40583B1D4F07D7B13ED62642ABFEC6AAA0D8A2114F07EDAFB2DF781C5">>}]},
|
||||
{pkg_hash_ext,[
|
||||
{<<"acceptor_pool">>, <<"0CBCD83FDC8B9AD2EEE2067EF8B91A14858A5883CB7CD800E6FCD5803E158788">>},
|
||||
{<<"chatterbox">>, <<"722FE2BAD52913AB7E87D849FC6370375F0C961FFB2F0B5E6D647C9170C382A6">>},
|
||||
{<<"ctx">>, <<"A14ED2D1B67723DBEBBE423B28D7615EB0BDCBA6FF28F2D1F1B0A7E1D4AA5FC2">>},
|
||||
{<<"gproc">>, <<"580ADAFA56463B75263EF5A5DF4C86AF321F68694E7786CB057FD805D1E2A7DE">>},
|
||||
{<<"grpcbox">>, <<"E24159B7B6D3F9869BBE528845C0125FED2259366BA908FD04A1F45FE81D0660">>},
|
||||
{<<"hpack">>, <<"06F580167C4B8B8A6429040DF36CC93BBA6D571FAEAEC1B28816523379CBB23A">>},
|
||||
{<<"opentelemetry_api">>, <<"2A8247F85C44216B883900067478D59955D11E58E5CFCA7C884CD4F203ACE3AC">>}]}
|
||||
].
|
|
@ -0,0 +1,16 @@
|
|||
{application, opentelemetry_grpcbox,
|
||||
[{description, "grpcbox interceptor for OpenTelemetry instrumentation"},
|
||||
{vsn, "0.1.0"},
|
||||
{registered, []},
|
||||
{applications,
|
||||
[kernel,
|
||||
stdlib,
|
||||
opentelemetry_api,
|
||||
grpcbox
|
||||
]},
|
||||
{env,[]},
|
||||
{modules, []},
|
||||
|
||||
{licenses, ["Apache-2.0"]},
|
||||
{links, [{"GitHub", "https://github.com/open-telemetry/opentelemetry-erlang-contrib/tree/main/instrumentation/opentelemetry_grpcbox"}]}
|
||||
]}.
|
|
@ -0,0 +1,79 @@
|
|||
%%%------------------------------------------------------------------------
|
||||
%% Copyright 2022, Tristan Sloughter
|
||||
%% 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.
|
||||
%%
|
||||
%% @doc grpcbox interceptor for tracing grpc client and server requests.
|
||||
%% @end
|
||||
%%%-------------------------------------------------------------------------
|
||||
-module(otel_grpcbox_interceptor).
|
||||
|
||||
-export([%% server side
|
||||
unary/4,
|
||||
stream/4,
|
||||
|
||||
%% unary client interceptor
|
||||
unary_client/7,
|
||||
|
||||
%% client streaminig interceptors
|
||||
new_stream/6,
|
||||
send_msg/3,
|
||||
recv_msg/3]).
|
||||
|
||||
-include_lib("opentelemetry_api/include/otel_tracer.hrl").
|
||||
|
||||
unary_client(Ctx, _Channel, Handler, FullMethod, Input, _Def, _Options) ->
|
||||
Metadata = otel_propagator_text_map:inject(opentelemetry:get_text_map_injector(),
|
||||
#{},
|
||||
fun set_metadata/3),
|
||||
Ctx1 = grpcbox_metadata:append_to_outgoing_ctx(Ctx, Metadata),
|
||||
?with_span(FullMethod, #{}, fun(_) ->
|
||||
Handler(Ctx1, Input)
|
||||
end).
|
||||
|
||||
new_stream(Ctx, Channel, Path, Def, Streamer, Options) ->
|
||||
{ok, S} = Streamer(Ctx, Channel, Path, Def, Options),
|
||||
{ok, #{client_stream => S}}.
|
||||
|
||||
send_msg(#{client_stream := ClientStream}, Streamer, Input) ->
|
||||
Streamer(ClientStream, Input).
|
||||
|
||||
recv_msg(#{client_stream := ClientStream}, Streamer, Input) ->
|
||||
Streamer(ClientStream, Input).
|
||||
|
||||
unary(Ctx, Message, _ServerInfo=#{full_method := FullMethod}, Handler) ->
|
||||
otel_ctx_from_ctx(Ctx),
|
||||
?with_span(FullMethod, #{}, fun(_) ->
|
||||
Handler(Ctx, Message)
|
||||
end).
|
||||
|
||||
stream(Ref, Stream, _ServerInfo=#{full_method := FullMethod}, Handler) ->
|
||||
Ctx = grpcbox_stream:ctx(Stream),
|
||||
otel_ctx_from_ctx(Ctx),
|
||||
?with_span(FullMethod, #{}, fun(_) ->
|
||||
Handler(Ref, Stream)
|
||||
end).
|
||||
|
||||
%%
|
||||
|
||||
otel_ctx_from_ctx(Ctx) ->
|
||||
Metadata = grpcbox_metadata:from_incoming_ctx(Ctx),
|
||||
otel_propagator_text_map:extract(opentelemetry:get_text_map_extractor(),
|
||||
Metadata,
|
||||
fun maps:keys/1,
|
||||
fun get_metadata/2).
|
||||
|
||||
get_metadata(Key, Metadata) ->
|
||||
maps:get(Key, Metadata, undefined).
|
||||
|
||||
set_metadata(Key, Value, Metadata) ->
|
||||
Metadata#{Key => Value}.
|
|
@ -0,0 +1,59 @@
|
|||
-module(otel_interceptor_SUITE).
|
||||
-compile(export_all).
|
||||
|
||||
-include_lib("common_test/include/ct.hrl").
|
||||
-include_lib("stdlib/include/assert.hrl").
|
||||
|
||||
-include_lib("opentelemetry_api/include/otel_tracer.hrl").
|
||||
|
||||
all() ->
|
||||
[trace_interceptor].
|
||||
|
||||
init_per_suite(Config) ->
|
||||
application:load(grpcbox),
|
||||
application:load(opentelemetry),
|
||||
Config.
|
||||
|
||||
end_per_suite(_Config) ->
|
||||
ok.
|
||||
|
||||
init_per_testcase(trace_interceptor, Config) ->
|
||||
application:set_env(opentelemetry, processors, [{otel_batch_processor, #{exporter => undefined}}]),
|
||||
application:set_env(grpcbox, client,
|
||||
#{channels => [{default_channel,
|
||||
[{http, "localhost", 8080, []}],
|
||||
#{unary_interceptor => fun otel_grpcbox_interceptor:unary_client/7}}]}),
|
||||
application:ensure_all_started(opentelemetry),
|
||||
application:set_env(grpcbox, servers,
|
||||
[#{grpc_opts =>
|
||||
#{service_protos => [route_guide_pb],
|
||||
services => #{'routeguide.RouteGuide' => routeguide_route_guide},
|
||||
unary_interceptor =>
|
||||
grpcbox_chain_interceptor:unary([fun otel_grpcbox_interceptor:unary/4,
|
||||
fun ?MODULE:trace_to_trailer/4])}}]),
|
||||
application:ensure_all_started(grpcbox),
|
||||
Config.
|
||||
|
||||
%% include a trace context and test that it works by having a second interceptor add
|
||||
%% the trace id from the context as a response trailer.
|
||||
trace_interceptor(_Config) ->
|
||||
Point = #{latitude => 409146138, longitude => -746188906},
|
||||
?with_span(<<"grpc-client-call">>, #{},
|
||||
fun(_) ->
|
||||
{_, _Feature, #{trailers := Trailers}} =
|
||||
routeguide_route_guide_client:get_feature(Point),
|
||||
SpanCtx = ?current_span_ctx,
|
||||
BinTraceId = integer_to_binary(otel_span:trace_id(SpanCtx)),
|
||||
?assertEqual(BinTraceId, maps:get(<<"x-grpc-trace-id">>, Trailers))
|
||||
|
||||
end),
|
||||
ok.
|
||||
|
||||
%%
|
||||
|
||||
trace_to_trailer(Ctx, Message, _ServerInfo, Handler) ->
|
||||
SpanCtx = ?current_span_ctx,
|
||||
BinTraceId = integer_to_binary(otel_span:trace_id(SpanCtx)),
|
||||
Trailer = grpcbox_metadata:pairs([{<<"x-grpc-trace-id">>, BinTraceId}]),
|
||||
Ctx1 = grpcbox_stream:add_trailers(Ctx, Trailer),
|
||||
Handler(Ctx1, Message).
|
|
@ -0,0 +1,120 @@
|
|||
// Copyright 2015 gRPC authors.
|
||||
//
|
||||
// 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.
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
option java_multiple_files = true;
|
||||
option java_package = "io.grpc.examples.routeguide";
|
||||
option java_outer_classname = "RouteGuideProto";
|
||||
|
||||
package routeguide;
|
||||
|
||||
// Interface exported by the server.
|
||||
service RouteGuide {
|
||||
// A simple RPC.
|
||||
//
|
||||
// Obtains the feature at a given position.
|
||||
//
|
||||
// A feature with an empty name is returned if there's no feature at the given
|
||||
// position.
|
||||
rpc GetFeature(Point) returns (Feature) {}
|
||||
|
||||
// A server-to-client streaming RPC.
|
||||
//
|
||||
// Obtains the Features available within the given Rectangle. Results are
|
||||
// streamed rather than returned at once (e.g. in a response message with a
|
||||
// repeated field), as the rectangle may cover a large area and contain a
|
||||
// huge number of features.
|
||||
rpc ListFeatures(Rectangle) returns (stream Feature) {}
|
||||
|
||||
// A client-to-server streaming RPC.
|
||||
//
|
||||
// Accepts a stream of Points on a route being traversed, returning a
|
||||
// RouteSummary when traversal is completed.
|
||||
rpc RecordRoute(stream Point) returns (RouteSummary) {}
|
||||
|
||||
// A Bidirectional streaming RPC.
|
||||
//
|
||||
// Accepts a stream of RouteNotes sent while a route is being traversed,
|
||||
// while receiving other RouteNotes (e.g. from other users).
|
||||
rpc RouteChat(stream RouteNote) returns (stream RouteNote) {}
|
||||
|
||||
// A simple RPC, which always generates error response.
|
||||
rpc GenerateError(Empty) returns (Empty) {}
|
||||
|
||||
// A simple RPC, which always generates error response.
|
||||
rpc StreamingGenerateError(Empty) returns (stream Empty) {}
|
||||
}
|
||||
|
||||
// Empty message - use for RPCs without input or output.
|
||||
message Empty {
|
||||
}
|
||||
|
||||
// Points are represented as latitude-longitude pairs in the E7 representation
|
||||
// (degrees multiplied by 10**7 and rounded to the nearest integer).
|
||||
// Latitudes should be in the range +/- 90 degrees and longitude should be in
|
||||
// the range +/- 180 degrees (inclusive).
|
||||
message Point {
|
||||
int32 latitude = 1;
|
||||
int32 longitude = 2;
|
||||
}
|
||||
|
||||
// A latitude-longitude rectangle, represented as two diagonally opposite
|
||||
// points "lo" and "hi".
|
||||
message Rectangle {
|
||||
// One corner of the rectangle.
|
||||
Point lo = 1;
|
||||
|
||||
// The other corner of the rectangle.
|
||||
Point hi = 2;
|
||||
}
|
||||
|
||||
// A feature names something at a given point.
|
||||
//
|
||||
// If a feature could not be named, the name is empty.
|
||||
message Feature {
|
||||
// The name of the feature.
|
||||
string name = 1;
|
||||
|
||||
// The point where the feature is detected.
|
||||
Point location = 2;
|
||||
}
|
||||
|
||||
// A RouteNote is a message sent while at a given point.
|
||||
message RouteNote {
|
||||
// The location from which the message is sent.
|
||||
Point location = 1;
|
||||
|
||||
// The message to be sent.
|
||||
string message = 2;
|
||||
}
|
||||
|
||||
// A RouteSummary is received in response to a RecordRoute rpc.
|
||||
//
|
||||
// It contains the number of individual points received, the number of
|
||||
// detected features, and the total distance covered as the cumulative sum of
|
||||
// the distance between each point.
|
||||
message RouteSummary {
|
||||
// The number of points received.
|
||||
int32 point_count = 1;
|
||||
|
||||
// The number of known features passed while traversing the route.
|
||||
int32 feature_count = 2;
|
||||
|
||||
// The distance covered in metres.
|
||||
int32 distance = 3;
|
||||
|
||||
// The duration of the traversal in seconds.
|
||||
int32 elapsed_time = 4;
|
||||
}
|
|
@ -0,0 +1,601 @@
|
|||
[{
|
||||
"location": {
|
||||
"latitude": 407838351,
|
||||
"longitude": -746143763
|
||||
},
|
||||
"name": "Patriots Path, Mendham, NJ 07945, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 408122808,
|
||||
"longitude": -743999179
|
||||
},
|
||||
"name": "101 New Jersey 10, Whippany, NJ 07981, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 413628156,
|
||||
"longitude": -749015468
|
||||
},
|
||||
"name": "U.S. 6, Shohola, PA 18458, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 419999544,
|
||||
"longitude": -740371136
|
||||
},
|
||||
"name": "5 Conners Road, Kingston, NY 12401, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 414008389,
|
||||
"longitude": -743951297
|
||||
},
|
||||
"name": "Mid Hudson Psychiatric Center, New Hampton, NY 10958, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 419611318,
|
||||
"longitude": -746524769
|
||||
},
|
||||
"name": "287 Flugertown Road, Livingston Manor, NY 12758, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 406109563,
|
||||
"longitude": -742186778
|
||||
},
|
||||
"name": "4001 Tremley Point Road, Linden, NJ 07036, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 416802456,
|
||||
"longitude": -742370183
|
||||
},
|
||||
"name": "352 South Mountain Road, Wallkill, NY 12589, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 412950425,
|
||||
"longitude": -741077389
|
||||
},
|
||||
"name": "Bailey Turn Road, Harriman, NY 10926, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 412144655,
|
||||
"longitude": -743949739
|
||||
},
|
||||
"name": "193-199 Wawayanda Road, Hewitt, NJ 07421, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 415736605,
|
||||
"longitude": -742847522
|
||||
},
|
||||
"name": "406-496 Ward Avenue, Pine Bush, NY 12566, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 413843930,
|
||||
"longitude": -740501726
|
||||
},
|
||||
"name": "162 Merrill Road, Highland Mills, NY 10930, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 410873075,
|
||||
"longitude": -744459023
|
||||
},
|
||||
"name": "Clinton Road, West Milford, NJ 07480, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 412346009,
|
||||
"longitude": -744026814
|
||||
},
|
||||
"name": "16 Old Brook Lane, Warwick, NY 10990, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 402948455,
|
||||
"longitude": -747903913
|
||||
},
|
||||
"name": "3 Drake Lane, Pennington, NJ 08534, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 406337092,
|
||||
"longitude": -740122226
|
||||
},
|
||||
"name": "6324 8th Avenue, Brooklyn, NY 11220, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 406421967,
|
||||
"longitude": -747727624
|
||||
},
|
||||
"name": "1 Merck Access Road, Whitehouse Station, NJ 08889, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 416318082,
|
||||
"longitude": -749677716
|
||||
},
|
||||
"name": "78-98 Schalck Road, Narrowsburg, NY 12764, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 415301720,
|
||||
"longitude": -748416257
|
||||
},
|
||||
"name": "282 Lakeview Drive Road, Highland Lake, NY 12743, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 402647019,
|
||||
"longitude": -747071791
|
||||
},
|
||||
"name": "330 Evelyn Avenue, Hamilton Township, NJ 08619, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 412567807,
|
||||
"longitude": -741058078
|
||||
},
|
||||
"name": "New York State Reference Route 987E, Southfields, NY 10975, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 416855156,
|
||||
"longitude": -744420597
|
||||
},
|
||||
"name": "103-271 Tempaloni Road, Ellenville, NY 12428, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 404663628,
|
||||
"longitude": -744820157
|
||||
},
|
||||
"name": "1300 Airport Road, North Brunswick Township, NJ 08902, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 407113723,
|
||||
"longitude": -749746483
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 402133926,
|
||||
"longitude": -743613249
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 400273442,
|
||||
"longitude": -741220915
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 411236786,
|
||||
"longitude": -744070769
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 411633782,
|
||||
"longitude": -746784970
|
||||
},
|
||||
"name": "211-225 Plains Road, Augusta, NJ 07822, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 415830701,
|
||||
"longitude": -742952812
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 413447164,
|
||||
"longitude": -748712898
|
||||
},
|
||||
"name": "165 Pedersen Ridge Road, Milford, PA 18337, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 405047245,
|
||||
"longitude": -749800722
|
||||
},
|
||||
"name": "100-122 Locktown Road, Frenchtown, NJ 08825, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 418858923,
|
||||
"longitude": -746156790
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 417951888,
|
||||
"longitude": -748484944
|
||||
},
|
||||
"name": "650-652 Willi Hill Road, Swan Lake, NY 12783, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 407033786,
|
||||
"longitude": -743977337
|
||||
},
|
||||
"name": "26 East 3rd Street, New Providence, NJ 07974, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 417548014,
|
||||
"longitude": -740075041
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 410395868,
|
||||
"longitude": -744972325
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 404615353,
|
||||
"longitude": -745129803
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 406589790,
|
||||
"longitude": -743560121
|
||||
},
|
||||
"name": "611 Lawrence Avenue, Westfield, NJ 07090, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 414653148,
|
||||
"longitude": -740477477
|
||||
},
|
||||
"name": "18 Lannis Avenue, New Windsor, NY 12553, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 405957808,
|
||||
"longitude": -743255336
|
||||
},
|
||||
"name": "82-104 Amherst Avenue, Colonia, NJ 07067, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 411733589,
|
||||
"longitude": -741648093
|
||||
},
|
||||
"name": "170 Seven Lakes Drive, Sloatsburg, NY 10974, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 412676291,
|
||||
"longitude": -742606606
|
||||
},
|
||||
"name": "1270 Lakes Road, Monroe, NY 10950, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 409224445,
|
||||
"longitude": -748286738
|
||||
},
|
||||
"name": "509-535 Alphano Road, Great Meadows, NJ 07838, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 406523420,
|
||||
"longitude": -742135517
|
||||
},
|
||||
"name": "652 Garden Street, Elizabeth, NJ 07202, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 401827388,
|
||||
"longitude": -740294537
|
||||
},
|
||||
"name": "349 Sea Spray Court, Neptune City, NJ 07753, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 410564152,
|
||||
"longitude": -743685054
|
||||
},
|
||||
"name": "13-17 Stanley Street, West Milford, NJ 07480, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 408472324,
|
||||
"longitude": -740726046
|
||||
},
|
||||
"name": "47 Industrial Avenue, Teterboro, NJ 07608, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 412452168,
|
||||
"longitude": -740214052
|
||||
},
|
||||
"name": "5 White Oak Lane, Stony Point, NY 10980, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 409146138,
|
||||
"longitude": -746188906
|
||||
},
|
||||
"name": "Berkshire Valley Management Area Trail, Jefferson, NJ, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 404701380,
|
||||
"longitude": -744781745
|
||||
},
|
||||
"name": "1007 Jersey Avenue, New Brunswick, NJ 08901, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 409642566,
|
||||
"longitude": -746017679
|
||||
},
|
||||
"name": "6 East Emerald Isle Drive, Lake Hopatcong, NJ 07849, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 408031728,
|
||||
"longitude": -748645385
|
||||
},
|
||||
"name": "1358-1474 New Jersey 57, Port Murray, NJ 07865, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 413700272,
|
||||
"longitude": -742135189
|
||||
},
|
||||
"name": "367 Prospect Road, Chester, NY 10918, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 404310607,
|
||||
"longitude": -740282632
|
||||
},
|
||||
"name": "10 Simon Lake Drive, Atlantic Highlands, NJ 07716, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 409319800,
|
||||
"longitude": -746201391
|
||||
},
|
||||
"name": "11 Ward Street, Mount Arlington, NJ 07856, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 406685311,
|
||||
"longitude": -742108603
|
||||
},
|
||||
"name": "300-398 Jefferson Avenue, Elizabeth, NJ 07201, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 419018117,
|
||||
"longitude": -749142781
|
||||
},
|
||||
"name": "43 Dreher Road, Roscoe, NY 12776, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 412856162,
|
||||
"longitude": -745148837
|
||||
},
|
||||
"name": "Swan Street, Pine Island, NY 10969, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 416560744,
|
||||
"longitude": -746721964
|
||||
},
|
||||
"name": "66 Pleasantview Avenue, Monticello, NY 12701, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 405314270,
|
||||
"longitude": -749836354
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 414219548,
|
||||
"longitude": -743327440
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 415534177,
|
||||
"longitude": -742900616
|
||||
},
|
||||
"name": "565 Winding Hills Road, Montgomery, NY 12549, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 406898530,
|
||||
"longitude": -749127080
|
||||
},
|
||||
"name": "231 Rocky Run Road, Glen Gardner, NJ 08826, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 407586880,
|
||||
"longitude": -741670168
|
||||
},
|
||||
"name": "100 Mount Pleasant Avenue, Newark, NJ 07104, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 400106455,
|
||||
"longitude": -742870190
|
||||
},
|
||||
"name": "517-521 Huntington Drive, Manchester Township, NJ 08759, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 400066188,
|
||||
"longitude": -746793294
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 418803880,
|
||||
"longitude": -744102673
|
||||
},
|
||||
"name": "40 Mountain Road, Napanoch, NY 12458, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 414204288,
|
||||
"longitude": -747895140
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 414777405,
|
||||
"longitude": -740615601
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 415464475,
|
||||
"longitude": -747175374
|
||||
},
|
||||
"name": "48 North Road, Forestburgh, NY 12777, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 404062378,
|
||||
"longitude": -746376177
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 405688272,
|
||||
"longitude": -749285130
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 400342070,
|
||||
"longitude": -748788996
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 401809022,
|
||||
"longitude": -744157964
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 404226644,
|
||||
"longitude": -740517141
|
||||
},
|
||||
"name": "9 Thompson Avenue, Leonardo, NJ 07737, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 410322033,
|
||||
"longitude": -747871659
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 407100674,
|
||||
"longitude": -747742727
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 418811433,
|
||||
"longitude": -741718005
|
||||
},
|
||||
"name": "213 Bush Road, Stone Ridge, NY 12484, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 415034302,
|
||||
"longitude": -743850945
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 411349992,
|
||||
"longitude": -743694161
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 404839914,
|
||||
"longitude": -744759616
|
||||
},
|
||||
"name": "1-17 Bergen Court, New Brunswick, NJ 08901, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 414638017,
|
||||
"longitude": -745957854
|
||||
},
|
||||
"name": "35 Oakland Valley Road, Cuddebackville, NY 12729, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 412127800,
|
||||
"longitude": -740173578
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 401263460,
|
||||
"longitude": -747964303
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 412843391,
|
||||
"longitude": -749086026
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 418512773,
|
||||
"longitude": -743067823
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 404318328,
|
||||
"longitude": -740835638
|
||||
},
|
||||
"name": "42-102 Main Street, Belford, NJ 07718, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 419020746,
|
||||
"longitude": -741172328
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 404080723,
|
||||
"longitude": -746119569
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 401012643,
|
||||
"longitude": -744035134
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 404306372,
|
||||
"longitude": -741079661
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 403966326,
|
||||
"longitude": -748519297
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 405002031,
|
||||
"longitude": -748407866
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 409532885,
|
||||
"longitude": -742200683
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 416851321,
|
||||
"longitude": -742674555
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 406411633,
|
||||
"longitude": -741722051
|
||||
},
|
||||
"name": "3387 Richmond Terrace, Staten Island, NY 10303, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 413069058,
|
||||
"longitude": -744597778
|
||||
},
|
||||
"name": "261 Van Sickle Road, Goshen, NY 10924, USA"
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 418465462,
|
||||
"longitude": -746859398
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 411733222,
|
||||
"longitude": -744228360
|
||||
},
|
||||
"name": ""
|
||||
}, {
|
||||
"location": {
|
||||
"latitude": 410248224,
|
||||
"longitude": -747127767
|
||||
},
|
||||
"name": "3 Hasta Way, Newton, NJ 07860, USA"
|
||||
}]
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,129 @@
|
|||
-module(routeguide_route_guide).
|
||||
|
||||
-include_lib("grpcbox/include/grpcbox.hrl").
|
||||
|
||||
-export([get_feature/2,
|
||||
list_features/2,
|
||||
record_route/2,
|
||||
route_chat/2,
|
||||
generate_error/2,
|
||||
streaming_generate_error/2]).
|
||||
|
||||
-type route_summary() ::
|
||||
#{point_count => integer(),
|
||||
feature_count => integer(),
|
||||
distance => integer(),
|
||||
elapsed_time => integer()}.
|
||||
|
||||
-type point() ::
|
||||
#{latitude => integer(),
|
||||
longitude => integer()}.
|
||||
|
||||
-type rectangle() ::
|
||||
#{lo => point(),
|
||||
hi => point()}.
|
||||
|
||||
-type route_note() ::
|
||||
#{location => point(),
|
||||
message => string()}.
|
||||
|
||||
-type feature() ::
|
||||
#{name => string(),
|
||||
location => point()}.
|
||||
|
||||
-spec get_feature(Ctx :: ctx:ctx(), Message :: point()) -> {ok, feature(), ctx:ctx()}.
|
||||
get_feature(Ctx, Message) ->
|
||||
Feature = #{name => find_point(Message, data()),
|
||||
location => Message},
|
||||
{ok, Feature, Ctx}.
|
||||
|
||||
-spec list_features(Message::rectangle(), GrpcStream :: grpcbox_stream:t()) -> ok.
|
||||
list_features(_Message, GrpcStream) ->
|
||||
grpcbox_stream:add_headers([{<<"info">>, <<"this is a test-implementation">>}], GrpcStream),
|
||||
grpcbox_stream:send(#{name => <<"Tour Eiffel">>,
|
||||
location => #{latitude => 3,
|
||||
longitude => 5}}, GrpcStream),
|
||||
grpcbox_stream:send(#{name => <<"Louvre">>,
|
||||
location => #{latitude => 4,
|
||||
longitude => 5}}, GrpcStream),
|
||||
|
||||
grpcbox_stream:add_trailers([{<<"nr_of_points_sent">>, <<"2">>}], GrpcStream),
|
||||
ok.
|
||||
|
||||
-spec record_route(reference(), GrpcStream :: grpcbox_stream:t()) -> {ok, route_summary(), grpcbox_stream:t()}.
|
||||
record_route(Ref, GrpcStream) ->
|
||||
record_route(Ref, #{t_start => erlang:system_time(1),
|
||||
acc => []}, GrpcStream).
|
||||
|
||||
record_route(Ref, Data=#{t_start := T0, acc := Points}, GrpcStream) ->
|
||||
receive
|
||||
{Ref, eos} ->
|
||||
%% receiving 'eos' tells us that we need to return a result.
|
||||
{ok, #{elapsed_time => erlang:system_time(1) - T0,
|
||||
point_count => length(Points),
|
||||
feature_count => count_features(Points),
|
||||
distance => distance(Points)}, GrpcStream};
|
||||
{Ref, Point} ->
|
||||
record_route(Ref, Data#{acc => [Point | Points]}, GrpcStream)
|
||||
end.
|
||||
|
||||
-spec route_chat(reference(), GrpcStream :: grpcbox_stream:t()) -> ok.
|
||||
route_chat(Ref, GrpcStream) ->
|
||||
route_chat(Ref, [], GrpcStream).
|
||||
|
||||
route_chat(Ref, Data, GrpcStream) ->
|
||||
receive
|
||||
{Ref, eos} ->
|
||||
ok;
|
||||
{Ref, #{location := Location} = P} ->
|
||||
Messages = proplists:get_all_values(Location, Data),
|
||||
[grpcbox_stream:send(Message, GrpcStream) || Message <- Messages],
|
||||
route_chat(Ref, [{Location, P} | Data], GrpcStream)
|
||||
end.
|
||||
|
||||
-spec generate_error(Ctx :: ctx:ctx(), Message :: map()) -> grpcbox_stream:grpc_extended_error_response().
|
||||
generate_error(_Ctx, _Message) ->
|
||||
{
|
||||
grpc_extended_error, #{
|
||||
status => ?GRPC_STATUS_INTERNAL,
|
||||
message => <<"error_message">>,
|
||||
trailers => #{
|
||||
<<"generate_error_trailer">> => <<"error_trailer">>
|
||||
}
|
||||
}
|
||||
}.
|
||||
|
||||
-spec streaming_generate_error(Message :: map(), GrpcStream :: grpcbox_stream:t()) -> no_return().
|
||||
streaming_generate_error(_Message, _GrpcStream) ->
|
||||
exit(
|
||||
{
|
||||
grpc_extended_error, #{
|
||||
status => ?GRPC_STATUS_INTERNAL,
|
||||
message => <<"error_message">>,
|
||||
trailers => #{
|
||||
<<"generate_error_trailer">> => <<"error_trailer">>
|
||||
}
|
||||
}
|
||||
}
|
||||
).
|
||||
|
||||
%% Supporting functions
|
||||
|
||||
data() ->
|
||||
case file:read_file("test/otel_interceptor_SUITE_data/route_guide_db.json") of
|
||||
{ok, Json} ->
|
||||
jsx:decode(Json, [return_maps, {labels, atom}]);
|
||||
{error, enoent} ->
|
||||
{ok, Json} = file:read_file("../../../../test/otel_interceptor_SUITE_data/route_guide_db.json"),
|
||||
jsx:decode(Json, [return_maps, {labels, atom}])
|
||||
end.
|
||||
|
||||
find_point(_Location, []) ->
|
||||
"";
|
||||
find_point(Location, [#{location := Location, name := Name} | _]) ->
|
||||
Name;
|
||||
find_point(Location, [_ | T]) ->
|
||||
find_point(Location, T).
|
||||
|
||||
count_features(_) -> 42.
|
||||
distance(_) -> 42.
|
|
@ -0,0 +1,33 @@
|
|||
%%%-------------------------------------------------------------------
|
||||
%% @doc Behaviour to implement for grpc service routeguide.RouteGuide.
|
||||
%% @end
|
||||
%%%-------------------------------------------------------------------
|
||||
|
||||
%% this module was generated on 2022-03-16T12:32:26+00:00 and should not be modified manually
|
||||
|
||||
-module(routeguide_route_guide_bhvr).
|
||||
|
||||
%% @doc Unary RPC
|
||||
-callback get_feature(ctx:ctx(), route_guide_pb:point()) ->
|
||||
{ok, route_guide_pb:feature(), ctx:ctx()} | grpcbox_stream:grpc_error_response().
|
||||
|
||||
%% @doc
|
||||
-callback list_features(route_guide_pb:rectangle(), grpcbox_stream:t()) ->
|
||||
ok | grpcbox_stream:grpc_error_response().
|
||||
|
||||
%% @doc
|
||||
-callback record_route(reference(), grpcbox_stream:t()) ->
|
||||
{ok, route_guide_pb:route_summary(), ctx:ctx()} | grpcbox_stream:grpc_error_response().
|
||||
|
||||
%% @doc
|
||||
-callback route_chat(reference(), grpcbox_stream:t()) ->
|
||||
ok | grpcbox_stream:grpc_error_response().
|
||||
|
||||
%% @doc Unary RPC
|
||||
-callback generate_error(ctx:ctx(), route_guide_pb:empty()) ->
|
||||
{ok, route_guide_pb:empty(), ctx:ctx()} | grpcbox_stream:grpc_error_response().
|
||||
|
||||
%% @doc
|
||||
-callback streaming_generate_error(route_guide_pb:empty(), grpcbox_stream:t()) ->
|
||||
ok | grpcbox_stream:grpc_error_response().
|
||||
|
|
@ -0,0 +1,133 @@
|
|||
%%%-------------------------------------------------------------------
|
||||
%% @doc Client module for grpc service routeguide.RouteGuide.
|
||||
%% @end
|
||||
%%%-------------------------------------------------------------------
|
||||
|
||||
%% this module was generated on 2022-03-16T12:32:26+00:00 and should not be modified manually
|
||||
|
||||
-module(routeguide_route_guide_client).
|
||||
|
||||
-compile(export_all).
|
||||
-compile(nowarn_export_all).
|
||||
|
||||
-include_lib("grpcbox/include/grpcbox.hrl").
|
||||
|
||||
-define(is_ctx(Ctx), is_tuple(Ctx) andalso element(1, Ctx) =:= ctx).
|
||||
|
||||
-define(SERVICE, 'routeguide.RouteGuide').
|
||||
-define(PROTO_MODULE, 'route_guide_pb').
|
||||
-define(MARSHAL_FUN(T), fun(I) -> ?PROTO_MODULE:encode_msg(I, T) end).
|
||||
-define(UNMARSHAL_FUN(T), fun(I) -> ?PROTO_MODULE:decode_msg(I, T) end).
|
||||
-define(DEF(Input, Output, MessageType), #grpcbox_def{service=?SERVICE,
|
||||
message_type=MessageType,
|
||||
marshal_fun=?MARSHAL_FUN(Input),
|
||||
unmarshal_fun=?UNMARSHAL_FUN(Output)}).
|
||||
|
||||
%% @doc Unary RPC
|
||||
-spec get_feature(route_guide_pb:point()) ->
|
||||
{ok, route_guide_pb:feature(), grpcbox:metadata()} | grpcbox_stream:grpc_error_response().
|
||||
get_feature(Input) ->
|
||||
get_feature(ctx:new(), Input, #{}).
|
||||
|
||||
-spec get_feature(ctx:t() | route_guide_pb:point(), route_guide_pb:point() | grpcbox_client:options()) ->
|
||||
{ok, route_guide_pb:feature(), grpcbox:metadata()} | grpcbox_stream:grpc_error_response().
|
||||
get_feature(Ctx, Input) when ?is_ctx(Ctx) ->
|
||||
get_feature(Ctx, Input, #{});
|
||||
get_feature(Input, Options) ->
|
||||
get_feature(ctx:new(), Input, Options).
|
||||
|
||||
-spec get_feature(ctx:t(), route_guide_pb:point(), grpcbox_client:options()) ->
|
||||
{ok, route_guide_pb:feature(), grpcbox:metadata()} | grpcbox_stream:grpc_error_response().
|
||||
get_feature(Ctx, Input, Options) ->
|
||||
grpcbox_client:unary(Ctx, <<"/routeguide.RouteGuide/GetFeature">>, Input, ?DEF(point, feature, <<"routeguide.Point">>), Options).
|
||||
|
||||
%% @doc
|
||||
-spec list_features(route_guide_pb:rectangle()) ->
|
||||
{ok, grpcbox_client:stream()} | grpcbox_stream:grpc_error_response().
|
||||
list_features(Input) ->
|
||||
list_features(ctx:new(), Input, #{}).
|
||||
|
||||
-spec list_features(ctx:t() | route_guide_pb:rectangle(), route_guide_pb:rectangle() | grpcbox_client:options()) ->
|
||||
{ok, grpcbox_client:stream()} | grpcbox_stream:grpc_error_response().
|
||||
list_features(Ctx, Input) when ?is_ctx(Ctx) ->
|
||||
list_features(Ctx, Input, #{});
|
||||
list_features(Input, Options) ->
|
||||
list_features(ctx:new(), Input, Options).
|
||||
|
||||
-spec list_features(ctx:t(), route_guide_pb:rectangle(), grpcbox_client:options()) ->
|
||||
{ok, grpcbox_client:stream()} | grpcbox_stream:grpc_error_response().
|
||||
list_features(Ctx, Input, Options) ->
|
||||
grpcbox_client:stream(Ctx, <<"/routeguide.RouteGuide/ListFeatures">>, Input, ?DEF(rectangle, feature, <<"routeguide.Rectangle">>), Options).
|
||||
|
||||
%% @doc
|
||||
-spec record_route() ->
|
||||
{ok, grpcbox_client:stream()} | grpcbox_stream:grpc_error_response().
|
||||
record_route() ->
|
||||
record_route(ctx:new(), #{}).
|
||||
|
||||
-spec record_route(ctx:t() | grpcbox_client:options()) ->
|
||||
{ok, grpcbox_client:stream()} | grpcbox_stream:grpc_error_response().
|
||||
record_route(Ctx) when ?is_ctx(Ctx) ->
|
||||
record_route(Ctx, #{});
|
||||
record_route(Options) ->
|
||||
record_route(ctx:new(), Options).
|
||||
|
||||
-spec record_route(ctx:t(), grpcbox_client:options()) ->
|
||||
{ok, grpcbox_client:stream()} | grpcbox_stream:grpc_error_response().
|
||||
record_route(Ctx, Options) ->
|
||||
grpcbox_client:stream(Ctx, <<"/routeguide.RouteGuide/RecordRoute">>, ?DEF(point, route_summary, <<"routeguide.Point">>), Options).
|
||||
|
||||
%% @doc
|
||||
-spec route_chat() ->
|
||||
{ok, grpcbox_client:stream()} | grpcbox_stream:grpc_error_response().
|
||||
route_chat() ->
|
||||
route_chat(ctx:new(), #{}).
|
||||
|
||||
-spec route_chat(ctx:t() | grpcbox_client:options()) ->
|
||||
{ok, grpcbox_client:stream()} | grpcbox_stream:grpc_error_response().
|
||||
route_chat(Ctx) when ?is_ctx(Ctx) ->
|
||||
route_chat(Ctx, #{});
|
||||
route_chat(Options) ->
|
||||
route_chat(ctx:new(), Options).
|
||||
|
||||
-spec route_chat(ctx:t(), grpcbox_client:options()) ->
|
||||
{ok, grpcbox_client:stream()} | grpcbox_stream:grpc_error_response().
|
||||
route_chat(Ctx, Options) ->
|
||||
grpcbox_client:stream(Ctx, <<"/routeguide.RouteGuide/RouteChat">>, ?DEF(route_note, route_note, <<"routeguide.RouteNote">>), Options).
|
||||
|
||||
%% @doc Unary RPC
|
||||
-spec generate_error(route_guide_pb:empty()) ->
|
||||
{ok, route_guide_pb:empty(), grpcbox:metadata()} | grpcbox_stream:grpc_error_response().
|
||||
generate_error(Input) ->
|
||||
generate_error(ctx:new(), Input, #{}).
|
||||
|
||||
-spec generate_error(ctx:t() | route_guide_pb:empty(), route_guide_pb:empty() | grpcbox_client:options()) ->
|
||||
{ok, route_guide_pb:empty(), grpcbox:metadata()} | grpcbox_stream:grpc_error_response().
|
||||
generate_error(Ctx, Input) when ?is_ctx(Ctx) ->
|
||||
generate_error(Ctx, Input, #{});
|
||||
generate_error(Input, Options) ->
|
||||
generate_error(ctx:new(), Input, Options).
|
||||
|
||||
-spec generate_error(ctx:t(), route_guide_pb:empty(), grpcbox_client:options()) ->
|
||||
{ok, route_guide_pb:empty(), grpcbox:metadata()} | grpcbox_stream:grpc_error_response().
|
||||
generate_error(Ctx, Input, Options) ->
|
||||
grpcbox_client:unary(Ctx, <<"/routeguide.RouteGuide/GenerateError">>, Input, ?DEF(empty, empty, <<"routeguide.Empty">>), Options).
|
||||
|
||||
%% @doc
|
||||
-spec streaming_generate_error(route_guide_pb:empty()) ->
|
||||
{ok, grpcbox_client:stream()} | grpcbox_stream:grpc_error_response().
|
||||
streaming_generate_error(Input) ->
|
||||
streaming_generate_error(ctx:new(), Input, #{}).
|
||||
|
||||
-spec streaming_generate_error(ctx:t() | route_guide_pb:empty(), route_guide_pb:empty() | grpcbox_client:options()) ->
|
||||
{ok, grpcbox_client:stream()} | grpcbox_stream:grpc_error_response().
|
||||
streaming_generate_error(Ctx, Input) when ?is_ctx(Ctx) ->
|
||||
streaming_generate_error(Ctx, Input, #{});
|
||||
streaming_generate_error(Input, Options) ->
|
||||
streaming_generate_error(ctx:new(), Input, Options).
|
||||
|
||||
-spec streaming_generate_error(ctx:t(), route_guide_pb:empty(), grpcbox_client:options()) ->
|
||||
{ok, grpcbox_client:stream()} | grpcbox_stream:grpc_error_response().
|
||||
streaming_generate_error(Ctx, Input, Options) ->
|
||||
grpcbox_client:stream(Ctx, <<"/routeguide.RouteGuide/StreamingGenerateError">>, Input, ?DEF(empty, empty, <<"routeguide.Empty">>), Options).
|
||||
|
Loading…
Reference in New Issue