예제 #1
0
 public bool IsProduce(MessageContext context, NodeDescriptor toNode)
 {
     if (context == null)
     {
         throw new ArgumentNullException("context");
     }
     if (toNode == null)
     {
         throw new ArgumentNullException("toNode");
     }
     if (toNode.Node.IsEnabled != 1
         || toNode.Node.IsProduceEnabled == false
         || !toNode.IsCareForOntology(context.Ontology)
         || (context.Command.Verb == Verb.Update
             && context.InfoTuplePair.ValueTuple.All(a => !toNode.IsCareforElement(a.Element))))
     {
         return false;
     }
     return true;
 }
        /// <summary>
        /// 验证Level1、Level2、Level3、Level4级权限。
        /// <remarks>
        /// 其它级权限不要在此验证。
        /// </remarks>
        /// </summary>
        /// <param name="context">命令上下文</param>
        /// <returns></returns>
        public ProcessResult Validate(MessageContext context)
        {
            // Level1Action
            #region 验证动作级权限
            ActionState action;
            if (!context.Ontology.Actions.TryGetValue(context.Command.Verb, out action))
            {
                throw new AnycmdException("非法的动作类型");
            }
            switch (action.AllowType)
            {
                case AllowType.Invalid:
                    return new ProcessResult(false, Status.NoPermission, "意外的AllowType:Invalid");
                case AllowType.ExplicitAllow:
                    return ProcessResult.Ok;
                case AllowType.ImplicitAllow:
                    break;
                case AllowType.NotAllow:
                    return new ProcessResult(false, Status.NoPermission, "已禁止" + context.Ontology.Actions[context.Command.Verb].Name + context.Ontology.Ontology.Name);
                default:
                    return new ProcessResult(false, Status.NoPermission, "意外的AllowType:" + action.AllowType.ToName());
            }
            #endregion
            // Level2ElementAction
            #region 验证本体元素级权限
            foreach (var infoIdItem in context.InfoTuplePair.IdTuple)
            {
                var elementActions = infoIdItem.Element.Element.ElementActions;
                IElement element = infoIdItem.Element.Element;
                bool getConfiged = elementActions.ContainsKey(Verb.Get);
                bool headConfiged = elementActions.ContainsKey(Verb.Head);
                if (!getConfiged && !headConfiged)
                {
                    return new ProcessResult(false, Status.NoPermission, element.Name + "无法进入InfoID项,因为它既不可get又不可head");
                }
                if ((getConfiged && elementActions[Verb.Get].AllowType == AllowType.NotAllow)
                    && (headConfiged && elementActions[Verb.Head].AllowType == AllowType.NotAllow))
                {
                    return new ProcessResult(false, Status.NoPermission, element.Name + "无法进入InfoID项,因为已禁止get和head" + element.Name);
                }
            }
            bool isUpdate = Verb.Update.Equals(context.Command.Verb);
            foreach (InfoItem infoValueItem in context.InfoTuplePair.ValueTuple)
            {
                var elementActions = infoValueItem.Element.Element.ElementActions;
                IElement element = infoValueItem.Element.Element;
                if (!elementActions.ContainsKey(context.Command.Verb))
                {
                    return new ProcessResult(false, Status.NoPermission, "已禁止" + context.Ontology.Actions[context.Command.Verb].Name + element.Name);
                }
                switch (elementActions[context.Command.Verb].AllowType)
                {
                    case AllowType.Invalid:
                        return new ProcessResult(false, Status.NoPermission, "意外的AllowType:Invalid");
                    case AllowType.ExplicitAllow:
                        return ProcessResult.Ok;
                    case AllowType.ImplicitAllow:
                        break;
                    case AllowType.NotAllow:
                        return new ProcessResult(false, Status.NoPermission, "已禁止" + context.Ontology.Actions[context.Command.Verb].Name + element.Name);
                    default:
                        return new ProcessResult(false, Status.NoPermission, "意外的AllowType:Invalid");
                }
                if (isUpdate && string.IsNullOrWhiteSpace(infoValueItem.Value))
                {
                    if (!elementActions.ContainsKey(Verb.Delete))
                    {
                        return new ProcessResult(false, Status.NoPermission, "已禁止" + context.Ontology.Actions[Verb.Delete].Name + element.Name);
                    }
                    switch (elementActions[Verb.Delete].AllowType)
                    {
                        case AllowType.Invalid:
                            return new ProcessResult(false, Status.NoPermission, "意外的AllowType:Invalid");
                        case AllowType.ExplicitAllow:
                            return ProcessResult.Ok;
                        case AllowType.ImplicitAllow:
                            break;
                        case AllowType.NotAllow:
                            return new ProcessResult(false, Status.NoPermission, "已禁止" + context.Ontology.Actions[Verb.Delete].Name + element.Name);
                        default:
                            return new ProcessResult(false, Status.NoPermission, "意外的AllowType:Invalid");
                    }
                }
            }
            #endregion
            // Level3ClientAction
            #region 验证节点动作级级权限
            var allowType = context.ClientAgent.GetOntologyPermission(context.Ontology, context.Command.Verb);
            switch (allowType)
            {
                case AllowType.Invalid:
                    return new ProcessResult(false, Status.NoPermission, "意外的AllowType:Invalid");
                case AllowType.ExplicitAllow:
                    return ProcessResult.Ok;
                case AllowType.ImplicitAllow:
                    break;
                case AllowType.NotAllow:
                    return new ProcessResult(false, Status.NoPermission, "已禁止" + context.ClientAgent.Name + context.Ontology.Actions[Verb.Delete].Name + context.Ontology.Ontology.Name);
                default:
                    return new ProcessResult(false, Status.NoPermission, "意外的AllowType:Invalid");
            }
            #endregion
            // Level4ClientElementAction
            #region 节点动作权限验证
            foreach (var infoIdItem in context.InfoTuplePair.IdTuple)
            {
                if (context.ClientAgent.GetElementPermission(infoIdItem.Element, Verb.Get) == AllowType.NotAllow
                    && context.ClientAgent.GetElementPermission(infoIdItem.Element, Verb.Head) == AllowType.NotAllow)
                {
                    return new ProcessResult(false, Status.NoPermission, string.Format("{0}不能进入InfoID项,因为来源节点既没有get{0}的权限又没有head{0}的权限", infoIdItem.Element.Element.Name));
                }
            }
            foreach (InfoItem infoValueItem in context.InfoTuplePair.ValueTuple)
            {
                IElement element = infoValueItem.Element.Element;
                if (context.ClientAgent.GetElementPermission(infoValueItem.Element, context.Command.Verb) == AllowType.NotAllow)
                {
                    return new ProcessResult(false, Status.NoPermission, string.Format("客户端'" + context.ClientAgent.Name + "'没有{0}{1}的权限", context.Ontology.Actions[context.Command.Verb].Name, element.Name));
                }
                if (isUpdate && string.IsNullOrWhiteSpace(infoValueItem.Value))
                {
                    if (context.ClientAgent.GetElementPermission(infoValueItem.Element, Verb.Delete) == AllowType.NotAllow)
                    {
                        return new ProcessResult(false, Status.NoPermission, string.Format("客户端'" + context.ClientAgent.Name + "'没有{0}{1}的权限", context.Ontology.Actions[Verb.Delete].Name, element.Name));
                    }
                }
            }
            #endregion

            return ProcessResult.Ok;
        }
