Example #1
0
        /// <summary>
        /// This method contains the work required to verify that an IVA is ready for a corresponding CKA before attempting to find and/or create the CKA.
        /// This method returns true if it created and added a sync item for the IVA/CKA pair, otherwise it returns false.
        /// if the requireUpdateNeeded flag is true then the method will only attempt to even check if the IVA is ready if its IsUpdateNeeded flag is set (aka it has been set since we last checked)
        /// </summary>
        private bool AttemptToAddSyncItemForIVA(AttemptToAddSyncItemForIVAInfo item, bool requireUpdateNeeded = true)
        {
            if (requireUpdateNeeded && !item.iva.IsUpdateNeeded)
            {
                return(false);
            }

            item.iva.Update();

            // we only attempt to propagate items to config that have been explicitly set and which currently have a non-empty value.
            if (item.iva.HasValueBeenSet && !item.iva.VC.IsEmpty)
            {
                IConfigKeyAccess cka = Config.GetConfigKeyAccess(new ConfigKeyAccessSpec()
                {
                    Key   = item.mappedToCKAKeyName,
                    Flags = new ConfigKeyAccessFlags()
                    {
                        MayBeChanged = true, EnsureExists = BridgeConfig.UseEnsureExists, DefaultProviderName = BridgeConfig.DefaultConfigKeyProviderName
                    },
                }
                                                                 , item.iva.VC);

                AddSyncItemAndPerformInitialPropagation(item.iva, cka, item.ivaNativeName, null, item.mappedFromIVAName, item.mappedToCKAKeyName);

                return(true);
            }
            else
            {
                return(false);
            }
        }
Example #2
0
        private SyncItem AddSyncItemAndPerformInitialPropagation(IValueAccessor iva, IConfigKeyAccess cka, string ivaLookupName, string ivaFromCkaMappedName, string ckaFromIvaMappedName, string ckaLookupKeyName)
        {
            SyncItem syncItem = new SyncItem()
            {
                iva = iva, icka = cka, ivaLookupName = ivaLookupName, ivaFromCkaMappedName = ivaFromCkaMappedName, ckaFromIvaMappedName = ckaFromIvaMappedName, ckaLookupKeyName = ckaLookupKeyName
            };

            syncItemList.Add(syncItem);
            syncItemArray = null;
            ivaArray      = null;

            // add syncItem to both maps using both original names and found names, in case target is using name mapping and has applied it to this name.
            ivaNameToSyncItemDictionary[ivaLookupName]          = syncItem;
            ivaNameToSyncItemDictionary[iva.Name]               = syncItem;
            configKeyNameToSyncItemDictionary[ckaLookupKeyName] = syncItem;
            configKeyNameToSyncItemDictionary[cka.Key]          = syncItem;

            ivaArray = null;

            if (cka.HasValue)
            {
                ValueContainer vc = cka.VC;
                if (!iva.VC.IsEqualTo(vc))
                {
                    ValueTraceEmitter.Emit("Propagating initial cka '{0}' to iva '{1}'", cka, iva);
                    iva.Set(vc);
                }
                else
                {
                    ValueTraceEmitter.Emit("Initial cka '{0}' matches initial iva '{1}'", cka, iva);
                }
            }
            else if (iva.HasValueBeenSet)
            {
                ValueContainer vc = iva.VC;
                ValueTraceEmitter.Emit("Propagating initial iva '{0}' to cka '{1}'", iva, cka);
                cka.SetValue(vc, "{0}: Propagating initial value from iva '{1}'".CheckedFormat(PartID, iva));
            }

            syncItem.UpdateCopyInSet(ReferenceSet);

            return(syncItem);
        }
