/* * 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.cassandra; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.UUID; import org.apache.usergrid.Application; import org.apache.usergrid.CoreApplication; import org.apache.usergrid.corepersistence.index.ReIndexRequestBuilder; import org.apache.usergrid.corepersistence.index.ReIndexService; import org.apache.usergrid.persistence.*; import org.junit.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.apache.commons.lang3.RandomStringUtils; import org.apache.usergrid.AbstractCoreIT; import org.apache.usergrid.persistence.cassandra.util.TraceTag; import org.apache.usergrid.persistence.cassandra.util.TraceTagManager; import org.apache.usergrid.persistence.cassandra.util.TraceTagReporter; import org.apache.usergrid.persistence.model.util.UUIDGenerator; import org.apache.usergrid.setup.ConcurrentProcessSingleton; import rx.functions.Func2; import javax.annotation.concurrent.NotThreadSafe; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @NotThreadSafe public class EntityManagerFactoryImplIT extends AbstractCoreIT { private static final Logger logger = LoggerFactory.getLogger( EntityManagerFactoryImplIT.class ); public EntityManagerFactoryImplIT() { emf = ConcurrentProcessSingleton.getInstance().getSpringResource().getBean( EntityManagerFactory.class ); } @Rule public Application app = new CoreApplication( setup ); @BeforeClass public static void setup() throws Exception { logger.info( "setup" ); } @AfterClass public static void teardown() throws Exception { logger.info( "teardown" ); } EntityManagerFactory emf; TraceTagManager traceTagManager; TraceTagReporter traceTagReporter; public UUID createApplication( String organizationName, String applicationName ) throws Exception { Entity appInfo = emf.createApplicationV2(organizationName, applicationName); UUID appId = appInfo.getUuid(); return appId; } @Before public void initTracing() { traceTagManager = ConcurrentProcessSingleton.getInstance().getSpringResource().getBean( "traceTagManager", TraceTagManager.class ); traceTagReporter = ConcurrentProcessSingleton.getInstance().getSpringResource().getBean( "traceTagReporter", TraceTagReporter.class ); } @Test public void testDeleteApplication() throws Exception { ReIndexService reIndexService = setup.getInjector().getInstance( ReIndexService.class ); int maxRetries = 10; String rand = UUIDGenerator.newTimeUUID().toString(); // create an application with a collection and an entity String appName = "test-app-" + rand; String orgName = "test-org-" + rand; final UUID deletedAppId = setup.createApplication( orgName, appName ); EntityManager em = setup.getEmf().getEntityManager(deletedAppId); Map<String, Object> properties1 = new LinkedHashMap<String, Object>(); properties1.put( "Name", "12 Angry Men" ); properties1.put( "Year", 1957 ); Entity film1 = em.create("film", properties1); Map<String, Object> properties2 = new LinkedHashMap<String, Object>(); properties2.put( "Name", "Reservoir Dogs" ); properties2.put( "Year", 1992 ); Entity film2 = em.create( "film", properties2 ); for ( int j=0; j<maxRetries; j++ ) { if ( setup.getEmf().lookupApplication( orgName + "/" + appName ) != null ) { break; } Thread.sleep( 500 ); } this.app.waitForQueueDrainAndRefreshIndex(); // wait for it to appear in delete apps list Func2<UUID, Map<String, UUID> ,Boolean> findApps = (applicationId, apps) -> { boolean found = false; for (String app : apps.keySet()) { UUID appId = apps.get(app); if (appId.equals(applicationId)) { found = true; break; } } return found; }; Map<String,UUID> apps = setup.getEmf().getApplications(); boolean found = findApps.call(deletedAppId, apps); assertTrue("Restored app not found in apps collection", found); // delete the application setup.getEmf().deleteApplication(deletedAppId); this.app.waitForQueueDrainAndRefreshIndex(); found = findApps.call( deletedAppId, emf.getDeletedApplications() ); assertTrue("Deleted app must be found in in deleted apps collection", found); // attempt to get entities in application's collections in various ways should all fail found = setup.getEmf().lookupApplication( orgName + "/" + appName ) != null; assertFalse("Lookup of deleted app must fail", found); // app must not be found in apps collection found = findApps.call( deletedAppId, emf.getApplications()); assertFalse("Deleted app must not be found in apps collection", found); // restore the app emf.restoreApplication(deletedAppId); final ReIndexRequestBuilder builder = reIndexService.getBuilder().withApplicationId( deletedAppId ); ReIndexService.ReIndexStatus status = reIndexService.rebuildIndex(builder); int count = 0; do{ status = reIndexService.getStatus(status.getJobId()); count++; if(count>0){ if(count>10){ break; } Thread.sleep(1000); } }while (status.getStatus()!= ReIndexService.Status.COMPLETE); this.app.waitForQueueDrainAndRefreshIndex(); // test to see that app now works and is happy // it should not be found in the deleted apps collection found = findApps.call( deletedAppId, emf.getDeletedApplications()); assertFalse("Restored app found in deleted apps collection", found); this.app.waitForQueueDrainAndRefreshIndex(); apps = setup.getEmf().getApplications(); found = findApps.call(deletedAppId, apps); assertTrue("Restored app not found in apps collection", found); // TODO: this assertion should work! assertTrue(setup.getEmf().lookupApplication( orgName + "/" + appName ) != null ); } @Test public void testCreateAndGet() throws Exception { TraceTag traceTag = traceTagManager.create( "testCreateAndGet" ); traceTagManager.attach( traceTag ); logger.info( "EntityDaoTest.testCreateAndGet" ); UUID applicationId = createApplication( "EntityManagerFactoryImplIT", "testCreateAndGet" + UUIDGenerator.newTimeUUID() ); logger.info( "Application id " + applicationId ); EntityManager em = emf.getEntityManager( applicationId ); int i; List<Entity> things = new ArrayList<Entity>(); for ( i = 0; i < 10; i++ ) { Map<String, Object> properties = new LinkedHashMap<String, Object>(); properties.put( "name", "thing" + i ); Entity thing = em.create( "thing", properties ); assertNotNull( "thing should not be null", thing ); assertFalse( "thing id not valid", thing.getUuid().equals( new UUID( 0, 0 ) ) ); assertEquals( "name not expected value", "thing" + i, thing.getProperty( "name" ) ); things.add( thing ); } assertEquals( "should be ten entities", 10, things.size() ); i = 0; for ( Entity entity : things ) { Entity thing = em.get( new SimpleEntityRef("thing", entity.getUuid())); assertNotNull( "thing should not be null", thing ); assertFalse( "thing id not valid", thing.getUuid().equals( new UUID( 0, 0 ) ) ); assertEquals( "name not expected value", "thing" + i, thing.getProperty( "name" ) ); i++; } List<UUID> ids = new ArrayList<UUID>(); for ( Entity entity : things ) { ids.add( entity.getUuid() ); Entity en = em.get( new SimpleEntityRef("thing", entity.getUuid())); String type = en.getType(); assertEquals( "type not expected value", "thing", type ); Object property = en.getProperty( "name" ); assertNotNull( "thing name property should not be null", property ); assertTrue( "thing name should start with \"thing\"", property.toString().startsWith( "thing" ) ); Map<String, Object> properties = en.getProperties(); assertEquals( "number of properties wrong", 6, properties.size() ); } i = 0; Results results = em.getEntities( ids, "thing" ); for ( Entity thing : results ) { assertNotNull( "thing should not be null", thing ); assertFalse( "thing id not valid", thing.getUuid().equals( new UUID( 0, 0 ) ) ); assertEquals( "wrong type", "thing", thing.getType() ); assertNotNull( "thing name should not be null", thing.getProperty( "name" ) ); String name = thing.getProperty( "name" ).toString(); assertEquals( "unexpected name", "thing" + i, name ); i++; } assertEquals( "entities unfound entity name count incorrect", 10, i ); /* * List<UUID> entities = emf.findEntityIds(applicationId, "thing", null, * null, 100); assertNotNull("entities list should not be null", * entities); assertEquals("entities count incorrect", 10, * entities.size()); */ traceTagReporter.report( traceTagManager.detach() ); } @Test public void testCreateAndImmediateGet() throws Exception { String random = RandomStringUtils.randomAlphabetic(10); String orgName = "org_" + random; String appName = "app_" + random; String orgAppName = orgName + "/" + appName; UUID appId = setup.createApplication(orgName, appName); UUID lookedUpId = setup.getEmf().lookupApplication( orgAppName ); Assert.assertEquals(appId, lookedUpId); } }