The Background Story

 

Those who closely follow this space may remember the blog posts about "Granny's Addressbook", a sample application created by a company called Open Software Integrators for the purpose of teaching how-to develop Spring-based Java applications. This sample applications was used as a reference to compare several PaaS offerings in the market - see Which freaking PaaS should I use?

 

Unfortunately the SAP HANA Cloud Platform wasn't on their radar back then, but once we heard about their comparison and the demo app we took our chances and deployed the app to our cloud platform. It run right away, w/o any modifications required. Harald Müller, Chief Product Owner of the JVM-based Runtime capabilities of the SAP HANA Cloud Platform, shared his experiences in a blog post: Which freaking PaaS should I use (1/2)?

 

Yet, he did not stop there and instead tinkered with it a bit more to "make the app a bit more enterprise ready!"

 

"This time i will not just deploy the applications as is but have a look into the source code and make the app a bit more enterprise ready (hey we are SAP ;-)." - Harald Müller [REF]

 

Andrew Oliver (the original author) noticed our efforts via Twitter and responded with a dedicated blog post titled "The best-run Granny's addressbooks run on SAP". This is how the idea of "Enterprise Granny was born"...

 

Enterprise Granny

 

The idea is simple: let's take this simple sample application and make it enterprise-ready. It's Maven-based and uses the popular Spring framework - a very common archetype out there - and as such seems like the perfect fit to showcase how-to port an existing Java application and optimize it for the SAP HANA Cloud Platform. We'll take it easy at first and apply a few subtle changes touching upon the most common development tasks like implementing logging/tracing, exception handling, I18N and so on. Later on, we may want to enhance the application to demonstrate how-to best leverage the capabilities of the SAP HANA Cloud Platform. In short: we'll have plenty of fun with it!

 

Note: I'm fully aware that the original intent of the application was purely for training purposes and that some of application's shortcomings are on purpose for educational reasons. Matter of fact, I'm considering to make a few common mistakes myself along the way in order to correct them at a later point in time for the exact same reason! As such, please do not mistake me talking about shortcomings in the original app as criticizing OS Integrators or their develovers!

 

There's no spoon - but a fork!

 

As you hopefully know we have started to publish a variety of open-source samples on our github page: sap.github.io or (github.com/SAP respectively). Consequently I did fork the original repo (repository) in order to create a new branch for Enterprise Granny.

 

You can find it here: https://github.com/SAP/cloud-enterprise-granny

 

Those of you who are interested to follow-up on this journey are more than welcome - and don't worry: we'll take it easy and enhance the app step-by-step! After all, the whole purpose of this exercise is to provide you with some guidance on how-to develop great cloud applications based on Open Source.

 

The best way to be informed about new chapters is to subscribe to this document:

http://scn.sap.com/docs/DOC-42001

 

 

Happy coding everyone!!!


 

PS: Of course we all know that there's only one person who can legitimately call herself "Enterprise Granny", which is the one-and-onlyMarilyn Pratt aka "Grannimari". In more than one way this can be considered a hommage to her and her ways of sharing with the community and hence I hope she doesn't mind us (re-) using that title

github.com turns 5 today and what better way to join in the celebrations than to polish our public source code repo: sap.github.io ?!?

 

Screenshot_11.04.13_12_18-2.png

 

 

So, if you're looking for code samples, demos, etc - search no more, but simply bookmark the URL! There's already a fine collection of samples there, but we got plenty more to come in the following weeks and months...

 

Happy coding!

 

PS: Special shout-out to Ingo Sauerzapf and Lars Karg for coming up with the new look & feel and for driving the consolidation efforts! The result speaks for itself!

In today's blog post I want to share with you a short video showcasing several tools currently in development that will greatly simplify the process of creating mobile applications, namely the AppDesigner and the SAP Mobile Platform Cloud Edition.

 

Those of you who were present during the keynote at the DSAG Technologietage in Mannheim this morning were able to see Bjoern Goerke, Executive Vice President & Corporate Officer at SAP, himself ran the demo live on stage. For all the others... well you have at least this recording of me walking you through the demo so you do not completely feel left out of the loop.

 

So, what is all that excitement about you may wonder? Well, let me tell you...

 