Example #3
0
        private void ServiceBridge()
        {
            if (useNominalSyncHoldoffTimer)
            {
                nominalSyncHoldoffTimer.Reset();
            }

            // service IVI table additions:
            if (lastIVINamesArrayLength != IVI.ValueNamesArrayLength)
            {
                string[] iviValueNamesArray = IVI.ValueNamesArray ?? emptyStringArray;
                lastIVINamesArrayLength = iviValueNamesArray.Length;

                // check for new IVI additions
                foreach (string ivaNativeName in iviValueNamesArray)
                {
                    if (ivaNameToSyncItemDictionary.ContainsKey(ivaNativeName) || lookAtLaterDictionary.ContainsKey(ivaNativeName))
                    {
                        continue;
                    }

                    bool propagateIVAName = BridgeConfig.IVAPropagateNameMatchRuleSet.MatchesAny(ivaNativeName);

                    string mappedFromIVAName = ivaNativeName;

                    propagateIVAName &= (BridgeConfig.IVAMapNameFromTo == null || BridgeConfig.IVAMapNameFromTo.Map(ivaNativeName, ref mappedFromIVAName));

                    string mappedToCKAKeyName = mappedFromIVAName;
                    propagateIVAName &= (BridgeConfig.CKAMapNameFromTo == null || BridgeConfig.CKAMapNameFromTo.MapInverse(mappedFromIVAName, ref mappedToCKAKeyName));

                    // check if we should add a sync item for this key or if we should indicate that we have seen it and that it will not be synced
                    if (propagateIVAName)
                    {
                        var attemptToAddSyncItemInfo = new AttemptToAddSyncItemForIVAInfo()
                        {
                            ivaNativeName      = ivaNativeName,
                            mappedFromIVAName  = mappedFromIVAName,
                            mappedToCKAKeyName = mappedToCKAKeyName,
                            iva = IVI.GetValueAccessor(ivaNativeName),
                        };

                        if (!AttemptToAddSyncItemForIVA(attemptToAddSyncItemInfo, requireUpdateNeeded: false))
                        {
                            lookAtLaterDictionary[ivaNativeName] = attemptToAddSyncItemInfo;

                            Log.Debug.Emit("IVA [{0}] has been added to look at later list", attemptToAddSyncItemInfo.iva);

                            useLookAtLaterTimer = !BridgeConfig.MinLookAtLaterInterval.IsZero();
                            if (useLookAtLaterTimer)
                            {
                                lookAtLaterTimer.StartIfNeeded(BridgeConfig.MinLookAtLaterInterval);
                            }
                        }
                    }
                    else
                    {
                        ivaNameToSyncItemDictionary[ivaNativeName] = null;
                    }
                }
            }

            // if we have lookAtLater items and the corresponding timer has triggered then
            if (lookAtLaterDictionary.Count > 0 && (!useLookAtLaterTimer || lookAtLaterTimer.IsTriggered))
            {
                foreach (var item in lookAtLaterDictionary.Values.ToArray())
                {
                    if (AttemptToAddSyncItemForIVA(item, requireUpdateNeeded: true))
                    {
                        Log.Debug.Emit("IVA [{0}] has been removed from the look at later list", item.iva);

                        lookAtLaterDictionary.Remove(item.ivaNativeName);
                    }
                }

                if (lookAtLaterDictionary.Count == 0)
                {
                    lookAtLaterTimer.Stop();
                }
            }

            // service CKA table addition:
            ConfigSubscriptionSeqNums configSeqNum = Config.SeqNums;

            if (lastConfigSeqNums.KeyAddedSeqNum != configSeqNum.KeyAddedSeqNum || lastConfigSeqNums.EnsureExistsSeqNum != configSeqNum.EnsureExistsSeqNum)
            {
                string[] configKeyNamesArray = Config.SearchForKeys();   // find all of the current keys

                foreach (string configKeyName in (configKeyNamesArray ?? emptyStringArray))
                {
                    if (configKeyNameToSyncItemDictionary.ContainsKey(configKeyName))
                    {
                        continue;
                    }

                    bool propagateConfigKeyName = BridgeConfig.CKAPropagateKeyMatchRuleSet.MatchesAny(configKeyName);

                    IConfigKeyAccess cka = (propagateConfigKeyName ? Config.GetConfigKeyAccess(new ConfigKeyAccessSpec()
                    {
                        Key = configKeyName, Flags = new ConfigKeyAccessFlags()
                        {
                            MayBeChanged = true
                        }
                    }) : null);

                    propagateConfigKeyName &= (BridgeConfig.CKAPropagateFilterPredicate == null || (cka != null && BridgeConfig.CKAPropagateFilterPredicate(cka.Key, cka.MetaData, cka.VC)));

                    string mappedFromConfigKeyName = configKeyName;
                    propagateConfigKeyName &= (BridgeConfig.CKAMapNameFromTo == null || BridgeConfig.CKAMapNameFromTo.MapInverse(configKeyName, ref mappedFromConfigKeyName));

                    string mappedToIVAName = mappedFromConfigKeyName;
                    propagateConfigKeyName &= (BridgeConfig.IVAMapNameFromTo == null || BridgeConfig.IVAMapNameFromTo.Map(mappedFromConfigKeyName, ref mappedToIVAName));

                    if (propagateConfigKeyName)
                    {
                        IValueAccessor iva = IVI.GetValueAccessor(mappedToIVAName);

                        AddSyncItemAndPerformInitialPropagation(iva, cka, mappedToIVAName, mappedFromConfigKeyName, null, configKeyName);
                    }
                    else
                    {
                        configKeyNameToSyncItemDictionary[configKeyName] = null;
                    }
                }
            }

            bool syncItemArrayUpdated = false;

            if (syncItemArray == null)
            {
                syncItemArray = syncItemList.ToArray();
                ivaArray      = syncItemArray.Select(syncItem => syncItem.iva).ToArray();
            }

            // service existing IVA -> CKA items
            if (syncItemArrayUpdated || ivaArray.IsUpdateNeeded())
            {
                foreach (SyncItem syncItem in syncItemArray)
                {
                    if (syncItem.iva.IsUpdateNeeded)
                    {
                        ValueContainer vc = syncItem.iva.Update().VC;

                        if (!vc.IsEqualTo(syncItem.icka.VC))
                        {
                            ValueTraceEmitter.Emit("Propagating iva change '{0}' to cka '{1}'", syncItem.iva, syncItem.icka);
                            syncItem.icka.SetValue(vc, "{0}: Propagating value change from iva '{1}'".CheckedFormat(PartID, syncItem.iva), autoUpdate: false);
                            syncItem.UpdateCopyInSet(ReferenceSet);
                        }
                        else
                        {
                            ValueTraceEmitter.Emit("iva '{0}' updated, value matches cka '{1}'", syncItem.iva, syncItem.icka);
                        }
                    }
                }
            }

            // service existing CKA -> IVA items
            if (lastConfigSeqNums.ChangeSeqNum != configSeqNum.ChangeSeqNum)
            {
                foreach (SyncItem syncItem in syncItemArray)
                {
                    if (syncItem.icka.UpdateValue())
                    {
                        ValueContainer vc = syncItem.icka.VC;

                        if (!vc.IsEqualTo(syncItem.iva.VC))
                        {
                            ValueTraceEmitter.Emit("Propagating cka change '{0}' to iva '{1}'", syncItem.icka, syncItem.iva);
                            syncItem.iva.Set(vc);
                            syncItem.UpdateCopyInSet(ReferenceSet);
                        }
                        else
                        {
                            ValueTraceEmitter.Emit("cka '{0}' updated, value matches iva '{1}'", syncItem.icka, syncItem.iva);
                        }
                    }
                }
            }

            // update lastConfigSeqNum as a whole
            if (!lastConfigSeqNums.Equals(configSeqNum))
            {
                lastConfigSeqNums = configSeqNum;
            }
        }
