public async Task ClaimLock_Given_Scope_Gives_ReturnItem()
        {
            var createItem = new TestItemBare
            {
                Value = "x"
            };
            var item = await _table.CreateAndReturnAsync(createItem);

            Assert.IsNotNull(item);

            bool?lockSuccess = null;

            using (var scope = CreateStandardScope())
            {
                try
                {
                    var lockedItem = await _table.SearchSingleAndLockWhereAsync("Id=@Id", new { Id = item.Id });

                    FulcrumAssert.IsNotNull(lockedItem);
                    lockSuccess = true;
                    scope.Complete();
                }
                catch (Exception)
                {
                    lockSuccess = false;
                }
            }
            Assert.IsNotNull(lockSuccess);
            Assert.IsTrue(lockSuccess);
        }
        private async Task <TReturn> GetAndMaybeReturnAsync <TReturn>(string key, DeserializeDelegate <TReturn> deserializeDelegate, TId id = default(TId), CancellationToken token = default(CancellationToken))
        {
            var byteArray = await Cache.GetAsync(key, token);

            if (byteArray == null)
            {
                return(default(TReturn));
            }
            var cacheEnvelope     = SerializingSupport.Deserialize <CacheEnvelope>(byteArray);
            var cacheItemStrategy = Equals(id, default(TId)) ? GetCacheItemStrategy(cacheEnvelope) : await GetCacheItemStrategyAsync(id, cacheEnvelope, token);

            switch (cacheItemStrategy)
            {
            case UseCacheStrategyEnum.Use:
                return(deserializeDelegate(cacheEnvelope));

            case UseCacheStrategyEnum.Ignore:
                return(default(TReturn));

            case UseCacheStrategyEnum.Remove:
                await Cache.RemoveAsync(key, token);

                return(default(TReturn));

            default:
                FulcrumAssert.Fail($"Unexpected value of {nameof(UseCacheStrategyEnum)} ({cacheItemStrategy}).");
                return(default(TReturn));
            }
        }
Exemple #3
0
        public void Initialize()
        {
            FulcrumApplicationHelper.UnitTestSetup(nameof(ManyToOneTest));
            var connectionString = TestSettings.ConnectionString;

            FulcrumAssert.IsNotNullOrWhiteSpace(connectionString);
            var manyTableMetadata = new SqlTableMetadata
            {
                TableName         = "TestItem",
                CustomColumnNames = new[] { "Value", "IncreasingNumber", "NumberModulo", "DecreasingString", "ParentId" },
                OrderBy           = new string[] { }
            };
            var oneTableMetadata = new SqlTableMetadata
            {
                TableName         = "TestItem",
                CustomColumnNames = new[] { "Value" },
                OrderBy           = new string[] { }
            };

            _oneStorage = new CrudSql <TestItemId <Guid> >(new DatabaseOptions
            {
                ConnectionString = connectionString
            }, oneTableMetadata);
            _manyStorage = new ManyToOneSql <TestItemManyToOneCreate <Guid, Guid?>, TestItemManyToOne <Guid, Guid?>, TestItemId <Guid> >(
                new DatabaseOptions
            {
                ConnectionString = connectionString
            }, manyTableMetadata, "ParentId", _oneStorage);
        }
        protected override async Task InvokeAsync(CompabilityInvocationContext context, CancellationToken cancellationToken)
        {
            FulcrumAssert.IsNotNull(FulcrumApplication.Setup.TelemetryHandler, null, $"When using this handler, setup the {nameof(FulcrumApplication.Setup.TelemetryHandler)}");
            FulcrumAssert.IsNotNull(_pathAndQueryMatching, null, $"Expected {nameof(_pathAndQueryMatching)}");

#if NETCOREAPP
            var pathAndQuery = context.Context.Request.Path;
            var method = context.Context.Request.Method.ToUpperInvariant();
#else
            var pathAndQuery = context.RequestMessage.RequestUri.PathAndQuery;
            var method = context.RequestMessage.Method.ToString().ToUpperInvariant();
#endif

            foreach (var entry in _pathAndQueryMatching)
            {
                var match = entry.Value.Match(pathAndQuery);
                if (match.Success)
                {
                    FulcrumApplication.Setup.TelemetryHandler.TrackEvent("AggregatedRequests", new Dictionary<string, string> {
                        { "AggregatedOn", entry.Key },
                        { "PathAndQuery", pathAndQuery },
                        { "HttpMethod", method },
                    });
                    break;
                }
            }

            await CallNextDelegateAsync(context, cancellationToken);
        }
Exemple #5
0
        public void GenericBase_Can_Still_Log_Error()
        {
            FulcrumApplicationHelper.UnitTestSetup(nameof(BootstrapApplicationTests));

            var loggerMock = new Mock <ISyncLogger>();

            FulcrumApplication.Setup.SynchronousFastLogger = loggerMock.Object;

            LogRecord loggedRecord = null;

            loggerMock
            .Setup(x => x.LogSync(It.IsAny <LogRecord>()))
            .Callback((LogRecord logRecord) =>
            {
                loggedRecord = logRecord;
                Console.WriteLine("LOGGED MESSAGE: " + logRecord.ToLogString());
            });

            try
            {
                FulcrumAssert.IsNotNull(null, "NIL");
                UT.Assert.Fail("Expected exception");
            }
            catch (Exception)
            {
                UT.Assert.IsNotNull(loggedRecord, "Expected a log record");
                UT.Assert.AreEqual(LogSeverityLevel.Error, loggedRecord.SeverityLevel);
            }
        }
        /// <inheritdoc />
        public virtual T ExecuteOrThrow <T>(Func <T> function)
        {
            try
            {
                Interlocked.Increment(ref ConcurrencyCount);

                if (IsQuickFailRecommended())
                {
                    FulcrumAssert.IsNotNull(LatestException, CodeLocation.AsString());
                    throw LatestException;
                }

                try
                {
                    var result = function();
                    ReportSuccess();
                    return(result);
                }
                catch (CircuitBreakerException e)
                {
                    FulcrumAssert.IsNotNull(e.InnerException, CodeLocation.AsString());
                    ReportFailure(e.InnerException);
                    // ReSharper disable once PossibleNullReferenceException
                    throw e.InnerException;
                }
            }
            finally
            {
                Interlocked.Decrement(ref ConcurrencyCount);
            }
        }
Exemple #7
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);
        }
        /// <inheritdoc />
        protected override ISyncLogger GetSynchronousFastLogger()
        {
            var stackifyKey = FulcrumApplication.AppSettings.GetString("Stackify.Key", true);

            FulcrumAssert.IsNotNullOrWhiteSpace(stackifyKey);
            return(new StackifyLogger(stackifyKey).AsQueuedSyncLogger().AsBatchLogger());
        }
Exemple #9
0
        /// <inheritdoc />
        protected override async Task <HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            var timer = new Stopwatch();

            timer.Start();
            try
            {
                HttpResponseMessage response;
                if (UnitTest_SendAsyncDependencyInjection == null)
                {
                    response = await base.SendAsync(request, cancellationToken);
                }
                else
                {
                    // This is for unit testing
                    FulcrumAssert.IsTrue(FulcrumApplication.IsInDevelopment);
                    response = await UnitTest_SendAsyncDependencyInjection(request, cancellationToken);
                }
                timer.Stop();
                await LogResponseAsync(request, response, timer.Elapsed, cancellationToken);

                return(response);
            }
            catch (Exception e)
            {
                timer.Stop();
                LogException(request, e, timer.Elapsed);
                throw;
            }
        }
