Example #1
0
        public async Task Execute(
            HttpContext context,
            IServiceInstance service,
            CancellationToken cancellationToken
            )
        {
            DateTimeOffset  start = ServiceClock.CurrentTime();
            ServiceResponse output;
            Guid?           correlationId = null;

            try
            {
                var input = await _converter.ConvertRequest(service.RequestType, context.Request, new HttpDataSerializerOptions());

                correlationId = input.CorrelationId;
                output        = await service.Execute(input, cancellationToken);
            }
            catch (ValidationErrorException vex)
            {
                output = new ServiceResponse(
                    new ResponseMetaData(
                        service,
                        ServiceResult.ValidationError,
                        validationErrors: ValidationHelper.Create(vex.Error, vex.Member)));
            }

            await _converter.ConvertResponse(output, service.ResponseType, context.Response);
        }
Example #2
0
 protected BaseTable()
 {
     Version       = 1;
     SchemaVersion = 1;
     Created       = ServiceClock.CurrentTime();
     Modified      = ServiceClock.CurrentTime();
 }
Example #3
0
 protected override void RegisterTriggerActions(RegistrationFactory register)
 {
     register.OnTrigger(Trigger.UpdateTime)
     .Do((request, token) =>
     {
         CurrentData.Now = ServiceClock.CurrentTime();
         return(Task.CompletedTask);
     });
 }
Example #4
0
 public async Task GenerateToken()
 {
     ServiceClock.CurrentTime = () => new DateTimeOffset(2020,01,01,1,0,0, TimeSpan.Zero);
     // ARRANGE
     var jwt = new JwtServices(new UserResolverSecretBasic("ABC"), NullLoggerFactory.Instance.CreateLogger<JwtServices>());
     var token = await jwt.Generate(new UserInformation
     {
         Username = "******",
         UserIdentifier = "12345",
         Roles = new[] { "A" }
     }, Guid.Empty, null, CancellationToken.None);
     Assert.AreEqual("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJUZXN0IiwidWlkIjoiMTIzNDUiLCJpYXQiOjE1Nzc4NDA0MDAsInJvbGVzIjpbIkEiXX0.-cgfiJfrxO3u_7gfq1ErHLrDpQG8vwXGVw8BrBIxTZuNxdptzl08mxAsLlLql9Y7FLinSasYXKvQLvn7mrQWMw", token);
     ServiceClock.ResetToUtc();
 }
Example #5
0
        protected override async Task <ServiceResponse <TimeResponse> > Implementation(TimeRequest request, CancellationToken cancellationToken)
        {
            var time      = ServiceClock.CurrentTime();
            var localTime = DateTimeOffset.Now;

            if (request.AddDelayMs > 0)
            {
                await Task.Delay(request.AddDelayMs, cancellationToken);
            }

            var response = new TimeResponse
            {
                CurrentTime = request.Zone == TimeZone.Local ? localTime : time,
                Zone        = request.Zone
            };

            return(Successful(response));
        }
Example #6
0
        protected BaseStatefulServiceInstance(
            CoreDependencies coreDependencies,
            StatefulDependencies statefulDependencies) : base(coreDependencies)
        {
            _stateRepository    = statefulDependencies.StateRepository;
            _currentEnvironment = coreDependencies.EnvironmentResolver.Environment;
            CreatedDate         = ServiceClock.CurrentTime();
            ModifiedDate        = CreatedDate;

            // REMOVE THE DEFAULT VALIDATION AND REPLACE WITH THE STATEFUL VALIDATION SERVICE
            var existingValidation = PipeLine.FirstOrDefault(x => typeof(ValidationMiddleware) == x.GetType());
            var idx = PipeLine.IndexOf(existingValidation);

            PipeLine.RemoveAt(idx);
            PipeLine.Insert(idx, new StateMachineValidatorMiddleware <TTrigger>(coreDependencies.RequestValidator));

            _data   = new TData();
            Machine = new StateMachine <TState, TTrigger>(() => _data.State, s => _data.State = s);
            Machine.OnTransitionCompletedAsync(OnTransitionAction);
        }