The demo starts with an early version of a tool called AppDesigner (some of you may remember seeing it in Vishal's keynote at SAP TechEd Las Vegas last year). In a nutshell, it's a WYSIWYG editor that allows you to grahically model HTML5 based mobile UIs. The AppDesigner greatly simplifies the task of creating nice looking user interfaces based on SAP's UI Development Toolkit for HTML5 (aka SAPUI5.) In general, the tool falls into the category of Rapid Application Development (RAD) tools. As such, the generated HTML5 coding can directly be executed to see how the application would look like once running on a mobile device.

 

Slide16.jpg

 

In this demo, we use the AppDesigner to create a user interface for a Leave Request application (kind of the new "Hello World" of enterprise demos), which will be connected to an SAP backend system via SAP Gateway. We replace the mock endpoint (pointing to static JSON data) of the model generated during the visual design process with a real one, which is mapped to an application configuration hosted on the SAP Mobile Platform Cloud Edition. So, instead of mapping the mobile application to the backend system directly we introduce the SAP Mobile Platform Cloud Edition (aka MaaS, Mobility-as-a-Service) as a mediator. With this approach we decouple the application from the backend system on purpose. This has several benefits as we now have a configurable middle layer that caters to enterprise mobility needs such as device management (as known from Afaria), customizable authentication schemas (e.g. SSO) and a variety of other value adding services like push notification support etc.

 

Once the graphical design of the application is finished and the endpoint has been replaced I download the project and save it to my local hard-drive, where I'll drop the generated index.html into a newly created Phonegap project (which pretty much is only the standard Phonegap template + the UI5 Javascript libraries.) The project is build and executed on the iOS Simulator within Xcode.

 

After that I quickly show you around the administration and monitoring cockpit of the SAP Mobile Platform Cloud Edition. I highlight the backend configuration, where the final endpoint to the Gateway system within the ES Workplace is maintained as well as the authentication configuration.

 

 

But enough of the talking... here's the video:

 

 

 

 

PS: All statements with the usual disclaimers: Any recourse to courts of law is excluded.

In this third chapter of this blog series originating from our SAP TechEd session Tapping into Open Source with SAP NetWeaver Cloud we'll talk about: social media integration.

 

With the ascent of social networks such as Facebook, Twitter or LinkedIn the power of consumers has been steadily growing. Companies big and small can no longer ignore the opinion of consumers (social buyers) and are well-advised to listen on such channels and ultimately to participate  in the conversation (to positively influence it.) One of the resulting trends is sentiment analysis (see How Companies Can Use Sentiment Analysis to Improve Their Business) leading to a whole new understanding of marketing called pull marketing: Using Social Media for Building, Selling and Supporting.

 

"Instead of holding a megaphone up to our mouth, we should be holding the megaphone up to our ears with the little end toward our ears and the big end facing out to our marketplace, listening to what they need from us. And the tone with which we provide it has to change, so that instead of being pushy and insistent on getting peoples’ attention, we should be sharing information openly in a more conversational and helpful way."

[Mark Yolton in an interview with MITSloan Management Review]

 

Ultimately, the best form of marketing is to have happy customers recommending your products proactively to their friends, colleagues and peers. So, it sounds like a good idea to let users do that as simply as possible - directly from within your web page, platform or application.

 

So, whether it comes to integration content from social networks or allowing users to share content: today's application are well-advised to embrace social media. As such, let us have a look on how-to integrate Twitter into our application for example.

 

As you may recall our session supplement web application features a Twitter dashboard that shows the latest tweets containing the "sapnwcloud" hashtag as well as the most active tweeps recently. In chapter 2, Lars Karg explained how we developed the UI to display this data. Now, we'll see how we developed the backend functionality. Off we go...

 

1. Getting started

 

This tutorial continues where chapter 1 left off, so if you want to code along, please clone the following repo: https://github.com/sapnwcloud/springrest

 

2. Create new spring configuration

 

First, let's create a new spring configuration within the webapp/WEB-INF directory called: springsocial-context.xml

 

It does look very similar to the old one, but there are a few important differences:

 

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
 xmlns:context="http://www.springframework.org/schema/context"
 xmlns:util="http://www.springframework.org/schema/util"   
 xmlns:jaxrs="http://cxf.apache.org/jaxrs"
 xmlns:cxf="http://cxf.apache.org/core"
 xsi:schemaLocation="
       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd 
       http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsd
       http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd
       http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd">

    <import resource="classpath:META-INF/cxf/cxf.xml" />
    <import resource="classpath:META-INF/cxf/cxf-servlet.xml" />

    <context:component-scan base-package="com.sap.netweaver.cloud.samples.springsocial"/> 

 <bean id="baseService" class="com.sap.netweaver.cloud.samples.springsocial.srv.BaseService" abstract="true">
 </bean>

 <bean id="dashboardService" class="com.sap.netweaver.cloud.samples.springsocial.srv.DashboardService" parent="baseService"/>
 <bean id="tweetService" class="com.sap.netweaver.cloud.samples.springsocial.srv.TweetService" parent="baseService"/>

 <jaxrs:server id="restContainer" address="/v1">
  <jaxrs:properties>
            <entry key="org.apache.cxf.propagate.exception" value="false" />
        </jaxrs:properties>
  <jaxrs:serviceBeans>
  <ref bean="dashboardService"/>
  <ref bean="tweetService"/>
  </jaxrs:serviceBeans>
  <jaxrs:providers>
            <ref bean="jacksonProvider" />
            <ref bean="formProvider" />
        </jaxrs:providers>
 </jaxrs:server>

 <bean id="jacksonProvider" class="org.codehaus.jackson.jaxrs.JacksonJaxbJsonProvider">
  <property name="mapper" ref="objectMapper"/>
 </bean>

 <bean id="formProvider" class="org.apache.cxf.jaxrs.provider.FormEncodingProvider" />

 <bean id="objectMapper" class="com.sap.netweaver.cloud.samples.springsocial.srv.CustomJsonMapper" />

 <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
  <property name="locations" value="classpath:oauth.properties"/>
 </bean>

 <bean id="twitter" class="org.springframework.social.twitter.api.impl.TwitterTemplate">
  <constructor-arg index="0" value="${oauth.consumerKey}"/>
  <constructor-arg index="1" value="${oauth.consumerSecret}"/>
  <constructor-arg index="2" value="${oauth.accessToken}"/>
  <constructor-arg index="3" value="${oauth.accessTokenSecret}"/>
 </bean>
</beans>

 

Lines 20-24 define the needed service beans. To show good practices I declare an empty BaseService bean, so that I can add central functionality in a common place later-on. I then define two Servcies: one which is in charge of providing the data for the Twitter Dashboard, the other is used to tweet messages.

 

Lines 34-37 define so called JAX-RS providers. Simply put, they are needed to (de)-serialize java objects to JSON and back. Jackson is a very cool library for this purpose as it greatly simplifies the process, especially when it comes to list and maps. The FormEncodingProvider is used to handle form data (used to tweet the text message submitted via an HTML form.)

 

In line 46 a custom JSON mapper is defined. As discussed in chapter 1, the main reason to do this is to have a bit more control of the de/-serialization of JSON.

 

Line 48-50 declare a so called PropertyPlaceholderConfigurer, which simply makes the values declared in a property file (oauth.properties) accessible within the spring configuration (lines 53-56). The reason for this approach was that we need to declare a few private keys to interact with Twitter, which for obvious reasons we do not want to check-into github.

 

In lines 52 ff the TwitterTemplate is defined, which is used to interact with the Twitter API. As part of the initialization the oauth parameters are passed (which are obtained form the before mentioned property file.

 

3. Update the web.xml

 

The web.xml file is almost identical to the one created for chapter 1.

 

<?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">
   <welcome-file-list>
    <welcome-file>index.html</welcome-file>
  </welcome-file-list>
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>WEB-INF/springsocial-context.xml</param-value>
  </context-param>
  <listener>
    <listener-class>
            org.springframework.web.context.ContextLoaderListener
        </listener-class>
  </listener>
  <servlet>
    <servlet-name>CXFServlet</servlet-name>
    <servlet-class>
            org.apache.cxf.transport.servlet.CXFServlet
        </servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>CXFServlet</servlet-name>
    <url-pattern>/api/*</url-pattern>
  </servlet-mapping>

</web-app>

 

Of course, the name of the spring configuration was replaced (line 10). We also removed the authentication section again. Last, we slightly change the mapping to the CXF servlet (line 26). Remember, in chapter 1 we used the "*" (match-all) mapping. In this chapter, we also want to display an HTML page that includes the form to submit our twitter status update, hence we cannot use the catch-all mapping no more.

 

4. Update the pom.xml

 

First, let's add some new properties again in the <properties /> section:

 

  <org.codehaus.jackson.version>1.9.9</org.codehaus.jackson.version>
  <org.slf4j.version>1.6.1</org.slf4j.version>
  <org.springframework.social.version>1.0.2.RELEASE</org.springframework.social.version>

 

Then we need to define some additional dependencies for spring social, jackson, guava (collections) and some logging-related dependencies respectively. Please have a look at the complete pom.xml file for the details.

 

5. Create domain model

 

For this application we need three domain model objects: Tweet, User and Dashboard. These objects are mere POJOs and only define the attributes and getter and setter methods. The only thing worth mentioned explicitly are the javax.xml.bind.annotation annotations, which are used to define the name of the properties when serialized into JSON. (These annotations are used by Jackson during the (De-)serialization process.

 

6. Create the Service classes

 

We already discussed the services during step 2. Let's have a closer look at them:

 

DashboardService

 

package com.sap.netweaver.cloud.samples.springsocial.srv;

// ...

@Service("dashboardService")
@Path("/dashboard")
@Produces({ "application/json" })
public class DashboardService extends BaseService
{
          @Inject
          ObjectMapper mapper = null;

          @Inject 
          Twitter twitter = null;

          @GET
          @Path("/{id}")
          public Dashboard getDashboardByID(@PathParam("id") String id)
          {
                    Dashboard dashboard = new Dashboard();
                    SearchResults results = twitter.searchOperations().search("#sapnwcloud");
                    //...
                    return dashboard;
          }
}

 

I omitted some of the coding for better readability (if you're interested in the details please check out the complete class source code here: DashboardService)

 

Line 5-7 are the familiar JAX-RS annotation again. We discussed them in detail in chapter 1.

 

Line 10-11 and 13-14 define references to other services we declared in the spring configuration. Note the Inject annotation, which instructs Spring to inject a reference to the specified bean at runtime (no getters/setters needed!)

 

Line 18-23 comprise the service operation. Here you can see the Twitter API at work. All we do here is to perform a public search for teh #sapnwcloud hashtag on Twitter. Pretty simple, isn't it?

 

TweetService

 

package com.sap.netweaver.cloud.samples.springsocial.srv;

//...

@Service("tweetService")
@Path("/twitter")
@Produces({ "application/json" })
public class TweetService extends BaseService
{
          @Inject
          Twitter twitter = null;

          @Path("/tweet")
          @POST
          public Response tweet(@FormParam("message") String message)
          {
                    try
                    {
                              Tweet tweet = twitter.timelineOperations().updateStatus(message);
                              return Response.ok(tweet).build();
                    }
                    catch (Exception ex)
                    {
                              return Response.serverError().entity(ex.getMessage()).build();
                    }
          }
}

 

By now, most of the coding should look fairly familiar and require little further explanations. Except for the FormParam annotation maybe... in a nutshell, the method gets the (HTML) form field with the name "message" injected by JAX-RS. (This will get much clearer once we look at the corresponding HTML page in a minute!) We simply take that message and post it as a Twitter status message... that's all.

 

7. Create the HTML page

 

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Basecamp</title>
</head>
<body>
<form action="api/v1/twitter/tweet" method="post">
          <textarea name="message" rows="2" cols="80"></textarea><br>
          <input type="submit" class="btn" value="Tweet">
</form>
</body>
</html>

 

It's a very simple form indeed. Please note the action URL we provide - which maps to the TweetService tweet() method. Furthermore, you can see that the textarea's name is "message", which was the name we referred to within the FormParam annotation in the tweet() method.

 

8. Provide the required OAuth credentials

 

The last remaining step is to provide the OAuth credentials required to interact with the Twitter API. Now, those of you who ever tried to perform the so-called "OAuth" dance manually will know that's far from being trivial and as such appreciate the fact that Spring Social take care of all the heavy lifting for us. Just have a look at the digrams on the public help document to get the idea:

 

http://static.springsource.org/spring-social/docs/1.0.x/reference/html/serviceprovider.html

 

The Service Provider framework is very powerful actually and I'm barely scratching the surface here. For the sake of keeping things digestible though we kept it simple and hence you only need to provide the four required parameters in the oauth.properties file:

 

# Please enter your oAuth credentials as provided by dev.twitter.com when you registered your app!
oauth.consumerKey=
oauth.consumerSecret=
oauth.accessToken=
oauth.accessTokenSecret=

 

You'll get these keys after you successfully registered an application of dev.twitter.com.

 

Wrap-up

 

With that you should be all set to start coding social apps. Sure, we only used Twitter in this example, but most of the popular social networks have similar support in Spring Social so it'S definitely worth checking it out! Here's a rudimentary Twitter client I developed a while back - Twitter Demo - and here's the source-code: https://github.com/sapnwcloud/socialspringdemo

 

Now that you're familiar with the basics of Maven-based Java projects and Spring you may want to take it to the next level and learn how you can create entire projects including persistence, MVC-based frontend and even Gateway connectivity services with just a few lines of scripting using Spring Roo. If so, then jump right into Lars Karg 's blog TechEd 2012 CD208 (Chapter 4/6) – Spring Roo

This blog post is the first of a series of tutorials provided as part of the SAP TechEd session Tapping into Open Source with SAP NetWeaver Cloud created by Lars Karg from SAP Research and myself. It was our goal to provide something more sustainable than just a slide deck talking about the benefits of Open Source and hence we decided to create a session supplements: https://cd208.netweaver.ondemand.com

 

The  session consists of six individual chapters building on top of each other and together they comprise a step-by-step tutorial  demonstrating how-to use popular Open Source frameworks with SAP NetWeaver Cloud. We provide you with all the source code and detailed documentation about how we developed the supplements application itself, so that you can try it yourself!

 

This very first chapter talks about - who would have guessed so - getting started!

 

Note:  Content-wise this blog post also links back to a previous series called The Rise of Enterprise APIs (Part 2, Part 3) and as such it kind-of also represents the promised fourth and final post of that series.

 

Enough of the small talk, let's tackle it!

 

cd208_screenshot.png

 

As stated in the introduction of chapter 1 in the supplements web application we'll clone a github repo(sitory) and then add some Maven dependencies to finally expose a simple service according to REST principles. For that matter, you need a few additional Eclipse plugins to work with Git and Maven respectively. I have described all you need to know in another blog post: Essentials - Working with Git & Maven in Eclipse

 

Once you have installed and configured these plug-ins we are ready to go...

 

1. Cloning the 'basecamp' repo

 

First thing we do is to clone the 'basecamp' github repo to our local workspace. I explained this in detail in the above mentioned blog, so no need to re-write it here.

 

2. Importing the project

 

Once, we have successfully cloned the repository, we have to import it into our Eclipse workspace. So let's switch to the "Java EE" perspective and use the "File > Import..." menu and then the "Existing Maven projects" option. Provide the link to the root directory of our cloned repo and click on Finish. Now, the project sources should be imported into your workspace. You should now see the project structure in the 'Project Explorer' view.

 

3. Updating the pom.xml

 

The most important file in a Maven-based project is the pom.xml file, which contains the so called "Project Object Model". In simple terms think of it as a "recipe" listing all the required "ingredients" (referenced Open Source projects) as well as the "cooking instructions" (build process). Please take a moment to look at the content of this file before we continue...

 

We'll reference a couple of Open Source projects such as Apache CXF and the famous Spring framework. In order to easily update these dependencies when new versions will be released we'll start by defining some version constants, so that we can update them with ease in a central place. This is done in the <properties /> section of the POM. So, let's add these two properties now:

 

<org.apache.cxf.version>2.6.1</org.apache.cxf.version>
<org.springframework.version>3.1.2.RELEASE</org.springframework.version>

 

As stated before, the POM is like a "ingredients" list. Sticking to this metaphor, we would need to specify the "stores" where one can get these ingredients. This is done in the <repositories> section of the POM. The standard "store" is called Maven Central and it is already contained in the POM we downloaded.

We'll get most of the commonly used projects here, but the Spring framework has it's own repository, which we'll now add:

 

 <repository>
<id>springsource-repo</id>
<name>SpringSource Repository</name>
<url>http://repo.springsource.org/release</url>
</repository>

 

The last remaining step to make our ingerdients list complete is to specify all the components(dependencies) we need. Please find the complete list to add below:

 

        <!-- Apache CXF -->
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-frontend-jaxws</artifactId>
            <version>${org.apache.cxf.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-transports-http</artifactId>
            <version>${org.apache.cxf.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-rs-extension-providers</artifactId>
            <version>${org.apache.cxf.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-bundle-jaxrs</artifactId>
            <version>${org.apache.cxf.version}</version>
        </dependency>

        <!--  Spring framework -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>

        <!-- Jettison -->
        <dependency>
            <groupId>org.codehaus.jettison</groupId>
            <artifactId>jettison</artifactId>
            <version>1.3.2</version>
            <scope>runtime</scope>
            <exclusions>
                <exclusion>
                    <groupId>stax</groupId>
                    <artifactId>stax-api</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

 

Once you save the POM file you'll notice that Maven will now get all the stated dependencies and download them into your local Maven repository (so that you don't have to download them over and over again!) If all went fine, your POM file should now look like this file (well, except for the artifactID!)

 

4. Let's code

 

Now that the project setup is completed let's create a simple class - UserService:

 

package com.sap.netweaver.cloud.samples.springrest.srv;

import javax.ws.rs.Path;
import javax.ws.rs.Produces;

import org.springframework.stereotype.Service;

@Service("userService")
@Path("/users")
@Produces({ "application/json" })
public class UserService
{
    @Path("/user")
    @Produces("text/plain")
    @GET
    /**
     * Returns the name of the currently logged-on user.
     * 
     * @param request The {@link HttpServletRequest} that is processed
     * @return the name of the currently logged-on user
     */
    public String getUserName(@Context HttpServletRequest request)
    {
        String retVal = null;

        retVal = (request.getUserPrincipal() != null) ? request.getUserPrincipal().getName() : "Guest";

        return retVal;
    }
}

 

As you can see it's pretty much straight-forward: we have a simple Java class (aka POJO) that contains one method, which returns the currently logged on username as a String. We see a few JAX-RS annotations. In principal we define the URL path pointing to this service via the @Papth annoations, while the annotation at method-level is added to the one on class level, hence making the complete path to access this service: "/users/user". The @GET annotation indicates that this RESTful service will be mapped to a HTTP GET operation. Please also note, that we did override the @Produces annotation at method-level, to switch from "application/json" to "text/plain" for that particular service.

 

There are two more things to point out here: a) we also use a Spring annotation called @Service to indicate that this is a Spring-baked Service. By giving ot a name we can make use of of a feature called component-scanning, which frees us from declaring all used beans explicitly in the Spring configuration but instead just use the stated bean name instead. (That will get more clear in just a few minutes - hang on!)

 

