SAPUI5 with Gateway

Link to presentation I did earlier for training my colleagues.

http://slides.com/sakiv/sapui5withgateway#/


Installation and version management of mobile applications without any MDM solution

From my SCN blog post:

http://scn.sap.com/community/mobile/blog/2014/08/24/installation-and-version-management-of-mobile-applications-without-any-mdm-solution

While testing applications, we used the below strategies and it took us some time to work these out. So I sum these up as reference – I trust people will find it useful. These are based on my experience in dealing with iOS apps.

Problem 1: I was working on an enterprise mobile application project but we couldn’t use the organisation’s pre-existing mobile device management ( MDM ) solution. This can happen due to any number of factors – in our case, the app was simply too big to be supported by the current version of MDM solution (it’s not a SAP MDM solution ).

Solution :

We used the below alternatives and they can be employed to work.

1. DropBox. A simple html page can be created in DropBox which points to the app’s plist file ( property list file ) and the plist file in turn will point to the relative location of the .app file. I kept the app in the Public folder of dropbox.

Let me draw a picture to make it clearer.

Screen Shot 2014-08-23 at 11.07.08 pm.png

2. TestFlight: I wasn’t aware of this site when we were first working on testing release I but found it extremely useful for subsequent releases. You can set up a project team, assign users to test and check the devices registered.

See the sample screenshot below.

Screen Shot 2014-08-23 at 6.png

3. Through a public site. You’ll need infrastructure team to create a publicly accessible domain ( if you want them to access via normal internet ).

Add the below MIME types to your web server ( for IIS ).

Mime type for plist -> application/xml

Mimet type for ipa -> application/octet-stream

4. The most obvious one : If the users can come to your desk, of course just use Xcode to install by making the device a developer device.

Hints on creating the HTML page:

a) Create the HTML page – this page will point to the plist file.

e.g.

<a href=”itms-services://?action=download-manifest&url=http://dl.dropbox.com/u/xxxxxxxxx/app_live.plist“>Download App</a>

This will create a quick and dirty page for users to install the app.

Screen Shot 2014-08-23 at 5.58.09 pm.png

Of course, you can make it better by adding icons etc.

b) The plist file will in turn point to the .ipa file. You’ll need to edit it manually from the one generated by Xcode.

<?xml version=”1.0″ encoding=”UTF-8″?>

<!DOCTYPE plist PUBLIC “-//Apple//DTD PLIST 1.0//EN” “http://www.apple.com/DTDs/PropertyList-1.0.dtd“>

<plist version=”1.0″>

<dict>

<key>items</key>

<array>

<dict>

  <key>assets</key>

  <array>

   <dict>

    <key>kind</key>

    <string>software-package</string>

    <key>url</key>

    <string>http://www.domain.com/app/Application.ipa</string>

   </dict>

  </array>

  <key>metadata</key>

  <dict>

   <key>bundle-identifier</key>

   <string>com.domain.ApplicationBundle</string>

   <key>bundle-version</key>

   <string>1.0.0</string>

   <key>kind</key>

   <string>software</string>

   <key>title</key>

   <string>Name Of Application</string>

  </dict>

</dict>

</array>

</dict>

</plist>

Problem 2: While testing we realised that sometimes the user’s app version was outdated and they’ll report issues or have inconsistencies due to a lower version. This can cause a lot of confusion.

Solution :

 

– Store the supported version of the app on a text file in an external URL .

– Get the version of the app and compare the version from an external URL.

– If the version in the app is lower than the supported version , display a message asking the user to upgrade and quit.

The supported version may not be the current version of the app – for minor UI tweaks, we may not change the supported version but if there are changes to the underlying object structure, the supported version will need to be changed.

Sample Objective-C code:  We can put it in the Main View Controller.

Main view controller :

    [self checkifObsoleteAppVersion];

….

