Exemple #1
0
        /// <summary>
        /// Process the <see cref="ConfigurationSetReadyRequest"/>
        /// </summary>
        /// <param name="request">
        /// The request
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        private async Task OnConfigurationCheck(ConfigurationCheckRequest request)
        {
            try
            {
                using (var ds = this.GetContext())
                {
                    Context.GetLogger().Info("{Type}: checking configuration {ConfigurationId}", this.GetType().Name, request.Id);
                    var configuration = ds.Configurations.FirstOrDefault(r => r.Id == request.Id);
                    if (configuration == null)
                    {
                        this.Sender.Tell(CrudActionResponse <Configuration> .Error(new EntityNotFoundException(), null));
                        Context.GetLogger().Info(
                            "{Type}: checking configuration {ConfigurationId} - not found",
                            this.GetType().Name,
                            request.Id);
                        return;
                    }

                    if (configuration.State != EnConfigurationState.Draft)
                    {
                        this.Sender.Tell(
                            CrudActionResponse <Configuration> .Error(
                                new Exception("Only draft configurations can be checked"),
                                null));
                        Context.GetLogger().Info(
                            "{Type}: checking configuration {ConfigurationId} - not draft",
                            this.GetType().Name,
                            request.Id);
                        return;
                    }

                    var supportedFrameworks =
                        Context.System.Settings.Config.GetStringList("KlusterKite.NodeManager.SupportedFrameworks");

                    Context.GetLogger().Info(
                        "{Type}: checking configuration {ConfigurationId} against frameworks {Frameworks}",
                        this.GetType().Name,
                        request.Id,
                        string.Join(", ", supportedFrameworks));
                    var errors = await configuration.CheckAll(ds, this.nugetRepository, supportedFrameworks.ToList());

                    if (errors.Count > 0)
                    {
                        this.Sender.Tell(
                            CrudActionResponse <Configuration> .Error(new MutationException(errors.ToArray()), null));
                        Context.GetLogger().Info(
                            "{Type}: checking configuration {ConfigurationId} completed",
                            this.GetType().Name,
                            request.Id);
                        return;
                    }

                    this.Sender.Tell(CrudActionResponse <Configuration> .Success(configuration, null));
                }
            }
            catch (Exception exception)
            {
                this.Sender.Tell(CrudActionResponse <Configuration> .Error(exception, null));
            }
        }
Exemple #2
0
        /// <summary>
        /// Creates mutation response from actor response
        /// </summary>
        /// <param name="response">The actor response</param>
        /// <returns>The mutation response</returns>
        protected static MutationResult <TObject> CreateResponse(CrudActionResponse <TObject> response)
        {
            if (response.Data != null)
            {
                return(new MutationResult <TObject> {
                    Result = response.Data
                });
            }

            var errors = response.Exception.Match <List <ErrorDescription> >()
                         .With <EntityNotFoundException>(
                e => new List <ErrorDescription> {
                new ErrorDescription("id", "not found")
            })
                         .With <MutationException>(e => e.Errors)
                         .ResultOrDefault(
                e =>
            {
                var exception        = e as Exception;
                var errorDescription = new ErrorDescription(
                    "null",
                    exception != null ? $"{exception.Message}\n{exception.StackTrace}" : "unknown error");
                return(new List <ErrorDescription> {
                    errorDescription
                });
            });

            return(new MutationResult <TObject> {
                Errors = errors
            });
        }
        protected virtual async Task OnRequest <TObject, TId>(CrudActionMessage <TObject, TId> request)
            where TObject : class
        {
            CrudActionResponse <TObject> response;

            try
            {
                response = await this.ProcessRequest(request);
            }
            catch (Exception exception)
            {
                Context.GetLogger().Error(
                    exception,
                    "{Type}: Error while processing {ActionType} for {EntityType}",
                    this.GetType().Name,
                    request.ActionType,
                    typeof(TObject).Name);
                response = new CrudActionResponse <TObject> {
                    Exception = exception, ExtraData = request.ExtraData
                };
            }

            if (typeof(ILargeObject).GetTypeInfo().IsAssignableFrom(typeof(TObject)))
            {
                Context.GetParcelManager().Tell(new Parcel {
                    Payload = response, Recipient = this.Sender
                }, this.Self);
            }
            else
            {
                this.Sender.Tell(response);
            }
        }
