/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.ambari.server.controller.internal; import static org.easymock.EasyMock.anyString; import static org.easymock.EasyMock.capture; import static org.easymock.EasyMock.createMock; import static org.easymock.EasyMock.createStrictMock; import static org.easymock.EasyMock.eq; import static org.easymock.EasyMock.expect; import static org.easymock.EasyMock.getCurrentArguments; import static org.easymock.EasyMock.newCapture; import static org.easymock.EasyMock.replay; import static org.easymock.EasyMock.reset; import static org.easymock.EasyMock.verify; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; 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; import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeMap; import javax.persistence.EntityManager; import org.apache.ambari.server.controller.AmbariManagementController; import org.apache.ambari.server.controller.spi.Predicate; import org.apache.ambari.server.controller.spi.Request; import org.apache.ambari.server.controller.spi.RequestStatus; import org.apache.ambari.server.controller.spi.Resource; import org.apache.ambari.server.controller.utilities.PredicateBuilder; import org.apache.ambari.server.orm.dao.ArtifactDAO; import org.apache.ambari.server.orm.entities.ArtifactEntity; import org.apache.ambari.server.state.Cluster; import org.apache.ambari.server.state.Clusters; import org.easymock.Capture; import org.easymock.IAnswer; import org.junit.Before; import org.junit.Test; import com.google.gson.Gson; /** * ArtifactResourceProvider unit tests. */ @SuppressWarnings("unchecked") public class ArtifactResourceProviderTest { private ArtifactDAO dao = createStrictMock(ArtifactDAO.class); private EntityManager em = createStrictMock(EntityManager.class); private AmbariManagementController controller = createStrictMock(AmbariManagementController.class); private Request request = createMock(Request.class); private Clusters clusters = createMock(Clusters.class); private Cluster cluster = createMock(Cluster.class); private ArtifactEntity entity = createMock(ArtifactEntity.class); private ArtifactEntity entity2 = createMock(ArtifactEntity.class); ArtifactResourceProvider resourceProvider; @Before public void setUp() throws Exception { reset(dao, em, controller, request, clusters, cluster, entity, entity2); resourceProvider = new ArtifactResourceProvider(controller); setPrivateField(resourceProvider, "artifactDAO", dao); } @Test public void testGetResources_instance() throws Exception { Set<String> propertyIds = new HashSet<>(); TreeMap<String, String> foreignKeys = new TreeMap<>(); foreignKeys.put("cluster", "500"); Map<String, Object> childMap = new TreeMap<>(); childMap.put("childKey", "childValue"); Map<String, Object> child2Map = new TreeMap<>(); childMap.put("child2", child2Map); child2Map.put("child2Key", "child2Value"); Map<String, Object> child3Map = new TreeMap<>(); child2Map.put("child3", child3Map); Map<String, Object> child4Map = new TreeMap<>(); child3Map.put("child4", child4Map); child4Map.put("child4Key", "child4Value"); Map<String, Object> artifact_data = new TreeMap<>(); artifact_data.put("foo", "bar"); artifact_data.put("child", childMap); Map<String, String> responseForeignKeys = new HashMap<>(); responseForeignKeys.put("cluster", "500"); // expectations expect(controller.getClusters()).andReturn(clusters).anyTimes(); expect(clusters.getCluster("test-cluster")).andReturn(cluster).anyTimes(); expect(clusters.getClusterById(500L)).andReturn(cluster).anyTimes(); expect(cluster.getClusterId()).andReturn(500L).anyTimes(); expect(cluster.getClusterName()).andReturn("test-cluster").anyTimes(); expect(request.getPropertyIds()).andReturn(propertyIds).anyTimes(); expect(dao.findByNameAndForeignKeys(eq("test-artifact"), eq(foreignKeys))).andReturn(entity).once(); expect(entity.getArtifactName()).andReturn("test-artifact").anyTimes(); expect(entity.getForeignKeys()).andReturn(responseForeignKeys).anyTimes(); expect(entity.getArtifactData()).andReturn(artifact_data).anyTimes(); // end of expectation setting replay(dao, em, controller, request, clusters, cluster, entity, entity2); // test PredicateBuilder pb = new PredicateBuilder(); Predicate predicate = pb.begin().property("Artifacts/cluster_name").equals("test-cluster").and(). property("Artifacts/artifact_name").equals("test-artifact").end().toPredicate(); 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 public void testGetResources_collection() throws Exception { Set<String> propertyIds = new HashSet<>(); TreeMap<String, String> foreignKeys = new TreeMap<>(); foreignKeys.put("cluster", "500"); List<ArtifactEntity> entities = new ArrayList<>(); entities.add(entity); entities.add(entity2); Map<String, Object> artifact_data = Collections.<String, Object>singletonMap("foo", "bar"); Map<String, Object> artifact_data2 = Collections.<String, Object>singletonMap("foo2", "bar2"); Map<String, String> responseForeignKeys = new HashMap<>(); responseForeignKeys.put("cluster", "500"); // expectations expect(controller.getClusters()).andReturn(clusters).anyTimes(); expect(clusters.getCluster("test-cluster")).andReturn(cluster).anyTimes(); expect(clusters.getClusterById(500L)).andReturn(cluster).anyTimes(); expect(cluster.getClusterId()).andReturn(500L).anyTimes(); expect(cluster.getClusterName()).andReturn("test-cluster").anyTimes(); expect(request.getPropertyIds()).andReturn(propertyIds).anyTimes(); expect(dao.findByForeignKeys(eq(foreignKeys))).andReturn(entities).anyTimes(); expect(entity.getArtifactName()).andReturn("test-artifact").anyTimes(); expect(entity.getForeignKeys()).andReturn(responseForeignKeys).anyTimes(); expect(entity.getArtifactData()).andReturn(artifact_data).anyTimes(); expect(entity2.getArtifactName()).andReturn("test-artifact2").anyTimes(); expect(entity2.getForeignKeys()).andReturn(responseForeignKeys).anyTimes(); expect(entity2.getArtifactData()).andReturn(artifact_data2).anyTimes(); // end of expectation setting replay(dao, em, controller, request, clusters, cluster, entity, entity2); // test PredicateBuilder pb = new PredicateBuilder(); Predicate predicate = pb.begin().property("Artifacts/cluster_name").equals("test-cluster").end().toPredicate(); Set<Resource> response = resourceProvider.getResources(request, predicate); assertEquals(2, response.size()); boolean artifact1Returned = false; boolean artifact2Returned = false; for (Resource resource : response) { if (resource.getPropertyValue("Artifacts/artifact_name").equals("test-artifact")) { artifact1Returned = true; assertEquals("bar", resource.getPropertyValue("artifact_data/foo")); assertEquals("test-cluster", resource.getPropertyValue("Artifacts/cluster_name")); } else if (resource.getPropertyValue("Artifacts/artifact_name").equals("test-artifact2")) { artifact2Returned = true; assertEquals("bar2", resource.getPropertyValue("artifact_data/foo2")); assertEquals("test-cluster", resource.getPropertyValue("Artifacts/cluster_name")); } else { fail("unexpected artifact name"); } } assertTrue(artifact1Returned); assertTrue(artifact2Returned); } @Test public void testCreateResource() throws Exception { Capture<ArtifactEntity> createEntityCapture = newCapture(); Map<String, Object> outerMap = new TreeMap<>(); Map<String, Object> childMap = new TreeMap<>(); outerMap.put("child", childMap); childMap.put("childKey", "childValue"); Map<String, Object> child2Map = new TreeMap<>(); childMap.put("child2", child2Map); child2Map.put("child2Key", "child2Value"); Map<String, Object> child3Map = new TreeMap<>(); child2Map.put("child3", child3Map); Map<String, Object> child4Map = new TreeMap<>(); child3Map.put("child4", child4Map); child4Map.put("child4Key", "child4Value"); Set<Map<String, Object>> propertySet = new HashSet<>(); propertySet.add(outerMap); propertySet.add(child4Map); Map<String, Object> artifact_data = new TreeMap<>(); artifact_data.put("foo", "bar"); artifact_data.put("child", childMap); artifact_data.put("collection", propertySet); TreeMap<String, String> foreignKeys = new TreeMap<>(); foreignKeys.put("cluster", "500"); Map<String, String> requestInfoProps = new HashMap<>(); requestInfoProps.put(Request.REQUEST_INFO_BODY_PROPERTY, bodyJson); // map with flattened properties Map<String, Object> properties = new HashMap<>(); 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<>(); properties.put("artifact_data/collection", collectionProperties); // collection with maps of flattened properties Map<String, Object> map1 = new TreeMap<>(); 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<>(); 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(); expect(clusters.getClusterById(500L)).andReturn(cluster).anyTimes(); expect(cluster.getClusterId()).andReturn(500L).anyTimes(); expect(cluster.getClusterName()).andReturn("test-cluster").anyTimes(); // check to see if entity already exists expect(dao.findByNameAndForeignKeys(eq("test-artifact"), eq(foreignKeys))).andReturn(null).once(); // create dao.create(capture(createEntityCapture)); // end of expectation setting replay(dao, em, controller, request, clusters, cluster, entity, entity2); resourceProvider.createResources(request); ArtifactEntity createEntity = createEntityCapture.getValue(); assertEquals("test-artifact", createEntity.getArtifactName()); 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()); } @Test public void testUpdateResources() throws Exception { Map<String, String> requestInfoProps = new HashMap<>(); requestInfoProps.put(Request.REQUEST_INFO_BODY_PROPERTY, bodyJson); Capture<ArtifactEntity> updateEntityCapture = newCapture(); Capture<ArtifactEntity> updateEntityCapture2 = newCapture(); Set<String> propertyIds = new HashSet<>(); TreeMap<String, String> foreignKeys = new TreeMap<>(); foreignKeys.put("cluster", "500"); List<ArtifactEntity> entities = new ArrayList<>(); entities.add(entity); entities.add(entity2); Map<String, Object> artifact_data = Collections.<String, Object>singletonMap("foo", "bar"); Map<String, Object> artifact_data2 = Collections.<String, Object>singletonMap("foo2", "bar2"); Map<String, String> responseForeignKeys = new HashMap<>(); responseForeignKeys.put("cluster", "500"); // map with flattened properties Map<String, Object> properties = new HashMap<>(); 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"); Set<Map<String, Object>> requestProperties = Collections.singleton(properties); properties.put("artifact_data/collection", Collections.emptySet()); // expectations expect(request.getProperties()).andReturn(requestProperties).anyTimes(); expect(request.getRequestInfoProperties()).andReturn(requestInfoProps).anyTimes(); expect(controller.getClusters()).andReturn(clusters).anyTimes(); expect(clusters.getCluster("test-cluster")).andReturn(cluster).anyTimes(); expect(clusters.getClusterById(500L)).andReturn(cluster).anyTimes(); expect(cluster.getClusterId()).andReturn(500L).anyTimes(); expect(cluster.getClusterName()).andReturn("test-cluster").anyTimes(); expect(request.getPropertyIds()).andReturn(propertyIds).anyTimes(); expect(dao.findByForeignKeys(eq(foreignKeys))).andReturn(entities).anyTimes(); expect(entity.getArtifactName()).andReturn("test-artifact").anyTimes(); expect(entity.getForeignKeys()).andReturn(responseForeignKeys).anyTimes(); expect(entity.getArtifactData()).andReturn(artifact_data).anyTimes(); expect(entity2.getArtifactName()).andReturn("test-artifact2").anyTimes(); expect(entity2.getForeignKeys()).andReturn(responseForeignKeys).anyTimes(); expect(entity2.getArtifactData()).andReturn(artifact_data2).anyTimes(); expect(dao.merge(capture(updateEntityCapture))).andReturn(entity).once(); expect(dao.merge(capture(updateEntityCapture2))).andReturn(entity2).once(); // end of expectation setting replay(dao, em, controller, request, clusters, cluster, entity, entity2); PredicateBuilder pb = new PredicateBuilder(); Predicate predicate = pb.begin().property("Artifacts/cluster_name").equals("test-cluster").end().toPredicate(); RequestStatus response = resourceProvider.updateResources(request, predicate); ArtifactEntity updateEntity = updateEntityCapture.getValue(); ArtifactEntity updateEntity2 = updateEntityCapture2.getValue(); Gson serializer = new Gson(); ArtifactEntity expected = new ArtifactEntity(); expected.setArtifactData((Map<String, Object>) serializer.<Map<String, Object>>fromJson( bodyJson, Map.class).get("artifact_data")); assertEquals(expected.getArtifactData(), updateEntity.getArtifactData()); assertEquals(expected.getArtifactData(), updateEntity2.getArtifactData()); if (updateEntity.getArtifactName().equals("test-artifact")) { assertEquals("test-artifact2",updateEntity2.getArtifactName() ); } else if (updateEntity.getArtifactName().equals("test-artifact2")) { assertEquals("test-artifact", updateEntity2.getArtifactName()); } else { fail ("Unexpected artifact name: " + updateEntity.getArtifactName()); } assertEquals(foreignKeys, updateEntity.getForeignKeys()); assertEquals(foreignKeys, updateEntity2.getForeignKeys()); assertEquals(RequestStatus.Status.Complete, response.getStatus()); verify(dao, em, controller, request, clusters, cluster, entity, entity2); } @Test public void testDeleteResources() throws Exception { Capture<ArtifactEntity> deleteEntityCapture = newCapture(); Capture<ArtifactEntity> deleteEntityCapture2 = newCapture(); TreeMap<String, String> foreignKeys = new TreeMap<>(); foreignKeys.put("cluster", "500"); List<ArtifactEntity> entities = new ArrayList<>(); entities.add(entity); entities.add(entity2); Map<String, Object> artifact_data = Collections.<String, Object>singletonMap("foo", "bar"); Map<String, Object> artifact_data2 = Collections.<String, Object>singletonMap("foo2", "bar2"); Map<String, String> responseForeignKeys = new HashMap<>(); responseForeignKeys.put("cluster", "500"); // expectations expect(controller.getClusters()).andReturn(clusters).anyTimes(); expect(clusters.getCluster("test-cluster")).andReturn(cluster).anyTimes(); expect(clusters.getClusterById(500L)).andReturn(cluster).anyTimes(); expect(cluster.getClusterId()).andReturn(500L).anyTimes(); expect(cluster.getClusterName()).andReturn("test-cluster").anyTimes(); expect(entity.getArtifactName()).andReturn("test-artifact").anyTimes(); expect(entity.getForeignKeys()).andReturn(responseForeignKeys).anyTimes(); expect(entity.getArtifactData()).andReturn(artifact_data).anyTimes(); expect(entity2.getArtifactName()).andReturn("test-artifact2").anyTimes(); expect(entity2.getForeignKeys()).andReturn(responseForeignKeys).anyTimes(); expect(entity2.getArtifactData()).andReturn(artifact_data2).anyTimes(); IAnswer<ArtifactEntity> findByNameAndForeignKeys = new IAnswer<ArtifactEntity>() { @Override public ArtifactEntity answer() throws Throwable { String artifactName = (String) getCurrentArguments()[0]; if ("test-artifact".equals(artifactName)) { return entity; } else if ("test-artifact2".equals(artifactName)) { return entity2; } else { return null; } } }; expect(dao.findByForeignKeys(eq(foreignKeys))).andReturn(entities).once(); expect(dao.findByNameAndForeignKeys(anyString(), eq(foreignKeys))).andAnswer(findByNameAndForeignKeys).once(); dao.remove(capture(deleteEntityCapture)); expect(dao.findByNameAndForeignKeys(anyString(), eq(foreignKeys))).andAnswer(findByNameAndForeignKeys).once(); dao.remove(capture(deleteEntityCapture2)); // end of expectation setting replay(dao, em, controller, request, clusters, cluster, entity, entity2); PredicateBuilder pb = new PredicateBuilder(); Predicate predicate = pb.begin().property("Artifacts/cluster_name").equals("test-cluster").end().toPredicate(); RequestStatus response = resourceProvider.deleteResources(new RequestImpl(null, null, null, null), predicate); ArtifactEntity deleteEntity = deleteEntityCapture.getValue(); ArtifactEntity deleteEntity2 = deleteEntityCapture2.getValue(); if (deleteEntity.getArtifactName().equals("test-artifact")) { assertEquals("test-artifact2", deleteEntity2.getArtifactName()); } else if (deleteEntity.getArtifactName().equals("test-artifact2")) { assertEquals("test-artifact", deleteEntity2.getArtifactName()); } else { fail ("Unexpected artifact name: " + deleteEntity.getArtifactName()); } assertEquals(foreignKeys, deleteEntity.getForeignKeys()); assertEquals(foreignKeys, deleteEntity2.getForeignKeys()); assertEquals(RequestStatus.Status.Complete, response.getStatus()); verify(dao, em, controller, request, clusters, cluster, entity, entity2); } private void setPrivateField(Object o, String field, Object value) throws Exception{ Class<?> c = o.getClass(); Field f = c.getDeclaredField(field); f.setAccessible(true); f.set(o, value); } private 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\"" + " } " + " ]" + " }" + "}"; }