You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@usergrid.apache.org by mr...@apache.org on 2016/06/29 17:55:26 UTC
[1/4] usergrid git commit: Improve read repair for missing Edge
(app->collection). Also enhance read repair for unique value cleanup to
happen only upon initial read before write-first strategy for Unique Values.
Add a bunch more tests around the read r
Repository: usergrid
Updated Branches:
refs/heads/release-2.1.1 37c482c5e -> f4ae0cb85
Improve read repair for missing Edge (app->collection). Also enhance read repair for unique value cleanup to happen only upon initial read before write-first strategy for Unique Values. Add a bunch more tests around the read repairs.
Project: http://git-wip-us.apache.org/repos/asf/usergrid/repo
Commit: http://git-wip-us.apache.org/repos/asf/usergrid/commit/724968a2
Tree: http://git-wip-us.apache.org/repos/asf/usergrid/tree/724968a2
Diff: http://git-wip-us.apache.org/repos/asf/usergrid/diff/724968a2
Branch: refs/heads/release-2.1.1
Commit: 724968a2bc354e3c3f317e1d0b98026c2fe3baeb
Parents: 9c4b524
Author: Michael Russo <mr...@apigee.com>
Authored: Wed Jun 29 01:45:57 2016 -0700
Committer: Michael Russo <mr...@apigee.com>
Committed: Wed Jun 29 01:45:57 2016 -0700
----------------------------------------------------------------------
.../corepersistence/CpEntityManager.java | 6 ++
.../corepersistence/CpRelationManager.java | 42 +++++++++
.../usergrid/persistence/EntityManager.java | 16 +++-
.../usergrid/persistence/RelationManager.java | 2 +
.../impl/EntityCollectionManagerImpl.java | 5 +-
.../mvcc/stage/write/WriteUniqueVerify.java | 13 ++-
.../UniqueValueSerializationStrategy.java | 7 +-
.../UniqueValueSerializationStrategyImpl.java | 89 +++++++++++---------
...iqueValueSerializationStrategyProxyImpl.java | 8 +-
.../mvcc/stage/write/WriteUniqueVerifyIT.java | 71 ++++++++++++++++
...niqueValueSerializationStrategyImplTest.java | 26 ++++--
.../collection/users/PermissionsResourceIT.java | 4 +-
.../services/AbstractCollectionService.java | 37 ++++++--
.../usergrid/services/ServiceInvocationIT.java | 28 +++++-
14 files changed, 280 insertions(+), 74 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/usergrid/blob/724968a2/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpEntityManager.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpEntityManager.java b/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpEntityManager.java
index ab62b36..3dc0d13 100644
--- a/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpEntityManager.java
+++ b/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpEntityManager.java
@@ -1545,6 +1545,12 @@ public class CpEntityManager implements EntityManager {
getRelationManager( entityRef ).removeFromCollection( collectionName, itemRef );
}
+ @Override
+ public void removeItemFromCollection( EntityRef entityRef, String collectionName, EntityRef itemRef ) throws Exception {
+
+ getRelationManager( entityRef ).removeItemFromCollection( collectionName, itemRef );
+ }
+
@Override
public Set<String> getCollectionIndexes( EntityRef entity, String collectionName ) throws Exception {
http://git-wip-us.apache.org/repos/asf/usergrid/blob/724968a2/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpRelationManager.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpRelationManager.java b/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpRelationManager.java
index 6e1bade..fbf0b14 100644
--- a/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpRelationManager.java
+++ b/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpRelationManager.java
@@ -579,6 +579,48 @@ public class CpRelationManager implements RelationManager {
}
}
+ @Override
+ public void removeItemFromCollection( String collectionName, EntityRef itemRef ) throws Exception {
+
+ Id entityId = new SimpleId( itemRef.getUuid(), itemRef.getType() );
+
+ // remove edge from collection to item
+ GraphManager gm = managerCache.getGraphManager( applicationScope );
+
+
+
+ // mark the edge versions and take the first for later delete edge queue event ( load is descending )
+ final Edge markedSourceEdge = gm.loadEdgeVersions(
+ CpNamingUtils.createEdgeFromCollectionName( cpHeadEntity.getId(), collectionName, entityId ) )
+ .flatMap(edge -> gm.markEdge(edge)).toBlocking().firstOrDefault(null);
+
+
+ Edge markedReversedEdge = null;
+ CollectionInfo collection = getDefaultSchema().getCollection( headEntity.getType(), collectionName );
+ if (collection != null && collection.getLinkedCollection() != null) {
+ // delete reverse edges
+ final String pluralType = InflectionUtils.pluralize( cpHeadEntity.getId().getType() );
+ markedReversedEdge = gm.loadEdgeVersions(
+ CpNamingUtils.createEdgeFromCollectionName( entityId, pluralType, cpHeadEntity.getId() ) )
+ .flatMap(reverseEdge -> gm.markEdge(reverseEdge)).toBlocking().firstOrDefault(null);
+ }
+
+
+ /**
+ * Remove from the index. This will call gm.deleteEdge which also deletes the reverse edge(s) and de-indexes
+ * older versions of the edge(s).
+ *
+ */
+ if( markedSourceEdge != null ) {
+ indexService.queueDeleteEdge(applicationScope, markedSourceEdge);
+ }
+ if( markedReversedEdge != null ){
+ indexService.queueDeleteEdge(applicationScope, markedReversedEdge);
+
+ }
+
+ }
+
@Override
public void copyRelationships( String srcRelationName, EntityRef dstEntityRef, String dstRelationName )
http://git-wip-us.apache.org/repos/asf/usergrid/blob/724968a2/stack/core/src/main/java/org/apache/usergrid/persistence/EntityManager.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/EntityManager.java b/stack/core/src/main/java/org/apache/usergrid/persistence/EntityManager.java
index 53a7a89..7e25a80 100644
--- a/stack/core/src/main/java/org/apache/usergrid/persistence/EntityManager.java
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/EntityManager.java
@@ -394,17 +394,29 @@ public interface EntityManager {
Map<String, Object> properties ) throws Exception;
/**
- * Removes an entity to the specified collection belonging to the specified entity.
+ * Deletes an entity from the specified collection.
*
* @param entityRef an entity reference
* @param collectionName the collection name.
- * @param itemRef a entity to be removed from the collection.
+ * @param itemRef a entity to be deleted and removed from the collection.
*
* @throws Exception the exception
*/
public void removeFromCollection( EntityRef entityRef, String collectionName, EntityRef itemRef)
throws Exception;
+ /**
+ * Removes only the edge from the specified collection, the entity is left in-tact
+ *
+ * @param entityRef an entity reference
+ * @param collectionName the collection name.
+ * @param itemRef a entity to be removed from the collection.
+ *
+ * @throws Exception the exception
+ */
+ public void removeItemFromCollection( EntityRef entityRef, String collectionName, EntityRef itemRef)
+ throws Exception;
+
public Results searchCollection( EntityRef entityRef, String collectionName, Query query )
throws Exception;
http://git-wip-us.apache.org/repos/asf/usergrid/blob/724968a2/stack/core/src/main/java/org/apache/usergrid/persistence/RelationManager.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/RelationManager.java b/stack/core/src/main/java/org/apache/usergrid/persistence/RelationManager.java
index 0011183..f0647ac 100644
--- a/stack/core/src/main/java/org/apache/usergrid/persistence/RelationManager.java
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/RelationManager.java
@@ -59,6 +59,8 @@ public interface RelationManager {
public void removeFromCollection( String collectionName, EntityRef itemRef ) throws Exception;
+ public void removeItemFromCollection( String collectionName, EntityRef itemRef ) throws Exception;
+
public void copyRelationships( String srcRelationName, EntityRef dstEntityRef, String dstRelationName )
throws Exception;
http://git-wip-us.apache.org/repos/asf/usergrid/blob/724968a2/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/impl/EntityCollectionManagerImpl.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/impl/EntityCollectionManagerImpl.java b/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/impl/EntityCollectionManagerImpl.java
index 1ccc18f..523b4df 100644
--- a/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/impl/EntityCollectionManagerImpl.java
+++ b/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/impl/EntityCollectionManagerImpl.java
@@ -385,10 +385,11 @@ public class EntityCollectionManagerImpl implements EntityCollectionManager {
if ( entity == null || !entity.getEntity().isPresent() ) {
if(logger.isTraceEnabled()) {
- logger.trace("Unique value [{}={}] does not have corresponding entity, executing " +
+ logger.trace("Unique value [{}={}] does not have corresponding entity [{}], executing " +
"read repair to remove stale unique value entry",
expectedUnique.getField().getName(),
- expectedUnique.getField().getValue().toString()
+ expectedUnique.getField().getValue().toString(),
+ expectedUnique.getEntityId()
);
}
http://git-wip-us.apache.org/repos/asf/usergrid/blob/724968a2/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/mvcc/stage/write/WriteUniqueVerify.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/mvcc/stage/write/WriteUniqueVerify.java b/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/mvcc/stage/write/WriteUniqueVerify.java
index 7b76dc8..d7c8ecd 100644
--- a/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/mvcc/stage/write/WriteUniqueVerify.java
+++ b/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/mvcc/stage/write/WriteUniqueVerify.java
@@ -122,7 +122,9 @@ public class WriteUniqueVerify implements Action1<CollectionIoEvent<MvccEntity>>
try {
// loading will retrieve the oldest unique value entry for the field
- UniqueValueSet set = uniqueValueStrat.load(scope, written.getEntityId().getType(), Collections.singletonList(written.getField()));
+ // purposely enable the read repair here to clean up before we write
+ UniqueValueSet set = uniqueValueStrat.load(scope, cassandraFig.getReadCL(),
+ written.getEntityId().getType(), Collections.singletonList(written.getField()), true);
set.forEach(uniqueValue -> {
@@ -149,6 +151,11 @@ public class WriteUniqueVerify implements Action1<CollectionIoEvent<MvccEntity>>
}
if(preWriteUniquenessViolations.size() > 0 ){
+ if(logger.isTraceEnabled()){
+ logger.trace("Pre-write unique violations found, raising exception before executing first write");
+ }
+ logger.error("Pre-write unique violations found, raising exception before executing first write");
+
throw new WriteUniqueVerifyException(mvccEntity, scope,
preWriteUniquenessViolations );
}
@@ -217,7 +224,9 @@ public class WriteUniqueVerify implements Action1<CollectionIoEvent<MvccEntity>>
final UniqueValueSet uniqueValues;
try {
// load ascending for verification to make sure we wrote is the last read back
- uniqueValues = uniqueValueSerializationStrategy.load( scope, consistencyLevel, type, uniqueFields );
+ // don't read repair on this read because our write-first strategy will introduce a duplicate
+ uniqueValues =
+ uniqueValueSerializationStrategy.load( scope, consistencyLevel, type, uniqueFields, false);
}
catch ( ConnectionException e ) {
throw new RuntimeException( "Unable to read from cassandra", e );
http://git-wip-us.apache.org/repos/asf/usergrid/blob/724968a2/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/UniqueValueSerializationStrategy.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/UniqueValueSerializationStrategy.java b/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/UniqueValueSerializationStrategy.java
index 95cfa68..35bb1b8 100644
--- a/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/UniqueValueSerializationStrategy.java
+++ b/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/UniqueValueSerializationStrategy.java
@@ -79,11 +79,12 @@ public interface UniqueValueSerializationStrategy extends Migration, VersionedDa
* @param consistencyLevel Consistency level of query
* @param type The type the unique value exists within
* @param fields Field name/value to search for
- * @return UniqueValueSet containing fields from the collection that exist in cassandra
+ * @param useReadRepair
+ * @return UniqueValueSet containing fields from the collection that exist in cassandra
* @throws ConnectionException on error connecting to Cassandra
*/
- UniqueValueSet load( ApplicationScope applicationScope, ConsistencyLevel consistencyLevel, String type,
- Collection<Field> fields ) throws ConnectionException;
+ UniqueValueSet load(ApplicationScope applicationScope, ConsistencyLevel consistencyLevel, String type,
+ Collection<Field> fields, boolean useReadRepair) throws ConnectionException;
/**
http://git-wip-us.apache.org/repos/asf/usergrid/blob/724968a2/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/UniqueValueSerializationStrategyImpl.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/UniqueValueSerializationStrategyImpl.java b/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/UniqueValueSerializationStrategyImpl.java
index aec2e58..db93272 100644
--- a/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/UniqueValueSerializationStrategyImpl.java
+++ b/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/UniqueValueSerializationStrategyImpl.java
@@ -237,13 +237,13 @@ public abstract class UniqueValueSerializationStrategyImpl<FieldKey, EntityKey>
@Override
public UniqueValueSet load( final ApplicationScope colScope, final String type, final Collection<Field> fields )
throws ConnectionException {
- return load( colScope, ConsistencyLevel.valueOf( cassandraFig.getReadCL() ), type, fields );
+ return load( colScope, ConsistencyLevel.valueOf( cassandraFig.getReadCL() ), type, fields, false);
}
@Override
- public UniqueValueSet load( final ApplicationScope appScope, final ConsistencyLevel consistencyLevel,
- final String type, final Collection<Field> fields ) throws ConnectionException {
+ public UniqueValueSet load(final ApplicationScope appScope, final ConsistencyLevel consistencyLevel,
+ final String type, final Collection<Field> fields, boolean useReadRepair) throws ConnectionException {
Preconditions.checkNotNull( fields, "fields are required" );
Preconditions.checkArgument( fields.size() > 0, "More than 1 field must be specified" );
@@ -307,71 +307,78 @@ public abstract class UniqueValueSerializationStrategyImpl<FieldKey, EntityKey>
final UniqueValue uniqueValue =
new UniqueValueImpl(field, entityVersion.getEntityId(), entityVersion.getEntityVersion());
-
// set the initial candidate and move on
- if(candidates.size() == 0){
+ if (candidates.size() == 0) {
candidates.add(uniqueValue);
continue;
}
- final int result = uniqueValueComparator.compare(uniqueValue, candidates.get(candidates.size() -1));
+ if(!useReadRepair){
- if(result == 0){
+ // take only the first
+ break;
- // do nothing, only versions can be newer and we're not worried about newer versions of same entity
- if(logger.isTraceEnabled()){
- logger.trace("Candidate unique value is equal to the current unique value");
- }
+ } else {
- // update candidate w/ latest version
- candidates.add(uniqueValue);
- }else if(result < 0){
+ final int result = uniqueValueComparator.compare(uniqueValue, candidates.get(candidates.size() - 1));
- // delete the duplicate from the unique value index
- candidates.forEach(candidate -> {
+ if (result == 0) {
- try {
+ // do nothing, only versions can be newer and we're not worried about newer versions of same entity
+ if (logger.isTraceEnabled()) {
+ logger.trace("Candidate unique value is equal to the current unique value");
+ }
- logger.warn("Duplicate unique value [{}={}] found for application [{}], removing newer " +
- "entry with entity id [{}] and entity version [{}]", field.getName(),
- field.getValue().toString(), applicationId.getUuid(),
- candidate.getEntityId().getUuid(), candidate.getEntityVersion() );
+ // update candidate w/ latest version
+ candidates.add(uniqueValue);
- delete(appScope, candidate ).execute();
+ } else if (result < 0) {
- } catch (ConnectionException e) {
- // do nothing for now
- }
+ // delete the duplicate from the unique value index
+ candidates.forEach(candidate -> {
- });
+ try {
- // clear the transient candidates list
- candidates.clear();
+ logger.warn("Duplicate unique value [{}={}] found for application [{}], removing newer " +
+ "entry with entity id [{}] and entity version [{}]", field.getName(),
+ field.getValue().toString(), applicationId.getUuid(),
+ candidate.getEntityId().getUuid(), candidate.getEntityVersion());
- if(logger.isTraceEnabled()) {
- logger.trace("Updating candidate to entity id [{}] and entity version [{}]",
- uniqueValue.getEntityId().getUuid(), uniqueValue.getEntityVersion());
+ delete(appScope, candidate).execute();
- }
+ } catch (ConnectionException e) {
+ // do nothing for now
+ }
- // add our new candidate to the list
- candidates.add(uniqueValue);
+ });
+
+ // clear the transient candidates list
+ candidates.clear();
+ if (logger.isTraceEnabled()) {
+ logger.trace("Updating candidate to entity id [{}] and entity version [{}]",
+ uniqueValue.getEntityId().getUuid(), uniqueValue.getEntityVersion());
- }else{
+ }
- logger.warn("Duplicate unique value [{}={}] found for application [{}], removing newer entry " +
- "with entity id [{}] and entity version [{}].", field.getName(), field.getValue().toString(),
- applicationId.getUuid(), uniqueValue.getEntityId().getUuid(), uniqueValue.getEntityVersion() );
+ // add our new candidate to the list
+ candidates.add(uniqueValue);
- // delete the duplicate from the unique value index
- delete(appScope, uniqueValue ).execute();
+ } else {
- }
+ logger.warn("Duplicate unique value [{}={}] found for application [{}], removing newer entry " +
+ "with entity id [{}] and entity version [{}].", field.getName(), field.getValue().toString(),
+ applicationId.getUuid(), uniqueValue.getEntityId().getUuid(), uniqueValue.getEntityVersion());
+ // delete the duplicate from the unique value index
+ delete(appScope, uniqueValue).execute();
+
+ }
+
+ }
}
// take the last candidate ( should be the latest version) and add to the result set
http://git-wip-us.apache.org/repos/asf/usergrid/blob/724968a2/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/UniqueValueSerializationStrategyProxyImpl.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/UniqueValueSerializationStrategyProxyImpl.java b/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/UniqueValueSerializationStrategyProxyImpl.java
index 1de4052..b9c9999 100644
--- a/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/UniqueValueSerializationStrategyProxyImpl.java
+++ b/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/UniqueValueSerializationStrategyProxyImpl.java
@@ -115,16 +115,16 @@ public class UniqueValueSerializationStrategyProxyImpl implements UniqueValueSer
@Override
- public UniqueValueSet load( final ApplicationScope applicationScope, final ConsistencyLevel consistencyLevel,
- final String type, final Collection<Field> fields ) throws ConnectionException {
+ public UniqueValueSet load(final ApplicationScope applicationScope, final ConsistencyLevel consistencyLevel,
+ final String type, final Collection<Field> fields, boolean useReadRepair) throws ConnectionException {
final MigrationRelationship<UniqueValueSerializationStrategy> migration = getMigrationRelationShip();
if ( migration.needsMigration() ) {
- return migration.from.load( applicationScope, type, fields );
+ return migration.from.load( applicationScope, consistencyLevel, type, fields, useReadRepair );
}
- return migration.to.load( applicationScope, type, fields );
+ return migration.to.load( applicationScope, consistencyLevel, type, fields, useReadRepair );
}
http://git-wip-us.apache.org/repos/asf/usergrid/blob/724968a2/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/mvcc/stage/write/WriteUniqueVerifyIT.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/mvcc/stage/write/WriteUniqueVerifyIT.java b/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/mvcc/stage/write/WriteUniqueVerifyIT.java
index 9d0cd20..3d411a4 100644
--- a/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/mvcc/stage/write/WriteUniqueVerifyIT.java
+++ b/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/mvcc/stage/write/WriteUniqueVerifyIT.java
@@ -18,6 +18,12 @@
package org.apache.usergrid.persistence.collection.mvcc.stage.write;
+import org.apache.usergrid.persistence.collection.FieldSet;
+import org.apache.usergrid.persistence.collection.MvccEntity;
+import org.apache.usergrid.persistence.collection.serialization.UniqueValue;
+import org.apache.usergrid.persistence.collection.serialization.UniqueValueSerializationStrategy;
+import org.apache.usergrid.persistence.collection.serialization.impl.UniqueValueImpl;
+import org.apache.usergrid.persistence.model.util.UUIDGenerator;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -41,6 +47,8 @@ import org.apache.usergrid.persistence.model.field.StringField;
import com.google.inject.Inject;
+import java.util.Collections;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
@@ -60,6 +68,9 @@ public class WriteUniqueVerifyIT {
public MigrationManagerRule migrationManagerRule;
@Inject
+ public UniqueValueSerializationStrategy uniqueValueSerializationStrategy;
+
+ @Inject
public EntityCollectionManagerFactory cmf;
@Test
@@ -142,4 +153,64 @@ public class WriteUniqueVerifyIT {
entity.setField( new StringField("foo", "bar"));
entityManager.write( entity ).toBlocking().last();
}
+
+ @Test
+ public void testConflictReadRepair() throws Exception {
+
+ final Id appId = new SimpleId("testNoConflict");
+
+
+
+ final ApplicationScope scope = new ApplicationScopeImpl( appId);
+
+ final EntityCollectionManager entityManager = cmf.createCollectionManager( scope );
+
+ final Entity entity = TestEntityGenerator.generateEntity();
+ entity.setField(new StringField("name", "Porsche 911 GT3", true));
+ entity.setField(new StringField("identifier", "911gt3", true));
+ entity.setField(new IntegerField("top_speed_mph", 194));
+ entityManager.write( entity ).toBlocking().last();
+
+
+ FieldSet fieldSet =
+ entityManager.getEntitiesFromFields("test", Collections.singletonList(entity.getField("name")), true)
+ .toBlocking().last();
+
+ MvccEntity entityFetched = fieldSet.getEntity( entity.getField("name") );
+
+
+ final Entity entityDuplicate = TestEntityGenerator.generateEntity();
+ UniqueValue uniqueValue = new UniqueValueImpl(new StringField("name", "Porsche 911 GT3", true),
+ entityDuplicate.getId(), UUIDGenerator.newTimeUUID());
+
+ // manually insert a record to simulate a 'duplicate' trying to be inserted
+ uniqueValueSerializationStrategy.
+ write(scope, uniqueValue).execute();
+
+
+
+ FieldSet fieldSetAgain =
+ entityManager.getEntitiesFromFields("test", Collections.singletonList(entity.getField("name")), true)
+ .toBlocking().last();
+
+ MvccEntity entityFetchedAgain = fieldSetAgain.getEntity( entity.getField("name") );
+
+ assertEquals(entityFetched, entityFetchedAgain);
+
+
+ // now test writing the original entity again ( simulates a PUT )
+ // this should read repair and work
+ entityManager.write( entity ).toBlocking().last();
+
+ FieldSet fieldSetAgainAgain =
+ entityManager.getEntitiesFromFields("test", Collections.singletonList(entity.getField("name")), true)
+ .toBlocking().last();
+
+ MvccEntity entityFetchedAgainAgain = fieldSetAgainAgain.getEntity( entity.getField("name") );
+
+ assertEquals(entityFetched, entityFetchedAgainAgain);
+
+
+
+ }
}
http://git-wip-us.apache.org/repos/asf/usergrid/blob/724968a2/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/serialization/impl/UniqueValueSerializationStrategyImplTest.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/serialization/impl/UniqueValueSerializationStrategyImplTest.java b/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/serialization/impl/UniqueValueSerializationStrategyImplTest.java
index ed3e42b..3dbf1ec 100644
--- a/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/serialization/impl/UniqueValueSerializationStrategyImplTest.java
+++ b/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/serialization/impl/UniqueValueSerializationStrategyImplTest.java
@@ -23,6 +23,7 @@ import java.util.Collections;
import java.util.Iterator;
import java.util.UUID;
+import com.netflix.astyanax.model.ConsistencyLevel;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
@@ -369,7 +370,8 @@ public abstract class UniqueValueSerializationStrategyImplTest {
strategy.write( scope, stored2 ).execute();
// load descending to get the older version of entity for this unique value
- UniqueValueSet fields = strategy.load( scope, entityId1.getType(), Collections.<Field>singleton( field ));
+ UniqueValueSet fields = strategy.load( scope, ConsistencyLevel.CL_LOCAL_QUORUM,
+ entityId1.getType(), Collections.<Field>singleton( field ), true);
UniqueValue retrieved = fields.getValue( field.getName() );
@@ -383,7 +385,8 @@ public abstract class UniqueValueSerializationStrategyImplTest {
strategy.write( scope, stored3 ).execute();
// load the values again, we should still only get back the original unique value
- fields = strategy.load( scope, entityId1.getType(), Collections.<Field>singleton( field ));
+ fields = strategy.load( scope, ConsistencyLevel.CL_LOCAL_QUORUM,
+ entityId1.getType(), Collections.<Field>singleton( field ), true);
retrieved = fields.getValue( field.getName() );
@@ -396,7 +399,8 @@ public abstract class UniqueValueSerializationStrategyImplTest {
strategy.write( scope, stored4 ).execute();
// load the values again, now we should get the latest version of the original UUID written
- fields = strategy.load( scope, entityId1.getType(), Collections.<Field>singleton( field ));
+ fields = strategy.load( scope, ConsistencyLevel.CL_LOCAL_QUORUM,
+ entityId1.getType(), Collections.<Field>singleton( field ), true);
retrieved = fields.getValue( field.getName() );
@@ -433,7 +437,8 @@ public abstract class UniqueValueSerializationStrategyImplTest {
strategy.write( scope, stored2 ).execute();
// load descending to get the older version of entity for this unique value
- UniqueValueSet fields = strategy.load( scope, entityId1.getType(), Collections.<Field>singleton( field ));
+ UniqueValueSet fields = strategy.load( scope, ConsistencyLevel.CL_LOCAL_QUORUM,
+ entityId1.getType(), Collections.<Field>singleton( field ), true);
UniqueValue retrieved = fields.getValue( field.getName() );
Assert.assertNotNull( retrieved );
@@ -470,7 +475,12 @@ public abstract class UniqueValueSerializationStrategyImplTest {
// load descending to get the older version of entity for this unique value
- UniqueValueSet fields = strategy.load( scope, entityId1.getType(), Collections.<Field>singleton( field ));
+ UniqueValueSet fields = strategy.load( scope, ConsistencyLevel.CL_LOCAL_QUORUM,
+ entityId1.getType(), Collections.<Field>singleton( field ), true);
+
+
+ fields = strategy.load( scope, ConsistencyLevel.CL_LOCAL_QUORUM,
+ entityId1.getType(), Collections.<Field>singleton( field ), false);
UniqueValue retrieved = fields.getValue( field.getName() );
assertEquals( stored3, retrieved );
@@ -506,7 +516,8 @@ public abstract class UniqueValueSerializationStrategyImplTest {
// load descending to get the older version of entity for this unique value
- UniqueValueSet fields = strategy.load( scope, entityId1.getType(), Collections.<Field>singleton( field ));
+ UniqueValueSet fields = strategy.load( scope,
+ ConsistencyLevel.CL_LOCAL_QUORUM, entityId1.getType(), Collections.<Field>singleton( field ), true);
UniqueValue retrieved = fields.getValue( field.getName() );
assertEquals( stored1, retrieved );
@@ -549,7 +560,8 @@ public abstract class UniqueValueSerializationStrategyImplTest {
// load descending to get the older version of entity for this unique value
- UniqueValueSet fields = strategy.load( scope, entityId1.getType(), Collections.<Field>singleton( field ));
+ UniqueValueSet fields = strategy.load( scope, ConsistencyLevel.CL_LOCAL_QUORUM,
+ entityId1.getType(), Collections.<Field>singleton( field ), true);
UniqueValue retrieved = fields.getValue( field.getName() );
assertEquals( stored1, retrieved );
http://git-wip-us.apache.org/repos/asf/usergrid/blob/724968a2/stack/rest/src/test/java/org/apache/usergrid/rest/applications/collection/users/PermissionsResourceIT.java
----------------------------------------------------------------------
diff --git a/stack/rest/src/test/java/org/apache/usergrid/rest/applications/collection/users/PermissionsResourceIT.java b/stack/rest/src/test/java/org/apache/usergrid/rest/applications/collection/users/PermissionsResourceIT.java
index b0b3791..5380e00 100644
--- a/stack/rest/src/test/java/org/apache/usergrid/rest/applications/collection/users/PermissionsResourceIT.java
+++ b/stack/rest/src/test/java/org/apache/usergrid/rest/applications/collection/users/PermissionsResourceIT.java
@@ -116,7 +116,7 @@ public class PermissionsResourceIT extends AbstractRestIT {
}
// check if the role was assigned
- assertEquals(status, 404);
+ assertEquals(404, status);
}
@@ -167,7 +167,7 @@ public class PermissionsResourceIT extends AbstractRestIT {
fail("Should not have been able to retrieve the user as it was deleted");
}catch (ClientErrorException e){
status=e.getResponse().getStatus();
- assertEquals( 404,status );
+ assertEquals( 404, status );
}
}
http://git-wip-us.apache.org/repos/asf/usergrid/blob/724968a2/stack/services/src/main/java/org/apache/usergrid/services/AbstractCollectionService.java
----------------------------------------------------------------------
diff --git a/stack/services/src/main/java/org/apache/usergrid/services/AbstractCollectionService.java b/stack/services/src/main/java/org/apache/usergrid/services/AbstractCollectionService.java
index 7539e0c..14b1df1 100644
--- a/stack/services/src/main/java/org/apache/usergrid/services/AbstractCollectionService.java
+++ b/stack/services/src/main/java/org/apache/usergrid/services/AbstractCollectionService.java
@@ -41,6 +41,7 @@ import org.apache.usergrid.services.ServiceResults.Type;
import org.apache.usergrid.services.exceptions.ForbiddenServiceOperationException;
import org.apache.usergrid.services.exceptions.ServiceResourceNotFoundException;
+import static org.apache.usergrid.persistence.Schema.TYPE_APPLICATION;
import static org.apache.usergrid.utils.ClassUtils.cast;
@@ -125,16 +126,34 @@ public class AbstractCollectionService extends AbstractService {
checkPermissionsForEntity( context, entity );
}
- // the context of the entity they're trying to load isn't owned by the owner
- // in the path, don't return it
+ // check ownership based on graph
if ( !em.isCollectionMember( context.getOwner(), context.getCollectionName(), entity ) ) {
- logger.info( "Someone tried to GET entity {} they don't own. Entity id {} with owner {}",
- getEntityType(), id, context.getOwner()
- );
- throw new ServiceResourceNotFoundException( context );
- }
- // TODO check that entity is in fact in the collection
+ // the entity is already loaded in the scope of the owner and type ( collection ) so it must exist at this point
+ // if for some reason it's not a member of the collection, it should be and read repair it
+ if( context.getOwner().getType().equals(TYPE_APPLICATION) ){
+ logger.warn( "Edge missing for entity id {} with owner {}. Executing edge read repair to create new edge in " +
+ "collection {}", id, context.getOwner(), context.getCollectionName());
+
+ em.addToCollection( context.getOwner(), context.getCollectionName(), entity);
+
+ // do a final check to be absolutely sure we're good now before returning back to the client
+ // TODO : Keep thinking if the double-check read after repair is necessary. Favoring stability here
+ if ( !em.isCollectionMember( context.getOwner(), context.getCollectionName(), entity ) ) {
+ logger.error( "Edge read repair failed for entity id {} with owner {} in collection {}",
+ id, context.getOwner(), context.getCollectionName());
+
+ throw new ServiceResourceNotFoundException( context );
+ }
+
+ }
+ // if not head application, then we can't assume the ownership is meant to be there
+ else{
+ throw new ServiceResourceNotFoundException( context );
+ }
+
+
+ }
List<ServiceRequest> nextRequests = context.getNextServiceRequests( entity );
@@ -158,7 +177,7 @@ public class AbstractCollectionService extends AbstractService {
if ( entityId == null ) {
if (logger.isTraceEnabled()) {
- logger.trace("miss on entityType: {} with name: {}", getEntityType(), name);
+ logger.trace("Miss on entityType: {} with name: {}", getEntityType(), name);
}
String msg = "Cannot find entity with name: "+name;
http://git-wip-us.apache.org/repos/asf/usergrid/blob/724968a2/stack/services/src/test/java/org/apache/usergrid/services/ServiceInvocationIT.java
----------------------------------------------------------------------
diff --git a/stack/services/src/test/java/org/apache/usergrid/services/ServiceInvocationIT.java b/stack/services/src/test/java/org/apache/usergrid/services/ServiceInvocationIT.java
index 57f0bb2..8c2be2c 100644
--- a/stack/services/src/test/java/org/apache/usergrid/services/ServiceInvocationIT.java
+++ b/stack/services/src/test/java/org/apache/usergrid/services/ServiceInvocationIT.java
@@ -24,11 +24,14 @@ import java.util.Map;
import java.util.UUID;
import org.apache.usergrid.cassandra.ClearShiroSubject;
-import org.apache.usergrid.persistence.Entity;
-import org.apache.usergrid.persistence.Query;
+import org.apache.usergrid.persistence.*;
import org.apache.usergrid.persistence.model.util.UUIDGenerator;
+
+import static junit.framework.TestCase.assertTrue;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
+import org.apache.usergrid.utils.InflectionUtils;
import org.junit.Rule;
import org.junit.Test;
import org.slf4j.Logger;
@@ -221,4 +224,25 @@ public class ServiceInvocationIT extends AbstractServiceIT {
app.testRequest( ServiceAction.GET, 1,
"projects", project.getName(), "contains", "contributors", contributor.getName());
}
+
+ @Test
+ public void testGetByIdAndNameEdgeReadRepair() throws Exception {
+
+ EntityManager em = setup.getEmf().getEntityManager( app.getId() );
+
+ Entity contributor = app.doCreate( "contributor", "Malaka" );
+
+ EntityRef appRef = new SimpleEntityRef("application", app.getId());
+
+
+ em.removeItemFromCollection(appRef, InflectionUtils.pluralize(contributor.getType()), contributor);
+
+ assertFalse("Entity should not have an edge from app to entity",
+ em.isCollectionMember(appRef, InflectionUtils.pluralize(contributor.getType()), contributor));
+
+ app.testRequest( ServiceAction.GET, 1, "contributor", contributor.getName());
+
+ assertTrue("Entity should now be member of the collection",
+ em.isCollectionMember(appRef, InflectionUtils.pluralize(contributor.getType()), contributor));
+ }
}
[3/4] usergrid git commit: Merge branch 'release-2.1.1' of
https://git-wip-us.apache.org/repos/asf/usergrid into release-2.1.1
Posted by mr...@apache.org.
Merge branch 'release-2.1.1' of https://git-wip-us.apache.org/repos/asf/usergrid into release-2.1.1
Project: http://git-wip-us.apache.org/repos/asf/usergrid/repo
Commit: http://git-wip-us.apache.org/repos/asf/usergrid/commit/426449e3
Tree: http://git-wip-us.apache.org/repos/asf/usergrid/tree/426449e3
Diff: http://git-wip-us.apache.org/repos/asf/usergrid/diff/426449e3
Branch: refs/heads/release-2.1.1
Commit: 426449e3a2ce2365d4ebf1e0ed498b75cf16d2f6
Parents: 5803916 37c482c
Author: Michael Russo <mr...@apigee.com>
Authored: Wed Jun 29 10:53:49 2016 -0700
Committer: Michael Russo <mr...@apigee.com>
Committed: Wed Jun 29 10:53:49 2016 -0700
----------------------------------------------------------------------
docs/orgs-and-apps/application.md | 104 +++++++++++++++++++++++++++++++++
1 file changed, 104 insertions(+)
----------------------------------------------------------------------
[4/4] usergrid git commit: Clean up em.removeFromCollection and fix
UniqueValueScanner to just log duplicates if scanning all of unique values.
Posted by mr...@apache.org.
Clean up em.removeFromCollection and fix UniqueValueScanner to just log duplicates if scanning all of unique values.
Project: http://git-wip-us.apache.org/repos/asf/usergrid/repo
Commit: http://git-wip-us.apache.org/repos/asf/usergrid/commit/f4ae0cb8
Tree: http://git-wip-us.apache.org/repos/asf/usergrid/tree/f4ae0cb8
Diff: http://git-wip-us.apache.org/repos/asf/usergrid/diff/f4ae0cb8
Branch: refs/heads/release-2.1.1
Commit: f4ae0cb85b09547a2bb808a8a80fa8a36c485551
Parents: 426449e
Author: Michael Russo <mr...@apigee.com>
Authored: Wed Jun 29 10:55:14 2016 -0700
Committer: Michael Russo <mr...@apigee.com>
Committed: Wed Jun 29 10:55:14 2016 -0700
----------------------------------------------------------------------
.../corepersistence/CpRelationManager.java | 36 ++------------------
.../mvcc/stage/write/WriteUniqueVerify.java | 1 -
2 files changed, 2 insertions(+), 35 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/usergrid/blob/f4ae0cb8/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpRelationManager.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpRelationManager.java b/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpRelationManager.java
index fbf0b14..d2ab702 100644
--- a/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpRelationManager.java
+++ b/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpRelationManager.java
@@ -525,41 +525,9 @@ public class CpRelationManager implements RelationManager {
Id entityId = new SimpleId( itemRef.getUuid(), itemRef.getType() );
- // remove edge from collection to item
- GraphManager gm = managerCache.getGraphManager( applicationScope );
-
-
-
- // mark the edge versions and take the first for later delete edge queue event ( load is descending )
- final Edge markedSourceEdge = gm.loadEdgeVersions(
- CpNamingUtils.createEdgeFromCollectionName( cpHeadEntity.getId(), collectionName, entityId ) )
- .flatMap(edge -> gm.markEdge(edge)).toBlocking().firstOrDefault(null);
-
-
- Edge markedReversedEdge = null;
- CollectionInfo collection = getDefaultSchema().getCollection( headEntity.getType(), collectionName );
- if (collection != null && collection.getLinkedCollection() != null) {
- // delete reverse edges
- final String pluralType = InflectionUtils.pluralize( cpHeadEntity.getId().getType() );
- markedReversedEdge = gm.loadEdgeVersions(
- CpNamingUtils.createEdgeFromCollectionName( entityId, pluralType, cpHeadEntity.getId() ) )
- .flatMap(reverseEdge -> gm.markEdge(reverseEdge)).toBlocking().firstOrDefault(null);
- }
-
-
- /**
- * Remove from the index. This will call gm.deleteEdge which also deletes the reverse edge(s) and de-indexes
- * older versions of the edge(s).
- *
- */
- if( markedSourceEdge != null ) {
- indexService.queueDeleteEdge(applicationScope, markedSourceEdge);
- }
- if( markedReversedEdge != null ){
- indexService.queueDeleteEdge(applicationScope, markedReversedEdge);
-
- }
+ // this will remove the edges from app->entity(collection)
+ removeItemFromCollection(collectionName, itemRef);
// special handling for roles collection of a group
if ( headEntity.getType().equals( Group.ENTITY_TYPE ) ) {
http://git-wip-us.apache.org/repos/asf/usergrid/blob/f4ae0cb8/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/mvcc/stage/write/WriteUniqueVerify.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/mvcc/stage/write/WriteUniqueVerify.java b/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/mvcc/stage/write/WriteUniqueVerify.java
index d7c8ecd..adbe03d 100644
--- a/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/mvcc/stage/write/WriteUniqueVerify.java
+++ b/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/mvcc/stage/write/WriteUniqueVerify.java
@@ -154,7 +154,6 @@ public class WriteUniqueVerify implements Action1<CollectionIoEvent<MvccEntity>>
if(logger.isTraceEnabled()){
logger.trace("Pre-write unique violations found, raising exception before executing first write");
}
- logger.error("Pre-write unique violations found, raising exception before executing first write");
throw new WriteUniqueVerifyException(mvccEntity, scope,
preWriteUniquenessViolations );
[2/4] usergrid git commit: Clean up em.removeFromCollection and fix
UniqueValueScanner to just log duplicates if scanning all of unique values.
Posted by mr...@apache.org.
Clean up em.removeFromCollection and fix UniqueValueScanner to just log duplicates if scanning all of unique values.
Project: http://git-wip-us.apache.org/repos/asf/usergrid/repo
Commit: http://git-wip-us.apache.org/repos/asf/usergrid/commit/58039166
Tree: http://git-wip-us.apache.org/repos/asf/usergrid/tree/58039166
Diff: http://git-wip-us.apache.org/repos/asf/usergrid/diff/58039166
Branch: refs/heads/release-2.1.1
Commit: 58039166b9b119eb0766b473e43a8a732f3cbd00
Parents: 724968a
Author: Michael Russo <mr...@apigee.com>
Authored: Wed Jun 29 10:39:04 2016 -0700
Committer: Michael Russo <mr...@apigee.com>
Committed: Wed Jun 29 10:39:04 2016 -0700
----------------------------------------------------------------------
.../usergrid/tools/UniqueValueScanner.java | 69 +++++++++++---------
1 file changed, 38 insertions(+), 31 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/usergrid/blob/58039166/stack/tools/src/main/java/org/apache/usergrid/tools/UniqueValueScanner.java
----------------------------------------------------------------------
diff --git a/stack/tools/src/main/java/org/apache/usergrid/tools/UniqueValueScanner.java b/stack/tools/src/main/java/org/apache/usergrid/tools/UniqueValueScanner.java
index bdebd01..182e692 100644
--- a/stack/tools/src/main/java/org/apache/usergrid/tools/UniqueValueScanner.java
+++ b/stack/tools/src/main/java/org/apache/usergrid/tools/UniqueValueScanner.java
@@ -17,9 +17,7 @@
package org.apache.usergrid.tools;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.UUID;
+import java.util.*;
import com.netflix.astyanax.connectionpool.exceptions.ConnectionException;
import com.netflix.astyanax.model.Column;
@@ -208,9 +206,11 @@ public class UniqueValueScanner extends ToolBase {
UUID finalAppToFilter = appToFilter;
rows.forEachRemaining(row -> {
- String fieldName = row.getKey().getKey().getField().getName();
- String scopeType = row.getKey().getScope().getType();
- UUID scopeUUID = row.getKey().getScope().getUuid();
+ final String fieldName = row.getKey().getKey().getField().getName();
+ final String fieldValue = row.getKey().getKey().getField().getValue().toString();
+ final String scopeType = row.getKey().getScope().getType();
+ final UUID scopeUUID = row.getKey().getScope().getUuid();
+
if (!fieldName.equalsIgnoreCase(fieldType) ||
(finalAppToFilter != null && !finalAppToFilter.equals(scopeUUID))
@@ -223,16 +223,19 @@ public class UniqueValueScanner extends ToolBase {
em = emf.getEntityManager(scopeUUID);
}
- Iterator<Column<EntityVersion>> columns = row.getColumns().iterator();
- columns.forEachRemaining(column -> {
+ // if we have more than 1 column, let's check for a duplicate
+ if(row.getColumns().size() > 1) {
+
+ final List<EntityVersion> values = new ArrayList<>(row.getColumns().size());
+
+ Iterator<Column<EntityVersion>> columns = row.getColumns().iterator();
+ columns.forEachRemaining(column -> {
+
- EntityVersion entityVersion = column.getName();
- if (entityType != null &&
- entityVersion.getEntityId().getType().equalsIgnoreCase(entityType)
- ) {
+ final EntityVersion entityVersion = column.getName();
+
- String fieldValue = row.getKey().getKey().getField().getValue().toString();
logger.trace(
scopeType + ": " + scopeUUID + ", " +
@@ -242,30 +245,34 @@ public class UniqueValueScanner extends ToolBase {
);
- Entity entity = em.getUniqueEntityFromAlias(entityType, fieldValue, false);
+ if (entityType != null &&
+ entityVersion.getEntityId().getType().equalsIgnoreCase(entityType)
+ ) {
-// Optional<MvccEntity> entity = mvccEntitySerializationStrategy.
-// load(new ApplicationScopeImpl(new SimpleId(scopeUUID, scopeType)), entityVersion.getEntityId());
-//
-// if(!entity.isPresent()){
+ // add the first value into the list
+ if(values.size() == 0 ) {
- if (entity == null) {
+ values.add(entityVersion);
- logger.error("{}: {}. Entity with type=[{}], name=[{}], and uuid=[{}] has a unique value entry " +
- "but cannot be loaded from Mvcc entity serialization",
- scopeType,
- scopeUUID,
- entityVersion.getEntityId().getType(),
- fieldValue,
- entityVersion.getEntityId().getUuid());
- }
- } else {
- // do nothing
- }
+ }else{
+
+ if( !values.get(0).getEntityId().getUuid().equals(entityVersion.getEntityId().getUuid())){
+ values.add(entityVersion);
- });
+ logger.error("Duplicate found for field [{}={}]. Entry 1: [{}], Entry 2: [{}]",
+ fieldName, fieldValue, values.get(0).getEntityId(), entityVersion.getEntityId());
+
+ }
+
+ }
+
+
+ }
+
+ });
+ }
}