예제 #3
0
        /// <summary>
        /// 命令响应。进入此方法标示者进入
        /// </summary>
        /// <returns></returns>
        public void Response(MessageContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }
            try
            {
                if (!context.Result.IsClosed)
                {
                    var requestType = context.Command.MessageType;
                    if (!context.IsValid)
                    {
                        if (!context.Result.ResultDataItems.Any(a => a.Key.Equals("Id", StringComparison.OrdinalIgnoreCase)))
                        {
                            context.Result.ResultDataItems.Add(new DataItem("Id", context.LocalEntityId));
                        }
                        if (context.Command is IEntity)
                        {
                            using (var cmdProviderAct = new WfAct(context.Host, context, context.Ontology.MessageProvider, "保存执行失败的命令"))
                            {
                                if (requestType == MessageType.Action || context.Command.CommandType == MessageTypeKind.Received)
                                {
                                    context.Ontology.MessageProvider.SaveCommand(context.Ontology, context.Command.ToExecuteFailing(context.Result));
                                }
                                else if (requestType == MessageType.Command)
                                {
                                    context.Ontology.MessageProvider.SaveCommand(context.Ontology, context.Command.ToUnaccepted(context.Result));
                                }
                            }
                            context.Ontology.MessageProvider.DeleteCommand(context.Command.CommandType, context.Ontology, context.Command.Id, context.Command.IsDumb);
                        }
                    }
                    else
                    {
                        if (!context.Result.ResultDataItems.Any(a => a.Key.Equals("Id", StringComparison.OrdinalIgnoreCase)))
                        {
                            context.Result.ResultDataItems.Add(new DataItem("Id", context.LocalEntityId));
                        }
                        if (Verb.Get.Equals(context.Command.Verb))
                        {
                            using (var act = new WfAct(context.Host, context, context.Ontology.EntityProvider, "填充get型命令的InfoValue字段"))
                            {
                                var selectElements = new OrderedElementSet();
                                foreach (var element in context.Ontology.Elements.Values.Where(a => a.Element.IsEnabled == 1))
                                {
                                    if (context.ClientAgent.GetElementPermission(element, Verb.Get) != AllowType.NotAllow)
                                    {
                                        selectElements.Add(element);
                                    }
                                }
                                IList<InfoItem> infoValues = context.Ontology.EntityProvider.Get(
                                    context.Ontology, context.LocalEntityId, selectElements);
                                context.Result.ResultDataItems = infoValues.Select(a => new DataItem(a.Key, a.Value)).ToList();
                            }
                        }
                        var nodeHost = context.Host.NodeHost;
                        // ApplyProcessingFilters 应用处理前过滤器
                        ProcessResult result = nodeHost.ApplyEdiMessageHandingFilters(context);
                        if (!result.IsSuccess)
                        {
                            context.Result.UpdateStatus(result.StateCode, result.Description);
                        }
                        if (!context.Result.IsClosed)
                        {
                            switch (requestType)
                            {
                                case MessageType.Action:
                                    HandleAction(context);
                                    break;
                                case MessageType.Command:
                                    HandleCommand(context);
                                    break;
                                case MessageType.Event:
                                    HandleEvent(context);
                                    break;
                                default:
                                    throw new AnycmdException("意外的请求类型" + context.Command.MessageType);
                            }

                            // ApplyProcessedFilters 应用处理后过滤器
                            result = nodeHost.ApplyEdiMessageHandledFilters(context);
                            if (!result.IsSuccess)
                            {
                                context.Result.UpdateStatus(result.StateCode, result.Description);
                            }
                        }
                    }
                }
                int stateCode = context.Result.Status;
                if (stateCode < 200)
                {
                    IInfoStringConverter converter;
                    if (!context.Host.NodeHost.InfoStringConverters.TryGetInfoStringConverter(context.Command.DataTuple.InfoFormat, out converter))
                    {
                        throw new AnycmdException("意外的信息格式" + context.Command.DataTuple.InfoFormat);
                    }
                    var anyLog = new AnyLog(Guid.NewGuid())
                    {
                        Req_Ontology = context.Ontology.Ontology.Code,
                        Req_Verb = context.Command.Verb.Code,
                        Req_ClientId = context.Command.ClientId,
                        Req_ClientType = context.Command.ClientType.ToName(),
                        CreateOn = context.Command.CreateOn,
                        Req_Description = context.Command.Description,
                        Req_EventSourceType = context.Command.EventSourceType,
                        Req_EventSubjectCode = context.Command.EventSubjectCode,
                        InfoFormat = context.Command.DataTuple.InfoFormat,
                        Req_InfoId = context.Command.DataTuple.IdItems.InfoString,
                        Req_InfoValue = context.Command.DataTuple.ValueItems.InfoString,
                        Req_UserName = context.Command.UserName,
                        Req_IsDumb = context.Command.IsDumb,
                        LocalEntityId = context.Command.LocalEntityId,
                        CatalogCode = context.Command.CatalogCode,
                        Req_ReasonPhrase = context.Command.ReasonPhrase,
                        ReceivedOn = context.Command.ReceivedOn,
                        Req_MessageId = context.Command.MessageId,
                        Req_MessageType = context.Command.MessageType.ToName(),
                        Req_QueryList = context.Command.DataTuple.QueryListString,
                        Req_Status = context.Command.Status,
                        Req_TimeStamp = context.Command.TimeStamp,
                        Req_Version = context.Command.Version,
                        Res_InfoValue = converter.ToInfoString(context.Result.ResultDataItems),
                        Res_Description = context.Result.Description,
                        Res_ReasonPhrase = context.Result.ReasonPhrase,
                        Res_StateCode = (int)context.Result.Status
                    };
                    context.Ontology.Host.LoggingService.Log(anyLog);
                }
            }
            catch (Exception ex)
            {
                context.Result.UpdateStatus(Status.InternalServerError, "服务器内部逻辑异常");
                context.Result.IsClosed = true;
                context.Exception = ex;
                throw;
            }
        }
