Quantcast
Channel: Jive Syndication Feed

Visualize SAP Gateway OData services

$
0
0

SAP NetWeaver Gateway OData services can contain a comprehensive set of entity types and associations. A visual representation can help you understand and communicate the contents of a SAP Gateway OData service.

In this post I will describe how you can explore SAP Gateway OData services, using the Open Data Protocol Visualizer, a free extension for Visual Studio 2010.

Installing the OData Protocol Visualizer in VS2010

The Open Data Protocol Visualizer is a Visual Studio 2010 extension, which you can install via the Extension manager.

Launch the “Extension Manager” from the Visual Studio “Tools” menu.

image

 

The visualizer is available from the online gallery, in the Tools>Data section:

SNAGHTML30ffac2.

Click to download and install. Restart Visual Studio and you’re done!

Configure a SAP Gateway service

Let’s use the ubiquitous Flight service on the SAP Gateway demo system as an example. You will need the demo username/password, provided on this page.

The service URL for the Flight service is:

http://gw.esworkplace.sap.com/sap/opu/odata/IWBEP/RMTSAMPLEFLIGHT_2/

To use the OData visualizer, you need to create a project in VS and include a Service Reference to an OData service:

First, create (for example) a Console project. In the Service References section, right-click and select '”Add Service Reference”:

image

In the dialog box, enter the service Url in the Address field and provide a meaningful name in the Namespace field. Click on Go and provide the demo username and password. Visual Studio will now download the service information ($metadata). Once completed, you should now be able to expand the Service header and see the collections available through the Flight service.

SNAGHTML3273d1f

Click OK, and the Service is available for use in your project

 

Visualize SAP Gateway service

To start using the visualizer, right-click the Service reference and click ‘View in Diagram”

image

This opens the visualizer window. In the left pane, you will find a model browser, which lists Entity types, Associations, Complex Types and their Attributes. The center pane contains a  ‘canvas’ where you select and layout the visual representation of the model.

SNAGHTML33dadcc

A detailed view of the Flight and Booking entity types:

image

The OData visualizer has several useful features:

  • layout: determine how the shapes are visually arranged
  • zoom in/out: canvas can be zoomed in and out.
  • collapsed view: just shows entity types and associations, no attributes
  • select/deselect: determine which part of the ‘model’ you want to visualize
  • view in browser: automatically open the collection for a selected Entity type. E.g. View ‘Booking’ in browser will request the BookingCollection from the Flight service.
  • export to XPS: export the content to XPS file format (unfortunately no other file format is supported...).

Here’s an example of a collapsed (partial) view of the Activity Management service (based on SAP CRM):

image

Finally, here’s an example of the properties pane showing the attribute properties of the Value attribute of a Sales Order Item.

SNAGHTML38012a7

The OData visualizer can be a valuable part of your toolbox. Give it a try!

Thanks for reading.


Building SAP mobile apps with Sencha Touch - part 1

$
0
0

SAP and Sencha partnership

 

Earlier this year SAP announced partnerships with Adobe (PhoneGap), Appcelerator and Sencha. These partnerships provide mobile developers ever more options to build apps on top of SAP back-ends.

 

In a series of posts I would like to provide an introduction to building SAP mobile apps with Sencha Touch. In this post I will give you a brief overview of Sencha's frameworks and tools. In part 2 we will dive into some demo code to illustrate how Sencha Touch apps can connect to SAP Gateway.

 

So, please let me introduce you to the members of the family:

 

Sencha Touch

Sencha Touch is an HTML5 framework for mobile web apps. It provides a wide range of UI components such as lists, forms, selectors, tabs, buttons, toolbars and charts. Sencha Touch facilitates an MVC approach to organize your code. To get quick feel of the Sencha Touch UI components, open the ‘kitchen sink demo’ with Chrome or Safari or mobile device. Sencha Touch apps can be deployed as web apps or packaged with PhoneGap or Sencha’s own packager.

 

SAP OData connector

As a result of the partnership with SAP, Sencha released the SAP OData connector. This data proxy helps you connect Sencha Touch apps to SAP Gateway and SAP HANA, using OData.  Alternatively, it is possible to use Sencha Touch in a SUP HWC.

 

