Brief description of my project: I'm writing a java class named "GreetingsNode", that works in a distributed environment where there is a "managementNode", that is just as service repository and receives and stores info (host port number and service offered) of other nodes and dispatches RPCs of methods offered by services registered. If a node can answer to an RPC, then a thrift socket is opened and a connection is established between the calling node and the answering node, and the answering node returns the result.
I'm using Apache thrift as IDL and framework for RPCs.
Now the problem. My GreetingsNodeHandler class implements a simple thrift interface containing a single method "getHello(user)" (user being a struct containing the name of the node, which is a parameter of the constructor of GreetingsNode class). When a GreetingsNode X, connected to the management Node, makes an RPC of that method, another registered GreetingsNode must answer with the message "hello X".
I don't understand properly how to implement the part of the handler where the result is returned, and consequently I fail to understand how I should write the junit test that should check if the method implementation works correctly.
an assert like assertEquals(client.getHello(user).getMessage(), "Hello John Doe")
would work, but I don't get how, in my case, should i put the client part...
The code for GreetingService thrift service:
struct Message {
1: string message
}
struct User {
1: string name
}
service GreetingsService {
Message getHello(1: User user)
}
Code for GreetingsServiceHandler that must implement GreetingsService method getHello()
public class GreetingsServiceHandler implements GreetingsService.Iface {
private static Random random = new Random(10);
private ManagementService.Client managementClient;
private GreetingsService.Client helloClient;
@Override
public Message getHello(User user) throws TException {
Message answer = null;
// class ServiceProvider is generated by thrift, part of ManagementService thrift service
ServiceProvider provider = null;
List<ServiceProvider>providers = managementClient.getProvidersForService(user.name);
if (providers.isEmpty())
throw new NoProviderAvailableException(); //separate file contains Exception
else {
provider = providers.get(random.nextInt(providers.size()));
//connection between nodes is established here
TTransport helloTransport = new TSocket(provider.getHostName(), provider.getPort());
TProtocol helloProtocol = new TBinaryProtocol(helloTransport);
helloClient = new GreetingsService.Client(helloProtocol);
helloTransport.open();
// here lies my problem
answer = helloClient.getHello(user);
//if I use this instead, then helloClient variable is clearly not used, but of course I need it to answer the method call
answer = answer.setMessage("Ciao " + user.getName() + ", welcome among us!");
}
return answer;
}
and GreetingsNode code is the following:
public class GreetingsNode implements NodeIface {
private ThriftServer helloServer;
private ManagementService.Client managementClient;
private NodeManifest nodeManifest;
private User user;
private String name;
public GreetingsNode(NodeManifest nodeManifest, String name) {
this.nodeManifest = nodeManifest;
this.helloServer = new ThriftServer(GreetingsServiceHandler.class);
this.name = name;
}
@Override
public void turnOn() throws TException {
helloServer.start();
TSocket helloServerTransport = new TSocket("localhost", Constants.SERVER_PORT);
TBinaryProtocol helloServerProtocol = new TBinaryProtocol(helloServerTransport);
managementClient = new ManagementService.Client(helloServerProtocol);
this.setUser(new User(name));
helloServerTransport.open();
helloServer = new ThriftServer(GreetingsServiceHandler.class);
//portNegotiator is a class described in a separate file, that handles the registration of other nodes to the managementNode. NodeManifest is a file generated by thrift, part of managementService thrift file, describing a struct that contains hostname and port number of nodes.
PortNegotiator negotiator = new PortNegotiator(managementClient);
negotiator.negotiate(nodeManifest, helloServer);
}
@Override
public void turnOff() {
helloServer.stop();
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}