01-30-2025 09:24 PM - edited 01-30-2025 09:27 PM
Hi everyone.
I tried to write a java code using 'io.grpc' library to receive periodic/on-change dial out notification. Problem is router is able to connect to my grpc server(listener) but I am not receiving any notification (I verified that my path is supported, yangsuite is receiving the notification, even a sample python code works too - generated schema and service code for python I found somewhere on internet ). I am just trying to figure out what might be wrong. Maybe proto it self is wrong or JAVA code? In python, I found the generated py code from proto already on internet but for java I found proto and I am generating servicer and schema code from it.
encoding: KV-GPB
Here is proto:
syntax = "proto3";
// Package implements gRPC Model Driven Telemetry service
package com.notification.streamingtelemetry.grpcProto;
// gRPCMdtDialout defines service used for client-side streaming pushing MdtDialoutArgs.
service gRPCMdtDialout {
rpc MdtDialout(stream MdtDialoutArgs) returns(stream MdtDialoutArgs) {};
}
// MdtDialoutArgs is the content pushed to the server
message MdtDialoutArgs {
int64 ReqId = 1;
// data carries the payload content.
bytes data = 2;
string errors = 3;
}
This is my main function server code:
ExampleServiceImpl servicer = new ExampleServiceImpl();
Server server = Grpc.newServerBuilderForPort(57565, InsecureServerCredentials.create())
.addService(servicer)
.build()
.start();
servicer.bindService();
server.awaitTermination();
Servicer:
package xyz;
import io.grpc.stub.StreamObserver;
import com.notification.streamingtelemetry.grpcProto.MdtGrpcDialout.MdtDialoutArgs;
import com.notification.streamingtelemetry.grpcProto.gRPCMdtDialoutGrpc;
// Implementation of the ExampleService defined in the proto file
public class ExampleServiceImpl extends gRPCMdtDialoutGrpc.gRPCMdtDialoutImplBase {
public ExampleServiceImpl() {
super();
}
@Override
public StreamObserver<MdtDialoutArgs> mdtDialout(StreamObserver<MdtDialoutArgs> responseObserver) {
System.out.println("request received...123");
return new StreamObserver<MdtDialoutArgs>() {
@Override
public void onNext(MdtDialoutArgs request) {
System.out.println("request received..." + request.toString());
for (int i = 1; i <= 2; i++) {
MdtDialoutArgs stockQuote = MdtDialoutArgs.newBuilder().build();
responseObserver.onNext(stockQuote);
}
}
@Override
public void onCompleted() {
System.out.println("request oncomplete...");
responseObserver.onCompleted();
}
@Override
public void onError(Throwable arg0) {
System.out.println("error");
arg0.printStackTrace();
// TODO Auto-generated method stub
}
};
}
}
Below python code worked flawlessly:
class MdtDialoutServicer(gRPCMdtDialoutServicer):
def MdtDialout(self, request_iterator, context):
print("------------------one request received---------------------------")
for request in request_iterator:
print(request.data)
class GrpcTelemetryServer(object):
def serve(self, address, port):
server = grpc.server(futures.ThreadPoolExecutor(max_workers=5))
server_port = server.add_insecure_port("{0}:{1}".format(address, port))
servicer = MdtDialoutServicer()
add_gRPCMdtDialoutServicer_to_server(servicer, server)
server.start()
print('Server started')
server.wait_for_termination()
serv = GrpcTelemetryServer()
serv.serve("xx.xx.xx.xx", 57565)
But I dont see any difference in both in terms of implementation.
Thanks
01-31-2025 03:04 AM
From what i can see here, you are pretty much there. In the past i have seen folks use the protoc
compiler with the Java plugin to generate the necessary classes. This will make sure that the generated classes match the expected package and class names.
This isi what i think the server code should look like (i think), there is couple of changes to the server set up, service implemntion and stream handling, when you compare this to your python code you had this set up correctly.
public class TelemetryServer {
public static void main(String[] args) throws IOException, InterruptedException {
ExampleServiceImpl servicer = new ExampleServiceImpl();
Server server = Grpc.newServerBuilderForPort(57565, InsecureServerCredentials.create())
.addService(servicer)
.build()
.start();
System.out.println("Server started on port 57565");
server.awaitTermination();
}
}
HTH
01-31-2025 04:06 AM
Hi @bigevilbeard
I am using protoc command on Linux with protoc java plugin to generate code for service and schema.
However since everything in JAVA looks good, may be generated code or the proto itself has any issue ??
1 . Is there a way to extract the proto from the Cisco IOS XE device ?
2. Proto version might be incorrect?
01-31-2025 05:18 AM
At the device level no, XE devices do not expose the .proto
file directly. I think you can use Yang Suite to inspect the YANG models and generate the corresponding .proto
file, not tried this but think this is possible. If you are using proto3 you should be fine, if this is the same one used by Python which is working you should be good here.
01-31-2025 08:47 AM
For key-value GPB, which yang module I should check?
My python proto generated code is not from the above proto file. For Java only I am using the above proto. Python generated code I got from internet.
01-31-2025 09:35 AM
For key-value gpb encoding maps yang data nodes to key-value pairs in the gpb message, then each field in the gpb message corresponds to a YANG leaf or container. So like example here
interface-name
might map to a GPB field with the key "interface-name"
and a string value.interface-stats
might map to a nested GPB message.To decode key-value gpb data, you need to idenfify your correct YANG model to understand the structure of the data and then .proto
file that defines the GPB message format.
HTH
Discover and save your favorite ideas. Come back to expert answers, step-by-step guides, recent topics, and more.
New here? Get started with these tips. How to use Community New member guide