Here are some example of Sencha Touch apps accessing SAP data through SAP Gateway:

SalesOrders.pngSalesOrder.png

Carriers.pngMap.png

 

On the Sencha website you can find essential resources for learning and using Sencha Touch: the developer guides, API documentation and community forums.

 

ExtJs

ExtJs is a complimentary Javascript framework for developing desktop web apps. Sharing the same foundation and development concepts, developing with ExtJs is very similar to using Sencha Touch. While Sencha Touch targets mobile browsers and WebKit based desktop browsers (and IE10 support is announced), ExtJs offers support for wide range of desktop browser (e.g. IE6+).

 

Sencha Architect

Sencha Architect is a visual application builder for Sencha Touch and ExtJs apps. It provides a drag-and-drop environment to mix and match UI components, in addition to configuration and code editor to build out your apps. Because you can inspect the code it generates it also is a great learning tool.

architect.png

 

Sencha Command

Sench Command is a set of command line tools you can use when generating, building and deploying apps. It performs tasks like:

  • initiate a project/folder structure and application skeleton
  • build optimized production versions of your app, by selecting required components from the library, source file concatenation and minification
  • package your HTML5 application as a native app and give your app access to the Device APIs

 

Sencha_CMD_example.png

 

Sencha Touch is licensed under free commercial and open source licenses for application development. You can buy support and the complimentary tools. See the Sencha site for more details.

 

Now you are familiar with the framework and tools, let's get started with some actual coding in part 2 of this series.

Building SAP mobile apps with Sencha Touch - part 2

$
0
0

My previous blog provided an overview Sencha frameworks and tools to build mobile apps. In this post we’ll start coding an example mobile app that connects to SAP Gateway using OData. We will be using the SAP Gateway demo system

 

 

Hello world!

So let's get started with the basics: an HTML page to load the Sencha Touch library and the app. The easiest way to get started with Sencha Touch is using the hosted library on cdn.sencha.io.

 

Create the following app.html file that includes Sencha Touch javascript library and stylesheet:

 

<!DOCTYPE html><html><head><title>Hello World</title><!-- include the Sencha Touch stylesheet --><link rel="stylesheet"         href="http://cdn.sencha.io/touch/sencha-touch-2.1.0/resources/css/sencha-touch.css"/><!-- include the Sencha Touch library -->    <script src="http://cdn.sencha.io/touch/sencha-touch-2.1.0/sencha-touch-all-debug.js"></script>    <!-- include your app code --><script src="app.js"></script>  </head><body></body></html>

 

 

 

Our application code is in app.js:

 

// Ext.application is entry point for a Sencha Touch application
Ext.application({  // launch function will be called when all code is loaded and DOM is ready  launch: function () {    // create and display a messagebox    Ext.Msg.alert('Hello SAP SCN', 'Sencha Touch is ready action!');  }
});

 

 

Put these files on a local webserver and point your Chrome browser at app.html:

helloword.png

 

We've got our basic app running! We're ready to take the next step.

 

 

Creating a list view

 

This step will introduce you to the class system that is at the heart of Sencha Touch (from now on abbreviated to ST). It provides inheritance, namespacing, mixins, dependency definitions and more.

 

In ST you typically create building blocks by defining classes that extend (i.e. inherit from) the classes offered by ST. This is shown in the next example. We define a new CarrierList class by extending the built-in Ext.dataview.List and create an instance of this class in the launch function (the DOM needs to be ready before we can insert a UI component).

 

// With Ext.define you can define a class
Ext.define('App.view.CarrierList', {    // we want to inherit from the built-in Ext.dataview.List     extend: 'Ext.dataview.List',    config: {        // this component should fill the whole screen (viewport)        fullscreen: true,        // we'll provide some inline data        data: [            { code: 'AB', name: 'Air Berlin' },            { code: 'BA', name: 'British Airways' },            { code: 'DE', name: 'Delta Airlines' }        ],        // define a template that is used to render each data record:        itemTpl: '{code} - {name}',        // define a titlebar at the top as a child item of the List container        items: [{            xtype: 'titlebar',            docked: 'top',            title: 'Carriers'        }]    }
});

