Exemple #1
0
        protected static string ExtractParentExecutionIdFromHeader(HttpContext context)
        {
            var request = context?.Request;

            FulcrumAssert.IsNotNull(request, CodeLocation.AsString());
            if (request == null)
            {
                return(null);
            }
            if (!request.Headers.TryGetValue(Constants.ParentExecutionIdHeaderName, out var executionIds))
            {
                return(null);
            }
            var executionsArray = executionIds.ToArray();

            if (!executionsArray.Any())
            {
                return(null);
            }
            if (executionsArray.Length == 1)
            {
                return(executionsArray[0]);
            }
            var message =
                $"There was more than one execution id in the header: {string.Join(", ", executionsArray)}. The first one was picked as the Fulcrum execution id from here on.";

            Log.LogWarning(message);
            return(executionsArray[0]);
        }
Exemple #2
0
        /// <summary>
        /// This is aimed at to be used by other AddConfiguration() methods
        /// </summary>
        /// <param name="configuration"></param>
        public static void AddConfiguration(IConfiguration configuration)
        {
            var configurationSection = configuration.GetSection("FulcrumApplication");

            FulcrumAssert.IsNotNull(configurationSection, CodeLocation.AsString());
            Application.FulcrumApplicationHelper.WebBasicSetup(configurationSection);
        }
Exemple #3
0
        /// <summary>
        ///
        /// </summary>
        protected static string GetNexusTestContextFromHeader(HttpContext context)
        {
            var request = context?.Request;

            FulcrumAssert.IsNotNull(request, CodeLocation.AsString());
            if (request == null)
            {
                return(null);
            }
            var headerValueExists = request.Headers.TryGetValue(Constants.NexusTestContextHeaderName, out var values);

            if (!headerValueExists)
            {
                return(null);
            }
            var valuesAsArray = values.ToArray();

            if (!valuesAsArray.Any())
            {
                return(null);
            }
            if (valuesAsArray.Length == 1)
            {
                return(valuesAsArray[0]);
            }
            var message = $"There was more than one {Constants.NexusTestContextHeaderName} headers: {string.Join(", ", valuesAsArray)}. Using the first one.";

            Log.LogWarning(message);
            return(valuesAsArray[0]);
        }
        private static StatusAndContent ToStatusAndContent(Exception e)
        {
            if (e is RequestAcceptedException acceptedException)
            {
                var acceptedContent = new RequestAcceptedContent()
                {
                    RequestId           = acceptedException.RequestId,
                    PollingUrl          = acceptedException.PollingUrl,
                    RegisterCallbackUrl = acceptedException.RegisterCallbackUrl
                };
                FulcrumAssert.IsValidated(acceptedContent, CodeLocation.AsString());
                return(new StatusAndContent
                {
                    // ReSharper disable once PossibleInvalidOperationException
                    StatusCode = HttpStatusCode.Accepted,
                    Content = JsonConvert.SerializeObject(acceptedContent)
                });
            }
            if (e is RequestPostponedException postponedException)
            {
                var postponedContent = new RequestPostponedContent()
                {
                    TryAgain              = postponedException.TryAgain,
                    WaitingForRequestIds  = postponedException.WaitingForRequestIds,
                    ReentryAuthentication = postponedException.ReentryAuthentication
                };
                FulcrumAssert.IsValidated(postponedContent, CodeLocation.AsString());
                return(new StatusAndContent
                {
                    // ReSharper disable once PossibleInvalidOperationException
                    StatusCode = HttpStatusCode.Accepted,
                    Content = JsonConvert.SerializeObject(postponedContent)
                });
            }
            if (!(e is FulcrumException fulcrumException))
            {
                var message = $"Application threw an exception that didn't inherit from {typeof(FulcrumException)}.\r{e.GetType().FullName}: {e.Message}\rFull exception:\r{e}";
                Log.LogError(message, e);
                fulcrumException = new FulcrumAssertionFailedException(message, e);
            }

            var error      = ExceptionConverter.ToFulcrumError(fulcrumException, true);
            var statusCode = ExceptionConverter.ToHttpStatusCode(error);

            FulcrumAssert.IsNotNull(statusCode, CodeLocation.AsString());
            Log.LogVerbose(
                $"{error.Type} => HTTP status {statusCode}");
            var content = ExceptionConverter.ToJsonString(error, Formatting.Indented);

            return(new StatusAndContent
            {
                // ReSharper disable once PossibleInvalidOperationException
                StatusCode = statusCode.Value,
                Content = content
            });
        }
        /// <inheritdoc />
        public async Task <TModel> CreateChildAndReturnAsync(TId parentId, TModelCreate item, CancellationToken cancellationToken = default)
        {
            InternalContract.RequireNotNull(item, nameof(item));
            InternalContract.RequireValidated(item, nameof(item));
            var createdItem = await _service.CreateAndReturnAsync(item, cancellationToken);

            FulcrumAssert.IsNotNull(createdItem, CodeLocation.AsString());
            FulcrumAssert.IsValidated(createdItem, CodeLocation.AsString());
            return(createdItem);
        }
