Commit 01840c37 authored by Sebastien Robin's avatar Sebastien Robin

added new tests (change an object on two different places at the same time,

                 working on subojbects)
added the simulation of conflicts in the synchronization
corrected some bugs


git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@387 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent 02f2305d
This diff is collapsed.
...@@ -198,6 +198,8 @@ class Signature(SyncCode): ...@@ -198,6 +198,8 @@ class Signature(SyncCode):
self.resetConflictList() self.resetConflictList()
self.md5_string = None self.md5_string = None
self.force = 0 self.force = 0
self.setSubscriberXupdate(None)
self.setPublisherXupdate(None)
#def __init__(self,object=None, status=None, xml_string=None): #def __init__(self,object=None, status=None, xml_string=None):
# self.uid = object.uid # self.uid = object.uid
...@@ -271,6 +273,30 @@ class Signature(SyncCode): ...@@ -271,6 +273,30 @@ class Signature(SyncCode):
""" """
return self.temp_xml return self.temp_xml
def setSubscriberXupdate(self, xupdate):
"""
set the full temp xupdate
"""
self.subscriber_xupdate = xupdate
def getSubscriberXupdate(self):
"""
get the full temp xupdate
"""
return self.subscriber_xupdate
def setPublisherXupdate(self, xupdate):
"""
set the full temp xupdate
"""
self.publisher_xupdate = xupdate
def getPublisherXupdate(self):
"""
get the full temp xupdate
"""
return self.publisher_xupdate
def setMD5(self, xml): def setMD5(self, xml):
""" """
set the MD5 object of this signature set the MD5 object of this signature
......
...@@ -552,13 +552,23 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -552,13 +552,23 @@ class XMLSyncUtilsMixin(SyncCode):
def getSyncMLData(self, domain=None,remote_xml=None,cmd_id=0, def getSyncMLData(self, domain=None,remote_xml=None,cmd_id=0,
subscriber=None,destination_path=None, subscriber=None,destination_path=None,
xml_confirmation=None): xml_confirmation=None,conduit=None):
""" """
This generate the syncml data message. This returns a string This generate the syncml data message. This returns a string
with all modification made locally (ie replace, add ,delete...) with all modification made locally (ie replace, add ,delete...)
if object is not None, this usually means we want to set the
actual xupdate on the signature.
""" """
local_gid_list = [] local_gid_list = []
syncml_data = '' syncml_data = ''
# store_xupdate = 0
# if object is None:
# object_list = domain.getObjectList()
# else:
# store_xupdate = 1
# object_list = [object]
for object in domain.getObjectList(): for object in domain.getObjectList():
status = self.SENT status = self.SENT
gid_generator = getattr(object,domain.getGidGenerator(),None) gid_generator = getattr(object,domain.getGidGenerator(),None)
...@@ -575,6 +585,7 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -575,6 +585,7 @@ class XMLSyncUtilsMixin(SyncCode):
LOG('getSyncMLData',0,'hasSignature: %s' % str(subscriber.hasSignature(object_gid))) LOG('getSyncMLData',0,'hasSignature: %s' % str(subscriber.hasSignature(object_gid)))
LOG('getSyncMLData',0,'alert_code == slowsync: %s' % str(self.getAlertCode(remote_xml)==self.SLOW_SYNC)) LOG('getSyncMLData',0,'alert_code == slowsync: %s' % str(self.getAlertCode(remote_xml)==self.SLOW_SYNC))
signature = subscriber.getSignature(object_gid) signature = subscriber.getSignature(object_gid)
LOG('getSyncMLData',0,'current object: %s' % str(object.getId()))
if signature is not None: if signature is not None:
LOG('getSyncMLData',0,'signature.status: %s' % str(signature.getStatus())) LOG('getSyncMLData',0,'signature.status: %s' % str(signature.getStatus()))
LOG('getSyncMLData',0,'signature.action: %s' % str(signature.getAction())) LOG('getSyncMLData',0,'signature.action: %s' % str(signature.getAction()))
...@@ -615,7 +626,9 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -615,7 +626,9 @@ class XMLSyncUtilsMixin(SyncCode):
if signature.getStatus()==self.PUB_CONFLICT_MERGE: if signature.getStatus()==self.PUB_CONFLICT_MERGE:
xml_confirmation += self.SyncMLConfirmation(cmd_id,object.id, xml_confirmation += self.SyncMLConfirmation(cmd_id,object.id,
self.CONFLICT_MERGE,'Replace') self.CONFLICT_MERGE,'Replace')
set_synchronized = 1
if not signature.checkMD5(xml_object): if not signature.checkMD5(xml_object):
set_synchronized = 0
# This object has changed on this side, we have to generate some xmldiff # This object has changed on this side, we have to generate some xmldiff
xml_string = self.getXupdateObject(object=object, xml_string = self.getXupdateObject(object=object,
xml_mapping=domain.xml_mapping, xml_mapping=domain.xml_mapping,
...@@ -638,7 +651,18 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -638,7 +651,18 @@ class XMLSyncUtilsMixin(SyncCode):
xml_string=xml_string, more_data=more_data) xml_string=xml_string, more_data=more_data)
cmd_id += 1 cmd_id += 1
signature.setTempXML(xml_object) signature.setTempXML(xml_object)
else: # We should not have this case when we are in CONFLICT_MERGE # Now we can apply the xupdate from the subscriber
subscriber_xupdate = signature.getSubscriberXupdate()
LOG('getSyncMLData subscriber_xupdate',0,subscriber_xupdate)
if subscriber_xupdate is not None:
old_xml = signature.getXML()
conduit.updateNode(xml=subscriber_xupdate, object=object,
previous_xml=old_xml,force=(domain.getDomainType==self.SUB),
simulate=0)
xml_object = self.getXMLObject(object=object,xml_mapping=domain.xml_mapping)
signature.setTempXML(xml_object)
if set_synchronized: # We have to do that after this previous update
# We should not have this case when we are in CONFLICT_MERGE
signature.setStatus(self.SYNCHRONIZED) signature.setStatus(self.SYNCHRONIZED)
elif signature.getStatus()==self.PUB_CONFLICT_CLIENT_WIN: elif signature.getStatus()==self.PUB_CONFLICT_CLIENT_WIN:
# We have decided to apply the update # We have decided to apply the update
...@@ -691,7 +715,7 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -691,7 +715,7 @@ class XMLSyncUtilsMixin(SyncCode):
return (syncml_data,xml_confirmation,cmd_id) return (syncml_data,xml_confirmation,cmd_id)
def applyActionList(self, domain=None, subscriber=None,destination_path=None, def applyActionList(self, domain=None, subscriber=None,destination_path=None,
cmd_id=0,remote_xml=None,conduit=None): cmd_id=0,remote_xml=None,conduit=None,simulate=0):
""" """
This just look to a list of action to do, then id applies This just look to a list of action to do, then id applies
each action one by one, thanks to a conduit each action one by one, thanks to a conduit
...@@ -706,8 +730,6 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -706,8 +730,6 @@ class XMLSyncUtilsMixin(SyncCode):
status_code = self.SUCCESS status_code = self.SUCCESS
# Thirst we have to check the kind of action it is # Thirst we have to check the kind of action it is
partial_data = self.getPartialData(next_action) partial_data = self.getPartialData(next_action)
#LOG('XMLSyncUtils',0,'partial_data: %s' % str(partial_data))
#LOG('XMLSyncUtils',0,'checkActionMoreData: %s' % str(self.checkActionMoreData(next_action)))
object_gid = self.getActionId(next_action) object_gid = self.getActionId(next_action)
signature = subscriber.getSignature(object_gid) signature = subscriber.getSignature(object_gid)
if signature == None: if signature == None:
...@@ -749,12 +771,6 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -749,12 +771,6 @@ class XMLSyncUtilsMixin(SyncCode):
self.SyncMLConfirmation(cmd_id,object_gid,self.SUCCESS,'Add') self.SyncMLConfirmation(cmd_id,object_gid,self.SUCCESS,'Add')
cmd_id +=1 cmd_id +=1
elif next_action.nodeName == 'Replace': elif next_action.nodeName == 'Replace':
#object = domain.getObjectFromGid(object=destination_path,gid=object_gid)
# object =None
# try:
# object = destination_path._getOb(self.getActionId(next_action))
# except (AttributeError, KeyError):
# pass
LOG('SyncModif',0,'object: %s will be updated...' % str(object)) LOG('SyncModif',0,'object: %s will be updated...' % str(object))
if object is not None: if object is not None:
LOG('SyncModif',0,'object: %s will be updated...' % object.id) LOG('SyncModif',0,'object: %s will be updated...' % object.id)
...@@ -763,7 +779,8 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -763,7 +779,8 @@ class XMLSyncUtilsMixin(SyncCode):
previous_xml = signature.getXML() previous_xml = signature.getXML()
LOG('SyncModif',0,'previous signature: %i' % len(previous_xml)) LOG('SyncModif',0,'previous signature: %i' % len(previous_xml))
conflict_list += conduit.updateNode(xml=data_subnode, object=object, conflict_list += conduit.updateNode(xml=data_subnode, object=object,
previous_xml=signature.getXML(),force=force) previous_xml=signature.getXML(),force=force,
simulate=simulate)
mapping = getattr(object,domain.getXMLMapping(),None) mapping = getattr(object,domain.getXMLMapping(),None)
xml_object = '' xml_object = ''
if mapping is not None: if mapping is not None:
...@@ -778,11 +795,25 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -778,11 +795,25 @@ class XMLSyncUtilsMixin(SyncCode):
PrettyPrint(data_subnode,stream=string_io) PrettyPrint(data_subnode,stream=string_io)
data_subnode_string = string_io.getvalue() data_subnode_string = string_io.getvalue()
signature.setPartialXML(data_subnode_string) signature.setPartialXML(data_subnode_string)
else: elif not simulate:
signature.setStatus(self.SYNCHRONIZED) signature.setStatus(self.SYNCHRONIZED)
xml_confirmation += self.SyncMLConfirmation(cmd_id, xml_confirmation += self.SyncMLConfirmation(cmd_id,
object_gid,status_code,'Replace') object_gid,status_code,'Replace')
cmd_id +=1 cmd_id +=1
if simulate:
# This means we are on the publiher side and we want to store
# the xupdate from the subscriber and we also want to generate
# the current xupdate from the last synchronization
string_io = StringIO()
PrettyPrint(data_subnode,stream=string_io)
data_subnode_string = string_io.getvalue()
LOG('applyActionList, subscriber_xupdate:',0,data_subnode_string)
signature.setSubscriberXupdate(data_subnode_string)
# xml_string = self.getXupdateObject(object=object,
# xml_mapping=domain.xml_mapping,
# old_xml=signature.getXML())
# signature.setPublisherXupdate(xml_string) XXX is it needed ??
elif next_action.nodeName == 'Delete': elif next_action.nodeName == 'Delete':
object_id = object.id object_id = object.id
conduit.deleteNode(xml=self.getDataSubNode(next_action), object=destination_path, conduit.deleteNode(xml=self.getDataSubNode(next_action), object=destination_path,
...@@ -881,7 +912,9 @@ class XMLSyncUtils(XMLSyncUtilsMixin): ...@@ -881,7 +912,9 @@ class XMLSyncUtils(XMLSyncUtilsMixin):
return return
subscriber = domain # If we are the client, this is fine subscriber = domain # If we are the client, this is fine
simulate = 0 # used by applyActionList, should be 0 for client
if domain.domain_type == self.PUB: if domain.domain_type == self.PUB:
simulate = 1
for subnode in xml_header.childNodes: for subnode in xml_header.childNodes:
if subnode.nodeType == subnode.ELEMENT_NODE and subnode.nodeName == "Source": if subnode.nodeType == subnode.ELEMENT_NODE and subnode.nodeName == "Source":
subscription_url = str(subnode.childNodes[0].data) subscription_url = str(subnode.childNodes[0].data)
...@@ -901,7 +934,7 @@ class XMLSyncUtils(XMLSyncUtilsMixin): ...@@ -901,7 +934,7 @@ class XMLSyncUtils(XMLSyncUtilsMixin):
destination_path=destination_path, destination_path=destination_path,
subscriber=subscriber, subscriber=subscriber,
remote_xml=remote_xml, remote_xml=remote_xml,
conduit=conduit) conduit=conduit, simulate=simulate)
LOG('SyncModif, has_next_action:',0,has_next_action) LOG('SyncModif, has_next_action:',0,has_next_action)
xml = "" xml = ""
...@@ -925,7 +958,8 @@ class XMLSyncUtils(XMLSyncUtilsMixin): ...@@ -925,7 +958,8 @@ class XMLSyncUtils(XMLSyncUtilsMixin):
remote_xml=remote_xml, remote_xml=remote_xml,
subscriber=subscriber, subscriber=subscriber,
destination_path=destination_path, destination_path=destination_path,
cmd_id=cmd_id,xml_confirmation=xml_confirmation) cmd_id=cmd_id,xml_confirmation=xml_confirmation,
conduit=conduit)
# syncml body # syncml body
xml += ' <SyncBody>\n' xml += ' <SyncBody>\n'
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment