/* * RHQ Management Platform * Copyright (C) 2005-2014 Red Hat, Inc. * All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ package org.rhq.modules.plugins.jbossas7.itest; import static java.lang.Boolean.TRUE; import static java.util.concurrent.TimeUnit.SECONDS; import static org.rhq.core.domain.resource.CreateResourceStatus.SUCCESS; import static org.rhq.modules.plugins.jbossas7.test.util.Constants.PLUGIN_NAME; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertFalse; import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertNull; import static org.testng.Assert.assertSame; import static org.testng.Assert.assertTrue; import java.util.List; import java.util.Set; import org.testng.annotations.Test; import org.rhq.core.clientapi.agent.PluginContainerException; import org.rhq.core.clientapi.agent.configuration.ConfigurationUpdateRequest; import org.rhq.core.clientapi.agent.inventory.CreateResourceRequest; import org.rhq.core.clientapi.agent.inventory.CreateResourceResponse; import org.rhq.core.clientapi.server.configuration.ConfigurationUpdateResponse; import org.rhq.core.domain.configuration.Configuration; import org.rhq.core.domain.configuration.ConfigurationUpdateStatus; import org.rhq.core.domain.configuration.Property; import org.rhq.core.domain.configuration.PropertyList; import org.rhq.core.domain.configuration.PropertyMap; import org.rhq.core.domain.configuration.PropertySimple; import org.rhq.core.domain.operation.OperationDefinition; import org.rhq.core.domain.resource.InventoryStatus; import org.rhq.core.domain.resource.Resource; import org.rhq.core.domain.resource.ResourceType; import org.rhq.core.pc.inventory.ResourceContainer; import org.rhq.core.pc.util.FacetLockType; import org.rhq.core.pluginapi.operation.OperationFacet; import org.rhq.core.pluginapi.operation.OperationResult; import org.rhq.test.arquillian.RunDiscovery; /** * @author Thomas Segismont */ public abstract class AbstractDatasourceTest extends AbstractJBossAS7PluginTest { private Resource datasourcesSubsystemResource; private ResourceType datasourceResourceType; private Resource datasourceTestResource; protected abstract String getDatasourceResourceTypeName(); protected abstract String getTestDatasourceName(); protected abstract Resource getDatasourcesSubsystemResource() throws Exception; @Test(priority = -10000) @RunDiscovery(discoverServers = true, discoverServices = false) public void initialDiscoveryTest() throws Exception { datasourcesSubsystemResource = getDatasourcesSubsystemResource(); for (ResourceType resourceType : datasourcesSubsystemResource.getResourceType().getChildResourceTypes()) { if (getDatasourceResourceTypeName().equals(resourceType.getName())) { datasourceResourceType = resourceType; break; } } assertNotNull(datasourceResourceType, "Could not find resource type: " + getDatasourceResourceTypeName()); } @Test(dependsOnMethods = { "initialDiscoveryTest" }) public void testCreateDatasource() throws Exception { Configuration pluginConfig = new Configuration(); pluginConfig.put(new PropertySimple("path", "data-source=" + getTestDatasourceName())); Configuration resourceConfig = datasourceResourceType.getResourceConfigurationDefinition().getDefaultTemplate() .createConfiguration(); resourceConfig.put(new PropertySimple("connection-url", "jdbc:h2:mem:" + getTestDatasourceName() + ";DB_CLOSE_DELAY=-1")); resourceConfig.put(new PropertySimple("user-name", "sa")); resourceConfig.put(new PropertySimple("password", "sa")); resourceConfig.put(new PropertySimple("driver-class", "org.h2.Driver")); resourceConfig.put(new PropertySimple("driver-name", "h2")); resourceConfig.put(new PropertySimple("jndi-name", "java:jboss/datasources/" + getTestDatasourceName())); resourceConfig.put(new PropertyList("*1", new PropertyMap("*:pname", new PropertySimple("pname", "DatasourceTestKey"), new PropertySimple("value", "DatasourceTestValue")))); CreateResourceRequest createRequest = new CreateResourceRequest(); createRequest.setParentResourceId(datasourcesSubsystemResource.getId()); createRequest.setPluginConfiguration(pluginConfig); createRequest.setPluginName(PLUGIN_NAME); createRequest.setResourceConfiguration(resourceConfig); createRequest.setResourceName(getTestDatasourceName()); createRequest.setResourceTypeName(datasourceResourceType.getName()); CreateResourceResponse createResourceResponse = pluginContainer.getResourceFactoryManager() .executeCreateResourceImmediately(createRequest); assertEquals(createResourceResponse.getStatus(), SUCCESS, createResourceResponse.getErrorMessage()); Set<Resource> datasourceResources = pluginContainer.getInventoryManager().getResourcesWithType( datasourceResourceType); datasourceTestResource = null; for (Resource datasourceResource : datasourceResources) { if (datasourceResource.getResourceKey().equals(createResourceResponse.getResourceKey())) { datasourceTestResource = datasourceResource; break; } } assertNotNull(datasourceTestResource, getTestDatasourceName() + " was not discovered"); assertEquals(datasourceTestResource.getInventoryStatus(), InventoryStatus.COMMITTED); } @Test(dependsOnMethods = { "testCreateDatasource" }) public void testDatasourceLoadConfiguration() throws Exception { Configuration configuration = pluginContainer.getConfigurationManager().loadResourceConfiguration( datasourceTestResource.getId()); assertTrue(Boolean.parseBoolean(configuration.getSimpleValue("enabled")), ""); assertEquals(configuration.getSimpleValue("connection-url"), "jdbc:h2:mem:" + getTestDatasourceName() + ";DB_CLOSE_DELAY=-1"); assertEquals(configuration.getSimpleValue("user-name"), "sa"); assertEquals(configuration.getSimpleValue("password"), "sa"); assertEquals(configuration.getSimpleValue("driver-class"), "org.h2.Driver"); assertEquals(configuration.getSimpleValue("driver-name"), "h2"); assertEquals(configuration.getSimpleValue("jndi-name"), "java:jboss/datasources/" + getTestDatasourceName()); PropertyList connectionPropertiesListWrapper = configuration.getList("*1"); assertNotNull(connectionPropertiesListWrapper, "Connection properties list wrapper is null"); List<Property> connectionPropertiesList = connectionPropertiesListWrapper.getList(); assertEquals(connectionPropertiesList.size(), 1); Property property = connectionPropertiesList.iterator().next(); assertTrue(property instanceof PropertyMap, "Connection properties should be a list of maps"); PropertyMap propertyMap = (PropertyMap) property; String pname = propertyMap.getSimpleValue("pname", null); assertNotNull(pname, "Connection property key is null"); assertEquals(pname, "DatasourceTestKey"); String value = propertyMap.getSimpleValue("value", null); assertNotNull(value, "Connection property value is null"); assertEquals(value, "DatasourceTestValue"); } @Test(dependsOnMethods = { "testDatasourceLoadConfiguration" }) public void changingMaxPoolSizeShouldNotRequireDisablingTheDatasourceNorReloadingServer() throws Exception { Configuration configuration = pluginContainer.getConfigurationManager().loadResourceConfiguration( datasourceTestResource.getId()); // Make a working copy configuration = configuration.deepCopy(false); // Change value PropertySimple propertySimple = configuration.getSimple("max-pool-size"); Long currentMaxPoolSize = propertySimple.getLongValue(); long newMaxPoolSize = currentMaxPoolSize == null ? 40 : currentMaxPoolSize + 1; propertySimple.setStringValue(String.valueOf(newMaxPoolSize)); ConfigurationUpdateRequest configurationUpdateRequest = new ConfigurationUpdateRequest(-1, configuration, datasourceTestResource.getId()); ConfigurationUpdateResponse configurationUpdateResponse = pluginContainer.getConfigurationManager() .executeUpdateResourceConfigurationImmediately(configurationUpdateRequest); assertSame(configurationUpdateResponse.getStatus(), ConfigurationUpdateStatus.SUCCESS); configuration = pluginContainer.getConfigurationManager().loadResourceConfiguration( datasourceTestResource.getId()); assertTrue(Boolean.parseBoolean(configuration.getSimpleValue("enabled")), ""); assertEquals(configuration.getSimple("max-pool-size").getLongValue(), Long.valueOf(newMaxPoolSize)); assertFalse( configuration.getNames().contains("__OOB"), "The configuration object should not contain out of band messages: " + configuration.getSimpleValue("__OOB")); } @Test(dependsOnMethods = { "changingMaxPoolSizeShouldNotRequireDisablingTheDatasourceNorReloadingServer" }) public void disableWithRestartThenChangeThenEnableShouldNotRequireReload() throws Exception { // First disable datasource (allow service restart) OperationDefinition disableOperation = getOperationDefinition("disable"); Configuration disableOperationParams = disableOperation.getParametersConfigurationDefinition() .getDefaultTemplate().createConfiguration(); disableOperationParams.setSimpleValue("allow-resource-service-restart", TRUE.toString()); OperationFacet operationFacet = getOperationFacet(datasourceTestResource); OperationResult operationResult = operationFacet.invokeOperation(disableOperation.getName(), disableOperationParams); assertNull(operationResult.getErrorMessage(), "Disable operation failed with error: " + operationResult.getErrorMessage()); // Then update properties which can only be changed when datasource is in disabled state Configuration configuration = pluginContainer.getConfigurationManager().loadResourceConfiguration( datasourceTestResource.getId()); assertFalse(Boolean.parseBoolean(configuration.getSimpleValue("enabled")), ""); // Make a working copy configuration = configuration.deepCopy(false); // Change values PropertySimple propertySimple = configuration.getSimple("prepared-statements-cache-size"); Long currentCacheSize = propertySimple.getLongValue(); long newCacheSize = currentCacheSize == null ? 40 : currentCacheSize + 1; propertySimple.setStringValue(String.valueOf(newCacheSize)); PropertyList connectionPropertiesListWrapper = configuration.getList("*1"); assertNotNull(connectionPropertiesListWrapper, "Connection properties list wrapper is null"); List<Property> connectionPropertiesList = connectionPropertiesListWrapper.getList(); connectionPropertiesList.add(new PropertyMap("*:pname", new PropertySimple("pname", "pipo"), new PropertySimple("value", "molo"))); ConfigurationUpdateRequest configurationUpdateRequest = new ConfigurationUpdateRequest(-1, configuration, datasourceTestResource.getId()); ConfigurationUpdateResponse configurationUpdateResponse = pluginContainer.getConfigurationManager() .executeUpdateResourceConfigurationImmediately(configurationUpdateRequest); assertSame(configurationUpdateResponse.getStatus(), ConfigurationUpdateStatus.SUCCESS); configuration = pluginContainer.getConfigurationManager().loadResourceConfiguration( datasourceTestResource.getId()); assertFalse(Boolean.parseBoolean(configuration.getSimpleValue("enabled")), ""); assertEquals(configuration.getSimple("prepared-statements-cache-size").getLongValue(), Long.valueOf(newCacheSize)); connectionPropertiesListWrapper = configuration.getList("*1"); assertNotNull(connectionPropertiesListWrapper, "Connection properties list wrapper is null"); connectionPropertiesList = connectionPropertiesListWrapper.getList(); String connectionPropertyValue = null; for (Property property : connectionPropertiesList) { assertTrue(property instanceof PropertyMap, "Connection properties should be a list of maps"); PropertyMap propertyMap = (PropertyMap) property; String pname = propertyMap.getSimpleValue("pname", null); assertNotNull(pname, "Connection property key is null"); String value = propertyMap.getSimpleValue("value", null); assertNotNull(value, "Connection property value is null"); if ("pipo".equals(pname)) { connectionPropertyValue = value; break; } } assertEquals(connectionPropertyValue, "molo"); assertFalse( configuration.getNames().contains("__OOB"), "The configuration object should not contain out of band messages: " + configuration.getSimpleValue("__OOB")); // Now re-enable datasource OperationDefinition enableOperation = getOperationDefinition("enable"); Configuration enableOperationParams = enableOperation.getParametersConfigurationDefinition() .getDefaultTemplate().createConfiguration(); operationResult = operationFacet.invokeOperation(enableOperation.getName(), enableOperationParams); assertNull(operationResult.getErrorMessage(), "Enable operation failed with error: " + operationResult.getErrorMessage()); // Check server state configuration = pluginContainer.getConfigurationManager().loadResourceConfiguration( datasourceTestResource.getId()); assertTrue(Boolean.parseBoolean(configuration.getSimpleValue("enabled")), ""); assertFalse( configuration.getNames().contains("__OOB"), "The configuration object should not contain out of band messages: " + configuration.getSimpleValue("__OOB")); } private OperationDefinition getOperationDefinition(String operationName) { Set<OperationDefinition> operationDefinitions = datasourceResourceType.getOperationDefinitions(); OperationDefinition operationDefinition = null; for (OperationDefinition opDef : operationDefinitions) { if (opDef.getName().equals(operationName)) { operationDefinition = opDef; break; } } assertNotNull(operationDefinition); return operationDefinition; } private OperationFacet getOperationFacet(Resource resource) { ResourceContainer resourceContainer = pluginContainer.getInventoryManager().getResourceContainer(resource); try { return resourceContainer.createResourceComponentProxy(OperationFacet.class, FacetLockType.WRITE, SECONDS.toMillis(5), false, false, false); } catch (PluginContainerException e) { return null; } } }