Exemple #10
0
        public void Initialize()
        {
            _personProfilesFunctionality = new Mock <IPersonProfilesFunctionality>();
            _controller = new PersonProfilesController(_personProfilesFunctionality.Object);
            var id   = Guid.NewGuid().ToString();
            var eTag = Guid.NewGuid().ToString();

            _bllPerson = new PersonProfile
            {
                Id        = id,
                ETag      = eTag,
                GivenName = "Joe",
                Surname   = "Smith"
            };
            _servicePerson = new ServicePersonProfile
            {
                Id        = id,
                ETag      = eTag,
                GivenName = "Joe",
                Surname   = "Smith"
            };
            FulcrumAssert.IsValidated(_bllPerson, $"{Namespace}: C3A453C9-77AA-4FFD-9DEB-DDD3291947DA");
            _personProfilesFunctionality.Setup(mock => mock.CreateAsync(It.IsAny <IPersonProfile>())).ReturnsAsync(_bllPerson);
            _personProfilesFunctionality.Setup(mock => mock.ReadAsync(It.IsAny <string>())).ReturnsAsync(_bllPerson);
            _personProfilesFunctionality.Setup(mock => mock.UpdateAsync(It.IsAny <IPersonProfile>())).ReturnsAsync(_bllPerson);
            _personProfilesFunctionality.Setup(mock => mock.DeleteAsync(It.IsAny <string>())).Returns(Task.FromResult(0));
        }
Exemple #11
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 #12
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]);
        }
Exemple #13
0
        /// <summary>
        /// Adds a Nexus Iam User Authorization header to the request before sending it.
        /// </summary>
        /// <param name="request"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        protected override async Task <HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            var userAuthorization = _provider.GetValue <string>(Constants.NexusUserAuthorizationKeyName);

            if (!string.IsNullOrWhiteSpace(userAuthorization))
            {
                if (!request.Headers.TryGetValues(Constants.NexusUserAuthorizationHeaderName, out _))
                {
                    request.Headers.Add(Constants.NexusUserAuthorizationHeaderName, userAuthorization);
                }
            }

            HttpResponseMessage response;

            if (UnitTest_SendAsyncDependencyInjection == null)
            {
                response = await base.SendAsync(request, cancellationToken);
            }
            else
            {
                // This is for unit testing
                FulcrumAssert.IsTrue(FulcrumApplication.IsInDevelopment);
                response = await UnitTest_SendAsyncDependencyInjection(request, cancellationToken);
            }
            return(response);
        }
        /// <inheritdoc />
        public Task <TStorableItem> CreateAsync(TStorableItem item)
        {
            InternalContract.RequireNotNull(item, nameof(item));
            InternalContract.RequireValidated(item, nameof(item));

            TId id = default(TId);

            if (typeof(TId) == typeof(Guid))
            {
                // ReSharper disable once SuspiciousTypeConversion.Global
                id = (dynamic)Guid.NewGuid();
            }
            else if (typeof(TId) == typeof(string))
            {
                // ReSharper disable once SuspiciousTypeConversion.Global
                id = (dynamic)Guid.NewGuid().ToString();
            }
            else if (typeof(TId) == typeof(int))
            {
                lock (LockObject)
                {
                    // ReSharper disable once SuspiciousTypeConversion.Global
                    id = (dynamic)_nextInteger++;
                }
            }
            else
            {
                FulcrumAssert.Fail($"{Namespace}: 5CBE07D8-4C31-43E7-A41C-1DF0B173ABF9", $"MemoryStorage can handle Guid, string and int as type for Id, but it can't handle {typeof(TId)}.");
            }
            return(CreateAsync(id, item));
        }
        private async Task <PersonConsent> MapFromServerAsync(PersonConsentTable source,
                                                              CancellationToken token = default(CancellationToken))
        {
            InternalContract.RequireNotNull(source, nameof(source));
            InternalContract.RequireValidated(source, nameof(source));
            var serverConsentTask = _storage.Consent.ReadAsync(source.ConsentId, token);
            var serverPersonTask  = _storage.Person.ReadAsync(source.PersonId, token);
            var serverConsent     = await serverConsentTask;
            var serverPerson      = await serverPersonTask;

            if (serverConsent == null)
            {
                throw new FulcrumNotFoundException($"Could not find consent with id {source.ConsentId}");
            }
            if (serverPerson == null)
            {
                throw new FulcrumNotFoundException($"Could not find person with id {source.PersonId}");
            }
            var target = new PersonConsent
            {
                Id              = MapperHelper.MapToType <string, Guid>(source.Id),
                ConsentId       = MapperHelper.MapToType <string, Guid>(source.ConsentId),
                PersonName      = serverPerson.Name,
                ConsentName     = serverConsent.Name,
                Etag            = source.Etag,
                PersonId        = MapperHelper.MapToType <string, Guid>(source.PersonId),
                HasGivenConsent = source.HasGivenConsent
            };

            FulcrumAssert.IsValidated(target);
            return(target);
        }
        public AzureBlobClient(string connectionString)
        {
            InternalContract.RequireNotNullOrWhiteSpace(connectionString, nameof(connectionString));
            var storageAccount = CloudStorageAccount.Parse(connectionString);

            _blobClient = storageAccount.CreateCloudBlobClient();
            FulcrumAssert.IsNotNull(_blobClient, null, "Could not create a cloud blob client.");
        }
