cancel
Showing results for 
Search instead for 
Did you mean: 

client side conflict solution fails

Former Member
0 Kudos

Hallo,

In our application we want to resolve synchronisation conflicts on the

client side.

For a specific SyncBO. We want the the client data to be dominant.

To achieve this we tried two ways of conflict resolvance:

1. We used the ErrorConflictInbox to loop over all conflicts for that

SyncBO and used the method acceptClientSyncBo on the SyncBoResponse

object

try{MeIterator meIter = SmartSyncRuntime.getInstance().getInboxNotifier

().getErrorConflictInbox().getSyncBoResponses

(assignmentSyncBoDescriptor,

SyncBoResponseType.CONFLICT);resolvedAssignmentConflicts =

meIter.hasNext();while (meIter.hasNext()){SyncBoResponse conflict =

(SyncBoResponse) meIter.next();if(conflict.getSyncBoResponseState

().equals(SyncBoResponseState.INITIAL)){conflict.acceptClientSyncBo

();}}} catch (Exception e){log.logException(e, true);}

2. We registered a SyncReplyObserver in which we used the method

acceptClientSyncBo on the SyncBoResponse object

public SynchronizationControllerImpl(){SmartSyncRuntime.getInstance

().getInboxNotifier().registerSyncReplyObserver(assignmentObserver);}

private AssignmentDeltaObserver assignmentObserver = new

AssignmentDeltaObserver();

private class AssignmentDeltaObserver implements SyncReplyObserver

{public SyncBoDescriptor[] observerSyncBoTypes(){return new

SyncBoDescriptor[] { assignmentSyncBoDescriptor };}public SyncReplyType

[] observeSyncReplyTypes(){return new SyncReplyType[] {

SyncReplyType.CONFLICT };}public void syncReplyReceived(SyncReply arg0,

SyncBoDescriptor arg1, String arg2){try{SyncBoResponse conflict =

SmartSyncRuntime.getInstance().getInboxNotifier().getErrorConflictInbox

().getSyncBoResponse(assignmentSyncBoDescriptor, new BigInteger

(arg2));conflict.acceptClientSyncBo();} catch (Exception ignored)

{log.logException(ignored,true);}}}

In the first case we did not get every conflict, in fact we only got

ONE unresolved conflict and the next time we only got SyncBoResponses

with status resolved.

In the second case we were able to process every conflict, but than the

following problem which applied also to the first case occured:

The SyncBoResponseState was changed to RESOLVED, but the BusinessObject

remaind in state 16 (BusinessObject.STATUS_IN_SYNC) and the client-/

and serverdata differed.

As far as I had understood, the client data now should have been send

to the server on the next synchronization, but the data had not been

synchronized until the BusinessObject had been changed again on the

client.

As it seemed to be necessary to change the data after the conflict had

been resolved, to make it synchronize again, we tried to make a change - change back cycle on some data, but although the BusinessObject's

state changed to 8 (BusinessObject.STATUS_GLOBAL) on the first change,

the state went back to 16 on re-modification.

More importantly the data had not been synchronized when the client was

synchronized again.

Has anyone done this before and am I on the right way? Why does not it work?

Greetings,

Kai

Accepted Solutions (0)

Answers (1)

Answers (1)

Former Member
0 Kudos

hello kai,

your first code doesn't have any problem at all. im just

wondering the line with //????// comment. do you assume

that the first iterator object is a resolved conflict?

after resolving the conflict, the SyncBoResponse instance

having a RESOLVED will stay in your local repository. you

have to call delete() method.

by the way, at which timing does your application resolve

the conflicts?

try{
 MeIterator meIter = SmartSyncRuntime.getInstance()
           .getInboxNotifier().getErrorConflictInbox()
           .getSyncBoResponses(assignmentSyncBoDescriptor,
            SyncBoResponseType.CONFLICT);
 <b>//????//</b>
 resolvedAssignmentConflicts = meIter.hasNext();
 while (meIter.hasNext()){
  SyncBoResponse conflict =(SyncBoResponse) meIter.next();
  if(conflict.getSyncBoResponseState().equals (SyncBoResponseState.INITIAL)){
   conflict.acceptClientSyncBo();
   <b>//removed the RESOLVED ones; you may add state check as well
   conflict.delete();</b>
  }
 }
} catch (Exception e){log.logException(e, true);}

the same thing goes to your 2nd code. you have to call the

delete() method of the SyncBoResponse once they are processed.

what really happens when you invoke the acceptClientSyncBo

method is that

1)the quarantined client SyncBo is copied to tempObject

2)the server data is applied; making the client SyncBo a

global image - state GLOBAL/SYNCHED

3)the client modification is applied using the tempObject

-> client syncBo state is now INCONSISTENT; there's a delta

data to be uploaded.

4)SyncBoResponse is transitional to RESOLVED

on your next sync, this delta data will be sent to the server

just like a normal delta upload. until your success response

for that delta upload message is received in the client,

your SyncBo will be in its INSYNC state.

hope this clear up some of your doubts.

just let me know if you need more details.

regards

jo

Former Member
0 Kudos

Hello Jo,

Thanks for your answer..but we did already try to delete the SyncBoResponse after accepting the ClientSyncBo, this did not lead to a solution of our problem.

The states of the SyncBo/SyncBoResponse are as you mentioned, except that there is no delta send to the server on next (or any following) sync and the SyncBo does not get into INSYNC state. Only if the SyncBo is changed afterwards, then delta data is send to the server and the state becomes INSYNC.

Greetings,

Kai

Former Member
0 Kudos

hello kai,

could you give me the State of your SyncBo before and

after the acceptClientSyncBo() call?

use SyncBo.getState() api to retrieve your state.

regards

jo

Former Member
0 Kudos

Hi Jo,

The state of the SyncBo before the acceptSyncBo call is QUARANTINED.

The state after the call is INCONSISTENT.

Does this helps you?

Greetings,

Kai

Former Member
0 Kudos

hello kai,

thanks for checking the states... they're normal at all.

if you think that your client delta is not uploaded, try

listing up your outbound delta before synchronizing. you

can make use of the SyncBoOutDeltaFacade.getAllDelta which

will give an MeIterator instance.

if your delta is in there and is not uploaded during sync,

try checking if you have a call to SyncBoOutDeltaFacade.setSendType

which suppresses the said SyncBo in sending the delta.

you can also check in the raw container logs if your data

was sent or not... if your data was sent and was not in

the worklist monitor, it could be a bug... open an OSS

message in this case.

regards

jo