Example #7
0
        public Task <string> Generate(UserInformation user, Guid correlationId, TimeSpan?expiresIn, CancellationToken cancellationToken)
        {
            var token = new JwtBuilder()
                        .WithAlgorithm(new HMACSHA512Algorithm())
                        .WithSecret(_userResolverSecret.GetSecret())
                        .AddClaim("sub", user.Username)
                        .AddClaim("uid", user.UserIdentifier)
                        .AddClaim("iat", ServiceClock.CurrentTime().ToUnixTimeSeconds())
            ;

            if (expiresIn != null)
            {
                token.AddClaim("exp", ServiceClock.CurrentTime().Add(expiresIn.Value).ToUnixTimeSeconds());
            }

            if (user.Roles != null && user.Roles.Length > 0)
            {
                token.AddClaim("roles", user.Roles);
            }
            else
            {
                token.AddClaim("roles", new string[0]);
            }

            if (user.Claims != null && user.Claims.Any())
            {
                foreach (var claim in user.Claims)
                {
                    string[] ignore = { "exp", "roles", "uid", "iat", "sub" };
                    if (!ignore.Contains(claim.Key))
                    {
                        token.AddClaim(claim.Key, claim.Value);
                    }
                }
            }

            var tokenStr = token.Encode();

            _logger.LogTrace($"Generated, token: {tokenStr}, correlationId: {correlationId}");
            return(Task.FromResult(tokenStr));
        }
Example #8
0
        protected override void RegisterTriggerActions(RegistrationFactory register)
        {
            register.OnTrigger(Trigger.Open)
            .WhenInState(State.Pending)
            .Do((req, ct) =>
            {
                var data                   = As <AccountRequest.OpenData>(req);
                CurrentData.Name           = data.Name;
                CurrentData.OpenDate       = ServiceClock.CurrentTime();
                CurrentData.Ssn            = data.Ssn;
                CurrentData.InitialBalance = req.Open.InitialBalance.GetValueOrDefault(0);
                return(Task.CompletedTask);
            });

            register.OnTrigger(Trigger.Update)
            .Do(async(req, ct) =>
            {
                await Task.CompletedTask;
                var data         = As <AccountRequest.UpdateData>(req);
                CurrentData.Name = data.Name;
                SetErrorCode(100, ErrorAction.AllowTrigger);
            });
        }
Example #9
0
        protected ThirdPartyCall(IStateRepository stateRepository)
        {
            _stateRepository = stateRepository;
            var allowManual = AllowManualOverride();

            _machine.OnTransitionCompletedAsync(async x =>
            {
                var nextSequenceNumber = await _stateRepository.StoreStateData <ThirdPartyStateData, State>(new StateDto
                {
                    Trigger        = x.Trigger.ToString(),
                    Destination    = x.Destination.ToString(),
                    MachineName    = MachineName,
                    IsReentry      = x.IsReentry,
                    Source         = x.Source.ToString(),
                    Created        = _created,
                    Modified       = _modified,
                    SequenceNumber = _sequenceNumber,
                    Identifier     = _statefulIdentifier.Identifier,
                    CorrelationId  = _correlationId
                }, _sequenceNumber, Data, saveHistory: true, _statefulIdentifier.ParentIdentifier);
                _sequenceNumber = nextSequenceNumber;
                _modified       = ServiceClock.CurrentTime();
            });

            _machine.Configure(State.BeforeRequest)
            .SubstateOf(State.InProcess);

            _machine.Configure(State.Pending)
            .SubstateOf(State.BeforeRequest)
            .Permit(Trigger.Verify, State.Verification);

            _machine.Configure(State.Verification)
            .SubstateOf(State.BeforeRequest)
            .OnEntryAsync(InternalVerify)
            .Permit(Trigger.ExecuteRequest, State.Requested)
            .Permit(Trigger.SuccessfulResponse, State.Completed)
            .Permit(Trigger.NoResponse, State.Unknown);

            _machine.Configure(State.Requested)
            .SubstateOf(State.BeforeRequest)
            .OnEntryAsync(InternalRequest)
            .Permit(Trigger.SuccessfulResponse, State.Completed)
            .Permit(Trigger.ErrorResponse, State.Error)
            .Permit(Trigger.NoResponse, State.Unknown);

            _machine.Configure(State.Error)
            .SubstateOf(State.AfterRequest)
            .Permit(Trigger.Reset, State.Pending);

            _machine.Configure(State.Unknown)
            .SubstateOf(State.AfterRequest)
            .Permit(Trigger.Reset, State.Pending);

            _machine.Configure(State.Completed)
            .SubstateOf(State.Terminal);

            _machine.Configure(State.Failed)
            .SubstateOf(State.Terminal);

            _machine.Configure(State.Pending).Permit(Trigger.ToFailed, State.Failed);
            _machine.Configure(State.Verification).Permit(Trigger.ToFailed, State.Failed);
            _machine.Configure(State.Error).Permit(Trigger.ToFailed, State.Failed);
            _machine.Configure(State.Unknown).Permit(Trigger.ToFailed, State.Failed);
            _machine.Configure(State.Completed).Permit(Trigger.ToFailed, State.Failed);

            if (allowManual)
            {
                _machine.Configure(State.Manual)
                .SubstateOf(State.AfterRequest)
                .Permit(Trigger.SuccessfulResponse, State.Completed)
                .Permit(Trigger.ErrorResponse, State.Failed);

                _machine.Configure(State.Pending).Permit(Trigger.ToManual, State.Manual);
                _machine.Configure(State.Verification).Permit(Trigger.ToManual, State.Manual);
                _machine.Configure(State.Error).Permit(Trigger.ToManual, State.Manual);
                _machine.Configure(State.Unknown).Permit(Trigger.ToManual, State.Manual);
                _machine.Configure(State.Completed).Permit(Trigger.ToManual, State.Manual);
                _machine.Configure(State.Failed).Permit(Trigger.ToManual, State.Manual);
            }
        }
