Initial work to support a typed null field for an entity, including a new index field type named "null" with value of null. Also changes to pass a Set to elasticsearch for fields to index instead of a non unique list.
Conflicts: stack/corepersistence/model/src/main/java/org/apache/usergrid/persistence/model/field/FieldTypeName.java stack/corepersistence/model/src/test/java/org/apache/usergrid/persistence/model/entity/MapToEntityConverterTest.java stack/corepersistence/queryindex/src/test/java/org/apache/usergrid/persistence/index/impl/EntityIndexTest.java Project: http://git-wip-us.apache.org/repos/asf/usergrid/repo Commit: http://git-wip-us.apache.org/repos/asf/usergrid/commit/4a695c09 Tree: http://git-wip-us.apache.org/repos/asf/usergrid/tree/4a695c09 Diff: http://git-wip-us.apache.org/repos/asf/usergrid/diff/4a695c09 Branch: refs/heads/USERGRID-1047 Commit: 4a695c09f8ea5ba88ae8fad528d0576e9ccee0df Parents: 38b6b88 Author: Michael Russo <michaelaru...@gmail.com> Authored: Fri Jan 15 09:10:10 2016 -0800 Committer: Michael Russo <michaelaru...@gmail.com> Committed: Fri Jan 15 09:16:10 2016 -0800 ---------------------------------------------------------------------- .../model/entity/MapToEntityConverter.java | 18 ++- .../persistence/model/field/FieldTypeName.java | 3 +- .../persistence/model/field/NullField.java | 44 ++++++ .../model/entity/MapToEntityConverterTest.java | 142 +++++++++++++++++++ .../persistence/model/field/EntityTest.java | 9 +- .../persistence/index/impl/EntityField.java | 11 ++ .../index/impl/EntityMappingParser.java | 16 ++- .../index/impl/EntityToMapConverter.java | 3 +- .../persistence/index/impl/FieldParser.java | 5 +- .../persistence/index/impl/IndexingUtils.java | 1 + .../persistence/index/impl/EntityIndexTest.java | 79 ++++++++++- .../index/impl/EntityToMapConverterTest.java | 80 +++++++++-- 12 files changed, 378 insertions(+), 33 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/usergrid/blob/4a695c09/stack/corepersistence/model/src/main/java/org/apache/usergrid/persistence/model/entity/MapToEntityConverter.java ---------------------------------------------------------------------- diff --git a/stack/corepersistence/model/src/main/java/org/apache/usergrid/persistence/model/entity/MapToEntityConverter.java b/stack/corepersistence/model/src/main/java/org/apache/usergrid/persistence/model/entity/MapToEntityConverter.java index aff7439..38d6631 100644 --- a/stack/corepersistence/model/src/main/java/org/apache/usergrid/persistence/model/entity/MapToEntityConverter.java +++ b/stack/corepersistence/model/src/main/java/org/apache/usergrid/persistence/model/entity/MapToEntityConverter.java @@ -77,7 +77,13 @@ public class MapToEntityConverter{ entity.setField( new LongField( fieldName, (Long)value, unique )); } else if ( value instanceof List) { - entity.setField( listToListField( fieldName, (List)value )); + + Field field = listToListField( fieldName, (List)value ); + if(field == null){ + entity.setField( new NullField( fieldName, unique)); + }else{ + entity.setField( listToListField( fieldName, (List)value )); + } } else if ( value instanceof UUID) { entity.setField( new UUIDField( fieldName, (UUID)value, unique )); @@ -88,7 +94,10 @@ public class MapToEntityConverter{ } else if ( value instanceof Enum ) { entity.setField( new StringField( fieldName, value.toString(), unique )); - } else if ( value != null ) { + } else if ( value == null ){ + entity.setField( new NullField( fieldName, unique )); + + } else { byte[] valueSerialized; try { valueSerialized = objectMapper.writeValueAsBytes( value ); @@ -137,7 +146,10 @@ public class MapToEntityConverter{ } else if ( sample instanceof Long ) { return new ArrayField<Long>( fieldName, (List<Long>)list ); - } else { + } else if ( sample == null ) { + return new ArrayField<Object>( fieldName, (List<Object>)list ); + + } else{ throw new RuntimeException("Unknown type " + sample.getClass().getName()); } } http://git-wip-us.apache.org/repos/asf/usergrid/blob/4a695c09/stack/corepersistence/model/src/main/java/org/apache/usergrid/persistence/model/field/FieldTypeName.java ---------------------------------------------------------------------- diff --git a/stack/corepersistence/model/src/main/java/org/apache/usergrid/persistence/model/field/FieldTypeName.java b/stack/corepersistence/model/src/main/java/org/apache/usergrid/persistence/model/field/FieldTypeName.java index 90f3879..975c6bb 100644 --- a/stack/corepersistence/model/src/main/java/org/apache/usergrid/persistence/model/field/FieldTypeName.java +++ b/stack/corepersistence/model/src/main/java/org/apache/usergrid/persistence/model/field/FieldTypeName.java @@ -39,5 +39,6 @@ public enum FieldTypeName { LONG, SET, STRING, - UUID + UUID, + NULL } http://git-wip-us.apache.org/repos/asf/usergrid/blob/4a695c09/stack/corepersistence/model/src/main/java/org/apache/usergrid/persistence/model/field/NullField.java ---------------------------------------------------------------------- diff --git a/stack/corepersistence/model/src/main/java/org/apache/usergrid/persistence/model/field/NullField.java b/stack/corepersistence/model/src/main/java/org/apache/usergrid/persistence/model/field/NullField.java new file mode 100644 index 0000000..6362bcb --- /dev/null +++ b/stack/corepersistence/model/src/main/java/org/apache/usergrid/persistence/model/field/NullField.java @@ -0,0 +1,44 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. 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. For additional information regarding + * copyright in this work, please see the NOTICE file in the top level + * directory of this distribution. + */ +package org.apache.usergrid.persistence.model.field; + + +/** + * Created by russo on 1/14/16. + */ +public class NullField extends AbstractField<Object>{ + + + public NullField(String name) { + super(name, null); + } + + public NullField(String name, boolean unique) { + super(name, null, unique); + } + + public NullField() { + } + + + @Override + public FieldTypeName getTypeName() { + return FieldTypeName.NULL; + } + +} http://git-wip-us.apache.org/repos/asf/usergrid/blob/4a695c09/stack/corepersistence/model/src/test/java/org/apache/usergrid/persistence/model/entity/MapToEntityConverterTest.java ---------------------------------------------------------------------- diff --git a/stack/corepersistence/model/src/test/java/org/apache/usergrid/persistence/model/entity/MapToEntityConverterTest.java b/stack/corepersistence/model/src/test/java/org/apache/usergrid/persistence/model/entity/MapToEntityConverterTest.java new file mode 100644 index 0000000..03dfa11 --- /dev/null +++ b/stack/corepersistence/model/src/test/java/org/apache/usergrid/persistence/model/entity/MapToEntityConverterTest.java @@ -0,0 +1,142 @@ +/* + * + * * 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.model.entity; + + +import org.apache.usergrid.persistence.model.field.FieldTypeName; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.*; + +import static org.junit.Assert.assertTrue; + + +public class MapToEntityConverterTest { + + public static final Logger logger = LoggerFactory.getLogger(MapToEntityConverterTest.class); + + + @Test + public void fullMapToEntityConversion() { + + // build top-level map + final Map<String,Object> data = new HashMap<>(1); + + final String stringField = "stringFieldValue"; + final List<String> listField = new ArrayList<>(1); + listField.add("listFieldValue"); + final boolean booleanField = true; + final double doubleField = new Double("1"); + final int intField = 2; + final long longField = 3L; + final float floatField = new Float("4"); + + // build Usergrid location object + final Map<String, Double> coordinates = new HashMap<>(2); + coordinates.put("latitude", 37.3338716); + coordinates.put("longitude", -121.894249); + + final Map<String, Object> objectField = new HashMap<>(1); + objectField.put("key1", "value1"); + + // add the data to the top-level map + data.put("stringField", stringField); + data.put("listField", listField); + data.put("booleanField", booleanField); + data.put("doubleField", doubleField); + data.put("intField", intField); + data.put("longField", longField); + data.put("floatField", floatField); + data.put("location", coordinates); + data.put("objectField", objectField); + data.put("nullField", null) +; + + // convert the map to an entity + MapToEntityConverter converter = new MapToEntityConverter(); + Entity entity = converter.fromMap(data, true); + + // make sure the nested array got converted into a ListField + assertTrue(entity.getField("stringField").getTypeName() == FieldTypeName.STRING); + assertTrue(entity.getField("listField").getTypeName() == FieldTypeName.LIST); + assertTrue(entity.getField("booleanField").getTypeName() == FieldTypeName.BOOLEAN); + assertTrue(entity.getField("doubleField").getTypeName() == FieldTypeName.DOUBLE); + assertTrue(entity.getField("intField").getTypeName() == FieldTypeName.INTEGER); + assertTrue(entity.getField("longField").getTypeName() == FieldTypeName.LONG); + assertTrue(entity.getField("floatField").getTypeName() == FieldTypeName.FLOAT); + assertTrue(entity.getField("location").getTypeName() == FieldTypeName.LOCATION); + assertTrue(entity.getField("objectField").getTypeName() == FieldTypeName.OBJECT); + assertTrue(entity.getField("nullField").getTypeName() == FieldTypeName.NULL); + + } + + @Test + public void testNestedArrays() { + + // build top-level map + final Map<String,Object> data = new HashMap<>(1); + + // build nested list structure + final List<Object> childArray = new ArrayList<>(1); + childArray.add("child"); + final List<Object> parentArray = new ArrayList<>(1); + parentArray.add(childArray); + + // add the nested list to the map + data.put("parentArray", parentArray); + + // convert the map to an entity + MapToEntityConverter converter = new MapToEntityConverter(); + Entity entity = converter.fromMap(data, true); + + // make sure the nested array got converted into a ListField + assertTrue(entity.getField("parentArray").getTypeName() == FieldTypeName.LIST); + } + + @Test + public void testNullWithinArrays() { + + // build top-level map + final Map<String,Object> data = new HashMap<>(1); + + final List<Object> arrayNullValues = new ArrayList<>(1); + arrayNullValues.add(null); + arrayNullValues.add(null); + + // add the nested list to the map + data.put("arrayNullValues", arrayNullValues); + + // convert the map to an entity + MapToEntityConverter converter = new MapToEntityConverter(); + Entity entity = converter.fromMap(data, true); + + // make sure the nested array got converted into a ListField + assertTrue(entity.getField("arrayNullValues").getTypeName() == FieldTypeName.LIST); + + List arrayReturned = (List) entity.getField("arrayNullValues").getValue(); + + assertTrue( arrayReturned.get(0) == null); + } + +} http://git-wip-us.apache.org/repos/asf/usergrid/blob/4a695c09/stack/corepersistence/model/src/test/java/org/apache/usergrid/persistence/model/field/EntityTest.java ---------------------------------------------------------------------- diff --git a/stack/corepersistence/model/src/test/java/org/apache/usergrid/persistence/model/field/EntityTest.java b/stack/corepersistence/model/src/test/java/org/apache/usergrid/persistence/model/field/EntityTest.java index c450263..06b8030 100644 --- a/stack/corepersistence/model/src/test/java/org/apache/usergrid/persistence/model/field/EntityTest.java +++ b/stack/corepersistence/model/src/test/java/org/apache/usergrid/persistence/model/field/EntityTest.java @@ -47,6 +47,7 @@ public class EntityTest LongField longField = new LongField( "int", 1l ); StringField stringField = new StringField( "name", "test" ); UUIDField uuidField = new UUIDField( "uuid", UUIDGenerator.newTimeUUID() ); + NullField nullField = new NullField("null"); entity.setField( boolField ); entity.setField( doubleField ); @@ -54,6 +55,7 @@ public class EntityTest entity.setField( longField ); entity.setField( stringField ); entity.setField( uuidField ); + entity.setField( nullField ); Field<Boolean> boolFieldReturned = entity.getField( boolField.getName() ); @@ -79,6 +81,10 @@ public class EntityTest assertSame( uuidField, uuidFieldReturned ); + Field<Object> nullFieldReturned = entity.getField( nullField.getName()); + + assertSame( nullField, nullFieldReturned); + Set<Field> results = new HashSet<Field>(); results.addAll( entity.getFields() ); @@ -90,8 +96,9 @@ public class EntityTest assertTrue( results.contains( longField ) ); assertTrue( results.contains( stringField ) ); assertTrue( results.contains( uuidField ) ); + assertTrue( results.contains( nullField ) ); - assertEquals( 6, results.size() ); + assertEquals( 7, results.size() ); assertEquals( simpleId, entity.getId() ); http://git-wip-us.apache.org/repos/asf/usergrid/blob/4a695c09/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/EntityField.java ---------------------------------------------------------------------- diff --git a/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/EntityField.java b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/EntityField.java index 39f0287..1d1cd84 100644 --- a/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/EntityField.java +++ b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/EntityField.java @@ -140,5 +140,16 @@ public class EntityField extends HashMap<String, Object> { return field; } + /** + * Set a null value into the field + */ + public static EntityField create( final String fieldName ) { + EntityField field = new EntityField(); + field.put( IndexingUtils.FIELD_NAME, fieldName.toLowerCase() ); + field.put( IndexingUtils.FIELD_NULL, null ); + + return field; + } + } http://git-wip-us.apache.org/repos/asf/usergrid/blob/4a695c09/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/EntityMappingParser.java ---------------------------------------------------------------------- diff --git a/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/EntityMappingParser.java b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/EntityMappingParser.java index 2c82782..42912e9 100644 --- a/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/EntityMappingParser.java +++ b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/EntityMappingParser.java @@ -52,7 +52,7 @@ public class EntityMappingParser implements FieldParser { /** * List of all field tuples to return */ - private List<EntityField> fields = new ArrayList<>(); + private Set<EntityField> fields = new HashSet<>(); /** @@ -92,6 +92,12 @@ public class EntityMappingParser implements FieldParser { fields.add( EntityField.create( fieldStack.peek(), value ) ); } + private void visitNull( ) { + fields.add( EntityField.create( fieldStack.peek()) ); + } + + + private void visit( final float value ) { fields.add( EntityField.create( fieldStack.peek(), value ) ); @@ -192,6 +198,12 @@ public class EntityMappingParser implements FieldParser { return; } + if ( object == null ) { + + visitNull(); + return; + } + } @@ -240,7 +252,7 @@ public class EntityMappingParser implements FieldParser { /** * Parse the map field */ - public List<EntityField> parse( final Map<String, ?> map ) { + public Set<EntityField> parse(final Map<String, ?> map ) { iterate( map ); return fields; http://git-wip-us.apache.org/repos/asf/usergrid/blob/4a695c09/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/EntityToMapConverter.java ---------------------------------------------------------------------- diff --git a/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/EntityToMapConverter.java b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/EntityToMapConverter.java index 1b0d110..d0a5c44 100644 --- a/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/EntityToMapConverter.java +++ b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/EntityToMapConverter.java @@ -20,6 +20,7 @@ package org.apache.usergrid.persistence.index.impl; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Set; import org.apache.usergrid.persistence.core.scope.ApplicationScope; import org.apache.usergrid.persistence.index.IndexEdge; @@ -95,7 +96,7 @@ public class EntityToMapConverter { //now visit our entity final FieldParser parser = new EntityMappingParser(); - final List<EntityField> fieldsToIndex = parser.parse( entityMap ); + final Set<EntityField> fieldsToIndex = parser.parse( entityMap ); //add our fields http://git-wip-us.apache.org/repos/asf/usergrid/blob/4a695c09/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/FieldParser.java ---------------------------------------------------------------------- diff --git a/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/FieldParser.java b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/FieldParser.java index b0a16a6..d32427c 100644 --- a/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/FieldParser.java +++ b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/FieldParser.java @@ -24,9 +24,8 @@ package org.apache.usergrid.persistence.index.impl; -import java.util.Collection; -import java.util.List; import java.util.Map; +import java.util.Set; /** @@ -39,7 +38,7 @@ public interface FieldParser { * Visit an object. Start the root object here. * @param map */ - List<EntityField> parse( final Map<String, ?> map ); + Set<EntityField> parse(final Map<String, ?> map ); } http://git-wip-us.apache.org/repos/asf/usergrid/blob/4a695c09/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/IndexingUtils.java ---------------------------------------------------------------------- diff --git a/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/IndexingUtils.java b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/IndexingUtils.java index 179b3c4..a0e3c3f 100644 --- a/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/IndexingUtils.java +++ b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/IndexingUtils.java @@ -114,6 +114,7 @@ public class IndexingUtils { public static final String FIELD_LOCATION = "location"; public static final String FIELD_STRING = "string"; public static final String FIELD_UUID = "uuid"; + public static final String FIELD_NULL = "null"; /** http://git-wip-us.apache.org/repos/asf/usergrid/blob/4a695c09/stack/corepersistence/queryindex/src/test/java/org/apache/usergrid/persistence/index/impl/EntityIndexTest.java ---------------------------------------------------------------------- diff --git a/stack/corepersistence/queryindex/src/test/java/org/apache/usergrid/persistence/index/impl/EntityIndexTest.java b/stack/corepersistence/queryindex/src/test/java/org/apache/usergrid/persistence/index/impl/EntityIndexTest.java index d6758dd..4d0e4ec 100644 --- a/stack/corepersistence/queryindex/src/test/java/org/apache/usergrid/persistence/index/impl/EntityIndexTest.java +++ b/stack/corepersistence/queryindex/src/test/java/org/apache/usergrid/persistence/index/impl/EntityIndexTest.java @@ -69,7 +69,7 @@ import static org.junit.Assert.fail; @UseModules( { TestIndexModule.class } ) public class EntityIndexTest extends BaseIT { - private static final Logger log = LoggerFactory.getLogger(EntityIndexTest.class); + private static final Logger logger = LoggerFactory.getLogger(EntityIndexTest.class); @Inject public EntityIndexFactory eif; @@ -133,7 +133,8 @@ public class EntityIndexTest extends BaseIT { entity1.setField(new UUIDField(IndexingUtils.ENTITY_ID_FIELDNAME, UUID.randomUUID())); entity1.setField( new StringField( "testfield", "test" ) ); entity1.setField(new IntegerField("ordinal", 0)); - entity1.setField(new UUIDField("testuuid",uuid)); + entity1.setField(new UUIDField("testuuid", uuid)); + entity1.setField( new NullField("nullfield")); batch.index( indexEdge, entity1 ); @@ -164,7 +165,7 @@ public class EntityIndexTest extends BaseIT { timer.stop(); assertEquals( 2, candidateResults.size() ); - log.debug( "Query time {}ms", timer.getTime() ); + logger.debug( "Query time {}ms", timer.getTime() ); final CandidateResult candidate1 = candidateResults.get(0); @@ -266,7 +267,7 @@ public class EntityIndexTest extends BaseIT { testQuery( searchEdge, searchTypes, "name = 'Lowe Kelley'", 1 ); - log.info("hi"); + logger.info("hi"); } @@ -309,7 +310,7 @@ public class EntityIndexTest extends BaseIT { indexProducer.put(batch.build()).subscribe();; IndexRefreshCommandImpl.IndexRefreshCommandInfo info = entityIndex.refreshAsync().toBlocking().first(); long time = info.getExecutionTime(); - log.info("refresh took ms:" + time); + logger.info("refresh took ms:" + time); } @@ -342,7 +343,7 @@ public class EntityIndexTest extends BaseIT { } timer.stop(); - log.info( "Total time to index {} entries {}ms, average {}ms/entry", + logger.info( "Total time to index {} entries {}ms, average {}ms/entry", new Object[] { count, timer.getTime(), timer.getTime() / count } ); } @@ -435,7 +436,7 @@ public class EntityIndexTest extends BaseIT { timer.stop(); assertEquals(num, candidateResults.size()); - log.debug("Query time {}ms", timer.getTime()); + logger.debug("Query time {}ms", timer.getTime()); return candidateResults; } @@ -1271,6 +1272,70 @@ public class EntityIndexTest extends BaseIT { } + /** + * Tests that we're supporting null fields when indexing at Elasticsearch + */ + @Test + public void testNullFields() throws IOException { + + Id appId = new SimpleId( "application" ); + final String entityType = "thing"; + IndexEdge indexEdge = new IndexEdgeImpl( appId, "things", SearchEdge.NodeType.SOURCE, 1 ); + final SearchTypes searchTypes = SearchTypes.fromTypes( entityType ); + EntityIndexBatch batch = entityIndex.createBatch(); + + + UUID uuid = UUID.randomUUID(); + Entity entity1 = new Entity( entityType ); + EntityUtils.setVersion(entity1, UUIDGenerator.newTimeUUID()); + entity1.setField(new UUIDField(IndexingUtils.ENTITY_ID_FIELDNAME, uuid)); + + // create a list and add 3 null values to it + List<Object> listOfNulls = new ArrayList<>(3); + listOfNulls.add(null); + listOfNulls.add(null); + listOfNulls.add(null); + + + List<Object> listOfMixedNulls = new ArrayList<>(3); + listOfMixedNulls.add(null); + listOfMixedNulls.add("stringvalue"); + listOfMixedNulls.add(null); + listOfMixedNulls.add(10); + + entity1.setField( new UUIDField("uuid", uuid, true)); + entity1.setField( new ArrayField<>( "arrayofnulls", listOfNulls) ); + entity1.setField( new ArrayField<>( "arrayofmixednulls", listOfMixedNulls) ); + entity1.setField( new NullField("nullfield")); + + + + batch.index( indexEdge, entity1 ); + indexProducer.put(batch.build()).subscribe(); + + + entityIndex.refreshAsync().toBlocking().first(); + + + StopWatch timer = new StopWatch(); + timer.start(); + CandidateResults candidateResults = + entityIndex.search( indexEdge, searchTypes, "select * where uuid = '"+uuid+"'", 100, 0 ); + + timer.stop(); + + assertEquals(1, candidateResults.size()); + logger.debug("Query time {}ms", timer.getTime()); + + final CandidateResult candidate1 = candidateResults.get(0); + + //check the id and version + assertEquals( entity1.getId(), candidate1.getId() ); + assertEquals(entity1.getVersion(), candidate1.getVersion()); + + } + + } http://git-wip-us.apache.org/repos/asf/usergrid/blob/4a695c09/stack/corepersistence/queryindex/src/test/java/org/apache/usergrid/persistence/index/impl/EntityToMapConverterTest.java ---------------------------------------------------------------------- diff --git a/stack/corepersistence/queryindex/src/test/java/org/apache/usergrid/persistence/index/impl/EntityToMapConverterTest.java b/stack/corepersistence/queryindex/src/test/java/org/apache/usergrid/persistence/index/impl/EntityToMapConverterTest.java index 7e7c466..bb033b0 100644 --- a/stack/corepersistence/queryindex/src/test/java/org/apache/usergrid/persistence/index/impl/EntityToMapConverterTest.java +++ b/stack/corepersistence/queryindex/src/test/java/org/apache/usergrid/persistence/index/impl/EntityToMapConverterTest.java @@ -24,10 +24,9 @@ package org.apache.usergrid.persistence.index.impl; -import java.util.List; -import java.util.Map; -import java.util.UUID; +import java.util.*; +import org.apache.usergrid.persistence.model.field.*; import org.junit.Test; import org.apache.usergrid.persistence.core.scope.ApplicationScope; @@ -35,17 +34,6 @@ import org.apache.usergrid.persistence.core.scope.ApplicationScopeImpl; import org.apache.usergrid.persistence.index.IndexEdge; import org.apache.usergrid.persistence.index.SearchEdge; import org.apache.usergrid.persistence.model.entity.Entity; -import org.apache.usergrid.persistence.model.field.ArrayField; -import org.apache.usergrid.persistence.model.field.BooleanField; -import org.apache.usergrid.persistence.model.field.DoubleField; -import org.apache.usergrid.persistence.model.field.EntityObjectField; -import org.apache.usergrid.persistence.model.field.Field; -import org.apache.usergrid.persistence.model.field.FloatField; -import org.apache.usergrid.persistence.model.field.IntegerField; -import org.apache.usergrid.persistence.model.field.LocationField; -import org.apache.usergrid.persistence.model.field.LongField; -import org.apache.usergrid.persistence.model.field.StringField; -import org.apache.usergrid.persistence.model.field.UUIDField; import org.apache.usergrid.persistence.model.field.value.EntityObject; import org.apache.usergrid.persistence.model.field.value.Location; import org.apache.usergrid.persistence.model.util.EntityUtils; @@ -55,6 +43,7 @@ import rx.functions.Action2; import static org.apache.usergrid.persistence.core.util.IdGenerator.createId; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; /** @@ -180,6 +169,12 @@ public class EntityToMapConverterTest { ( field, entityField ) -> assertEquals( field.getValue(), entityField.get( IndexingUtils.FIELD_DOUBLE ) ) ); } + @Test + public void testNullField() { + testSingleField( new NullField( "NameNullField" ), + ( field, entityField ) -> assertEquals( field.getValue(), entityField.get( IndexingUtils.FIELD_NULL) ) ); + } + @Test public void testLocationField() { @@ -690,7 +685,7 @@ public class EntityToMapConverterTest { // if size of fields is not == 1, then we either // 1) did not index anything or 2) indexed the nested array that shouldn't be indexed at all assertEquals( 1, fields.size() ); - + final EntityField field = fields.get( 0 ); final String path = "array.nestedArrayInObject.nestedKey".toLowerCase(); @@ -698,4 +693,59 @@ public class EntityToMapConverterTest { } + + /** + * 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); + + // we added 3 values to our only array, but 2 were duplicaes. we should only have 2 now + assertEquals( 2, fields.size() ); + + final EntityField field = fieldsArray.get( 0 ); + final EntityField field1 = fieldsArray.get( 1 ); + + assertEquals( null, field.get( IndexingUtils.FIELD_NULL ) ); + assertEquals( "test", field1.get( IndexingUtils.FIELD_STRING ) ); + + } + + @Test + public void entityFieldEquality() { + + final EntityField e1 = EntityField.create("testname", "testvalue"); + final EntityField e2 = EntityField.create("testname", "testvalue"); + + final EntityField e3 = EntityField.create("testname", "testvalue1"); + + assertTrue( e1.equals(e2)); + assertTrue( !e1.equals(e3)); + + } + + }