Skip to Content
Author's profile photo Former Member

How to Consume Multiple ODATA Services in Native Android(Online) App Using SMP 3.0

Hi Folks,

Before proceeding on this blog, i would like to thank Claudia Pacheco for her wonderful self explanatory blog How to consume OData Services in online Mode (Android) which really helps me in achieving my goal.

As i was proceeding on my app development, i faced a requirement to consume multiple OData services from a single data source. As a newbie on SMP and Android side i faced few challenges in starting to achieve it and tried to find some useful code but hard luck. Later on i got the success. So, thought to share how i implemented hoping it may become useful to other newbie like me.

Prerequisites

  • SMP SDK 3.5+ & Android Studio installed on machine
  • Added the MAF resources and completed the on boarding of users on SMP 3.0 using MAF logon UI /Core libraries
  • Have set the primary back-end point url and created the multiple back-end connections for multiple OData.

Here i’ll take an example of read and create operation with two different OData services.

Steps to Achieve

Step 1 : Creating the MultipleOpenListner class which implements the OpenListner as “multipleOpenListner.java”


public class multipleOpenListner implements OpenListner{
//creating multiple listener instance for multiple back-end connections
public static leOpenListner Instance = null, readInstance, createInstance ;
private final CountDownLatch latch = new CountDownLatch(1);
OnlineODataStore store;
Exception error;
public static multipleOpenListner getInstance(String ch){
switch(ch){
case "read":if(readInstance == null){
readInstance = new multipleOpenListner();
Instance = readInstance;
}
break;
case "create":if(createInstance == null){
createInstance = new multipleOpenListner();
Instance = createInstance;
}
break;
  }
return Instance;
}
@Override:
public void storeOpened(OnlineODataStore store){
this.store = store;
latch.countdown();
}
@Override:
public void storeOpenError(ODataException e){
this.error = e;
latch.countDown();
}
public synchronized boolean finished(){
return (store != null || error!=null);
}
public synchronized Exception getError(){
return error;
}
public synchronized OnlineODataStore getStore(){
return store;
}
public void waitForCompletion(){
try{
if(!latch.await(30, TimeUnit.Seconds)){
throw new IllegalStateException("Open listener was not called within 30 seconds");
}
else if(!finished()){
throw new IllegalStateException("Open listener is not in finished state after having completed successfully");
}
}
catch(InterruptedException e){
throw new IllegalStateException("Open Listener waiting for result was interrupted");
}
}
}



Step 2 : Opening OnlineODataStore under the class “OnlineManager.java”


