예제 #1
0
        /*
         * /// <summary>
         * /// Configure a trigger for an event to start a process.
         * /// </summary>
         * public void AddProcessTrigger(Func<RFEvent, bool> evaluator, RFEngineProcessDefinition processConfig)
         * {
         *  Triggers.Add(new RFSingleCommandTrigger(e => evaluator(e) ? new RFParamProcessInstruction(processConfig.Name, null) : null));
         * }
         */
        /// <summary>
        /// Define a new process inside the engine triggered by a key update.
        /// </summary>
        /// <param name="processName">Unique user-friendly name.</param>
        /// <param name="processor">
        /// Function that creates the processor (may pass static config etc.)
        /// </param>
        /// <param name="triggerKey">Key that triggers the execution (matched by root).</param>
        /// <returns></returns>
        public RFEngineProcessDefinition AddProcessWithCatalogTrigger <P>(string processName, string description, Func <IRFEngineProcessor> processor,
                                                                          RFCatalogKey triggerKey) where P : RFEngineProcessorParam
        {
            if (Processes.ContainsKey(processName))
            {
                throw new Exception(String.Format("Already registered process {0}", processName));
            }
            var p = processor(); // test instantiation

            //Func<RFInstruction, RFEngineProcessorParam> instanceParams = i => i.ExtractParam();// new P().ExtractFrom;

            var newProcess = new RFEngineProcessDefinition
            {
                Name           = processName,
                InstanceParams = i => i.ExtractParam()?.ConvertTo <P>(),
                Processor      = processor,
                Description    = description,
                IsExclusive    = p.IsExclusive
            };

            Processes.Add(processName, newProcess);

            AddCatalogUpdateTrigger <RFCatalogKey>(k => k.MatchesRoot(triggerKey), newProcess);

            return(newProcess);
        }
예제 #2
0
        protected static SqlCommand LoadEntryCommand(RFCatalogKey itemKey, int version, SqlConnection connection, SqlTransaction transaction = null)
        {
            if (itemKey.StoreType != RFStoreType.Document)
            {
                throw new Exception(String.Format("Unrecognized store type {0}", itemKey.StoreType));
            }

            SqlCommand sqlCommand = null;

            if (transaction != null)
            {
                sqlCommand = CreateCommand("[RIFF].[GetDocument]", connection, transaction);
            }
            else
            {
                sqlCommand = CreateCommand("[RIFF].[GetDocument]", connection);
            }

            var keyString = itemKey.ToString();

            sqlCommand.CommandType = CommandType.StoredProcedure;
            sqlCommand.Parameters.AddWithValue("@KeyType", itemKey.GetType().FullName);
            sqlCommand.Parameters.AddWithValue("@SerializedKey", keyString);
            sqlCommand.Parameters.AddWithValue("@KeyHash", RFStringHelpers.QuickHash(keyString));
            sqlCommand.Parameters.AddWithValue("@Version", version);
            return(sqlCommand);
        }
예제 #3
0
 private void LogKey(RFCatalogKey key)
 {
     lock (mSync)
     {
         Keys.Add(key);
         KeyCount++;
     }
 }
예제 #4
0
        public T LoadDocumentContent <T>(RFCatalogKey key, RFCatalogOptions options = null) where T : class
        {
            var document = (LoadEntry(key, options) as RFDocument);

            if (document != null && document.IsValid)
            {
                return(document.GetContent <T>());
            }
            return(null);
        }
예제 #5
0
 public RFGraphReactor(RFCatalogKey key, RFDateBehaviour dateBehaviour, string processName, IRFReadingContext context, Func <RFGraphInstance, RFDate> dateFunc,
                       Func <RFDate, RFDate> maxDateFunc)
 {
     _key           = key;
     _dateBehaviour = dateBehaviour;
     _processName   = processName;
     _context       = context;
     _dateFunc      = dateFunc;
     _maxDateFunc   = maxDateFunc;
 }