Exemple #4
0
        /// <summary>
        /// Process the <see cref="ConfigurationSetReadyRequest"/>
        /// </summary>
        /// <param name="request">
        /// The request
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        private async Task OnConfigurationSetReady(ConfigurationSetReadyRequest request)
        {
            try
            {
                using (var ds = this.GetContext())
                {
                    var configuration = ds.Configurations.FirstOrDefault(r => r.Id == request.Id);
                    if (configuration == null)
                    {
                        this.Sender.Tell(CrudActionResponse <Configuration> .Error(new EntityNotFoundException(), null));
                        return;
                    }

                    if (configuration.State != EnConfigurationState.Draft)
                    {
                        this.Sender.Tell(
                            CrudActionResponse <Configuration> .Error(
                                new Exception("Only draft configurations can be made ready"),
                                null));
                        return;
                    }

                    if (ds.Configurations.Any(r => r.State == EnConfigurationState.Ready))
                    {
                        this.Sender.Tell(
                            CrudActionResponse <Configuration> .Error(
                                new Exception(
                                    "There is an already defined ready configuration. Please remove the previous one."),
                                null));
                        return;
                    }

                    var supportedFrameworks =
                        Context.System.Settings.Config.GetStringList("KlusterKite.NodeManager.SupportedFrameworks");
                    var errors = await configuration.CheckAll(ds, this.nugetRepository, supportedFrameworks.ToList());

                    if (errors.Count > 0)
                    {
                        this.Sender.Tell(CrudActionResponse <Configuration> .Error(new MutationException(errors.ToArray()), null));
                        return;
                    }

                    configuration.State = EnConfigurationState.Ready;
                    ds.SaveChanges();
                    this.Sender.Tell(CrudActionResponse <Configuration> .Success(configuration, null));
                    SecurityLog.CreateRecord(
                        EnSecurityLogType.OperationGranted,
                        EnSeverity.Crucial,
                        request.Context,
                        "Configuration {ConfigurationId} marked as Ready",
                        configuration.Id);
                }
            }
            catch (Exception exception)
            {
                this.Sender.Tell(CrudActionResponse <Configuration> .Error(exception, null));
            }
        }
Exemple #5
0
        /// <summary>
        /// Process the <see cref="ConfigurationSetStableRequest"/>
        /// </summary>
        /// <param name="request">The request</param>
        private void OnConfigurationSetStable(ConfigurationSetStableRequest request)
        {
            try
            {
                using (var ds = this.GetContext())
                {
                    var configuration = ds.Configurations.FirstOrDefault(r => r.Id == request.Id);
                    if (configuration == null)
                    {
                        this.Sender.Tell(CrudActionResponse <Configuration> .Error(new EntityNotFoundException(), null));
                        return;
                    }

                    if (configuration.State != EnConfigurationState.Active)
                    {
                        this.Sender.Tell(
                            CrudActionResponse <Configuration> .Error(
                                new Exception("Only active configurations can be marked as stable"),
                                null));
                        return;
                    }

                    if (configuration.IsStable != request.IsStable)
                    {
                        var error             = new ErrorDescription("isStable", "The value is not changed");
                        var mutationException = new MutationException(error);
                        this.Sender.Tell(CrudActionResponse <Configuration> .Error(mutationException, null));
                        return;
                    }

                    configuration.IsStable = request.IsStable;
                    ds.SaveChanges();
                    this.Sender.Tell(CrudActionResponse <Configuration> .Success(configuration, null));
                }
            }
            catch (Exception exception)
            {
                this.Sender.Tell(CrudActionResponse <Configuration> .Error(exception, null));
            }
        }
