Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/main/java/org/conductoross/grpcbin/GRPCServer.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ private void start() throws IOException {
int noAuthPort = 50051;
noAuthServer = ServerBuilder.forPort(noAuthPort)
.addService(new HelloWorldServiceImpl())
.addService(new KitchensinkServiceImpl())
.addService(ProtoReflectionService.newInstance())
.build()
.start();
Expand All @@ -31,6 +32,7 @@ private void start() throws IOException {
int authPort = 50052;
authServer = ServerBuilder.forPort(authPort)
.addService(new HelloWorldServiceImpl())
.addService(new KitchensinkServiceImpl())
.addService(ProtoReflectionService.newInstance())
.intercept(new AuthInterceptor()) // Add auth interceptor
.build()
Expand All @@ -44,6 +46,7 @@ private void start() throws IOException {
tlsServer = NettyServerBuilder.forPort(tlsPort)
.sslContext(GrpcSslContexts.configure(SslContextBuilder.forServer(certChain, privateKey)).build())
.addService(new HelloWorldServiceImpl())
.addService(new KitchensinkServiceImpl())
.addService(ProtoReflectionService.newInstance())
.intercept(new AuthInterceptor())
.build()
Expand Down
66 changes: 66 additions & 0 deletions src/main/java/org/conductoross/grpcbin/KitchensinkServiceImpl.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package org.conductoross.grpcbin;

import io.grpc.stub.StreamObserver;

/**
* Echo implementation of KitchensinkService.
*
* Every RPC reflects the request straight back to the caller, exercising all
* proto3 syntax features (scalars, nested messages, enums, repeated, map,
* oneof, well-known types, and recursive message references) over a real gRPC
* transport without any application logic.
*/
public class KitchensinkServiceImpl extends KitchensinkServiceGrpc.KitchensinkServiceImplBase {

@Override
public void echoScalars(AllScalars request, StreamObserver<AllScalars> responseObserver) {
responseObserver.onNext(request);
responseObserver.onCompleted();
}

@Override
public void echoNested(Outer request, StreamObserver<Outer> responseObserver) {
responseObserver.onNext(request);
responseObserver.onCompleted();
}

@Override
public void echoRepeated(RepeatedFields request, StreamObserver<RepeatedFields> responseObserver) {
responseObserver.onNext(request);
responseObserver.onCompleted();
}

@Override
public void echoMap(MapFields request, StreamObserver<MapFields> responseObserver) {
responseObserver.onNext(request);
responseObserver.onCompleted();
}

@Override
public void echoOneof(OneofMessage request, StreamObserver<OneofMessage> responseObserver) {
responseObserver.onNext(request);
responseObserver.onCompleted();
}

@Override
public void echoWkt(WellKnownTypes request, StreamObserver<WellKnownTypes> responseObserver) {
responseObserver.onNext(request);
responseObserver.onCompleted();
}

@Override
public void echoTree(TreeNode request, StreamObserver<TreeNode> responseObserver) {
responseObserver.onNext(request);
responseObserver.onCompleted();
}

// NodeA → NodeB: map value and count from the request where possible.
@Override
public void echoRecursive(NodeA request, StreamObserver<NodeB> responseObserver) {
NodeB response = NodeB.newBuilder()
.setCount(request.getValue().length())
.build();
responseObserver.onNext(response);
responseObserver.onCompleted();
}
}
Binary file added src/main/proto/compiled.bin
Binary file not shown.
118 changes: 118 additions & 0 deletions src/main/proto/kitchensink.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
syntax = "proto3";

package kitchensink;

option java_package = "org.conductoross.grpcbin";
option java_multiple_files = true;

import "google/protobuf/any.proto";
import "google/protobuf/duration.proto";
import "google/protobuf/struct.proto";
import "google/protobuf/timestamp.proto";

// ── Scalars ──────────────────────────────────────────────────────────────────
// Exercises all 15 proto3 scalar types.
message AllScalars {
double f_double = 1;
float f_float = 2;
int32 f_int32 = 3;
int64 f_int64 = 4;
uint32 f_uint32 = 5;
uint64 f_uint64 = 6;
sint32 f_sint32 = 7;
sint64 f_sint64 = 8;
fixed32 f_fixed32 = 9;
fixed64 f_fixed64 = 10;
sfixed32 f_sfixed32 = 11;
sfixed64 f_sfixed64 = 12;
bool f_bool = 13;
string f_string = 14;
bytes f_bytes = 15;
}

// ── Enum ─────────────────────────────────────────────────────────────────────
enum Status {
UNKNOWN = 0;
ACTIVE = 1;
INACTIVE = 2;
}

// ── Nested messages ───────────────────────────────────────────────────────────
message Outer {
string name = 1;
Inner inner = 2;

message Inner {
int32 value = 1;
Status status = 2;
}
}

// ── Repeated fields ───────────────────────────────────────────────────────────
message RepeatedFields {
repeated string tags = 1;
repeated int32 scores = 2;
repeated Outer items = 3;
}

// ── Map fields ────────────────────────────────────────────────────────────────
message MapFields {
map<string, string> string_map = 1;
map<string, int32> count_map = 2;
map<int32, string> index_map = 3;
}

// ── Oneof ─────────────────────────────────────────────────────────────────────
message OneofMessage {
string common_field = 1;
oneof kind {
string text_value = 2;
int32 int_value = 3;
bool bool_value = 4;
double float_value = 5;
}
}

// ── Well-known types ──────────────────────────────────────────────────────────
message WellKnownTypes {
google.protobuf.Timestamp created_at = 1;
google.protobuf.Duration ttl = 2;
google.protobuf.Any payload = 3;
google.protobuf.Struct metadata = 4;
google.protobuf.Value dynamic = 5;
google.protobuf.ListValue items = 6;
}

// ── Self-referential (was the StackOverflowError trigger) ────────────────────
message TreeNode {
string label = 1;
repeated TreeNode children = 2;
}

// ── Mutually recursive ────────────────────────────────────────────────────────
message NodeA {
string value = 1;
NodeB partner = 2;
}

message NodeB {
int32 count = 1;
NodeA partner = 2;
}

// ── Map whose value type is the containing message ────────────────────────────
message RecursiveMap {
map<string, RecursiveMap> nested = 1;
}

// ── Service with representative RPC patterns ──────────────────────────────────
service KitchensinkService {
rpc EchoScalars (AllScalars) returns (AllScalars) {}
rpc EchoNested (Outer) returns (Outer) {}
rpc EchoRepeated (RepeatedFields) returns (RepeatedFields) {}
rpc EchoMap (MapFields) returns (MapFields) {}
rpc EchoOneof (OneofMessage) returns (OneofMessage) {}
rpc EchoWkt (WellKnownTypes) returns (WellKnownTypes) {}
rpc EchoTree (TreeNode) returns (TreeNode) {}
rpc EchoRecursive (NodeA) returns (NodeB) {}
}
Loading