implementing an ExternalCallout connecting to my GRPC server

I have been trying to connect my gRPC server as an external callout to Apigee. I have deployed the server and added the gRPC server as external callout. But when I try to call the server I get the error 

{"fault":{"faultstring":"Encountered the following exception while sending the gRPC request or processing the response: [io.grpc.StatusRuntimeException: UNIMPLEMENTED: unknown service apigee.ExternalCalloutService].","detail":{"errorcode":"steps.externalcallout.ExecutionError"}}}

My gRPC server code looks like this

func (s *server) ProcessMessage(ctx context.Context, in *pb.MessageContext) (*pb.MessageContext, error) {
log.Printf("request ", in)
return &pb.MessageContext{ MessageId: "Hellotesting " }, nil
}

func main() {
flag.Parse()
lis, err := net.Listen("tcp", fmt.Sprintf(":%d", *port))
if err != nil {
log.Fatalf("failed to listen: %v", err)
}
log.Printf("server listening at %v")
s := grpc.NewServer()
pb.RegisterExternalCalloutServiceServer(s, &server{})
log.Printf("server listening at %v", lis.Addr())
if err := s.Serve(lis); err != nil {
log.Fatalf("failed to serve: %v", err)
}
}

I have also added my gRPC server details in Apigee as a target server in Environments.

I am confused on where the error is coming from. Thanks

Solved Solved
0 1 777
1 ACCEPTED SOLUTION

The error message suggests that the gRPC service does not implement the necessary interface. You didn't show the full code you're using, but the code ought to implement the protobuf that Apigee defines. It should look like this: 

package service

import (
	"context"
	"github.com/srinandan/external-callout-samples/common/pkg/apigee"
)

type ExternalCalloutServiceServer struct {
	apigee.UnimplementedExternalCalloutServiceServer
}

func NewExternalCalloutServiceServer() (apigee.ExternalCalloutServiceServer, error) {
	return &ExternalCalloutServiceServer{}, nil
}

func (c *ExternalCalloutServiceServer) ProcessMessage(ctx context.Context, req *apigee.MessageContext) (*apigee.MessageContext, error) {
	var err error
        .... 
	return req, err
}

Have you got something like that? And have you checked the logs on that gRPC service?  To verify that it's healthy, up, listening? 

There is a working example of a golang gRPC server that can be used as an ExternalCallout, here

View solution in original post

1 REPLY 1

The error message suggests that the gRPC service does not implement the necessary interface. You didn't show the full code you're using, but the code ought to implement the protobuf that Apigee defines. It should look like this: 

package service

import (
	"context"
	"github.com/srinandan/external-callout-samples/common/pkg/apigee"
)

type ExternalCalloutServiceServer struct {
	apigee.UnimplementedExternalCalloutServiceServer
}

func NewExternalCalloutServiceServer() (apigee.ExternalCalloutServiceServer, error) {
	return &ExternalCalloutServiceServer{}, nil
}

func (c *ExternalCalloutServiceServer) ProcessMessage(ctx context.Context, req *apigee.MessageContext) (*apigee.MessageContext, error) {
	var err error
        .... 
	return req, err
}

Have you got something like that? And have you checked the logs on that gRPC service?  To verify that it's healthy, up, listening? 

There is a working example of a golang gRPC server that can be used as an ExternalCallout, here