예제 #6
0
 public static RFDocument Create(RFCatalogKey key, object content, RFMetadata metadata = null)
 {
     return(new RFDocument
     {
         Key = key,
         Content = content,
         Type = content.GetType().FullName,
         Metadata = metadata
     });
 }
예제 #7
0
        /// <summary>
        /// Configures process to automatically run on catalog update
        /// </summary>
        /// <param name="taskName"></param>
        /// <param name="triggerKey"></param>
        /// <param name="process"></param>
        /// <returns></returns>
        public RFEngineTaskDefinition AddTriggeredTask(string taskName, RFCatalogKey triggerKey, RFEngineProcessDefinition process)
        {
            var task = new RFTriggeredEngineTaskDefinition
            {
                TriggerKey  = triggerKey,
                TaskName    = taskName,
                TaskProcess = process
            };

            Tasks.Add(task);
            task.AddToEngine(this);
            return(task);
        }
예제 #8
0
        public override RFCatalogKeyMetadata GetKeyMetadata(RFCatalogKey key)
        {
            var keyType   = key.GetType().FullName;
            var keyString = key.ToString();
            var keyHash   = RFStringHelpers.QuickHash(keyString);

            //Log.Debug(this, "GetKeyMetadata {0}", keyType);
            try
            {
                var dataTable = new DataTable();
                using (var connection = new SqlConnection(_connectionString))
                {
                    connection.Open();

                    using (var getCommand = CreateCommand("[RIFF].[GetKeyMetadata]", connection))
                    {
                        getCommand.CommandType = CommandType.StoredProcedure;
                        getCommand.Parameters.AddWithValue("@KeyType", keyType);
                        getCommand.Parameters.AddWithValue("@SerializedKey", keyString);
                        getCommand.Parameters.AddWithValue("@KeyHash", keyHash);

                        using (var reader = getCommand.ExecuteReader(System.Data.CommandBehavior.SingleResult))
                        {
                            dataTable.Load(reader);
                        }
                    }
                }
                if (dataTable != null && dataTable.Rows != null && dataTable.Rows.Count > 0)
                {
                    var dataRow = dataTable.Rows[0];
                    return(new RFCatalogKeyMetadata
                    {
                        ContentType = dataRow["ContentType"].ToString(),
                        KeyType = dataRow["KeyType"].ToString(),
                        Key = RFXMLSerializer.DeserializeContract(dataRow["KeyType"].ToString(), dataRow["SerializedKey"].ToString()) as RFCatalogKey,
                        KeyReference = (long)dataRow["CatalogKeyID"],
                        Metadata = RFMetadata.Deserialize(dataRow["Metadata"].ToString()),
                        UpdateTime = (DateTimeOffset)dataRow["UpdateTime"],
                        IsValid = (bool)dataRow["IsValid"],
                        DataSize = (long)dataRow["DataSize"]
                    });
                }
            }
            catch (Exception ex)
            {
                Log.Exception(this, "Error retrieving key metadata", ex);
            }
            return(null);
        }
예제 #9
0
 public void Invalidate(RFCatalogKey key)
 {
     try
     {
         var entry = LoadEntry(key);
         if (entry != null)
         {
             entry.SetInvalid();
             SaveEntry(entry, false, true);
         }
     }
     catch (Exception ex)
     {
         throw new RFSystemException(this, ex, "Error invalidating {0}", key);
     }
 }
예제 #10
0
 public static string KeyLabel(RFCatalogKey key)
 {
     return(key.FriendlyString());
 }
예제 #11
0
 public static RFGraphReactor SimpleReactor(RFCatalogKey key, RFDateBehaviour dateBehaviour, string processName, IRFReadingContext context, Func <RFDate, RFDate> maxInstanceFunc)
 {
     return(new RFGraphReactor(key, dateBehaviour, processName, context, d => d.ValueDate.Value, (d) => maxInstanceFunc(d)));
 }
