Skip to content

MBO Migration

Metadata Conversion Tool

SAP Mobile Platform 3.0 includes MBO Toolkit and MBO Runtime, where MBO is an abbreviation for Mobile Business Object. MBO Toolkit is used to define the metadata for MBOs, and MBO Runtime is a server execution environment for MBOs. For each MBO package, MBO toolkit creates a deployment-unit.xml deployment unit file, also known as an AFX document or MBO metadata.

This document describes the usage of the afx-to-csdl metadata conversion tool, as well as manual and post-conversion migration tasks, to convert an MBO package to an OData CSDL XML file that is compatible with OData services for Cache Databases generated by the service generator tool.

Use the metadata conversion tool, followed by the csdl-to-war tool, to convert an MBO package into a change-tracking-enabled OData service that is deployable into SAP Business Technology Platform (Cloud Foundry or Neo environment) or Apache TomEE / Eclipse Virgo (on-premise), and which is also compatible with SAP Business Technology Platform client SDKs for Android and iOS.

While there is no automated conversion process available for client applications, you can use an SAP BTP SDK for Android or iOS, together with Offline OData, to construct a new client application. Alternatively, you can manually update a client application for Android or iOS that currently uses MBO APIs to instead use the DataService and related OData APIs while leaving the user interface code intact. See also Client Applications.

Automated Model Conversion

The metadata conversion tool is delivered as Windows batch file afx-to-csdl.bat and as Mac/Linux shell script afx-to-csdl.sh inside the resources\server-odata-sdk\bin folder within the Visual Studio Code Extension.

  • Windows: %USERPROFILE%\\.vscode\\extensions\\sapse.vsc-extension-mbt-*X.Y.Z*\\resources\\server-odata-sdk\\bin\\afx-to-csdl.bat

  • Mac/Linux: $HOME/.vscode/extensions/sapse.vsc-extension-mbt-*X.Y.Z*/resources/server-odata-sdk/bin/afx-to-csdl.sh

  • SAP Business Application Studio (in a Terminal window): locate with find /tmp/vscode-unpacked -name afx-to-csdl.sh -print

The minimal command-line tool parameters are an OData version (2.0 or 4.0), an SAP Mobile Platform MBO metadata input file name, and an OData CSDL XML output project folder name.

Mac/Linux shell example:

afx-to-csdl.sh 4.0 ~/test/deployment-unit.xml ~/projects/myshop

Windows Command Prompt example:

afx-to-csdl.bat 2.0 c:/test/deployment-unit.xml c:/projects/myshop

The converted model will be named metadata.csdl.xml in the output project folder.

Manual Model Conversion

MBO model elements are converted to corresponding OData schema elements with CSDL Annotations.

An understanding of how to manually convert an MBO model to CSDL may be helpful for a number of reasons:

  • If automated model conversion fails due to a converter deficiency or model problem.

  • If the output of automated conversion requires subsequent manual changes to complete the full conversion.

  • If additional business objects need to be added to a converted model (for future maintenance of the model, for example).

  • If a new model is to be developed by someone whose background includes usage of MBO Toolkit.

An initial OData schema should be created as follows:

