Changeset 4131


Ignore:
Timestamp:
2010-07-09 14:38:26 (3 years ago)
Author:
bruno
Message:

Adding 'books sample':

  • sample import file
  • matching sample indexer config
  • matching SOLR schema.xml

Add special handling in import tool for vtag fields:

  • check they match the structural requirements (non-versioned, long type)
  • support special 'last' value for vtag fields, which will cause them to be automatically set to the last version. This part is currently tricky, and is done by doing a second update on the record. This is probably something which will need native support inside the repository to do it well.

For the import tool and the tester, removed the default arguments specified in the pom.xml so that they can be supplied via the command line. See updated README.txt for sample.

Use the standard zookeeper port (2181) in HBaseRunner and all sample configs.

Location:
projects/lily/trunk
Files:
3 added
9 edited

Legend:

Unmodified
Added
Removed
  • projects/lily/trunk/testfw/src/main/java/org/lilycms/testfw/HBaseProxy.java

    r4111 r4131  
    7373            case CONNECT: 
    7474                CONF.set("hbase.zookeeper.quorum", "localhost"); 
    75                 CONF.set("hbase.zookeeper.property.clientPort", "21812"); // matches HBaseRunner 
     75                CONF.set("hbase.zookeeper.property.clientPort", "2181"); // matches HBaseRunner 
    7676                addUserProps(CONF); 
    7777                cleanTables(); 
  • projects/lily/trunk/testfw/src/main/java/org/lilycms/testfw/HBaseRunner.java

    r4112 r4131  
    2828    private File clusterTestBuildDir = null; 
    2929    private Configuration conf; 
    30     private int zkPort = 21812; 
     30    private int zkPort = 2181; 
    3131 
    3232    public static final String TEST_DIRECTORY_KEY = "test.build.data"; 
  • projects/lily/trunk/tools/import/README.txt

    r4127 r4131  
    1313In a source setting, you can run this tool with maven: 
    1414 
    15 mvn exec:java 
     15mvn exec:java -Dexec.args="sample.json localhost:2181" 
  • projects/lily/trunk/tools/import/pom.xml

    r4127 r4131  
    4242          <mainClass>org.lilycms.tools.import_.JsonImportTool</mainClass> 
    4343          <classpathScope>runtime</classpathScope> 
    44           <commandlineArgs>sample.json localhost:21812</commandlineArgs> 
    4544        </configuration> 
    4645      </plugin> 
  • projects/lily/trunk/tools/import/src/main/java/org/lilycms/tools/import_/ImportTool.java

    r4130 r4131  
    22 
    33import org.lilycms.repository.api.*; 
     4import org.lilycms.repoutil.VersionTag; 
    45 
    56import java.util.*; 
     
    108109 
    109110        if (oldRecord != null) { 
     111            // Collect the set of vtag fields that should be automatically set to the last version. 
     112            // These are by contract those that have the value -1. 
     113            Set<QName> vtagFieldsToBeSetToLastVersion = new HashSet<QName>(); 
     114            for (Map.Entry<QName, Object> field : newRecord.getFields().entrySet()) { 
     115                if (field.getKey().getNamespace().equals(VersionTag.NAMESPACE) && field.getValue().equals(-1L)) { 
     116                    vtagFieldsToBeSetToLastVersion.add(field.getKey()); 
     117                } 
     118            } 
     119 
     120            // Before comparing with the previous state, set the vtag fields to the currently last version 
     121            for (QName vtag : vtagFieldsToBeSetToLastVersion) { 
     122                newRecord.setField(vtag, oldRecord.getVersion()); 
     123            } 
     124 
    110125            if (newRecord.softEquals(oldRecord)) { 
    111126                importListener.existsAndEqual(EntityType.RECORD, null, newRecord.getId().toString()); 
     
    118133                    } 
    119134                } 
     135 
     136                // Exclude vtag fields to-be-set-to-last-version from the update, will set those afterwards 
     137                for (QName vtag : vtagFieldsToBeSetToLastVersion) { 
     138                    newRecord.delete(vtag, false); 
     139                } 
     140 
     141                // Update the record 
    120142                Record updatedRecord = repository.update(newRecord); 
     143 
     144                // Now do a second update to set the vtags to version created 
     145                if (updatedRecord.getVersion() != null && !vtagFieldsToBeSetToLastVersion.isEmpty()) { 
     146                    Record vtagsUpdate = repository.newRecord(newRecord.getId()); 
     147                    for (QName vtag : vtagFieldsToBeSetToLastVersion) { 
     148                        if (!(oldRecord.hasField(vtag) && oldRecord.getField(vtag).equals(updatedRecord.getVersion()))) { 
     149                            vtagsUpdate.setField(vtag, updatedRecord.getVersion()); 
     150                        } 
     151                    } 
     152 
     153                    if (!vtagsUpdate.getFields().isEmpty()) { 
     154                        vtagsUpdate.setRecordType(updatedRecord.getRecordTypeId(), updatedRecord.getRecordTypeVersion()); 
     155                        updatedRecord = repository.update(vtagsUpdate); 
     156                    } 
     157                } 
     158 
    121159                importListener.updated(EntityType.RECORD, null, updatedRecord.getId().toString(), updatedRecord.getVersion()); 
    122160                return updatedRecord; 
    123161            } 
    124162        } else { 
     163            // For new records, let the vtag fields which should point to the last version point to 1 
     164            // TODO: this should check if there are actually any versioned fields. 
     165            for (Map.Entry<QName, Object> field : newRecord.getFields().entrySet()) { 
     166                if (field.getKey().getNamespace().equals(VersionTag.NAMESPACE) && field.getValue().equals(-1L)) { 
     167                    newRecord.setField(field.getKey(), 1L); 
     168                } 
     169            } 
    125170            Record createdRecord = repository.create(newRecord); 
    126171            importListener.created(EntityType.RECORD, null, createdRecord.getId().toString()); 
  • projects/lily/trunk/tools/import/src/main/java/org/lilycms/tools/import_/JsonImportTool.java

    r4130 r4131  
    1010import org.lilycms.client.Client; 
    1111import org.lilycms.repository.api.*; 
     12import org.lilycms.repoutil.VersionTag; 
     13 
    1214import static org.lilycms.repoutil.JsonUtil.*; 
    1315 
     
    141143        FieldType fieldType = typeManager.newFieldType(valueType, name, scope); 
    142144 
     145        // Some sanity checks for version tag fields 
     146        if (fieldType.getName().getNamespace().equals(VersionTag.NAMESPACE)) { 
     147            if (fieldType.getScope() != Scope.NON_VERSIONED) 
     148                throw new ImportException("vtag fields should be in the non-versioned scope"); 
     149 
     150            if (!fieldType.getValueType().getPrimitive().getName().equals("LONG")) 
     151                throw new ImportException("vtag fields should be of type LONG"); 
     152 
     153            if (fieldType.getValueType().isMultiValue()) 
     154                throw new ImportException("vtag fields should not be multi-valued"); 
     155 
     156            if (fieldType.getValueType().isHierarchical()) 
     157                throw new ImportException("vtag fields should not be hierarchical"); 
     158        } 
     159         
    143160        return importTool.importFieldType(fieldType); 
    144161    } 
     
    183200            if (name.contains(":")) { 
    184201                QName qname = parseQName(name); 
    185                 ValueType valueType = typeManager.getFieldTypeByName(qname).getValueType(); 
    186                 Object value = readMultiValue(getNode(node, name), valueType, name); 
     202                FieldType fieldType = typeManager.getFieldTypeByName(qname); 
     203                Object value = readMultiValue(getNode(node, name), fieldType, name); 
    187204                record.setField(qname, value); 
    188205            } 
     
    192209    } 
    193210 
    194     private Object readMultiValue(JsonNode node, ValueType valueType, String prop) throws ImportException { 
    195         if (valueType.isMultiValue()) { 
     211    private Object readMultiValue(JsonNode node, FieldType fieldType, String prop) throws ImportException { 
     212        if (fieldType.getValueType().isMultiValue()) { 
    196213            if (!node.isArray()) { 
    197214                throw new ImportException("Multi-value value should be specified as array in " + prop); 
     
    200217            List<Object> value = new ArrayList<Object>(); 
    201218            for (int i = 0; i < node.size(); i++) { 
    202                 value.add(readHierarchical(node.get(i), valueType, prop)); 
     219                value.add(readHierarchical(node.get(i), fieldType, prop)); 
    203220            } 
    204221 
    205222            return value; 
    206223        } else { 
    207             return readHierarchical(node, valueType, prop); 
    208         } 
    209     } 
    210  
    211     private Object readHierarchical(JsonNode node, ValueType valueType, String prop) throws ImportException { 
    212         if (valueType.isHierarchical()) { 
     224            return readHierarchical(node, fieldType, prop); 
     225        } 
     226    } 
     227 
     228    private Object readHierarchical(JsonNode node, FieldType fieldType, String prop) throws ImportException { 
     229        if (fieldType.getValueType().isHierarchical()) { 
    213230            if (!node.isArray()) { 
    214231                throw new ImportException("Hierarchical value should be specified as an array in " + prop); 
     
    217234            Object[] elements = new Object[node.size()]; 
    218235            for (int i = 0; i < node.size(); i++) { 
    219                 elements[i] = readPrimitive(node.get(i), valueType, prop); 
     236                elements[i] = readPrimitive(node.get(i), fieldType, prop); 
    220237            } 
    221238 
    222239            return new HierarchyPath(elements); 
    223240        } else { 
    224             return readPrimitive(node, valueType, prop); 
    225         } 
    226     } 
    227  
    228     private Object readPrimitive(JsonNode node, ValueType valueType, String prop) throws ImportException { 
    229         String primitive = valueType.getPrimitive().getName(); 
     241            return readPrimitive(node, fieldType, prop); 
     242        } 
     243    } 
     244 
     245    private Object readPrimitive(JsonNode node, FieldType fieldType, String prop) throws ImportException { 
     246        String primitive = fieldType.getValueType().getPrimitive().getName(); 
    230247 
    231248        if (primitive.equals("STRING")) { 
     
    240257            return node.getIntValue(); 
    241258        } else if (primitive.equals("LONG")) { 
     259            // Special handling for version tag fields 
     260            if (fieldType.getName().getNamespace().equals(VersionTag.NAMESPACE)) { 
     261                if (node.isTextual()) { 
     262                    if (node.getTextValue().equals("last")) { 
     263                        return -1L; 
     264                    } else { 
     265                        throw new ImportException("Version tag fields can only have 'last' as string value. Field " + 
     266                                prop + ", value " + node.getTextValue()); 
     267                    } 
     268                } else if (node.isIntegralNumber()) { 
     269                    if (node.getLongValue() < 0) { 
     270                        throw new ImportException("Version tag fields should be larger than 0. Field " + prop + 
     271                                ", value " + node.getLongValue()); 
     272                    } 
     273                } else { 
     274                    throw new ImportException("Expected long value or \"last\" for " + prop); 
     275                } 
     276            } 
     277 
    242278            if (!node.isIntegralNumber()) 
    243279                throw new ImportException("Expected long value for " + prop); 
  • projects/lily/trunk/tools/tester/README.txt

    r4125 r4131  
    1717In a source setting, you can run this tool with maven: 
    1818 
    19 mvn exec:java 
     19mvn exec:java -Dexec.args="config.json" 
  • projects/lily/trunk/tools/tester/config.json

    r4125 r4131  
    11{ 
    2   "zookeeper": "localhost:21812", 
     2  "zookeeper": "localhost:2181", 
    33 
    44  "reportFile": "testreport.csv", 
  • projects/lily/trunk/tools/tester/pom.xml

    r4125 r4131  
    4242          <mainClass>org.lilycms.tools.tester.Tester</mainClass> 
    4343          <classpathScope>runtime</classpathScope> 
    44           <commandlineArgs>config.json</commandlineArgs> 
    4544        </configuration> 
    4645      </plugin> 
Note: See TracChangeset for help on using the changeset viewer.