public class OnlineManager {
   public static final String TAG = OnlineManager.class.getSimpleName();
   public static boolean openOnlineStore(Context context, String conCase) throws ODataException{   multipleOpenListner openListener = multipleOpenListner.getInstance(conCase);
   if (openListener.getStore()==null) {
  LogonCoreContext lgCtx = LogonCore.getInstance().getLogonContext();
  IManagerConfigurator configurator = LogonUIFacade.getInstance().getLogonConfigurator(context);
  HttpConversationManager manager = new HttpConversationManager(context);
  configurator.configure(manager);
   //XCSRFTokenRequestFilter implements IRequestFilter  //Request filter that is allowed to preprocess the request before sending   XCSRFTokenRequestFilter requestFilter =
  XCSRFTokenRequestFilter.getInstance(lgCtx);
  XCSRFTokenResponseFilter responseFilter =
  XCSRFTokenResponseFilter.getInstance(context, requestFilter);
  manager.addFilter(requestFilter);
  manager.addFilter(responseFilter);
   try {
  String endPointURL ="";
   switch(conCase){
   case "read": endPointURL = lgCtx.getAppEndPointUrl();
   break;
   case "create": endPointURL = "http://server:8080/backEnd_ConnectionName";
   break;
   default : break;
  }
  URL url = new URL(endPointURL);
   // Method to open a new online store asynchronously   OnlineODataStore.open(context, url, manager, openListener, null);
  openListener.waitForCompletion();
   if (openListener.getError() != null) {
   throw openListener.getError();
  }
  } catch (Exception e) {
   // throw e;   Log.e(TAG, e.getLocalizedMessage(), e);
  }
   //Check if OnlineODataStore opened successfully   OnlineODataStore store = openListener.getStore();
   if (store != null) {
   return true;
  } else {
   return false;
  }
  } else {
   return true;
  }
   //End   }
// Method to read
public static ArrayList read(String conCase) throws ODataException{
  ArrayList<String> arrList = new ArrayList<String>();
  multipleOpenListner openListener = multipleOpenListner.getInstance(conCase);
  OnlineODataStore store = openListener.getStore();
   if (store!=null){
     ODataProperty property;
  ODataPropMap properties;
   try {
   //Executor method for reading an Entity set synchronously   ODataResponseSingle resp = store.executeReadEntitySet("Entity",null);
   //Get the response payload   ODataEntitySet feed = (ODataEntitySet) resp.getPayload();
   //Get the list of ODataEntity   List<ODataEntity> entities = feed.getEntities();
   //Loop to retrieve the information from the response   for (ODataEntity entity: entities){
  properties = entity.getProperties();
  property = properties.get("Property_Name");
  String propName = property.getValue().toString();
  arrList.add(propName);
  }
  } catch (Exception e) {
  Log.e(TAG, e.getLocalizedMessage(), e);
  }
  }
   return arrList;
}
// Method to create
public static void create(UIListener uiListener, String conCase) throws ODataException{   multipleOpenListner openListener = multipleOpenListner.getInstance(conCase);
  OnlineODataStore store = openListener.getStore();
   if(store==null) return;
   try{
  ODataEntity newEntity = createEntity(store);
  RequestListener requestListener = new RequestListener( Operation.Create.getValue(),uiListener);
   //Scheduling method for creating an Entity asynchronously   store.scheduleCreateEntity(newEntity, "cms_Data",
  requestListener, null);
  }
   catch (Exception e){
  e.printStackTrace();
  }
}
public static ODataEntity createEntity(OnlineODataStore store){
  ODataEntity createData = null;
   if(store!= null){
   //If available, it will populates those properties of an OData Entity which are defined by the allocation mode   createData = new ODataEntityDefaultImpl("Model.cms_Data");
   leadData.getProperties().put("Full_Name", new ODataPropertyDefaultImpl("\"Full_Name\"","Deepak Sharma"));
   leadData.getProperties().put("Contact_Number", new ODataPropertyDefaultImpl("\"Contact_Number\"","9810234567"));
    createData.setResourcePath("cms_Data", "cms_Data");
}
return createData;
}
}

Step 3 : Call openOnlineStore method from your MAFLogon Activity class.



try {
  OnlineManager.openOnlineStore(this,"read");
} catch (ODataException e) {
  e.printStackTrace();
}



Step 4 : Call read and create methods from activity class wherever required with openOnlineStore method.



try {
   OnlineManager.openOnlineStore(this,"create");
   OnlineManager.create(this, "create");
} catch (ODataException e) {
  e.printStackTrace();
}




Hope it helps!!! 🙂

Assigned Tags

      4 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Vishnu Pankajakshan Panicker
      Vishnu Pankajakshan Panicker

      Hi Deepak Sharma,

      Since u have worked with the Claudia tutorial for consuming OData Services(online mode) in Android Studio.

      Kindly help me with the below mentioned discussion thread.

      Unable to consume OData in Android Studio

      Regards,

      Vishnu

      Author's profile photo Michael Appleby
      Michael Appleby

      Hi Vishnu,

      To more easily bring this to someone's attention, mouseover their name, right click, select "Copy Shortcut" and past the link into your Discussion.  It will get their attention using the same notification mechanisms as posting to their document.  You can also use the same method to link in another Discussion or document if you wish to do so.

      Also you can auto-title the link by mouseover, click on the balloon that appears, click on the T all the way to the right.  The link will change to the title (name of the person, Discussion, Blog, or Document) of the url rather the url.

      Regards, Mike (Moderator)

      SAP Technology RIG

      Author's profile photo Vishnu Pankajakshan Panicker
      Vishnu Pankajakshan Panicker
      Author's profile photo Former Member
      Former Member
      Blog Post Author

      Hi Vishnu,

      Is your issue resolved? As i saw on your thread "It is assumed answered".

      Thanks & regards,

      Deepak