Exemple #6
0
        /// <summary>
        /// Process the <see cref="ConfigurationSetObsoleteRequest"/>
        /// </summary>
        /// <param name="request">The request</param>
        private void OnConfigurationSetObsolete(ConfigurationSetObsoleteRequest request)
        {
            try
            {
                using (var ds = this.GetContext())
                {
                    var configuration = ds.Configurations.FirstOrDefault(r => r.Id == request.Id);
                    if (configuration == null)
                    {
                        this.Sender.Tell(CrudActionResponse <Configuration> .Error(new EntityNotFoundException(), null));
                        return;
                    }

                    if (configuration.State != EnConfigurationState.Ready)
                    {
                        this.Sender.Tell(
                            CrudActionResponse <Configuration> .Error(
                                new Exception("Only ready configurations can be made obsolete manually"),
                                null));
                        return;
                    }

                    configuration.State = EnConfigurationState.Obsolete;
                    ds.SaveChanges();
                    this.Sender.Tell(CrudActionResponse <Configuration> .Success(configuration, null));
                    SecurityLog.CreateRecord(
                        EnSecurityLogType.OperationGranted,
                        EnSeverity.Crucial,
                        request.Context,
                        "Configuration {ConfigurationId} marked as obsolete",
                        configuration.Id);
                }
            }
            catch (Exception exception)
            {
                this.Sender.Tell(CrudActionResponse <Configuration> .Error(exception, null));
            }
        }
        protected virtual async Task <CrudActionResponse <TObject> > ProcessRequest <TObject, TId>(
            CrudActionMessage <TObject, TId> request)
            where TObject : class
        {
            using (var ds = this.GetContext())
            {
                var factory = DataFactory <TContext, TObject, TId> .CreateFactory(this.ComponentContext, ds);

                switch (request.ActionType)
                {
                case EnActionType.Get:
                    try
                    {
                        var result = await factory.Get(request.Id);

                        if (result.HasValue)
                        {
                            result = this.OnSelect(result.Value);
                        }

                        // security read log should be set on client endpoint
                        return(result.HasValue
                                       ? CrudActionResponse <TObject> .Success(result, request.ExtraData)
                                       : CrudActionResponse <TObject> .Error(
                                   new EntityNotFoundException(),
                                   request.ExtraData));
                    }
                    catch (Exception exception)
                    {
                        return(CrudActionResponse <TObject> .Error(
                                   new DatasourceInnerException("Exception on Get operation", exception),
                                   request.ExtraData));
                    }

                case EnActionType.Create:
                {
                    var entity = request.Data;
                    if (entity == null)
                    {
                        return(CrudActionResponse <TObject> .Error(
                                   new RequestEmptyException(),
                                   request.ExtraData));
                    }

                    entity = this.BeforeCreate(entity);
                    var oldObject = await factory.Get(factory.GetId(entity));

                    if (oldObject != null)
                    {
                        var crudActionResponse = CrudActionResponse <TObject> .Error(
                            new InsertDuplicateIdException(),
                            request.ExtraData);

                        crudActionResponse.Data = oldObject;

                        return(crudActionResponse);
                    }

                    if (entity == null)
                    {
                        return(CrudActionResponse <TObject> .Error(
                                   new BeforeActionException(),
                                   request.ExtraData));
                    }

                    try
                    {
                        await factory.Insert(entity);

                        // security update logs are set here to be sure that they are made independently of client notification success
                        SecurityLog.CreateRecord(
                            EnSecurityLogType.DataCreateGranted,
                            entity is ICrucialObject ? EnSeverity.Crucial : EnSeverity.Trivial,
                            request.RequestContext,
                            "{ObjectType} with {ObjectId} id was created",
                            typeof(TObject).FullName,
                            factory.GetId(entity));

                        this.AfterCreate(entity);
                        return(CrudActionResponse <TObject> .Success(entity, request.ExtraData));
                    }
                    catch (Exception exception)
                    {
                        return(CrudActionResponse <TObject> .Error(
                                   new DatasourceInnerException("Exception on Insert operation", exception),
                                   request.ExtraData));
                    }
                }

                case EnActionType.Update:
                {
                    var entity = request.Data;
                    if (entity == null)
                    {
                        return(CrudActionResponse <TObject> .Error(
                                   new RequestEmptyException(),
                                   request.ExtraData));
                    }

                    var oldObject = await factory.Get(request.Id);

                    if (oldObject == null)
                    {
                        return(CrudActionResponse <TObject> .Error(
                                   new EntityNotFoundException(),
                                   request.ExtraData));
                    }

                    if (request.ApiRequest != null)
                    {
                        var updatedObject = await factory.Get(request.Id);

                        if (updatedObject == null)
                        {
                            return(CrudActionResponse <TObject> .Error(
                                       new EntityNotFoundException(),
                                       request.ExtraData));
                        }

                        DataUpdater <TObject> .Update(updatedObject, entity, request.ApiRequest);

                        entity = updatedObject;
                    }

                    entity = this.BeforeUpdate <TObject>(entity, oldObject);
                    if (entity == null)
                    {
                        return(CrudActionResponse <TObject> .Error(
                                   new BeforeActionException(),
                                   request.ExtraData));
                    }

                    try
                    {
                        await factory.Update(entity, oldObject);

                        // security update logs are set here to be sure that they are made independently of client notification success
                        if (!factory.GetId(entity).Equals(factory.GetId(oldObject)))
                        {
                            SecurityLog.CreateRecord(
                                EnSecurityLogType.DataUpdateGranted,
                                entity is ICrucialObject ? EnSeverity.Crucial : EnSeverity.Trivial,
                                request.RequestContext,
                                "{ObjectType} with id {ObjectId} was updated. New id is {NewObjectId}",
                                typeof(TObject).FullName,
                                factory.GetId(oldObject),
                                factory.GetId(entity));
                        }
                        else
                        {
                            SecurityLog.CreateRecord(
                                EnSecurityLogType.DataUpdateGranted,
                                entity is ICrucialObject ? EnSeverity.Crucial : EnSeverity.Trivial,
                                request.RequestContext,
                                "{ObjectType} with id {ObjectId} was updated.",
                                typeof(TObject).FullName,
                                factory.GetId(entity));
                        }

                        this.AfterUpdate <TObject>(entity, oldObject);
                        return(CrudActionResponse <TObject> .Success(entity, request.ExtraData));
                    }
                    catch (Exception exception)
                    {
                        return(CrudActionResponse <TObject> .Error(
                                   new DatasourceInnerException("Exception on Update operation", exception),
                                   request.ExtraData));
                    }
                }

                case EnActionType.Delete:
                {
                    var oldObject = await factory.Get(request.Id);

                    if (oldObject == null)
                    {
                        return(CrudActionResponse <TObject> .Error(
                                   new EntityNotFoundException(),
                                   request.ExtraData));
                    }

                    oldObject = this.BeforeDelete(oldObject.Value);
                    if (oldObject == null)
                    {
                        return(CrudActionResponse <TObject> .Error(
                                   new BeforeActionException(),
                                   request.ExtraData));
                    }

                    try
                    {
                        oldObject = await factory.Delete(factory.GetId(oldObject));
                    }
                    catch (Exception exception)
                    {
                        return(CrudActionResponse <TObject> .Error(
                                   new DatasourceInnerException("Exception on Delete operation", exception),
                                   request.ExtraData));
                    }

                    if (oldObject == null)
                    {
                        return(CrudActionResponse <TObject> .Error(
                                   new EntityNotFoundException("After \"Before\" action modification"),
                                   request.ExtraData));
                    }

                    // security update logs are set here to be sure that they are made independently of client notification success
                    SecurityLog.CreateRecord(
                        EnSecurityLogType.DataDeleteGranted,
                        oldObject.Value is ICrucialObject ? EnSeverity.Crucial : EnSeverity.Trivial,
                        request.RequestContext,
                        "{ObjectType} with id {ObjectId} was deleted.",
                        typeof(TObject).FullName,
                        factory.GetId(oldObject));

                    this.AfterDelete <TObject>(oldObject);
                    return(CrudActionResponse <TObject> .Success(oldObject, request.ExtraData));
                }

                default:
                    return(CrudActionResponse <TObject> .Error(
                               new ArgumentOutOfRangeException(nameof(request.ActionType)),
                               request.ExtraData));
                }
            }
        }