<edmx:Edmx xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx" Version="4.0">
    <edmx:Reference Uri="vocabularies/com.sap.cloud.server.odata.cache.v1.xml">
        <edmx:Include Namespace="com.sap.cloud.server.odata.cache.v1" Alias="Cache"/>
    </edmx:Reference>
    <edmx:Reference Uri="vocabularies/com.sap.cloud.server.odata.http.v1.xml">
        <edmx:Include Namespace="com.sap.cloud.server.odata.http.v1" Alias="HTTP"/>
    </edmx:Reference>
    <edmx:Reference Uri="vocabularies/com.sap.cloud.server.odata.jco.v1.xml">
        <edmx:Include Namespace="com.sap.cloud.server.odata.jco.v1" Alias="JCO"/>
    </edmx:Reference>
    <edmx:Reference Uri="vocabularies/com.sap.cloud.server.odata.sql.v1.xml">
        <edmx:Include Namespace="com.sap.cloud.server.odata.sql.v1" Alias="SQL"/>
    </edmx:Reference>
    <edmx:DataServices>
        <Schema Namespace="com.example.mbo" Alias="Self" xmlns="http://docs.oasis-open.org/odata/ns/edm">
            <EntityType Name="ClientRegistration">
                <Key>
                    <PropertyRef Name="ClientID"/>
                </Key>
                <Property Name="ClientID" Type="Edm.Int64" Nullable="false"/>
                <Property Name="ClientGUID" Type="Edm.Guid" Nullable="false"/>
            </EntityType>
            <EntityContainer Name="EntityContainer">
                <Annotation Term="SQL.CacheDatabase"/>
                <Annotation Term="SQL.TrackChanges"/>
                <Annotation Term="SQL.TrackDownloads"/>
                <EntitySet Name="ClientRegistrationSet" EntityType="Self.ClientRegistration"/>
            </EntityContainer>
        </Schema>
    </edmx:DataServices>
</edmx:Edmx>

Note

  1. The Windows batch file csdl-convert.bat and Mac/Linux shell script csdl-convert.sh are provided and can be used for OData CSDL version changes.
  2. The HTTP and JCo references are optional. The HTTP reference allows conversion of MBOs using REST/SOAP back ends, and the JCo reference allows conversion of SAP RFC-based back ends.
  3. The Schema Namespace can be any valid OData schema namespace. An MBO package name can be used unmodified.
  4. The EntityContainer name does not need to be "EntityContainer". It may be set to a name such as "BankService", "FlightService" etc.

Conversion of Entity Types

Each Mobile Business Object in the MBO package should be mapped to an OData CSDL EntityType within the Schema, paired with an EntitySet within the EntityContainer. Each entity relationship in the MBO package should be mapped to a bidirectional CSDL relationship, using NavigationProperty elements with Partner attributes, with one side of the relationship (the child side, holding a foreign key to the parent entity) having a suitable ReferentialConstraint.

Example:

<Schema Namespace="com.example.mbo" Alias="Self" xmlns="http://docs.oasis-open.org/odata/ns/edm">
    ...
    <EntityType Name="Customer">
        <Key>
            <PropertyRef Name="CustomerID"/>
        </Key>
        <Property Name="CustomerID" Type="Edm.Int64" Nullable="false"/>
        <Property Name="RegionID" Type="Edm.Int64" Nullable="false"/>
        <Property Name="Name" Type="Edm.String" Nullable="false" MaxLength="100"/>
        <NavigationProperty Name="Orders" Type="Collection(Self.Order)" Partner="Customer"/>
    </EntityType>
    <EntityType Name="Order">
        <Key>
            <PropertyRef Name="OrderID"/>
        </Key>
        <Property Name="OrderID" Type="Edm.Int64" Nullable="false"/>
        <Property Name="CustomerID" Type="Edm.Int64" Nullable="false"/>
        <Property Name="Product" Type="Edm.String" Nullable="false" MaxLength="100"/>
        <Property Name="Quantity" Type="Edm.Int32" Nullable="false"/>
        <NavigationProperty Name="Customer" Type="Self.Customer" Nullable="false" Partner="Orders">
            <ReferentialConstraint Property="CustomerID" ReferencedProperty="CustomerID"/>
        </NavigationProperty>
    </EntityType>
    <EntityContainer Name="EntityContainer">
        ...
        <EntitySet Name="CustomerSet" EntityType="Self.Customer">
            <NavigationPropertyBinding Path="Orders" Target="OrderSet"/>
        </EntitySet>
        <EntitySet Name="OrderSet" EntityType="Self.Order">
            <NavigationPropertyBinding Path="Customer" Target="CustomerSet"/>
        </EntitySet>
    </EntityContainer>
