public void TestSyncDelta()
        {
            ConnectorObjectBuilder objbuilder =
                new ConnectorObjectBuilder();
            objbuilder.SetName("myname");
            objbuilder.SetUid("myuid");
            objbuilder.AddAttribute(CreateTestAttribute());
            ConnectorObject obj = objbuilder.Build();

            SyncDeltaBuilder builder =
                new SyncDeltaBuilder();
            builder.DeltaType = (SyncDeltaType.DELETE);
            builder.Token = (new SyncToken("mytoken"));
            builder.Uid = (new Uid("myuid"));
            builder.Object = (obj);
            SyncDelta v1 = builder.Build();
            SyncDelta v2 = CreateTestNormalizer().NormalizeSyncDelta(v1);
            builder =
                new SyncDeltaBuilder();
            builder.DeltaType = (SyncDeltaType.DELETE);
            builder.Token = (new SyncToken("mytoken"));
            builder.Uid = (new Uid("myuid"));
            objbuilder =
                new ConnectorObjectBuilder();
            objbuilder.SetName("myname");
            objbuilder.SetUid("myuid");
            objbuilder.AddAttribute(CreateNormalizedTestAttribute());
            builder.Object = objbuilder.Build();
            SyncDelta expected = builder.Build();
            Assert.AreEqual(expected, v2);
            Assert.IsFalse(expected.Equals(v1));
        }