예제 #12
0
 public virtual bool MatchesRoot(RFCatalogKey key)
 {
     return(key != null && RootString() == key.RootString());
 }
예제 #13
0
 public static RFGraphReactor RangeReactor(RFCatalogKey key, string processName, IRFReadingContext context, Func <RFGraphInstance, RFDate>
                                           rangeUpdateFunc, Func <RFDate, RFDate> maxInstanceFunc)
 {
     return(new RFGraphReactor(key, RFDateBehaviour.Range, processName, context, rangeUpdateFunc, (d) => maxInstanceFunc(d)));
 }
예제 #14
0
 public RFGraphProcessDefinition MapState <S>(Expression <Func <S, object> > property, RFCatalogKey key) where S : RFGraphProcessorDomain
 {
     return(AddIOMapping(property, key, RFIOBehaviour.State));
 }
예제 #15
0
        public override RFCatalogEntry LoadItem(RFCatalogKey itemKey, int version = 0, bool ignoreContent = false)
        {
            RFCatalogEntry entry = null;

            if (itemKey.Plane == RFPlane.User)
            {
                //Log.Debug(this, "LoadItem {0}", catalogKey.ToString());
            }
            try
            {
                var dataRow = new Dictionary <string, object>();
                using (var connection = new SqlConnection(_connectionString))
                {
                    connection.Open();
                    try
                    {
                        long catalogEntryID = 0;
                        using (var command = LoadEntryCommand(itemKey, version, connection))
                        {
                            using (var reader = command.ExecuteReader(System.Data.CommandBehavior.SingleRow))
                            {
                                if (reader.HasRows)
                                {
                                    reader.Read();

                                    catalogEntryID = reader.GetInt64(7);

                                    dataRow.Add("CatalogKeyID", reader.GetInt64(0));
                                    dataRow.Add("KeyType", reader.GetString(1));
                                    dataRow.Add("SerializedKey", reader.GetString(2));
                                    dataRow.Add("Version", reader.GetInt32(3));
                                    dataRow.Add("Metadata", reader.IsDBNull(4) ? String.Empty : reader.GetString(4));
                                    dataRow.Add("IsValid", reader.GetBoolean(5));
                                    dataRow.Add("UpdateTime", reader.GetDateTimeOffset(6));
                                    dataRow.Add("CatalogEntryID", catalogEntryID);
                                    dataRow.Add("ContentType", reader.GetString(8));
                                    dataRow.Add("BinaryContent", reader.IsDBNull(9) ? null : reader.GetSqlBinary(9).Value);
                                }
                            }
                        }
                    }
                    catch (SqlException)
                    {
                        throw;
                    }
                    catch (InvalidOperationException)
                    {
                        throw;
                    }
                    catch (Exception ex)
                    {
                        Log.Exception(this, ex, "Error loading entry {0}", itemKey);
                    }
                }
                if (dataRow.Any())
                {
                    entry = ExtractEntry(itemKey.StoreType, dataRow, ignoreContent);
                }
            }
            catch (SqlException)
            {
                throw;
            }
            catch (InvalidOperationException)
            {
                throw;
            }
            catch (Exception ex)
            {
                Log.Exception(this, ex, "Error loading entry {0}", itemKey);
            }

            return(entry);
        }
예제 #16
0
 public RFCatalogKeyMetadata GetKeyMetadata(RFCatalogKey key)
 {
     return(_catalog.GetKeyMetadata(key));
 }
예제 #17
0
 public Dictionary <RFGraphInstance, RFCatalogKey> GetKeyInstances(RFCatalogKey key)
 {
     return(_catalog.GetKeyInstances(key));
 }