Exemple #6
0
        protected static async Task ConvertExceptionToResponseAsync(HttpContext context, Exception exception, CancellationToken cancellationToken)
        {
            if (exception is RequestPostponedException rpe && rpe.ReentryAuthentication == null)
            {
                rpe.ReentryAuthentication = CalculateReentryAuthentication(context.Request);
            }
            var response = AspNetExceptionConverter.ToContentResult(exception);

            FulcrumAssert.IsTrue(response.StatusCode.HasValue, CodeLocation.AsString());
            Debug.Assert(response.StatusCode.HasValue);
            context.Response.StatusCode  = response.StatusCode.Value;
            context.Response.ContentType = response.ContentType;
            await context.Response.WriteAsync(response.Content, cancellationToken : cancellationToken);
        }
        /// <inheritdoc />
        public async Task <int> CountItemsAdvancedAsync(string selectFirst, string selectRest, object param = null, CancellationToken cancellationToken = default)
        {
            InternalContract.RequireNotNullOrWhiteSpace(selectFirst, nameof(selectFirst));
            InternalContract.RequireNotNullOrWhiteSpace(selectRest, nameof(selectRest));
            if (selectRest == null)
            {
                return(0);
            }
            var selectStatement = $"{selectFirst} {selectRest}";
            var result          = await InternalQueryAsync <int>(selectStatement, param, cancellationToken);

            FulcrumAssert.IsNotNull(result, CodeLocation.AsString());
            return(result.SingleOrDefault());
        }
        // https://www.programmersought.com/article/49936898629/
        public static async Task <string> GetRequestBodyAsync(this HttpRequest request)
        {
            FulcrumAssert.IsNotNull(request.Body, CodeLocation.AsString());
            request.EnableBuffering();
            request.Body.Position = 0;
            var sr   = new StreamReader(request.Body);
            var body = await sr.ReadToEndAsync();

            request.Body.Position = 0;
            if (body == "")
            {
                FulcrumAssert.IsTrue(request.ContentLength == null || request.ContentLength.Value == 0, CodeLocation.AsString());
            }
            return(body);
        }
        // https://docs.microsoft.com/en-us/aspnet/core/mvc/advanced/app-parts?view=aspnetcore-2.2
        // When we need a controller, this code will add all controllers in the same assembly.
        // See RemoveRedundantControllers for removing the controllers that are redundant.
        private void AddControllersToMvc(IServiceCollection services, IMvcBuilder mvcBuilder)
        {
            using (var serviceScope = services.BuildServiceProvider().CreateScope())
            {
                var serviceProvider = serviceScope.ServiceProvider;
                var assemblies      = new HashSet <Assembly>();

                foreach (var serviceType in _capabilityInterfaceToControllerClasses.Keys)
                {
                    FulcrumAssert.IsTrue(serviceType.IsInterface, CodeLocation.AsString());
                    var service = serviceProvider.GetService(serviceType);
                    if (service == null)
                    {
                        continue;
                    }
                    var controllerTypes = _capabilityInterfaceToControllerClasses[serviceType];
                    FulcrumAssert.IsNotNull(controllerTypes);
                    var controllerList = controllerTypes as List <Type> ?? controllerTypes.ToList();

                    foreach (var controllerType in controllerList)
                    {
                        FulcrumAssert.IsTrue(controllerType.IsClass, CodeLocation.AsString());
                        var assembly = controllerType.GetTypeInfo().Assembly;
                        assemblies.Add(assembly);
                        _controllersToKeep.Add(controllerType);
                    }

                    if (controllerList.Count > 0)
                    {
                        var names = controllerList.Select(t => t.Name);
                        Log.LogInformation(
                            $"Injecting controllers for the capability {serviceType.Name}: {string.Join(", ", names)}");
                        Log.LogVerbose(
                            $"The capability {serviceType.Name} was implemented by {service.GetType().FullName}");
                    }
                }

                foreach (var assembly in assemblies)
                {
                    mvcBuilder.AddApplicationPart(assembly);
                    Log.LogInformation(
                        $"Injected all controllers in assembly {assembly.FullName}. The redundant ones will be removed later.");
                }
            }
        }
 public void IsValidatedFail()
 {
     try
     {
         var validatable = new Validatable();
         FulcrumAssert.IsValidated(validatable, CodeLocation.AsString());
         UT.Assert.Fail("An exception should have been thrown");
     }
     catch (FulcrumAssertionFailedException fulcrumException)
     {
         UT.Assert.IsNotNull(fulcrumException.TechnicalMessage);
         UT.Assert.IsTrue(fulcrumException.TechnicalMessage.StartsWith("Expected validation to pass (Property Validatable.Name"),
                          $"TechnicalMessage: '{fulcrumException.TechnicalMessage}'");
     }
     catch (Exception e)
     {
         UT.Assert.Fail($"Expected a specific FulcrumException but got {e.GetType().FullName}.");
     }
 }
        public void AreEqualAssertionFailWithCodeLocation()
        {
            const string message      = "A random message";
            var          codeLocation = CodeLocation.AsString();

            try
            {
                FulcrumAssert.AreEqual("Knoll", "Tott", codeLocation);
                UT.Assert.Fail("An exception should have been thrown");
            }
            catch (FulcrumAssertionFailedException fulcrumException)
            {
                UT.Assert.IsNotNull(fulcrumException.TechnicalMessage.Contains(message));
                UT.Assert.AreEqual(codeLocation, fulcrumException.ErrorLocation);
            }
            catch (Exception e)
            {
                UT.Assert.Fail($"Expected a specific FulcrumException but got {e.GetType().FullName}.");
            }
        }
