Fresh off the heels of SPC, I’m in Vienna at the annual SAP TechEd conference. We wanted to attend this conference for a couple of reasons. First, the curtains have lifted on Office and SharePoint 2010 so we can now get out there and show it, talk about the innards, and get developers excited about it. Second, whenever you talk about OBAs SAP is top-of-mind for me. It represents a great opportunity for integrating Office and SharePoint with SAP to enhance the IW experience; it represents a major piece of the quintessential OBA. For example, if you check out the architecture below (yes, very high-level), you’ll see that for the developer there are a number of entry points for building OBAs that integrate with SAP. This is no different from any other OBA: you can use Silverlight and integrate with SharePoint; you can create custom web parts; using the BCS you can now create read/write lists called External Lists (read/write into the SAP back-end); you can extend the client UI to create add-ins or doc-level solutions; and you can also leverage Open XML to manage SAP data into and out of documents. Very powerful stuff.

I will admit that the below is not all-encompassing when it comes to integrating SAP with Office and SharePoint; it is a starting point for programmatically tying the technologies together. (As an alternate to building, you can go the buy route and implement the partner solution between MS and SAP called Duet: http://www.duet.com/.) You can also use the SharePoint iView, Business Server Pages, and CMIS for example. However, if you want to architect and design your OBA from the ground up, you’d be looking at this type of architecture to build that solution.  Of note in the services layer are the fact that you as the developer have options. For example, you can leverage the WS* standards, use the BizTalk LOB adapters to implement your connection as a WCF-based integration, or you can also use BCS, which adds the value of supporting an offline story.

image 

I’ve talked about BCS in a previous post, but will spend a few posts on this as to me this seems like a really promising technology. For example, you can create what’s called an External Content Type (ECT)—the successor to the application definition file in SharePoint 2007, and then use the ECT to load external data into SharePoint. The interesting thing here is the fact that you can build service-based ECTs, so the BCS works as a higher-level layer to ASMX or WCF (the other service entry points in SAP) or other adaptors that are service-based. And simply put, the ECT is a metadata file—an XML file that defines the relationship your application has with the external data source. See below for a very simple ECT:

<?xml version="1.0" encoding="utf-8"?>

<Model xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.microsoft.com/windows/2007/BusinessDataCatalog" Name="BusinessDataCatalog1">

<LobSystems>

<LobSystem Name=“HelloWorld" Type="DotNetAssembly">

<LobSystemInstances>

<LobSystemInstance Name=“HelloWorldInstance1" />

</LobSystemInstances>

<Entities>

<Entity Name="Product" Namespace="ProductModel.BusinessDataCatalog1" EstimatedInstanceCount="1000" Version="1.0.0.13">

<Properties>

<Property Name="Class" Type="System.String">ProductModel.BusinessDataCatalog1.ProductService, HelloWorld</Property>

</Properties>

<Identifiers>

<Identifier Name="ID" TypeName="System.String" />

</Identifiers>

<Methods>

<Method Name="FindAllEntities">

<Parameters>

<Parameter Direction="Return" Name="returnParameter">

<TypeDescriptor TypeName="System.Collections.Generic.IEnumerable1[[ProductModel.BusinessDataCatalog1.Entity1, HelloWorld]]" IsCollection="true" Name="Entity1List">

<TypeDescriptors>

<TypeDescriptor TypeName="ProductModel.BusinessDataCatalog1.Entity1, HelloWorld" Name="Entity1">

<TypeDescriptors>

<TypeDescriptor TypeName="System.String" IdentifierName="ID" Name="ID" />

<TypeDescriptor TypeName="System.String" Name="Manufacturer" />

<TypeDescriptor Name="Name" TypeName="System.String" />

</TypeDescriptors>

</Parameter>

</Parameters>

<MethodInstances>

<MethodInstance Type="Finder" ReturnParameterName="returnParameter" Default="true" Name="FindAllEntities" DefaultDisplayName="Entity1 List" />

</MethodInstances>

</Method>

</Methods>

</Entity>

</Entities>

</LobSystem>

</LobSystems>

</Model>

BCS also comes with its own API, so you could use the ECT to load SAP data (which supports CRUD operations). If you’re not realizing this is big already, BCS also has an offline story. So, you can effectively create a symmetrical entity relationship across server and client. You’re probably asking how, right?

If you look at the diagram below, you’ll see that if you move from the left to the right you need to do a few things to get an OBA working using the BCS. Starting from the left, you first need to have your external system up and running. For SAP, this would mean, for example, having a BAPI in place and then creating a web service wrapper to that business object using the native SAP developer workbench. Second, once you’ve got your service you can use tools like SharePoint Designer 2010 to create the ECT (you create the ECT with multiple operations that are each configured against the web methods within your service connection, e.g. GetAllFlights would be a read operation and UpdateSpecificFlightData would be an update operation). You can also create the External List directly from within SharePoint Designer, which results in your read/write SharePoint list.

image

Once you’ve created the External List, you can do one of two things: you can code against it on the server or you can take it offline and create a client-side integration. The below is an example of where we’ve coded against the BCS API using Silverlight and then added the Silverlight apps as a web part in SharePoint. The interesting thing about the example below is that the data is aggregated from multiple data sources—yet to your user the experience is seamless across the two data sources.

image

Okay, since we’re now through step 3 we can move onto step 4, which is where we can begin coding against the client-side cache of the data (when you take the data offline, you essentially are creating an offline cache of the data). For example, the following code sample gets all of the entities you’ve taken offline and loads them into a listbox so the user can choose from them. In reality, you could use the catalog object to get a specific entity and pass the * parameter to get them all.

private void getLOBEntities(object sender, EventArgs e)

{

RemoteSharePointFileBackedMetadataCatalog catalog = new RemoteSharePointFileBackedMetadataCatalog();

INamespaceEntityDictionaryDictionary entDictAll = catalog.GetEntities(“*”);

foreach (INamedEntityDictionary entDict in entDictAll.Values)

{

   foreach(IEntity entity in entDict.Values)

     {

         myListBox.Items.Add(entity.Name);

     }

}

}

The result of the client-side coding exercise is very compelling: you have Office add-ins that can interact with the client-side cache of the data. Users can work from within their Office applications and interact with the data offline. What pushes the data back to the server is a BCSSync (essentially a listener service) that listens for and queues changes on the client and then pushes those changes to the server. The final step would be to deploy the add-in on the client using the ClickOnce deployment method (or other supported method).

Overall, I see the BCS reflecting some serious value—especially when you look at the ability for it to tie into a service layer. While this is especially relevant this week as I’m attending SAP TechEd, it’s also very relevant to other LOB systems as well (e.g. Siebel, PeopleSoft, Dynamics, and so on). Essentially, create a service and you can connect the BCS to it and create your OBA.

Okay, more to come soon.

Steve