Skip to content

Commit

Permalink
0000728: Lookup table router should throw an exception when the route…
Browse files Browse the repository at this point in the history
…r expression is invalid.

Modified the LookupTableDataRouter to validate Lookup Table expressions. 

Created unit tests to test validating Lookup Table router expressions.
  • Loading branch information
abrougher committed Jul 27, 2012
1 parent bf4f775 commit 585d617
Show file tree
Hide file tree
Showing 2 changed files with 140 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import org.jumpmind.db.sql.ISqlRowMapper;
import org.jumpmind.db.sql.ISqlTemplate;
import org.jumpmind.db.sql.Row;
import org.jumpmind.symmetric.SyntaxParsingException;
import org.jumpmind.symmetric.db.ISymmetricDialect;
import org.jumpmind.symmetric.model.DataMetaData;
import org.jumpmind.symmetric.model.Node;
Expand Down Expand Up @@ -61,18 +62,25 @@ public LookupTableDataRouter(ISymmetricDialect symmetricDialect) {
this.symmetricDialect = symmetricDialect;
}

public LookupTableDataRouter() {
}

public Set<String> routeToNodes(SimpleRouterContext routingContext, DataMetaData dataMetaData,
Set<Node> nodes, boolean initialLoad) {

Set<String> nodeIds = null;
Router router = dataMetaData.getTriggerRouter().getRouter();
Map<String, String> params = getParams(router, routingContext);
Map<String, String> dataMap = getDataMap(dataMetaData);
boolean validExpression = params.containsKey(PARAM_TABLE)
&& params.containsKey(PARAM_KEY_COLUMN)
&& params.containsKey(PARAM_MAPPED_KEY_COLUMN)
&& params.containsKey(PARAM_EXTERNAL_ID_COLUMN);
boolean validExpression = true;
Map<String, String> params = null;

try {
params = getParams(router, routingContext);
} catch(SyntaxParsingException ex) {
validExpression = false;
}

if (validExpression) {
Map<String, String> dataMap = getDataMap(dataMetaData);
Map<String, Set<String>> lookupTable = getLookupTable(params, router, routingContext);
String column = params.get(PARAM_KEY_COLUMN);
String keyData = dataMap.get(column);
Expand All @@ -85,12 +93,9 @@ public Set<String> routeToNodes(SimpleRouterContext routingContext, DataMetaData
}
}

} else {
log.warn("The provided table mapped router expression was invalid: {}.", router.getRouterExpression());
}

return nodeIds;

}

/**
Expand All @@ -103,26 +108,47 @@ protected Map<String, String> getParams(Router router, SimpleRouterContext routi
Map<String, String> params = (Map<String, String>) routingContext.getContextCache()
.get(KEY);
if (params == null) {
params = new HashMap<String, String>();
params = parse(router.getRouterExpression());
routingContext.getContextCache().put(KEY, params);
String routerExpression = router.getRouterExpression();
if (!StringUtils.isBlank(routerExpression)) {
String[] expTokens = routerExpression.split("\r\n|\r|\n");
if (expTokens != null) {
for (String t : expTokens) {
if (!StringUtils.isBlank(t)) {
String[] tokens = t.split("=");
if (tokens.length >= 2) {
params.put(tokens[0], tokens[1]);
}
}
return params;
}

public Map<String, String> parse(String routerExpression) {
boolean valid = true;
Map<String, String> params = new HashMap<String, String>();
if (!StringUtils.isBlank(routerExpression)) {
String[] expTokens = routerExpression.split("\r\n|\r|\n");
if (expTokens != null) {
for (String t : expTokens) {
if (!StringUtils.isBlank(t)) {
String[] tokens = t.split("=");
if (tokens.length == 2 && !params.containsKey(tokens[0])) {
params.put(tokens[0], tokens[1]);
} else {
valid = false;
break;
}
}
}
if (!valid ||
params.size() != 4 ||
!params.containsKey(PARAM_TABLE) ||
!params.containsKey(PARAM_KEY_COLUMN) ||
!params.containsKey(PARAM_MAPPED_KEY_COLUMN) ||
!params.containsKey(PARAM_EXTERNAL_ID_COLUMN)) {

log.warn("The provided lookup table router expression was invalid. The full expression is " + routerExpression + ".");
throw new SyntaxParsingException("The provided lookup table router expression was invalid. The full expression is " + routerExpression + ".");
}
}
}
else {
log.warn("The provided lookup table router expression is empty");
}
return params;
}

@SuppressWarnings("unchecked")
protected Map<String, Set<String>> getLookupTable(final Map<String, String> params, Router router,
SimpleRouterContext routingContext) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package org.jumpmind.symmetric.route;

import junit.framework.Assert;

import org.jumpmind.symmetric.SyntaxParsingException;
import org.junit.Test;

public class LookupTableDataRouterTest {

@Test
public void testValidExpression() {
LookupTableDataRouter router = new LookupTableDataRouter();

boolean valid = true;
try {
router.parse("LOOKUP_TABLE=STORE\r\n" +
"KEY_COLUMN=BRAND_ID\r\n" +
"LOOKUP_KEY_COLUMN=BRAND_ID\r\n" +
"EXTERNAL_ID_COLUMN=STORE_ID");
} catch(SyntaxParsingException ex) {
valid = false;
}

Assert.assertEquals(true, valid);
}

@Test
public void testExpressionWithoutNewLines() {
LookupTableDataRouter router = new LookupTableDataRouter();

boolean valid = true;
try {
router.parse("LOOKUP_TABLE=STORE KEY_COLUMN=BRAND_ID " +
"LOOKUP_KEY_COLUMN=BRAND_ID EXTERNAL_ID_COLUMN=STORE_ID");
} catch(SyntaxParsingException ex) {
valid = false;
}

Assert.assertEquals(false, valid);
}

@Test
public void testMissingEqualSign() {
LookupTableDataRouter router = new LookupTableDataRouter();

boolean valid = true;
try {
router.parse("LOOKUP_TABLE=STORE\r\n" +
"KEY_COLUMNBRAND_ID\r\n" + // <-- Missing Equal
"LOOKUP_KEY_COLUMN=BRAND_ID\r\n" +
"EXTERNAL_ID_COLUMN=STORE_ID");
} catch(SyntaxParsingException ex) {
valid = false;
}

Assert.assertEquals(false, valid);
}

@Test
public void testBadKey() {
LookupTableDataRouter router = new LookupTableDataRouter();

boolean valid = true;
try {
router.parse("LOOKUP_TAB=STORE\r\n" + // <-- Should be LOOKUP_TABLE
"KEY_COLUMN=BRAND_ID\r\n" +
"LOOKUP_KEY_COLUMN=BRAND_ID\r\n" +
"EXTERNAL_ID_COLUMN=STORE_ID");
} catch(SyntaxParsingException ex) {
valid = false;
}

Assert.assertEquals(false, valid);
}

@Test
public void testDoubleLine() {
LookupTableDataRouter router = new LookupTableDataRouter();

boolean valid = true;
try {
router.parse("LOOKUP_TABLE=STORE\r\n" +
"LOOKUP_TABLE=STORE\r\n" + // <-- Duplicate
"KEY_COLUMN=BRAND_ID\r\n" +
"LOOKUP_KEY_COLUMN=BRAND_ID\r\n" +
"EXTERNAL_ID_COLUMN=STORE_ID");
} catch(SyntaxParsingException ex) {
valid = false;
}

Assert.assertEquals(false, valid);
}
}

0 comments on commit 585d617

Please sign in to comment.