– (void) checkifObsoleteAppVersion{

 

//Get version from external site

    NSString *versionURLString = @”http://URL/version.txt;  //<<– Version information stored in a simple text file

    NSURL *versionURL = [NSURL URLWithString:[versionURLStringstringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];

    NSString *versionOnExternalSite = [[NSString stringWithContentsOfURL:versionURLencoding:NSUTF8StringEncoding error:nilsubstringToIndex:6];

 

//Get version from App

    NSString *versionFromApp = [self.syncManager.appVersion substringToIndex:6];

 

//Format the versions to numbers

    NSNumberFormatter *versionFromAppNo = [[[NSNumberFormatter alloc]init]autorelease];

    NSNumber *appNo = [ versionFromAppNo numberFromString:versionFromApp];

 

    NSNumberFormatter *versionFromAppNoExt = [[[NSNumberFormatter alloc]init]autorelease];

    NSNumber *appNoExt = [ versionFromAppNoExt numberFromString:versionOnExternalSite];

       

//App version shouldn’t be lower than the one maintained in version file

       

    if ([appNo floatValue] < [appNoExt floatValue] )

    {

 

// Show a message

        UIAlertView *appObsoleteView = [[[UIAlertView alloc]initWithTitle:@”App version obsolete”message:@”A new version of App has been released and this version is obsolete.Please upgrade App to the new version.” delegate:self cancelButtonTitle:@”Exit” otherButtonTitles:nil, nil]autorelease];

        appObsoleteView.tag = 666;

        [appObsoleteView show];

 

    }

 

}

 

@end

 

Problem 3: Just putting as a reference to consolidate the information in a single place. Users were required to be manually registered and there were issues caused sometimes due to wrong information being set up due to manual process.

 

Solution:

I created a solution using SUP’s Java APIs and shared the experience in an earlier blog.

 

http://scn.sap.com/community/mobile/blog/2013/05/30/automating-user-registration-in-sybase-control-center

 


Integration Gateway in SAP Mobile Platform 3.0

Main features of SMP 3.0 :

– SUP, Agentry and Mobiliser combined. This itself is a pretty big as each of the platforms had an integration framework and it had to be harmonised . It’s simplified to just use SMP with services exposed in oData format.

– Through SMP 3.0, services from ABAP backend ( using SAP Gateway ) and non SAP backends can be easily consumed. This is pretty powerful as data could be spread out over multiple kinds of data sources. It allows for data consumption from JPA, JDBC , SOAP  etc.

– Eclipse GWPA has been enhanced for new features – to consume services from different backend types.

– A big drawback I see is that it doesn’t seem to talk about MBO based replication. My first iOS mobility project involved creating an iOS ( iPAD app ) using SUP which was based on MBOs and it’s sad to see them go. Support for offline capabilities is planned from later releases of SMP 3.0.

– A big positive is the ability to schedule different data based on speed ( or other requirements ) – the ability to assign priorities in scheduling is a big one – our users were extremely frustrated that they can’t control the information they wanted and had to wait for sync of everything from past before relevant data for today could be synced.

 Comparisons between SAP Gateway and SAP Integration Gateway:

– ABAP based vs Lean Java server ( Java, OSGI ).

– Supports SAP vs Supports both SAP and non-SAP data sources.

– Available as a standalone solution vs embedded inside SMP 3.0 .

– On premse vs On premise / Cloud.

 


Automating user registration in SUP

I had originally posted this on SCN : http://scn.sap.com/community/mobile/blog/2013/05/30/automating-user-registration-in-sybase-control-center

This blog documents the solution I had worked on to automate user registration in SUP. We use a mobile solution for sales force automation providing SAP functionality on the mobile device. It’s an iOS native app using SUP as data cache and is authenticated against SAP. Hence, we need SAP users to be present in SUP. Usually the task of provisioning and controlling a user in SUP  is done by a MDM solution but our MDM solution ( it’s not Afaria ) was not able to handle our iOS app which is around 500MB . Apart from being a sales force automation app allowing sales reps to work on the go, it has lot of picture contents about products which bloated the app size.

Here’s the landscape diagram relevant for the issue.

CUA system: Central User Administration. The users are created here and replicated to SAP ECC.

SUP.png

Problem: How to automate user registration in SUP? It is error prone to register them manually in Sybase Control Center – I’ve made mistakes myself and then tried to spent better part of a day trying to figure out what went wrong. Debugging iOS code was definitely not fun in this case even .And even if a person is not careless like me, it’s not feasible if the number of user is in hundreds and new users need to be added regularly.

I used Unwired Server Management APIs to automate the use registration. Approach at a high level :

– Develop a java program that will be executed as a daily batch job for user registration.

– The program will perform the following steps:

– Read list of users from SAP (e.g. all users of a defined role)

– Read list of users in already registered in SUP.

– For any new user found, perform registration using server management APIs.

I’m not pasting the entire code  here but github link at the bottom of the page can be referred to look at the code . I’ll mention the basic building blocks in understanding the solution.

ABAP development:

We’ll need a RFC enabled function module which returns table of users which should be  registered in SUP. The below code uses roles set in a custom table which is populated in lt_sup_roles.

Main part in ABAP code will be to get users based on SAP roles, which is in AGR_USERS table.

    select uname

    from agr_users into table users

    for all entries in lt_sup_roles

    where agr_name = lt_sup_roles-value.

Java Development :

We’ll need a Java program which will be executed as a daily batch job.

– The program needs to communicate to SAP ECC server to get the list of users and hence we’ll need to have JCo libraries added to the Java project.

– For communicating to SUP, some library files are needed . Here’s the link for the list and where to get them from:

http://infocenter.sybase.com/help/index.jsp?topic=/com.sybase.infocenter.dc01332.0210/doc/html/title.html

This is required even if the program is run on SUP app server itself .

From experience, Juno version of Eclipse makes it really easy to export the project as a single jar file. Indigo required more work when trying to export the project as a jar with required libraries ( JCO, SUP libs and jar for property file ) .

The java program has the following overall steps:

  • Create a property file so that the settings are configurable for dev, QA and prod.It has connection settings for SAP and SUP servers. You may create a   jar file.
  • Attach JCO and SUP library files.
  • The basic structure of code is as follows:

Create three lists holding users in SAP , SUP and one for users to be added ( who are present in SAP but not yet in SUP ).

List<String> SAPUserlist = new ArrayList<String>();

List<String> SUPUserlist = new ArrayList<String>();

List<String> UserAddSAPlist = new ArrayList<String>();

Get the list of SAP users . Simple JCo call.

                              JCoDestination destination = JCoDestinationManager.getDestination(DESTINATION_NAME2);

                                JCoFunction function = destination.getRepository().getFunction(

                                                                “ZSD_SUP_GET_USER_LIST”);

                                JCoTable codes = function.getTableParameterList().getTable(“USERS”);

                                for (int i = 0; i < codes.getNumRows(); i++) {

                                                codes.setRow(i);

                                                SAPUserlist.add(codes.getString(“BNAME”)); }

Get the list of SUP users :

ServerContext serverContext = new ServerContext(host, intserverPort,admin, password, true);

String noll = “”;

ClusterContext clusterContext = new ClusterContext(serverContext, noll);

SUPApplication app = SUPObjectFactory.getSUPApplication(clusterContext);

PaginationResult<ApplicationConnectionVO> pag = new PaginationResult<ApplicationConnectionVO>();

AppConnectionFilterSortVO filter = new AppConnectionFilterSortVO();

int a = 0;

Long a1 = new Long(a);

int max = 200;

Integer max1 = new Integer(max);

pag = app.getApplicationConnections(filter, a1, max1);

int i = pag.getTotalAvailableRecords();

List&lt;ApplicationConnectionVO> SUPlist = new ArrayList<ApplicationConnectionVO>();

SUPlist = pag.getItems();

for (int j = 0; j < SUPlist.size(); j++) {

  1. SUPUserlist.add(SUPlist.get(j).getApplicationUser().toUpperCase());

}

Now, create a new list for users to add the ones missing in SUP which are present in SAP.

            for (int j = 0; j < SAPUserlist.size(); j++) {

                  if (SUPUserlist.contains(SAPUserlist.get(j)) == false) {

                       UserAddSAPlist.add(SAPUserlist.get(j));

                  }

            }

Register the users in SUP.

AppConnectionRegistrationRequestVO acrrvo1 = new AppConnectionRegistrationRequestVO();

Collection<AppConnectionRegistrationRequestVO> vos = new ArrayList<AppConnectionRegistrationRequestVO>();

Map<APPCONNECTION_REGISTRATION, Object> req1 = new HashMap<APPCONNECTION_REGISTRATION, Object>();

req1.put(APPCONNECTION_REGISTRATION.USER_ID, UserAddSAPlist.get(j));

req1.put(APPCONNECTION_REGISTRATION.ACTIVATION_CODE, intactivationCode);

req1.put(APPCONNECTION_REGISTRATION.EXPIRATION_HOUR, intexpirationTime);

acrrvo1.setRequest(req1);

  • vos.add(acrrvo1);

AppConnectionSettingVO settings = new AppConnectionSettingVO();

Map<APPCONNECTION_SETTING_FIELD, Object> settingMap = new HashMap<APPCONNECTION_SETTING_FIELD, Object>();

     settingMap.put(APPCONNECTION_SETTING_FIELD.SERVER_NAME, host);

     settings.setSetting(settingMap);

     app.registerApplicationConnections(templateName, vos, settings);

Create a jar file for the project and use it to schedule a windows task on SUP server ( it should also work on any other server which has visibility to both SAP and SUP servers ).

The development can be further enhanced by removing users who are no longer active. For this to happen, the following could be checked:

– In ABAP : USR02 lock status as 32 or 64 ( i.e. locked by admin and not due to incorrect logins ) to get users to be removed.

– Update java program to add step for removal of users as well for the list derived above.

There was no real need in our case but could be useful depending on the business case and can be easily extended using above steps.

I’ve put the entire code on github:  https://github.com/viksingh/SUPUserregn .