A simple example covering both types of applications involved in the JSON-RPC communication - a service application and a client Web application.
The client application makes a JSON-RPC request to the service application and shows on its Web page the result from the OSGi runtime.
The Hello World Service Application
Content
Following is the Java source code and the manifest file of the Hello World service application. It consists of a remote.helloworld.HelloWorld service interface, a class remote.helloworld.impl.HelloWorldActivator representing the application's bundle activator and service interface implementation, and of a manifest holding headers describing the application to the OSGi Framework.
Having a separate interface as the application's service is not a mandatory approach. You can register directly a service object implementing the dedicated public Java methods under its class name.
The code below contains the interface defining a single method sayHello which is designed for remote access. The sayHello has one String argument which represents a person's name and returns a greeting message to this person.
The interface of the application's service:
package remote.helloworld;
/**
* The service interface of the HelloWorld application.
*
*/
public interface HelloWorld {
/**
* Returns a hello message to the specific person.
* @param yourName the name of the person
* @return a personal hello message
*/
public String sayHello(String yourName);
}
The following code contains the implementation of the remote.helloworld.HelloWorld interface from above and of the org.osgi.framework.BundleActivator interface. On application startup, the OSGi Framework calls the start method and then the application is able to register its Hello World service.
The implementation of the application's service:
package remote.helloworld.impl;
import java.util.Hashtable;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceRegistration;
import com.prosyst.mbs.services.remote.RemoteServiceConstants;
import remote.helloworld.HelloWorld;
// The bundle activator and service implementation of the HelloWorld application.
public class HelloWorldActivator implements BundleActivator, HelloWorld {
private ServiceRegistration sReg;
// Registers the HelloWorld service providing callable methods.
public void start(BundleContext bundleContext) throws Exception {
Hashtable props = new Hashtable(3);
props.put(Constants.SERVICE_PID, "HelloWorld");
props.put(RemoteServiceConstants.SERVICE_EXPORTED_INTERFACES, new String[] { "*" });
props.put(RemoteServiceConstants.CONFIG_EXPORTED_METHODS, new String[] { "HelloWorld/sayHello" });
sReg = bundleContext.registerService(HelloWorld.class.getName(), this, props);
}
// Unregisters the HelloWorld service upon bundle stop.
public void stop(BundleContext bundleContext) throws Exception {
if (sReg != null) {
sReg.unregister();
}
}
// Inherited from the HelloWorld interface. This method simply generates a
// hello message appending the specified name.
public String sayHello(String yourName) {
String helloMessage = null;
helloMessage = yourName != null ? "Hello, " + yourName + "!" : "No name";
return helloMessage;
}
}
The code below contains the manifest file of the Hello World service application specifying which is the bundle activator implementation and which Java packages the application needs.
Hello World application manifest:
Manifest-Version: 1.0
Bundle-Version: 1.0.0.201112071248
Bundle-Category: helloworld
Bundle-Name: Remote Hello World Service
Bundle-Activator: remote.hello.world.impl.HelloWorldActivator
Bundle-ManifestVersion: 2
Import-Package: com.prosyst.mbs.services.remote;version="1.0.0",
org.osgi.framework;version="1.3.0"
Bundle-SymbolicName: remote.hello.world
Deployment
Pack the service application in a JAR file, e.g. called helloworld.jar, holding the manifest above, and install it on the OSGi runtime. For example, you can use the fw.install command in the OSGi runtime console.
If we check the services of helloworld.jar with the fw.services -p <bundle_id> console command, we'll see the needed registration properties listed.
The Hello World Client Web Application
Content
The Hello World client Web application consists of an HTML file start.html used for starting the real code and for registration on a Web server and a main JavaScript file helloworld.js. The HTML page contains a box for typing some name to send to the Hello World service application.
The main page of the Hello World client application:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Hello World</title>
<script type="text/javascript" charset="utf-8" src="json2.min.js"></script>
<script type="text/javascript" charset="utf-8" src="helloworld.js"></script>
</head>
<body onLoad="start()">
<div id="send.name">
<form action="" method="post" accept-charset="utf-8">
<p>
<label for="name">Your Name: </label>
<input type="text" name="name" value="" id="name"/>
</p>
<p>
<input type="button" value="Send" id="send.button"/>
</p>
</form>
</div>
</body>
</html>
When start.html is loaded, the code from helloworld.js JavaScript file inserts a box for typing the name to address the hello message. Upon submitting the information, the JavaScript code sets the required cookies and sends a JSON-RPC request over AJAX for the HelloWorld/sayHello method passing the name from the box. When the response forwarded from the Hello World service application comes, the JavaScript code shows it on the Web page.
The JavaScript code relies on the conventional JSON JavaScript library json2.min.js for processing JSON objects.
The main JavaScript code of the Hello World client application:
/* Start function*/
function start() {
/* Create the elements to get the name for the hello message.*/
var nameField = document.getElementById("name");
var sendButton = document.getElementById("send.button");
/* Call the HelloWorld/sayHello JSON-RPC method when the user clicks the Send button*/
sendButton.onclick = function(e) {
if (!e) e = window.event;
if (e.preventDefault) {
e.preventDefault();
} else {
e.returnValue = false;
}
var name = nameField.value;
sendRequest(name); };
}
/* Send a JSON-RPC request setting the required cookies and assigning a response handler*/
function sendRequest(name) {
/* Prepare the JSON-RPC object for the request*/
var myJSONObject = {
"jsonrpc" : "2.0",
"method" : "HelloWorld/sayHello",
"params" : name
};
/* A piece of code for handling AJAX browser specifics*/
var xmlhttp = null;
// Mozilla-based browsers
if (window.XMLHttpRequest) {
xmlhttp = new XMLHttpRequest();
} else if (window.ActiveXObject) {
xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
if (!xmlhttp) {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
}
/* Open the request to the target URL of the management agent/distribution provider*/
xmlhttp.open("POST", "/remote/json-rpc/sg", true);
/* When the response arrives, call the function to show it to the user*/
xmlhttp.onreadystatechange = function() {
createOutput(xmlhttp);
};
/* Send the request.*/
xmlhttp.send(JSON.stringify(myJSONObject));
}
/*Insert the result along with the gateway ID at the end of the page */
function createOutput(xmlhttp) {
if (xmlhttp.readyState == 4) {
var output = document.getElementById("service.output");
if (!output) {
output = document.createElement("p");
output.setAttribute("id", "service.output");
var body = document.getElementsByTagName("body")[0];
body.appendChild(output);
}
if (xmlhttp.status == 200) {
output.innerHTML = JSON.parse(xmlhttp.responseText).result;
} else {
output.innerHTML = "<b>Error: </b> " + xmlhttp.response;
}
}
}
Deployment
There are several ways to deploy the Hello World client Web application:
We will use the first simpler approach:
Let us have all components of the client application in a common directory in the following way:
We have to copy the whole helloworld directory into <osgi_root>/www on the OSGi runtime.
As a result, when the OSGi runtime is started, the Hello World client Web application will be available at the following URL:
http://<osgi_host>/root/helloworld/start.html
The Result