Example #10
0
        public async Task <HttpResponseMessage> Handle(
            HttpRequestMessage request,
            IServiceInstance service,
            CancellationToken cancellationToken)
        {
            var start = ServiceClock.CurrentTime();

            try
            {
                var input = await _responseGenerator.ConvertRequest(service.RequestType, request);

                var output = await service.Execute(input, cancellationToken);

                var response = await _responseGenerator.ConvertResponse(request, output, service.ResponseType);

                return(response);
            }
            catch (SchemaValidationException ex)
            {
                var error = await _responseGenerator.ConvertResponse(
                    request,
                    new ServiceResponse(
                        new ResponseMetaData(
                            service.FullName,
                            service.CorrelationId == default(Guid) ? Guid.Empty : service.CorrelationId,
                            ServiceResult.ValidationError,
                            (long)(ServiceClock.CurrentTime() - start).TotalMilliseconds,
                            ServiceClock.CurrentTime(),
                            validationErrors: ex.Errors
                            )
                        ),
                    service.ResponseType);

                return(error);
            }
            catch (Exception ex)
            {
                var    serialEx        = ex as CodeWorksSerializationException;
                string originalPayload = serialEx?.RawData ?? "";

                Dictionary <string, string[]> errors = null;
                if (!string.IsNullOrWhiteSpace(originalPayload))
                {
                    errors = new Dictionary <string, string[]> {
                        ["payload"] = new[] { originalPayload }
                    };
                }

                var error = await _responseGenerator.ConvertResponse(
                    request,
                    new ServiceResponse(
                        new ResponseMetaData(
                            service.FullName,
                            service.CorrelationId == default(Guid) ? Guid.Empty : service.CorrelationId,
                            ServiceResult.PermanentError,
                            (long)(ServiceClock.CurrentTime() - start).TotalMilliseconds,
                            ServiceClock.CurrentTime(),
                            validationErrors: errors,
                            exceptionMessage: ex.ToString()
                            )
                        ),
                    service.ResponseType);

                return(error);
            }
        }
