As the server side Javascript is emerging, we decided to have a look on different Javascript server platforms. RingoJS is Rhino/JVM based Javascript engine which is very easy to integrate with Java. More about Ringo can be found here - http://ringojs.org/ . In contrast to some other engines, RingoJS script can directly use Java objects, so a Ringo Javascript could reuse any Java program/library. The opposite is also true - a Java program can execute a Javascript using Ringo. In the context of SAP Netweaver Cloud, it means that a RingoJS Javascript application is able to:
This blog will show you how to run a RingoJS Javascript application on top of SAP NetWeaver Cloud and connect to HANA.
Let's start with a simple stand-alone RingoJS web application which is connecting to a database, executes a select statement and returns the result in JSON format. The main.js is a standard RingoJS web application skeleton, so I am not showing it here, you could find it under <Ringo Install Folder>\tools\admin\skeletons\app\main.js. It loads the actions.js, where we implement the request processing logic. The function "getConnection" is connecting to HANA Database using HANA JDBC driver. The driver jar must be part of RingoJS classpath, of course.
actions.js |
---|
var response = require('ringo/jsgi/response'); java.lang.Class.forName("com.sap.db.jdbc.Driver"); function getConnection( req ) { var hana_conn = java.sql.DriverManager.getConnection( "jdbc:sap://MyHost:30115?SID=MySID", "User", "Password"); return hana_conn; } exports.index = function (req) { var resource = getResource("./index.html"); return response.static( resource ); }; exports.persons = function( req ){ var result_array = []; var conn = getConnection( req ); var result = conn.createStatement().executeQuery("select * from PERSON"); while( result.next() ) { var row = {}; row.number = result.getString(1); row.name = result.getString(2); result_array.push( row ); } return response.json(result_array); }; |
We cannot run the stand-alone Ringo application directly in the cloud. There are several obstacles.
1. RingoServlet
Ringo is offering an adapter for the web container environment, called JsgiServlet(org.ringojs.jsgi.JsgiServlet). One could describe and map that servlet directly in the web.xml. In our case we want HANA access, so we have to extend the JsgIServlet functionality a bit and provide a DataSource.That servlet is registered in the web container and accessible from the javascript program. The DataSource object is retreived during the init() method,note that it is not possible to lookup in the getDataSource() method since it is plain Java method, without any container managed context.
RingoServlet.java |
---|
public class RingoServlet extends org.ringojs.jsgi.JsgiServlet { public DataSource dataSource; @Override public void init() throws ServletException { .... dataSource = (DataSource)new InitialContext().lookup("java:comp/env/jdbc/DefaultDB"); .... } public Object getDataSource() throws Exception { return dataSource; } } |
The RingoServlet must be described and mapped in the web.xml. In order to give full control to the Javascript application, RingoServlet is mapped to all URLs, e.g. /*
web.xml |
---|
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <display-name>ringo4neo</display-name> <servlet> <description></description> <display-name>RingoServlet</display-name> <servlet-name>RingoServlet</servlet-name> <servlet-class>com.sap.cloud.ringo.RingoServlet</servlet-class> <init-param> <param-name>optlevel</param-name> <param-value>0</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>RingoServlet</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping> </web-app> |
2. Database connection
As I already mentioned, we must adapt database connectivity since we do not know connection details in the cloud but use the DataSource interface instead. The DataSource is retrieved from the servlet and the later is accessible from the Ringo request environment - req.env.servlet . Let's see how to adapt the getConnection() method in the actions.js
actions.js |
---|
.......... function getConnection( req ) { var dataSource = req.env.servlet.getDataSource(); if(dataSource!=null) { return dataSource.getConnection(); } } ................ |
We have to declare the DataSource resource in the META-INF/context.xml
context.xml |
---|
<?xml version='1.0' encoding='utf-8'?> <Context> <Resource name="jdbc/DefaultDB" auth="Container" type="javax.sql.DataSource" factory="com.sap.jpaas.service.persistence.core.JNDIDataSourceFactory" /> </Context> |
3. Dependant libraries and modules
The following libraries must be copied from your Ringo installation into the WebContent/WEB-INF/lib folder.
Ringo modules folder must be copied under WebContent/WEB-INF
4. Structuring the web application
The file structure is listed below.
Application - file structure |
---|
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
13 | |
10 | |
10 | |
7 | |
7 | |
6 | |
5 | |
5 | |
5 | |
4 |