MIM 2016: Workday C# ECMA Connector

Creating an ECMA connector

I am not going to discuss how to create an ECMA connector, I think I have rehashed that topic in various blogposts, I am going to assume that you know your Visual Studio and you have created an ECMA connector before. If you haven’t, here is a blogpost I did on the creation of a generic ECMA connector. I will be talking mostly about reading Workday data. Brief mention about write-back.

Pre-work

Workday Admin needs to

  1. Create an account in Workday for MIM.
  2. Give the account the necessary permissions to read and write data. See this article.
  3. For write-back the MIM account should be given rights to Workday process that will be called on via the api function.

Reading Workday data

There are two primary ways to read data from Workday.

Via WSDL

You can download the Workday WSDL from here. Get the Human_Resources WSDL from here. Click on the WSDL link and down the file, name it “Human_Resources.cs”. Add it to your ECMA visual studio solution, you will reference functions in the code. If you use this method, you will have to

  1. Read all the user data into a collection via the SOAP Webservice.
  2. Iterate through the collection and apply business rules to the users. E.g if employeeStatus says “Leave of Absence” then write “InActive” to your CS object.

The disadvantage of this method is that if there are any changes to your business rules then the MIM code has to be amended and recompiled.

Via Custom Report

In this case the Workday Admin will publish a report in Workday and give the MIM account rights to the report. Within the report config there are various options for how MIM can access the report, Next go to the Actions>Web Service>View URLs. I use the SimpleXML

The advantage of the custom report is that it gives the Workday Admin complete control on the business rules that govern the data so that if there is a change to the business rules it can be implemented by the Workday Admin and would not require a MIM code change and recompile.

The Code

Lets get into the code.

Via WSDL

I have several WSDLs and I must say the Workday WSDL is one of the most intriguing. That’s a kind way of say is not so straight forward. I will do my best to explain it. Create a WSDL proxy client to the Webservice. Then use that client to pull the user data. For purpose of this post, I will only take Active users.

Create WSDL proxy client

  1. public static Human_ResourcesPortClient CreateHumanResourcesProxy()  

  2. {  

  3.     SecurityBindingElement sb = SecurityBindingElement.CreateUserNameOverTransportBindingElement();  

  4.     sb.IncludeTimestamp = false;  

  5.     const int lim = Int32.MaxValue;  

  6.     var timeout = TimeSpan.FromMinutes(2);  

  7.     var cb = new CustomBinding(  

  8.         sb,  

  9.         new TextMessageEncodingBindingElement(MessageVersion.Soap11, Encoding.UTF8)  

  10.         {  

  11.             ReaderQuotas = new XmlDictionaryReaderQuotas  

  12.             {  

  13.                 MaxDepth = lim,  

  14.                 MaxStringContentLength = lim,  

  15.                 MaxArrayLength = lim,  

  16.                 MaxBytesPerRead = lim,  

  17.                 MaxNameTableCharCount = lim  

  18.             }  

  19.         },  

  20.         new HttpsTransportBindingElement  

  21.         {  

  22.             MaxBufferPoolSize = lim,  

  23.             MaxReceivedMessageSize = lim,  

  24.             MaxBufferSize = lim,  

  25.             Realm = string.Empty  

  26.         })  

  27.     {  

  28.         SendTimeout = timeout,  

  29.         ReceiveTimeout = timeout  

  30.     };  

  31.   ServicePointManager.Expect100Continue = true;  

  32.             ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;  

  33.     var proxy = new Human_ResourcesPortClient(cb, new EndpointAddress(https://wd2-impl-services1.workday.com/ccx/service/{tenantID}/Human_Resources”));  

  34.     proxy.ClientCredentials.UserName.UserName = “{username@tenantID}”;  

  35.     proxy.ClientCredentials.UserName.Password = “{password}”;  

  36.     return proxy;  

  37. }  

Get the Work data with the Client

  1. public static WorkerType GetWorker(string empId)  

  2.         {  

  3.             var request = new Get_Workers_RequestType { version = “v31.0” };    

  4.             var workerId = new WorkerObjectIDType()  

  5.             {  

  6.                 type = “Employee_ID”,  

  7.                 Value = empId  

  8.             };    

  9.             var idTypes = new List<WorkerObjectIDType> { workerId };    

  10.    request.Request_References = new Worker_Request_ReferencesType { Worker_Reference = new WorkerObjectType[1] { new WorkerObjectType() } };  

  11.             request.Request_References.Worker_Reference[0].ID = idTypes.ToArray();    

  12.             request.Request_Criteria = new Worker_Request_CriteriaType  

  13.             {  

  14.                 Exclude_Inactive_Workers = true,  

  15.                 Exclude_Inactive_WorkersSpecified = true  

  16.             };  

  17.             var proxy = CreateHumanResourcesProxy();  

  18.             Get_Workers_ResponseType response = null;  

  19.             try  

  20.             {  

  21.               response = proxy.Get_Workers(new Workday_Common_HeaderType(),  request); 

  22.             }  

  23.             catch (FaultException fe)  

  24.             {                    

  25.                 return null;  

  26.             }  

  27.             return response.Response_Data.FirstOrDefault();  

  28.         }  

Via Custom Reports

The Xml looks like this

Open a Connection and use HttpWebrequest to get the data

  1. // Connect to Workday to get the report  

  2.             // Create the web request  

  3.             ServicePointManager.Expect100Continue = true;  

  4.             ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;  

  5.             String encoded = System.Convert.ToBase64String(System.Text.Encoding.GetEncoding(“ISO-8859-1”).GetBytes(WorkDayUsername + “:” + WorkDayPassword));  

  6.             HttpWebRequest request = WebRequest.Create(this.WorkdayReportPath) as HttpWebRequest;  

  7.             request.Headers.Add(“Authorization”“Basic “ + encoded);    

  8.             // Retrieve all the TLK Users from the report.  

  9.             // Get response    

  10.             using (HttpWebResponse response = request.GetResponse() as HttpWebResponse 

  11.             {  

  12.                 //load data into dataset  

  13.                 DataSet da = new DataSet();  

  14.                 da.ReadXml(response.GetResponseStream());  

  15.                 foreach (DataRow user in da.Tables[“Report_Entry”].Rows)  

  16.                 {  

  17.                   //Iterate through the data and add to CS  

  18.                 }  

Notice that I use this in both Code

  1. ServicePointManager.Expect100Continue = true;  

  2.             ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;  

This is because Workday rejects TLS1 and below.