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));
+
+    }
+
+
 }

Reply via email to