How can I request a service based on a keyword in a description?
By far the most common use of a request to a service is not through the canonical name but rather through the keyword describing the service or through the engine name. In this exercise we will demonstrate how we can find and request the hello-world service just by knowing that the description of the service contains the word “hello”. As usual we start by extending JOrchestrator class (due to the similarity of all orchestrator classes the class definition and the constructor of this particular orchestrator is not shown here).
We pass two parameters to the main method of this class: a) the name of this orchestrator (arbitrary) and the description keyword (in this particular case it would be the “hello” string). As always the connection to the ClaRA framework platform is done when we call the parent (JOrchestrator) constructor. In the next step we ask the platform registration services to report all registered services.
public static void main(String[] args) {
String oName = args[0];
String descKey = args[1];
// an instance of this class
ServiceByDescriptionrso = new ServiceByDescription (oName);
// get registration information form the platform normative services
rso.updateRegistration();
The method getServiceNameByDescription will scan over all registered service descriptions and return the canonical name of the service that contains the required keyword in its description, and is local to this orchestrator or is a remote service and has the smallest load. The service load is defined as the number of requests to a service per second.
// get the service canonical name that has a required description //keyword in the description.
String serviceName = rso.getServiceNameByDescription(descKey);
Here is the rest of the code where we request a found service by creating and sending a transient data object.
if(!serviceName.equals(CConstants.udf)){
System.out.println("Found a service = "+serviceName+"\n");
// list service information
rso.listServiceInformation(serviceName);
// create a request transient data
JioSerial dataRequest = new JioSerial();
dataRequest.setLanguage(CConstants.LANG_JAVA);
dataRequest.setData(oName);
dataRequest.setMimeType(MimeType.STRING);
// send the request
System.out.println("\nRequesting the service\n");
JioSerial dataResponse = rso.syncRunService(serviceName, dataRequest,1000);
// print the response
System.out.println(dataResponse);
} else {
System.out.println("Can not find a service with the specified description keyword.");
}
rso.exit();
}
Below is a snapshot of the terminal that was used to compile and run the described orchestrator.
>javac -cp $CLARA_SERVICES/lib/clara.jar:$CLARA_SERVICES/lib/jtools-1.0.jar:$CLARA_SERVICES/lib/cMsg-3.3.jar ServiceByDescription.java -d $CLARA_SERVICES/
>java -cp "$CLARA_SERVICES/.:$CLARA_SERVICES/lib/*" examples.orchestrator.request.ServiceByDescription xName hello
Found a service = 192.168.1.132/xContainer/Hello
Description: Hello World service
Version : 1.0
Author : Gyurjyan
Requesting the service
mimeType = STRING
dataUnit = undefined
dataDescription = response to xName
language = java
version = 0.0
status = Info
control = undefined
exceptionSink = undefined
exceptionSource = undefined
data = 2012/08/07 22:22:50: Hello
Asynchronous service request
In previous chapters we demonstrated mainly synchronous service requests, where an entire action, including a service response handling, was taking place in a main thread of an orchestrator. However a general design consideration and a key attribute of the ClaRA is the loose coupling between components that is achieved by means of asynchronous message passing between services. So, let us walk you through an example of an orchestrator that sends an asynchronous request to a previously created hello-world service and receives the response in a callback.
public class ServiceAsync extends JOrchestrator implements ICallBack {
private String oName;
private String serviceName;
/**
* Connects to the ClaRA platform
* @param name of this orchestrator
*/
public ServiceAsync(String name) {
super(name);
}
Note that the response from the requested service will arrive asynchronously in a callback of a JCallBack object (that we are going to create in a main method before sending a request to a service). The JCallback object, in turn, will call the monitorCallback method of the ICallBack interface, implemented by the orchestrator example above. As part of the ICallBack agreement we implement the monitorCallBack method that simply prints the received (output) transient data object from the requested service.
@Override
public void monitorCallBack(JioSerial data) {
//here we simply print the transient data
System.out.println(data);
// remove the monitor
serviceMonitorOff(serviceName,oName,oName);
// exit after you deal with the response
exit();
}
After printing data on the screen, the orchestrator stops monitoring the required service and gracefully exits (see code snippet below).
Now let us take a look at the main method of the class. Along with the usual steps of creating an object of the class and finding a service of interest by means of communication with the platform registration and discovery services, we create a JCallBack object.
public static void main(String[] args) {
// instance of this class
ServiceAsync rs = new ServiceAsync(args[0]);
rs.oName = args[0];
rs.serviceName = args[1];
// get registration information form the platform registration and //discovery services
rs.updateRegistration();
// check the platform registration if the service in question is //registered
if(rs.isServiceRunning(rs.serviceName)){
JCallBack myCallBack = new JCallBack(rs);
// monitor this service
rs.serviceMonitorOn(rs.serviceName,rs.oName,rs.oName,myCallBack);
// Now that we have callback in a place, request the service
// create a request transient data
JioSerial dataRequest = new JioSerial();
dataRequest.setLanguage(CConstants.LANG_JAVA);
dataRequest.setData(rs.oName);
dataRequest.setMimeType(MimeType.STRING);
// async send the request
rs.runService(rs.serviceName, dataRequest,1);
} else {
System.out.println("Service was not found");
}
}
This is the object that will be notified whenever the monitored service (in this particular example the hello-world service) generates output data. Note that we use one of the overloaded constructors of the JCallBack that ignores the sender, the subject and the type of the received message. After we set the monitor to watch the output of the hello-world service, we create and send transient data requesting asynchronously the hello-world service.
Share with your friends: |