Ext.application({
    launch: function () {        // Ext.create will create an instance of a class        Ext.create('App.view.CarrierList');    }
});

 

 

 

If you put this code in your app.js, you’ll see:

CarrierList.png

 

 

A couple of thing to note here:

 

  • Ext.define() defines a class, Ext.create() creates an instance of a class
  • The titlebar is a child item of the CarrierList. The titlebar is an example of a UI component. Components that can contain other components (i.e. child items) are called Containers.
  • The titlebar is not instantiated immediately with Ext.create(). Instead it is configured using an xtype, which is a short alias for a UI component class, e.g.
    ‘titlebar’ refers to class Ext.TitleBar. ST will defer instantiation until the a CarrierList is created. This is called lazy instantiation.

 

 

Fetching data from SAP Gateway

 

In the previous example we used inline data. Now let’s get some data from SAP Gateway using OData.

 

We will use the TravelAgency collection from the Flight sample database on the SAP Gateway demo system and display the Travel Agencies in a List.

 

The screenshot below shows a part of the OData feed for the TravelAgency collection:

OData.png

 

To access this SAP data from Sencha Touch, we first define a TravelAgency model.

 

// define the TravelAgency model
Ext.define('App.model.TravelAgency', {    extend: 'Ext.data.Model',    config: {        // list the fields, the default type is string        fields: [          { name: "TravelAgencyID" },          { name: "Name" },          { name: "Street" },          { name: "POBox" },          { name: "PostalCode" },          { name: "City" },          { name: "Country" },          { name: "Region" },          { name: "TelephoneNumber" },          { name: "URL" },          { name: "LanguageCode" },          { name: "LocalCurrencyCode" }        ],        proxy: {            type: 'odata',            url: 'http://gw.esworkplace.sap.com/sap/opu/odata/IWBEP/RMTSAMPLEFLIGHT_2/'+                  'TravelAgencyCollection',            withCredentials: true,            username: 'GW@ESW',            password: 'ESW4GW'        }    }
});

 

This Model defines the fields and also the proxy type to use. In Sencha Touch, a data proxy is the bridge between data on the server and data in the application. The proxy takes care of preparing requests (e.g. parameters, and payload) and transforming server responses into Model instances.

 

As a result of the partnership with SAP, Sencha made available the SAP OData connector, which contains a data proxy to communicate with SAP Gateway and other SAP OData sources (e.g. SAP HANA). Please download the SAP connector and include a script link to the OData.js file after the ST library and before your app.js in your html page.

 

 

For a list we actually want to fetch multiple records in one go. So we'll define a Store, which can hold a collection of model instances.

 

// define a store to load a collection TravelAgency records
Ext.define('App.store.TravelAgencies', {    extend: 'Ext.data.Store',    config: {        model: 'App.model.TravelAgency',        // perform client-side sorting on field Name        sorters: 'Name',        // configure grouping        grouper: {            // group by the first letter of Name field            groupFn: function (record) {                return record.get('Name')[0];            }        }    }
});

 

As you can see the TravelAgencies Store is configured wth the TravelAgency Model. This way ST knows which proxy and fields to use when trying to load server data.

 

Please note that I included a grouper function. It returns the first letter of the Travel Ageny's name and is used to build a grouped list, which we will define next

 

The List view lists the names of the agencies and groups them by first letter.

// define a List to display Travel Agencies
Ext.define('App.view.TravelAgencyList', {    extend: 'Ext.dataview.List',    config: {        // we want a grouped list        grouped: true,        // just display the name of each TravelAgency        itemTpl: '{Name}'    }
});

 

Finally, we use our building blocks to launch our application:

 

Ext.application({    launch: function () {        // create a store.         var store = Ext.create('App.store.TravelAgencies');       // load the records from the SAP Gateway       store.load();        // create a list view and bind it to the store        Ext.create('App.view.TravelAgencyList', {            fullscreen: true,            store: store        });    }
});

 

 

Now, fire up your Chrome browser with the “disable-web-security” command line. This will suppress the Same Origin Policy which normally doesn’t allow you to do XHR request across domains:

 

ChromeDisableWebSecurity.png

 

Now you can view app.html in Chrome, showing the TravelAgencies fetched from SAP Gateway:

TravelAgencyList.png

 

Time to wrap up: in this post we have seen models and views. In the part 3 we're going to add a controller to coordinate between models and views. We will also cover how ST can create, update and delete data on SAP Gateway data.

 

Thanks for reading!

Building SAP mobile apps with Sencha Touch - part 3

$
0
0

This is part 3 in a series about building SAP mobile apps with Sencha Touch. Part 1 provides an overview of the Sencha family of framework and tools. In part 2 we started coding and introduced Models, Stores and Views.

 

 

Controllers

 

Now let’s have a look at Controllers. Controllers respond to view events and handle the data through Models and Stores.

 

 

We are going to expand our sample app so that the user can select an agency from the Travel Agency list and its details are shown in a details view. The details view contains a back button to return to the list.

NavigationView.png

 

 

ST offers a UI component, called NavigationView which makes it very easy to build this type of user interface. Conceptually, the NavigationVIew manages a stack of pages and displays the one on top of the stack. You can simply push a new page on the stack. The NavigationView will automatically take care of the toolbar title, back buttons and page transitions.

 

Here’s the code for the TravelAgencyList view, which will be the first page in the stack:

 

 

// define a List to display Travel Agencies
Ext.define('App.view.TravelAgencyList', {    extend: 'Ext.dataview.List',    alias: 'widget.travelagencylist',    config: {        grouped: true,        title: 'Travel Agencies',        itemTpl: '{Name}'    }
});

 

 

Please note the alias. This offers a shorthand to include this list in other components, such as the NavigationView:

 

Ext.define('App.view.MainNavigationView', {    extend: 'Ext.navigation.View',    config: {        fullscreen: true,        // we would like a navigation bar on top for title and back button        navigationBar: {            docked: 'top'        },        // initially the navigation view will only contain the travel agency list        items: [{            xtype: 'travelagencylist'        }]    }
});

 

 

 

Now, let’s define a view to display the details of a Travel Agency. We’ll use a FormPanel which can contain Fieldsets and Fields.

 

// define a FormPanel to display Travel Agency details
Ext.define('App.view.TravelAgencyDetails', {    extend: 'Ext.form.Panel',    alias: 'widget.travelagencydetails',    config: {        title: 'Travel Agency',        items:  [{            xtype: 'fieldset',            title: 'Address', // title of fieldset            // define defaults that apply to all items in this container            defaults: {                xtype: 'textfield',                readOnly: true,                labelWidth: '30%'            },            items: [                {                    name: 'Name',                    label: 'Name'                }, {                    name: 'Street',                    label: 'Street'                }, {                    name: 'City',                    label: 'City'                }, {                    name: 'Country',                    label: 'Country'                }            ]        }]    }
});

 

 

 

The next step is to actually display the details view when a users selects (taps on) an Agency from the list. We could easily create an event listener in the list view to open a details view. But we want to maintain a clear separation and loose coupling, so we are going to handle the list item tap event in a controller:

 

 

Ext.define('App.controller.TravelAgencies', {    extend: 'Ext.app.Controller',    config: {        views: ['TravelAgencyDetails'],        // define a reference to the main nav view        refs: {            navView: 'mainnavigationview'        },        // define which event handlers should be invoked        control: {            'travelagencylist': {                itemtap: 'onTravelAgencyListItemTap'            }        }    },    onTravelAgencyListItemTap: function (list, index, target, record) {                var navView = this.getNavView(),               name = record.get('Name');        navView.push({            xtype: 'travelagencydetails',            title: name,            record: record // pass the selected record        });    }
});

 

 

 

Let’s point out some details:

 

  • The refs config object creates references using component queries. This works similarly to CSS selector, but now operating on ST component. ST will automatically create getters on the controller. E.g. this.getNavView() will return the MainNavigationView instance
  • The control config object is used to connect component events to event handlers. You can refer to handler functions by their name.

 

 

Finally, you need to tell the Ext.application which controller to include:

 

Ext.application({    name: 'App',    // define required stores, views and controllers    stores: ['TravelAgencies'],    views: ['MainNavigationView', 'TravelAgencyList'],    controllers: ['TravelAgencies'],    launch: function () {        // create a store and navigation view        var store = Ext.create('App.store.TravelAgencies'),            view = Ext.create('App.view.MainNavigationView');        // push a travel agency list into the Navigation view        view.push({            xtype: 'travelagencylist',            store: store        });    }
});

 

 

 

Code organization

 

You are now familiar with all the key ingredients of a ST application: models, stores, proxies, views and controllers. It is best practices to organize your code into separate source files, one file for each class, in a folder structure that mirrors the namespace. The root folder is by default called ‘app’.

 

Here’s how your file structure should look like:

Code Organization.png

 

 

Instead of manually including all the different js files in your application html file, you can let Sencha Touch dynamically load all the source files. But you have to inform ST about the dependencies in your code through the ‘requires’ config of a class.

 

Let’s look at the TravelAgency Store class. It requires the TravelAgency Model class, because it is used in the model config:

 

// define a store to load a collection TravelAgency records
Ext.define('App.store.TravelAgencies', {    extend: 'Ext.data.Store',    // the class depends on the TravelAgency model    requires: 'App.model.TravelAgency',    config: {        // in the model config we use the TravelAgency model,         // that's why we need to define it as a dependency.        model: 'App.model.TravelAgency',        // automatically load the records when store is created        autoLoad: true,        // perform client-side sorting on field Name        sorters: 'Name',        // configure grouping        grouper: {            // group by the first letter of Name field            groupFn: function (record) {                return record.get('Name')[0];            }        }    }
});

 

The Sencha Command tools will use the same dependency information to include only the source files required from your app and the framework when building the production version of your app.

 

 

Create, update and delete bookings

So far, we have used the SAP OData connector to fetch data from the SAP NW Gateway server. However, we can modify server data just as well!
As an example we will create, modify and delete a Booking for a Flight in the SAP NW Gateway Flight service.


We’ll first define a Booking model:

 

Ext.define('App.model.Booking', {    extend: 'Ext.data.Model',    config: {        fields: [{            name: 'AirLineID',            type: 'string'        }, {            name: 'FlightConnectionID',            type: 'string'        }, {            name: 'FlightDate',            type: 'string'        },    {        name: 'BookingID',        type: 'string',        defaultValue: ''    },    {        name: 'CustomerID',        type: 'string'    }, {        name: 'TravelAgencyID',        type: 'string'    }, {        name: 'PassengerName',        type: 'string'    }, {        name: 'CustomerType',        type: 'string'    }, {        name: 'Smoker',        type: 'boolean'    }, {        name: 'LuggageWeight',        type: 'float'    }, {        name: 'WeightUnit',        type: 'string'    }, {        name: 'Invoice',        type: 'boolean'    }, {        name: 'FlightClass',        type: 'string'    }, {        name: 'PriceInForeignCurrency',        type: 'float'    }, {        name: 'ForeignCurrencyCode',        type: 'string'    }, {        name: 'PriceInLocalCurrency',        type: 'float'    }, {        name: 'LocalCurrencyCode',        type: 'string'    }, {        name: 'SalesOfficeID',        type: 'string'    }, {        name: 'BookingDate',        type: 'string'    }, {        name: 'TravelAgencyID',        type: 'string'    }, {        name: 'Cancelled',        type: 'boolean'    }    , {        name: 'Reserved',        type: 'boolean'    }    , {        name: 'PassengerName',        type: 'string'    }, {        name: 'Title',        type: 'string'    }, {        name: 'PassengerDateOfBirth',        type: 'string'    }],        proxy: {            type: 'odata',            url: 'http://gw.esworkplace.sap.com/sap/opu/odata/IWBEP/RMTSAMPLEFLIGHT_2'+                        '/BookingCollection',            withCredentials: true,            username: 'GW@ESW',            password: 'ESW4GW'        }    }
});

 

 

Now, let’s create a booking. Please note that there are some required fields that we need to provide:

 

var booking;
booking = Ext.create('App.model.Booking', {    AirLineID: flight.get('AirLineID'),    FlightConnectionID: flight.get('FlightConnectionID'),    FlightDate: flight.get('FlightDate'),    CustomerID: '00004274',    TravelAgencyID: '00000087',    PassengerName: 'Joe Picard'
});
booking.save(function (record, operation) {    if (operation.wasSuccessful()) {        console.log('Booking created. Id:' + record.get('BookingID'));    } else {        console.log('Create booking failed');    }
});

 

 

Once we a Booking, we may update its properties:

 

booking.set('PassengerName', 'Tom Picard');
booking.save(function (record) {    console.log('Booking updated')
});

 

 

 

Finally, to delete a booking:

 

booking.erase(function () {    console.log('Booking cancelled');
})

 

Please note that the server determines how to handle the delete request. In the Flights service, the Booking record is not removed from the database. Instead, the Booking is marked as ‘Cancelled’.

 

Have a look at Developer Tools in Chrome, while developing your app. Here you can sse the Create (POST), Update (PUT) and Delete (DELETE) requests on HTTP level:

 

http requests.png

 

Typically you’ll place code to fetch and modify data in the controller, in response to view events.

 

 

It's time to wrap up! In this post we have introduced controllers to handle UI events and access the Models. We  organized our code in seperate source files and let Sencha Touch dynamically load the source files. Finally, we performed create, update and delete actions on the server data. 

 

I hope this helps you get started with building SAP mobile apps with Sencha Touch.

 

Thanks for reading!

Visualize SAP Gateway OData services

$
0
0

SAP NetWeaver Gateway OData services can contain a comprehensive set of entity types and associations. A visual representation can help you understand and communicate the contents of a SAP Gateway OData service.

In this post I will describe how you can explore SAP Gateway OData services, using the Open Data Protocol Visualizer, a free extension for Visual Studio 2010.

Installing the OData Protocol Visualizer in VS2010

The Open Data Protocol Visualizer is a Visual Studio 2010 extension, which you can install via the Extension manager.

Launch the “Extension Manager” from the Visual Studio “Tools” menu.

image

 

The visualizer is available from the online gallery, in the Tools>Data section:

SNAGHTML30ffac2.

Click to download and install. Restart Visual Studio and you’re done!

Configure a SAP Gateway service

Let’s use the ubiquitous Flight service on the SAP Gateway demo system as an example. You will need the demo username/password, provided on this page.

The service URL for the Flight service is:

http://gw.esworkplace.sap.com/sap/opu/odata/IWBEP/RMTSAMPLEFLIGHT_2/

To use the OData visualizer, you need to create a project in VS and include a Service Reference to an OData service:

First, create (for example) a Console project. In the Service References section, right-click and select '”Add Service Reference”:

image

In the dialog box, enter the service Url in the Address field and provide a meaningful name in the Namespace field. Click on Go and provide the demo username and password. Visual Studio will now download the service information ($metadata). Once completed, you should now be able to expand the Service header and see the collections available through the Flight service.

SNAGHTML3273d1f

Click OK, and the Service is available for use in your project

 

Visualize SAP Gateway service

To start using the visualizer, right-click the Service reference and click ‘View in Diagram”

image

This opens the visualizer window. In the left pane, you will find a model browser, which lists Entity types, Associations, Complex Types and their Attributes. The center pane contains a  ‘canvas’ where you select and layout the visual representation of the model.

SNAGHTML33dadcc

A detailed view of the Flight and Booking entity types:

image

The OData visualizer has several useful features:

  • layout: determine how the shapes are visually arranged
  • zoom in/out: canvas can be zoomed in and out.
  • collapsed view: just shows entity types and associations, no attributes
  • select/deselect: determine which part of the ‘model’ you want to visualize
  • view in browser: automatically open the collection for a selected Entity type. E.g. View ‘Booking’ in browser will request the BookingCollection from the Flight service.
  • export to XPS: export the content to XPS file format (unfortunately no other file format is supported...).

Here’s an example of a collapsed (partial) view of the Activity Management service (based on SAP CRM):

image

Finally, here’s an example of the properties pane showing the attribute properties of the Value attribute of a Sales Order Item.

SNAGHTML38012a7

The OData visualizer can be a valuable part of your toolbox. Give it a try!

Thanks for reading.





Latest Images