using System.Reflection; using System.ServiceModel; using System.Xml.Linq; using Microsoft.Extensions.Options; using Serilog; using Serilog.Events; using CRIF.ACTion.Configuration; namespace CRIF.ACTion.Services.Crif { public class CrifService : ICrifService { private ConnectorServiceClient serviceClient; private readonly IWcfInspectorBehavior WcfInspectorBehavior; private readonly CrifSettings _settings; public CrifService(IWcfInspectorBehavior wcfInspectorBehavior, IOptions settings) { WcfInspectorBehavior = wcfInspectorBehavior; _settings = settings.Value; IsAnyNullOrEmpty(_settings.ApiSettings); CreateServiceClient(); } private void CreateServiceClient() { Log.Debug("Creating client binding and object"); var binding = new BasicHttpsBinding { MaxBufferSize = int.MaxValue, ReaderQuotas = System.Xml.XmlDictionaryReaderQuotas.Max, MaxReceivedMessageSize = int.MaxValue, AllowCookies = true, SendTimeout = CrifConstants.SubmissionTimeoutInMinutes }; var endpoint = new EndpointAddress(_settings.ApiSettings.EndpointUrl); serviceClient = new ConnectorServiceClient(binding, endpoint); if (Log.IsEnabled(LogEventLevel.Debug)) { serviceClient.Endpoint.EndpointBehaviors.Add(WcfInspectorBehavior); } } public btMessage BuildMessage(XElement actionApi) { Log.Information("Building btMessage"); btMessage message = new btMessage { body = actionApi, routing = new Routing { org = new Org { orgCode = _settings.ApiSettings.OrgCode, orgID = _settings.ApiSettings.OrgId, orgIDSpecified = true, }, user = new User { userName = _settings.ApiSettings.Username, }, @interface = new Interface { interfaceID = _settings.ApiSettings.InterfaceId, interfaceIDSpecified = true, }, action = new CRIF.ACTion.Action { transactionType = "API", }, system = new ApproSystem(), // empty object required approResult = new ApproResult(), // empty object required } }; return message; } public async Task SendMessage(XElement request) { var message = BuildMessage(request); XElement body; try { Log.Information("Sending message to CRIF"); var response = await serviceClient.SubmitExAsync(message); if (response.routing.approResult.exceptionCodeSpecified) { //Note that approResult.result will likely equal ApproResultEnum.Success //even with a failed submission var errorResult = response.routing.approResult; var errorText = "CRIF responded with error " + errorResult.exceptionCode + " - " + errorResult.exceptionText; if (errorResult.exceptionCode == 13) { // Go ahead and catch the error 13 that CRIF won't resolve. throw new Error13Exception(errorText + "[KnownReoccuringError]"); } else { throw new FormatException("CRIF responded with error " + errorResult.exceptionCode + " - " + errorResult.exceptionText); } } body = response.body; } catch (Exception e) { Log.Debug("{exception}", e.Message); throw; } return body; } public static bool IsAnyNullOrEmpty(ApiConnectionSettings myObject) { foreach (PropertyInfo pi in myObject.GetType().GetProperties()) { if (pi.PropertyType == typeof(string)) { string value = (string)pi.GetValue(myObject); if (string.IsNullOrEmpty(value)) { throw new ArgumentNullException(pi.ToString()); } } } return false; } } }