IndexMasterObserver extends BaseMasterObserver { protected static void checkIndexNames(HColumnDescriptor familyDesc) throws IOException { String indexAttribute = familyDesc.getValue(THEMIS_SECONDARY_INDEX_FAMILY_ATTRIBUTE_KEY); String[] indexColumns = indexAttribute.split(THEMIS_SECONDARY_INDEX_NAME_SPLITOR); Set<String> indexColumnSet = new HashSet<String>(); for (String indexColumn : indexColumns) { if (indexColumnSet.contains(indexColumn)) { throw new IOException("duplicate secondary index definition, indexAttribute=" + indexAttribute + ", familyDesc:" + familyDesc); } byte[][] indexNameAndColumn = KeyValue.parseColumn(Bytes.toBytes(indexColumn)); if (indexNameAndColumn.length == 1 || indexNameAndColumn[0] == null || indexNameAndColumn[0].length == 0 || indexNameAndColumn[1] == null || indexNameAndColumn[1].length == 0) { throw new IOException( "illegal secondary index definition, please set index as 'indexName:qualifier', but is:" + indexColumn); } indexColumnSet.add(indexColumn); } }  @Override void preCreateTable(ObserverContext<MasterCoprocessorEnvironment> ctx,
      HTableDescriptor desc, HRegionInfo[] regions); @Override void preDeleteTable(ObserverContext<MasterCoprocessorEnvironment> ctx,
      byte[] tableName); @Override void postDeleteTable(ObserverContext<MasterCoprocessorEnvironment> ctx,
      byte[] tableName); static final String THEMIS_SECONDARY_INDEX_FAMILY_ATTRIBUTE_KEY; static final String THEMIS_SECONDARY_INDEX_NAME_SPLITOR; static final String THEMIS_SECONDARY_INDEX_TABLE_NAME_PREFIX; static final String THEMIS_SECONDARY_INDEX_TABLE_ATTRIBUTE_KEY; static final String THEMIS_SECONDARY_INDEX_TABLE_FAMILY; static final byte[] THEMIS_SECONDARY_INDEX_TABLE_FAMILY_BYTES; }
@Test public void testCheckIndexNames() throws IOException { HColumnDescriptor desc = new HColumnDescriptor("C"); String familyIndexAttribute = "index_a:a;index_a:a"; desc.setValue(IndexMasterObserver.THEMIS_SECONDARY_INDEX_FAMILY_ATTRIBUTE_KEY, familyIndexAttribute); try { IndexMasterObserver.checkIndexNames(desc); } catch (IOException e) { Assert.assertTrue(e.getMessage().indexOf("duplicate secondary index definition") >= 0); } String[] familyIndexAttributes = new String[] {"index_a:", ":index_a", ":"}; for (String indexAttribute : familyIndexAttributes) { desc.setValue(IndexMasterObserver.THEMIS_SECONDARY_INDEX_FAMILY_ATTRIBUTE_KEY, indexAttribute); try { IndexMasterObserver.checkIndexNames(desc); } catch (IOException e) { Assert.assertTrue(e.getMessage().indexOf("illegal secondary index definition") >= 0); } } familyIndexAttributes = new String[]{"index_a:a", "index_a:a;index_a:b;index_b:a"}; for (String indexAttribute : familyIndexAttributes) { desc.setValue(IndexMasterObserver.THEMIS_SECONDARY_INDEX_FAMILY_ATTRIBUTE_KEY, indexAttribute); IndexMasterObserver.checkIndexNames(desc); } }