Exemple #17
0
        public async Task AddMessageAsync(T message, TimeSpan?timeSpanToWait = null, CancellationToken cancellationToken = default)
        {
            var queue = (await _cloudQueueTask);

            FulcrumAssert.IsNotNull(queue);
            var messageAsString = SerializeToString(message);
            await queue.AddMessageAsync(new CloudQueueMessage(messageAsString), null, timeSpanToWait, null, null, cancellationToken);
        }
Exemple #18
0
        /// <summary>
        /// Read the correlation id header from the <paramref name="request"/> and save it to the execution context.
        /// </summary>
        /// <param name="request">The request that we will read the header from.</param>
        /// <returns></returns>
        /// <remarks>This method is made public for testing purposes. Should normally not be called from outside this class.</remarks>
        public void SaveCorrelationIdToExecutionContext(HttpRequestMessage request)
        {
            InternalContract.RequireNotNull(request, nameof(request));
            var correlationId = ExtractCorrelationIdFromHeader(request);

            FulcrumAssert.IsNotNull(_correlationIdValueProvider, $"{Namespace}: 917BF2A8-1C68-45DB-BABB-C4331244C579");
            _correlationIdValueProvider.CorrelationId = correlationId ?? Guid.NewGuid().ToString();
        }
        public AzureStorageTable(string connectionString, string name)
        {
            InternalContract.RequireNotNullOrWhiteSpace(connectionString, nameof(connectionString));
            var storageAccount = CloudStorageAccount.Parse(connectionString);
            var client         = storageAccount.CreateCloudTableClient();

            FulcrumAssert.IsNotNull(client, null, "Could not create a cloud table client.");
            Table = client.GetTableReference(name);
        }