예제 #4
0
        /// <summary>
        /// 处理事件。Event类型的命令是面向主题和状态码编程的。
        /// </summary>
        /// <returns></returns>
        private static void HandleEvent(MessageContext context)
        {
            EventSourceType eventSourceType;
            context.Command.EventSourceType.TryParse(out eventSourceType);
            switch (eventSourceType)
            {
                case EventSourceType.Command:
                    {
                        #region 命令事件
                        // 如果是审计节点的审计事件
                        if (context.Command.EventSubjectCode.Equals(EventSubjectCode.StateCodeChanged_Audit)
                                && (context.ClientAgent == context.Host.NodeHost.Nodes.ThisNode))
                        {
                            #region 审计节点事件
                            var localEvent = context.Ontology.MessageProvider.GetCommand(MessageTypeKind.LocalEvent,
                                context.Ontology, new Guid(context.Command.MessageId));
                            if (localEvent == null)
                            {
                                context.Result.UpdateStatus(Status.NotExist, "给定的MessageID标识的服务端事件不存在。");
                                return;
                            }
                            if (!Verb.Create.Equals(localEvent.Verb))
                            {
                                long total;
                                var localEvents = context.Ontology.MessageProvider.GetPlistCommands(MessageTypeKind.LocalEvent, context.Ontology, null, null, null, localEvent.LocalEntityId, 0, 1, "CreateOn", "asc", out total);
                                if (localEvents[0].Id != localEvent.Id)
                                {
                                    context.Result.UpdateStatus(Status.InvalidCommandTicks, "请按照时间顺序审核命令");
                                    return;
                                }
                            }
                            using (var act = new WfAct(context.Host, context, context.Ontology.MessageProvider, "审核完成"))
                            {
                                var ctx = new MessageContext(context.Host, localEvent);
                                if (context.Command.Status == (int)Status.AuditApproved)
                                {
                                    localEvent.IsDumb = context.Command.IsDumb;
                                    #region 执行
                                    using (var sqlAct = new WfAct(context.Host, ctx, ctx.Ontology.EntityProvider, "执行命令"))
                                    {
                                        // 注意:执行的是本地事件,而不是请求事件
                                        var actionCode = ctx.Command.Verb;
                                        var r = ctx.Ontology.EntityProvider.ExecuteCommand(ctx.ToDbCommand());
                                        context.Result.UpdateStatus(r.StateCode, r.Description);
                                        ctx.Result.UpdateStatus(r.StateCode, r.Description);

                                        if (r.IsSuccess)
                                        {
                                            ctx.Ontology.MessageProvider.SaveCommand(ctx.Ontology, ctx.Command.ToExecuted(context.Result));

                                            var commandFactory = context.Host.NodeHost.MessageProducer;
                                            using (var factoryAct = new WfAct(context.Host, ctx, commandFactory, "生产命令"))
                                            {
                                                var products = commandFactory.Produce(new MessageTuple(ctx, GetTuple(ctx)));
                                                // 保存生产的待分发命令
                                                if (products != null && products.Count != 0)
                                                {
                                                    ctx.Ontology.MessageProvider.SaveCommands(ctx.Ontology, products.ToArray());
                                                }
                                            }
                                        }
                                        else
                                        {
                                            ctx.Ontology.MessageProvider.SaveCommand(ctx.Ontology, ctx.Command.ToExecuteFailing(context.Result));
                                        }
                                    }
                                    #endregion
                                }
                                else
                                {
                                    using (var cmdProviderAct = new WfAct(context.Host, ctx, ctx.Ontology.MessageProvider, "保存执行失败的命令"))
                                    {
                                        ctx.Ontology.MessageProvider.SaveCommand(ctx.Ontology, ctx.Command.ToExecuteFailing(context.Result));
                                    }
                                    context.Result.UpdateStatus(Status.AuditUnapproved, "审计未通过");
                                }
                                ctx.Ontology.MessageProvider.DeleteCommand(MessageTypeKind.LocalEvent, ctx.Ontology, localEvent.Id, context.Command.IsDumb);
                            }
                            #endregion
                        }
                        else
                        {
                            var distrubutedCommand = context.Ontology.MessageProvider.GetCommand(MessageTypeKind.Distributed,
                                context.Ontology, new Guid(context.Command.MessageId));
                            if (distrubutedCommand == null)
                            {
                                context.Result.UpdateStatus(Status.NotExist, "给定的MessageID标识的服务端命令不存在。服务端认为没有向您的节点分发过MessageID为" + context.Command.MessageId + "的命令");
                            }
                            else
                            {
                                using (var act = new WfAct(context.Host, context, context.Ontology.MessageProvider, context.Result.Description))
                                {
                                    context.Ontology.MessageProvider.SaveCommand(context.Ontology, context.Command.ToClientEvent(context.Result));
                                }
                                context.Result.UpdateStatus(Status.ReceiveOk, "接收成功");
                            }
                        }
                        break;
                        #endregion
                    }
                case EventSourceType.Entity:
                    {
                        #region 实体事件
                        context.Result.UpdateStatus(Status.Nonsupport, "暂不支持客户端实体事件");
                        break;
                        #endregion
                    }
                default:
                    context.Exception = new AnycmdException("意外的事件源类型");
                    throw context.Exception;
            }
        }
