You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by js...@apache.org on 2013/02/22 19:45:02 UTC
svn commit: r1449165 - in /incubator/ambari/trunk: ./
ambari-server/src/main/java/org/apache/ambari/server/api/predicate/
ambari-server/src/main/java/org/apache/ambari/server/api/services/
ambari-server/src/test/java/org/apache/ambari/server/api/predic...
Author: jspeidel
Date: Fri Feb 22 18:45:02 2013
New Revision: 1449165
URL: http://svn.apache.org/r1449165
Log:
AMBARI-1479. Query Lexer fails to parse some query strings containing 'fields'
Modified:
incubator/ambari/trunk/CHANGES.txt
incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/predicate/QueryLexer.java
incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/services/BaseService.java
incubator/ambari/trunk/ambari-server/src/test/java/org/apache/ambari/server/api/predicate/QueryLexerTest.java
Modified: incubator/ambari/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/CHANGES.txt?rev=1449165&r1=1449164&r2=1449165&view=diff
==============================================================================
--- incubator/ambari/trunk/CHANGES.txt (original)
+++ incubator/ambari/trunk/CHANGES.txt Fri Feb 22 18:45:02 2013
@@ -380,6 +380,9 @@ Trunk (unreleased changes):
AMBARI-1439. rrd file location should be configurable through UI. (jaimin)
+ AMBARI-1479. Query Lexer sometimes fails to properly parse query strings with
+ ignored properties such as 'fields' present. (jspeidel)
+
AMBARI-1446. URL used by API to invoke Ganglia rrd script may exceed max length
for query string for large clusters. (jspeidel)
Modified: incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/predicate/QueryLexer.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/predicate/QueryLexer.java?rev=1449165&r1=1449164&r2=1449165&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/predicate/QueryLexer.java (original)
+++ incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/predicate/QueryLexer.java Fri Feb 22 18:45:02 2013
@@ -191,11 +191,9 @@ public class QueryLexer {
private List<Token> m_listTokens = new ArrayList<Token>();
/**
- * Whether the current expression should be ignored.
- * This is used to ignore portions of the query string that are
- * not query specific.
+ * If non-null, ignore all tokens up to and including this token type.
*/
- private boolean m_ignore = false;
+ private Token.TYPE m_ignoreSegmentEndToken = null;
/**
* Constructor.
@@ -206,12 +204,12 @@ public class QueryLexer {
}
/**
- * Set the ignore tokens flag.
+ * Ignore all subsequent tokens up to and including the provided token.
*
- * @param ignore true to ignore tokens; false otherwise
+ * @param type the last token type of the ignore segment
*/
- public void setIgnoreTokens(boolean ignore) {
- m_ignore = ignore;
+ public void setIgnoreSegmentEndToken(Token.TYPE type) {
+ m_ignoreSegmentEndToken = type;
}
/**
@@ -258,8 +256,10 @@ public class QueryLexer {
* @param token the token to add
*/
public void addToken(Token token) {
- if (! m_ignore) {
+ if (m_ignoreSegmentEndToken == null) {
m_listTokens.add(token);
+ } else if (token.getType() == m_ignoreSegmentEndToken) {
+ m_ignoreSegmentEndToken = null;
}
}
@@ -335,10 +335,14 @@ public class QueryLexer {
if (! SET_IGNORE.contains(token)) {
ctx.setPropertyOperand(token);
} else {
- ctx.setIgnoreTokens(true);
- if (!ctx.getTokenList().isEmpty()) {
- // remove '&' token that separates ignored token and query
+ if (!ctx.getTokenList().isEmpty() ) {
+ // ignore through next value operand
+ ctx.setIgnoreSegmentEndToken(Token.TYPE.VALUE_OPERAND);
+ // remove preceding '&' token
ctx.getTokenList().remove(ctx.getTokenList().size() -1);
+ } else {
+ // first expression. Ignore and strip out next '&'
+ ctx.setIgnoreSegmentEndToken(Token.TYPE.LOGICAL_OPERATOR);
}
}
}
@@ -465,7 +469,6 @@ public class QueryLexer {
@Override
public void _handleToken(String token, ScanContext ctx) throws InvalidQueryException {
ctx.addToken(new Token(Token.TYPE.LOGICAL_OPERATOR, token));
- ctx.setIgnoreTokens(false);
}
@Override
Modified: incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/services/BaseService.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/services/BaseService.java?rev=1449165&r1=1449164&r2=1449165&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/services/BaseService.java (original)
+++ incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/services/BaseService.java Fri Feb 22 18:45:02 2013
@@ -25,6 +25,8 @@ import org.apache.ambari.server.api.reso
import org.apache.ambari.server.api.resources.ResourceInstanceFactoryImpl;
import org.apache.ambari.server.api.services.serializers.ResultSerializer;
import org.apache.ambari.server.controller.spi.Resource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.Response;
@@ -47,6 +49,11 @@ public abstract class BaseService {
private RequestHandlerFactory m_handlerFactory = new RequestHandlerFactory();
/**
+ * Logger instance.
+ */
+ private final static Logger LOG = LoggerFactory.getLogger(BaseService.class);
+
+ /**
* All requests are funneled through this method so that common logic can be executed.
* This consists of creating a {@link Request} instance, invoking the correct {@link RequestHandler} and
* applying the proper {@link ResultSerializer} to the result.
@@ -65,6 +72,8 @@ public abstract class BaseService {
Request request = getRequestFactory().createRequest(
headers, body, uriInfo, requestType, resource);
+ LOG.info("Handling API Request: '" + request.getURI() + "'");
+
Result result = getRequestHandler(request.getRequestType()).handleRequest(request);
if (! result.getStatus().isErrorState()) {
request.getResultPostProcessor().process(result);
Modified: incubator/ambari/trunk/ambari-server/src/test/java/org/apache/ambari/server/api/predicate/QueryLexerTest.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-server/src/test/java/org/apache/ambari/server/api/predicate/QueryLexerTest.java?rev=1449165&r1=1449164&r2=1449165&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-server/src/test/java/org/apache/ambari/server/api/predicate/QueryLexerTest.java (original)
+++ incubator/ambari/trunk/ambari-server/src/test/java/org/apache/ambari/server/api/predicate/QueryLexerTest.java Fri Feb 22 18:45:02 2013
@@ -195,6 +195,79 @@ public class QueryLexerTest {
}
@Test
+ public void testTokens_ignore__multipleIgnoreFields() throws InvalidQueryException {
+ List<Token> listTokens = new ArrayList<Token>();
+ listTokens.add(new Token(Token.TYPE.RELATIONAL_OPERATOR, "="));
+ listTokens.add(new Token(Token.TYPE.PROPERTY_OPERAND, "foo"));
+ listTokens.add(new Token(Token.TYPE.VALUE_OPERAND, "1"));
+
+ QueryLexer lexer = new QueryLexer();
+ Token[] tokens = lexer.tokens("fields=a/b&foo=1&_=5555555");
+
+ assertArrayEquals(listTokens.toArray(new Token[listTokens.size()]), tokens);
+ }
+
+ @Test
+ public void testTokens_ignore__multipleConsecutiveIgnoreFields() throws InvalidQueryException {
+ List<Token> listTokens = new ArrayList<Token>();
+ listTokens.add(new Token(Token.TYPE.RELATIONAL_OPERATOR, "="));
+ listTokens.add(new Token(Token.TYPE.PROPERTY_OPERAND, "foo"));
+ listTokens.add(new Token(Token.TYPE.VALUE_OPERAND, "1"));
+
+ QueryLexer lexer = new QueryLexer();
+ Token[] tokens = lexer.tokens("foo=1&fields=a/b&_=5555555");
+
+ assertArrayEquals(listTokens.toArray(new Token[listTokens.size()]), tokens);
+ }
+
+ @Test
+ public void testTokens_ignore__multipleConsecutiveIgnoreFields2() throws InvalidQueryException {
+ List<Token> listTokens = new ArrayList<Token>();
+ listTokens.add(new Token(Token.TYPE.RELATIONAL_OPERATOR, "="));
+ listTokens.add(new Token(Token.TYPE.PROPERTY_OPERAND, "foo"));
+ listTokens.add(new Token(Token.TYPE.VALUE_OPERAND, "1"));
+
+ QueryLexer lexer = new QueryLexer();
+ Token[] tokens = lexer.tokens("fields=a/b&_=5555555&foo=1");
+
+ assertArrayEquals(listTokens.toArray(new Token[listTokens.size()]), tokens);
+ }
+
+ @Test
+ public void testTokens_ignore__fieldsMiddle() throws InvalidQueryException {
+ List<Token> listTokens = new ArrayList<Token>();
+ listTokens.add(new Token(Token.TYPE.RELATIONAL_OPERATOR, "="));
+ listTokens.add(new Token(Token.TYPE.PROPERTY_OPERAND, "foo"));
+ listTokens.add(new Token(Token.TYPE.VALUE_OPERAND, "1"));
+ listTokens.add(new Token(Token.TYPE.LOGICAL_OPERATOR, "&"));
+ listTokens.add(new Token(Token.TYPE.RELATIONAL_OPERATOR, "="));
+ listTokens.add(new Token(Token.TYPE.PROPERTY_OPERAND, "bar"));
+ listTokens.add(new Token(Token.TYPE.VALUE_OPERAND, "2"));
+
+ QueryLexer lexer = new QueryLexer();
+ Token[] tokens = lexer.tokens("foo=1&fields=a/b&bar=2");
+
+ assertArrayEquals(listTokens.toArray(new Token[listTokens.size()]), tokens);
+ }
+
+ @Test
+ public void testTokens_ignore__fieldsMiddle2() throws InvalidQueryException {
+ List<Token> listTokens = new ArrayList<Token>();
+ listTokens.add(new Token(Token.TYPE.RELATIONAL_OPERATOR, "="));
+ listTokens.add(new Token(Token.TYPE.PROPERTY_OPERAND, "foo"));
+ listTokens.add(new Token(Token.TYPE.VALUE_OPERAND, "1"));
+ listTokens.add(new Token(Token.TYPE.LOGICAL_OPERATOR, "&"));
+ listTokens.add(new Token(Token.TYPE.RELATIONAL_OPERATOR, "="));
+ listTokens.add(new Token(Token.TYPE.PROPERTY_OPERAND, "bar"));
+ listTokens.add(new Token(Token.TYPE.VALUE_OPERAND, "2"));
+
+ QueryLexer lexer = new QueryLexer();
+ Token[] tokens = lexer.tokens("foo=1&fields=a/b,c&_=123&bar=2");
+
+ assertArrayEquals(listTokens.toArray(new Token[listTokens.size()]), tokens);
+ }
+
+ @Test
public void testTokens_invalidRelationalOp() {
try {
new QueryLexer().tokens("foo=1&bar|5");