Repository: ambari
Updated Branches:
  refs/heads/trunk 9f296a25c -> 0edce3c4f


AMBARI-8605 Query predicate .matches doesn't work for stacks endpoint with 
passed logical OR(URL-encoding) (dsen)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/0edce3c4
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/0edce3c4
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/0edce3c4

Branch: refs/heads/trunk
Commit: 0edce3c4f275b2ebca042e1fd8fb877acb7c5336
Parents: f77be4c
Author: Dmytro Sen <d...@apache.org>
Authored: Thu Jan 22 18:24:19 2015 +0200
Committer: Dmytro Sen <d...@apache.org>
Committed: Thu Jan 22 19:23:35 2015 +0200

----------------------------------------------------------------------
 .../api/services/ResultPostProcessorImpl.java   | 13 +++++-
 .../server/api/services/StacksService.java      | 47 ++++++++++++++------
 .../server/api/services/StacksServiceTest.java  | 19 +++++++-
 3 files changed, 63 insertions(+), 16 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/0edce3c4/ambari-server/src/main/java/org/apache/ambari/server/api/services/ResultPostProcessorImpl.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/api/services/ResultPostProcessorImpl.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ResultPostProcessorImpl.java
index 8d17846..61afee2 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/api/services/ResultPostProcessorImpl.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ResultPostProcessorImpl.java
@@ -61,7 +61,18 @@ public class ResultPostProcessorImpl implements 
ResultPostProcessor {
 
   @Override
   public void process(Result result) {
-    processNode(result.getResultTree(), m_request.getURI());
+    // Decode query string only
+    // Path should not be decoded here (username can contain '?')
+    String href = m_request.getURI();
+    int pos = href.indexOf('?');
+    if (pos != -1) {
+      try {
+        href = href.substring(0, pos + 1) + 
URLDecoder.decode(href.substring(pos + 1), "UTF-8");
+      } catch (UnsupportedEncodingException e) {
+        throw new RuntimeException("Unable to decode URI: " + e, e);
+      }
+    }
+    processNode(result.getResultTree(), href);
   }
 
   /**

http://git-wip-us.apache.org/repos/asf/ambari/blob/0edce3c4/ambari-server/src/main/java/org/apache/ambari/server/api/services/StacksService.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/api/services/StacksService.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/api/services/StacksService.java
index 366accf..74c7b57 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/api/services/StacksService.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/api/services/StacksService.java
@@ -22,6 +22,7 @@ import java.io.UnsupportedEncodingException;
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.net.URLDecoder;
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
@@ -42,6 +43,9 @@ import javax.ws.rs.core.UriInfo;
 import org.apache.ambari.server.api.predicate.QueryLexer;
 import org.apache.ambari.server.api.resources.ResourceInstance;
 import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.http.NameValuePair;
+import org.apache.http.client.utils.URLEncodedUtils;
+import org.apache.http.message.BasicNameValuePair;
 
 /**
  * Service for stacks management.
@@ -426,23 +430,38 @@ public class StacksService extends BaseService {
       return m_delegate.getPathSegments(b);
     }
 
+    /**
+     * Converts the new corrected property names to the old names for the 
backend.
+     * Because both the /stacks and /stacks2 api use the same underlying 
classes, we
+     * need to convert the new corrected property names to the old names for 
the backend.
+     * This should be removed when /stacks2 is removed and we can change the 
property names
+     * in the resource definitions to the new form.
+     */
+    private String normalizeComponentNames(String value) {
+      if (value == null) {
+        return null;
+      }
+      value = value.replaceAll("services/", "stackServices/");
+      value = value.replaceAll("components/", "serviceComponents/");
+      value = value.replaceAll("operating_systems/", "operatingSystems/");
+      return value;
+    }
+
     @Override
     public URI getRequestUri() {
-      String uri;
-      try {
-        uri = URLDecoder.decode(m_delegate.getRequestUri().toASCIIString(), 
"UTF-8");
-      } catch (UnsupportedEncodingException e) {
-        throw new RuntimeException("Unable to decode URI: " + e, e);
-      }
-      uri = uri.replaceAll("services/", "stackServices/");
-      uri = uri.replaceAll("components/", "serviceComponents/");
-      uri = uri.replaceAll("operating_systems/", "operatingSystems/");
-
-      try {
-        return new URI(uri);
-      } catch (URISyntaxException e) {
-        throw new RuntimeException("Unable to create modified stacks URI: " + 
e, e);
+      String uriPath = m_delegate.getRequestUri().getPath();
+      UriBuilder uriBuilder = UriBuilder.fromUri(m_delegate.getRequestUri());
+      List<NameValuePair> parametersList = 
URLEncodedUtils.parse(m_delegate.getRequestUri(), "UTF-8");
+      List<NameValuePair> newQuery = new ArrayList<NameValuePair>();
+      for (NameValuePair nameValuePair : parametersList) {
+        newQuery.add(new 
BasicNameValuePair(normalizeComponentNames(nameValuePair.getName()),
+            normalizeComponentNames(nameValuePair.getValue())));
       }
+
+      uriBuilder.replacePath(normalizeComponentNames(uriPath));
+      uriBuilder.replaceQuery(URLEncodedUtils.format(newQuery, "UTF-8"));
+
+      return uriBuilder.build();
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/ambari/blob/0edce3c4/ambari-server/src/test/java/org/apache/ambari/server/api/services/StacksServiceTest.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/test/java/org/apache/ambari/server/api/services/StacksServiceTest.java
 
b/ambari-server/src/test/java/org/apache/ambari/server/api/services/StacksServiceTest.java
index e5be477..c36c6d9 100644
--- 
a/ambari-server/src/test/java/org/apache/ambari/server/api/services/StacksServiceTest.java
+++ 
b/ambari-server/src/test/java/org/apache/ambari/server/api/services/StacksServiceTest.java
@@ -21,17 +21,22 @@ package org.apache.ambari.server.api.services;
 import org.apache.ambari.server.api.resources.ResourceInstance;
 import org.apache.ambari.server.api.services.parsers.RequestBodyParser;
 import org.apache.ambari.server.api.services.serializers.ResultSerializer;
+import org.easymock.EasyMock;
+import org.junit.Test;
+
 
 import javax.ws.rs.PathParam;
 import javax.ws.rs.core.Context;
 import javax.ws.rs.core.HttpHeaders;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.UriInfo;
-
 import java.lang.reflect.Method;
+import java.net.URI;
+import java.net.URISyntaxException;
 import java.util.ArrayList;
 import java.util.List;
 
+
 import static org.easymock.EasyMock.expect;
 import static org.easymock.EasyMock.notNull;
 import static org.easymock.EasyMock.same;
@@ -215,4 +220,16 @@ public class StacksServiceTest extends BaseServiceTest {
     expect(requestFactory.createRequest(same(httpHeaders), same(requestBody), 
(UriInfo) notNull(),
         same(testMethod.getRequestType()), 
same(resourceInstance))).andReturn(request);
   }
+
+  @Test
+  public void testStackUriInfo() throws URISyntaxException {
+
+    UriInfo delegate = new LocalUriInfo("http://host/services/?fields=*";);
+    StacksService.StackUriInfo sui = new StacksService.StackUriInfo(delegate);
+    assertEquals(new URI("http://host/stackServices/?fields=*";), 
sui.getRequestUri());
+
+    delegate = new 
LocalUriInfo("http://host/?condition1=true&condition2=true&services/service.matches(A%7CB)");
+    sui = new StacksService.StackUriInfo(delegate);
+    assertEquals(new 
URI("http://host/?condition1=true&condition2=true&stackServices%2Fservice.matches%28A%7CB%29";),
 sui.getRequestUri());
+  }
 }

Reply via email to