Exemple #12
0
        public async Task InvokeAsync(HttpContext context)
        {
            try
            {
                await _next(context);
            }
            catch (Exception exception)
            {
                Log.LogError($"The web service had an internal exception ({exception.Message})", exception);

                var response = AspNetExceptionConverter.ToContentResult(exception);
                Log.LogInformation(
                    $"Exception ({exception.Message}) was converted to an HTTP response ({response.StatusCode}).");

                FulcrumAssert.IsTrue(response.StatusCode.HasValue, CodeLocation.AsString());
                Debug.Assert(response.StatusCode.HasValue);
                context.Response.StatusCode  = response.StatusCode.Value;
                context.Response.ContentType = response.ContentType;
                await context.Response.WriteAsync(response.Content);
            }
        }
Exemple #13
0
        /// <inheritdoc />
        public Task <PageEnvelope <TManyModel> > SearchChildrenAsync(Guid parentId, SearchDetails <TManyModel> details, int offset, int?limit = null,
                                                                     CancellationToken cancellationToken = default)
        {
            InternalContract.RequireNotNull(details, nameof(details));
            InternalContract.RequireValidated(details, nameof(details));
            InternalContract.RequireGreaterThanOrEqualTo(0, offset, nameof(offset));
            if (limit != null)
            {
                InternalContract.RequireGreaterThan(0, limit.Value, nameof(limit));
            }

            var whereAsModel = details.GetWhereAsModel("%", "_");
            var param        = whereAsModel == null ? new TManyModel() : whereAsModel;
            var property     = typeof(TManyModel).GetProperty(ParentColumnName);

            FulcrumAssert.IsNotNull(property, CodeLocation.AsString());
            property?.SetValue(param, parentId);

            var where = CrudSearchHelper.GetWhereStatement(details, ParentColumnName);
            var orderBy = CrudSearchHelper.GetOrderByStatement(details);

            return(SearchWhereAsync(where, orderBy, param, offset, limit, cancellationToken));
        }
Exemple #14
0
 /// <summary>
 /// Factory method
 /// </summary>
 public static FulcrumException Create(string message, Exception innerException)
 {
     FulcrumAssert.IsNull(innerException, CodeLocation.AsString());
     return(new FulcrumAcceptedException(message));
 }
        public async Task ClaimLock_Given_AlreadyLocked_Gives_FulcrumTryAgainException()
        {
            var createItem = new TestItemBare
            {
                Value = "x"
            };
            var item = await _table.CreateAndReturnAsync(createItem);

            Assert.IsNotNull(item);
            bool?lock2Success = null;

            var claimLock1Success    = new ManualResetEvent(false);
            var hasTriedToClaimLock2 = new ManualResetEvent(false);
            var thread1 = ThreadHelper.FireAndForget(async() =>
            {
                using (var scope = CreateStandardScope())
                {
                    var lockedItem = await _table.SearchSingleAndLockWhereAsync("Id=@Id", new { Id = item.Id });
                    FulcrumAssert.IsNotNull(lockedItem);
                    claimLock1Success.Set();
                    FulcrumAssert.IsTrue(hasTriedToClaimLock2.WaitOne(TimeSpan.FromSeconds(1)), CodeLocation.AsString());
                    scope.Complete();
                }
            });
            var thread2 = ThreadHelper.FireAndForget(async() =>
            {
                FulcrumAssert.IsTrue(claimLock1Success.WaitOne(TimeSpan.FromSeconds(1)));
                using (var scope = CreateStandardScope())
                {
                    try
                    {
                        var lockedItem = await _table.SearchSingleAndLockWhereAsync("Id=@Id", new { Id = item.Id });
                        FulcrumAssert.IsNotNull(lockedItem);
                        lock2Success = true;
                        scope.Complete();
                    }
                    catch (FulcrumTryAgainException)
                    {
                        lock2Success = false;
                    }
                }
                hasTriedToClaimLock2.Set();
            });

            Assert.IsTrue(thread2.Join(TimeSpan.FromSeconds(5)));
            Assert.IsNotNull(lock2Success);
            Assert.IsFalse(lock2Success);
            Assert.IsTrue(thread1.Join(TimeSpan.FromSeconds(1)));
        }