Using NW Cloud as a data service for mobile apps
NetWeaver Cloud – or NW Cloud – is available and it comes with a free (FREE!) trial account for everyone interested. NW Cloud (I am sure I will type this name several times again, so let me just call it Neo) is Java. Pure Java in the sense that you can finally reuse your Java knowledge acquired somewhere else for SAP projects. Neo works nicely with all the other tools Java developers are used to, like Maven, Ivy, Jenkins, Sonar, or what else you use for your other Java code projects. No more NWDI or SCs, DCs, public / private parts and activities. You can use the code revision as well as the build and dependency system you want, no need to set up anymore a separate infrastructure. The SDK is Eclipse and now you are free to choose which Eclipse you want to use: it is not the same as with the closed NWDS that is Eclipse based, but at the same time forces you to stay with an old Eclipse version.
Short: Neo is good news for Java developers on SAP projects!
The mobile application
To show a benefit of Neo, let me create a Java application for storing and retrieving information about persons. To make things easy, I used as a starting point the Neo tutorial for JPA and Dagfinn Parnas’ blog about Jersey for Neo apps.
Neo is cloud, implying that you do not have any more to worry on how to access your internal system from somewhere else. Once the application is deployed on Neo, you can already start using it by other services, be it internal or cloud. Mobility is everywhere and with a public available service that understands JSON and REST in a way most Javascript frameworks expect it, let’s create a mobile application using another cloud service (and at the same time eagerly waiting for VC5 and App Designer).
The servlet for providing the data
The data to be stored in the database is easy: some general information about a person, one Java object, one database table.
To make it easier for starting from scratch every time the servlet is deployed the database will be created from scratch:
Creating methods for retrieving and storing information via REST and JSON:
public List<Person> getAllPersons()
public Person getPerson(@QueryParam("id") long personId)
public Person createPerson(Person person)
Mobile User Interface
For the UI you are free to use whatever you want, as long as your frontend can access the servlet running inside Neo. Free really means free: Neo comes with SAPUI5, but you are not forced to use it (as you are in “normal” SAP Java with Web Dynpro). As the service is already available publicly in the cloud, accessing it by a HTML5 app is not a problem at all. The problem is to create the HTML5 app.
Just to show that you are not bound to use SAP and because I do not have mobile UI tools from SAP at my fingertips right now, let’s use a tiggzi. As soon as SAP releases VC5 or AppDesigner to people like me, for sure I’ll use these tools. As for right now, these are not available; I had to choose another tool.
Creating a UI in tiggzi is done by drag and drop, making it easy to create a HTML5 app.
Services for data consumption are created via drag and drop, as well as assigning input and output elements (reminds me of Visual Composer).
Tiggzi does not give you much choice when it comes to REST services. Either you are able to adopt your service to work with tiggzi, or you cannot use it. For instance, data is sent in JSON in a specific format and values are passed as parameters. While you can specify that a parameter should be included in the header, adding it as a part of the path is not possible. Here you have to adjust your service to (the limitation of) the frontend. Thankfully, in Neo it is up to you to define the service, so you have total control.
Running the HTML5 app inside a browser
The save button triggers the service to POST the data to the servlet running in Neo.
To get a list of available persons, click the “Load Persons” button. This sends a GET request to the service and receives a list of all persons found in the database. Selecting a person in the select box shows then the information about that specific person.
How does this work on a mobile device
The run the application on a mobile device, you can either use the online version or install it as a hybrid application on the device. On a Galaxy Note the screens look like:
Next
Neois cloud with no limitations. It is offered by SAP, but you are free on how you use it. Combining Neo with other non-SAP software and cloud products is not a problem. You can host your services on Neo and use your other tools you are already used to; or vice versa. SO, what next? Using continuous integration for Neo projects.
Note
When in the web interface you cannot restart the app. You only can stop and then start the app:
In case you do not want to wait for the application to be stopped first (takes some time), use Eclipse. There you can restart the application:
Besides this, it takes some time for Neo to get up and running (local or cloud). Due to a copy & paste error, I had to stop the application several times. This is time consuming, as it took more than a minute for stopping, deploying, starting and be able to use the application. If you are used to NW Java development and data dictionary: the DB is created by JPA in the above example. You have to think how the existing DB is treated when deploying the servlet. Adding a new field means to first drop the DB. Did not expect me to say this: being able to create the DB in a separate deploy is a feature I miss.
The source code
The code is basically the same as used in the JPA tutorial and the Jersey code posted by Dagfinn. This code looks up all Persons saved in the database and returns a list of Person object in JSON format:
[Excerpt of the servlet]
@GET
@Produces({ MediaType.APPLICATION_JSON })
public List<Person> getAllPersons() {
EntityManager em = emf.createEntityManager();
try {
@SuppressWarnings("unchecked")
List<Person> resultList = em.createNamedQuery("AllPersons").getResultList();
return resultList;
}
[...]
Now, there is one small problem with Jersey and Neo: they do not work together. Looks like Jersey does not like OSGI, but there is a workaround available.
1. Create a new class:
package com.tobias.neo.api.rest;
import java.util.HashSet;
import java.util.Set;
import javax.ws.rs.core.Application;
public class MyApplication extends Application {
public Set<Class<?>> getClasses() {
Set<Class<?>> s = new HashSet<Class<?>>();
s.add(RestAPI.class);
return s;
}
}
2. In web.xml:
<servlet>
<servlet-name>Jersey REST Service</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>com.tobias.neo.api.rest.MyApplication</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.spi.container.ContainerResponseFilters</param-name>
<param-value>com.tobias.neo.api.filter.ResponseCorsFilter</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
Calling the servlet under <appname>/api/person shows that Jersey is working under Neo:
{"person":[{"company":"Other","description":"SAP Mentor","firstName":"Tobias","id":"1","job":"Solution Architect","lastName":"Hofmann"}]}
Interesting blog.
Tiggzi looks cool but, as you suggest, this functionality should be included in the NW Cloud... I wonder if VC5 or AppDesigner will provide similar features.
D.
I hope that VC5 will offer a similar data mapping and HTML5 creation tool. Exporting the app as a "native" package is really a nice feature.
Hi Tobias -
Thank you for a great article and including Tiggzi!
I do have one comment on the above. The REST service editor in Tiggzi is actually pretty flexible. If you want to send data in the body in JSON format but still include a request parameter, you could simply add them to the URL. Adding a parameter as part of path (I'm assuming the path URL?), you can do by using {param} notation. Hope this helps. If you have a service that you would like to try, I'll be more than happy to help you. Lastly, we are just about to launch our new, completely HTML/JS builder. Let us know what you think!
Max
Developer Relations @ Tiggzi
Hi Max,
thanks for stepping in and clarifying that tiggzi is also flexible when it comes to services 🙂 I went through the tutorial and the documentation (http://help.gotiggr.com/documentation/services/rest-service/defining-request-parameters) when "learning" tiggzi (Google search results). Only now I found the documentation page explaining how to include parameters in the path http://help.gotiggr.com/documentation/services/rest-service/dynamic-service-url
Nice blog Tobias. Great to see how Neo works nicely with open frameworks such as Tiggzi.
Max, thanks for quick reply on the topic above.
On the DB schema handling and the comments regards to the DDIC.
EclipseLink is indeed rather limited w.r.g.t. the lifecycle managment support for database tables.
However there exist other much more flexible and powerful frameworks. We recommend the usage of Liquibase. There is already a nice blog from Michael Wenz on this topic in the Neo community.
http://scn.sap.com/community/developer-center/cloud-platform/blog/2012/09/05/using-liquibase-for-database-migrations-in-sap-netweaver-cloud
Harald
Hi Harald,
thanks for pointing out to the Liquibase blog from Michael Wenz Will take a closer look at this one 🙂
Nice one! Seems you're on a roll here 🙂
One last question: anx chance sou could upload your sample app to a source code repo for people to download?
Thanks for sharing!
matthias
Don't worry, I will. In case you have read the other blog about Jenkins, you may get an idea on how I plan to do this 😆
Neat !! thanks for sharing.
Regards,
@tarik_parkar