예제 #5
0
 private static void PublishAuditEvent(MessageContext context)
 {
     #region 审核事件
     using (var auditAct = new WfAct(context.Host, context, context.Ontology.MessageProvider, "持久化本地事件,转化为待分发事件打入分发队列"))
     {
         var evnt = new MessageEntity(MessageTypeKind.LocalEvent, context.Command.Id, context.Command.DataTuple)
         {
             Verb = context.Command.Verb,
             ClientType = context.Command.ClientType,
             ReceivedOn = context.Command.ReceivedOn,
             TimeStamp = context.Command.TimeStamp,
             CreateOn = DateTime.Now,
             LocalEntityId = context.LocalEntityId,
             CatalogCode = context.CatalogCode,
             ClientId = context.Command.ClientId,
             Ontology = context.Command.Ontology,
             Status = (int)context.Result.Status,
             ReasonPhrase = context.Result.ReasonPhrase,
             Description = context.Result.Description,
             MessageId = context.Command.MessageId,
             EventSourceType = EventSourceType.Command.ToName(),
             EventSubjectCode = EventSubjectCode.StateCodeChanged_Audit,
             MessageType = context.Command.MessageType,
             UserName = context.Command.UserName,
             IsDumb = context.Command.IsDumb,
             Version = context.Command.Version
         };
         // 持久化本地事件
         context.Ontology.MessageProvider.SaveCommand(context.Ontology, evnt);
         // 如果是之前已经接收的命令,但现在需要审核了。这往往是因为成功接收后系统配置有变化
         if (context.Command is IEntity)
         {
             context.Ontology.MessageProvider.DeleteCommand(MessageTypeKind.Received, context.Ontology, context.Command.Id, context.Command.IsDumb);
         }
     }
     #endregion
 }