Exemple #20
0
        public async Task AddMessageAsync(T message, TimeSpan?timeSpanToWait = null, CancellationToken cancellationToken = default)
        {
            // Inspired by https://docs.microsoft.com/en-us/azure/storage/queues/storage-tutorial-queues?tabs=dotnet
            var queue = (await _cloudQueueTask);

            FulcrumAssert.IsNotNull(queue);
            var messageAsString = JsonConvert.SerializeObject(message);
            await queue.SendMessageAsync(messageAsString, timeSpanToWait, TimeSpan.FromSeconds(-1), cancellationToken);
        }
        /// <inheritdoc />
        public async Task <HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken = default)
        {
            cancellationToken.ThrowIfCancellationRequested();
            var response = await HttpClient.SendAsync(request, cancellationToken).ConfigureAwait(false);

            cancellationToken.ThrowIfCancellationRequested();
            FulcrumAssert.IsNotNull(response);
            return(response);
        }
        public async Task <IPersonProfile> ReadAsync(string id)
        {
            ServiceContract.RequireNotNullOrWhitespace(id, nameof(id));
            var personProfile = await PersonProfilesFunctionality.ReadAsync(id);

            FulcrumAssert.IsNotNull(personProfile, $"{Namespace}: 56B82634-89A6-4EE4-969D-B7FFB4F9C016");
            FulcrumAssert.IsValidated(personProfile, $"{Namespace}: 56B82634-89A6-4EE4-969D-B7FFB4F9C016");
            return(personProfile);
        }
        /// <inheritdoc />
        public async Task <PageEnvelope <Person> > ReadAllWithPagingAsync(int offset, int?limit = null, CancellationToken token = new CancellationToken())
        {
            var storagePage = await _storage.Person.ReadAllWithPagingAsync(offset, limit, token);

            FulcrumAssert.IsNotNull(storagePage?.Data);
            var tasks = storagePage?.Data.Select(record => MapFromServerAsync(record, token));

            return(new PageEnvelope <Person>(storagePage?.PageInfo, await Task.WhenAll(tasks)));
        }
        public void IsValidatedOk()
        {
            var validatable = new Validatable
            {
                Name = "Jim"
            };

            FulcrumAssert.IsValidated(validatable, $"{Namespace}: DCB46FEB-9347-47CC-9307-10702F8026E4");
        }
Exemple #25
0
 /// <inheritdoc />
 public GdprCapability()
 {
     PersonService  = new PersonService("http://localhost/GdprConsent.NexusAdapter.WebApi/api/Gdpr/Persons");
     ConsentService = new ConsentService("http://localhost/GdprConsent.NexusAdapter.WebApi/api/Gdpr/Consents");
     FulcrumAssert.IsNotNull(ConsentService);
     PersonConsentService = new PersonConsentService("http://localhost/GdprConsent.NexusAdapter.WebApi/api/Gdpr/Persons", "Persons", "Consents");
     ConsentPersonService = new ConsentPersonService("http://localhost/GdprConsent.NexusAdapter.WebApi/api/Gdpr/Consents", "Consents", "Persons");
     FulcrumAssert.IsNotNull(PersonConsentService);
 }
 private async Task <HealthResponse> CheckAuthentication()
 {
     return(await ChackAction("Authentication", async() =>
     {
         var jwt = await _tokenRefresher.GetJwtTokenAsync();
         FulcrumAssert.IsNotNull(jwt);
         FulcrumAssert.IsNotNullOrWhiteSpace(jwt.AccessToken);
     }));
 }
Exemple #27
0
 private void RestoreStackTrace()
 {
     lock (ClassLock)
     {
         ThreadStackTraces.Value = _stackTraces;
         ThreadCallDepth.Value   = _callDepth + 1;
     }
     FulcrumAssert.IsLessThan(MaxDepthForBackgroundThreads, ThreadCallDepth.Value, null, "Too deep nesting of background jobs.");
 }
        private TStorableItem GetMemoryItem(TId id)
        {
            ValidateExists(id);
            InternalContract.RequireNotDefaultValue(id, nameof(id));
            var item = _memoryItems[id];

            FulcrumAssert.IsNotNull(item, $"{Namespace}: B431A6BB-4A76-4672-9607-65E1C6EBFBC9");
            return(CopyItem(item));
        }
        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
            });
        }
Exemple #30
0
        public async Task ErrorAsync()
        {
            FulcrumAssert.IsNotNull(_hueClient, null, "Must have a valid HueClient.");
            var command = new LightCommand();

            command.SetColor(ClientHelper.GetRgbColor(ClientHelper.ColorEnum.Red));
            command.Alert = Alert.Once;
            _status       = "Error";
            await _hueClient.SendCommandAsync(command, _lamps);
        }