/// <summary> /// 获取规则步骤数据操作类 /// </summary> /// <param name="stepTypeCode">步骤类型唯一编码</param> /// <param name="repository"></param> /// <param name="taskId"></param> /// <param name="step"></param> /// <returns></returns> public static IRuleStepData GetRuleStepData(string stepTypeCode, IRepository repository, DmeTask task, DmeRuleStep step) { if (!Register.RuleStepPluginsMap.ContainsKey(stepTypeCode)) { LOG.Warn($"没有找到步骤类型为[{stepTypeCode}]的插件信息"); return(null); } RuleStepPluginRegisterDTO ruleStepPluginRegisterDTO = Register.RuleStepPluginsMap[stepTypeCode]; String baseDir = AppDomain.CurrentDomain.BaseDirectory; string assemblyPath = Path.Combine(baseDir, ruleStepPluginRegisterDTO.Assembly); Assembly assembly = Assembly.LoadFile(assemblyPath); IRuleStepData ruleStepData = (IRuleStepData)assembly.CreateInstance(ruleStepPluginRegisterDTO.ClassId, true, BindingFlags.CreateInstance, null , new object[] { repository, task, step }, null, null); return(ruleStepData); }
/// <summary> /// 处理步骤属性信息 /// </summary> /// <param name="db"></param> /// <param name="model"></param> /// <param name="version"></param> /// <param name="subStepAdd"></param> /// <param name="step"></param> private void HandleAttributes(SqlSugarClient db, DmeModel model, DmeModelVersion version, RuleStepAddDTO subStepAdd, DmeRuleStep step) { IList <AttributeReqDTO> properties = subStepAdd.Attributes; if (properties?.Count == 0) { LOG.Warn("没有可处理的步骤属性信息"); return; } if (Register.RuleStepPluginsMap.ContainsKey(subStepAdd.StepType.Code)) { RuleStepPluginRegisterDTO ruleStepPluginRegisterDTO = Register.RuleStepPluginsMap[subStepAdd.StepType.Code]; String baseDir = AppDomain.CurrentDomain.BaseDirectory; string assemblyPath = Path.Combine(baseDir, ruleStepPluginRegisterDTO.Assembly); Assembly assembly = Assembly.LoadFile(assemblyPath); IRuleStepData ruleStepData = (IRuleStepData)assembly.CreateInstance(ruleStepPluginRegisterDTO.ClassId, true, BindingFlags.CreateInstance, null , new object[] { Repository, null, step }, null, null); if (null == ruleStepData) { LOG.Warn($"无法创建步骤实体[{ruleStepPluginRegisterDTO.ClassId}]"); return; } IDictionary <string, Property> attributes = new Dictionary <string, Property>(); // DmeRuleStepAttribute dmeRuleStepAttribute = null; foreach (var p in properties) { EnumValueMetaType enumValueMetaType = new EnumValueMetaType(); if (string.IsNullOrEmpty(p.DataTypeCode)) { enumValueMetaType = EnumValueMetaType.TYPE_UNKNOWN; } else { enumValueMetaType = EnumUtil.GetEnumObjByName <EnumValueMetaType>(p.DataTypeCode); } attributes[p.Name] = new Property(p.Name, p.Name, enumValueMetaType, p.Value, null, null, null, 1, 0, 1, p.DataSourceCode, p.IsNeedPrecursor, p.Type); } ruleStepData.SaveAttributes(attributes); } }
public object GetRuntimeAttributes(string modelVersionCode) { DmeModelVersion dmeModelVersion = base.Db.Queryable <DmeModelVersion>().Single(mv => mv.SysCode == modelVersionCode); if (null == dmeModelVersion) { throw new BusinessException((int)EnumSystemStatusCode.DME_ERROR, $"模型版本[{modelVersionCode}]不存在"); } // 查找模型版本下步骤信息 List <DmeRuleStep> steps = base.Db.Queryable <DmeRuleStep>().Where(rs => rs.ModelId == dmeModelVersion.ModelId && rs.VersionId == dmeModelVersion.Id).ToList(); if (0 == steps?.Count) { LOG.Warn($"模型版本[{modelVersionCode}]下没有找到步骤信息"); return(null); } IList <AttributeRuntimeRespDTO> ruleStepRuntimeAttributes = new List <AttributeRuntimeRespDTO>(); IList <AttributeRuntimeDTO> runtimeAttriRespDTOs = null; foreach (var step in steps) { LOG.Info($"模型版本[{modelVersionCode}],步骤编码[{step.SysCode}],步骤名称[{step.Name}]"); // 查找运行时参数 List <DmeRuleStepAttribute> runtimeAtts = base.Db.Queryable <DmeRuleStepAttribute>().Where(rsa => rsa.RuleStepId == step.Id && rsa.AttributeType == (int)EnumAttributeType.RUNTIME).ToList(); if (0 == runtimeAtts?.Count) { LOG.Warn($"步骤[{step.Name}]下没有设置属性"); continue; } // 查找步骤类型 DmeRuleStepType ruleStepType = base.Db.Queryable <DmeRuleStepType>().InSingle(step.StepTypeId); if (null == ruleStepType) { LOG.Warn($"步骤类型id[{step.StepTypeId}]不存在"); continue; } IRuleStepData ruleStepData = RuleStepFactory.GetRuleStepData(ruleStepType.Code, base.Repository, null, step); IDictionary <string, Property> inParams = ruleStepData.RuleStepMeta.InParams; if (null == inParams) { LOG.Warn($"步骤编码[{step.SysCode}],步骤名称[{step.Name}],获取不到步骤元数据的输入参数"); continue; } runtimeAttriRespDTOs = new List <AttributeRuntimeDTO>(); foreach (var item in runtimeAtts) { if (inParams.ContainsKey(item.AttributeCode)) { Property property = inParams[item.AttributeCode]; runtimeAttriRespDTOs.Add(new AttributeRuntimeDTO() { ModelId = step.ModelId, VersionId = step.VersionId, RuleStepId = step.Id, Name = item.AttributeCode, Alias = property.Alias, DataTypeCode = property.DataTypeCode, DataTypeDesc = property.DataTypeDesc }); } } if (0 == runtimeAttriRespDTOs.Count) { continue; } ruleStepRuntimeAttributes.Add(new AttributeRuntimeRespDTO() { RuleStep = new RuleStepRespDTO() { SysCode = step.SysCode, Name = step.Name, Remark = step.Remark, ModelId = step.ModelId, VersionId = step.VersionId }, RuntimeAtts = runtimeAttriRespDTOs }); } return(ruleStepRuntimeAttributes); }
/// <summary> /// 内部方法,获取模型元数据 /// </summary> /// <param name="model"></param> /// <param name="detail"></param> /// <returns></returns> private ModelDTO GetModelMetadata(DmeModel model, Boolean detail) { ModelDTO modelDTO = ClassValueCopier <ModelDTO> .Copy(model); if (!detail) { return(modelDTO); } var db = base.Repository.GetDbContext(); // 获取模型版本 IList <DmeModelVersion> versions = db.Queryable <DmeModelVersion>().Where(mv => mv.ModelId == model.Id).ToList(); if (null == versions || 0 == versions.Count) { return(modelDTO); } foreach (var v in versions) { ModelVersionDTO versionDTO = ClassValueCopier <ModelVersionDTO> .Copy(v); modelDTO.Versions.Add(versionDTO); IList <DmeRuleStep> ruleStepEntities = db.Queryable <DmeRuleStep>().Where(rs => rs.ModelId == model.Id && rs.VersionId == v.Id).ToList(); if (null == ruleStepEntities || 0 == ruleStepEntities.Count) { continue; } RuleStepDTO ruleStepDTO = null; foreach (var ruleStep in ruleStepEntities) { ruleStepDTO = ClassValueCopier <RuleStepDTO> .Copy(ruleStep); versionDTO.Steps.Add(ruleStepDTO); // 获取步骤类型实体 ruleStepDTO.StepType = db.Queryable <DmeRuleStepType>().Where(rst => rst.Id == ruleStep.StepTypeId).Single(); IRuleStepData ruleStepData = RuleStepFactory.GetRuleStepData(ruleStepDTO.StepType.Code, base.Repository, null, ruleStep); IDictionary <string, Property> attributeDic = ruleStepData.RuleStepMeta.ReadAttributes(); if (attributeDic?.Count > 0) { foreach (var item in attributeDic.Values) { ruleStepDTO.Attributes.Add(item); } } // 检索步骤的属性值信息 //IList<DmeRuleStepAttribute> attributes = db.Queryable<DmeRuleStepAttribute>().Where(rsa => rsa.RuleStepId == ruleStep.Id).ToList(); //if (null == attributes || 0 == attributes.Count) //{ // continue; //} //foreach (var att in attributes) //{ // ruleStepDTO.Attributes.Add(new KeyValuePair<string, object>(att.AttributeCode, att.AttributeValue)); //} } // 每个模型版本下的数据源(多表关联查询) // 当不需要用LEFT JOIN或者 RIGHT JOIN 只是单纯的INNER JOIN时我们还提供了更简单的语法实现多表查询 IList <DmeDataSource> datasources = db.Queryable <DmeDataSource, DmeRuleStepDataSource>((ds, rsds) => ds.Id == rsds.DataSourceId).Select(ds => new DmeDataSource { SysCode = ds.SysCode, Connection = ds.Connection, CreateTime = ds.CreateTime, Id = ds.Id, Name = ds.Name, Remark = ds.Remark, Type = ds.Type }).ToList(); if (datasources?.Count > 0) { foreach (var datasourceItem in datasources) { if (versionDTO.DataSources.ContainsKey(datasourceItem.SysCode)) { continue; } versionDTO.DataSources[datasourceItem.SysCode] = datasourceItem; } } // 每个模型版本下的节点向量信息 IList <DmeRuleStepHop> hops = db.Queryable <DmeRuleStepHop>() .Where(rsh => rsh.ModelId == model.Id && rsh.VersionId == v.Id) .OrderBy(rsh => rsh.StepFromId) .ToList(); if (hops?.Count > 0) { DmeRuleStep stepFromTemp = null; DmeRuleStep stepToTemp = null; foreach (var item in hops) { stepFromTemp = db.Queryable <DmeRuleStep>().InSingle(item.StepFromId); stepToTemp = db.Queryable <DmeRuleStep>().InSingle(item.StepToId); if (null == stepFromTemp || null == stepToTemp) { LOG.Warn($"开始步骤[{item.StepFromId}],或者结束步骤[{item.StepToId}]找不到对应实体信息"); continue; } versionDTO.Hops.Add(new RuleStepHopDTO(stepFromTemp.Name, stepToTemp.Name, item.Enabled, item.Name)); } } } return(modelDTO); }
public object SaveRuleStepInfos(ModelRuleStepInfoDTO info) { var db = base.Repository.GetDbContext(); // 开始事务 return(db.Ado.UseTran <object>(() => { // 根据模型版本号,获取模型版本信息 DmeModelVersion modelVersion = base.Repository.GetDbContext().Queryable <DmeModelVersion>().Single(mv => mv.SysCode == info.ModelVersionCode); // 清除模型的步骤信息 db.Deleteable <DmeRuleStep>(rs => rs.ModelId == modelVersion.ModelId && rs.VersionId == modelVersion.Id).ExecuteCommand(); // 清除步骤属性信息 db.Deleteable <DmeRuleStepAttribute>(rsa => rsa.ModelId == modelVersion.ModelId && rsa.VersionId == modelVersion.Id).ExecuteCommand(); // 根据key建立起关系 if (info.RuleSteps?.Count > 0) { // 客户端传过来的key和业务id映射关系 IDictionary <string, int> key2BizId = new Dictionary <string, int>(); foreach (var step in info.RuleSteps) { DmeRuleStep stepEntity = new DmeRuleStep { SysCode = GuidUtil.NewGuid(), ModelId = modelVersion.ModelId, VersionId = modelVersion.Id }; stepEntity.Id = db.Insertable <DmeRuleStep>(stepEntity).ExecuteReturnIdentity(); key2BizId[step.Key] = stepEntity.Id; // 处理步骤属性 if (step.Attributes?.Count > 0) { IRuleStepData ruleStepData = RuleStepFactory.GetRuleStepData(step.TypeCode, base.Repository, null, stepEntity); ruleStepData.SaveAttributes(step.Attributes); //IList<DmeRuleStepAttribute> attributeEntities = new List<DmeRuleStepAttribute>(); //foreach (var att in step.Attributes) //{ // attributeEntities.Add(new DmeRuleStepAttribute // { // RuleStepId = stepEntity.Id, // ModelId = stepEntity.ModelId, // VersionId = stepEntity.VersionId, // AttributeCode = att.Key, // AttributeValue = att.Value // }); //} //db.Insertable<DmeRuleStepAttribute>(attributeEntities).ExecuteCommand(); } } // 处理步骤的向量关系 if (info.Vectors?.Count > 0) { IList <DmeRuleStepHop> ruleStepHops = new List <DmeRuleStepHop>(); foreach (var vector in info.Vectors) { // 只要向量的信息不完整,都不需要保存连接信息 if (!key2BizId.ContainsKey(vector.StepFromName) || !key2BizId.ContainsKey(vector.StepToName)) { continue; } ruleStepHops.Add(new DmeRuleStepHop { ModelId = modelVersion.ModelId, VersionId = modelVersion.Id, StepFromId = key2BizId[vector.StepFromName], StepToId = key2BizId[vector.StepToName], Enabled = vector.Enabled }); } db.Insertable <DmeRuleStepHop>(ruleStepHops).ExecuteCommandAsync(); } } return true; }).Data); }
/// <summary> /// 运行步骤节点 /// </summary> /// <param name="db"></param> /// <param name="task"></param> /// <param name="node"></param> private void RunRuleStepNode(SqlSugarClient db, DmeTask task, RuleStepLinkedListNode <DmeRuleStep> node) { // 先计算前置节点 if (node.Previous?.Count > 0) { foreach (var item in node.Previous) { RunRuleStepNode(db, task, item); } } DmeTaskRuleStep dmeTaskRuleStep = null; try { // 先判断任务的状态,是否被停止 DmeTask taskStatus = db.Queryable <DmeTask>().Single(t => t.SysCode == task.SysCode); if (null == taskStatus || taskStatus.Status.Equals(EnumUtil.GetEnumDisplayName(EnumSystemStatusCode.DME_STOP))) { LOG.Info($"任务[{task.SysCode}]不存在或者已被停止"); return; } dmeTaskRuleStep = this.GetTaskRuleStep(db, task, node.Value, out string cacheKey); if (dmeTaskRuleStep != null && EnumUtil.GetEnumDisplayName(EnumSystemStatusCode.DME_SUCCESS).Equals(dmeTaskRuleStep.Status)) { // 释放 dmeTaskRuleStep = null; LOG.Info($"任务[{task.SysCode}]下的步骤[{node.Value.SysCode}]已被计算过,并且状态为[success]"); return; } // 如果前置节点没有了,则计算当前节点内容 DmeRuleStepType ruleStepTypeTemp = db.Queryable <DmeRuleStepType>().Single(rst => rst.Id == node.Value.StepTypeId); IRuleStepData ruleStepData = RuleStepFactory.GetRuleStepData(ruleStepTypeTemp.Code, this.Repository, task, node.Value); if (null == ruleStepData) { throw new BusinessException((int)EnumSystemStatusCode.DME_ERROR, $"步骤工厂无法创建编码为[{ruleStepTypeTemp.Code}]的流程实例节点"); } dmeTaskRuleStep = new DmeTaskRuleStep { SysCode = GuidUtil.NewGuid(), TaskId = task.Id, RuleStepId = node.Value.Id, Status = EnumUtil.GetEnumDisplayName(EnumSystemStatusCode.DME_RUNNING), CreateTime = DateUtil.CurrentTimeMillis, LastTime = DateUtil.CurrentTimeMillis }; dmeTaskRuleStep = db.Insertable <DmeTaskRuleStep>(dmeTaskRuleStep).ExecuteReturnEntity(); // 任务步骤创建成功后,把相关信息记录在缓存中 ServiceFactory.CacheService.AddAsync(cacheKey, dmeTaskRuleStep, 60); Result stepResult = ruleStepData.Run(); UpdateRuleStep(db, dmeTaskRuleStep, cacheKey, stepResult); // 然后计算下一个步骤 if (node?.Next.Count > 0) { foreach (var item in node.Next) { RunRuleStepNode(db, task, item); } } } catch (Exception ex) { dmeTaskRuleStep.Status = EnumUtil.GetEnumDisplayName(EnumSystemStatusCode.DME_ERROR); dmeTaskRuleStep.LastTime = DateUtil.CurrentTimeMillis; // 只更新状态和最后时间 db.Updateable <DmeTaskRuleStep>(dmeTaskRuleStep).UpdateColumns(ts => new { ts.Status, ts.LastTime }).ExecuteCommand(); this.LogService.AddLogAsync(Base.Common.Log.EnumLogType.ENTITY, EnumLogLevel.ERROR, nameof(DmeTaskRuleStep), dmeTaskRuleStep.SysCode, "", ex, "", NetAssist.GetLocalHost()); } }
public Property GetStepAttributeValue(string otherStepName, string attributeCode) { // var db = repository.GetDbContext(); DmeRuleStep otherStep = db.Queryable <DmeRuleStep>().Single(rs => rs.ModelId == step.ModelId && rs.VersionId == step.VersionId && rs.Name == otherStepName); if (null == otherStep) { throw new BusinessException((int)EnumSystemStatusCode.DME_FAIL, $"步骤[{otherStepName}]在模型[{step.ModelId}]版本[{step.VersionId}]下不存在"); } DmeRuleStepType otherStepType = db.Queryable <DmeRuleStepType>().Single(rst => rst.Id == otherStep.StepTypeId); if (null == otherStepType) { throw new BusinessException((int)EnumSystemStatusCode.DME_FAIL, $"步骤类型id[{otherStep.StepTypeId}]不存在"); } IRuleStepData ruleStepData = RuleStepFactory.GetRuleStepData(otherStepType.Name, repository, this.task, otherStep); IDictionary <string, Property> inputParameters = ruleStepData.RuleStepMeta.InParams; IDictionary <string, Property> outputParameters = ruleStepData.RuleStepMeta.OutParams; Property property = null; if (inputParameters.ContainsKey(attributeCode)) { // 从步骤属性表查找 property = inputParameters[attributeCode]; DmeRuleStepAttribute dmeRuleStepAttribute = db.Queryable <DmeRuleStepAttribute>().Single(rsa => rsa.RuleStepId == otherStep.Id && rsa.RowIndex == 0 && rsa.AttributeCode == attributeCode); property.Value = dmeRuleStepAttribute.AttributeValue; } else if (outputParameters.ContainsKey(attributeCode)) { // 从步骤结果表查找 property = outputParameters[attributeCode]; DmeTaskResult dmeTaskResult = db.Queryable <DmeTaskResult>().Single(tr => tr.TaskId == this.taskId && tr.RuleStepId == otherStep.Id && tr.ResultCode == attributeCode); EnumValueMetaType @enum = EnumUtil.GetEnumObjByName <EnumValueMetaType>(property.DataTypeCode); switch (@enum) { case EnumValueMetaType.TYPE_UNKNOWN: case EnumValueMetaType.TYPE_NUMBER: case EnumValueMetaType.TYPE_STRING: case EnumValueMetaType.TYPE_INTEGER: case EnumValueMetaType.TYPE_BIGNUMBER: case EnumValueMetaType.TYPE_TIMESTAMP: case EnumValueMetaType.TYPE_INET: case EnumValueMetaType.TYPE_LOCAL_FILE: case EnumValueMetaType.TYPE_GDB_PATH: case EnumValueMetaType.TYPE_FOLDER: property.Value = dmeTaskResult.ResultValue; break; case EnumValueMetaType.TYPE_DATE: // 要求格式:yyyy-MM-dd hh:mm:ss property.Value = Convert.ToDateTime(dmeTaskResult.ResultValue?.ToString()); break; case EnumValueMetaType.TYPE_BOOLEAN: property.Value = Boolean.Parse(dmeTaskResult.ResultValue?.ToString()); break; case EnumValueMetaType.TYPE_SERIALIZABLE: break; case EnumValueMetaType.TYPE_BINARY: break; case EnumValueMetaType.TYPE_MDB_FEATURECLASS: break; case EnumValueMetaType.TYPE_STRING_LIST: property.Value = dmeTaskResult.ResultValue?.ToString().Split(";"); break; case EnumValueMetaType.TYPE_SDE_FEATURECLASS: break; case EnumValueMetaType.TYPE_FEATURECLASS: break; case EnumValueMetaType.TYPE_JSON: // 从mongo中获取 var filter = Builders <TaskResultColl> .Filter.And( Builders <TaskResultColl> .Filter.Eq("TaskCode", this.task.SysCode), Builders <TaskResultColl> .Filter.Eq("RuleStepCode", otherStep.SysCode), Builders <TaskResultColl> .Filter.Eq("Code", attributeCode)); IList <TaskResultColl> colls = MongodbHelper <TaskResultColl> .FindList(ServiceFactory.MongoDatabase, filter); if (colls != null && colls.Count > 0) { property.Value = colls[0].Value; } break; default: break; } } else { LOG.Error($"属性编码[{attributeCode}]无效"); throw new BusinessException((int)EnumSystemStatusCode.DME_FAIL, $"属性编码[{attributeCode}]无效"); } return(property); }