예제 #6
0
 /// <summary>
 /// 执行。Action类型的命令是立即执行的。
 /// <remarks>
 /// 该执行不会从成功接收的命令表中删除已执行的记录。
 /// </remarks>
 /// </summary>
 /// <exception cref="AnycmdException">
 /// 当当前命令不是成功接收的命令时或者当前命令的动作码是get或head时引发
 /// </exception>
 /// <returns></returns>
 private static void HandleAction(MessageContext context)
 {
     if (context.NeedAudit)
     {
         PublishAuditEvent(context);
         return;
     }
     context.Result.UpdateStatus(Status.ExecuteOk, "执行成功");
     if (Verb.Get.Equals(context.Command.Verb)
         || Verb.Head.Equals(context.Command.Verb))
     {
         return;
     }
     #region 执行
     using (var act = new WfAct(context.Host, context, context.Ontology.EntityProvider, context.Ontology.EntityProvider.Description))
     {
         using (var sqlAct = new WfAct(context.Host, context, context.Ontology.EntityProvider, "执行命令"))
         {
             Verb actionCode = context.Command.Verb;
             ProcessResult r = context.Ontology.EntityProvider.ExecuteCommand(context.ToDbCommand());
             context.Result.UpdateStatus(r.StateCode, r.Description);
             // 执行成功
             if (r.IsSuccess)
             {
                 using (var cmdProviderAct = new WfAct(context.Host, context, context.Ontology.MessageProvider, "保存成功执行的命令和由于命令执行而生产的待分发命令"))
                 {
                     #region 如果是正在接收的命令
                     if (!(context.Command is IEntity))
                     {
                         context.Ontology.MessageProvider.SaveCommand(context.Ontology, context.Command.ToExecuted(context.Result));
                     }
                     #endregion
                     #region 如果是以前接收的命令
                     else if (context.Command is IEntity)
                     {
                         context.Ontology.MessageProvider.SaveCommand(context.Ontology, context.Command.ToExecuted(context.Result));
                         context.Ontology.MessageProvider.DeleteCommand(MessageTypeKind.Received, context.Ontology, context.Command.Id, context.Command.IsDumb);
                     }
                     #endregion
                     #region 建造待分发命令
                     var commandFactory = context.Host.NodeHost.MessageProducer;
                     using (var factoryAct = new WfAct(context.Host, context, commandFactory, "命令工厂建造待分发命令"))
                     {
                         var products = commandFactory.Produce(new MessageTuple(context, GetTuple(context)));
                         // 保存生产的待分发命令
                         if (products != null && products.Count != 0)
                         {
                             context.Ontology.MessageProvider.SaveCommands(context.Ontology, products.ToArray());
                         }
                     }
                     #endregion
                 }
             }
             // 执行失败
             else
             {
                 using (var cmdProviderAct = new WfAct(context.Host, context, context.Ontology.MessageProvider, "保存执行失败的命令"))
                 {
                     context.Ontology.MessageProvider.SaveCommand(context.Ontology, context.Command.ToExecuteFailing(context.Result));
                     if (context.Command is IEntity)
                     {
                         context.Ontology.MessageProvider.DeleteCommand(MessageTypeKind.Received, context.Ontology, context.Command.Id, context.Command.IsDumb);
                     }
                 }
             }
         }
     }
     #endregion
 }
예제 #7
0
 /// <summary>
 /// 接收MessageType为Command的命令。Command类型的命令是推迟执行的。
 /// </summary>
 /// <returns></returns>
 private static void HandleCommand(MessageContext context)
 {
     if (context.Command.CommandType == MessageTypeKind.Received)
     {
         HandleAction(context);
         return;
     }
     context.Result.UpdateStatus(Status.ReceiveOk, "接收成功");
     if (context.NeedAudit)
     {
         PublishAuditEvent(context);
         return;
     }
     else
     {
         // 如果当前命令不是DTO则不需要持久化
         if (context.Command is IEntity)
         {
             return;
         }
         // 如果当前本体动作配置为不需要持久化则不持久化
         if (context.Ontology.Actions[context.Command.Verb].IsPersist)
         {
             using (var act = new WfAct(context.Host, context, context.Ontology.MessageProvider, "持久化成功接收的命令"))
             {
                 var r = context.Ontology.MessageProvider.SaveCommand(context.Ontology, context.Command.ToReceived(context.Result));
                 if (!r.IsSuccess)
                 {
                     context.Result.UpdateStatus(r.StateCode, r.Description);
                 }
             }
         }
     }
 }
