Usage:
public class RESTServiceBL
{
public Response<List<TServiceModel>> CallRESTService<TServiceModel>(RESTServiceRequest request)
{
return Integrator.GetData<TServiceModel>(request, Enums.DataRequestTypes.RESTService);
}
}
using Fnx.Ambulatory.Data.Sql.Actions;
using Fnx.Ambulatory.Data.Sql.Contexts;
using Fnx.Ambulatory.Entities.Domain.DataEntities;
using Fnx.Ambulatory.Entities.Transfer.Request;
using Fnx.Ambulatory.Entities.Transfer.Response;
using Fnx.Ambulatory.Infrastructure.Common;
using Fnx.Ambulatory.Infrastructure.Common.Types;
using Newtonsoft;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Phoenix.CommonUtils;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data;
using System.Data.Entity;
using System.IO;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Text;
namespace Fnx.Ambulatory.Data.Integrator
{
public static class Integrator
{
public static Response<List<T>> GetData<T>(object parameter, Enums.DataRequestTypes requestType)
{
Response<List<T>> response = new Response<List<T>>();
switch (requestType)
{
case Enums.DataRequestTypes.Database:
Enums.DatabaseDataRequestTypes databaseRequestType;
AmbulatoryRequestActions ambulatoryRequestAction = new AmbulatoryRequestActions();
Enum.TryParse<Enums.DatabaseDataRequestTypes>(parameter.ToString(), out databaseRequestType);
switch (databaseRequestType)
{
//TODO - all the implementation for obtaining data from the DB...
case Enums.DatabaseDataRequestTypes.GetTable:
AmbulatoryBaseContext db = new AmbulatoryBaseContext();
Type type = typeof(AmbulatoryBaseContext);
List<PropertyInfo> properties = type.GetProperties(BindingFlags.Public).ToList();
Type t = properties.Find(property => property.PropertyType.Name == typeof(T).Name).PropertyType;
// MethodInfo method = t.GetMethod("GenericMethod");
// MethodInfo generic = method.MakeGenericMethod(myType);
// generic.Invoke(this, null);
// data = db.AmbulatoryRequests.ToList<type>();
// //data = //dbContext as IEnumerable<AmbulatoryRequest>;
break;
}
//response.Data = data as List<AmbulatoryRequest>;
break;
case Enums.DataRequestTypes.RESTService:
response = CallRESTService<T>(parameter as RESTServiceRequest);
break;
case Enums.DataRequestTypes.SOAPService:
break;
}
return response;
}
private static Response<List<TServiceModel>> CallRESTService<TServiceModel>(RESTServiceRequest request)
{
Response<object> response = new Response<object> { Data = string.Empty };
List<TServiceModel> modelList = new List<TServiceModel>();
if (!string.IsNullOrEmpty(request.URI))
{
Logger.Info(string.Format("About to call REST Service... Service URI: [{0}].", request.URI));
response = GetRESTServiceResponse(request.URI);
if (response.Status == Enums.ResponseStatus.Success)
{
try
{
JArray entries = JToken.Parse(response.Data.ToString()).SelectToken(request.CollectionPath) as JArray;
string modelJsonStr = string.Empty;
//if no Entry element was found, skip...
if (entries != null)
{
foreach (JToken entry in entries)
{
modelList.Add(JToken.Parse(CustomizeEntryString(entry, request.ViewModelPath, request.ReplaceStrings)).ToObject<TServiceModel>());
}
}
// server returned a single Entry JSON
else
{
modelList.Add(JToken.Parse(CustomizeEntryString(JToken.Parse(response.Data.ToString()).SelectToken(request.CollectionPath), request.ViewModelPath, request.ReplaceStrings)).ToObject<TServiceModel>());
}
}
catch (JsonSerializationException ex)
{
string msg = "Error in parsing REST json response.";
Logger.Error(string.Format("{0}\n{1}. Response: [{2}]", msg, ex.Message, response.Data.ToString()));
response.Status = Enums.ResponseStatus.Error;
response.Message = msg;
}
}
}
return new Response<List<TServiceModel>> { ServiceURI = response.ServiceURI, Data = modelList, Message = response.Message, Status = response.Status, MetaData = response.MetaData };
}
private static Response<object> GetRESTServiceResponse(string requestURI)
{
HttpWebRequest httpWebRequest = null;
ESBServiceResponseMetadata responseMetadata = new ESBServiceResponseMetadata();
HttpWebResponse httpWebResponse = null;
Stream responseStream = null;
StreamReader responseStreamReader = null;
StringBuilder httpActivityLog = new StringBuilder();
Response<object> response = new Response<object> { ServiceURI = requestURI, Data = string.Empty, Message = string.Empty };
bool tryAgain;
try
{
httpWebRequest = WebRequest.Create(requestURI) as HttpWebRequest;
Logger.Info(string.Format("HttpWebRequest object created for request [{0}].", requestURI));
LogHTTPHeaderData(httpWebRequest.Headers, httpActivityLog);
do
{
tryAgain = false;
try
{
httpWebResponse = httpWebRequest.GetResponse() as HttpWebResponse;
LogHTTPHeaderData(httpWebResponse.Headers, httpActivityLog);
Logger.Info(httpActivityLog.ToString());
try
{
responseStream = httpWebResponse.GetResponseStream();
responseStreamReader = new StreamReader(responseStream);
response.Data = responseStreamReader.ReadToEnd();
JToken esbServiceToken = JToken.Parse(response.Data.ToString()).SelectToken("feed.ESBServiceResponseMetadata");
if (esbServiceToken != null)
{
try
{
responseMetadata = esbServiceToken.ToObject<ESBServiceResponseMetadata>();
response.MetaData = responseMetadata;
if (responseMetadata.ResponseStatus == Enums.ESBResponseStatuses.TechnicalError)
{
if (responseMetadata.ResponseDescription.IndexOf("Failed to establish a backside connection") > -1)
{
tryAgain = true;
}
}
}
catch (JsonSerializationException ex)
{
string msg = "Error in parsing REST json response.";
Logger.Error(string.Format("{0}\n{1}. Response: [{2}]", msg, ex.Message, response.Data.ToString()));
response.Status = Enums.ResponseStatus.Error;
response.Message = msg;
Logger.Error(ex);
}
response.Status = responseMetadata.ResponseStatus == Enums.ESBResponseStatuses.Success ? Enums.ResponseStatus.Success : Enums.ResponseStatus.Error;
//response.Message = Enums.GetEnumDescription(responseMetadata.ResponseDescription);
response.Message = responseMetadata.ResponseDescription;
}
else
{
response.Status = Enums.ResponseStatus.Error;
response.Message = "Could not find path 'feed.ESBServiceResponseMetadata' in JSON string.";
}
}
catch (WebException ex)
{
if (ex.Message.ToLower().IndexOf("timed out") > -1)
{
tryAgain = true;
response.FailedAttempts++;
Logger.Error(string.Format("Response timed out. Commencing retry number {0}.", response.FailedAttempts));
Logger.Error(ex);
}
}
}
catch (WebException ex)
{
if (ex.Message.ToLower().IndexOf("timed out") > -1)
{
tryAgain = true;
response.FailedAttempts++;
Logger.Error(string.Format("Response timed out. Commencing retry number {0}.", response.FailedAttempts));
Logger.Error(ex);
}
}
catch (Exception ex)
{
Logger.Error(string.Format("Error in getting request's Response Stream object for [{0}].\n{1}\n{2}", requestURI, ex.Message, ex.InnerException != null ? ex.InnerException.Message : string.Empty));
Logger.Error(ex);
Logger.Info(httpActivityLog.ToString());
response.Status = Enums.ResponseStatus.Error;
response.Message = string.Format("Error in getting request's Response Stream object for [{0}].\n{1}\n{2}", requestURI, ex.Message, ex.InnerException != null ? ex.InnerException.Message : string.Empty);
response.Data = httpActivityLog.ToString();
}
}
while (tryAgain);
}
catch (Exception ex)
{
httpWebRequest.Abort();
Logger.Error(string.Format("Error in creating HttpWebRequest object for [{0}].", requestURI));
Logger.Error(ex);
Logger.Info(httpActivityLog.ToString());
response.Status = Enums.ResponseStatus.Error;
response.Message = string.Format("Error in creating HttpWebRequest object for [{0}].\n{1}", requestURI, ex.Message);
response.Data = httpActivityLog.ToString();
}
finally
{
if (httpWebResponse != null)
httpWebResponse.Close();
if (responseStream != null)
responseStream.Dispose();
if (responseStreamReader != null)
responseStreamReader.Dispose();
}
return response;
}
private static string CustomizeEntryString(JToken entry, string viewModelPath, List<string> replaceStrings)
{
string modelJsonStr = string.Empty;
modelJsonStr = entry.SelectToken(viewModelPath).ToString();
#region Remove unwanted characters
/*
* In case there are characters that need to be removed from the Json structure the service returns,
* so the names of the fields in the Json object match our model field names - and the cast/mapping works
*/
foreach (string replaceStr in replaceStrings)
{
modelJsonStr = modelJsonStr.Replace(replaceStr, "");
}
#endregion Remove unwanted characters
return modelJsonStr;
}
private static void LogHTTPHeaderData(WebHeaderCollection webHeaderCollection, StringBuilder httpActivityLog)
{
for (int i = 0; i < webHeaderCollection.Count; ++i)
httpActivityLog.AppendLine(string.Format("\nHTTP header parameter:{0}, Value :{1}", webHeaderCollection.Keys[i], webHeaderCollection[i]));
}
}
}
No comments:
Post a Comment