/// <summary></summary> /// <param name="baseUri">The base URL that all HTTP calls methods will refer to.</param> // ReSharper disable once UnusedParameter.Local public HttpSender(string baseUri) { try { if (!string.IsNullOrWhiteSpace(baseUri)) { BaseUri = new Uri(baseUri); } } catch (UriFormatException e) { InternalContract.Fail($"The format of {nameof(baseUri)} ({baseUri}) is not correct: {e.Message}"); } lock (LockClass) { if (DefaultHttpClient == null) { var handlers = OutboundPipeFactory.CreateDelegatingHandlers(); var httpClient = HttpClientFactory.Create(handlers); DefaultHttpClient = new HttpClientWrapper(httpClient); } } HttpClient = new HttpClientWrapper(DefaultHttpClient.ActualHttpClient) { SimulateOutgoingCalls = DefaultHttpClient.SimulateOutgoingCalls }; Log.LogVerbose($"Created REST client {GetType().FullName}: {baseUri}"); }
/// <summary> /// Initialize <see cref="Setup"/>. /// </summary> /// <param name="name">The name of the application.</param> /// <param name="tenant">The tenant that the application itself runs in.</param> /// <param name="level">The run time level for the application itself.</param> /// <remarks>Will setup all mandatory fields for <see cref="Setup"/>, but you might want to override those values when this method returns."/></remarks> public static void Initialize(string name, Tenant tenant, RunTimeLevelEnum level) { InternalContract.RequireNotNullOrWhiteSpace(name, nameof(name)); InternalContract.RequireValidated(tenant, nameof(tenant)); InternalContract.Require(level != RunTimeLevelEnum.None, $"{nameof(level)} ({level}) must be set to something else than {RunTimeLevelEnum.None}"); Setup.Name = name; Setup.Tenant = tenant; Setup.RunTimeLevel = level; Setup.ThreadHandler = ThreadHelper.RecommendedForRuntime; Setup.SynchronousFastLogger = LogHelper.RecommendedSyncLoggerForRuntime; switch (level) { case RunTimeLevelEnum.None: case RunTimeLevelEnum.Development: Setup.LogSeverityLevelThreshold = LogSeverityLevel.Verbose; break; case RunTimeLevelEnum.Test: Setup.LogSeverityLevelThreshold = LogSeverityLevel.Information; break; case RunTimeLevelEnum.ProductionSimulation: case RunTimeLevelEnum.Production: Setup.LogSeverityLevelThreshold = LogSeverityLevel.Warning; break; default: Setup.LogSeverityLevelThreshold = LogSeverityLevel.Verbose; InternalContract.Fail($"Parameter {nameof(level)} had an unexpected value ({level})"); break; } }
public string GetAbsoluteUrl(string relativeUrl) { string baseUri = BaseUri?.OriginalString ?? HttpClient.ActualHttpClient?.BaseAddress?.OriginalString ?? ""; if (baseUri != "" && !string.IsNullOrWhiteSpace(relativeUrl)) { var relativeUrlBeginsWithSpecialCharacter = relativeUrl.StartsWith("/") || relativeUrl.StartsWith("?"); var slashIsRequired = !string.IsNullOrWhiteSpace(relativeUrl) && !relativeUrlBeginsWithSpecialCharacter; if (baseUri.EndsWith("/")) { // Maybe remove the / if (relativeUrlBeginsWithSpecialCharacter) { baseUri = baseUri.Substring(0, baseUri.Length - 1); } } else { if (slashIsRequired) { baseUri += "/"; } } } var concatenatedUrl = baseUri + relativeUrl?.Trim(' '); if (!(Uri.TryCreate(concatenatedUrl, UriKind.Absolute, out var uri) && (uri.Scheme == Uri.UriSchemeHttp || uri.Scheme == Uri.UriSchemeHttps))) { InternalContract.Fail($"The format of the concatenated url ({concatenatedUrl}) is not correct. BaseUrl: '{baseUri}'. RelativeUrl: '{relativeUrl}'"); } return(concatenatedUrl); }
/// <summary> /// Serialize the <paramref name="source"/>. /// </summary> public static async Task <RequestData> FromAsync(this RequestData target, HttpRequest source, CancellationToken cancellationToken = default) { // Verify that we can convert the string to an HttpMethod VerifyMethodName(source.Method); target.Method = source.Method; target.EncodedUrl = source.GetEncodedUrl(); target.Headers = new Dictionary <string, StringValues>(); target.ContentType = source.ContentType; target.ContentLength = source.ContentLength; target.Headers = CopyWithoutContentHeaders(source.Headers); target.BodyAsString = await source.GetRequestBodyAsync(); return(target); void VerifyMethodName(string methodName) { try { _ = new HttpMethod(methodName); } catch (Exception e) { InternalContract.Fail($"The following HTTP method is not recognized: {methodName}: {e.Message}"); } } }
/// <summary> /// Parse a string into a <see cref="IConceptValue"/> object. /// </summary> /// <param name="path">The string to parse</param> public static IConceptValue Parse(string path) { if (!TryParse(path, out var result)) { InternalContract.Fail($"The path ({path}) could not be parsed as a concept value path."); } return(result); }
/// <inheritdoc /> public Task <IDictionary <string, string> > TranslateAsync(IEnumerable <string> conceptValues, string targetClientName) { var translations = new Dictionary <string, string>(); foreach (var conceptValuePath in conceptValues) { var conceptValue = ToConceptValue(conceptValuePath); if (conceptValue == null) { // Not a concept value path, no translation possible. translations[conceptValuePath] = conceptValuePath; continue; } if ((_fromServer && conceptValue.ClientName == "client") || (!_fromServer && conceptValue.ClientName == "server")) { // Not a concept value path, no translation possible. translations[conceptValuePath] = conceptValue.Value; continue; } var value = conceptValue.Value; if (conceptValue.ConceptName == "person.address.type.code") { value = _fromServer ? ToAddressTypeClient(value) : ToAddressTypeServer(value); } else { if (_fromServer) { if (value.StartsWith(_clientPrefix)) { InternalContract.Fail( $"The value of {conceptValue} must NOT begin with \"{_clientPrefix}\" from the server."); } value = $"{_clientPrefix}{value}"; } else { if (!value.StartsWith(_clientPrefix)) { InternalContract.Fail( $"The value of {conceptValue} must begin with \"{_clientPrefix}\" from the client."); } value = value.Replace(_clientPrefix, ""); } } translations[conceptValuePath] = value; } return(Task.FromResult((IDictionary <string, string>)translations)); }
/// <summary> /// Helper method to convert from one parameter type to another. /// </summary> /// <param name="source"></param> /// <returns></returns> public static T ConvertToParameterType <T>(object source) { object referenceIdAsObject = source; try { var target = (T)referenceIdAsObject; return(target); } catch (Exception e) { InternalContract.Fail( $"The value \"{source}\" of type {source.GetType().Name} can't be converted into type {typeof(T).Name}:\r" + $"{e.Message}"); // We should not end up at this line, but the compiler think that we can, so we add a throw here. throw; } }
public void Fail() { const string message = "fail with this string"; try { // ReSharper disable once ExpressionIsAlwaysNull InternalContract.Fail(message); Microsoft.VisualStudio.TestTools.UnitTesting.Assert.Fail("An exception should have been thrown"); } catch (FulcrumContractException fulcrumException) { Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsTrue(fulcrumException.TechnicalMessage.Contains(message)); } catch (Exception e) { Microsoft.VisualStudio.TestTools.UnitTesting.Assert.Fail($"Expected a specific FulcrumException but got {e.GetType().FullName}."); } }