예제 #8
0
 private static InfoItem[] GetTuple(MessageContext context)
 {
     if (context.Command.Verb == Verb.Create)
     {
         var items = new List<InfoItem>();
         var commandFactory = context.Host.NodeHost.MessageProducer;
         foreach (var node in context.Host.NodeHost.Nodes)
         {
             if (commandFactory.IsProduce(context, node))
             {
                 bool isCare = false;
                 foreach (var item in context.InfoTuplePair.ValueTuple)
                 {
                     if (node.IsCareforElement(item.Element))
                     {
                         isCare = true;
                         items.Add(item);
                     }
                 }
                 if (isCare)
                 {
                     foreach (var element in node.GetInfoIdElements())
                     {
                         items.Add(InfoItem.Create(element, string.Empty));
                     }
                 }
             }
         }
         return items.ToArray();
     }
     return context.TowInfoTuple.SingleInfoTuple;
 }
예제 #9
0
 /// <summary>
 /// 
 /// </summary>
 /// <param name="acDomain"></param>
 /// <param name="context"></param>
 public static MessageContext Create(IAcDomain acDomain, HecpContext context)
 {
     if (context == null)
     {
         throw new ArgumentNullException("context");
     }
     var commandContext = new MessageContext(acDomain, AnyMessage.Create(context.Request, acDomain.NodeHost.Nodes.ThisNode));
     foreach (var act in context)
     {
         commandContext.Trace(act);
     }
     return commandContext;
 }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public DiscriminateResult IsNeedAudit(MessageContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }
            var requestType = context.Command.MessageType;
            // 如果是事件则不需要审核
            if (requestType == MessageType.Event || requestType == MessageType.Undefined)
            {
                return DiscriminateResult.No;
            }
            // 如果未验证通过则不需要审核
            if (context.Ontology == null)
            {
                return DiscriminateResult.No;
            }
            // Level1Action 如果本体动作不需要审核则不审核
            #region Level1Action
            ActionState action;
            if (!context.Ontology.Actions.TryGetValue(context.Command.Verb, out action))
            {
                throw new AnycmdException("非法的动作类型");
            }
            var auditType = action.AuditType;
            switch (auditType)
            {
                case AuditType.Invalid:
                    return new DiscriminateResult(false, "意外的审核类型Invalid");
                case AuditType.ExplicitAudit:
                    return DiscriminateResult.Yes;
                case AuditType.ImplicitAudit:
                    break;
                case AuditType.NotAudit:
                    return DiscriminateResult.No;
                default:
                    return new DiscriminateResult(false, "意外的审核类型" + auditType.ToName());
            }
            #endregion
            // Level2ElementAction 如果所有本体元素都不需要审核则不审核
            #region Level2ElementAction
            if (context.InfoTuplePair == null)
            {
                return DiscriminateResult.No;
            }
            var isAudit = false;
            foreach (var elementActionDic in context.InfoTuplePair.ValueTuple.Select(a => a.Element.Element.ElementActions))
            {
                if (elementActionDic.ContainsKey(context.Command.Verb))
                {
                    continue;
                }
                var elementAction = elementActionDic[context.Command.Verb];
                switch (elementAction.AuditType)
                {
                    case AuditType.Invalid:
                        return new DiscriminateResult(false, "意外的审核类型Invalid");
                    case AuditType.ExplicitAudit:
                        isAudit = true;
                        return DiscriminateResult.Yes;
                    case AuditType.ImplicitAudit:
                        break;
                    case AuditType.NotAudit:
                        break;
                    default:
                        return new DiscriminateResult(false, "意外的审核类型" + auditType.ToName());
                }
            }
            if (isAudit)
            {
                return DiscriminateResult.Yes;
            }
            #endregion
            // Level3ClientAction 如果来源节点的这个本体动作不需要审核则不审核
            #region Level3ClientAction
            if (context.ClientAgent.GetOntologyAudit(context.Ontology, context.Command.Verb) == AuditType.NotAudit)
            {
                return DiscriminateResult.No;
            }
            #endregion
            // Level4ClientElementAction 如果来自来源节点的当前命令的所有涉及元素不需要审核则不审核
            #region Level4ClientElementAction
            var isA = false;
            ElementDescriptor auditElement = null;
            foreach (var valueItem in context.InfoTuplePair.ValueTuple)
            {
                isA = context.ClientAgent.GetElementAudit(valueItem.Element, context.Command.Verb) != AuditType.NotAudit;
                if (isA)
                {
                    auditElement = valueItem.Element;
                    break;
                }
            }
            if (!isA)
            {
                return DiscriminateResult.No;
            }
            #endregion
            if (context.Ontology.Ontology.IsCataloguedEntity)
            {
                // Level5CatalogAction 如果是目录型本体且当前实体所属的目录的这个本体动作不需要审核则不审核
                #region Level5CatalogAction
                CatalogState org;
                if (!context.Host.CatalogSet.TryGetCatalog(context.CatalogCode, out org))
                {
                    throw new AnycmdException("非法的目录码" + context.CatalogCode);
                }
                OntologyCatalogState ontologyOrg;
                if (!context.Ontology.Catalogs.TryGetValue(org, out ontologyOrg))
                {
                    context.Exception = new AnycmdException("非法的目录码。非法的目录码的命令应该未验证通过,不应该走到这一步");
                    throw context.Exception;
                }
                var orgActions = ontologyOrg.CatalogActions;
                if (!orgActions.ContainsKey(context.Command.Verb) || orgActions[context.Command.Verb].AuditType == AuditType.NotAudit)
                {
                    return DiscriminateResult.No;
                }
                else
                {
                    string msg = string.Empty;
                    if (auditElement != null && !auditElement.Element.Code.Equals("ZZJGM", StringComparison.OrdinalIgnoreCase))
                    {
                        msg = "在" + org.Name + "下" + action.Name + context.Ontology.Ontology.Name + auditElement.Element.Name + "需要审核。审核消息已发出,请等待管理员处理";
                    }
                    else
                    {
                        msg = "在" + org.Name + "下" + action.Name + context.Ontology.Ontology.Name + "需要审核。审核消息已发出,请等待管理员处理";
                    }
                    return new DiscriminateResult(true, msg);
                }
                #endregion

                // Level6EntityAction

                // Level7EntityElementAction
            }
            return new DiscriminateResult(true, "需要审核");
        }
