@Test public void testConflict() throws Exception { final ApplicationScope scope = mock( ApplicationScope.class ); when( scope.getApplication() ) .thenReturn( new SimpleId( UUIDGenerator.newTimeUUID(), "organization" ) ); final Session session = mock(Session.class); final Entity entity = generateEntity(); entity.setField(new StringField("name", "FOO", true)); entity.setField(new StringField("identifier", "BAR", true)); List<MvccLogEntry> logEntries = new ArrayList<MvccLogEntry>(); logEntries.add( new MvccLogEntryImpl( entity.getId(), UUIDGenerator.newTimeUUID(), Stage.ACTIVE, MvccLogEntry.State.COMPLETE )); logEntries.add( new MvccLogEntryImpl( entity.getId(), UUIDGenerator.newTimeUUID(), Stage.ACTIVE, MvccLogEntry.State.COMPLETE )); MvccLogEntrySerializationStrategy mvccLog = mock( MvccLogEntrySerializationStrategy.class ); when( mvccLog.load( scope, entity.getId(), entity.getVersion(), 2) ) .thenReturn( logEntries ); UniqueValueSerializationStrategy uvstrat = mock( UniqueValueSerializationStrategy.class); UniqueValue uv1 = new UniqueValueImpl(entity.getField("name"), entity.getId(), entity.getVersion()); UniqueValue uv2 = new UniqueValueImpl( entity.getField("identifier"), entity.getId(), entity.getVersion()); final MvccEntity mvccEntity = fromEntity( entity ); boolean conflictDetected = false; WriteOptimisticVerify newStage = new WriteOptimisticVerify( mvccLog ); RollbackAction rollbackAction = new RollbackAction( mvccLog, uvstrat, session ); try { newStage.call( new CollectionIoEvent<>(scope, mvccEntity)); } catch (WriteOptimisticVerifyException e) { logger.info("Error", e); conflictDetected = true; rollbackAction.call( e ); } assertTrue( conflictDetected ); verify( uvstrat, times(1) ).deleteCQL(scope, uv1 ); verify( uvstrat, times(1) ).deleteCQL(scope, uv2 ); }
@Override public void call( final CollectionIoEvent<MvccEntity> ioevent ) { MvccValidationUtils.verifyMvccEntityWithEntity( ioevent.getEvent() ); MvccEntity mvccEntity = ioevent.getEvent(); final Entity entity = mvccEntity.getEntity().get(); ApplicationScope applicationScope = ioevent.getEntityCollection(); if ( entity.getVersion() == null ) { return; } List<MvccLogEntry> versions = logEntryStrat.load( applicationScope, entity.getId(), entity.getVersion(), 2 ); if ( versions.size() > 1 && versions.get( 1 ).getStage().ordinal() < Stage.COMMITTED.ordinal() ) { logger.debug( "Conflict writing entity id {} version {}", entity.getId().toString(), entity.getVersion().toString() ); throw new WriteOptimisticVerifyException( mvccEntity, applicationScope, "Change conflict, not first writer" ); } }
WriteOptimisticVerify implements Action1<CollectionIoEvent<MvccEntity>> { @Override public void call( final CollectionIoEvent<MvccEntity> ioevent ) { MvccValidationUtils.verifyMvccEntityWithEntity( ioevent.getEvent() ); MvccEntity mvccEntity = ioevent.getEvent(); final Entity entity = mvccEntity.getEntity().get(); ApplicationScope applicationScope = ioevent.getEntityCollection(); if ( entity.getVersion() == null ) { return; } List<MvccLogEntry> versions = logEntryStrat.load( applicationScope, entity.getId(), entity.getVersion(), 2 ); if ( versions.size() > 1 && versions.get( 1 ).getStage().ordinal() < Stage.COMMITTED.ordinal() ) { logger.debug( "Conflict writing entity id {} version {}", entity.getId().toString(), entity.getVersion().toString() ); throw new WriteOptimisticVerifyException( mvccEntity, applicationScope, "Change conflict, not first writer" ); } } }
WriteOptimisticVerify implements Action1<CollectionIoEvent<MvccEntity>> { @Override public void call( final CollectionIoEvent<MvccEntity> ioevent ) { MvccValidationUtils.verifyMvccEntityWithEntity( ioevent.getEvent() ); MvccEntity mvccEntity = ioevent.getEvent(); final Entity entity = mvccEntity.getEntity().get(); ApplicationScope applicationScope = ioevent.getEntityCollection(); if ( entity.getVersion() == null ) { return; } List<MvccLogEntry> versions = logEntryStrat.load( applicationScope, entity.getId(), entity.getVersion(), 2 ); if ( versions.size() > 1 && versions.get( 1 ).getStage().ordinal() < Stage.COMMITTED.ordinal() ) { logger.debug( "Conflict writing entity id {} version {}", entity.getId().toString(), entity.getVersion().toString() ); throw new WriteOptimisticVerifyException( mvccEntity, applicationScope, "Change conflict, not first writer" ); } } @Inject  WriteOptimisticVerify( MvccLogEntrySerializationStrategy logEntryStrat ); }
WriteOptimisticVerify implements Action1<CollectionIoEvent<MvccEntity>> { @Override public void call( final CollectionIoEvent<MvccEntity> ioevent ) { MvccValidationUtils.verifyMvccEntityWithEntity( ioevent.getEvent() ); MvccEntity mvccEntity = ioevent.getEvent(); final Entity entity = mvccEntity.getEntity().get(); ApplicationScope applicationScope = ioevent.getEntityCollection(); if ( entity.getVersion() == null ) { return; } List<MvccLogEntry> versions = logEntryStrat.load( applicationScope, entity.getId(), entity.getVersion(), 2 ); if ( versions.size() > 1 && versions.get( 1 ).getStage().ordinal() < Stage.COMMITTED.ordinal() ) { logger.debug( "Conflict writing entity id {} version {}", entity.getId().toString(), entity.getVersion().toString() ); throw new WriteOptimisticVerifyException( mvccEntity, applicationScope, "Change conflict, not first writer" ); } } @Inject  WriteOptimisticVerify( MvccLogEntrySerializationStrategy logEntryStrat ); @Override void call( final CollectionIoEvent<MvccEntity> ioevent ); }
WriteOptimisticVerify implements Action1<CollectionIoEvent<MvccEntity>> { @Override public void call( final CollectionIoEvent<MvccEntity> ioevent ) { MvccValidationUtils.verifyMvccEntityWithEntity( ioevent.getEvent() ); MvccEntity mvccEntity = ioevent.getEvent(); final Entity entity = mvccEntity.getEntity().get(); ApplicationScope applicationScope = ioevent.getEntityCollection(); if ( entity.getVersion() == null ) { return; } List<MvccLogEntry> versions = logEntryStrat.load( applicationScope, entity.getId(), entity.getVersion(), 2 ); if ( versions.size() > 1 && versions.get( 1 ).getStage().ordinal() < Stage.COMMITTED.ordinal() ) { logger.debug( "Conflict writing entity id {} version {}", entity.getId().toString(), entity.getVersion().toString() ); throw new WriteOptimisticVerifyException( mvccEntity, applicationScope, "Change conflict, not first writer" ); } } @Inject  WriteOptimisticVerify( MvccLogEntrySerializationStrategy logEntryStrat ); @Override void call( final CollectionIoEvent<MvccEntity> ioevent );  }