http://git-wip-us.apache.org/repos/asf/ambari/blob/4fa9ac55/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AmbariConfigurationResourceProviderTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AmbariConfigurationResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AmbariConfigurationResourceProviderTest.java index c2a1421..a2ecb27 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AmbariConfigurationResourceProviderTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AmbariConfigurationResourceProviderTest.java @@ -14,238 +14,364 @@ package org.apache.ambari.server.controller.internal; +import static org.apache.ambari.server.controller.internal.AmbariConfigurationResourceProvider.AMBARI_CONFIGURATION_CATEGORY_PROPERTY_ID; +import static org.apache.ambari.server.controller.internal.AmbariConfigurationResourceProvider.AMBARI_CONFIGURATION_PROPERTIES_PROPERTY_ID; +import static org.easymock.EasyMock.anyObject; +import static org.easymock.EasyMock.capture; +import static org.easymock.EasyMock.eq; +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.expectLastCall; +import static org.easymock.EasyMock.newCapture; + +import java.util.ArrayList; +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.spi.Predicate; import org.apache.ambari.server.controller.spi.Request; import org.apache.ambari.server.controller.spi.Resource; +import org.apache.ambari.server.controller.spi.ResourceProvider; import org.apache.ambari.server.controller.utilities.PredicateBuilder; -import org.apache.ambari.server.events.AmbariLdapConfigChangedEvent; +import org.apache.ambari.server.events.AmbariConfigurationChangedEvent; import org.apache.ambari.server.events.publishers.AmbariEventPublisher; import org.apache.ambari.server.orm.dao.AmbariConfigurationDAO; import org.apache.ambari.server.orm.entities.AmbariConfigurationEntity; -import org.apache.ambari.server.orm.entities.ConfigurationBaseEntity; +import org.apache.ambari.server.security.TestAuthenticationFactory; +import org.apache.ambari.server.security.authorization.AuthorizationException; import org.easymock.Capture; -import org.easymock.EasyMock; -import org.easymock.EasyMockRule; import org.easymock.EasyMockSupport; -import org.easymock.Mock; -import org.easymock.TestSubject; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Rule; +import org.junit.After; import org.junit.Test; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; +import com.google.inject.AbstractModule; +import com.google.inject.Guice; +import com.google.inject.Injector; public class AmbariConfigurationResourceProviderTest extends EasyMockSupport { - @Rule - public EasyMockRule mocks = new EasyMockRule(this); + private static final String CATEGORY_NAME_1 = "test-category-1"; + private static final String CATEGORY_NAME_2 = "test-category-2"; - @Mock - private Request requestMock; + @After + public void clearAuthentication() { + SecurityContextHolder.getContext().setAuthentication(null); + } - @Mock - private AmbariConfigurationDAO ambariConfigurationDAO; + @Test + public void testCreateResources_Administrator() throws Exception { + testCreateResources(TestAuthenticationFactory.createAdministrator()); + } - @Mock - private AmbariEventPublisher publisher; + @Test(expected = AuthorizationException.class) + public void testCreateResources_ClusterAdministrator() throws Exception { + testCreateResources(TestAuthenticationFactory.createClusterAdministrator()); + } - private Capture<AmbariConfigurationEntity> ambariConfigurationEntityCapture; + @Test(expected = AuthorizationException.class) + public void testCreateResources_ClusterOperator() throws Exception { + testCreateResources(TestAuthenticationFactory.createClusterOperator()); + } - private Gson gson; + @Test(expected = AuthorizationException.class) + public void testCreateResources_ServiceAdministrator() throws Exception { + testCreateResources(TestAuthenticationFactory.createServiceAdministrator()); + } - private static final String DATA_MOCK_STR = "[\n" + - " {\n" + - " \"authentication.ldap.baseDn\" : \"dc=ambari,dc=apache,dc=org\",\n" + - " \"authentication.ldap.primaryUrl\" : \"localhost:33389\",\n" + - " \"authentication.ldap.secondaryUrl\" : \"localhost:333\"\n" + - " }\n" + - " ]"; + @Test(expected = AuthorizationException.class) + public void testCreateResources_ServiceOperator() throws Exception { + testCreateResources(TestAuthenticationFactory.createServiceOperator()); + } - private static final Long PK_LONG = Long.valueOf(1); - private static final String PK_STRING = String.valueOf(1); - private static final String VERSION_TAG = "test version"; - private static final String VERSION = "1"; - private static final String TYPE = "AmbariConfiguration"; + private void testCreateResources(Authentication authentication) throws Exception { + Injector injector = createInjector(); - @TestSubject - private AmbariConfigurationResourceProvider ambariConfigurationResourceProvider = new AmbariConfigurationResourceProvider(); + ResourceProvider resourceProvider = injector.getInstance(AmbariConfigurationResourceProvider.class); - @Before - public void setup() { - ambariConfigurationEntityCapture = Capture.newInstance(); - gson = new GsonBuilder().create(); - } + Set<Map<String, Object>> propertySets = new HashSet<>(); - @Test - public void testCreateAmbariConfigurationRequestResultsInTheProperPersistenceCall() throws Exception { - - // GIVEN - // configuration properties parsed from the request - Set<Map<String, Object>> resourcePropertiesSet = Sets.newHashSet( - new PropertiesMapBuilder() - .withId(PK_LONG) - .withVersion(VERSION) - .withVersionTag(VERSION_TAG) - .withData(DATA_MOCK_STR) - .withType(TYPE) - .build()); - - // mock the request to return the properties - EasyMock.expect(requestMock.getProperties()).andReturn(resourcePropertiesSet); - - // capture the entity the DAO gets called with - ambariConfigurationDAO.create(EasyMock.capture(ambariConfigurationEntityCapture)); - publisher.publish(EasyMock.anyObject(AmbariLdapConfigChangedEvent.class)); + Map<String, String> properties1 = new HashMap<>(); + properties1.put("property1a", "value1"); + properties1.put("property2a", "value2"); + propertySets.add(toRequestProperties(CATEGORY_NAME_1, properties1)); + + Map<String, String> properties2 = new HashMap<>(); + properties2.put("property1b", "value1"); + properties2.put("property2b", "value2"); + propertySets.add(toRequestProperties(CATEGORY_NAME_2, properties2)); + + Request request = createMock(Request.class); + expect(request.getProperties()).andReturn(propertySets).once(); + + Capture<Map<String, String>> capturedProperties1 = newCapture(); + Capture<Map<String, String>> capturedProperties2 = newCapture(); + + AmbariConfigurationDAO dao = injector.getInstance(AmbariConfigurationDAO.class); + expect(dao.reconcileCategory(eq(CATEGORY_NAME_1), capture(capturedProperties1), eq(true))) + .andReturn(true) + .once(); + expect(dao.reconcileCategory(eq(CATEGORY_NAME_2), capture(capturedProperties2), eq(true))) + .andReturn(true) + .once(); + + AmbariEventPublisher publisher = injector.getInstance(AmbariEventPublisher.class); + publisher.publish(anyObject(AmbariConfigurationChangedEvent.class)); + expectLastCall().times(2); replayAll(); - // WHEN - ambariConfigurationResourceProvider.createResourcesAuthorized(requestMock); + SecurityContextHolder.getContext().setAuthentication(authentication); - // THEN - AmbariConfigurationEntity capturedAmbariConfigurationEntity = ambariConfigurationEntityCapture.getValue(); - Assert.assertNotNull(capturedAmbariConfigurationEntity); - Assert.assertNull("The entity identifier should be null", capturedAmbariConfigurationEntity.getId()); - Assert.assertEquals("The entity version is not the expected", Integer.valueOf(VERSION), - capturedAmbariConfigurationEntity.getConfigurationBaseEntity().getVersion()); - Assert.assertEquals("The entity version tag is not the expected", VERSION_TAG, - capturedAmbariConfigurationEntity.getConfigurationBaseEntity().getVersionTag()); - Assert.assertEquals("The entity data is not the expected", DATA_MOCK_STR, - gson.fromJson(capturedAmbariConfigurationEntity.getConfigurationBaseEntity().getConfigurationData(), String.class)); + resourceProvider.createResources(request); + + verifyAll(); + + validateCapturedProperties(properties1, capturedProperties1); + validateCapturedProperties(properties2, capturedProperties2); } @Test - public void testRemoveAmbariConfigurationRequestResultsInTheProperPersistenceCall() throws Exception { - // GIVEN - Predicate predicate = new PredicateBuilder().property( - AmbariConfigurationResourceProvider.ResourcePropertyId.ID.getPropertyId()).equals("1").toPredicate(); + public void testDeleteResources_Administrator() throws Exception { + testDeleteResources(TestAuthenticationFactory.createAdministrator()); + } - Capture<Long> pkCapture = Capture.newInstance(); - ambariConfigurationDAO.removeByPK(EasyMock.capture(pkCapture)); - publisher.publish(EasyMock.anyObject(AmbariLdapConfigChangedEvent.class)); + @Test(expected = AuthorizationException.class) + public void testDeleteResources_ClusterAdministrator() throws Exception { + testDeleteResources(TestAuthenticationFactory.createClusterAdministrator()); + } - replayAll(); + @Test(expected = AuthorizationException.class) + public void testDeleteResources_ClusterOperator() throws Exception { + testDeleteResources(TestAuthenticationFactory.createClusterOperator()); + } - // WHEN - ambariConfigurationResourceProvider.deleteResourcesAuthorized(requestMock, predicate); + @Test(expected = AuthorizationException.class) + public void testDeleteResources_ServiceAdministrator() throws Exception { + testDeleteResources(TestAuthenticationFactory.createServiceAdministrator()); + } - // THEN - Assert.assertEquals("The pk of the entity to be removed doen't match the expected id", Long.valueOf(1), pkCapture.getValue()); + @Test(expected = AuthorizationException.class) + public void testDeleteResources_ServiceOperator() throws Exception { + testDeleteResources(TestAuthenticationFactory.createServiceOperator()); } + private void testDeleteResources(Authentication authentication) throws Exception { + Injector injector = createInjector(); - @Test - public void testRetrieveAmbariConfigurationShouldResultsInTheProperDAOCall() throws Exception { - // GIVEN - Predicate predicate = new PredicateBuilder().property( - AmbariConfigurationResourceProvider.ResourcePropertyId.ID.getPropertyId()).equals("1").toPredicate(); + ResourceProvider resourceProvider = injector.getInstance(AmbariConfigurationResourceProvider.class); + + Predicate predicate = new PredicateBuilder() + .property(AMBARI_CONFIGURATION_CATEGORY_PROPERTY_ID) + .equals(CATEGORY_NAME_1) + .toPredicate(); + + Request request = createMock(Request.class); + + AmbariConfigurationDAO dao = injector.getInstance(AmbariConfigurationDAO.class); + expect(dao.removeByCategory(CATEGORY_NAME_1)).andReturn(1).once(); + + AmbariEventPublisher publisher = injector.getInstance(AmbariEventPublisher.class); + publisher.publish(anyObject(AmbariConfigurationChangedEvent.class)); + expectLastCall().once(); - EasyMock.expect(ambariConfigurationDAO.findAll()).andReturn(Lists.newArrayList(createDummyAmbariConfigurationEntity())); replayAll(); - // WHEN - Set<Resource> resourceSet = ambariConfigurationResourceProvider.getResourcesAuthorized(requestMock, predicate); + SecurityContextHolder.getContext().setAuthentication(authentication); + + resourceProvider.deleteResources(request, predicate); - // THEN - Assert.assertNotNull(resourceSet); - Assert.assertFalse(resourceSet.isEmpty()); + verifyAll(); } @Test - public void testUpdateAmbariConfigurationShouldResultInTheProperDAOCalls() throws Exception { - // GIVEN + public void testGetResources_Administrator() throws Exception { + testGetResources(TestAuthenticationFactory.createAdministrator()); + } + + @Test(expected = AuthorizationException.class) + public void testGetResources_ClusterAdministrator() throws Exception { + testGetResources(TestAuthenticationFactory.createClusterAdministrator()); + } + + @Test(expected = AuthorizationException.class) + public void testGetResources_ClusterOperator() throws Exception { + testGetResources(TestAuthenticationFactory.createClusterOperator()); + } + + @Test(expected = AuthorizationException.class) + public void testGetResources_ServiceAdministrator() throws Exception { + testGetResources(TestAuthenticationFactory.createServiceAdministrator()); + } + + @Test(expected = AuthorizationException.class) + public void testGetResources_ServiceOperator() throws Exception { + testGetResources(TestAuthenticationFactory.createServiceOperator()); + } + + private void testGetResources(Authentication authentication) throws Exception { + Injector injector = createInjector(); + + ResourceProvider resourceProvider = injector.getInstance(AmbariConfigurationResourceProvider.class); - Predicate predicate = new PredicateBuilder().property( - AmbariConfigurationResourceProvider.ResourcePropertyId.ID.getPropertyId()).equals("1").toPredicate(); + Predicate predicate = new PredicateBuilder() + .property(AMBARI_CONFIGURATION_CATEGORY_PROPERTY_ID) + .equals(CATEGORY_NAME_1) + .toPredicate(); - // properteies in the request, representing the updated configuration - Set<Map<String, Object>> resourcePropertiesSet = Sets.newHashSet(new PropertiesMapBuilder() - .withId(PK_LONG) - .withVersion("2") - .withVersionTag("version-2") - .withData(DATA_MOCK_STR) - .withType(TYPE) - .build()); + Request request = createMock(Request.class); + expect(request.getPropertyIds()).andReturn(null).anyTimes(); - EasyMock.expect(requestMock.getProperties()).andReturn(resourcePropertiesSet); + Map<String, String> properties = new HashMap<>(); + properties.put("property1a", "value1"); + properties.put("property2a", "value2"); - AmbariConfigurationEntity persistedEntity = createDummyAmbariConfigurationEntity(); - EasyMock.expect(ambariConfigurationDAO.findByPK(PK_LONG)).andReturn(persistedEntity); - ambariConfigurationDAO.update(EasyMock.capture(ambariConfigurationEntityCapture)); - publisher.publish(EasyMock.anyObject(AmbariLdapConfigChangedEvent.class)); + AmbariConfigurationDAO dao = injector.getInstance(AmbariConfigurationDAO.class); + expect(dao.findByCategory(CATEGORY_NAME_1)).andReturn(createEntities(CATEGORY_NAME_1, properties)).once(); replayAll(); - // WHEN - ambariConfigurationResourceProvider.updateResourcesAuthorized(requestMock, predicate); + SecurityContextHolder.getContext().setAuthentication(authentication); - // the captured entity should be the updated one - AmbariConfigurationEntity updatedEntity = ambariConfigurationEntityCapture.getValue(); + Set<Resource> response = resourceProvider.getResources(request, predicate); - // THEN - Assert.assertNotNull(updatedEntity); - Assert.assertEquals("The updated version is wrong", Integer.valueOf(2), updatedEntity.getConfigurationBaseEntity().getVersion()); - } + verifyAll(); - private class PropertiesMapBuilder { + junit.framework.Assert.assertNotNull(response); + junit.framework.Assert.assertEquals(1, response.size()); - private Map<String, Object> resourcePropertiesMap = Maps.newHashMap(); + Resource resource = response.iterator().next(); + junit.framework.Assert.assertEquals(Resource.Type.AmbariConfiguration, resource.getType()); - private PropertiesMapBuilder() { - } + Map<String, Map<String, Object>> propertiesMap = resource.getPropertiesMap(); + junit.framework.Assert.assertEquals(2, propertiesMap.size()); - public PropertiesMapBuilder withId(Long id) { - resourcePropertiesMap.put(AmbariConfigurationResourceProvider.ResourcePropertyId.ID.getPropertyId(), id); - return this; - } + junit.framework.Assert.assertEquals(CATEGORY_NAME_1, propertiesMap.get(Resource.Type.AmbariConfiguration.name()).get("category")); - private PropertiesMapBuilder withVersion(String version) { - resourcePropertiesMap.put(AmbariConfigurationResourceProvider.ResourcePropertyId.VERSION.getPropertyId(), version); - return this; - } + Map<String, Object> retrievedProperties = propertiesMap.get(Resource.Type.AmbariConfiguration.name() + "/properties"); + junit.framework.Assert.assertEquals(2, retrievedProperties.size()); - private PropertiesMapBuilder withVersionTag(String versionTag) { - resourcePropertiesMap.put(AmbariConfigurationResourceProvider.ResourcePropertyId.VERSION_TAG.getPropertyId(), versionTag); - return this; + for (Map.Entry<String, String> entry : properties.entrySet()) { + junit.framework.Assert.assertEquals(entry.getValue(), retrievedProperties.get(entry.getKey())); } + } - private PropertiesMapBuilder withData(String dataJson) { - resourcePropertiesMap.put(AmbariConfigurationResourceProvider.ResourcePropertyId.DATA.getPropertyId(), dataJson); - return this; - } + @Test + public void testUpdateResources_Administrator() throws Exception { + testUpdateResources(TestAuthenticationFactory.createAdministrator()); + } - private PropertiesMapBuilder withType(String type) { - resourcePropertiesMap.put(AmbariConfigurationResourceProvider.ResourcePropertyId.TYPE.getPropertyId(), type); - return this; - } + @Test(expected = AuthorizationException.class) + public void testUpdateResources_ClusterAdministrator() throws Exception { + testUpdateResources(TestAuthenticationFactory.createClusterAdministrator()); + } + @Test(expected = AuthorizationException.class) + public void testUpdateResources_ClusterOperator() throws Exception { + testUpdateResources(TestAuthenticationFactory.createClusterOperator()); + } - public Map<String, Object> build() { - return this.resourcePropertiesMap; - } + @Test(expected = AuthorizationException.class) + public void testUpdateResources_ServiceAdministrator() throws Exception { + testUpdateResources(TestAuthenticationFactory.createServiceAdministrator()); + } + + @Test(expected = AuthorizationException.class) + public void testUpdateResources_ServiceOperator() throws Exception { + testUpdateResources(TestAuthenticationFactory.createServiceOperator()); + } + + private void testUpdateResources(Authentication authentication) throws Exception { + Injector injector = createInjector(); + + ResourceProvider resourceProvider = injector.getInstance(AmbariConfigurationResourceProvider.class); + + Predicate predicate = new PredicateBuilder() + .property(AMBARI_CONFIGURATION_CATEGORY_PROPERTY_ID) + .equals(CATEGORY_NAME_1) + .toPredicate(); + + Set<Map<String, Object>> propertySets = new HashSet<>(); + Map<String, String> properties1 = new HashMap<>(); + properties1.put("property1a", "value1"); + properties1.put("property2a", "value2"); + propertySets.add(toRequestProperties(CATEGORY_NAME_1, properties1)); + + Request request = createMock(Request.class); + expect(request.getProperties()).andReturn(propertySets).once(); + + Capture<Map<String, String>> capturedProperties1 = newCapture(); + + AmbariConfigurationDAO dao = injector.getInstance(AmbariConfigurationDAO.class); + expect(dao.reconcileCategory(eq(CATEGORY_NAME_1), capture(capturedProperties1), eq(false))) + .andReturn(true) + .once(); + + AmbariEventPublisher publisher = injector.getInstance(AmbariEventPublisher.class); + publisher.publish(anyObject(AmbariConfigurationChangedEvent.class)); + expectLastCall().times(1); + + replayAll(); + + SecurityContextHolder.getContext().setAuthentication(authentication); + + resourceProvider.updateResources(request, predicate); + + verifyAll(); + + validateCapturedProperties(properties1, capturedProperties1); } - private AmbariConfigurationEntity createDummyAmbariConfigurationEntity() { - AmbariConfigurationEntity acEntity = new AmbariConfigurationEntity(); - ConfigurationBaseEntity configurationBaseEntity = new ConfigurationBaseEntity(); - acEntity.setConfigurationBaseEntity(configurationBaseEntity); - acEntity.setId(PK_LONG); - acEntity.getConfigurationBaseEntity().setConfigurationData(DATA_MOCK_STR); - acEntity.getConfigurationBaseEntity().setVersion(Integer.valueOf(VERSION)); - acEntity.getConfigurationBaseEntity().setVersionTag(VERSION_TAG); - acEntity.getConfigurationBaseEntity().setType("ldap-config"); + private List<AmbariConfigurationEntity> createEntities(String categoryName, Map<String, String> properties) { + List<AmbariConfigurationEntity> entities = new ArrayList<>(); - return acEntity; + for (Map.Entry<String, String> property : properties.entrySet()) { + AmbariConfigurationEntity entity = new AmbariConfigurationEntity(); + entity.setCategoryName(categoryName); + entity.setPropertyName(property.getKey()); + entity.setPropertyValue(property.getValue()); + entities.add(entity); + } + + return entities; + } + + private Map<String, Object> toRequestProperties(String categoryName1, Map<String, String> properties) { + Map<String, Object> requestProperties = new HashMap<>(); + requestProperties.put(AMBARI_CONFIGURATION_CATEGORY_PROPERTY_ID, categoryName1); + for (Map.Entry<String, String> entry : properties.entrySet()) { + requestProperties.put(AMBARI_CONFIGURATION_PROPERTIES_PROPERTY_ID + "/" + entry.getKey(), entry.getValue()); + } + return requestProperties; } + private void validateCapturedProperties(Map<String, String> expectedProperties, Capture<Map<String, String>> capturedProperties) { + junit.framework.Assert.assertTrue(capturedProperties.hasCaptured()); + Map<String, String> properties = capturedProperties.getValue(); + junit.framework.Assert.assertNotNull(properties); + + // Convert the Map to a TreeMap to help with comparisons + expectedProperties = new TreeMap<>(expectedProperties); + properties = new TreeMap<>(properties); + junit.framework.Assert.assertEquals(expectedProperties, properties); + } + + private Injector createInjector() throws Exception { + return Guice.createInjector(new AbstractModule() { + @Override + protected void configure() { + bind(EntityManager.class).toInstance(createNiceMock(EntityManager.class)); + bind(AmbariConfigurationDAO.class).toInstance(createMock(AmbariConfigurationDAO.class)); + bind(AmbariEventPublisher.class).toInstance(createMock(AmbariEventPublisher.class)); + } + }); + } } \ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/4fa9ac55/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AmbariConfigurationDAOTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AmbariConfigurationDAOTest.java b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AmbariConfigurationDAOTest.java new file mode 100644 index 0000000..f801fd6 --- /dev/null +++ b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AmbariConfigurationDAOTest.java @@ -0,0 +1,298 @@ +/* + * 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.orm.dao; + +import static org.easymock.EasyMock.capture; +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.expectLastCall; +import static org.easymock.EasyMock.newCapture; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; + +import javax.persistence.EntityManager; + +import org.apache.ambari.server.orm.entities.AmbariConfigurationEntity; +import org.easymock.Capture; +import org.easymock.CaptureType; +import org.easymock.EasyMockSupport; +import org.junit.BeforeClass; +import org.junit.Test; + +import com.google.inject.Provider; + +import junit.framework.Assert; + +public class AmbariConfigurationDAOTest extends EasyMockSupport { + + private static final String CATEGORY_NAME = "test-category"; + private static Method methodMerge; + private static Method methodRemove; + private static Method methodCreate; + private static Method methodFindByCategory; + + private static Field fieldEntityManagerProvider; + + @BeforeClass + public static void beforeKDCKerberosOperationHandlerTest() throws Exception { + methodMerge = AmbariConfigurationDAO.class.getMethod("merge", AmbariConfigurationEntity.class); + methodRemove = CrudDAO.class.getMethod("remove", Object.class); + methodCreate = AmbariConfigurationDAO.class.getMethod("create", AmbariConfigurationEntity.class); + methodFindByCategory = AmbariConfigurationDAO.class.getMethod("findByCategory", String.class); + + fieldEntityManagerProvider = CrudDAO.class.getDeclaredField("entityManagerProvider"); + } + + @Test + public void testReconcileCategoryNewCategory() throws Exception { + Capture<AmbariConfigurationEntity> capturedEntities = newCapture(CaptureType.ALL); + + AmbariConfigurationDAO dao = createDao(); + + expect(dao.findByCategory(CATEGORY_NAME)).andReturn(null).once(); + + dao.create(capture(capturedEntities)); + expectLastCall().anyTimes(); + + replayAll(); + + Map<String, String> properties; + properties = new HashMap<>(); + properties.put("property1", "value1"); + properties.put("property2", "value2"); + dao.reconcileCategory(CATEGORY_NAME, properties, true); + + verifyAll(); + + validateCapturedEntities(CATEGORY_NAME, properties, capturedEntities); + } + + @Test + public void testReconcileCategoryReplaceCategory() throws Exception { + + Map<String, String> existingProperties; + existingProperties = new HashMap<>(); + existingProperties.put("property1", "value1"); + existingProperties.put("property2", "value2"); + + Capture<AmbariConfigurationEntity> capturedCreatedEntities = newCapture(CaptureType.ALL); + Capture<AmbariConfigurationEntity> capturedRemovedEntities = newCapture(CaptureType.ALL); + + AmbariConfigurationDAO dao = createDao(); + + expect(dao.findByCategory(CATEGORY_NAME)).andReturn(toEntities(CATEGORY_NAME, existingProperties)).once(); + + dao.remove(capture(capturedRemovedEntities)); + expectLastCall().anyTimes(); + + dao.create(capture(capturedCreatedEntities)); + expectLastCall().anyTimes(); + + replayAll(); + + Map<String, String> newProperties; + newProperties = new HashMap<>(); + newProperties.put("property1_new", "value1"); + newProperties.put("property2_new", "value2"); + dao.reconcileCategory(CATEGORY_NAME, newProperties, true); + + verifyAll(); + + validateCapturedEntities(CATEGORY_NAME, newProperties, capturedCreatedEntities); + validateCapturedEntities(CATEGORY_NAME, existingProperties, capturedRemovedEntities); + } + + @Test + public void testReconcileCategoryUpdateCategoryKeepNotSpecified() throws Exception { + + Map<String, String> existingProperties; + existingProperties = new HashMap<>(); + existingProperties.put("property1", "value1"); + existingProperties.put("property2", "value2"); + + Capture<AmbariConfigurationEntity> capturedCreatedEntities = newCapture(CaptureType.ALL); + Capture<AmbariConfigurationEntity> capturedMergedEntities = newCapture(CaptureType.ALL); + + AmbariConfigurationDAO dao = createDao(); + + expect(dao.findByCategory(CATEGORY_NAME)).andReturn(toEntities(CATEGORY_NAME, existingProperties)).once(); + + expect(dao.merge(capture(capturedMergedEntities))).andReturn(createNiceMock(AmbariConfigurationEntity.class)).anyTimes(); + + dao.create(capture(capturedCreatedEntities)); + expectLastCall().anyTimes(); + + replayAll(); + + Map<String, String> newProperties; + newProperties = new HashMap<>(); + newProperties.put("property1", "new_value1"); + newProperties.put("property2_new", "value2"); + newProperties.put("property3", "value3"); + dao.reconcileCategory(CATEGORY_NAME, newProperties, false); + + verifyAll(); + + Map<String, String> expectedProperties; + + expectedProperties = new HashMap<>(); + expectedProperties.put("property2_new", "value2"); + expectedProperties.put("property3", "value3"); + validateCapturedEntities(CATEGORY_NAME, expectedProperties, capturedCreatedEntities); + + expectedProperties = new HashMap<>(); + expectedProperties.put("property1", "new_value1"); + validateCapturedEntities(CATEGORY_NAME, expectedProperties, capturedMergedEntities); + } + + @Test + public void testReconcileCategoryUpdateCategoryRemoveNotSpecified() throws Exception { + + Map<String, String> existingProperties; + existingProperties = new HashMap<>(); + existingProperties.put("property1", "value1"); + existingProperties.put("property2", "value2"); + + Capture<AmbariConfigurationEntity> capturedCreatedEntities = newCapture(CaptureType.ALL); + Capture<AmbariConfigurationEntity> capturedRemovedEntities = newCapture(CaptureType.ALL); + Capture<AmbariConfigurationEntity> capturedMergedEntities = newCapture(CaptureType.ALL); + + AmbariConfigurationDAO dao = createDao(); + + expect(dao.findByCategory(CATEGORY_NAME)).andReturn(toEntities(CATEGORY_NAME, existingProperties)).once(); + + expect(dao.merge(capture(capturedMergedEntities))).andReturn(createNiceMock(AmbariConfigurationEntity.class)).anyTimes(); + + dao.remove(capture(capturedRemovedEntities)); + expectLastCall().anyTimes(); + + dao.create(capture(capturedCreatedEntities)); + expectLastCall().anyTimes(); + + replayAll(); + + Map<String, String> newProperties; + newProperties = new HashMap<>(); + newProperties.put("property1", "new_value1"); + newProperties.put("property2_new", "value2"); + newProperties.put("property3", "value3"); + dao.reconcileCategory(CATEGORY_NAME, newProperties, true); + + verifyAll(); + + Map<String, String> expectedProperties; + + expectedProperties = new HashMap<>(); + expectedProperties.put("property2_new", "value2"); + expectedProperties.put("property3", "value3"); + validateCapturedEntities(CATEGORY_NAME, expectedProperties, capturedCreatedEntities); + + expectedProperties = new HashMap<>(); + expectedProperties.put("property2", "value2"); + validateCapturedEntities(CATEGORY_NAME, expectedProperties, capturedRemovedEntities); + + expectedProperties = new HashMap<>(); + expectedProperties.put("property1", "new_value1"); + validateCapturedEntities(CATEGORY_NAME, expectedProperties, capturedMergedEntities); + } + + @Test + public void testReconcileCategoryAppendCategory() throws Exception { + + Map<String, String> existingProperties; + existingProperties = new HashMap<>(); + existingProperties.put("property1", "value1"); + existingProperties.put("property2", "value2"); + + Capture<AmbariConfigurationEntity> capturedCreatedEntities = newCapture(CaptureType.ALL); + + AmbariConfigurationDAO dao = createDao(); + + expect(dao.findByCategory(CATEGORY_NAME)).andReturn(toEntities(CATEGORY_NAME, existingProperties)).once(); + + dao.create(capture(capturedCreatedEntities)); + expectLastCall().anyTimes(); + + replayAll(); + + Map<String, String> newProperties; + newProperties = new HashMap<>(); + newProperties.put("property3", "value3"); + newProperties.put("property4", "value3"); + dao.reconcileCategory(CATEGORY_NAME, newProperties, false); + + verifyAll(); + + validateCapturedEntities(CATEGORY_NAME, newProperties, capturedCreatedEntities); + } + + private AmbariConfigurationDAO createDao() throws IllegalAccessException { + AmbariConfigurationDAO dao = createMockBuilder(AmbariConfigurationDAO.class) + .addMockedMethods(methodMerge, methodRemove, methodCreate, methodFindByCategory) + .createMock(); + + EntityManager entityManager = createMock(EntityManager.class); + entityManager.flush(); + expectLastCall().anyTimes(); + + Provider<EntityManager> entityManagerProvider = createMock(Provider.class); + expect(entityManagerProvider.get()).andReturn(entityManager).anyTimes(); + + fieldEntityManagerProvider.set(dao, entityManagerProvider); + + return dao; + } + + private List<AmbariConfigurationEntity> toEntities(String categoryName, Map<String, String> properties) { + List<AmbariConfigurationEntity> entities = new ArrayList<>(); + + for (Map.Entry<String, String> property : properties.entrySet()) { + AmbariConfigurationEntity entity = new AmbariConfigurationEntity(); + entity.setCategoryName(categoryName); + entity.setPropertyName(property.getKey()); + entity.setPropertyValue(property.getValue()); + entities.add(entity); + } + + return entities; + } + + private void validateCapturedEntities(String expectedCategoryName, Map<String, String> expectedProperties, Capture<AmbariConfigurationEntity> capturedEntities) { + Assert.assertTrue(capturedEntities.hasCaptured()); + + List<AmbariConfigurationEntity> entities = capturedEntities.getValues(); + Assert.assertNotNull(entities); + + Map<String, String> capturedProperties = new TreeMap<>(); + for (AmbariConfigurationEntity entity : entities) { + Assert.assertEquals(expectedCategoryName, entity.getCategoryName()); + capturedProperties.put(entity.getPropertyName(), entity.getPropertyValue()); + } + + // Convert the Map to a TreeMap to help with comparisons + expectedProperties = new TreeMap<>(expectedProperties); + Assert.assertEquals(expectedProperties, capturedProperties); + } + +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/4fa9ac55/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog300Test.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog300Test.java b/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog300Test.java index bd8f5cb..747f99b 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog300Test.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog300Test.java @@ -17,6 +17,10 @@ */ package org.apache.ambari.server.upgrade; +import static org.apache.ambari.server.upgrade.UpgradeCatalog300.AMBARI_CONFIGURATION_CATEGORY_NAME_COLUMN; +import static org.apache.ambari.server.upgrade.UpgradeCatalog300.AMBARI_CONFIGURATION_PROPERTY_NAME_COLUMN; +import static org.apache.ambari.server.upgrade.UpgradeCatalog300.AMBARI_CONFIGURATION_PROPERTY_VALUE_COLUMN; +import static org.apache.ambari.server.upgrade.UpgradeCatalog300.AMBARI_CONFIGURATION_TABLE; import static org.apache.ambari.server.upgrade.UpgradeCatalog300.COMPONENT_DESIRED_STATE_TABLE; import static org.apache.ambari.server.upgrade.UpgradeCatalog300.COMPONENT_STATE_TABLE; import static org.apache.ambari.server.upgrade.UpgradeCatalog300.SECURITY_STATE_COLUMN; @@ -42,6 +46,7 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashMap; +import java.util.List; import java.util.Map; import javax.persistence.EntityManager; @@ -186,6 +191,15 @@ public class UpgradeCatalog300Test { dbAccessor.dropColumn(SERVICE_DESIRED_STATE_TABLE, SECURITY_STATE_COLUMN); expectLastCall().once(); + // Ambari configuration table addition... + Capture<List<DBAccessor.DBColumnInfo>> ambariConfigurationTableColumns = newCapture(); + + dbAccessor.createTable(eq(AMBARI_CONFIGURATION_TABLE), capture(ambariConfigurationTableColumns)); + expectLastCall().once(); + dbAccessor.addPKConstraint(AMBARI_CONFIGURATION_TABLE, "PK_ambari_configuration", AMBARI_CONFIGURATION_CATEGORY_NAME_COLUMN, AMBARI_CONFIGURATION_PROPERTY_NAME_COLUMN); + expectLastCall().once(); + // Ambari configuration table addition... + replay(dbAccessor, configuration); Injector injector = Guice.createInjector(module); @@ -197,6 +211,35 @@ public class UpgradeCatalog300Test { Assert.assertEquals(null, capturedOpsDisplayNameColumn.getDefaultValue()); Assert.assertEquals(String.class, capturedOpsDisplayNameColumn.getType()); + // Ambari configuration table addition... + Assert.assertTrue(ambariConfigurationTableColumns.hasCaptured()); + List<DBAccessor.DBColumnInfo> columns = ambariConfigurationTableColumns.getValue(); + Assert.assertEquals(3, columns.size()); + + for (DBAccessor.DBColumnInfo column : columns) { + String columnName = column.getName(); + + if (AMBARI_CONFIGURATION_CATEGORY_NAME_COLUMN.equals(columnName)) { + Assert.assertEquals(String.class, column.getType()); + Assert.assertEquals(Integer.valueOf(100), column.getLength()); + Assert.assertEquals(null, column.getDefaultValue()); + Assert.assertFalse(column.isNullable()); + } else if (AMBARI_CONFIGURATION_PROPERTY_NAME_COLUMN.equals(columnName)) { + Assert.assertEquals(String.class, column.getType()); + Assert.assertEquals(Integer.valueOf(100), column.getLength()); + Assert.assertEquals(null, column.getDefaultValue()); + Assert.assertFalse(column.isNullable()); + } else if (AMBARI_CONFIGURATION_PROPERTY_VALUE_COLUMN.equals(columnName)) { + Assert.assertEquals(String.class, column.getType()); + Assert.assertEquals(Integer.valueOf(255), column.getLength()); + Assert.assertEquals(null, column.getDefaultValue()); + Assert.assertTrue(column.isNullable()); + } else { + Assert.fail("Unexpected column name: " + columnName); + } + } + // Ambari configuration table addition... + verify(dbAccessor); }