package org.rhq.enterprise.server.resource.metadata; import java.util.HashSet; import java.util.List; import java.util.Set; import org.testng.annotations.Test; 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.definition.ConfigurationDefinition; import org.rhq.core.domain.configuration.definition.PropertyDefinition; import org.rhq.core.domain.configuration.definition.PropertyGroupDefinition; import org.rhq.core.domain.criteria.ResourceTypeCriteria; import org.rhq.core.domain.drift.DriftConfigurationDefinition.BaseDirValueContext; import org.rhq.core.domain.drift.DriftDefinition; import org.rhq.core.domain.drift.DriftDefinition.BaseDirectory; import org.rhq.core.domain.drift.DriftDefinitionTemplate; import org.rhq.core.domain.event.EventDefinition; import org.rhq.core.domain.measurement.MeasurementDefinition; import org.rhq.core.domain.operation.OperationDefinition; import org.rhq.core.domain.resource.ProcessScan; import org.rhq.core.domain.resource.ResourceType; import org.rhq.enterprise.server.auth.SubjectManagerLocal; import org.rhq.enterprise.server.resource.ResourceTypeManagerLocal; import org.rhq.enterprise.server.util.LookupUtil; @Test(groups = { "plugin.extension.metadata", "plugin.metadata" }) public class PluginExtensionMetadataTest extends MetadataBeanTest { private static final String PLUGIN_NAME_PARENT = "PluginExtensionMetadataParentTestPlugin"; private static final String PLUGIN_NAME_CHILD = "PluginExtensionMetadataChildTestPlugin"; private static final String TYPE_NAME_PARENT = "ParentServerA"; private static final String TYPE_NAME_CHILD = "ChildServerA"; // names of things from the first version of the plugin metadata private static final String SUBCAT = "A-subcat"; private static final String SUBCAT_DISPLAYNAME = "a subcat"; private static final String PC_GROUP = "A-pc-group"; private static final boolean PC_GROUP_HIDDEN = true; private static final String PC_PROP = "A-pc-prop"; private static final boolean PC_PROP_REQUIRED = false; private static final String PROCESS_SCAN_NAME = "A-process-scan"; private static final String PROCESS_SCAN_QUERY = "process|basename|match=A.exe"; private static final String OP_NAME = "A-op"; private static final int OP_TIMEOUT = 123456; private static final String OP_DESC = "a op"; private static final String METRIC_PROP = "A-metric"; private static final long METRIC_DEFAULT_INTERVAL = 123456L; private static final String EVENT_NAME = "A-event"; private static final String EVENT_DESC = "a event"; private static final String RC_PROP = "A-rc-prop"; private static final boolean RC_PROP_REQUIRED = false; private static final String DRIFT_DEF_NAME = "A-drift-def"; private static final BaseDirValueContext DRIFT_DEF_BASEDIR_CONTEXT = BaseDirValueContext.pluginConfiguration; private static final String DRIFT_DEF_BASEDIR_VALUE = PC_PROP; private static final String BUNDLE_TARGET_NAME = "A-bundle-basedir"; private static final Context BUNDLE_BASEDIR_CONTEXT = Context.resourceConfiguration; private static final String BUNDLE_BASEDIR_VALUE = RC_PROP; // names of things from the second, updated version of the plugin metadata // updated plugin config private static final String CHANGED_PC_GROUP = PC_GROUP; // we only change its members, not the name itself private static final boolean CHANGED_PC_GROUP_HIDDEN = false; private static final String CHANGED_PC_PROP = "A-pc-prop-CHANGED"; private static final boolean CHANGED_PC_PROP_REQUIRED = true; private static final String NEW_PC_GROUP = "A-pc-group-NEW"; private static final boolean NEW_PC_GROUP_HIDDEN = true; private static final String NEW_PC_PROP = "A-pc-prop-NEW"; private static final boolean NEW_PC_PROP_REQUIRED = false; // updated process scans private static final String CHANGED_PROCESS_SCAN_NAME = "A-process-scan"; private static final String CHANGED_PROCESS_SCAN_QUERY = "process|basename|match=CHANGED.exe"; private static final String NEW_PROCESS_SCAN_NAME = "A-process-scan-NEW"; private static final String NEW_PROCESS_SCAN_QUERY = "process|basename|match=NEW.exe"; // updated operations private static final String CHANGED_OP_NAME = OP_NAME; // we don't actually change its name in our test private static final int CHANGED_OP_TIMEOUT = 987654; private static final String CHANGED_OP_DESC = "a changed op"; private static final String NEW_OP_NAME = "A-op-NEW"; private static final int NEW_OP_TIMEOUT = 111111; private static final String NEW_OP_DESC = "a new op"; // updated metrics private static final String CHANGED_METRIC_PROP = METRIC_PROP; // we don't actually change its name in our test private static final String NEW_METRIC_PROP = "A-metric-NEW"; private static final long NEW_METRIC_DEFAULT_INTERVAL = 98765L; // updated events private static final String CHANGED_EVENT_NAME = "A-event-CHANGED"; private static final String CHANGED_EVENT_DESC = "a changed event"; private static final String NEW_EVENT_NAME = "A-event-NEW"; private static final String NEW_EVENT_DESC = "a new event"; // updated resource config private static final String CHANGED_RC_PROP = "A-rc-prop-CHANGED"; private static final boolean CHANGED_RC_PROP_REQUIRED = true; private static final String NEW_RC_PROP = "A-rc-prop-NEW"; private static final boolean NEW_RC_PROP_REQUIRED = false; // updated drift private static final String CHANGED_DRIFT_DEF_NAME = "A-drift-def-CHANGED"; private static final BaseDirValueContext CHANGED_DRIFT_DEF_BASEDIR_CONTEXT = BaseDirValueContext.pluginConfiguration; private static final String CHANGED_DRIFT_DEF_BASEDIR_VALUE = PC_PROP; private static final String NEW_DRIFT_DEF_NAME = "A-drift-def-NEW"; private static final BaseDirValueContext NEW_DRIFT_DEF_BASEDIR_CONTEXT = BaseDirValueContext.resourceConfiguration; private static final String NEW_DRIFT_DEF_BASEDIR_VALUE = RC_PROP; // updated bundle private static final String CHANGED_BUNDLE_TARGET_NAME = "A-bundle-basedir-CHANGED"; private static final Context CHANGED_BUNDLE_BASEDIR_CONTEXT = Context.resourceConfiguration; private static final String CHANGED_BUNDLE_BASEDIR_VALUE = RC_PROP; private static final String NEW_BUNDLE_TARGET_NAME = "A-bundle-basedir-NEW"; private static final Context NEW_BUNDLE_BASEDIR_CONTEXT = Context.pluginConfiguration; private static final String NEW_BUNDLE_BASEDIR_VALUE = PC_PROP; private SubjectManagerLocal subjectMgr; private ResourceTypeManagerLocal resourceTypeMgr; public void testRegisterPlugins() throws Exception { subjectMgr = LookupUtil.getSubjectManager(); resourceTypeMgr = LookupUtil.getResourceTypeManager(); registerParentPluginV1(); // create an initial type (called the parent) registerChildPluginV1(); // using plugin extension mechanism, create a child type that extends that parent type registerParentPluginV2(); // update the parent type checkChildPlugin(); // check that the changes to the parent type propogated to the child } // this needs to be the last test executed in the class, it does cleanup @Test(priority = 10, alwaysRun = true, dependsOnMethods = { "testRegisterPlugins" }) public void afterClassWorkTest() throws Exception { afterClassWork(); } private void registerParentPluginV1() throws Exception { // register the plugin, load the new type and test to make sure its what we expect createPlugin("parent-plugin.jar", "1.0", "parent_plugin_v1.xml"); ResourceType resourceType = loadResourceTypeFully(TYPE_NAME_PARENT, PLUGIN_NAME_PARENT); assert resourceType.getName().equals(TYPE_NAME_PARENT); assert resourceType.getPlugin().equals(PLUGIN_NAME_PARENT); assertVersion1(resourceType); } private void registerChildPluginV1() throws Exception { // register the plugin, load the new type and test to make sure its what we expect createPlugin("child-plugin.jar", "1.0", "child_plugin_v1.xml"); ResourceType resourceType = loadResourceTypeFully(TYPE_NAME_CHILD, PLUGIN_NAME_CHILD); assert resourceType.getName().equals(TYPE_NAME_CHILD); assert resourceType.getPlugin().equals(PLUGIN_NAME_CHILD); assertVersion1(resourceType); } private void registerParentPluginV2() throws Exception { // register the plugin, load the new type and test to make sure its what we expect createPlugin("parent-plugin.jar", "2.0", "parent_plugin_v2.xml"); ResourceType resourceType = loadResourceTypeFully(TYPE_NAME_PARENT, PLUGIN_NAME_PARENT); assert resourceType.getName().equals(TYPE_NAME_PARENT); assert resourceType.getPlugin().equals(PLUGIN_NAME_PARENT); assertVersion2(resourceType); } private void checkChildPlugin() throws Exception { // load the child type and test to make sure it has been updated to what we expect ResourceType resourceType = loadResourceTypeFully(TYPE_NAME_CHILD, PLUGIN_NAME_CHILD); assert resourceType.getName().equals(TYPE_NAME_CHILD); assert resourceType.getPlugin().equals(PLUGIN_NAME_CHILD); assertVersion2(resourceType); } private void assertVersion1(ResourceType resourceType) { PropertyGroupDefinition group; PropertyDefinition prop; ProcessScan processScan; OperationDefinition op; MeasurementDefinition metric; EventDefinition event; DriftDefinitionTemplate drift; BaseDirectory driftBasedir; ResourceTypeBundleConfiguration bundle; BundleDestinationBaseDirectory bundleBasedir; assert resourceType.getChildSubCategories() == null; assert resourceType.getPluginConfigurationDefinition().getGroupDefinitions().size() == 1; group = resourceType.getPluginConfigurationDefinition().getGroupDefinitions().get(0); assert group.getName().equals(PC_GROUP); assert group.isDefaultHidden() == PC_GROUP_HIDDEN; prop = resourceType.getPluginConfigurationDefinition().get(PC_PROP); assert prop != null; assert prop.getName().equals(PC_PROP); assert prop.isRequired() == PC_PROP_REQUIRED; assert prop.getPropertyGroupDefinition().getName().equals(PC_GROUP); assert resourceType.getProcessScans().size() == 1; processScan = resourceType.getProcessScans().iterator().next(); assert processScan.getName().equals(PROCESS_SCAN_NAME); assert processScan.getQuery().equals(PROCESS_SCAN_QUERY); assert resourceType.getOperationDefinitions().size() == 1; op = resourceType.getOperationDefinitions().iterator().next(); assert op.getName().equals(OP_NAME); assert op.getTimeout().intValue() == OP_TIMEOUT; assert op.getDescription().equals(OP_DESC); assert resourceType.getMetricDefinitions().size() == 2; // include built-in Availability metric metric = resourceType.getMetricDefinitions().iterator().next(); assert metric.getName().equals(METRIC_PROP); assert metric.getDefaultInterval() == METRIC_DEFAULT_INTERVAL; assert resourceType.getEventDefinitions().size() == 1; event = resourceType.getEventDefinitions().iterator().next(); assert event.getName().equals(EVENT_NAME); assert event.getDescription().equals(EVENT_DESC); assert resourceType.getResourceConfigurationDefinition().getGroupDefinitions().size() == 0; prop = resourceType.getResourceConfigurationDefinition().get(RC_PROP); assert prop != null; assert prop.getName().equals(RC_PROP); assert prop.isRequired() == RC_PROP_REQUIRED; assert resourceType.getDriftDefinitionTemplates().size() == 1; drift = resourceType.getDriftDefinitionTemplates().iterator().next(); assert drift.getTemplateDefinition().getName().equals(DRIFT_DEF_NAME); driftBasedir = drift.getTemplateDefinition().getBasedir(); assert driftBasedir.getValueContext().equals(DRIFT_DEF_BASEDIR_CONTEXT); assert driftBasedir.getValueName().equals(DRIFT_DEF_BASEDIR_VALUE); bundle = resourceType.getResourceTypeBundleConfiguration(); assert bundle.getBundleDestinationBaseDirectories().size() == 1; bundleBasedir = bundle.getBundleDestinationBaseDirectories().iterator().next(); assert bundleBasedir.getName().equals(BUNDLE_TARGET_NAME); assert bundleBasedir.getValueContext().equals(BUNDLE_BASEDIR_CONTEXT); assert bundleBasedir.getValueName().equals(BUNDLE_BASEDIR_VALUE); } private void assertVersion2(ResourceType resourceType) { PropertyDefinition prop; Set<String> seen = new HashSet<String>(2); // we use to this remember names of the things that we've seen assert resourceType.getChildSubCategories() == null; seen.clear(); ConfigurationDefinition pcDef = resourceType.getPluginConfigurationDefinition(); assert pcDef.getGroupDefinitions().size() == 2; for (PropertyGroupDefinition group : pcDef.getGroupDefinitions()) { seen.add(group.getName()); if (group.getName().equals(CHANGED_PC_GROUP)) { assert group.isDefaultHidden() == CHANGED_PC_GROUP_HIDDEN; } else if (group.getName().equals(NEW_PC_GROUP)) { assert group.isDefaultHidden() == NEW_PC_GROUP_HIDDEN; } else { assert false : "Unexpected group [" + group.getName() + "]:" + group; } } if (seen.size() != 2) { assert false : "did not see what we expected to see: " + seen; } prop = pcDef.get(CHANGED_PC_PROP); assert prop != null; assert prop.getName().equals(CHANGED_PC_PROP); assert prop.isRequired() == CHANGED_PC_PROP_REQUIRED; assert prop.getPropertyGroupDefinition().getName().equals(CHANGED_PC_GROUP); prop = pcDef.get(NEW_PC_PROP); assert prop != null; assert prop.getName().equals(NEW_PC_PROP); assert prop.isRequired() == NEW_PC_PROP_REQUIRED; assert prop.getPropertyGroupDefinition().getName().equals(NEW_PC_GROUP); seen.clear(); assert resourceType.getProcessScans().size() == 2; for (ProcessScan processScan : resourceType.getProcessScans()) { seen.add(processScan.getName()); if (processScan.getName().equals(CHANGED_PROCESS_SCAN_NAME)) { assert processScan.getQuery().equals(CHANGED_PROCESS_SCAN_QUERY); } else if (processScan.getName().equals(NEW_PROCESS_SCAN_NAME)) { assert processScan.getQuery().equals(NEW_PROCESS_SCAN_QUERY); } else { assert false : "Unexpected process scan[" + processScan.getName() + "]:" + processScan; } } if (seen.size() != 2) { assert false : "did not see what we expected to see: " + seen; } seen.clear(); assert resourceType.getOperationDefinitions().size() == 2; for (OperationDefinition op : resourceType.getOperationDefinitions()) { seen.add(op.getName()); if (op.getName().equals(CHANGED_OP_NAME)) { assert op.getTimeout().intValue() == CHANGED_OP_TIMEOUT; assert op.getDescription().equals(CHANGED_OP_DESC); } else if (op.getName().equals(NEW_OP_NAME)) { assert op.getTimeout().intValue() == NEW_OP_TIMEOUT; assert op.getDescription().equals(NEW_OP_DESC); } else { assert false : "Unexpected operation [" + op.getName() + "]:" + op; } } if (seen.size() != 2) { assert false : "did not see what we expected to see: " + seen; } seen.clear(); assert resourceType.getMetricDefinitions().size() == 3; // include built-in Availability metric for (MeasurementDefinition metric : resourceType.getMetricDefinitions()) { if (metric.getName().equals(MeasurementDefinition.AVAILABILITY_NAME)) { // expected, ignore continue; } seen.add(metric.getName()); if (metric.getName().equals(CHANGED_METRIC_PROP)) { // even though our _v2 plugin set this to something different, our upgrade doesn't change it because // we don't want to overwrite changes a user possibly made to the defaut interval (aka metric template) assert metric.getDefaultInterval() == METRIC_DEFAULT_INTERVAL; } else if (metric.getName().equals(NEW_METRIC_PROP)) { assert metric.getDefaultInterval() == NEW_METRIC_DEFAULT_INTERVAL; } else { assert false : "Unexpected metric [" + metric.getName() + "]:" + metric; } } if (seen.size() != 2) { assert false : "did not see what we expected to see: " + seen; } seen.clear(); assert resourceType.getEventDefinitions().size() == 2; for (EventDefinition event : resourceType.getEventDefinitions()) { seen.add(event.getName()); if (event.getName().equals(CHANGED_EVENT_NAME)) { assert event.getDescription().equals(CHANGED_EVENT_DESC); } else if (event.getName().equals(NEW_EVENT_NAME)) { assert event.getDescription().equals(NEW_EVENT_DESC); } else { assert false : "Unexpected event [" + event.getName() + "]:" + event; } } if (seen.size() != 2) { assert false : "did not see what we expected to see: " + seen; } assert resourceType.getResourceConfigurationDefinition().getGroupDefinitions().size() == 0; prop = resourceType.getResourceConfigurationDefinition().get(CHANGED_RC_PROP); assert prop != null; assert prop.getName().equals(CHANGED_RC_PROP); assert prop.isRequired() == CHANGED_RC_PROP_REQUIRED; prop = resourceType.getResourceConfigurationDefinition().get(NEW_RC_PROP); assert prop != null; assert prop.getName().equals(NEW_RC_PROP); assert prop.isRequired() == NEW_RC_PROP_REQUIRED; seen.clear(); assert resourceType.getDriftDefinitionTemplates().size() == 2; for (DriftDefinitionTemplate drift : resourceType.getDriftDefinitionTemplates()) { DriftDefinition def = drift.getTemplateDefinition(); seen.add(def.getName()); if (def.getName().equals(CHANGED_DRIFT_DEF_NAME)) { BaseDirectory driftBasedir = def.getBasedir(); assert driftBasedir.getValueContext().equals(CHANGED_DRIFT_DEF_BASEDIR_CONTEXT); assert driftBasedir.getValueName().equals(CHANGED_DRIFT_DEF_BASEDIR_VALUE); } else if (def.getName().equals(NEW_DRIFT_DEF_NAME)) { BaseDirectory driftBasedir = def.getBasedir(); assert driftBasedir.getValueContext().equals(NEW_DRIFT_DEF_BASEDIR_CONTEXT); assert driftBasedir.getValueName().equals(NEW_DRIFT_DEF_BASEDIR_VALUE); } else { assert false : "Unexpected drift def [" + def.getName() + "]:" + def; } } if (seen.size() != 2) { assert false : "did not see what we expected to see: " + seen; } seen.clear(); ResourceTypeBundleConfiguration bundle = resourceType.getResourceTypeBundleConfiguration(); assert bundle.getBundleDestinationBaseDirectories().size() == 2; for (BundleDestinationBaseDirectory bundleBasedir : bundle.getBundleDestinationBaseDirectories()) { seen.add(bundleBasedir.getName()); if (bundleBasedir.getName().equals(CHANGED_BUNDLE_TARGET_NAME)) { assert bundleBasedir.getValueContext().equals(CHANGED_BUNDLE_BASEDIR_CONTEXT); assert bundleBasedir.getValueName().equals(CHANGED_BUNDLE_BASEDIR_VALUE); } else if (bundleBasedir.getName().equals(NEW_BUNDLE_TARGET_NAME)) { assert bundleBasedir.getValueContext().equals(NEW_BUNDLE_BASEDIR_CONTEXT); assert bundleBasedir.getValueName().equals(NEW_BUNDLE_BASEDIR_VALUE); } else { assert false : "Unexpected bundle basedir [" + bundleBasedir.getName() + "]:" + bundleBasedir; } } if (seen.size() != 2) { assert false : "did not see what we expected to see: " + seen; } } private ResourceType loadResourceTypeFully(String typeName, String typePlugin) { ResourceTypeCriteria c = new ResourceTypeCriteria(); c.addFilterName(typeName); c.addFilterPluginName(typePlugin); c.setStrict(true); c.fetchPluginConfigurationDefinition(true); c.fetchProcessScans(true); c.fetchOperationDefinitions(true); c.fetchMetricDefinitions(true); c.fetchEventDefinitions(true); c.fetchResourceConfigurationDefinition(true); c.fetchDriftDefinitionTemplates(true); c.fetchBundleConfiguration(true); List<ResourceType> t = resourceTypeMgr.findResourceTypesByCriteria(subjectMgr.getOverlord(), c); ResourceType resourceType = t.get(0); return resourceType; } }