예제 #11
0
        public ProcessResult Validate(MessageContext context)
        {
            if (context == null)
            {
                return new ProcessResult(false, Status.NoneCommand, "空命令");
            }
            MessageType type = context.Command.MessageType;
            #region 非法的表述类型
            if (type == MessageType.Undefined
                || type == default(MessageType))
            {
                return new ProcessResult(false, Status.InvalidMessageType, "非法的表述类型");
            }
            #endregion
            #region 验证事件
            if (type == MessageType.Event)
            {
                #region 非法的事件源类型
                EventSourceType eventSourceType;
                if (!context.Command.EventSourceType.TryParse(out eventSourceType)
                    || eventSourceType == EventSourceType.Invalid
                    || eventSourceType == default(EventSourceType))
                {
                    return new ProcessResult(false, Status.InvalidEventSourceType, "非法的事件源类型");
                }
                #endregion
                #region 非法的事件主题码
                if (!EventSubjectCode.Contains(context.Command.EventSubjectCode))
                {
                    return new ProcessResult(false, Status.InvalidEventSubject, "非法的事件主题码");
                }
                #endregion
                #region 非法的状态码或原因短语
                Status outStateCode;
                if (!context.Command.Status.TryParse(out outStateCode))
                {
                    return new ProcessResult(false, Status.InvalidStatus, "非法的状态码");
                }
                if (!string.IsNullOrEmpty(context.Command.ReasonPhrase)
                    && context.Command.ReasonPhrase.Length > 50)
                {
                    return new ProcessResult(false, Status.OutOfLength, "原因短语超过50个字符长度");
                }
                #endregion
                #region 本节点分发的命令的请求标识是Guid型的

                if (eventSourceType == EventSourceType.Command)
                {
                    Guid requestId;
                    if (!Guid.TryParse(context.Command.MessageId, out requestId))
                    {
                        return new ProcessResult(false, Status.InvalidArgument, @"参数MessageID错误:服务端的请求标识是Guid类型的。当EventSourceType取值Command时该MessageID是服务端分发该条命令时使用的MessageId");
                    }
                }

                #endregion
            }
            #endregion
            #region 发起人验证
            if (!string.IsNullOrEmpty(context.Command.UserName) && context.Command.UserName.Length > 50)
            {
                return new ProcessResult(false, Status.OutOfLength, "发起人超过最大50个字符长度。一条命令至多由一个人发起,这个人就是责任人,不存在联名发起命令一说。");
            }
            #endregion
            #region 时间戳验证
            if (context.Command.TimeStamp < SystemTime.Now().AddYears(-1) // TODO:配置消息的左时间
                || context.Command.TimeStamp > SystemTime.Now().AddSeconds(context.Host.Config.TicksTimeout))
            {
                return new ProcessResult(false, Status.InvalidCommandTicks, "非法的命令时间戳,命令时间戳不能是一年前或将来。");
            }
            #endregion
            #region 客户端类型验证
            if (context.Command.ClientType == ClientType.Undefined)
            {
                return new ProcessResult(false, Status.InvalidClientType, "非法的客户端类型");
            }
            #endregion
            #region 节点验证
            NodeDescriptor requestNode = null;
            if (context.Command.ClientType == ClientType.Node)
            {
                if (!context.Host.NodeHost.Nodes.TryGetNodeById(context.Command.ClientId, out requestNode))
                {
                    return new ProcessResult(false, Status.InvalidClientId, "非法的节点");
                }
            }
            #endregion
            #region 本体码验证
            if (string.IsNullOrEmpty(context.Command.Ontology))
            {
                return new ProcessResult(false, Status.InvalidOntology, "必须通过本体码界定命令的上下文,本体码不能为空。");
            }
            OntologyDescriptor ontology;
            if (!context.Host.NodeHost.Ontologies.TryGetOntology(context.Command.Ontology, out ontology))
            {
                return new ProcessResult(false, Status.InvalidOntology, "非法的本体码。本体列表中不存在编码为" + context.Ontology + "的本体码");
            }
            if (ontology.Ontology.IsEnabled != 1)
            {
                return new ProcessResult(false, Status.InvalidOntology, "该本体已被禁用");
            }
            #endregion
            #region 动作码验证
            if (string.IsNullOrEmpty(context.Command.Verb.Code))
            {
                return new ProcessResult(false, Status.InvalidVerb, "必须通过本体动作码来表明您的命令是要做什么,本体动作码不能为空。");
            }
            if (!ontology.Actions.ContainsKey(context.Command.Verb))
            {
                return new ProcessResult(false, Status.InvalidVerb, "非法的动作码," + ontology.Ontology.Name + "未定义编码为" + context.Command.Verb + "的动作");
            }
            if (context.Command.ClientType == ClientType.Node)
            {
                var nodeActions = requestNode.Node.NodeActions;
                if (!nodeActions.ContainsKey(ontology) || !nodeActions[ontology].ContainsKey(context.Command.Verb))
                {
                    return new ProcessResult(false, Status.NoPermission, "您的节点没有" + ontology.Actions[context.Command.Verb].Name + ontology.Ontology.Name + "的权限");
                }
            }
            #endregion
            #region 本体元素码验证器
            if (context.Command.DataTuple.IdItems == null || context.Command.DataTuple.IdItems.IsEmpty)
            {
                return new ProcessResult(false, Status.InvalidInfoId, "信息标识不能为空");
            }
            var elementDic = ontology.Elements;
            var failDescription = new List<DataItem>();
            var infoIdItems = new List<InfoItem>();
            if (context.Command.DataTuple.IdItems != null)
            {
                foreach (var item in context.Command.DataTuple.IdItems.Items)
                {
                    if (item.Key == null || !elementDic.ContainsKey(item.Key) || elementDic[item.Key].Element.IsEnabled != 1)
                    {
                        failDescription.Add(item);
                    }
                    else
                    {
                        infoIdItems.Add(InfoItem.Create(elementDic[item.Key], item.Value));
                    }
                }
            }
            var infoValueItems = new List<InfoItem>();
            if (context.Command.DataTuple.ValueItems != null)
            {
                foreach (var item in context.Command.DataTuple.ValueItems.Items)
                {
                    if (item.Key != null && !elementDic.ContainsKey(item.Key))
                    {
                        failDescription.Add(item);
                    }
                    else
                    {
                        infoValueItems.Add(InfoItem.Create(elementDic[item.Key], item.Value));
                    }
                }
            }
            if (failDescription.Count > 0)
            {
                return new ProcessResult(false, Status.InvalidElement, "非法的本体元素码" + failDescription[0].Key);
            }
            #endregion
            #region 信息标识验证
            if (context.Command.DataTuple.IdItems.IsEmpty)
            {
                return new ProcessResult(false, Status.InvalidInfoId, "非法的信息标识");
            }
            else if (ontology.Ontology.IsCataloguedEntity)
            {
                if (Verb.Create.Equals(context.Command.Verb)
                    && type != MessageType.Event)
                {
                    if (requestNode != context.Host.NodeHost.Nodes.CenterNode
                        && context.Command.DataTuple.IdItems.Items.Any(a => string.Equals(a.Key, "Id", StringComparison.OrdinalIgnoreCase)))
                    {
                        return new ProcessResult(false, Status.InvalidInfoId, "非中心节点的create型命令不能提供Id");
                    }
                    else if ((ontology.Ontology.IsCataloguedEntity &&
                        !context.Command.DataTuple.IdItems.Items.Any(a => string.Equals(a.Key, "ZZJGM", StringComparison.OrdinalIgnoreCase)))
                        || !context.Command.DataTuple.IdItems.Items.Any(a => string.Equals(a.Key, "XM", StringComparison.OrdinalIgnoreCase)))
                    {
                        return new ProcessResult(false, Status.InvalidInfoId, "没有提供姓名或目录");
                    }
                }
            }
            #endregion
            #region 信息标识项验证
            ProcessResult result;
            foreach (var infoItem in infoIdItems)
            {
                if (!this.ValidInfoItem(infoItem, out result))
                {
                    return result;
                }
            }
            #endregion
            #region 信息值项验证
            if (Verb.Create.Equals(context.Command.Verb)
                || Verb.Update.Equals(context.Command.Verb))
            {
                if (context.Command.DataTuple.ValueItems.IsEmpty)
                {
                    return new ProcessResult(false, Status.InvalidInfoValue, "Create和Update型动作必须提供InfoValue输入");
                }
                foreach (var infoItem in infoValueItems)
                {
                    if (!this.ValidInfoItem(infoItem, out result))
                    {
                        return result;
                    }
                }
            }
            #endregion

            return new ProcessResult(true, Status.Ok, "命令输入验证通过");
        }
예제 #12
0
 public MessageTuple(MessageContext context, InfoItem[] tuple)
 {
     this.Context = context;
     this.Tuple = tuple;
 }