Creación de External Data Source en Salesforce mediante un servicio OData en .Net
Salesforce permite acceder a fuentes de datos externas (external data sources) usando el protocolo OData. Esta característica es una de las más útiles a la hora de diseñar una estrategia de integración con sistemas terceros. En cambio de usar servicios web o el DataLoader para meter datos en Salesforce, es posible obtener información actualizada directamente desde sistemas terceros mediante el uso de fuentes de datos externos. Mediante el uso de estas fuentes de datos externos, y los objetos externos que se crean, podemos obtener información localizada fuera de Salesforce como si ésta estuviera dentro de Salesforce. La única desventaja, por el momento, es que una fuente de datos externos es de solo lectura, no podemos usarlo para actualizar datos en sistemas terceros. Pero de todas maneras, esto abre un gran abanico de posibilidades de integración.
Veamos un ejemplo donde esto puede resultar de utilidad. Recientemente trabajé en un proyecto donde se requería una integración entre Salesforce y el ERP. Los ejecutivos de ventas necesitaban tener acceso a alertas administrativas (por ejemplo “el cliente tiene facturas pendientes”, o “el cliente tiene un reclamo en su última factura”, etc.) en Salesforce. Estas alertas eran generadas en el ERP por los usuarios administrativos. Claramente necesitábamos poner estas alertas en Salesforce.
Una posible solución sería usar el DataLoader para subir las alertas en batch en Salesforce, con una frecuencia predefinida (una vez al día por ejemplo). Esta solución es rápida y fácil, pero requiere muchos pasos: crear un objeto Alertas en Salesforce, configurar la línea de comandos del DataLoader para obtener directamente del ERP los datos y realizar un “upsert” en Salesforce, y el uso de un programa para agendar la ejecución del DataLoader a intervalos regulares. Pero resulta que ¡hay una forma más fácil! Bueno, fácil si lees este articulo 🙂
En vez de meter los datos en Salesforce, haremos que Salesforce obtenga los datos dinámicamente del ERP. Para esto usaremos una fuente de datos externos y crearemos objetos externos. Es posible crear una fuente de datos externos basada en OData (desafortunadamente solo versión 2.0, aunque al momento de escribir este artículo OData se encuentra en versión 4.0). Veamos cómo podemos usar Visual Studio y .Net para exponer los datos el ERP.
Configuración del Ejemplo
Usaré un ejemplo sencillo. Voy a similar el ERP como una base de datos SQLServer. Tendremos una tabla para cuentas (clientes) y una tabla de alertas que contiene las alertas de nuestros clientes. Nuestro ERP es el siguiente:
Puedes usar el siguiente script para crear la BD y las tablas:
/****** Object: Database [ERP] Script Date: 12/30/2014 17:22:48 ******/ CREATE DATABASE [ERP] ON PRIMARY ( NAME = N'ERP', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL10_50.MSSQLSERVER\MSSQL\DATA\ERP.mdf' , SIZE = 3072KB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB ) LOG ON ( NAME = N'ERP_log', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL10_50.MSSQLSERVER\MSSQL\DATA\ERP_log.ldf' , SIZE = 1024KB , MAXSIZE = 2048GB , FILEGROWTH = 10%) GO USE [ERP] /****** Object: Table [dbo].[Account] Script Date: 12/30/2014 17:22:49 ******/ CREATE TABLE [dbo].[Account]( [id] [int] IDENTITY(1,1) NOT NULL, [name] [varchar](50) NOT NULL, CONSTRAINT [PK_Account] PRIMARY KEY CLUSTERED ( [id] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO /****** Object: Table [dbo].[Alert] Script Date: 12/30/2014 17:22:49 ******/ CREATE TABLE [dbo].[Alert]( [id] [int] IDENTITY(1,1) NOT NULL, [accountId] [int] NOT NULL, [alertText] [varchar](50) NULL, CONSTRAINT [PK_Alert] PRIMARY KEY CLUSTERED ( [id] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO SET ANSI_PADDING OFF GO /****** Object: ForeignKey [FK_Alert_Account] Script Date: 12/30/2014 17:22:49 ******/ ALTER TABLE [dbo].[Alert] WITH CHECK ADD CONSTRAINT [FK_Alert_Account] FOREIGN KEY([accountId]) REFERENCES [dbo].[Account] ([id]) GO ALTER TABLE [dbo].[Alert] CHECK CONSTRAINT [FK_Alert_Account] GO
Y poblar la base de datos con la siguiente secuencia de comandos:
insert into Account values('ModicaTech') insert into Account values('Microsoft') insert into Account values('Salesforce') insert into Alert values(1,'Client requesting support') insert into Alert values(2,'Client has pending receipts')
Creación del Servicio Web OData
Using Visual Studio 2013 Community Edition, y crearemos un proyecto de tipo “empty ASP.Net Web”. Agregaremos un modelo de datos de Entity Framework a este proyecto.
Pincha con el botón derecho del ratón sobre el nombre del proyecto y selecciona “Add New Item”. Selecciona “ADO.ET Entity Data Model” y llámalo ErpModel.
En el wizard de Entity Data Model Wizard, selecciona “EF Designer from database” y pincha en “Next”. Crea una nueva conexión al SQLServer donde estamos simulando el ERP:
Pincha en “Next” y asegúrate de seleccionar “Entity Framework 5.0” para la versión de Entity Framework a utilizar, y luego pincha en “Next”. Selecciona ambas tablas:
Pincha en “Finish”. El wizard generará el código para conectarse a la base de datos. Ahora agregaremos un servicio OData al proyecto. Pincha con el botón derecho del ratón sobre el nombre del Proyecto y selecciona “Add New Item…”. Selecciona “WCF Data Service 5.6” y llámalo ErpService.svc :
El wizard creará el archivo ErpService.svc.cs y lo abrirá en el editor. Reemplaza el texto del TODO por el nombre de nuestra entidad de datos. El archivo debería ser como el siguiente:
using System; using System.Collections.Generic; using System.Data.Services; using System.Data.Services.Common; using System.Linq; using System.ServiceModel.Web; using System.Web; namespace ErpODataService { public class ErpService : DataService<ERPEntities> { // This method is called only once to initialize service-wide policies. public static void InitializeService(DataServiceConfiguration config) { config.SetEntitySetAccessRule("*", EntitySetRights.AllRead); // config.SetServiceOperationAccessRule("MyServiceOperation", ServiceOperationRights.All); config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2; } } }
En la línea 11 se especifica el nombre de nuestra entidad de datos. En la línea 16 se especifica el acceso de solo lectura para todas las entidades. Finalmente, en la línea 18 se especifica que la versión de OData a utilizar es la 2.0 (la requerida por Salesforce). Si ahora se ejecuta el proyecto se debería ver algo como esto:
Hay que publicar el servicio web en internet. Yo lo he publicado en un servidor IIS en la DMZ con el URL https://grupolanka.com/Salesforce/ErpODataService/ErpService.svc (no intentes probarlo, no funcionará).
Creación de la Fuente de Datos Externos en Salesforce
En Salesforce, dirígete a “Configuración->Compilación->Desarrollo->External Data Sources” y pincha en el botón “Nueva External Data Source”. Introduce una etiqueta y un nombre y asegúrate de seleccionar “Lighting Connect: OData 2.0” como el tipo. En el campo “URL del servidor” coloca el URL del servicio OData creado anteriormente, y en el campo “Formato” selecciona AtomPub. Usaremos la identificación anónima ya que no hemos especificado ningún protocolo de seguridad en nuestro servicio OData (por simplicidad). La fuente de datos externa debería ser como sigue:
Al guardarla pincha en el botón de “Validar y Sincronizar”:
Selecciona el objeto Alerts y pincha en el botón “Sync”. Salesforce creará el objeto Alerts__x. Pincha en el nuevo objeto para ver sus propiedades:
Ahora pasaremos a crear la relación entre este objeto externo y el objeto Cuenta para enlazar las alertas a las cuentas. Pero antes necesitamos crear un nuevo campo personalizado en el objeto Cuenta y marcarlo como id externo para así poder realizar el enlace. Dirígete a “Configuración->Compilación->Personalizar->Cuentas->Campos“ y en la sección “Relaciones y campos personalizados de cuenta” crea un nuevo campo personalizado llamado External_ID. Asegúrate de marcarlo como “Exclusiva” and “Id. Externo”:
Regresa al objeto externo Alerts (“Configuración->Compilación->Desarrollo->Objetos externos”). En la sección de “Relaciones y campos personalizados” pincha en “Nuevo”. Selecciona “Relación de búsqueda indirecta” como el tipo de datos del campo. A continuación selecciona Cuenta en el campo “Relacionado con”:
Pincha en “Siguiente”. En el campo “Campo de destino” selecciona el campo personalizado creado anteriormente (External_ID__c)
Pincha en “Siguiente”. Introduce la etiqueta y el nombre del campo. Asegúrate de especificar accountId como el “Nombre de columna externa”. Este es el campo en la fuente de datos externos que contiene la clave foránea a la cuenta.
Pincha en “Siguiente” para el resto del wizard.
Ahora necesitamos crear una Ficha para el nuevo objeto y agregarla a una aplicación. Dirígete a “Configuración->Compilación->Crear->Fichas” and y crea una nueva ficha para el objeto Alerts. Selecciona un tema. Luego asigna la ficha a una aplicación. Deberías poder ver algo como lo siguiente:
Pincha uno de los registros para ver el detalle:
Visualizar los Datos Externos en un Objeto de Salesforce
A continuación, vamos a abrir una cuenta (cualquier cuenta). Coloca un valor para el campo de “External Id”. Usa 1 para el valor de manera que podamos ver las alertas asociadas a la cuenta con identificador 1
Es necesario editar el formato de la lista relacionada para mostrar el campo alertText.
¡Listo! Podemos ver dinámicamente los datos del ERP en Salesforce. Hagamos una prueba. Inserta una nueva alerta para la cuenta con identificador 1:
insert into Alert values(1,'This thing works!')
Refresca la cuenta en Salesforce, y deberías poder ver la nueva alerta:
La versión original de este articulo ha sido publicada en http://www.giovannimodica.com/
Grupo Lanka es partner certificado para Salesforce España.
Estimado, que puedo decir, me sirvió mucho tu post sobre el tema de fuentes externas, una cosa tan simple que no había visualizado el tema de la versión del OData soportado y no funcaba mi conexión…espero seguir viendo más de estos post amigo… saludos y un abrazo desde Chile
Gracias Hector por tu visita a nuestro blog. Nos alegra saber que hemos podido ayudarte.
Hasta pronto.