Cherry picking Akka/UV changes 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/45bb03ef Tree: http://git-wip-us.apache.org/repos/asf/usergrid/tree/45bb03ef Diff: http://git-wip-us.apache.org/repos/asf/usergrid/diff/45bb03ef Branch: refs/heads/usergrid-1268-akka-211 Commit: 45bb03ef1a70e8207ee463d80956db5b3eca3624 Parents: 5352494 Author: Dave Johnson <[email protected]> Authored: Thu Apr 14 09:49:26 2016 -0400 Committer: Dave Johnson <[email protected]> Committed: Mon Apr 25 14:38:36 2016 -0400 ---------------------------------------------------------------------- .../uniquevalues/UniqueValuesService.java | 5 + .../collection/uniquevalues/AkkaFigTest.java | 41 ----- .../uniquevalues/LocalPreventDupsTest.java | 137 ---------------- .../uniquevalues/UniqueValuesServiceTest.java | 155 +++++++++++++++++++ 4 files changed, 160 insertions(+), 178 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/usergrid/blob/45bb03ef/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/uniquevalues/UniqueValuesService.java ---------------------------------------------------------------------- diff --git a/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/uniquevalues/UniqueValuesService.java b/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/uniquevalues/UniqueValuesService.java index 7ebab15..06aea4b 100644 --- a/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/uniquevalues/UniqueValuesService.java +++ b/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/uniquevalues/UniqueValuesService.java @@ -41,6 +41,11 @@ public interface UniqueValuesService { void confirmUniqueValues( ApplicationScope scope, Entity entity, UUID version ) throws UniqueValueException; /** + * Initialize and wait for Akka actors to start. + */ + void start(); + + /** * For test purposes only. */ void start( String hostname, Integer port, String region ); http://git-wip-us.apache.org/repos/asf/usergrid/blob/45bb03ef/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/uniquevalues/AkkaFigTest.java ---------------------------------------------------------------------- diff --git a/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/uniquevalues/AkkaFigTest.java b/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/uniquevalues/AkkaFigTest.java deleted file mode 100644 index 59f76de..0000000 --- a/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/uniquevalues/AkkaFigTest.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.usergrid.persistence.collection.uniquevalues; - -import com.google.inject.Inject; -import org.apache.usergrid.persistence.collection.guice.TestCollectionModule; -import org.apache.usergrid.persistence.core.test.ITRunner; -import org.apache.usergrid.persistence.core.test.UseModules; -import org.junit.Assert; -import org.junit.Test; -import org.junit.runner.RunWith; - - -@RunWith( ITRunner.class ) -@UseModules( TestCollectionModule.class ) -public class AkkaFigTest { - - @Inject - AkkaFig akkaFig; - - @Test - public void testBasicOperation() { - Assert.assertNotNull( akkaFig ); - } -} http://git-wip-us.apache.org/repos/asf/usergrid/blob/45bb03ef/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/uniquevalues/LocalPreventDupsTest.java ---------------------------------------------------------------------- diff --git a/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/uniquevalues/LocalPreventDupsTest.java b/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/uniquevalues/LocalPreventDupsTest.java deleted file mode 100644 index ef5c16f..0000000 --- a/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/uniquevalues/LocalPreventDupsTest.java +++ /dev/null @@ -1,137 +0,0 @@ -package org.apache.usergrid.persistence.collection.uniquevalues; - -import com.google.common.collect.ArrayListMultimap; -import com.google.common.collect.Multimap; -import com.google.common.collect.Multimaps; -import com.google.inject.Inject; -import org.apache.usergrid.persistence.collection.EntityCollectionManager; -import org.apache.usergrid.persistence.collection.EntityCollectionManagerFactory; -import org.apache.usergrid.persistence.collection.exception.WriteUniqueVerifyException; -import org.apache.usergrid.persistence.collection.guice.TestCollectionModule; -import org.apache.usergrid.persistence.core.guice.MigrationManagerRule; -import org.apache.usergrid.persistence.core.scope.ApplicationScope; -import org.apache.usergrid.persistence.core.scope.ApplicationScopeImpl; -import org.apache.usergrid.persistence.core.test.ITRunner; -import org.apache.usergrid.persistence.core.test.UseModules; -import org.apache.usergrid.persistence.model.entity.Entity; -import org.apache.usergrid.persistence.model.entity.SimpleId; -import org.apache.usergrid.persistence.model.field.StringField; -import org.junit.Assert; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import rx.Observable; - -import java.util.Collection; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; - -/** - * Prevent dups test that uses UserManager and not REST. - */ -@RunWith( ITRunner.class ) -@UseModules( TestCollectionModule.class ) -public class LocalPreventDupsTest { - private static final Logger logger = LoggerFactory.getLogger( LocalPreventDupsTest.class ); - - @Inject - private EntityCollectionManagerFactory factory; - - @Inject - @Rule - public MigrationManagerRule migrationManagerRule; - - @Inject - UniqueValuesService uniqueValuesService; - - - private static final AtomicInteger successCounter = new AtomicInteger( 0 ); - private static final AtomicInteger errorCounter = new AtomicInteger( 0 ); - - @Test - public void testBasicOperation() throws Exception { - - uniqueValuesService.start("127.0.0.1", 2551, "us-east"); - uniqueValuesService.waitForRequestActors(); - - int numUsers = 100; - Multimap<String, Entity> usersCreated = generateDuplicateUsers( numUsers ); - - int userCount = 0; - int usernamesWithDuplicates = 0; - for ( String username : usersCreated.keySet() ) { - Collection<Entity> users = usersCreated.get( username ); - if ( users.size() > 1 ) { - usernamesWithDuplicates++; - } - userCount++; - } - - Assert.assertEquals( 0, usernamesWithDuplicates ); - Assert.assertEquals( numUsers, successCounter.get() ); - Assert.assertEquals( 0, errorCounter.get() ); - Assert.assertEquals( numUsers, usersCreated.size() ); - Assert.assertEquals( numUsers, userCount ); - } - - private Multimap<String, Entity> generateDuplicateUsers(int numUsers ) { - - ApplicationScope context = new ApplicationScopeImpl( new SimpleId( "organization" ) ); - - EntityCollectionManager manager = factory.createCollectionManager( context ); - - Multimap<String, Entity> usersCreated = - Multimaps.synchronizedListMultimap( ArrayListMultimap.create() ); - - ExecutorService execService = Executors.newFixedThreadPool( 10 ); - - for (int i = 0; i < numUsers; i++) { - - // multiple threads simultaneously trying to create a user with the same propertyName - for (int j = 0; j < 5; j++) { - String username = "user_" + i; - - execService.submit( () -> { - - try { - Entity newEntity = new Entity( new SimpleId( "user" ) ); - newEntity.setField( new StringField( "username", username, true ) ); - newEntity.setField( new StringField( "email", username + "@example.org", true ) ); - - Observable<Entity> observable = manager.write( newEntity ); - Entity returned = observable.toBlocking().lastOrDefault( null ); - - usersCreated.put( username, newEntity ); - successCounter.incrementAndGet(); - - logger.debug("Created user {}", username); - - } catch ( Throwable t ) { - if ( t instanceof WriteUniqueVerifyException) { - // we expect lots of these - } else { - errorCounter.incrementAndGet(); - logger.error( "Error creating user " + username, t ); - } - } - - } ); - } - } - execService.shutdown(); - - try { - while (!execService.awaitTermination( 60, TimeUnit.SECONDS )) { - System.out.println( "Waiting..." ); - } - } catch (InterruptedException e) { - e.printStackTrace(); - } - - return usersCreated; - } -} http://git-wip-us.apache.org/repos/asf/usergrid/blob/45bb03ef/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/uniquevalues/UniqueValuesServiceTest.java ---------------------------------------------------------------------- diff --git a/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/uniquevalues/UniqueValuesServiceTest.java b/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/uniquevalues/UniqueValuesServiceTest.java new file mode 100644 index 0000000..0847649 --- /dev/null +++ b/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/uniquevalues/UniqueValuesServiceTest.java @@ -0,0 +1,155 @@ +package org.apache.usergrid.persistence.collection.uniquevalues; + +import com.google.common.collect.ArrayListMultimap; +import com.google.common.collect.Multimap; +import com.google.common.collect.Multimaps; +import com.google.inject.Inject; +import org.apache.usergrid.persistence.collection.EntityCollectionManager; +import org.apache.usergrid.persistence.collection.EntityCollectionManagerFactory; +import org.apache.usergrid.persistence.collection.exception.WriteUniqueVerifyException; +import org.apache.usergrid.persistence.collection.guice.TestCollectionModule; +import org.apache.usergrid.persistence.core.guice.MigrationManagerRule; +import org.apache.usergrid.persistence.core.scope.ApplicationScope; +import org.apache.usergrid.persistence.core.scope.ApplicationScopeImpl; +import org.apache.usergrid.persistence.core.test.ITRunner; +import org.apache.usergrid.persistence.core.test.UseModules; +import org.apache.usergrid.persistence.model.entity.Entity; +import org.apache.usergrid.persistence.model.entity.SimpleId; +import org.apache.usergrid.persistence.model.field.StringField; +import org.junit.Assert; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import rx.Observable; + +import java.util.Collection; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; + + +/** + * Test the unique values service. + */ +@RunWith( ITRunner.class ) +@UseModules( TestCollectionModule.class ) +public class UniqueValuesServiceTest { + private static final Logger logger = LoggerFactory.getLogger( UniqueValuesServiceTest.class ); + + @Inject + private EntityCollectionManagerFactory factory; + + @Inject + @Rule + public MigrationManagerRule migrationManagerRule; + + @Inject + AkkaFig akkaFig; + + @Inject + UniqueValuesService uniqueValuesService; + + + + /** + * Use multiple threads to attempt to create entities with duplicate usernames. + */ + @Test + public void testDuplicatePrevention() throws Exception { + + if ( !akkaFig.getAkkaEnabled() ) { + logger.warn("Skipping test because Akka is not enabled"); + return; + } + uniqueValuesService.start("127.0.0.1", 2551, "us-east"); + uniqueValuesService.waitForRequestActors(); + + final AtomicInteger successCounter = new AtomicInteger( 0 ); + final AtomicInteger errorCounter = new AtomicInteger( 0 ); + + int numUsers = 100; + Multimap<String, Entity> usersCreated = + generateDuplicateUsers( numUsers, successCounter, errorCounter ); + + int userCount = 0; + int usernamesWithDuplicates = 0; + for ( String username : usersCreated.keySet() ) { + Collection<Entity> users = usersCreated.get( username ); + if ( users.size() > 1 ) { + usernamesWithDuplicates++; + } + userCount++; + } + + Assert.assertEquals( 0, usernamesWithDuplicates ); + + Assert.assertEquals( numUsers, successCounter.get() ); + Assert.assertEquals( 0, errorCounter.get() ); + Assert.assertEquals( numUsers, usersCreated.size() ); + Assert.assertEquals( numUsers, userCount ); + } + + + private Multimap<String, Entity> generateDuplicateUsers( + int numUsers, AtomicInteger successCounter, AtomicInteger errorCounter ) { + + ApplicationScope context = new ApplicationScopeImpl( new SimpleId( "organization" ) ); + + EntityCollectionManager manager = factory.createCollectionManager( context ); + + Multimap<String, Entity> usersCreated = + Multimaps.synchronizedListMultimap( ArrayListMultimap.create() ); + + ExecutorService execService = Executors.newFixedThreadPool( 10 ); + + for (int i = 0; i < numUsers; i++) { + + // multiple threads simultaneously trying to create a user with the same propertyName + for (int j = 0; j < 5; j++) { + String username = "user_" + i; + + execService.submit( () -> { + + try { + + // give entity two unqiue fields username and email + Entity newEntity = new Entity( new SimpleId( "user" ) ); + newEntity.setField( new StringField( "username", username, true ) ); + newEntity.setField( new StringField( "email", username + "@example.org", true ) ); + + Observable<Entity> observable = manager.write( newEntity ); + Entity returned = observable.toBlocking().lastOrDefault( null ); + + usersCreated.put( username, newEntity ); + successCounter.incrementAndGet(); + + logger.debug("Created user {}", username); + + } catch ( Throwable t ) { + if ( t instanceof WriteUniqueVerifyException) { + // we expect lots of these + } else { + errorCounter.incrementAndGet(); + logger.error( "Error creating user " + username, t ); + } + } + + } ); + } + } + execService.shutdown(); + + try { + while (!execService.awaitTermination( 60, TimeUnit.SECONDS )) { + System.out.println( "Waiting..." ); + } + } catch (InterruptedException e) { + e.printStackTrace(); + } + + return usersCreated; + } +}
