/*
* RHQ Management Platform
* Copyright (C) 2005-2010 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
package org.rhq.enterprise.server.resource.metadata.test;
import java.util.Set;
import javax.transaction.Status;
import org.testng.annotations.Test;
import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.bundle.ResourceTypeBundleConfiguration;
import org.rhq.core.domain.bundle.ResourceTypeBundleConfiguration.BundleDestinationBaseDirectory;
import org.rhq.core.domain.bundle.ResourceTypeBundleConfiguration.BundleDestinationBaseDirectory.Context;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.criteria.ResourceCriteria;
import org.rhq.core.domain.measurement.DisplayType;
import org.rhq.core.domain.measurement.MeasurementDefinition;
import org.rhq.core.domain.resource.Resource;
import org.rhq.core.domain.resource.ResourceType;
import org.rhq.enterprise.server.util.LookupUtil;
/**
* Note, plugins are registered in new transactions. For tests, this means
* you can't do everything in a trans and roll back at the end. You must clean up manually.
*/
public class UpdateResourceTypeSubsystemTest extends UpdatePluginMetadataTestBase {
@Override
protected String getSubsystemDirectory() {
return "resource-type";
}
/**
* Tests updating bundle-target config
*/
@Test
public void testResourceTypeBundleTarget() throws Exception {
try {
// register the plugin - it has a platform with child server that is a bundle target
registerPlugin("updateResourceTypeBundleTarget-v1.xml");
ResourceType platform1 = getResourceType("myPlatform1");
getTransactionManager().begin();
platform1 = em.find(ResourceType.class, platform1.getId());
assert platform1.getResourceTypeBundleConfiguration() == null : "platform should not be a bundle target";
Set<ResourceType> servers1 = platform1.getChildResourceTypes();
assert servers1.size() == 1 : "must only have one child server under the test platform";
ResourceType server1 = servers1.iterator().next();
ResourceTypeBundleConfiguration bundleConfig1 = server1.getResourceTypeBundleConfiguration();
assert bundleConfig1 != null : "server should have been a bundle target";
Set<BundleDestinationBaseDirectory> baseDirs1 = bundleConfig1.getBundleDestinationBaseDirectories();
assert baseDirs1.size() == 2 : "should have been 2 bundle dest base dirs: " + baseDirs1;
for (BundleDestinationBaseDirectory baseDir : baseDirs1) {
if (baseDir.getName().equals("firstDestBaseDir")) {
assert baseDir.getValueContext() == Context.pluginConfiguration : "bad context: " + baseDir;
assert baseDir.getValueName().equals("prop1") : "bad value" + baseDir;
} else if (baseDir.getName().equals("secondDestBaseDir")) {
assert baseDir.getValueContext() == Context.fileSystem : "bad context: " + baseDir;
assert baseDir.getValueName().equals("/") : "bad value" + baseDir;
} else {
assert false : "wrong dest base dir was retrieved: " + baseDir;
}
}
getTransactionManager().rollback();
// now upgrade the plugin - the bundle config will have changed in the server
registerPlugin("updateResourceTypeBundleTarget-v2.xml");
ResourceType platform2 = getResourceType("myPlatform1");
getTransactionManager().begin();
platform2 = em.find(ResourceType.class, platform2.getId());
assert platform1.getResourceTypeBundleConfiguration() == null : "platform should not be a bundle target";
Set<ResourceType> servers2 = platform2.getChildResourceTypes();
assert servers2.size() == 1 : "Expected to find 1 server";
ResourceType server2 = servers2.iterator().next();
ResourceTypeBundleConfiguration bundleConfig2 = server2.getResourceTypeBundleConfiguration();
assert bundleConfig2 != null : "server should have been a bundle target";
Set<BundleDestinationBaseDirectory> baseDirs2 = bundleConfig2.getBundleDestinationBaseDirectories();
assert baseDirs2.size() == 1 : "should have been 1 bundle dest base dir: " + baseDirs2;
BundleDestinationBaseDirectory baseDir = baseDirs2.iterator().next();
assert baseDir.getName().equals("thirdDestBaseDir");
assert baseDir.getValueContext() == Context.resourceConfiguration : "bad context: " + baseDir;
assert baseDir.getValueName().equals("resourceProp1") : "bad value" + baseDir;
// make sure the old bundle config was deleted when we upgraded and overwrite it with the new config
assert null == em.find(Configuration.class, bundleConfig1.getBundleConfiguration().getId()) : "The configuration "
+ bundleConfig1 + " should have been deleted";
getTransactionManager().rollback();
} finally {
if (Status.STATUS_NO_TRANSACTION != getTransactionManager().getStatus()) {
getTransactionManager().rollback();
}
}
}
/**
* See if deletion of a resource type just works
*
* @throws Exception on error
*/
@Test
public void testResourceTypeDeletion() throws Exception {
try {
registerPlugin("update4-v1_0.xml");
ResourceType platform1 = getResourceType("myPlatform4");
getTransactionManager().begin();
platform1 = em.find(ResourceType.class, platform1.getId());
Set<ResourceType> servers1 = platform1.getChildResourceTypes();
assert servers1.size() == 2 : "Expected to find 2 servers in v1";
int found = 0;
for (ResourceType server : servers1) {
if (server.getName().equals("testServer1")) {
found++;
}
if (server.getName().equals("testServer2")) {
found++;
}
}
assert found == 2 : "I did not find the expected servers in v1";
getTransactionManager().rollback();
registerPlugin("update4-v2_0.xml");
ResourceType platform2 = getResourceType("myPlatform4");
getTransactionManager().begin();
platform2 = em.find(ResourceType.class, platform2.getId());
Set<ResourceType> servers2 = platform2.getChildResourceTypes();
assert servers2.size() == 1 : "Expected to find 1 servers in v2";
ResourceType server2 = servers2.iterator().next();
assert server2.getName().equals("testServer1");
Set<MeasurementDefinition> mdef = server2.getMetricDefinitions();
// include the built-in AvailabilityType metric
assert mdef.size() == 2 : "Expected 2 MeasurementDefinition in v2";
getTransactionManager().rollback();
registerPlugin("update4-v1_0.xml", "3.0");
ResourceType platform3 = getResourceType("myPlatform4");
getTransactionManager().begin();
platform3 = em.find(ResourceType.class, platform3.getId());
Set<ResourceType> servers3 = platform3.getChildResourceTypes();
assert servers3.size() == 2 : "Expected to find 2 servers in v1/2";
found = 0;
for (ResourceType server : servers3) {
if (server.getName().equals("testServer1")) {
found++;
}
if (server.getName().equals("testServer2")) {
found++;
}
}
assert found == 2 : "I did not find the expected servers in v1/2";
} finally {
if (Status.STATUS_NO_TRANSACTION != getTransactionManager().getStatus()) {
getTransactionManager().rollback();
}
}
}
@Test
/**
* Tests moving a resource type to a new parent resource type.
*/
public void testMoveResourceType() throws Exception {
System.out.println("testMoveResourceType --- start");
try {
registerPlugin("update2-v1_0.xml");
Subject overlord = LookupUtil.getSubjectManager().getOverlord();
ResourceType platform1 = getResourceType("myPlatform");
Resource platformResource = createResource("foo-myPlatform", "foo-myPlatform", platform1);
resourceManager.createResource(overlord, platformResource, -1);
ResourceType service1 = getResourceType("service1");
Resource service1Resource = createResource("foo-service1", "foo-service1", service1);
platformResource.addChildResource(service1Resource);
resourceManager.createResource(overlord, service1Resource, -1);
ResourceType nestedOne = getResourceType("nestedOne");
Resource nestedOneResource = createResource("foo-nestedOne", "foo-nestedOne", nestedOne);
service1Resource.addChildResource(nestedOneResource);
resourceManager.createResource(overlord, nestedOneResource, -1);
getTransactionManager().begin();
platform1 = em.find(ResourceType.class, platform1.getId());
assert platform1 != null : "I did not find myPlatform";
Set<MeasurementDefinition> defs = platform1.getMetricDefinitions();
// no built-in AvailabilityType metric for platforms
assert defs.size() == 1 : "I was expecting 1 metric definition at platform level in v1";
assert DisplayType.DETAIL == defs.iterator().next().getDisplayType() : "Display type should be DETAIL in v1";
// one child service in v1
Set<ResourceType> platformChildren = platform1.getChildResourceTypes();
assert platformChildren.size() == 1 : "Expected 1 direct child service of platform in v1";
service1 = platformChildren.iterator().next();
assert service1.getName().equals("service1") : "Expected 'service1' as name of direct platform child in v1";
// include the built-in AvailabilityType metric
assert service1.getMetricDefinitions().size() == 2 : "Expected 2 metric for 'service1' in v1";
Set<ResourceType> nestedServices = service1.getChildResourceTypes();
assert nestedServices.size() == 1 : "Expected 1 nested service of 'service1' in v1";
Set<MeasurementDefinition> nestedDefs = nestedServices.iterator().next().getMetricDefinitions();
// include the built-in AvailabilityType metric
assert nestedDefs.size() == 2 : "Expected 2 definition within 'nestedService' in v1";
MeasurementDefinition defThree = nestedDefs.iterator().next();
int definitionId = defThree.getId(); // get the id of the definition "Three" and save it for later use
getTransactionManager().rollback();
System.out.println("testMoveResourceType -- done with the first plugin version");
/*
* The nested service got pulled out and put under platform
*/
registerPlugin("update2-v2_0.xml");
ResourceType platform2 = getResourceType("myPlatform");
getTransactionManager().begin();
platform2 = em.find(ResourceType.class, platform2.getId());
assert platform2 != null : "I did not find myPlatform";
Set<MeasurementDefinition> defs2 = platform2.getMetricDefinitions();
// no built-in AvailabilityType metric for platforms
assert defs2.size() == 1 : "I was expecting 1 definition at platform level in v2";
assert DisplayType.SUMMARY == defs2.iterator().next().getDisplayType() : "Display type should be SUMMARY in v2";
ResourceCriteria resourceCriteria = new ResourceCriteria();
resourceCriteria.setStrict(true);
resourceCriteria.addFilterResourceKey("foo-myPlatform");
resourceCriteria.fetchChildResources(true);
Resource platform2Resource = getResource(resourceCriteria);
assert platform2Resource != null : "Expected to find platform Resource in db.";
// two children in v2
Set<ResourceType> platformChildren2 = platform2.getChildResourceTypes();
assert platformChildren2.size() == 2 : "Expected 2 direct child service types of platform in v2";
Set<Resource> platform2ChildResources = platform2Resource.getChildResources();
assert platform2ChildResources.size() == 2 : "Expected 2 direct child services of platform in v2";
boolean foundMovedResource = false;
for (Resource childResource : platform2ChildResources) {
assert childResource.getChildResources().isEmpty() : "Expected child Resource " + childResource
+ " to have no children";
if (childResource.getResourceKey().equals("foo-nestedOne")) {
foundMovedResource = true;
}
}
assert foundMovedResource : "Expected 'foo-nestedOne' Resource to have been moved directly under platform Resource";
for (ResourceType type : platformChildren2) {
String typeName = type.getName();
// include the built-in AvailabilityType metric
assert type.getMetricDefinitions().size() == 2 : "Expected two definition for " + typeName + " in v2";
if (typeName.equals("nestedOne")) // The moved one
{
Set<MeasurementDefinition> defs3 = type.getMetricDefinitions();
MeasurementDefinition three = defs3.iterator().next();
assert three.getDisplayName().equals("Three") : "Expected the nestedOne to have a metric withDisplayName Three in v2, but it was "
+ three.getDisplayName();
assert three.getDisplayType() == DisplayType.SUMMARY : "Expected three to be SUMMARY in v2";
/*
* TODO check here if the Definition is the one from above which got moved. this should be the case.
* Else we would loose all measurement schedules (and disassociate them from measurement data. But the
* latter is a different story. We probably should cascade that anyway.
*/
assert three.getId() == definitionId : "Expected the id of 'Three' to be " + definitionId
+ ", but it was " + three.getId() + " in v2";
} else if (typeName.equals("service1")) {
// check that the nested service is gone
Set<ResourceType> childrenOfService = type.getChildResourceTypes();
assert childrenOfService.size() == 0 : "No children of 'service1' expected in v2, but found: "
+ childrenOfService.size();
} else {
assert true == false : "We found an unknown type with name " + typeName;
}
}
// TODO now that we're done here, apply v1 again to also test the other direction
} finally {
if (Status.STATUS_NO_TRANSACTION != getTransactionManager().getStatus()) {
getTransactionManager().rollback();
}
}
System.out.println("testMoveResourceType --- end");
}
@Test
public void testDuplicateResourceType() throws Exception {
System.out.println("= testDuplicateResourceType");
try {
System.out.println("NOTE: A stack trace coming out of this is expected.");
registerPlugin("duplicateResourceType.xml");
getResourceType("ops");
assert false : "We should not have hit this line";
} catch (Exception e) {
// ignore - We expect an exception to come out of the ResourceMetadataManager
} finally {
if (Status.STATUS_NO_TRANSACTION != getTransactionManager().getStatus()) {
getTransactionManager().rollback();
}
}
}
}