Example #4
0
        protected override string PerformServiceActionEx(IProviderFacet ipf, string serviceName, INamedValueSet npv)
        {
            switch (serviceName)
            {
            case "Sync":
                return(PerformSync());

            case "SetKey":
            {
                string         key          = npv["key"].VC.GetValue <string>(rethrow: true);
                ValueContainer value        = npv["value"].VC;
                string         comment      = npv["comment"].VC.GetValue <string>(rethrow: false, defaultValue: null).MapNullTo("{0} operation has been performed using the {1} part".CheckedFormat(serviceName, PartID));
                bool?          ensureExists = npv["ensureExists"].VC.GetValue <bool?>(rethrow: false);

                IConfigKeyAccess icka = Config.GetConfigKeyAccess(key, ensureExists: ensureExists, defaultValue: value);

                if (icka == null)
                {
                    return("Internal: GetConfigKeyAccess generated null ICKA for key '{0}'".CheckedFormat(key));
                }

                if (!icka.IsUsable)
                {
                    return("Key lookup for '{0}' gave error: {1}".CheckedFormat(key, icka.ResultCode));
                }

                string ec = icka.SetValue(value, commentStr: comment);

                ServiceBridge();

                return(ec.MapNullTo("[Internal: final ec was null]"));
            }

            case "SetKeys":
            {
                string []         keys    = npv["keys"].VC.GetValue <string []>(rethrow: true);
                ValueContainer [] values  = npv["values"].VC.GetValue <ValueContainer []>(rethrow: true);
                string            comment = npv["comment"].VC.GetValue <string>(rethrow: false, defaultValue: null).MapNullTo("{0} operation has been performed using the {1} part".CheckedFormat(serviceName, PartID));
                bool?ensureExists         = npv["ensureExists"].VC.GetValue <bool?>(rethrow: false);

                if (keys.SafeLength() != values.SafeLength())
                {
                    return("Given keys and values were not the same length");
                }

                if (keys.SafeLength() == 0)
                {
                    return("No keys were given to change");
                }

                IConfigKeyAccess[] ickaArray = keys.Select((key, idx) => Config.GetConfigKeyAccess(key, ensureExists: ensureExists, defaultValue: values[idx])).ToArray();

                if (ickaArray.Any(icka => icka == null))
                {
                    return("Internal: GetConfigKeyAccess generated null ICKA for one or more keys in [{0}]".CheckedFormat(string.Join(",", keys)));
                }

                var notFoundKeys = ickaArray.Where(icka => !icka.IsUsable).Select(icka => icka.Key).ToArray();
                if (!notFoundKeys.IsNullOrEmpty())
                {
                    return("Key lookup for keys '{0}' failed".CheckedFormat(string.Join(",", notFoundKeys)));
                }

                string ec = Config.SetValues(ickaArray.Select((icka, idx) => KVP.Create(icka, values[idx])).ToArray(), comment);

                ServiceBridge();

                return(ec.MapNullTo("[Internal: final ec was null]"));
            }

            default:
                return(base.PerformServiceAction(serviceName));
            }
        }