Пример #2
0
        public void TestSyncDelta()
        {
            ConnectorObjectBuilder bld = new ConnectorObjectBuilder();
            bld.SetUid("foo");
            bld.SetName("name");
            SyncDeltaBuilder builder = new SyncDeltaBuilder();
            builder.PreviousUid = (new Uid("mypreviousuid"));
            builder.Uid = (new Uid("myuid"));
            builder.DeltaType = (SyncDeltaType.CREATE_OR_UPDATE);
            builder.Token = (new SyncToken("mytoken"));
            builder.Object = (bld.Build());
            SyncDelta v1 = builder.Build();
            SyncDelta v2 = (SyncDelta)CloneObject(v1);
            Assert.AreEqual(new Uid("mypreviousuid"), v2.PreviousUid);
            Assert.AreEqual(new Uid("foo"), v2.Uid);
            Assert.AreEqual(new SyncToken("mytoken"), v2.Token);
            Assert.AreEqual(SyncDeltaType.CREATE_OR_UPDATE, v2.DeltaType);
            Assert.AreEqual(v1, v2);

            builder = new SyncDeltaBuilder();
            builder.DeltaType = SyncDeltaType.DELETE;
            builder.Token = new SyncToken("mytoken");
            builder.ObjectClass = ObjectClass.ACCOUNT;
            builder.Uid = new Uid("foo");
            v1 = builder.Build();
            v2 = (SyncDelta)CloneObject(v1);
            Assert.AreEqual(ObjectClass.ACCOUNT, v2.ObjectClass);
            Assert.AreEqual(new Uid("foo"), v2.Uid);
            Assert.AreEqual(new SyncToken("mytoken"), v2.Token);
            Assert.AreEqual(SyncDeltaType.DELETE, v2.DeltaType);
            Assert.AreEqual(v1, v2);
        }
        /// <summary>
        /// Process the Hashtable result and convert it to a SyncDelta object
        /// ready to be processed by the sync handler 
        /// </summary>
        /// <remarks>
        /// The result Hashtable must follow a specific format and contain the following key/value:
        /// 
        /// "Token": (Object) token object (could be Integer, Date, String), [!! could be null]
        /// "DeltaType": (String) ("CREATE|UPDATE|CREATE_OR_UPDATE"|"DELETE"),
        /// "Uid": (String) uid  (uid of the entry),
        /// "PreviousUid": (String) previous uid (This is for rename ops),
        /// "Object": Hashtable(String,List) of attributes name/values describing the object
        /// "ObjectClass": (String) must be set if Operation = DELETE and Object = null
        /// </remarks>
        /// <param name="result"></param>
        /// <returns></returns>
        public Object Process(Hashtable result)
        {
            var syncbld = new SyncDeltaBuilder();
            var cobld = new ConnectorObjectBuilder();
            Uid uid;

            // SyncToken
            // Mandatory here
            if (result.ContainsKey(SyncTokenKeyName))
            {
                syncbld.Token = result[SyncTokenKeyName] == null ? new SyncToken(0L) : new SyncToken(result[SyncTokenKeyName]);
            }
            else
                throw new ArgumentException("SyncToken is missing in Sync result");

            // SyncDelta
            // Mandatory here
            if (isValidKeyAndValue(result,DeltaTypeKeyName))
            {
                var op = result[DeltaTypeKeyName];
                if (SyncDeltaType.CREATE.ToString().Equals(op as String, StringComparison.OrdinalIgnoreCase))
                    syncbld.DeltaType = SyncDeltaType.CREATE;
                else if (SyncDeltaType.UPDATE.ToString().Equals(op as String, StringComparison.OrdinalIgnoreCase))
                    syncbld.DeltaType = SyncDeltaType.UPDATE;
                else if (SyncDeltaType.DELETE.ToString().Equals(op as String, StringComparison.OrdinalIgnoreCase))
                    syncbld.DeltaType = SyncDeltaType.DELETE;
                else if (SyncDeltaType.CREATE_OR_UPDATE.ToString().Equals(op as String, StringComparison.OrdinalIgnoreCase))
                    syncbld.DeltaType = SyncDeltaType.CREATE_OR_UPDATE;
                else
                    throw new ArgumentException("Unrecognized DeltaType in Sync result");
            }
            else
                throw new ArgumentException("DeltaType is missing in Sync result");

            // Uid
            // Mandatory
            if (isValidKeyAndValue(result, UidKeyName))
            {
                var value = result[UidKeyName];
                if (value is String)
                {
                    uid = new Uid(value as String);
                } else if (value is Uid)
                {
                    uid = value as Uid;
                }
                else
                {
                    throw new ArgumentException("Unrecognized Uid in Sync result");
                }
                syncbld.Uid = uid;
                cobld.SetUid(uid);
            }
            else
            {
                throw new ArgumentException("Uid is missing in Sync result");
            }

            // PreviousUid
            // Not valid if DELETE
            if (isValidKeyAndValue(result, PreviousUidKeyName))
            {
                var value = result[PreviousUidKeyName];
                Uid previousUid;
                if (value is String)
                {
                    previousUid = new Uid(value as String);
                }
                else if (value is Uid)
                {
                    previousUid = value as Uid;
                }
                else
                {
                    throw new ArgumentException("Unrecognized PreviousUid in Sync result");
                }
                syncbld.PreviousUid = previousUid;
            }
            if (syncbld.PreviousUid != null && syncbld.DeltaType == SyncDeltaType.DELETE)
            {
                throw new ArgumentException("PreviousUid can only be specified for Create or Update.");
            }

            // Connector object
            // Mandatory unless DELETE
            if (result.ContainsKey(ConnectorObjectKeyName) && result[ConnectorObjectKeyName] is Hashtable)
            {
                var attrs = result[ConnectorObjectKeyName] as Hashtable;

                if (!attrs.ContainsKey(Name.NAME))
                    throw new ArgumentException("The Object must contain a Name");

                foreach (DictionaryEntry attr in attrs)
                {
                    var attrName = attr.Key as String;
                    var attrValue = attr.Value;

                    if (Name.NAME.Equals(attrName))
                        cobld.SetName(attrValue as String);
                    else if (Uid.NAME.Equals((attrName)))
                    {
                        if (!uid.GetUidValue().Equals(attrValue))
                            throw new ArgumentException("Uid from Object is different than Uid from Sync result");
                    }
                    else if (OperationalAttributes.ENABLE_NAME.Equals((attrName)))
                        cobld.AddAttribute(ConnectorAttributeBuilder.BuildEnabled(attr.Value is bool && (bool) attr.Value));
                    else
                    {
                        if (attrValue == null)
                        {
                            cobld.AddAttribute(ConnectorAttributeBuilder.Build(attrName));
                        }
                        else if (attrValue.GetType() == typeof(Object[]) || attrValue.GetType() == typeof(System.Collections.ICollection))
                        {
                            var list = new Collection<object>();
                            foreach (var val in (ICollection)attrValue)
                            {
                                list.Add(FrameworkUtil.IsSupportedAttributeType(val.GetType()) ? val : val.ToString());
                            }
                            cobld.AddAttribute(ConnectorAttributeBuilder.Build(attrName, list));
                        }
                        else
                        {
                            cobld.AddAttribute(ConnectorAttributeBuilder.Build(attrName, attrValue));
                        }
                    }
                }
                cobld.ObjectClass = _objectClass;
                syncbld.Object = cobld.Build();
            }
            // If operation is DELETE and the ConnectorObject is null,
            // we need to set the ObjectClass at the SyncDelta level
            else if ((SyncDeltaType.DELETE == syncbld.DeltaType) && isValidKeyAndValue(result, ObjectClassKeyName))
            {
                var objclass = result[ObjectClassKeyName];
                if (objclass is ObjectClass)
                {
                    syncbld.ObjectClass = objclass as ObjectClass;
                }
                else if (objclass is String)
                {
                    syncbld.ObjectClass = new ObjectClass(objclass as String);
                }
                else
                {
                    throw new ArgumentException("Unrecognized ObjectClass in Sync result");
                }
            }
            else
            {
                throw new ArgumentException("Object is missing in Sync result");
            }

            return _handler.Handle(syncbld.Build());
        }