Last thing to note is that we inject the HttpServletRequest as a method parameter. This is automatically done via Spring and JAX-RS and hence we can retrieve the currently logged on user via the standard servlet API.

 

5. Updating the web.xml

 

Now, with the coding in place let's have a look at the 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">
   <welcome-file-list>
    <welcome-file>index.html</welcome-file>
  </welcome-file-list>
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>WEB-INF/springrest-context.xml</param-value>
  </context-param>
  <listener>
    <listener-class>
            org.springframework.web.context.ContextLoaderListener
        </listener-class>
  </listener>
  <servlet>
    <servlet-name>CXFServlet</servlet-name>
    <servlet-class>
            org.apache.cxf.transport.servlet.CXFServlet
        </servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>CXFServlet</servlet-name>
    <url-pattern>/*</url-pattern>
  </servlet-mapping>

<login-config>
  <auth-method>FORM</auth-method>
</login-config>
<security-constraint>
  <web-resource-collection>
    <web-resource-name>Protected Area</web-resource-name>
    <url-pattern>/*</url-pattern>
  </web-resource-collection>
  <auth-constraint>
    <role-name>Everyone</role-name>
    </auth-constraint>
</security-constraint>
<security-role>
  <description>All SAP NetWeaver Cloud users</description>
  <role-name>Everyone</role-name>
</security-role>
</web-app>

 

Let's quickly go through this, shall we? So lines 8-16 simply make  Spring to automatically start once the web application is started via the ContextLoaderListener based on the spring configuration declared at line no 10.

 

Lines 17-27 define the CFX Servlet and map it to every incoming request via the "*" asterisk (catch-all) url-pattern.

 

Lines 29-44 comprise the security configuration, which enforces that all users need to authenticate prior to being able to access any resource of this web application (we protected the whole app via the "*" asterisk in line 35.) All of this is well explained in the corresponding chapter (User Authentication) of our online help.

 

6. Spring Configuration

 

The last missing piece is the spring configuration file we talked about when we created the UserService class and which we referenced in the web.xml. So, let's check it out. [springrest-context.xml]

 

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxrs="http://cxf.apache.org/jaxrs"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />

<context:component-scan base-package="com.sap.netweaver.cloud.samples.springrest.srv" />

<jaxrs:server id="restContainer" address="/api/v1">
<jaxrs:serviceBeans>
    <ref bean="userService" />
</jaxrs:serviceBeans>
<jaxrs:providers>
            <ref bean="jsonProvider"/>
        </jaxrs:providers>
</jaxrs:server>

<bean id="jsonProvider" class="org.apache.cxf.jaxrs.provider.json.JSONProvider">
        <property name="ignoreNamespaces" value="true"/>
        <property name="serializeAsArray" value="true"/>
 </bean>

</beans>

 

Line 13 shows the context component scan we briefly touched upon in step 4. Simply put, Spring scans all defined packages here and searches for a variety of annotations such as the @Service annotation we used in our UserService class. As we provided a simple name "userService" as a value to this annotation we can now reference this service (bean) within the configuration w/o explicitly defining it.

 

Lines 15-22 define a logical JAX-RS based server. Please note that we specify the address here: "/api/v1". This is the base url path this logical server is bound to. Hence, the url path to access the getUserName() would be "/<application-context>/api/v1/users/user".

 

Line 16-18 define the services exposed via this logical server; which in our examples is only the UserService.

 

Line 19-21 define the so-called providers. For this example we only specify a standard JSONProvider, which is responsible for converting the output of a particular operation to the specified MIME type of the method.

 

In line 24-27 this JSONProvider is defined and a few properties are set, which influence the rendering of JSON content. For further info please consult the excellent documentation.

 

 

7. Run the application

 

With that our project is ready to be deployed. Well, almost! There's one last step to be done, we need to activate the 'Project Facets' in order to be able to treat this Maven-based project just like any other 'Dynamic Web Module' in Eclipse (WTP).

 

For that purpose, please open up the project properties by using the context-menu of the project in the "Project Explorer" view. Select 'Properties' and then "Project Facets". Here, you need to convert the project to faceted form (This is an Eclipse-specific setting and hence - by design - not part of the Maven project nor the project repo.) Once this is done you should see a "Dynamic Web Module" Facet being active. Select it. On the right hand side you should see a "Details/Runtimes" toggle. Switch to the "Runtimes" option and select "SAP NetWeaver Cloud" as the designated runtime.

 

Now, you can build your project by selecting "Run as > Maven install" from the context menu of the project. Once the build is complete you can just add the web project to either the local server or a cloud server. Publish the project and start the server (if applicable.)

 

Note: If you use a local server, make sure you have defined at least one user by following this documentation. If you deploy to the cloud you have to use your SCN credentials to log on.

 

Once you're logged on, you should be able to access the 'service' via the following URL: http://<server>:<port>/<application-context>/api/v1/users/user

 

Wrap-up

 

So, that's it! Let's recap... so, in this tutorial we learned how-to clone a repo(sitory) from Github and import it into our Eclipse IDE. We learned the very basics about Maven and how to use Spring + Apache CXF to expose business functionality as RESTful services. We also touched upon the basics of securing a web application... not bad for a day, isn't it?

 

So, whether or not you liked this tutorial, you may want to check out chapter 2, where Lars Karg explains how to build a responsive UI with Twitter Bootstrap, Backbone.JS, Handlebars.JS and some other great open source frameworks...

 

PS: The result of this tutorial can be downloaded here.

As stated in the first post of my "Essentials" series it's all about lowering the entry barrier and helping newbies to get started with SAP NetWeaver Cloud. So, in this blog post I quickly want to provide you with the 'bare necessities' to install the required tooling for Git and Maven for Eclipse in order to simplify the process of getting examples from social code sharing sites such as Github up and running.

Note: Please do not expect me to provide you with the ultimate beginners guide to the stated technologies! By no means do I want give impression that I'll serve you all you need to know on a silver plate. You'd certainly be well-advised to familiarize yourself with these tools IF you want to stay in control of what you're doing! All I want to achieve with this post is to help you with getting your setup right in just a few minutes - establishing a basecamp if you will - you still have to climb the rest of the mountain yourself though.

 

Installing EGit

 

Alright, in order to install the Git plugin for Eclipse (called EGit) you would need to do the following steps:

 

  1. In Eclipse, goto "Help > Install New Software..."
  2. Depending on which version of Eclipse you use (we currently support Juno and Indigo) you have to select the corresponding Update Site from the drop-down box
  3. Select the plugins/features checked in the following screenshot under the "Collaboration" node

egit_updatesite.jpeg

 

Installing Maven for Eclipse

 

Now that we got EGit installed, we want to add Maven support: m2e-wtp. That may sound a bit cryptic (gotta love developers, right!), so let's explain: it's a Maven plugin for Eclipse that allows to use Maven-based projects in conjunction with the Web Tools Platform (WTP).

 

  1. Again, goto "Help > Install New Software..."
  2. Enter "http://download.eclipse.org/m2e-wtp/releases/" in the drop-down box and click "Add"
  3. Select the plugins/features checked in the screenshot below:

m2e_updatesite.jpeg

 

EGit configuration

 

Next thing we do is to configure EGit. For that we have to perform the following steps:

 

  1. Goto "Preferences"
  2. Enter "Git" in the filter field in the top-left corner
  3. Select the "Configuration" node
  4. Copy & adjust the settings shown below as they match your environment (proxy, email, etc.)

egit_config.jpg

 

Maven configuration

 

Last remaining step is to configure Maven. It's simple:

 

  1. Goto "Preferences"
  2. Enter "Maven" in the filter field in the top-left corner
  3. Select the "Installations" node
  4. If you already haven Maven installed you want to point to a (global) pre-existing settings file. If not, you may want to create a settings.xml file and point to it here. I attached a sample settings.xml file that shows you how-to speficy a proxy server.

 

So, that's pretty much it... you may want to check that it all works fine by cloning one of the SAP NetWeaver Cloud samples on Github. Let's do it together...

 

Cloning a git repo(sitory)

 

So, let's got to one of the easier samples on our Github account: https://github.com/sapnwcloud/springrest

github_cloning.jpeg

 

Copy the URL to the repo (https://github.com/sapnwcloud/springrest.git) by clicking the little notepad icon. (Note: As you can see from the screenshot I've been logged on with my Github user and as I'm a contributor to this project I have both Read + Write access.)

 

Now, let's go back to Eclipse and open the Git perspective via the "Windows > Open Perspective > Other..." menu entry and the selecting the "Git Repository Exploring" option. In this perspective you have the "Git Repositories" view on the left. In the corresponding menu (top-right of the view), click on the "Clone Git repository and add the clone to this view" icon.

 

In the pop-up window, select "URI" as the repository source. Click next to get to the next step of the wizard. Here, all the details should already be pre-filled (if you have used the notepad button on Github!) If you should have a Github user and you do want to contribute to the respective repo, you may want to maintain your username/password in the authentication section at the bottom. But cloning the repo should equally well work without it. Press "Next" and skip over the next wizard step - there is no need to make any changes. On the third and last page, select the directory to clone this repo to. In general, it's a good idea to store all your git repositories in a dedicated folder. Click on "Finish" to clone the repository.

 

github_cloning2.jpeg

 

Let's switch to the "Java EE" perspective and use the "File > Import..." menu and then the "Existing Maven projects" option. Provide the link to the root directory and click on Finish. Now, the project sources should be imported into your workspace. We're almost there...

 

Open up the project properties by using the context-menu of the project in the "Project Explorer" view. Select 'Properties' and then "Project Facets". here, you need to convert the project to facted form (This is an Eclipse-specific setting and hence - by design - not part of the Maven project nor the project repo.) Once this has happened you should see a "Dynamic Web Module" Facet being active. Select it. On the right hand side you should see a "Details/Runtimes" toggle. Switch to the "Runtimes" option and select "SAP NetWeaver Cloud" as the designated runtime.

 

Last thing you need to do is to use the context.menu of the project to trigger the build by using the "Run As > Maven install" option. Once the build has ended successfully you can add the project to a local or remote server as you would do with non-Maven projects....

 

Hope this blog post is useful to some of you... let me know about your experiences (good AND bad!)

While brainstorming about how-to adequately represent SAP NetWeaver Cloud at SAP TechEd now that I'm officially part of the team and given the task to push the adoption among the developer community it sounded desirable to come up with a fresh concept: one that conveys my understanding of NW Cloud being the prime example of the new SAP when it comes to agility, speed and openness.

 

The way I see it NW Cloud is truly the front-runner in many areas like continuous delivery (releasing new features in a bi-weekly rhythm) and fully embracing Open Source just to name two very important topics. Of course, I wanted these characteristics to shine at TechEd. With so many interesting things happening related to NW Cloud within SAP such as the SAP NetWeaver Cloud Labs it didn't take long to find a similar minded colleague eager to team up: Lars Karg.

 

Together, we came up with the concept of Tapping into Open Source with SAP NetWeaver Cloud, a 2h long lecture full of live coding. We believe actions speak louder than words - instead of walking you through a slide-deck, we opted for showing you what it feels like to code with/for SAP NetWeaver Cloud using Open Source software.

 

We broke down our understanding of the value proposition of using Open Source Software into six chapters, that build on top of each other:

 

Get started - Get results fast - Experience social - Give back - Achieve quality and Co-innovate

 

For each of these chapter we have prepared a 18min live-coding demo. Yet, we also wanted to make our lecture more sustainable and hence we decided to write down a dedicated blog post for each of the chapters plus hosting the corresponding sample projects on Github, so that everyone can test-drive the presented demos themselves...

 

But enough of the talking, here's a screenshot of the session supplements application [bit.ly/cd208]

 

cd208_screenshot_web_home.jpg

 

During our session, one of the things you'll learn is how we developed this application using some of the most popular Open Source projects out there. So, if you're interested in NetWeaver Cloud and/or Open Source - we would be happy to see you in our session! Cheers!

 

"Do you have kids?"

 

If so, then there's a good chance you remember having had more than just one discussion about the 'right' name with your partner. I, for one, remember it well. And it just seems natural to not take such a decision lightly as the name is something very important. Hence, it usually is a very emotional and winding decision process... some even say that a name has impact on the (future) character. Well, my wife and me - we called our third daughter Lotta and if you ever read one of the books by Astrid Lindgren than you would have at least some idea what she's like... (one of the books is called 'Lotta on Troublemaker Street' so just that you get the idea!)

 

The Naming Game

 

So, we all got a 'given name' and whether we like it or not that's the name our parents have chosen for us and there's little we can do about it. Now, for many reasons that may not be the name our parents, our friends or colleagues call us by. It may be too long, too complicated to pronounce or there are many more reasons why we may end up with one a nickname. Sometimes we even end up with multiple nicknames, one for each peer group we are in. That just seems natural...

 

In the enterprise software world the whole process of naming a product is equally complex and challenging as there are many things to consider like branding strategy, marketing aspects and all sort of trademarks and copyrights. Usually, new products start their lifecycle with fancy 'projects names' - a common pattern for these would be the place where the idea for a particular project was born or set in stone. Anyone of you still remember Vienna?

 

SAP NetWeaver Cloud aka NEO

 

As some of you may know I'm working in the team for a product called 'SAP NetWeaver Cloud'.

 

This particular product has gone by many (informal) names through its early-days and people may have heard it being called JPaaS, SAP NetWeaver OnDemand, SAP NetWeaver NEO (or just NEO in short) and we even referred to it as 'Project River' for a brief moment in time. That's all past us now though... or isn't it?

 

For some reasons the (nick-) name NEO seems to stick to people, especially in the developer community. Here are some thoughts on why that be the case:

 

  1. It's a name (and not a description)
  2. It's short - just three letters only
  3. It's geeky and developers typically associate it with a character from a well-known movie
  4. It stands for 'new'
  5. It may just be an acronym in the great tradition of names like GNU (my favorite interpretation would be: Next Evolution Of...)
  6. ...
  7. Developers love it!
  8. Developers love it!
  9. ... oh, and did I state: developers love it?!?

 

Be it as it is... the official/formal/given name is SAP NetWeaver Cloud.

 

And that's just fine! It reflects the fact that the platform is part of the broader NetWeaver family and it leaves no doubt about it's domain: the cloud.

 

The only thing that worries me a bit (if you allow me to express my thoughts) is that it may lead people to the wrong conclusion that this platform is just the 'old' NetWeaver platform put in the cloud. Which is wrong! It's an entirely different thing - it's been rewritten and assembled from scratch to address it's natural habitat: the cloud!

 

We usually describe it as "an open, standards-based and modular Platform as a Service for rapid development of on-demand applications" built on top of some of the most popular and common Open Source projects. It's definitely new and exciting and personally I consider it as the prime example of the new SAP or SAP's intelectual renewal as our CTO Vishal Sikka calls it. And who knows... next to our first lady HANA, NEO may just well be the Chosen One!

 

Back to the original question

 

"So, may I still call you NEO?" (Of course, I'm asking for a friend of mine!!!)

 

Tricky question! And if you expected me to give you an official approval for using the nickname then I may disappoint you now. On the other hand, if you - like me and many others - were good buddies with NEO before he became MR. SAP NetWeaver Cloud  then I guess noone can stop you...

 

I mean a lot of our board members and executives still refer to NEO in (in-)formal situations:

 

 

or a variety of recent tweets:

 

While Oracle seeks to delay cloud features in enterprise Java ( bit.ly/UuKJDN ) NEO rocks it.cloud+java & soon, cloud portal...

— Vishal Sikka (@vsikka) September 8, 2012

@steinermatt I thought you dreamt of being an @sapmentors and #SAP #NetWeaver Cloud aka #Neo evangelist...

— Björn Goerke (@_bgoerke) August 27, 2012

Interesting use case from myspotworld combining FB, Google, #SAPNetweaverCloud (Neo) and #SAP #HANA. #Startups saving the world (biz savvy)

— aiazkazi (@aiazkazi) August 15, 2012

 

 

At the end of the day, I guess it matters more that people talk about the platform at all rather than what people will call it by. Don't you agree?

 

Note: This blog post only reflects my very own personal opinion on the matter and it must NOT be regarded an official SAP statement on SAP NetWeaver Cloud or SAP's naming policies.

 

Update: In the meanwhile SAP NetWeaver Cloud has evolved into the broader SAP HANA Cloud (Platform).

Open Source Summit

 

Last week, SAP conducted the (internal) SAP Open Source Summit in Walldorf, a two day event to discuss, share and promote the usage of Open Source software (OSS) at the company. In addition to the usual suspects (Barbara Hartel, Claus von Riegen, Sanjay Patil and Karsten 'OSS' Schmidt) in this space we had developers sharing their experience of what it is like to actively contribute to Open Source projects like:

 

 

Of course, there also was a great line-up of external speakers such as:

 

 

For me, it's been a great and content-packed summit, one that rest-assured me that we are well underway at SAP in regards to Open Source. We learned about good and bad OSS licenses, the importance of growing a community and how-to establish processes that encourage the use of Open Source in the enterprise.

 

However, the one topic that stuck with me was Mike Milinkovich's presentations, in which he stated: "SAP is not doing a good enough job in promoting its contributions to Open Source!" (I'm paraphrasing here.) He did provide data to back up his statement, e.g. did you know that SAP is 3rd most active contributing company to Eclipse projects? No? Well, take a look at this dashboard: Company / Project Commit Details

 

As such, I thought it may be a good idea to make (parts of) my own presentation "SAP NetWeaver Cloud and Open Source - A match made in heaven" public as I truly feel that SAP NetWeaver Cloud (aka NEO) is taking it to the next level. So, here we go...

 

Mission statement - 1 Billion users

 

1BillionUsers.jpg

When it comes to explaining the importance of NW Cloud within SAP's overall strategy I usually start with the big picture. As you may know... (and SAP's executives are making sure to keep spreading the message internally and externally) SAP aims at having 1 Billion users by 2015. The question that immediately comes to mind is: 'how to get there?'

 

Well, from my point of view it's simple (to explain, that is!): SAP needs to provide an attractive platform that is easy to use and provides developers access to a huge customer base. It's easy math indeed: the more developers SAP gets to develop applications on the platform, the more apps there will be. If there are plenty of apps, there will be plenty of good apps. And the platform that has the best apps will be the most attractive for customers (and new developers.)

 

As such, it's more or less about porting the platform + store model that Apple™ has been so successful with to the enterprise space. As you probably recall, SAP announced several developer programs and trial licenses at SAPPHIRE NOW this May. Giving developers easy (and affordable) access to development tools is an important first step into the right direction. But is it enough to get mass adoption?

 

Let's take a closer look at the Open Source movement and the keys to successfully getting mass adoption.

 

The Open Source way

 

In general the charm (reads: value proposition) of Open Source can be broken down to the following steps:

OSS_way.jpg

 

  • Get started
  • Get results fast
  • Get involved
  • Give back
  • Achieve quality
  • Co-innovate

 

 

1. Getting started

 

One of the most important aspects of getting developers to use your stuff is to make it simple stupid for them to get started. You cannot market to developers, you may get them interested by talking to them, but ultimately they will want to test-drive what you got themselves! Consequently try to lower the entry barrier as much as possible and offer your tools for download for free. The harder it will be to download the tools, the less people will try!

 

The next step for a developer is to get the tools up and running. It's crucial to have a rock-solid installation guide, or - even better - an automated installation as using scripts or dependency/build management tools such as Ant, Ivy or Maven. If people will face a hard time getting the tool(s) installed, they'll move on and try out something else (could be the tool of your competitor!)

 

2. Get results fast

 

Let's face it: developers are always under pressure. Timelines are always tight and requirements keep changing! That's one of the reasons developers like libraries to ease their lives, so that they do not have to re.invent the wheel, but instead can build on top of quality code. This way, they can concentrate on coding the stuff that is unique to the challenge at hand. Consequently it's very important to have a good documentation of the tools to be used. And plenty of examples and executable samples and demos... (if you ever wondered why Spring got so popular - have a look at their documentation! )

 

3. Get involved

 

Once people start using a particular tool they eventually end up facing issues. Fortunately, there are plenty of ways to get help: discussions forums, mailing lists and special platforms such as stackoverflow. Usually, the answer to a problem is only a search away! This is where the community factor kicks in: the more people using a particular software, the more likely someone has faced a similar issue already - AND documented it somewhere on the internet. If not, you'd be well-advised to post your problem out there (including meaningful code snippets and exception log extracts!)

4. Give back

 

If everybody would only consume Open Source software w/o giving back it simply wouldn't work. So, why not blog about your experience using a particular software and hereby spreading the word? Why not paying it forward by answering some questions other people asked and to which you know the answer? (Maybe you found out the hard-way yourself!) Why not share your code samples on Github so that others may get a quick(er) start? 

 

5. Achieve quality

 

It's simple... the more people using a particular piece of software, the more likely that bugs have been found and fixed. More users usually results in less errors = better quality. In addition, there are plenty of Open Source projects out there that help you in producing quality code like JUnit, Selenium, Gerrit and Sonar - just to name a few. Oh... and while we are at it, don't you think you'd polish your code (and its documentation) when knowing it'll be out there for everyone to see? Guess it boils down to Hubris.

 

6. Co-Innovate

 

You'd be surprised to see what happens if you let geeks 'party with your code'. If you let them, they may just take it to the next level or fork it and give it a new spin altogether. One more reason to just put it our there and let the community do its thing...

 

SAP NetWeaver Cloud - We love Open Source!

 

With all that being said, you may understand why we - the SAP NetWeaver Cloud team - opted for developing our platform based on the Open Source way. Because it seems to be the best only way to provide a platform that developers will love to use!

 

weloveoss.jpg

 

As illustrated in the picture above, there's plenty of Open Source software within NEO. At the very core (from a dev's perspective), we got the Virgo server: an

OSGi runtime-container with an embedded Tomcat server. In addition there are plenty of well-known projects from Apache and Eclipse and many others. As I said before, we are not only using Open Source, but are actively contributing to it (see this list of projects.)

 

And... not only is the platform built using Open Source frameworks, but it is also developed according to best practices established in the Open Source movement. We follow agile methodologies and use the tools mentioned above e.g. we got Git as our version control system, we do Gerrit-based code reviews and we use Jenkins for Continuous Integration etc.

 

So, before we call it a day - let's do a quick check-up against the characteristics I stated above:

 

1. Get started

 

Eclipse is the standard IDE of choice due to its wide adoption both within and outside of the current ecosystem. Developers can download all required tools via the well-known process of using an Eclipse Update Site. SAP NetWeaver Cloud can freely be downloaded from the Developer Center and users can go from zero to their first deployment in about 10 minutes (here's proof!) 

 

2. Get results fast

 

SAP NetWeaver Cloud integrates seamlessly into the Eclipse Web Tools Platform, which means that everyone who has done Java Web Development before will feel at home right away. Given the selection of common OSS frameworks incorporated into the platform the entry barrier is really low and developers can get productive very fast. And instead of needing to learn proprietary tools, all components are designed to work using the standard way of Java programming: securing your app, using JDBC or JPA and even communicating with backend systems or SaaS applications via the connectivity API. It's all based on open standards and comes with a detailed documentation (available both in the IDE and online.)

 

3. Get involved

 

The SAP NetWeaver Cloud Development Center is the place to go to and read the latest blogs written by the community, check out the release notes of the bi-weekly updates or to get help in case you're stuck. The development team is constantly scanning the discussion forums and there are also the friendly people from the neighborhood watch regularly answering questions. Please feel encouraged to share your stories and experiences with the rest of the community here!

 

4. Give back

 

As mentioned already SAP actively contributes to a wide range of Open Source projects. And who knows, we may even have a few aces up our sleeves...

 

5. Achieve quality

 

Ever looked at the sample folder of the SDK? If not, you should... here you find ready-to-go sample projects including unit and integration tests. You may want to copy & adapt that for your projects.

 

6. Co-Innovate

 

Well, now it's your turn... others have already shared some really cool blogs about their experiments on NEO like using Clojure or Server-Side Javascript. We're eager to hear what you got!

 

 

 

Well, that's it for today. If you're interested in the topic and planning to attend TechEd this year you may want to look out for our session 'Tapping into Open Source with SAP NetWeaver Cloud.' Together with my partners in crime Lars KargKrasimir Semerdzhiev and Dimitar Mihaylov we have compiled a 2h lecture packed with live coding sessions using the who-is-who in Open Source software these days... plus, we will have some special guests!

SAP TechEd season is about to start and once again the geeks have been asked to submit their demos for DemoJam...

 

As such we're glad to see several contenders choosing SAP NetWeaver Cloud as their platform of choice. Let me share with you a few demos we'll see:

 

Garbage Collector

 

 

Description: A waste receiving process simplified for truck drivers and weigh bridge operators. See how SAP NetWeaver Cloud with SAP NetWeaver BPM and SAP UI5 actually facilitates a process that usually is handled in all kind of paper documents.

 

Authors: Twan van den Broek, Leo van Hengel

 

 

 

SAP Droids FoodAgent

 

 

 

Further info: http://androids.astill.mobi/

 

Related blog: SAP Netweaver Cloud - it's childs play

 

Coach: John Astill

 

 

 

Store Trek

 

 

Description:

Powered by K-Motion Store technology. This is the first incarnation of a 3D store that crosses the divide between in store and online shopping. Online is quick and convenient and products are recommended to you but the experience is not very engaging or immersive. In store you can see entire product ranges but they are not tailored to you, you have to travel to the store and get stuck in the queue at checkout. Store Trek takes the benefits of in store by delivering tailored virtual shelves in a virtual store layout driven by a personalisation engine you would have with an online store.

 

The kinect allows you to walk round the TV with the shelves automatically adjusting to give you the rich 3D experience. Rendering tens of thousands of products from real retailers in realtime you can purchase items by reaching out towards the shelf and the product will be added directly to your basket.

 

Authors: Dan McNamara

 

 

Looking forward to seeing you on stage - keeping our fingers crossed for you all!

In part II we  discussed some of the considerations to apply when designing an API and we identified the most suitable approach from an implementation perspective: JAX-RS. Now, it's time to stop talking and start coding...

 

Creating the basic project structure

 

In order to make it simple to consume and distribute our application we'll use Maven to take care of some of the heavy lifting in regards to dependency management and build operations. A full introduction into Maven is beyond the focus of this tutorial, so if you're interested in finding out more - please use your search engine of choice. All you need to know (and install) in regards to using Maven in Eclipse for now is described here: Running Sample Applications

 

 

So, the first thing we do is to create an simple Maven Project. For this we use the Project Creation Wizard in Eclipse:

 

  1. Select File > New > Other...
  2. Navigate to the Maven node and select 'Maven Project'
  3. Click on Next
  4. On the first page of the wizard we just need to tick the top checkbox 'Create a simple project (skip archetype selection)' and click on Next
  5. On the second page we need to maintain a few entries like group and artifact ID etc. Please check the screenshot below and adopt/adjust the entries as you see fit. The only important part is the packaging: make sure to select 'war' here. Then click on Finish.
    New Maven Project.jpg

 

With this empty project structure in place we now have to start setting up the project dependencies and build instructions. Being lazy developers (which is a virtue according to Larry Wall [ref]) we don't want to start from zero, but instead go for the classic copy & paste approach. So, if you have downloaded the SDK (version 1.7 or higher) you will find a samples folder in your SAP NetWeaver Neo SDK. Within this folder there's a pom.xml file. POM is an abbreviation for Project Object Model and in a nutshell it contains all the info required to build your project.

 

Next we have to merge that sample POM with our own. Sounds more complicated than it really is, because we want to keep almost all of the content from the sample POM, except for the first few lines, which represent the entries we maintained in step 5 above.

 

To make things a bit more simpler on your end I've attached the result of that operation for you: pom.xml. Make sure to adjust the group and artifact ids again to match what you entered in step 5.

 

Note: I also added a few standard dependencies as typically required when developing web applications such as pointing to the servlet archive bundled with the SAP NetWeaver Cloud SDK. You may want to keep that as a baseline file for the next projects you'll create (after you've verified that it all works that is!)

 

Please also make sure to adjust the <nw.cloud.sdk.path> property to reflect your current environment! (I know the Maven purists will now scream out in agony, but to keep things simple it seems to be the best approach for now in order to not overly confuse beginners.)

 

Now, if all worked out as it should <fingers crossed> saving the file in Eclipse should trigger the Maven2Eclipse plugin to build the project for us - fetching the required libraries from Maven Central.If not, you cal always manually trigger a build by choosing "Run as > Maven install" from the context menu of the project. 

 

There's one last thing to do and that is to attach our project to the SAP NetWeaver Cloud runtime and making sure the project uses the Servlet API 2.5. For that purpose we go into the project properties by activating the context-menu. Then we navigate to the 'Project Facets' menu and select version 2.5 for the Dynamic Web Module facet. On the right hand side you would need to switch from the 'Details' to the 'Runtime' tab and tick the checkbox for 'SAP NetWeaver Cloud'.

 

And that's that...

 

Adding dependencies

 

Now with the basic structure in place we need to add some dependencies so that Maven can fetch them for us during the build process.

 

  <dependency>
                              <groupId>org.apache.cxf</groupId>
                              <artifactId>cxf-rt-frontend-jaxws</artifactId>
                              <version>${cxf.version}</version>
  </dependency>
  <dependency>
                              <groupId>org.apache.cxf</groupId>
                              <artifactId>cxf-rt-transports-http</artifactId>
                              <version>${cxf.version}</version>
  </dependency>
  <dependency>
                              <groupId>org.apache.cxf</groupId>
                              <artifactId>cxf-rt-rs-extension-providers</artifactId>
                              <version>${cxf.version}</version>
  </dependency>
  <dependency>
                              <groupId>org.apache.cxf</groupId>
                              <artifactId>cxf-bundle-jaxrs</artifactId>
                              <version>${cxf.version}</version>
  </dependency>

 

(Note: I only stated the dependencies required for CXF. Please take look at this final POM file to see all the declared dependencies required to run the project.)

 

Setting up the web.xml

 

As mentioned in part 2 Apache CXF sits on top of the Servlet API, hence we need to declare a handler servlet within the 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">
 <welcome-file-list>
  <welcome-file>index.html</welcome-file>
 </welcome-file-list>
 <servlet>
  <servlet-name>CXFServlet</servlet-name>
                    <servlet-class>org.apache.cxf.jaxrs.servlet.CXFNonSpringJaxrsServlet</servlet-class>
  <init-param>
                              <param-name>jaxrs.serviceClasses</param-name>
                              <param-value>com.sap.nwcloud.demo.srv.FeedService</param-value>
  </init-param>
  <init-param>
  <param-name>jaxrs.providers</param-name>
                              <param-value>com.sap.nwcloud.demo.utils.cxf.CustomJSONProvider</param-value>
  </init-param>
  <load-on-startup>1</load-on-startup>
 </servlet>
 <servlet-mapping>
  <servlet-name>CXFServlet</servlet-name>
  <url-pattern>/api/v1/*</url-pattern>
 </servlet-mapping>
</web-app>

 

As you can see it's not really a whole lot to specify here, so let's quickly go over it. I registered the CXFNonSpringJaxrsServlet (as we go w/o Spring for now) and mapped it to the url-path 'api/v1/*'. If you read the Web API Design eBook from Apigee I referred to in part II of this blog series you'll recognize that I stick to the conventions they recommend.

 

The other important thing to notice is that I provided the class path to our service in the jaxrs.serviceClass parameter. This will tell CXF to introspect the corresponding class and search for specific (jaxrs) annotations it can interpret. We'll get to talk about this in a minute...

 

Sample Use-case

 

Now every demo app needs a crisp example, right? For some reason it seems that most people familiarizing themselves with SAP NW Cloud and RESTful APIs are all having the same idea: a Feed Reader. I did it a year ago while developing the demo app for my TechEd session and so did a whole lot of other people:

 

 

As such, let's stick to that tradition and develop a service that provides a blog Feed as a RESTful Service. And what other feed could be more interesting than our beloved SCN? (Now, let's not argue about the usefulness of converting an RSS feed to JSON. We just want a simple example to be able to focus on the technical aspects, right?)

 

Before we dig deeper you may want to see the end-result. If so, you can test-drive the 'app' here:

https://restdemo.netweaver.ondemand.com/simplerest/api/v1/feeds

 

RESTful Services

 

As mentioned already we only have service: FeedService. So, let's have a closer look at that file:

 

package com.sap.nwcloud.demo.srv;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;

import org.apache.cxf.jaxrs.ext.MessageContext;

import com.sap.nwcloud.demo.api.FeedQueryByElements;
import com.sap.nwcloud.demo.dao.DAOFactory;
import com.sap.nwcloud.demo.dao.FeedDAO;
import com.sap.nwcloud.demo.model.Feed;
import com.sap.nwcloud.demo.model.FeedList;
import com.sap.nwcloud.demo.model.ObjectFactory;

@Path("/feeds")
@Produces({ "application/json" })
public class FeedService extends BaseService
{
          @GET
          @Path("/")
          public FeedList getFeeds(@PathParam("") FeedQueryByElements query)
          {
                    FeedList list = new ObjectFactory().createFeedList();

                    Collection<Feed> feeds = new ArrayList<Feed>(1);

                    // dirty hardcoded string ;)
                    final String url = "http://scn.sap.com/community/feeds/blogs";
                    FeedDAO dao = DAOFactory.getInstance().getDAO();

                    Feed feed = dao.findFeedByURL(url);

                    feeds.add(feed);

                    List<Feed> feedList = new ArrayList<Feed>(feeds.size());
                    feedList.addAll(feeds);

                    list.setFeeds(feedList);

                    return list;
          }
}

 

At the very top of the file I specified two annotations: Path and Produces. The first one specifies the url-path to map this service to, in this case "feeds". With that information CXF knows, which service to invoke if a url is called. The Produces annotation simply specifies the default data format of the data returned in the response (and yes, you can dynamically switch the data format too.)

 

Let's have a look at the getFeeds() method and its annotations. GET simply specifies the HTTP verb to map the method to. I set the Path to "/" to simply use the default one provided on class level.

 

Now, the beauty of using JAX-RS is that it's unobtrusive. Our class is just a plain POJO (Plain Ordinary Java Object) with a few JAX-RS annotations. This makes the implementation quite flexible and if I should ever want/need to switch to another JAX-RS implementation it should be fairly easy. It also helps with unit tests as all the services can be consumed outside of the web container as well.

 

In fact, that's another note-worthy aspect of this implementation: both the request object FeedQueryByElements and the response FeedList are domain model objects. Consequently I can call this method from any other class within my service layer as well and I do not need to provide a dedicated facade. All the marshalling/unmarshalling to JSON is taken care of by the underlying framework. Now, isn't that nice? (We'll talk about that very topic and the benefits it brings when developing flexible APIs in part IV of this series.)

 

Architecture considerations

 

Before we call it a day let's talk about two more aspects of this sample app. For one, I still believe the good old way of applying clean separation of concerns (SoC) is appropriate! As you see by the code above, I delegated the whole data fetching to a dedicated DAO (Data Access Object). There are multiple reasons why this makes sense:

 

  • the business logic data should not need to care where the data comes from, but should only need to cope with business logic.
  • it makes the app more flexible as I can change the data source on the fly, without having to change the service (notice the factory pattern for constructing the DAO?) In a productive app you may want to cache or persist the feed so you don't have to call the feed provider all the time. In that case you may have multiple implementations of the DAO: one that calls the feed provider and one that queries a database or cache. By using the same interface it's just a matter of dynamically calling the appropriate implementation.
  • it also helps in unit tests and in cases where the data-source may not be accessible. All you need to do is to create a stub implementation that mimics the behavior of a real DAO by returning hard-coded data.

 

Last, but not least let's talk a bit about the domain model objects. Fortunately the days are gone, where we were forced to use dedicated DTOs (Data Transfer Objects) to send data over the wire. There still are valid uses cases for designing dedicated DTOs, but the fact that we can use our domain model objects as-is is certainly nice. However, our objects still need to be serializable so that they can be be converted to/from JSON (or XML etc.) and so a few considerations apply.

 

Take the Feed class for example:

 

@XmlRootElement(name = "feed")
@XmlAccessorType(XmlAccessType.FIELD)
public class Feed extends BaseObject implements Serializable
{

  private static final long serialVersionUID = 1L;

  private String title = null;

  //...
}

 

As you can see we work with annotations again. The XMLRootElement annotation indicates that a FeedObject can be the root object of a hierarchy. The XMLAccessorType annotation tells JAXB (Java Architecture for XML Binding) whether to use the attributes directly or use getter/setter methods during the de-/serialization process. And... we of course mark our class as being serializable and provide a serialVersionUID.

 

Wrap-up

 

I sure don't want to provide all the listings for the various objects used in this sample, but instead opted for providing it on Github. You can either clone it from here, or download the zip and manually merge it into the project structure we created at the beginning of this tutorial.

 

Hope to see you back for part IV, where we'll step it up a notch and port the whole thing to Spring and dig into more advanced features of JAX-RS in general and CFX in particular. Cheers...

 

PS: Special thanks to Vedran Lerenc and Kaloyan Raev for helping me sort out some issues with Maven.

In part I of this series we've talked about the most prominent use-cases for PaaS and I provided some reasons why I believe that the provisioning of APIs is one of them. In today's blog post we'll get a bit more technical and shed some light on how-to build apps that expose public APIs.

 

Setting the stage

 

Before we get started it sounds like a good idea to have a quick look about what Wikipedia has to say about APIs so that we have a common understanding of the term:

An application programming interface (API) is a specification intended to be used as an interface by software components to communicate with each other.

 

While I assume most of the readers are fairly familiar with the concept I considered it to be worthwhile to have a closer look at the definition again, because it helps us focus on some of the most vital aspects of it:

 

  • APIs are an interface and as such are expected to be somewhat stable or at least backwards-compatible.
  • APIs are used by other software components = consumers or clients. These components are build by developers.

 

The reason to explicitly mention this is to raise awareness about the fact that developing a good API is something not to take lightly. The intention to develop an API is to allow others to develop applications against it and as such the interface should cater to this need. You'd want to make it as easy and intuitive as possible, while at the same time making the API flexible enough to grow over time without enforcing developers to cope with incompatible changes. So, if you consider writing an API I'd recommend to spend some time designing it before releasing it to public - as once it's out there you may no longer change it at will (well, at least not without upsetting your consumers!)

 

Fortunately, there are lots of resources on the web providing excellent insight and best practices when it comes to API design. I recommend the content provided by the nice folks at Apigee [http://apigee.com/about/resources/] and especially their "Web API Design - Crafting Interfaces that Developers Love" eBook as a good starting point. You may also want to read about the experiences @Sascha Wenniger shared about developing  RESTful APIs from Scratch: Lessons Learnt (so far).

 

RESTful services

 

With the design aspects sorted out it's now time to look into the implementation details. So, what is the best way to develop an app that exposes its functionality as an easy-to-consume API? Well, it looks like the most popular approach these days is to use RESTful services. In contrast to other "web services" technologies it's not a standardized protocol (such as SOAP), but more of an architectural style using a mix of other standards.Some consider this as a drawback, others emphasize that exactly this lack of standardization makes it so flexible and easy to use.

 

Fact is, using the HTTP protocol and its verbs (read HTTP methods) helps to keep things lightweight and easy to implement and consume. Most browsers (incl. mobile ones) understand this protocol without any additional plugins or tools. Typically JSON (JavaScript Object Notation) is used as the data format, which is less verbose as XML and - again - is supported by most browsers out-of-the-box. Consequently, this combination seems to be a perfect match for modern application in times of web 2.0.

 

Java Servlets

 

Based on the above it sounds as RESTful services may be the best option for the provisioning of an API. Fortunately, it's quite easy to develop them with Java. Matter of fact, if we take a trip down memory lane we'll see that the Java Servlet API already supports (simple) means to communicate via HTTP and that the HTTPServlet provides functionality to implement all HTTP verbs.  Some may doubt that a technology from 1997 is the appropriate solution to address modern (web) development needs, but it's not far off the truth. Matter of fact, I was skeptical at first too, yet after giving it some further thoughts I realized that, while the technology may be a bit out-dated, yet it has all the characteristics of a great API:

 

  • it's lightweight
  • it's robust and mature
  • and it's flexible (read: easy to extend!)

 

We've seen plenty of great frameworks and libraries being built on top of Servlets. One of the most prominent ones being Struts, which became one of the most popular MVC frameworks of its time. So, for the last decade Servlets weren't used directly anymore, but served as the foundation for other frameworks and libraries. At the time, the server did most of the heavy-lifting and provided the whole enchilada in regards to multi-tier applications from database, to services up to the presentation layer. Nowadays, with the rise of smartphones and tables equipped with modern browsers we see a trend to let the client take care of the presentation and control flow of an app and the server is only providing the data via well-defined services. It has become state-of-the-art to shift the MVC pattern to the client, regardless of whether it's a web-based (e.g. HTML5) or native app.

 

JAX-RS: Java API for RESTful web services

 

Consequently, the type of frameworks built on top of the Servlet API have evolved addressing these needs. Not surprisingly there is a variety of frameworks that focus on supporting the development of RESTful services based on the JAX-RS API. In a recent blog postDagfinn Parnas already explained how-to use the JAX-RS reference implementation Jersey. In part III of this series we'll have a closer look on Apache CXF and develop a baseline project you can re-use as a starting point for your own applications.

 

PS: NO - you do not have to use Servlets directly - after all: it's soo last-century!

For those still thinking that large enterprise and agile development is an oxymoron - take that: the NetWeaver Cloud team is delivering new features on a bi-weekly rhythm! And the latest (and greatest) release of SAP NetWeaver Cloud just went live and is now available for download [https://tools.netweaver.ondemand.com]

 

Personally I've been eagerly waiting for some of the features contained in that build and as some gems may get easily overlooked I decided to write a short post highlighting them. So, what am I so excited about: it's maven-ized samples!

 

So, where's the big deal you may wonder? Well, it's quite simple:

 

[Maven] can be used for building and managing any Java-based project. We hope that we have created something that will make the day-to-day work of Java developers easier and generally help with the comprehension of any Java-based project.

 

[http://maven.apache.org/what-is-maven.html]

 

I think that summarizes it quite well and flows nicely with our vision of "ease of use". By using Maven for build management we can simplify the "getting started" aspect and the sharing of example code. No more hassle getting sample code to run in your environment. No more worries about legal issues that may come by distributing open-source libraries. Life as it should be!

 

Enough of the talk... let's just do it! All you really need to know to to get started is documented here: Running Sample Applications

 

In a nutshell it consists of a few simple steps:

 

  1. Download Maven and related plugins to make it work with Eclipse
  2. Make sure to set your proxy settings in case you are located behind a corporate firewall
  3. Import the sample apps as "Existing Maven Projects"
  4. Run a "maven build install" to build a standard war archive

 

It really is that simple! If you want to build your own sample apps using this approach I'd recommend taking the parent pom.xml and the hello world sample as a starting point. I really hope to see lots of demo code popping up now and matter of fact I'll post one within the next days to lead the way

 

PS: Special shout-out to our SDK team for providing very comprehensive examples and a well-structured pom to start with!!!

Intro

 

One of the cool things in my new role is that I get to work with the community on a daily basis and as the SAP NetWeaver Cloud platform gets traction we see lots of new people popping up willing to give it a try. It's simply amazing to see the diverse crowd of people eager to test-drive the platform: I have met old veterans, yet also newcomers who are attracted by the ease-of-use promise of PaaS and then I know there are even some high-school kids and students out there getting their feet wet and taking their first steps in the cloud. Whatever bucket you should belong to - we are happy to have you!

 

Some turn to me asking for help to get started and that's just fine, because that's exactly what my new role is all about: to push adoption. Admittedly, some of the questions I get asked are rather basic, yet as a wise man once said: there are no stupid questions!

 

Based on this rationale I figured it may be time to kick-off this "Essentials" series to lower the entry barrier even further; taking nothing for granted. This series will really focus on the "bare necessities" [feel free to hum along!] in order to help beginners to get started.

 

Local database support

 

In the first blog post of the series I want to address working with the local database as it's the domain of the most common questions I got asked lately.

 

By default, we launch a in-memory (in the classical sense of the word, so not HANA) Derby DB on the localhost. While that is the most simple approach and requires no work on your side it comes with the caveat that a) all data will be lost once you shutdown the server and b) that you have no way of looking at the data from the outside. We also have support for MaxDB and HANA DB, but then the number of people with access to a local HANA DB outside of SAP is rather limited at the moment I guess.

 

So, this is the problem space I want to adress today, by providing you with a short tutorial on how to use a local Derby DB running as a server. Interested? Here we go...

 

 

Installing Apache Derby

 

So, let's get started with downloading and installing Derby.

 

  1. Download the release of your choice from the website: http://db.apache.org/derby/derby_downloads.html (at the time of writing the latest release was 10.9.1.0)
  2. Move it and extract it to your preferred location. It should look like this:

    Derby file structure
  3. In the bin folder you'll find the startup scripts for both the windows and the linux world: startNetworkServer. If all goes well, you should get a console window with the following output:

 

Thu Jul 12 10:53:47 CEST 2012 : Security manager installed using the Basic server security policy.
Thu Jul 12 10:53:47 CEST 2012 : Apache Derby Network Server - 10.9.1.0 - (1344872) started and ready to accept connections on port 1527

 

Couldn't be any simpler than that, right? So, now that we have a running DB, let's do the necessary changes to the local JPaaS runtime to use this database.

 

Adjusting the local JPaaS runtime

 

Again, this is an easy change. In your Project Explorer you have a Servers node. Collapse it and drill down to the connection_data folder with the config_master node. There's a file called connection.properties.

 

ide_servers.jpg

 

Let's open it up and change the content so it looks as follows:

 

#----------------------------------------
# Connection parameters for a local Derby database
# DB and tables are created automatically (if missing)
#----------------------------------------
javax.persistence.jdbc.driver=org.apache.derby.jdbc.ClientDriver
javax.persistence.jdbc.url=jdbc:derby://localhost:1527/DemoDB;
javax.persistence.jdbc.user=demo  
javax.persistence.jdbc.password=demo
eclipselink.target-database=Derby

 

Note: Make sure that you comment out the other DB driver definitions (by adding the # prefix.)

 

Bonus: Install SQuirreL to manage your data

 

SQuirreL logo

 

Well, as I mentioned in the intro most of us would like to have the possibility to check the data in our DB and make some changes (if required.) There are many tools to do so, but one of my favorite ones is SQuirreL - a universal SQL tool. Not only, because it's quite versatile, easy to install and small, but also because it has a damn geeky name and... how can one not love squirrels?!? They are so cute...

 

So, let's quickly walk through the steps to get it up and running, shall we?

 

  1. Download the program from the website: http://squirrel-sql.sourceforge.net/#installation. There are installer for all the major platforms and the installation guide is one of the best I ever saw.
  2. The next thing we need to do is complete the JDBC driver definition for Derby. For this purpose, click on the Drivers tab and then select the Apache Derby Client entry. Trigger the context menu and choose Modify Driver...

    squirrel_driver1.jpg
  3. Now, we need to add the Derby Client JDBC jar to the Extra Class Path as shown below:

    derby_driver.jpg
  4. Next step is to create a database alias for our DB via the Aliases tab. Simply click on the + icon, select the Apache Derby Client driver and maintain the same info we did in the connection.properties file:

    squirrel_add_alias.jpg
  5. You may want to test the connection prior to saving it to make sure all is fine! If everything works as expected, you can click OK and voilà - we are done!

 

With that, I leave you alone for the day... have fun coding!

There's one thing that people associate with the term 'Cloud' and that is having access to it everywhere and anytime. Gone are the days where people accepted/tolerated long turn-around times or tedious processes just to get what they need to do their jobs. Especially developers are not known for their patience!

 

To accomodate to that mindset we - the SAP NetWeaver Cloud team - tried our best to make the on-boarding process for our platform as streamlined and simple as possible. However, if we take a look at our discussion forums we see some people are still struggling with getting started, even though we have documented it quite well right here:

Get your free developer license for SAP HANA Cloud in 5 minutes

 

Whatever it is... (guess it goes back to RTMF) we know that real developers do not need to read manuals, just as a real men do not need to read instructions on how-to assemble any kind of electronic device or a piece of furniture, right?

 

Either way, we are also aware that all of us got way too little time on our hands to do all this reading and hence I decided to create a short little video walking you through all the steps it takes to get started with the platform: from point zero up to deploying your first app to the cloud - all that in roughly 10 minutes!

 

As you'll see it's pretty much straight forward (if you know what you're doing!)

 

Filter Blog

By author:
By date: By tag: