cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
622
Views
2
Helpful
5
Replies

JAVA code for gRPC is not working (Cisco IOS XE 17.3.2/CSR1000V)

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


5 Replies 5

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

Please mark this as helpful or solution accepted to help others
Connect with me https://bigevilbeard.github.io

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?


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.

Please mark this as helpful or solution accepted to help others
Connect with me https://bigevilbeard.github.io

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.





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

  1. A YANG leaf interface-name might map to a GPB field with the key "interface-name" and a string value.
  2. A YANG container 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

Please mark this as helpful or solution accepted to help others
Connect with me https://bigevilbeard.github.io