Commit 4a8bfc53 authored by Meelad Vahdat's avatar Meelad Vahdat

- Added ServiceHelper.cs

- Added a Request and Record class for each service
- Fixed ConfigurationForm logic
- Each service now uses ServiceHelper.cs instead of having a version of it's own code
- ServiceHelper uses the Request and Record class to send and return requests.
parent 8848106b
......@@ -58,7 +58,10 @@ namespace ListwareDesktop.Framework
{"companyname", companyVariations},
{"recordid", recordIDVariations},
{"emailaddress", emailVariations},
{"phonenumber", phoneVariations}
{"phonenumber", phoneVariations},
{"a1", addressVariations},
{"a2", address2Variations},
{"postal", zipVariations}
};
}
}
......@@ -56,6 +56,8 @@ namespace ListwareDesktop.Framework
* inputRecordsFinished - If needs all records is set to true, then the GUI will set this bool to true when it has finished passing in all of the records.
*/
string endpoint { get; set; }
//Dictionary of all options and the values the user has set for them
Dictionary<string, string> serviceOptions { get; set; }
......
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json.Linq;
using System.Net;
using System.IO;
using Microsoft.Win32.SafeHandles;
using System.Runtime.InteropServices;
using System.Reflection;
using Newtonsoft.Json;
namespace ListwareDesktop.Framework
{
internal class ServiceHelper : IDisposable
{
private int[] recordID { get; set; }
bool disposed = false;
public Record[] sendRequest(string endpoint, Dictionary<string, string> serviceOptions, Record[] inputRecords, Type requestType, Type recordType)
{
this.adjustDictionary(ref serviceOptions);
JObject requestJObject = this.createInputJObject(serviceOptions, inputRecords, requestType, recordType);
JObject responseJObject = this.sendJSONPOSTRequest(endpoint, requestJObject);
return this.returnRecords(responseJObject);
}
private void adjustDictionary(ref Dictionary<string, string> serviceOptions)
{
List<string[]> tempStrList = new List<string[]>();
List<string> keysToRemove = new List<string>();
foreach (KeyValuePair<string, string> serviceOption in serviceOptions)
{
if (serviceOption.Key.Contains('_'))
{
tempStrList.Add(new [] {(serviceOption.Key.Split('_'))[0], serviceOption.Key.Split('_')[1] + ":" + serviceOption.Value});
keysToRemove.Add(serviceOption.Key);
}
}
foreach (string keyToRemove in keysToRemove)
{
serviceOptions.Remove(keyToRemove);
}
Dictionary<string, string> adjustedOptions = new Dictionary<string, string>();
foreach (string[] optionAndValue in tempStrList)
{
if (!adjustedOptions.ContainsKey(optionAndValue[0]))
{
adjustedOptions.Add(optionAndValue[0], optionAndValue[1]);
}
else
{
adjustedOptions[optionAndValue[0]] += ";" + optionAndValue[1];
}
}
foreach (KeyValuePair<string, string> adjustedOption in adjustedOptions)
{
if (!serviceOptions.ContainsKey(adjustedOption.Key))
{
serviceOptions.Add(adjustedOption.Key, adjustedOption.Value);
}
else
{
serviceOptions[adjustedOption.Key] = adjustedOption.Value;
}
}
}
private void retryOnException(int times, TimeSpan delay, Action operation)
{
var attempts = 0;
do
{
try
{
attempts++;
operation();
break;
}
catch (Exception ex)
{
if (attempts == times)
{
throw;
}
Task.Delay(delay).Wait();
}
} while (true);
}
//Method that sends JObject as a JSON POST request to the endpoint given
internal JObject sendJSONPOSTRequest(string endpoint, JObject jsonInput)
{
JObject jsonOutput;
int attempts = 0;
do
{
try
{
attempts++;
HttpWebRequest httpWebRequest;
httpWebRequest = (HttpWebRequest)WebRequest.Create(endpoint);
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "POST";
//Open StreamWriter to send request
using (StreamWriter streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
streamWriter.Write(jsonInput);
streamWriter.Flush();
streamWriter.Close();
}
//Create a web response object to get response
HttpWebResponse httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse();
//Get response with StreamReader
using (StreamReader streamReader = new StreamReader(httpWebResponse.GetResponseStream()))
{
string result = streamReader.ReadToEnd();
jsonOutput = JObject.Parse(result);
}
break;
}
catch (Exception ex)
{
if (attempts == 10)
{
throw;
}
}
} while (true);
return jsonOutput;
}
//Method that creates a JObject based on request structure, field names, and input records
private JObject createInputJObject(Dictionary<string, string> serviceOptions, Record[] inputRecords, Type requestType, Type recordType)
{
this.recordID = new int[inputRecords.Length];
this.recordID = inputRecords.Select(s => s.recordID).ToArray();
object request = Activator.CreateInstance(requestType);
foreach (KeyValuePair<string, string> serviceOption in serviceOptions)
{
this.setRequestFields(serviceOption.Key, serviceOption.Value, requestType, ref request);
}
Array records = Array.CreateInstance(recordType, inputRecords.Length);
foreach (Record inputRecord in inputRecords)
{
object record = Activator.CreateInstance(recordType);
foreach (KeyValuePair<string, string> inputFieldAndData in inputRecord.fieldAndData)
{
this.setRequestFields(inputFieldAndData.Key, inputFieldAndData.Value, recordType, ref record);
}
records.SetValue(record, Array.IndexOf(inputRecords, inputRecord));
}
this.setRequestFields("Records", records, requestType, ref request);
return JObject.FromObject(request);
}
//Method that changes JObject output from service to array of Record
private Record[] returnRecords(JObject serviceResponseJObject)
{
List<Record> tempList = new List<Record>();
JToken outputRecords = serviceResponseJObject["Records"];
int recordCounter = 0;
foreach (JToken tempToken in outputRecords.Children())
{
Record tempRecord = new Record();
foreach (JToken innerTempToken in tempToken.Children())
{
var property = innerTempToken as JProperty;
tempRecord.addField("MD_" + property.Name.ToString(), property.Value.ToString());
}
tempRecord.recordID = this.recordID[recordCounter];
recordCounter++;
tempList.Add(tempRecord);
}
//Return an array of output records
Record[] processedRecords = tempList.ToArray();
return processedRecords;
}
//Method that sets a field name of an
private void setRequestFields(string fieldName, object fieldValue, Type inputObjectType, ref object inputObject)
{
if (inputObjectType.GetProperty(fieldName) != null)
{
inputObjectType.GetProperty(fieldName).SetValue(inputObject, fieldValue);
}
}
public string[] returnProperties(Type recordType)
{
return (recordType.GetProperties()).Select(o => o.Name).ToArray();
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposed)
{
return;
}
if (disposing)
{
//Free unmanaged resources, however since we have none, do nothing
this.recordID = null;
disposed = true;
}
}
}
}
......@@ -59,6 +59,7 @@
<Compile Include="Framework\IWS.cs" />
<Compile Include="Framework\Output.cs" />
<Compile Include="Framework\Record.cs" />
<Compile Include="Framework\ServiceHelper.cs" />
<Compile Include="MainForm.cs">
<SubType>Form</SubType>
</Compile>
......
......@@ -100,8 +100,8 @@
this.aboutCreditsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.aboutMelissaToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.wikiToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.pauseButton = new System.Windows.Forms.Button();
this.gitlabToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.pauseButton = new System.Windows.Forms.Button();
this.inputFileGroupBox.SuspendLayout();
this.inputFileQualifierGroupBox.SuspendLayout();
this.inputFileDelimiterGroupBox.SuspendLayout();
......@@ -834,7 +834,6 @@
this.numberOfThreadsMenuStripTextBox.MaxLength = 2;
this.numberOfThreadsMenuStripTextBox.Name = "numberOfThreadsMenuStripTextBox";
this.numberOfThreadsMenuStripTextBox.Size = new System.Drawing.Size(100, 23);
this.numberOfThreadsMenuStripTextBox.Text = "5";
this.numberOfThreadsMenuStripTextBox.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.numberOfThreadsMenuStripTextBox_KeyPress);
//
// helpToolStripMenuItem
......@@ -851,24 +850,31 @@
// aboutCreditsToolStripMenuItem
//
this.aboutCreditsToolStripMenuItem.Name = "aboutCreditsToolStripMenuItem";
this.aboutCreditsToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
this.aboutCreditsToolStripMenuItem.Size = new System.Drawing.Size(149, 22);
this.aboutCreditsToolStripMenuItem.Text = "About Credits";
this.aboutCreditsToolStripMenuItem.Click += new System.EventHandler(this.aboutCreditsToolStripMenuItem_Click);
//
// aboutMelissaToolStripMenuItem
//
this.aboutMelissaToolStripMenuItem.Name = "aboutMelissaToolStripMenuItem";
this.aboutMelissaToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
this.aboutMelissaToolStripMenuItem.Size = new System.Drawing.Size(149, 22);
this.aboutMelissaToolStripMenuItem.Text = "About Melissa";
this.aboutMelissaToolStripMenuItem.Click += new System.EventHandler(this.aboutToolStripMenuItem_Click);
//
// wikiToolStripMenuItem
//
this.wikiToolStripMenuItem.Name = "wikiToolStripMenuItem";
this.wikiToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
this.wikiToolStripMenuItem.Size = new System.Drawing.Size(149, 22);
this.wikiToolStripMenuItem.Text = "Wiki";
this.wikiToolStripMenuItem.Click += new System.EventHandler(this.wikiToolStripMenuItem_Click);
//
// gitlabToolStripMenuItem
//
this.gitlabToolStripMenuItem.Name = "gitlabToolStripMenuItem";
this.gitlabToolStripMenuItem.Size = new System.Drawing.Size(149, 22);
this.gitlabToolStripMenuItem.Text = "Gitlab";
this.gitlabToolStripMenuItem.Click += new System.EventHandler(this.gitlabToolStripMenuItem_Click);
//
// pauseButton
//
this.pauseButton.Enabled = false;
......@@ -881,13 +887,6 @@
this.pauseButton.Visible = false;
this.pauseButton.Click += new System.EventHandler(this.pauseButton_Click);
//
// gitlabToolStripMenuItem
//
this.gitlabToolStripMenuItem.Name = "gitlabToolStripMenuItem";
this.gitlabToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
this.gitlabToolStripMenuItem.Text = "Gitlab";
this.gitlabToolStripMenuItem.Click += new System.EventHandler(this.gitlabToolStripMenuItem_Click);
//
// MainForm
//
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
......
This diff is collapsed.
This diff is collapsed.
......@@ -14,7 +14,6 @@ namespace ListwareDesktop.Services
class GlobalAddress : IWS
{
#region Global Address Options (Settings)
// IWS Interface Settings
public Dictionary<string, string> serviceOptions { get; set; }
public Dictionary<string, List<string>> settingsList { get; set; }
public String[] inputColumns { get; set; }
......@@ -27,9 +26,7 @@ namespace ListwareDesktop.Services
public bool serviceFinishedProcessing { get; set; }
public bool inputRecordsFinished { get; set; }
public Record[] outputRecords { get; set; }
// Global Address Stuff
private String AddressEndpoint = "https://address.melissadata.net/v3/WEB/GlobalAddress/doGlobalAddress";
public string endpoint { get; set; }
private List<int> recordID;
#endregion
......@@ -45,159 +42,33 @@ namespace ListwareDesktop.Services
this.serviceOptions["CustomerID"] = this.userLicense;
}
outputRecords = processRecords(createRequest(inputRecords));
}
//Get the JObject request, send and receive response
public Record[] processRecords(JObject jsonInput)
{
HttpWebRequest httpWebRequest;
//Open connection
httpWebRequest = (HttpWebRequest)WebRequest.Create(AddressEndpoint);
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "POST";
//Use JObject to create the request
JObject jsonOutputFormatted;
//Open StreamWriter to send request
using (StreamWriter streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
streamWriter.Write(jsonInput);
streamWriter.Flush();
streamWriter.Close();
}
//Create a web response object to get response
HttpWebResponse httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse();
//Get response with StreamReader
using (StreamReader streamReader = new StreamReader(httpWebResponse.GetResponseStream()))
{
string result = streamReader.ReadToEnd();
jsonOutputFormatted = JObject.Parse(result);
}
if (!String.IsNullOrEmpty(jsonOutputFormatted["TransmissionResults"].ToString().Trim()))
{
this.errorStatus = true;
this.statusMessage = jsonOutputFormatted["TransmissionResults"].ToString();
return null;
}
else
{
this.errorStatus = false;
this.statusMessage = null;
}
//Create a temporary list to add records to while we parse through the given records
List<Record> tempList = new List<Record>();
//Get output records by searching the JObject
//Parse through each token (which is each record)
//Then parse through each child token (which is the field of each record)
//We also add "MD_" to the output fields to make sure that we can tell them apart from inputs
JToken outputRecords = jsonOutputFormatted["Records"];
int recordCounter = 0;
foreach (JToken tempToken in outputRecords.Children())
using (ServiceHelper sh = new ServiceHelper())
{
Record tempRecord = new Record();
foreach (JToken innerTempToken in tempToken.Children())
{
var property = innerTempToken as JProperty;
tempRecord.addField("MD_" + property.Name.ToString(), property.Value.ToString());
}
tempRecord.recordID = this.recordID[recordCounter];
recordCounter++;
tempList.Add(tempRecord);
this.outputRecords = sh.sendRequest(this.endpoint, this.serviceOptions, inputRecords, typeof(GlobalAddressRequest), typeof(GlobalAddressRecord));
}
//Return an array of output records
Record[] processedRecords = tempList.ToArray();
return processedRecords;
}
//Create JObject request from input records
public JObject createRequest(Record[] inputRecords)
public GlobalAddress()
{
JObject jsonObjectInput = new JObject();
string options = "";
//Add all the options (basically anything that isn't a part of a contact record)
foreach (KeyValuePair<string, string> tempKVP in serviceOptions)
{
if (tempKVP.Key.Equals("DeliveryLines") || tempKVP.Key.Equals("LineSeparator") || tempKVP.Key.Equals("OutputScript") || tempKVP.Equals("OutputGeo") || tempKVP.Equals("CountryOfOrigin"))
{
options += tempKVP.Key + ":" + tempKVP.Value + ",";
}
else
{
jsonObjectInput.Add(tempKVP.Key, tempKVP.Value);
}
}
options = options.TrimEnd(',');
jsonObjectInput.Add("Options", options);
jsonObjectInput.Add("TransmissionReference", MainForm._lwdtSrc);
JArray array = new JArray();
this.endpoint = @"https://address.melissadata.net/v3/WEB/GlobalAddress/doGlobalAddress";
this.maxRecsPerRequest = 100;
this.needsAllRecords = false;
//Add records to the JObject
foreach (Record tempInputRecord in inputRecords)
using (ServiceHelper sh = new ServiceHelper())
{
JObject individualRecords = new JObject();
foreach (KeyValuePair<string, string> innerKVP in tempInputRecord.fieldAndData)
{
individualRecords.Add(innerKVP.Key, innerKVP.Value);
}
array.Add(individualRecords);
this.inputColumns = sh.returnProperties(typeof(GlobalAddressRecord));
}
//Add records to the original JObject
jsonObjectInput.Add("Records", array);
this.recordID = inputRecords.Select(s => s.recordID).ToList();
return jsonObjectInput;
}
public GlobalAddress()
{
this.needsAllRecords = false;
this.maxRecsPerRequest = 100;
this.serviceOptions = new Dictionary<string, string>();
#region settings
this.serviceOptions = new Dictionary<string, string>();
this.settingsList = new Dictionary<String, List<String>>();
settingsList.Add("LineSeparator", new List<String> { "Single", "SEMICOLON", "PIPE", "CR", "LF", "CRLF", "TAB", "BR" });
settingsList.Add("OutputScript", new List<String> { "Single", "NOCHANGE", "LATIN", "NATIVE" });
settingsList.Add("OutputGeo", new List<String> { "Single", "ON", "OFF" });
settingsList.Add("CountryOfOrigin", new List<String> { "Manual" });
settingsList.Add("Options_DeliveryLines", new List<string> { "Single", "ON", "OFF" });
settingsList.Add("Options_LineSeparator", new List<String> { "Single", "SEMICOLON", "PIPE", "CR", "LF", "CRLF", "TAB", "BR" });
settingsList.Add("Options_OutputScript", new List<String> { "Single", "NOCHANGE", "LATIN", "NATIVE" });
settingsList.Add("Options_OutputGeo", new List<String> { "Single", "ON", "OFF" });
settingsList.Add("Options_CountryOfOrigin", new List<String> { "Manual" });
#endregion
#region input
this.inputColumns = new String[]
{
"Organization",
"AddressLine1",
"AddressLine2",
"AddressLine3",
"AddressLine4",
"AddressLine5",
"AddressLine6",
"AddressLine7",
"AddressLine8",
"DoubleDependentLocality",
"DependentLocality",
"Locality",
"SubAdministrativeArea",
"AdministrativeArea",
"PostalCode",
"SubNationalArea",
"Country"
};
#endregion
#region output
this.outputColumns = new String[]
{
......@@ -248,7 +119,36 @@ namespace ListwareDesktop.Services
"Longitude"
};
#endregion
}
class GlobalAddressRequest
{
public string TransmissionReference { get; set; }
public string CustomerID { get; set; }
public string Options { get; set; }
public string Format { get; set; }
public GlobalAddressRecord[] Records { get; set; }
}
class GlobalAddressRecord
{
public string Organization { get; set; }
public string AddressLine1 { get; set; }
public string AddressLine2 { get; set; }
public string AddressLine3 { get; set; }
public string AddressLine4 { get; set; }
public string AddressLine5 { get; set; }
public string AddressLine6 { get; set; }
public string AddressLine7 { get; set; }
public string AddressLine8 { get; set; }
public string DoubleDependentLocality { get; set; }
public string DependentLocality { get; set; }
public string Locality { get; set; }
public string SubAdministrativeArea { get; set; }
public string AdministrativeArea { get; set; }
public string PostalCode { get; set; }
public string SubNationalArea { get; set; }
public string Country { get; set; }
}
}
}
......@@ -14,12 +14,8 @@ namespace ListwareDesktop.Services
internal class GlobalEmail : IWS
{
#region settings
private string geEndpoint = @"http://globalemail.melissadata.net/v3/WEB/GlobalEmail/doGlobalEmail";
//public string[][] settingsList { get; set; }
public string endpoint { get; set; }
public string[] inputColumns { get; set; }
public string[] outputColumns { get; set; }
public int maxRecsPerRequest { get; set; }
public Dictionary<string, string> serviceOptions { get; set; }
......@@ -32,7 +28,6 @@ namespace ListwareDesktop.Services
public bool errorStatus { get; set; }
public Dictionary<string, List<string>> settingsList { get; set; }
private List<int> recordID;
#endregion settings
//Send records to service and return output records
......@@ -48,123 +43,31 @@ namespace ListwareDesktop.Services
this.serviceOptions["CustomerID"] = this.userLicense;
}
outputRecords = processRecords(createRequest(inputRecords), true);
}
//Get the JObject request, send and receive response
public Record[] processRecords(JObject jsonInput, bool usRecord)
{
HttpWebRequest httpWebRequest;
//Open connection
httpWebRequest = (HttpWebRequest)WebRequest.Create(geEndpoint);
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "POST";
//Use JObject to create the request
JObject jsonOutputFormatted;
//Open StreamWriter to send request
using (StreamWriter streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
streamWriter.Write(jsonInput);
streamWriter.Flush();
streamWriter.Close();
}
//Create a web response object to get response
HttpWebResponse httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse();
//Get response with StreamReader
using (StreamReader streamReader = new StreamReader(httpWebResponse.GetResponseStream()))
using (ServiceHelper sh = new ServiceHelper())
{
string result = streamReader.ReadToEnd();
jsonOutputFormatted = JObject.Parse(result);
this.outputRecords = sh.sendRequest(this.endpoint, this.serviceOptions, inputRecords, typeof(GlobalEmailRequest), typeof(GlobalEmailRecord));
}
if (!String.IsNullOrEmpty(jsonOutputFormatted["TransmissionResults"].ToString().Trim()))
{
this.errorStatus = true;
this.statusMessage = jsonOutputFormatted["TransmissionResults"].ToString();
return null;
}
else
{
this.errorStatus = false;
this.statusMessage = null;
}
//Create a temporary list to add records to while we parse through the given records
List<Record> tempList = new List<Record>();
//Get output records by searching the JObject
//Parse through each token (which is each record)
//Then parse through each child token (which is the field of each record)
//We also add "MD_" to the output fields to make sure that we can tell them apart from inputs
JToken outputRecords = jsonOutputFormatted["Records"];
int recordCounter = 0;
foreach (JToken tempToken in outputRecords.Children())
{
Record tempRecord = new Record();
foreach (JToken innerTempToken in tempToken.Children())
{
var property = innerTempToken as JProperty;
tempRecord.addField("MD_" + property.Name.ToString(), property.Value.ToString());
}
tempRecord.recordID = this.recordID[recordCounter];
recordCounter++;
tempList.Add(tempRecord);
}
//Return an array of output records
Record[] processedRecords = tempList.ToArray();
return processedRecords;
}
//Create JObject request from input records
public JObject createRequest(Record[] inputRecords)
{
JObject jsonObjectInput = new JObject();
//Add all the options (basically anything that isn't a part of a contact record)
foreach (KeyValuePair<string, string> tempKVP in serviceOptions)
{
jsonObjectInput.Add(tempKVP.Key, tempKVP.Value);
}
jsonObjectInput.Add("TransmissionReference", MainForm._lwdtSrc);
JArray array = new JArray();
//Add records to the JObject
foreach (Record tempInputRecord in inputRecords)
{
JObject individualRecords = new JObject();
foreach (KeyValuePair<string, string> innerKVP in tempInputRecord.fieldAndData)
{
individualRecords.Add(innerKVP.Key, innerKVP.Value);
}
array.Add(individualRecords);
}
//Add records to the original JObject
jsonObjectInput.Add("Records", array);
this.recordID = inputRecords.Select(s => s.recordID).ToList();
return jsonObjectInput;
}
public GlobalEmail()
{
this.endpoint = @"http://globalemail.melissadata.net/v3/WEB/GlobalEmail/doGlobalEmail";
this.maxRecsPerRequest = 10;
this.needsAllRecords = false;
this.serviceOptions = new Dictionary<string, string>();
#region Service Settings
using (ServiceHelper sh = new ServiceHelper())
{
this.inputColumns = sh.returnProperties(typeof(GlobalEmailRecord));
}
#region Service Settings
this.serviceOptions = new Dictionary<string, string>();
this.settingsList = new Dictionary<string, List<string>>();