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 2015/01/21 23:45:11 UTC
ambari git commit: AMBARI-9243. Preserve nested map structures for
artifact resource data
Repository: ambari
Updated Branches:
refs/heads/trunk 07c78ba39 -> fcc6a4ccf
AMBARI-9243. Preserve nested map structures for artifact resource data
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/fcc6a4cc
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/fcc6a4cc
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/fcc6a4cc
Branch: refs/heads/trunk
Commit: fcc6a4ccf7bd4e49e5ad0d6062c0ce727183b4b2
Parents: 07c78ba
Author: John Speidel <js...@hortonworks.com>
Authored: Wed Jan 21 13:23:45 2015 -0500
Committer: John Speidel <js...@hortonworks.com>
Committed: Wed Jan 21 17:45:00 2015 -0500
----------------------------------------------------------------------
.../ambari/server/api/services/RequestBody.java | 2 +
.../internal/ArtifactResourceProvider.java | 37 +++---
.../ambari/server/controller/spi/Request.java | 4 +
.../parsers/JsonRequestBodyParserTest.java | 3 +-
.../internal/ArtifactResourceProviderTest.java | 120 ++++++++++++++++++-
5 files changed, 146 insertions(+), 20 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/fcc6a4cc/ambari-server/src/main/java/org/apache/ambari/server/api/services/RequestBody.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/RequestBody.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/RequestBody.java
index f4c5647..548922d 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/RequestBody.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/RequestBody.java
@@ -144,12 +144,14 @@ public class RequestBody {
/**
* Set the body from the request.
+ * Also sets the body as a request info property.
*
* @param body the request body
*/
public void setBody(String body) {
if (body != null && ! body.isEmpty()) {
m_body = body;
+ m_requestInfoProps.put("RAW_REQUEST_BODY", body);
}
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/fcc6a4cc/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ArtifactResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ArtifactResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ArtifactResourceProvider.java
index b3eb159..e476f62 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ArtifactResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ArtifactResourceProvider.java
@@ -18,6 +18,7 @@
package org.apache.ambari.server.controller.internal;
+import com.google.gson.Gson;
import com.google.inject.Inject;
import org.apache.ambari.server.AmbariException;
import org.apache.ambari.server.DuplicateResourceException;
@@ -105,6 +106,11 @@ public class ArtifactResourceProvider extends AbstractResourceProvider {
new HashMap<String, TypeRegistration>();
/**
+ * serializer used to convert json to map
+ */
+ private static final Gson jsonSerializer = new Gson();
+
+ /**
* artifact data access object
*/
@Inject
@@ -181,7 +187,7 @@ public class ArtifactResourceProvider extends AbstractResourceProvider {
NoSuchParentResourceException {
for (Map<String, Object> properties : request.getProperties()) {
- createResources(getCreateCommand(properties));
+ createResources(getCreateCommand(properties, request.getRequestInfoProperties()));
}
notifyCreate(Resource.Type.Artifact, request);
@@ -232,11 +238,13 @@ public class ArtifactResourceProvider extends AbstractResourceProvider {
/**
* Create a command to create the resource.
*
- * @param properties request properties
+ * @param properties request properties
+ * @param requestInfoProps request info properties
*
* @return a new create command
*/
- private Command<Void> getCreateCommand(final Map<String, Object> properties) {
+ private Command<Void> getCreateCommand(final Map<String, Object> properties,
+ final Map<String, String> requestInfoProps) {
return new Command<Void>() {
@Override
public Void invoke() throws AmbariException {
@@ -255,7 +263,7 @@ public class ArtifactResourceProvider extends AbstractResourceProvider {
LOG.debug("Creating Artifact Resource with name '{}'. Parent information: {}",
artifactName, getRequestForeignKeys(properties));
- artifactDAO.create(toEntity(properties));
+ artifactDAO.create(toEntity(properties, requestInfoProps.get(Request.REQUEST_INFO_BODY_PROPERTY)));
return null;
}
@@ -369,7 +377,8 @@ public class ArtifactResourceProvider extends AbstractResourceProvider {
*
* @return new artifact entity
*/
- private ArtifactEntity toEntity(Map<String, Object> properties)
+ @SuppressWarnings("unchecked")
+ private ArtifactEntity toEntity(Map<String, Object> properties, String rawRequestBody)
throws AmbariException {
String name = (String) properties.get(ARTIFACT_NAME_PROPERTY);
@@ -379,17 +388,17 @@ public class ArtifactResourceProvider extends AbstractResourceProvider {
ArtifactEntity artifact = new ArtifactEntity();
artifact.setArtifactName(name);
- Map<String, Object> dataMap = new HashMap<String, Object>();
- for (Map.Entry<String, Object> entry : properties.entrySet()) {
- String key = entry.getKey();
- //todo: should we handle scalar value?
- if (key.startsWith(ARTIFACT_DATA_PROPERTY)) {
- dataMap.put(key.split("/")[1], entry.getValue());
- }
- }
- artifact.setArtifactData(dataMap);
artifact.setForeignKeys(createForeignKeyMap(properties));
+ Map<String, Object> rawBodyMap = jsonSerializer.<Map<String, Object>>fromJson(
+ rawRequestBody, Map.class);
+
+ Object artifactData = rawBodyMap.get(ARTIFACT_DATA_PROPERTY);
+ if (! (artifactData instanceof Map)) {
+ throw new IllegalArgumentException("artifact_data property must be a map");
+ }
+ artifact.setArtifactData((Map<String, Object>) artifactData);
+
return artifact;
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/fcc6a4cc/ambari-server/src/main/java/org/apache/ambari/server/controller/spi/Request.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/spi/Request.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/spi/Request.java
index f937a4c..50eed9a 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/spi/Request.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/spi/Request.java
@@ -26,6 +26,10 @@ import java.util.Set;
* temporal (date range) information, if any, for each requested property.
*/
public interface Request {
+ /**
+ * Constant for request info property which contains the raw request body.
+ */
+ public static final String REQUEST_INFO_BODY_PROPERTY = "RAW_REQUEST_BODY";
/**
* Get the set of property ids being requested. Used for requests to get
http://git-wip-us.apache.org/repos/asf/ambari/blob/fcc6a4cc/ambari-server/src/test/java/org/apache/ambari/server/api/services/parsers/JsonRequestBodyParserTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/api/services/parsers/JsonRequestBodyParserTest.java b/ambari-server/src/test/java/org/apache/ambari/server/api/services/parsers/JsonRequestBodyParserTest.java
index 8b78524..f89b1b3 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/api/services/parsers/JsonRequestBodyParserTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/api/services/parsers/JsonRequestBodyParserTest.java
@@ -552,10 +552,11 @@ public class JsonRequestBodyParserTest {
assertEquals("foo=bar", body.getQueryString());
Map<String, String > mapRequestInfoProps = body.getRequestInfoProperties();
- assertEquals(3, mapRequestInfoProps.size());
+ assertEquals(4, mapRequestInfoProps.size());
assertEquals("val1", mapRequestInfoProps.get("prop1"));
assertEquals("val2", mapRequestInfoProps.get("prop2"));
assertEquals("foo=bar", mapRequestInfoProps.get("query"));
+ assertEquals(bodyWithRequestInfoProperties, mapRequestInfoProps.get("RAW_REQUEST_BODY"));
//assert body is correct by checking that properties match
String b = body.getBody();
http://git-wip-us.apache.org/repos/asf/ambari/blob/fcc6a4cc/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ArtifactResourceProviderTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ArtifactResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ArtifactResourceProviderTest.java
index 4ed1a51..046c5d8 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ArtifactResourceProviderTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ArtifactResourceProviderTest.java
@@ -35,6 +35,7 @@ import javax.persistence.EntityManager;
import java.lang.reflect.Field;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
@@ -62,7 +63,7 @@ public class ArtifactResourceProviderTest {
private ArtifactDAO dao = createStrictMock(ArtifactDAO.class);
private EntityManager em = createStrictMock(EntityManager.class);
private AmbariManagementController controller = createStrictMock(AmbariManagementController.class);
- private Request request = createStrictMock(Request.class);
+ private Request request = createMock(Request.class);
private Clusters clusters = createStrictMock(Clusters.class);
private Cluster cluster = createStrictMock(Cluster.class);
private ArtifactEntity entity = createMock(ArtifactEntity.class);
@@ -83,7 +84,20 @@ public class ArtifactResourceProviderTest {
TreeMap<String, String> foreignKeys = new TreeMap<String, String>();
foreignKeys.put("cluster", "500");
- Map<String, Object> artifact_data = Collections.<String, Object>singletonMap("foo", "bar");
+ Map<String, Object> childMap = new TreeMap<String, Object>();
+ childMap.put("childKey", "childValue");
+ Map<String, Object> child2Map = new TreeMap<String, Object>();
+ childMap.put("child2", child2Map);
+ child2Map.put("child2Key", "child2Value");
+ Map<String, Object> child3Map = new TreeMap<String, Object>();
+ child2Map.put("child3", child3Map);
+ Map<String, Object> child4Map = new TreeMap<String, Object>();
+ child3Map.put("child4", child4Map);
+ child4Map.put("child4Key", "child4Value");
+
+ Map<String, Object> artifact_data = new TreeMap<String, Object>();
+ artifact_data.put("foo", "bar");
+ artifact_data.put("child", childMap);
Map<String, String> responseForeignKeys = new HashMap<String, String>();
responseForeignKeys.put("cluster", "500");
@@ -113,9 +127,18 @@ public class ArtifactResourceProviderTest {
Set<Resource> response = resourceProvider.getResources(request, predicate);
assertEquals(1, response.size());
Resource resource = response.iterator().next();
+ Map<String, Map<String, Object>> responseProperties = resource.getPropertiesMap();
+ assertEquals(5, responseProperties.size());
+
+ Map<String, Object> artifactDataMap = responseProperties.get("artifact_data");
+ assertEquals("bar", artifactDataMap.get("foo"));
+
assertEquals("test-artifact", resource.getPropertyValue("Artifacts/artifact_name"));
assertEquals("test-cluster", resource.getPropertyValue("Artifacts/cluster_name"));
assertEquals("bar", resource.getPropertyValue("artifact_data/foo"));
+ assertEquals("childValue", resource.getPropertyValue("artifact_data/child/childKey"));
+ assertEquals("child2Value", resource.getPropertyValue("artifact_data/child/child2/child2Key"));
+ assertEquals("child4Value", resource.getPropertyValue("artifact_data/child/child2/child3/child4/child4Key"));
}
@Test
@@ -183,19 +206,100 @@ public class ArtifactResourceProviderTest {
@Test
public void testCreateResource() throws Exception {
Capture<ArtifactEntity> createEntityCapture = new Capture<ArtifactEntity>();
-
- Map<String, Object> artifact_data = Collections.<String, Object>singletonMap("foo", "bar");
+ Map<String, Object> outerMap = new TreeMap<String, Object>();
+ Map<String, Object> childMap = new TreeMap<String, Object>();
+ outerMap.put("child", childMap);
+ childMap.put("childKey", "childValue");
+ Map<String, Object> child2Map = new TreeMap<String, Object>();
+ childMap.put("child2", child2Map);
+ child2Map.put("child2Key", "child2Value");
+ Map<String, Object> child3Map = new TreeMap<String, Object>();
+ child2Map.put("child3", child3Map);
+ Map<String, Object> child4Map = new TreeMap<String, Object>();
+ child3Map.put("child4", child4Map);
+ child4Map.put("child4Key", "child4Value");
+
+ Set<Map<String, Object>> propertySet = new HashSet<Map<String, Object>>();
+ propertySet.add(outerMap);
+ propertySet.add(child4Map);
+
+ Map<String, Object> artifact_data = new TreeMap<String, Object>();
+ artifact_data.put("foo", "bar");
+ artifact_data.put("child", childMap);
+ artifact_data.put("collection", propertySet);
TreeMap<String, String> foreignKeys = new TreeMap<String, String>();
foreignKeys.put("cluster", "500");
+
+ String bodyJson =
+ "{ " +
+ " \"artifact_data\" : {" +
+ " \"foo\" : \"bar\"," +
+ " \"child\" : {" +
+ " \"childKey\" : \"childValue\"," +
+ " \"child2\" : {" +
+ " \"child2Key\" : \"child2Value\"," +
+ " \"child3\" : {" +
+ " \"child4\" : {" +
+ " \"child4Key\" : \"child4Value\"" +
+ " }" +
+ " }" +
+ " }" +
+ " }," +
+ " \"collection\" : [" +
+ " {" +
+ " \"child\" : {" +
+ " \"childKey\" : \"childValue\"," +
+ " \"child2\" : {" +
+ " \"child2Key\" : \"child2Value\"," +
+ " \"child3\" : {" +
+ " \"child4\" : {" +
+ " \"child4Key\" : \"child4Value\"" +
+ " }" +
+ " }" +
+ " }" +
+ " }" +
+ " }," +
+ " {" +
+ " \"child4Key\" : \"child4Value\"" +
+ " } " +
+ " ]" +
+ " }" +
+ "}";
+
+ Map<String, String> requestInfoProps = new HashMap<String, String>();
+ requestInfoProps.put(Request.REQUEST_INFO_BODY_PROPERTY, bodyJson);
+
+
+ // map with flattened properties
Map<String, Object> properties = new HashMap<String, Object>();
properties.put("Artifacts/artifact_name", "test-artifact");
properties.put("Artifacts/cluster_name", "test-cluster");
properties.put("artifact_data/foo", "bar");
+ properties.put("artifact_data/child/childKey", "childValue");
+ properties.put("artifact_data/child/child2/child2Key", "child2Value");
+ properties.put("artifact_data/child/child2/child3/child4/child4Key", "child4Value");
+
+ Collection<Object> collectionProperties = new HashSet<Object>();
+ properties.put("artifact_data/collection", collectionProperties);
+
+ // collection with maps of flattened properties
+ Map<String, Object> map1 = new TreeMap<String, Object>();
+ collectionProperties.add(map1);
+ map1.put("foo", "bar");
+ map1.put("child/childKey", "childValue");
+ map1.put("child/child2/child2Key", "child2Value");
+ map1.put("child/child2/child3/child4/child4Key", "child4Value");
+
+ Map<String, Object> map2 = new TreeMap<String, Object>();
+ collectionProperties.add(map2);
+ map2.put("child4Key", "child4Value");
+
Set<Map<String, Object>> requestProperties = Collections.singleton(properties);
// expectations
+ expect(request.getRequestInfoProperties()).andReturn(requestInfoProps).anyTimes();
expect(request.getProperties()).andReturn(requestProperties).anyTimes();
expect(controller.getClusters()).andReturn(clusters).anyTimes();
expect(clusters.getCluster("test-cluster")).andReturn(cluster).anyTimes();
@@ -215,7 +319,13 @@ public class ArtifactResourceProviderTest {
ArtifactEntity createEntity = createEntityCapture.getValue();
assertEquals("test-artifact", createEntity.getArtifactName());
- assertEquals(createEntity.getArtifactData(), artifact_data);
+ Map<String, Object> actualArtifactData = createEntity.getArtifactData();
+ // need to decompose actualArtifactData because actualArtifactData.get("collection") returns a set
+ // implementation that does not equal an identical(same elements) HashSet instance
+ assertEquals(artifact_data.size(), actualArtifactData.size());
+ assertEquals(artifact_data.get("foo"), actualArtifactData.get("foo"));
+ assertEquals(artifact_data.get("child"), actualArtifactData.get("child"));
+ assertEquals(artifact_data.get("collection"), new HashSet(((Collection) actualArtifactData.get("collection"))));
assertEquals(foreignKeys, createEntity.getForeignKeys());
}