예제 #18
0
        public override Dictionary <RFGraphInstance, RFCatalogKey> GetKeyInstances(RFCatalogKey key)
        {
            var    t       = key.GetType();
            var    keys    = new Dictionary <RFGraphInstance, RFCatalogKey>();
            string keyType = t.FullName;

            Log.Debug(this, "GetKeyInstances {0}", keyType);
            try
            {
                var dataTable = new DataTable();
                using (var connection = new SqlConnection(_connectionString))
                {
                    connection.Open();

                    string getKeysSQL = "RIFF.GetKeyInstances";
                    using (var getCommand = CreateCommand(getKeysSQL, connection))
                    {
                        var rootHash = RFStringHelpers.QuickHash(key.RootKey().ToString());

                        getCommand.CommandType = CommandType.StoredProcedure;
                        getCommand.Parameters.AddWithValue("@KeyType", keyType);
                        getCommand.Parameters.AddWithValue("@SerializedKey", RFXMLSerializer.SerializeContract(key));
                        getCommand.Parameters.AddWithValue("@RootHash", rootHash);
                        using (var reader = getCommand.ExecuteReader(System.Data.CommandBehavior.SingleResult))
                        {
                            dataTable.Load(reader);
                        }
                    }
                }
                if (dataTable != null && dataTable.Rows != null && dataTable.Rows.Count > 0)
                {
                    // cache deserializer if key is explicit
                    foreach (DataRow dataRow in dataTable.Rows)
                    {
                        try
                        {
                            var catalogKeyID      = (long)dataRow["CatalogKeyID"];
                            var retrievedKeyType  = dataRow["KeyType"].ToString();
                            var serializedKey     = dataRow["SerializedKey"].ToString();
                            var graphInstanceName = dataRow["GraphInstanceName"].ToString();
                            var graphInstanceDate = new RFDate((int)dataRow["GraphInstanceDate"]);
                            var deserializedKey   = RFXMLSerializer.DeserializeContract(retrievedKeyType, serializedKey);

                            keys.Add(
                                new RFGraphInstance
                            {
                                Name      = graphInstanceName,
                                ValueDate = graphInstanceDate
                            },
                                deserializedKey as RFCatalogKey);
                        }
                        catch (Exception ex)
                        {
                            Log.Exception(this, ex, "Error deserializing key {0}", dataRow["SerializedKey"].ToString());
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Log.Exception(this, "Error retrieving key instances", ex);
            }

            return(keys);
        }
예제 #19
0
        public RFCatalogEntry LoadEntry(RFCatalogKey key, RFCatalogOptions options = null)
        {
            DefaultOptions(ref options);
            if (key is RFCatalogKey)
            {
                lock (_memoryStore)
                {
                    if (_memoryStore.ContainsKey(key.ToString()))
                    {
                        return(_memoryStore[key.ToString()]);
                    }
                }

                switch (options.DateBehaviour)
                {
                case RFDateBehaviour.NotSet:
                case RFDateBehaviour.Exact:
                {
                    var item = _catalog.LoadItem(key as RFCatalogKey, options.Version, options.IgnoreContent);
                    return((item != null && item.IsValid) ? item : null);
                }

                case RFDateBehaviour.Dateless:
                {
                    var keyToLoad = key.CreateForInstance(new RFGraphInstance
                        {
                            Name      = key.GraphInstance.Name,
                            ValueDate = null
                        });
                    var item = _catalog.LoadItem(keyToLoad, options.Version, options.IgnoreContent);
                    return((item != null && item.IsValid) ? item : null);
                }

                case RFDateBehaviour.Latest:
                case RFDateBehaviour.Previous:
                {
                    if (key.GraphInstance == null || !key.GraphInstance.ValueDate.HasValue)
                    {
                        throw new RFSystemException(this, "Unable to load latest date for key without date {0}", key);
                    }
                    var allKeys        = _catalog.GetKeyInstances(key);
                    var candidateDates = new SortedSet <RFDate>();

                    foreach (var candidateKey in allKeys.Where(k => k.Key.Name == key.GraphInstance.Name))
                    {
                        if (candidateKey.Value.GraphInstance.ValueDate.Value <= key.GraphInstance.ValueDate.Value)
                        {
                            if ((options.DateBehaviour == RFDateBehaviour.Latest) ||
                                (options.DateBehaviour == RFDateBehaviour.Previous && candidateKey.Value.GraphInstance.ValueDate.Value < key.GraphInstance.ValueDate.Value))
                            {
                                candidateDates.Add(candidateKey.Value.GraphInstance.ValueDate.Value);
                            }
                        }
                    }
                    if (candidateDates.Count == 0)
                    {
                        SystemLog.Warning(this, "No latest date instance item found for key {0}", key);
                        return(null);
                    }
                    foreach (var latestDate in candidateDates.OrderByDescending(d => d))
                    {
                        var keyToLoad = key.CreateForInstance(new RFGraphInstance
                            {
                                Name      = key.GraphInstance.Name,
                                ValueDate = latestDate
                            });
                        var item = _catalog.LoadItem(keyToLoad, options.Version, options.IgnoreContent);
                        if (item != null && item.IsValid)
                        {
                            return(item);
                        }
                    }
                    return(null);
                }

                default:
                    throw new RFSystemException(this, "Unsupported date behaviour in LoadEntry: {0}", options.DateBehaviour);
                }
            }
            else
            {
                throw new RFSystemException(this, "Unknown store key type {0}", key.ToString());
            }
        }
예제 #20
0
 public RFGraphProcessDefinition MapRangeInput <S>(Expression <Func <S, object> > property, RFCatalogKey key, Func <RFGraphInstance, List <RFDate> > rangeRequestFunc,
                                                   Func <RFGraphInstance, RFDate> rangeUpdateFunc) where S : RFGraphProcessorDomain
 {
     return(AddIOMapping(property, key, RFIOBehaviour.Input, rangeRequestFunc, rangeUpdateFunc));
 }
예제 #21
0
 public void SaveDocument(RFCatalogKey key, object content, bool raiseEvent = true)
 {
     SaveEntry(RFDocument.Create(key, content), raiseEvent);
 }
예제 #22
0
        protected RFGraphProcessDefinition AddIOMapping <S>(Expression <Func <S, object> > property, RFCatalogKey key, RFIOBehaviour expectedBehvaiour, Func <RFGraphInstance, List <RFDate> > rangeRequestFunc = null,
                                                            Func <RFGraphInstance, RFDate> rangeUpdateFunc = null) where S : RFGraphProcessorDomain
        {
            var processor = Processor();
            var domain    = processor.CreateDomain();

            if (domain.GetType() != typeof(S))
            {
                throw new RFLogicException(this, "IO Domain Type mismatch on processor {0}: {1} vs {2}", RFGraphDefinition.GetFullName(GraphName, Name),
                                           domain.GetType().Name, typeof(S).Name);
            }

            var propertyInfo = property.GetProperty <S>();
            var ioBehaviour  = RFReflectionHelpers.GetIOBehaviour(propertyInfo);

            if (ioBehaviour != expectedBehvaiour)
            {
                throw new RFLogicException(this, "Inconsistent IO direction {0} on property {1}, expected {2}.", ioBehaviour, propertyInfo.FullName(), expectedBehvaiour);
            }
            var dateBehaviour = RFReflectionHelpers.GetDateBehaviour(propertyInfo);

            if (dateBehaviour == RFDateBehaviour.Range && (rangeRequestFunc == null || rangeUpdateFunc == null))
            {
                throw new RFLogicException(this, "Range input doesn't have range functions specified on property {0}.", propertyInfo.FullName());
            }
            IOMappings.Add(new RFGraphIOMapping {
                Key = key, Property = propertyInfo, RangeRequestFunc = rangeRequestFunc, RangeUpdateFunc = rangeUpdateFunc, DateBehaviour = dateBehaviour
            });
            return(this);
        }
 public RFEngineProcessorKeyParam(RFCatalogKey key)
 {
     Key = key;
 }