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
- Create an account in Workday for MIM.
- Give the account the necessary permissions to read and write data. See this article.
- 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
- Read all the user data into a collection via the SOAP Webservice.
- 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
-
public static Human_ResourcesPortClient CreateHumanResourcesProxy()
-
{
-
SecurityBindingElement sb = SecurityBindingElement.CreateUserNameOverTransportBindingElement();
-
sb.IncludeTimestamp = false;
-
const int lim = Int32.MaxValue;
-
var timeout = TimeSpan.FromMinutes(2);
-
var cb = new CustomBinding(
-
sb,
-
new TextMessageEncodingBindingElement(MessageVersion.Soap11, Encoding.UTF8)
-
{
-
ReaderQuotas = new XmlDictionaryReaderQuotas
-
{
-
MaxDepth = lim,
-
MaxStringContentLength = lim,
-
MaxArrayLength = lim,
-
MaxBytesPerRead = lim,
-
MaxNameTableCharCount = lim
-
}
-
},
-
new HttpsTransportBindingElement
-
{
-
MaxBufferPoolSize = lim,
-
MaxReceivedMessageSize = lim,
-
MaxBufferSize = lim,
-
Realm = string.Empty
-
})
-
{
-
SendTimeout = timeout,
-
ReceiveTimeout = timeout
-
};
-
ServicePointManager.Expect100Continue = true;
-
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
-
var proxy = new Human_ResourcesPortClient(cb, new EndpointAddress(“https://wd2-impl-services1.workday.com/ccx/service/{tenantID}/Human_Resources”));
-
proxy.ClientCredentials.UserName.UserName = “{username@tenantID}”;
-
proxy.ClientCredentials.UserName.Password = “{password}”;
-
return proxy;
-
}
Get the Work data with the Client
-
public static WorkerType GetWorker(string empId)
-
{
-
var request = new Get_Workers_RequestType { version = “v31.0” };
-
var workerId = new WorkerObjectIDType()
-
{
-
type = “Employee_ID”,
-
Value = empId
-
};
-
var idTypes = new List<WorkerObjectIDType> { workerId };
-
request.Request_References = new Worker_Request_ReferencesType { Worker_Reference = new WorkerObjectType[1] { new WorkerObjectType() } };
-
request.Request_References.Worker_Reference[0].ID = idTypes.ToArray();
-
request.Request_Criteria = new Worker_Request_CriteriaType
-
{
-
Exclude_Inactive_Workers = true,
-
Exclude_Inactive_WorkersSpecified = true
-
};
-
var proxy = CreateHumanResourcesProxy();
-
Get_Workers_ResponseType response = null;
-
try
-
{
-
response = proxy.Get_Workers(new Workday_Common_HeaderType(), request);
-
}
-
catch (FaultException fe)
-
{
-
return null;
-
}
-
return response.Response_Data.FirstOrDefault();
-
}
Via Custom Reports
The Xml looks like this
Open a Connection and use HttpWebrequest to get the data
-
// Connect to Workday to get the report
-
// Create the web request
-
ServicePointManager.Expect100Continue = true;
-
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
-
String encoded = System.Convert.ToBase64String(System.Text.Encoding.GetEncoding(“ISO-8859-1”).GetBytes(WorkDayUsername + “:” + WorkDayPassword));
-
HttpWebRequest request = WebRequest.Create(this.WorkdayReportPath) as HttpWebRequest;
-
request.Headers.Add(“Authorization”, “Basic “ + encoded);
-
// Retrieve all the TLK Users from the report.
-
// Get response
-
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse
-
{
-
//load data into dataset
-
DataSet da = new DataSet();
-
da.ReadXml(response.GetResponseStream());
-
foreach (DataRow user in da.Tables[“Report_Entry”].Rows)
-
{
-
//Iterate through the data and add to CS
-
}
Notice that I use this in both Code
-
ServicePointManager.Expect100Continue = true;
-
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
This is because Workday rejects TLS1 and below.