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 withfind /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
- The Windows batch file
csdl-convert.bat
and Mac/Linux shell scriptcsdl-convert.sh
are provided and can be used for OData CSDL version changes. - 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.
- The Schema Namespace can be any valid OData schema namespace. An MBO package name can be used unmodified.
- 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:
-
For conversion of HTTP back-end operations (REST, SOAP), see Entity Handlers for HTTP Destinations.
-
For conversion of RFC back-end operations, see Entity Handlers for RFC Destinations.
-
For conversion of SQL back-end operations, see Entity Handlers for SQL Destinations.
Conversion of Refresh Methods¶
Cache refreshing is pull-based (on-demand and scheduled refresh) or push-based (DCN).
-
For conversion of on-demand and scheduled refresh, see When to Refresh.
-
For conversion of Data Change Notification (DCN), see Data Change Notification.
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.