public Entity fromMap(final Entity entity,final Map<String, Object> map,final SchemaManager schemaManager, final String entityType, boolean topLevel) { for ( String fieldName : map.keySet() ) { Object value = map.get( fieldName ); boolean unique = schemaManager == null ? topLevel : topLevel && schemaManager.isPropertyUnique(entityType, fieldName); entity.setField( processField( fieldName, value, unique)); } return entity; }
private Entity createEntity() { final UUID version = UUIDGenerator.newTimeUUID(); Entity entity = new Entity( new SimpleId( "test" ) ); EntityUtils.setVersion( entity, version ); BooleanField boolField = new BooleanField( "boolean", false ); DoubleField doubleField = new DoubleField( "double", 1d ); IntegerField intField = new IntegerField( "long", 1 ); LongField longField = new LongField( "int", 1l ); StringField stringField = new StringField( "name", "test" ); UUIDField uuidField = new UUIDField( "uuid", UUIDGenerator.newTimeUUID() ); entity.setField( boolField ); entity.setField( doubleField ); entity.setField( intField ); entity.setField( longField ); entity.setField( stringField ); entity.setField( uuidField ); return entity; } }
/** * Generates an entity with all string fields to have at least the minSize number of characters in the field names + * field values */ public static Entity generateEntity( final int minSize ) { int currentLength = 0; final Entity entity = new Entity( new SimpleId( "test" ) ); //generate a really large string value //loop until our size is beyond the set size for ( int i = 0; currentLength < minSize; i++ ) { final String key = "newStringField" + i; currentLength += key.length(); StringBuilder builder = new StringBuilder(); for ( int j = 0; j < 1000 && currentLength < minSize; j++ ) { builder.append( "a" ); currentLength ++; } entity.setField( new StringField( key, builder.toString() ) ); } return entity; }
@Test public void testNoConflict2() { 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", "Alfa Romeo 8C Competizione", true)); entity.setField(new StringField("identifier", "ar8c", true)); entity.setField(new IntegerField("top_speed_mph", 182)); entityManager.write( entity, null ).toBlocking().last(); entity.setField( new StringField("foo", "bar")); entityManager.write( entity, null ).toBlocking().last(); }
@Test public void testNoConflict1() { 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, null ).toBlocking().last(); Entity entityFetched = entityManager.load( entity.getId() ).toBlocking().last(); entityFetched.setField( new StringField("foo", "baz")); entityManager.write( entityFetched, null ).toBlocking().last(); }
/** * We no longer support partial writes, ensure that an exception is thrown when this occurs after v3 * @throws com.netflix.astyanax.connectionpool.exceptions.ConnectionException */ @Test public void writeLoadDeletePartial() throws ConnectionException { final Id applicationId = new SimpleId( "application" ); ApplicationScope context = new ApplicationScopeImpl( applicationId ); final UUID entityId = UUIDGenerator.newTimeUUID(); final UUID version = UUIDGenerator.newTimeUUID(); final String type = "test"; final Id id = new SimpleId( entityId, type ); Entity entity = new Entity( id ); EntityUtils.setVersion( entity, version ); BooleanField boolField = new BooleanField( "boolean", false ); DoubleField doubleField = new DoubleField( "double", 1d ); IntegerField intField = new IntegerField( "long", 1 ); LongField longField = new LongField( "int", 1l ); StringField stringField = new StringField( "name", "test" ); UUIDField uuidField = new UUIDField( "uuid", UUIDGenerator.newTimeUUID() ); entity.setField( boolField ); entity.setField( doubleField ); entity.setField( intField ); entity.setField( longField ); entity.setField( stringField ); entity.setField( uuidField ); MvccEntity saved = new MvccEntityImpl( id, version, MvccEntity.Status.PARTIAL, Optional.of( entity ) ); //persist the entity serializationStrategy.write( context, saved ).execute(); }
/** * We no longer support partial writes, ensure that an exception is thrown when this occurs after v3 * @throws ConnectionException */ @Test(expected = UnsupportedOperationException.class) public void writeLoadDeletePartial() throws ConnectionException { final Id applicationId = new SimpleId( "application" ); ApplicationScope context = new ApplicationScopeImpl( applicationId ); final UUID entityId = UUIDGenerator.newTimeUUID(); final UUID version = UUIDGenerator.newTimeUUID(); final String type = "test"; final Id id = new SimpleId( entityId, type ); Entity entity = new Entity( id ); EntityUtils.setVersion( entity, version ); BooleanField boolField = new BooleanField( "boolean", false ); DoubleField doubleField = new DoubleField( "double", 1d ); IntegerField intField = new IntegerField( "long", 1 ); LongField longField = new LongField( "int", 1l ); StringField stringField = new StringField( "name", "test" ); UUIDField uuidField = new UUIDField( "uuid", UUIDGenerator.newTimeUUID() ); entity.setField( boolField ); entity.setField( doubleField ); entity.setField( intField ); entity.setField( longField ); entity.setField( stringField ); entity.setField( uuidField ); MvccEntity saved = new MvccEntityImpl( id, version, MvccEntity.Status.PARTIAL, Optional.of( entity ) ); //persist the entity serializationStrategy.write( context, saved ).execute(); }
@Test public void testNoConflict() throws Exception { final ApplicationScope collectionScope = mock( ApplicationScope.class ); when( collectionScope.getApplication() ) .thenReturn( new SimpleId( UUIDGenerator.newTimeUUID(), "organization" ) ); final Entity entity = generateEntity(); entity.setField(new StringField("name", "FOO", true)); entity.setField(new StringField("identifier", "BAR", true)); final MvccEntity mvccEntity = fromEntity( entity ); 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.COMMITTED, MvccLogEntry.State.COMPLETE )); MvccLogEntrySerializationStrategy noConflictLog = mock( MvccLogEntrySerializationStrategy.class ); when( noConflictLog.load( collectionScope, entity.getId(), entity.getVersion(), 2) ) .thenReturn( logEntries ); UniqueValueSerializationStrategy uvstrat = mock( UniqueValueSerializationStrategy.class); // Run the stage WriteOptimisticVerify newStage = new WriteOptimisticVerify( noConflictLog ); newStage.call( new CollectionIoEvent<>( collectionScope, mvccEntity ) ); }
/** * Test the single field in our root level */ public <T> void testSingleField( final Field<T> field, Action2<Field, EntityField> assertFunction ) { Entity entity = new Entity( "test" ); entity.setField( field ); final UUID version = UUIDGenerator.newTimeUUID(); EntityUtils.setVersion( entity, version ); final ApplicationScope scope = new ApplicationScopeImpl( createId( "application" ) ); final IndexEdge indexEdge = new IndexEdgeImpl( createId( "source" ), "testEdgeType", SearchEdge.NodeType.SOURCE, 1000 ); final Map<String, Object> entityMap = EntityToMapConverter.convert( scope, indexEdge, entity ); final Set<EntityField> fieldSet = ( Set<EntityField> ) entityMap.get( IndexingUtils.ENTITY_FIELDS ); final List<EntityField> fields = new ArrayList<>(); fields.addAll(fieldSet); assertEquals( 1, fields.size() ); final EntityField esField = fields.get( 0 ); //always test the lower case arrays final String fieldName = field.getName().toLowerCase(); assertEquals( fieldName, esField.get( IndexingUtils.FIELD_NAME ) ); assertFunction.call( field, esField ); }
@Test public void testSingleIndexFromSource() { final Entity entity = new Entity( createId( "test" ), UUIDGenerator.newTimeUUID() ); entity.setField( new StringField( "string", "foo" ) ); final Edge collectionEdge = createCollectionEdge( applicationScope.getApplication(), "tests", entity.getId() ); //write the edge graphManager.writeEdge( collectionEdge ).toBlocking().last(); //index the edge final Observable<IndexOperationMessage> indexed = indexService.indexEntity( applicationScope, entity ); //real users should never call to blocking, we're not sure what we'll get final IndexOperationMessage results = indexed.toBlocking().last(); indexProducer.put(results).subscribe(); final Set<IndexOperation> indexRequests = results.getIndexRequests(); //ensure our value made it to the index request final IndexOperation indexRequest = indexRequests.iterator().next(); assertNotNull( indexRequest ); }
private void insertJsonBlob( List<Object> sampleJson, EntityIndexBatch batch, String entityType, IndexEdge indexEdge, final int max, final int startIndex ) throws IOException { int count = 0; StopWatch timer = new StopWatch(); timer.start(); if ( startIndex > 0 ) { for ( int i = 0; i < startIndex; i++ ) { sampleJson.remove( 0 ); } } for ( Object o : sampleJson ) { Map<String, Object> item = ( Map<String, Object> ) o; Entity entity = new Entity( entityType ); entity = EntityIndexMapUtils.fromMap( entity, item ); EntityUtils.setVersion( entity, UUIDGenerator.newTimeUUID() ); entity.setField( new UUIDField( IndexingUtils.ENTITY_ID_FIELDNAME, UUID.randomUUID() ) ); batch.index( indexEdge, entity ); if ( ++count > max ) { break; } } timer.stop(); logger.info( "Total time to index {} entries {}ms, average {}ms/entry", new Object[] { count, timer.getTime(), timer.getTime() / count } ); }
/** * Objects nested within arrays are allowed to be indexed (just not n+1 nested arrays themselves) */ @Test public void testNullsWithinArray() { final ArrayField<Object> array = new ArrayField<>("array"); // add a couple null values array.add(null); array.add("test"); // this should get indexed Entity rootEntity = new Entity( "test" ); rootEntity.setField( array ); final UUID version = UUIDGenerator.newTimeUUID(); EntityUtils.setVersion( rootEntity, version ); final ApplicationScope scope = new ApplicationScopeImpl( createId( "application" ) ); final IndexEdge indexEdge = new IndexEdgeImpl( createId( "source" ), "testEdgeType", SearchEdge.NodeType.SOURCE, 1000 ); final Map<String, Object> entityMap = EntityToMapConverter.convert( scope, indexEdge, rootEntity ); final Set<EntityField> fields = ( Set<EntityField> ) entityMap.get( IndexingUtils.ENTITY_FIELDS ); List<EntityField> fieldsArray = new ArrayList<>(); fieldsArray.addAll(fields); assertEquals( 2, fields.size() ); final EntityField field = fieldsArray.get( 0 ); final EntityField field1 = fieldsArray.get( 1 ); // the fields get re-sorted on array to list conversion assertEquals( "test", field.get( IndexingUtils.FIELD_STRING ) ); assertEquals( null, field1.get( IndexingUtils.FIELD_NULL ) ); }
@Test public void writeWithUniqueValues() { ApplicationScope context = new ApplicationScopeImpl( new SimpleId( "organization" ) ); EntityCollectionManager manager = factory.createCollectionManager( context ); { Entity newEntity = new Entity( new SimpleId( "test" ) ); newEntity.setField( new IntegerField( "count", 5, true ) ); Observable<Entity> observable = manager.write( newEntity, null ); Entity returned = observable.toBlocking().lastOrDefault( null ); } { try { Entity newEntity = new Entity( new SimpleId( "test" ) ); newEntity.setField( new IntegerField( "count", 5, true ) ); manager.write( newEntity, null ).toBlocking().last(); fail( "Write should have thrown an exception" ); } catch ( Exception ex ) { WriteUniqueVerifyException e = ( WriteUniqueVerifyException ) ex; assertEquals( 1, e.getViolations().size() ); } } }
rootEntity.setField( nested1Field );
@Test public void testSizeByEdge(){ final String type = UUID.randomUUID().toString(); Id ownerId = new SimpleId( "owner" ); final Entity first = new Entity( type ); first.setField( new StringField( "string", "I ate a sammich" ) ); first.setSize(100); EntityUtils.setVersion( first, UUIDGenerator.newTimeUUID() ); final Entity second = new Entity( type ); second.setSize(100); second.setField( new StringField( "string", "I drank a beer" ) ); EntityUtils.setVersion( second, UUIDGenerator.newTimeUUID() ); EntityIndexBatch batch = entityIndex.createBatch(); //get ordering, so 2 is before 1 when both match IndexEdge indexScope1 = new IndexEdgeImpl( ownerId,type , SearchEdge.NodeType.SOURCE, 10 ); batch.index( indexScope1, first ); IndexEdge indexScope2 = new IndexEdgeImpl( ownerId, type+"er", SearchEdge.NodeType.SOURCE, 11 ); batch.index( indexScope2, second); indexProducer.put(batch.build()).subscribe();; entityIndex.refreshAsync().toBlocking().first(); long size = entityIndex.getTotalEntitySizeInBytes(new SearchEdgeImpl(ownerId,type, SearchEdge.NodeType.SOURCE)); assertTrue( size == 100 ); }
@Test public void testGetIdField() throws Exception { ApplicationScope context = new ApplicationScopeImpl( new SimpleId( "organization" ) ); EntityCollectionManager manager = factory.createCollectionManager( context ); // create an entity of type "item" with a unique_id field value = 1 Entity entity1 = new Entity( new SimpleId( "item" ) ); entity1.setField( new StringField( "unique_id", "1", true ) ); manager.write( entity1, null ).toBlocking().last(); final Observable<Id> idObs = manager.getIdField( "item", new StringField( "unique_id", "1" ) ); Id id = idObs.toBlocking().lastOrDefault( null ); assertEquals( entity1.getId(), id ); // create an entity of type "deleted_item" with a unique_id field value = 1 Entity entity2 = new Entity( new SimpleId( "deleted_item" ) ); entity2.setField( new StringField( "unique_id", "1", true ) ); manager = factory.createCollectionManager( context ); manager.write( entity2, null ).toBlocking().last(); final Observable<Id> id2Obs = manager.getIdField( "deleted_item", new StringField( "unique_id", "1" ) ); Id id2 = id2Obs.toBlocking().lastOrDefault( null ); assertEquals( entity2.getId(), id2 ); }
@Test public void updateVersioning() { // create entity Entity origEntity = new Entity( new SimpleId( "testUpdate" ) ); origEntity.setField( new StringField( "testField", "value" ) ); ApplicationScope context = new ApplicationScopeImpl( new SimpleId( "organization" ) ); EntityCollectionManager manager = factory.createCollectionManager( context ); Entity returned = manager.write( origEntity, null ).toBlocking().lastOrDefault( null ); // note its version UUID oldVersion = returned.getVersion(); // partial update entity but with new entity that has version = null assertNotNull( "A version must be assigned", oldVersion ); // partial update entity but we don't have version number Entity updateEntity = new Entity( origEntity.getId() ); updateEntity.setField( new StringField( "addedField", "other value" ) ); manager.write( updateEntity, null ).toBlocking().lastOrDefault( null ); // get entity now, it must have a new version returned = manager.load( origEntity.getId() ).toBlocking().lastOrDefault( null ); UUID newVersion = returned.getVersion(); assertNotNull( "A new version must be assigned", newVersion ); // new Version should be > old version assertTrue( UUIDComparator.staticCompare( newVersion, oldVersion ) > 0 ); }
@Test public void writeLoadUpdateLoad() { ApplicationScope context = new ApplicationScopeImpl( new SimpleId( "organization" ) ); Entity newEntity = new Entity( new SimpleId( "test" ) ); newEntity.setField( new IntegerField( "counter", 1 ) ); EntityCollectionManager manager = factory.createCollectionManager( context ); Observable<Entity> observable = manager.write( newEntity, null ); Entity createReturned = observable.toBlocking().lastOrDefault( null ); assertNotNull( "Id was assigned", createReturned.getId() ); Observable<Entity> loadObservable = manager.load( createReturned.getId() ); Entity loadReturned = loadObservable.toBlocking().lastOrDefault( null ); assertEquals( "Same value", createReturned, loadReturned ); assertEquals( "Field value correct", createReturned.getField( "counter" ), loadReturned.getField( "counter" ) ); //update the field to 2 createReturned.setField( new IntegerField( "counter", 2 ) ); //wait for the write to complete manager.write( createReturned, null ).toBlocking().lastOrDefault( null ); loadObservable = manager.load( createReturned.getId() ); loadReturned = loadObservable.toBlocking().lastOrDefault( null ); assertEquals( "Same value", createReturned, loadReturned ); assertEquals( "Field value correct", createReturned.getField( "counter" ), loadReturned.getField( "counter" ) ); }
@Test public void writeAndGetField() { ApplicationScope collectionScope1 = new ApplicationScopeImpl( new SimpleId( "organization" ) ); Entity newEntity = new Entity( new SimpleId( "test" ) ); Field field = new StringField( "testField", "unique", true ); newEntity.setField( field ); EntityCollectionManager manager = factory.createCollectionManager( collectionScope1 ); Observable<Entity> observable = manager.write( newEntity, null ); Entity createReturned = observable.toBlocking().lastOrDefault( null ); assertNotNull( "Id was assigned", createReturned.getId() ); assertNotNull( "Version was assigned", createReturned.getVersion() ); Id id = manager.getIdField( newEntity.getId().getType(), field ).toBlocking().lastOrDefault( null ); assertNotNull( id ); assertEquals( newEntity.getId(), id ); Field fieldNull = new StringField( "testFieldNotThere", "uniquely", true ); id = manager.getIdField( newEntity.getId().getType(), fieldNull ).toBlocking().lastOrDefault( null ); assertNull( id ); }
@Test public void testDeindex() { IndexEdge searchEdge = new IndexEdgeImpl( appId, "fastcars", SearchEdge.NodeType.SOURCE, 1 ); Map entityMap = new HashMap() {{ put( "name", "Ferrari 212 Inter" ); put( "introduced", 1952 ); put( "topspeed", 215 ); }}; Entity entity = EntityIndexMapUtils.fromMap( entityMap ); EntityUtils.setId(entity, new SimpleId( "fastcar" ) ); EntityUtils.setVersion(entity, UUIDGenerator.newTimeUUID() ); entity.setField(new UUIDField(IndexingUtils.ENTITY_ID_FIELDNAME, UUID.randomUUID() ) ); indexProducer.put(entityIndex.createBatch().index( searchEdge, entity ).build()).subscribe(); entityIndex.refreshAsync().toBlocking().first(); CandidateResults candidateResults = entityIndex .search( searchEdge, SearchTypes.fromTypes( entity.getId().getType() ), "name contains 'Ferrari*'", 10, 0, false ); assertEquals( 1, candidateResults.size() ); EntityIndexBatch batch = entityIndex.createBatch(); batch.deindex( searchEdge, entity ); indexProducer.put(batch.build()).subscribe();; entityIndex.refreshAsync().toBlocking().first(); candidateResults = entityIndex .search(searchEdge, SearchTypes.fromTypes( entity.getId().getType() ), "name contains 'Ferrari*'", 10, 0, false ); assertEquals(0, candidateResults.size()); }