Skip to content

Commit

Permalink
added more validation
Browse files Browse the repository at this point in the history
  • Loading branch information
oemergenc committed Mar 13, 2020
1 parent 2f28399 commit 80da5ca
Show file tree
Hide file tree
Showing 8 changed files with 71 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public HBDynamicColumnObjectMapper() {
public <R extends Serializable & Comparable<R>, T extends HBRecord<R>>
Get getAsGet(Class<T> hbRecordClazz, byte[] rowKey, String family, List<String> qualifierParts) {
HBDynamicColumnRecordValidator.validateQualifierParts(qualifierParts);
HBDynamicColumnRecordValidator.validateFamily(family);
HBDynamicColumnRecordValidator.validateFamilyName(family);

Get get = new Get(rowKey);
List<HBDynamicColumn> hbDynamicColumnsForFamily = getHBDynamicColumnsForFamily(hbRecordClazz, family);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
package io.github.oemergenc.hbase.orm.extensions.dynamic.validator;

import com.flipkart.hbaseobjectmapper.DynamicQualifier;
import com.flipkart.hbaseobjectmapper.Family;
import com.flipkart.hbaseobjectmapper.HBRecord;
import com.flipkart.hbaseobjectmapper.HBTable;
import io.github.oemergenc.hbase.orm.extensions.HBDynamicColumn;
import io.github.oemergenc.hbase.orm.extensions.exception.DuplicateColumnIdentifierException;
import io.github.oemergenc.hbase.orm.extensions.exception.MissingHbTableAnnotationForFamilyException;
import lombok.val;
import net.vidageek.mirror.dsl.Mirror;
import org.apache.hbase.thirdparty.io.netty.util.internal.StringUtil;
Expand All @@ -23,6 +26,10 @@ public class HBDynamicColumnRecordValidator {
private static Mirror MIRROR = new Mirror();

static public <T extends HBRecord<?>> void validate(Class<T> hbRecordClazz) {
val hbTableFamilies = MIRROR.on(hbRecordClazz).reflect()
.annotation(HBTable.class).atClass().families();
List<String> tableFamilyNames = Arrays.stream(hbTableFamilies)
.map(Family::name).collect(Collectors.toList());
val hbDynamicColumnFields = MIRROR.on(hbRecordClazz).reflectAll().fields()
.matching(element -> element.getAnnotation(HBDynamicColumn.class) != null);

Expand All @@ -39,7 +46,7 @@ static public <T extends HBRecord<?>> void validate(Class<T> hbRecordClazz) {
}
validateQualifierField(dynamicField, qualifier);
validateQualifierParts(Arrays.asList(qualifier.parts()));
validateFamily(family);
validateFamily(family, tableFamilyNames);
validateAlias(alias);
validateSeparator(separator);
columnPrefixList.add(family.concat(separator).concat(alias));
Expand Down Expand Up @@ -70,8 +77,15 @@ static public void validateQualifierParts(List<String> parts) {
}
}

static public void validateFamily(String alias) {
if (StringUtil.isNullOrEmpty(alias)) {
static public void validateFamily(String family, List<String> tableFamilyNames) {
validateFamilyName(family);
if (!tableFamilyNames.contains(family)) {
throw new MissingHbTableAnnotationForFamilyException(family);
}
}

public static void validateFamilyName(String family) {
if (StringUtil.isNullOrEmpty(family)) {
throw new IllegalArgumentException("family of HBDynamicColumn cannot be empty or null");
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package io.github.oemergenc.hbase.orm.extensions.exception;

public class MissingHbTableAnnotationForFamilyException extends IllegalArgumentException {

public MissingHbTableAnnotationForFamilyException(Object family) {
super(String.format("The family %s is not defined on the HBTable definition. Consider adding a new Family on the HBTable class", family));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ abstract class AbstractComponentSpec extends Specification {
bigTableHelper.createTable("users", ["address", "optional"])
bigTableHelper.createTable("bd_omm_prp_campaigns", ["campaigns", "days", "optional"])
bigTableHelper.createTable("multiple_dynamic_columns_table", ["staticFamily", "dynamicFamily1", "dynamicFamily2", "dynamicFamily3", "dynamicFamily4"])
bigTableHelper.createTable("multiple_dynamic_columns_table_with_same_family", ["staticFamily", "dynamicFamily1"])
}

def setupSpec() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package io.github.oemergenc.hbase.orm.extensions.mapper

import com.flipkart.hbaseobjectmapper.DynamicQualifier
import com.flipkart.hbaseobjectmapper.Family
import com.flipkart.hbaseobjectmapper.HBRecord
import com.flipkart.hbaseobjectmapper.HBTable
import io.github.oemergenc.hbase.orm.extensions.HBDynamicColumn
import io.github.oemergenc.hbase.orm.extensions.HBDynamicColumnObjectMapper
import io.github.oemergenc.hbase.orm.extensions.exception.DuplicateColumnIdentifierException
import io.github.oemergenc.hbase.orm.extensions.exception.MissingHbTableAnnotationForFamilyException
import spock.lang.Specification
import spock.lang.Unroll

Expand Down Expand Up @@ -47,6 +50,19 @@ class InvalidHBDynamicColumnRecordSpec extends Specification {
DuplicateHBDynamicColumnClass.class | _
}

@Unroll
def "Missing hbdynamic columns family on table throws exception"() {
when:
mapper.validate(clazz)

then:
thrown(MissingHbTableAnnotationForFamilyException)

where:
clazz | _
MissingHBDynamicColumnFamilyOnTableClass.class | _
}

@Unroll
def "invalid qualifier field throws exception"() {
when:
Expand Down Expand Up @@ -105,6 +121,7 @@ class InvalidHBDynamicColumnRecordSpec extends Specification {
String q2;
}

@HBTable(name = "HBRecordTestBase", families = [@Family(name = "f")])
class HBRecordTestBase implements HBRecord<String> {
def static ID = "theId"

Expand All @@ -119,6 +136,7 @@ class InvalidHBDynamicColumnRecordSpec extends Specification {
}
}

@HBTable(name = "HBRecordTestBase", families = [@Family(name = "f")])
class ValidHBDynamicColumnClass extends HBRecordTestBase {
@HBDynamicColumn(family = "f",
alias = "a",
Expand All @@ -127,13 +145,23 @@ class InvalidHBDynamicColumnRecordSpec extends Specification {
List<SimpleQualifierClass> field;
}

@HBTable(name = "HBRecordTestBase", families = [@Family(name = "f")])
class DuplicateHBDynamicColumnClass extends HBRecordTestBase {
@HBDynamicColumn(family = "f", alias = "a", qualifier = @DynamicQualifier(parts = ["q"]))
List<SimpleQualifierClass> field;
@HBDynamicColumn(family = "f", alias = "a", qualifier = @DynamicQualifier(parts = ["q"]))
List<SimpleQualifierClass> field2;
}

@HBTable(name = "HBRecordTestBase", families = [@Family(name = "f")])
class MissingHBDynamicColumnFamilyOnTableClass extends HBRecordTestBase {
@HBDynamicColumn(family = "f", alias = "a", qualifier = @DynamicQualifier(parts = ["q"]))
List<SimpleQualifierClass> field;
@HBDynamicColumn(family = "NotOnTable", alias = "a", qualifier = @DynamicQualifier(parts = ["q"]))
List<SimpleQualifierClass> field2;
}

@HBTable(name = "HBRecordTestBase", families = [@Family(name = "f")])
class EmptyQualifierHBDynamicColumnClass extends HBRecordTestBase {
@HBDynamicColumn(family = "f",
alias = "a",
Expand All @@ -142,6 +170,7 @@ class InvalidHBDynamicColumnRecordSpec extends Specification {
List<SimpleQualifierClass> field;
}

@HBTable(name = "HBRecordTestBase", families = [@Family(name = "f")])
class BlankQualifierHBDynamicColumnClass extends HBRecordTestBase {
@HBDynamicColumn(family = "f",
alias = "a",
Expand All @@ -150,62 +179,43 @@ class InvalidHBDynamicColumnRecordSpec extends Specification {
List<SimpleQualifierClass> field;
}

class ListHBDynamicColumnClass extends HBRecordTestBase {
@HBDynamicColumn(family = "",
alias = "a",
qualifier = @DynamicQualifier(parts = ["q"])
)
List<String> field;
}

@HBTable(name = "HBRecordTestBase", families = [@Family(name = "f")])
class WrongPrimitiveHBDynamicColumnClass extends HBRecordTestBase {
@HBDynamicColumn(family = "",
@HBDynamicColumn(family = "f",
alias = "a",
qualifier = @DynamicQualifier(parts = ["q"])
)
String field;
}

@HBTable(name = "HBRecordTestBase", families = [@Family(name = "f")])
class WrongComplexHBDynamicColumnClass extends HBRecordTestBase {
@HBDynamicColumn(family = "",
@HBDynamicColumn(family = "f",
alias = "a",
qualifier = @DynamicQualifier(parts = ["q"])
)
Map<String, String> field;
}

@HBTable(name = "HBRecordTestBase", families = [@Family(name = "f")])
class WrongListPrimitiveHBDynamicColumnClass extends HBRecordTestBase {
@HBDynamicColumn(family = "",
@HBDynamicColumn(family = "f",
alias = "a",
qualifier = @DynamicQualifier(parts = ["q"])
)
List<Integer> field;
}

@HBTable(name = "HBRecordTestBase", families = [@Family(name = "f")])
class WrongListComplexTypeHBDynamicColumnClass extends HBRecordTestBase {
@HBDynamicColumn(family = "",
@HBDynamicColumn(family = "f",
alias = "a",
qualifier = @DynamicQualifier(parts = ["q"])
)
List<Map<String, String>> field;
}

class MultiplePartsHBDynamicColumnClass extends HBRecordTestBase {
@HBDynamicColumn(family = "f",
alias = "a",
qualifier = @DynamicQualifier(parts = ["q", "q1"])
)
List<TwoPartsQualifierClass> field;
}

class MultiplePartsHBDynamicColumnClass2 extends HBRecordTestBase {
@HBDynamicColumn(family = "f",
alias = "a",
qualifier = @DynamicQualifier(parts = ["q2", "q", "q1"])
)
List<ThreePartsQualifierClass> field;
}

@HBTable(name = "HBRecordTestBase", families = [@Family(name = "f")])
class InvalidMultiplePartsHBDynamicColumnClass1 extends HBRecordTestBase {
@HBDynamicColumn(family = "f",
alias = "a",
Expand All @@ -214,6 +224,7 @@ class InvalidHBDynamicColumnRecordSpec extends Specification {
List<TwoPartsQualifierClass> field;
}

@HBTable(name = "HBRecordTestBase", families = [@Family(name = "f")])
class InvalidMultiplePartsHBDynamicColumnClass2 extends HBRecordTestBase {
@HBDynamicColumn(family = "f",
alias = "a",
Expand All @@ -222,16 +233,13 @@ class InvalidHBDynamicColumnRecordSpec extends Specification {
List<TwoPartsQualifierClass> field;
}

@HBTable(name = "HBRecordTestBase", families = [@Family(name = "f")])
class EmptyPartsHBDynamicColumnClass2 extends HBRecordTestBase {
@HBDynamicColumn(family = "f",
alias = "a",
qualifier = @DynamicQualifier(parts = [])
)
List<TwoPartsQualifierClass> field;
}

class NoHBDynamicColumnClass extends HBRecordTestBase {
def field;
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
@Data
@AllArgsConstructor
@NoArgsConstructor
@HBTable(name = "users", families = {@Family(name = "address"), @Family(name = "optional")})
@HBTable(name = "users", families = {@Family(name = "addresses"), @Family(name = "optional")})
public class InvalidUserRecord implements HBRecord<String> {

@HBRowKey
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,15 @@

import static io.github.oemergenc.hbase.orm.extensions.domain.recipe.RecipeCampaignActionRecord.CAMPAIGNS_FAMILY;
import static io.github.oemergenc.hbase.orm.extensions.domain.recipe.RecipeCampaignActionRecord.CAMPAIGNS_TABLENAME;
import static io.github.oemergenc.hbase.orm.extensions.domain.recipe.RecipeCampaignActionRecord.DAYS_FAMILY;
import static io.github.oemergenc.hbase.orm.extensions.domain.recipe.RecipeCampaignActionRecord.OPTIONAL_FAMILY;


@Data
@AllArgsConstructor
@NoArgsConstructor
@HBTable(name = CAMPAIGNS_TABLENAME,
families = {@Family(name = CAMPAIGNS_FAMILY), @Family(name = OPTIONAL_FAMILY)})
families = {@Family(name = CAMPAIGNS_FAMILY), @Family(name = DAYS_FAMILY), @Family(name = OPTIONAL_FAMILY)})
public class RecipeCampaignActionRecord implements HBRecord<String> {
public static final String CAMPAIGNS_TABLENAME = "bd_omm_prp_campaigns";
public static final String CAMPAIGNS_FAMILY = "campaigns";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
@Data
@AllArgsConstructor
@NoArgsConstructor
@HBTable(name = "multiple_dynamic_columns_table", families = {
@HBTable(name = "multiple_dynamic_columns_table_with_same_family", families = {
@Family(name = "dynamicFamily1"),
@Family(name = "staticFamily")})
public class MultipleHBDynamicColumnsWithSameFamilyRecord implements HBRecord<String> {
Expand Down

0 comments on commit 80da5ca

Please sign in to comment.