Example #11
0
        public async Task <ServiceResponse <TResponse> > Call <TRequest, TResponse>(TRequest request, IDictionary <string, object> data, CancellationToken cancellationToken) where TRequest : BaseRequest where TResponse : new()
        {
            if (data == null)
            {
                throw new ArgumentNullException(nameof(data));
            }
            Uri uri = null;

            if (data.TryGetValue("uri", out object uriObj))
            {
                uri = uriObj as Uri;
            }

            if (uri == null)
            {
                throw new Exception("Expected a data entry called \"uri\" of the type Uri with a reference to the Http Service URL");
            }

            _logger.LogTrace("Calling Uri:{uri}, Request:{request?.CorrelationId}", uri, request?.CorrelationId);

            var            options = _optionsResolver?.Options() ?? new HttpDataSerializerOptions();
            DateTimeOffset start   = ServiceClock.CurrentTime();

            _logger.LogTrace("Serializing request payload {request}, Request:{request?.CorrelationId}", request, request?.CorrelationId);
            var payload = await _dataSerializer.SerializeRequest(request, typeof(TRequest), options);

            _logger.LogTrace("Serialized request payload {payload}, Request:{request?.CorrelationId}", payload, request?.CorrelationId);

            var requestMsg = new HttpRequestMessage(HttpMethod.Post, uri);

            if (options.EnumSerializationMethod != default)
            {
                _logger.LogTrace("Options.EnumSerializationMethod:{method} RequestId:{request}",
                                 options.EnumSerializationMethod, request?.CorrelationId);
                requestMsg.Headers.Add("codeworks-prefs-enum", options.EnumSerializationMethod.ToString());
            }

            if (options.JsonSchemaValidation != default)
            {
                _logger.LogTrace("Options.JsonSchemaValidation:{method} RequestId:{request}",
                                 options.JsonSchemaValidation, request?.CorrelationId);
                requestMsg.Headers.Add("codeworks-prefs-schema-check", options.JsonSchemaValidation.ToString());
            }

            if (options.IncludeDependencyMetaData != default)
            {
                _logger.LogTrace("options.IncludeDependencyMetaData:{includeDependencyMetaData} RequestId:{{request}}",
                                 options.IncludeDependencyMetaData, request?.CorrelationId);
                requestMsg.Headers.Add("codeworks-prefs-dep-meta", options.IncludeDependencyMetaData.ToString());
            }

            requestMsg.Content = new StringContent(payload, Encoding.UTF8, "application/json");
            var apiResponse = await _client.SendAsync(requestMsg, cancellationToken);

            var responseData = await apiResponse.Content.ReadAsByteArrayAsync();

            if (_logger.IsEnabled(LogLevel.Trace))
            {
                var contents = Encoding.UTF8.GetString(responseData);
                _logger.LogTrace("Serialized response payload {contents}, Request:{request?.CorrelationId}", contents, request?.CorrelationId);
            }

            InternalServiceResponse <TResponse> response = null;

            try
            {
                response = await _dataSerializer
                           .DeserializeResponse <InternalServiceResponse <TResponse> >(responseData);
            }
            catch (CodeWorksSerializationException ex)
            {
                return(new ServiceResponse <TResponse>
                           (default(TResponse), new ResponseMetaData(
                               uri.ToString(),
                               request?.CorrelationId ?? Guid.Empty,
                               ServiceResult.PermanentError,
                               (long)(ServiceClock.CurrentTime() - start).TotalMilliseconds,
                               exceptionMessage: ex.ToString()
                               )));
            }


            Dictionary <string, ResponseMetaData> dependencies = null;

            if (options.IncludeDependencyMetaData == IncludeDependencyMetaDataStrategy.Full)
            {
                //TODO: Currently handles 1 level of dependencies - need to add recursion

                dependencies = new Dictionary <string, ResponseMetaData>
                {
                    {
                        response.MetaData.ServiceName, new ResponseMetaData(
                            response.MetaData.ServiceName,
                            response.MetaData.CorrelationId,
                            response.MetaData.Result,
                            response.MetaData.DurationMs,
                            response.MetaData.ResponseCreated,
                            response.MetaData.ErrorCodes?.ToDictionary(k => Convert.ToInt32(k.Key), v => v.Value),
                            response.MetaData.ValidationErrors,
                            response.MetaData.PublicMessage,
                            response.MetaData.ExceptionMessage,
                            response.MetaData.Dependencies
                            )
                    }
                };
            }

            var end = ServiceClock.CurrentTime();

            return(new ServiceResponse <TResponse>(
                       response.Data,
                       new ResponseMetaData(
                           $"{response.MetaData.ServiceName}.Client",
                           response.MetaData.CorrelationId,
                           response.MetaData.Result,
                           (long)(end - start).TotalMilliseconds,
                           end,
                           response.MetaData.ErrorCodes?.ToDictionary(k => Convert.ToInt32(k.Key), v => v.Value),
                           response.MetaData.ValidationErrors,
                           response.MetaData.PublicMessage,
                           response.MetaData.ExceptionMessage,
                           dependencies))); //TODO: FIX ERROR DATA
        }