Skip to main content

Developing MEP Connectors - Part III

Posted by spericas on October 1, 2008 at 7:09 AM PDT

In the two installments of this series we've looked at the architecture of a MEP connector, discussed the main abstractions of the ECBO (Enterprise Connector Business Object) API and showed an example of a MusicAlbum business object. In this third part, we'll focus on the MusicAlbumProvider class which is needed to complete the implementation of the connector to access music albums from a JDBC database.

The complete source code for the MusicDB enterprise connector is included in the MEP client bundle available for download here. In the directory where you unzipped the client bundle, look for it under sjsmep-client-1_0-fcs/samples/ecbo/.

As explained earlier in this series, the ECBO API provides two essential abstractions: BusinessObject and BusinessObjectProvider. Due to the nature of the synchronization process, every enterprise connector must provide the ability to CRUD (create, retrieve, update and delete) business objects. The BusinessObject abstraction provides support for CUD, i.e. each object provides the ability to create, update and delete itself as shown in Part II. The R operation, or retrieve, is implemented by the BusinessObjectProvider. Here is the implementation of the R operation in MusicAlbumProvider, a class extending BusinessObjectProvider.

    @Override
    public List<MusicAlbum> getBusinessObjects() {
        Statement stmt = null;
        List<MusicAlbum> albums = null;
       
        try {
            stmt = sqlConnection.createStatement();
           
            // Read all music albums and store them in array
            albums = new ArrayList<MusicAlbum>();
            ResultSet rs = stmt.executeQuery(
                    "SELECT * FROM album WHERE username = '" + username + "'");
            while (rs.next()) {
                MusicAlbum album = new MusicAlbum(this);
                album.setName(rs.getString(1));
                album.setArtist(rs.getString(2));
                album.setDatePublished(rs.getString(3).replace("-", ""));
                album.setRating(rs.getInt(4));
                albums.add(album);
            }
            rs.close();
        } catch (Exception ex) {
            throw new RuntimeException(ex);
        } finally {
            if (stmt != null) {
                try { stmt.close(); } catch (Exception e) { /* ignore !*/ }
            }
        }       
        return albums;
    }

The getBusinessObjects() method simply queries the database for all albums that are owned by the user that logged in into the connector and returns them as a List.

In addition to providing support for the R operation, a business object provider being the entry point to the connector, should also provide implementations for the lifecycle methods initialize() and terminate(). These methods are called at the beginning and at the end of a synchronization session. In most connectors, these methods are used to connect to and disconnect from an enterprise system; in the MusicDB connector, in particular, they are used to connect and disconnect from the database as shown below.

    @Override
    public void initialize() {
        try {
            Context jndiContext = new InitialContext();
            DataSource ds = (DataSource) jndiContext.lookup(MUSICDB_JNDI_DATASOURCE);
            sqlConnection = ds.getConnection();
        } catch (Exception ex) {
            throw new RuntimeException(ex);
        }
    }

    @Override
    public void terminate() {
        try {
            if (sqlConnection != null) {
                sqlConnection.close();
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

Contextual information related to the active synchronization session (e.g., session id or user logged in) can be access via calling getSessionContext(). Finally, each connector may define its own transaction manager by overriding the method getTransactionManager(). For more information on these features, the reader is referred to the MEP online documentation.

If you're interested in developing a MEP connector, I suggest that you start by using Maven's MEP Connector Archetype (JAR). If you're a Netbeans user, simply go to File -> New Project -> Maven -> Maven Project and select it from the list. Happy synching!

Related Topics >>

Comments

Hello Santiago, Does that: "Contextual information related to the active synchronization session (e.g., session id or user logged in) can be access via calling getSessionContext(). Finally, each connector may define its own transaction manager by overriding the method getTransactionManager(). For more information on these features, the reader is referred to the MEP online documentation." Means that the synch process "hits" the backend each time a device syncs? That would be a performance killer for enterprise applications... Julien.

Julien, Yes, all the data is stored in the back-end. You need to hit the back-end to know what has changed. Duplicating (caching) data in the gateway opens a whole different kind of worms (stale data, database duplication, data sharing between carrier and enterprise in 2-tier deployments, etc.). Hope this helps.

Julien, I guess it all depends how you access the back-end. We have samples running against Siebel, SAP and Remedy and the latency is quite reasonable for all of them. In the order of seconds in all cases. Thanks.

Thanks for the answers. It opens a different can of worms. The backend is not always a database and querying on enterprise software is costly (for example querying business partners on SAP systems with particular filtering attribute takes as much as 5 min.) Not preparing the data upfront means that the perceived sync time for the user will be greater. It is true that the final design will be more trivial and less prone to errors but will lead to performance drops in some heavy use scenarios... Thank you! Julien. http://www.msc-mobile.com