</Schema>

MBO attribute types should be mapped to OData property types as follows:

MBO type OData type OData notes
boolean Edm.Boolean
string Edm.String
binary Edm.Binary
byte Edm.SByte
short Edm.Int16
int Edm.Int32
long Edm.Int64
float Edm.Single
double Edm.Double
decimal Edm.Decimal
integer Edm.Decimal with Scale="0"
date Edm.Date for OData Version 2: Edm.DateTimeOffset
time Edm.TimeOfDay for OData Version 2: Edm.Time
dateTime Edm.DateTimeOffset

Conversion of Personalization Parameters

Each personalization parameter should be made into a Property within either the ClientRegistration or ClientCredentials entity type.

Any credentials that are not specific to a client user (technical user credentials for a back-end system, for instance) should not be put into ClientRegistration. Instead, such credentials should be placed in the appropriate JDBC data source configuration or HTTP/JCo destination configuration in the target execution environment (Cloud Foundry, Neo, etc).

Conversion of Synchronization Parameters

If an MBO has synchronization parameters then an additional filter entity type should be defined to store them. This additional entity type should have the base MBO name appended with "Filter" (using OData terminology) or "SynchronizationParameters" (using MBO terminology). These naming conventions are not firm requirements but will aid in the understanding of the generated OData schema.

A filter entity type should define a FilterID key property with type Edm.Int64, as well as an annotation using the SQL.ClientFilter term to indicate that the filter is client-specific. The filter entity type should also define one extra property for each value that is required to express the client's selection criteria (MBO synchronization parameters). The following filter permits a client to effectively subscribe to customer data for any number of regions (by region ID).

Example:

<EntityType Name="CustomerFilter">
    <Annotation Term="SQL.ClientFilter"/>
    <Key>
        <PropertyRef Name="FilterID"/>
    </Key>
    <Property Name="FilterID" Type="Edm.Int64" Nullable="false"/>
    <Property Name="RegionID" Type="Edm.Int64" Nullable="false"/>
    ...
</EntityType>

Conversion of Download Queries

If an MBO has a "Customized download data" query it must be converted to a SQL statement that joins (if needed) the MBO entity type with the MBO filter type. If the original customized download data query looks like this:

select x.* from Customer x where x.RegionID = :RegionID

where :RegionID represents the synchronization parameter, then the converted query, wrapped inside a SQL.DownloadQuery annotation inside the entity type, will look like this:

<EntityType Name="Customer">
    <Annotation Term="SQL.DownloadQuery">
        <String>
            select entity.* from Customer entity, CustomerFilter filter
            where entity.RegionID = filter.RegionID
        </String>
    </Annotation>
    <Property Name="CustomerID" Type="Edm.Int64" Nullable="false"/>
    <Property Name="RegionID" Type="Edm.Int64" Nullable="false"/>
    <Property Name="Name" Type="Edm.String" Nullable="false" MaxLength="100"/>
    <NavigationProperty Name="Orders" Type="Collection(Self.Order)" Partner="Customer"/>
</EntityType>

SQL aliases must be used, although they need not be named "entity" and "filter". These names are recommended, however, to aid readability of the converted queries.

See also Inherited Download Queries.

Conversion of Back-End Operations

Back-end operation calls load data from a back-end system into the cache database, and propagate client-initiated changes into the back-end system (create, update, and delete operations). Back-end operation calls can be generated from CSDL annotations, or can be implemented by custom Entity Handlers:

Conversion of Refresh Methods

Cache refreshing is pull-based (on-demand and scheduled refresh) or push-based (DCN).

Service Generation

See Generating an OData Service.

Specify the -bind option for the csdl-to-war command to indicate the target cache database. This can be specified in tasks.json.

Service Deployment

See Deploying the Generated Service.


Last update: January 25, 2022