.classpath | 30 .gitignore | 2 etc/apt/pom.xml | 199 + etc/apt/src/main/java/org/rhq/plugins/apt/AptSourcesComponent.java | 144 + etc/apt/src/main/java/org/rhq/plugins/apt/AptSourcesDiscoveryComponent.java | 50 etc/apt/src/main/resources/META-INF/rhq-plugin.xml | 48 etc/apt/src/test/java/org/rhq/plugins/apt/AptSourcesComponentTest.java | 93 etc/apt/src/test/resources/log4j.xml | 32 etc/eclipse-tools/maven/RHQ | 22 etc/eclipse-tools/templates/schema.xmlcatalog | 22 etc/m2/settings-linux-config.xml | 54 etc/m2/settings-rawconfig.xml | 1 etc/m2/settings.xml | 15 etc/samples/perspectives/sample-perspective/app/pom.xml | 143 + etc/samples/perspectives/sample-perspective/app/src/main/webapp/WEB-INF/web.xml | 12 etc/samples/perspectives/sample-perspective/app/src/main/webapp/images/create.png |binary etc/samples/perspectives/sample-perspective/app/src/main/webapp/images/jboss.png |binary etc/samples/perspectives/sample-perspective/app/src/main/webapp/index.html | 14 etc/samples/perspectives/sample-perspective/perspective/pom.xml | 159 + etc/samples/perspectives/sample-perspective/perspective/src/main/resources/META-INF/rhq-serverplugin.xml | 127 + etc/samples/perspectives/sample-perspective/pom.xml | 45 etc/samples/simplereport-serverplugin/pom.xml | 158 + etc/samples/simplereport-serverplugin/src/main/java/org/custom/SimpleReportsPluginComponent.java | 277 ++ etc/samples/simplereport-serverplugin/src/main/resources/META-INF/rhq-serverplugin.xml | 81 modules/core/client-api/pom.xml | 20 modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/configuration/ConfigurationAgentService.java | 20 modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/metadata/ConfigurationMetadataParser.java | 21 modules/core/client-api/src/main/java/org/rhq/core/clientapi/descriptor/PluginTransformException.java | 48 modules/core/client-api/src/main/java/org/rhq/core/clientapi/descriptor/PluginTransformer.java | 131 + modules/core/client-api/src/main/resources/rhq-configuration.xsd | 10 modules/core/client-api/src/test/groovy/org/rhq/core/clientapi/agent/metadata/PluginMetadataParserTest.groovy | 392 +++ modules/core/client-api/src/test/java/org/rhq/core/clientapi/descriptor/PluginTransformerTest.java | 318 ++ modules/core/dbutils/pom.xml | 50 modules/core/dbutils/pom.xml.orig | 279 ++ modules/core/dbutils/src/main/scripts/dbsetup/alert-schema.xml | 13 modules/core/dbutils/src/main/scripts/dbsetup/config-schema.xml | 3 modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml | 268 +- modules/core/domain/src/main/java/META-INF/MANIFEST.MF | 4 modules/core/domain/src/main/java/org/rhq/core/domain/alert/Alert.java | 56 modules/core/domain/src/main/java/org/rhq/core/domain/alert/notification/AlertNotification.java | 48 modules/core/domain/src/main/java/org/rhq/core/domain/alert/notification/EmailNotification.java | 3 modules/core/domain/src/main/java/org/rhq/core/domain/alert/notification/NotificationTemplate.java | 123 + modules/core/domain/src/main/java/org/rhq/core/domain/alert/notification/RoleNotification.java | 3 modules/core/domain/src/main/java/org/rhq/core/domain/alert/notification/SnmpNotification.java | 3 modules/core/domain/src/main/java/org/rhq/core/domain/alert/notification/SubjectNotification.java | 3 modules/core/domain/src/main/java/org/rhq/core/domain/configuration/AbstractConfigurationUpdate.java | 6 modules/core/domain/src/main/java/org/rhq/core/domain/configuration/AbstractResourceConfigurationUpdate.java | 3 modules/core/domain/src/main/java/org/rhq/core/domain/configuration/Configuration.java | 70 modules/core/domain/src/main/java/org/rhq/core/domain/configuration/RawConfiguration.java | 17 modules/core/domain/src/main/java/org/rhq/core/domain/configuration/definition/ConfigurationDefinition.java | 29 modules/core/domain/src/main/java/org/rhq/core/domain/configuration/definition/ConfigurationFormat.java | 49 modules/core/domain/src/main/java/org/rhq/core/domain/measurement/MeasurementDefinition.java | 17 modules/core/domain/src/main/java/org/rhq/core/domain/plugin/Plugin.java | 10 modules/core/domain/src/main/java/org/rhq/core/domain/plugin/ServerPlugin.java | 85 modules/core/domain/src/main/java/org/rhq/core/domain/util/EntitySerializer.java | 2 modules/core/domain/src/test/java/org/rhq/core/domain/configuration/AbstractConfigurationUpdateTest.java | 114 + modules/core/domain/src/test/java/org/rhq/core/domain/configuration/ConfigurationTest.java | 258 ++ modules/core/domain/src/test/java/org/rhq/core/domain/configuration/PluginConfigurationUpdateTest.java | 67 modules/core/domain/src/test/java/org/rhq/core/domain/configuration/RawConfigurationTest.java | 12 modules/core/domain/src/test/java/org/rhq/core/domain/configuration/ResourceConfigurationUpdateTest.java | 67 modules/core/domain/src/test/java/org/rhq/core/domain/configuration/TestUtil.java | 45 modules/core/domain/src/test/java/org/rhq/core/domain/configuration/group/GroupPluginConfigurationUpdateTest.java | 51 modules/core/domain/src/test/java/org/rhq/core/domain/configuration/group/GroupResourceConfigurationUpdateTest.java | 51 modules/core/domain/src/test/java/org/rhq/core/domain/configuration/test/ConfigurationDefinitionTest.java | 2 modules/core/domain/src/test/java/org/rhq/core/domain/resource/test/PluginTest.java | 9 modules/core/domain/src/test/java/org/rhq/core/domain/resource/test/ServerPluginTest.java | 13 modules/core/gui/src/main/java/org/rhq/core/gui/configuration/AbstractConfigurationComponent.java | 2 modules/core/gui/src/main/java/org/rhq/core/gui/configuration/ConfigRenderer.java | 3 modules/core/native-system/src/main/java/org/rhq/core/system/NativeSystemInfo.java | 3 modules/core/native-system/src/main/java/org/rhq/core/system/ProcessInfo.java | 107 modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/configuration/ConfigurationFacet.java | 2 modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/configuration/ConfigurationFacetSupport.java | 27 modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/configuration/ResourceConfigurationFacet.java | 49 modules/core/plugin-container/pom.xml | 7 modules/core/plugin-container/src/main/java/org/rhq/core/pc/PluginContainer.java | 6 modules/core/plugin-container/src/main/java/org/rhq/core/pc/PluginContainerConfiguration.java | 16 modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigManagement.java | 48 modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigManagementFactory.java | 32 modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigManagementFactoryImpl.java | 89 modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigManagementSupport.java | 82 modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManager.java | 199 + modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManagerInitializer.java | 41 modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationUpdateException.java | 55 modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationUtilityService.java | 37 modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationUtilityServiceImpl.java | 42 modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LegacyConfigManagement.java | 102 modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/RawConfigManagement.java | 74 modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/StructuredAndRawConfigManagement.java | 95 modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/StructuredConfigManagement.java | 75 modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/UpdateInProgressException.java | 43 modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/UpdateResourceConfigurationRunner.java | 100 modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/AutoDiscoveryExecutor.java | 9 modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java | 4 modules/core/plugin-container/src/main/java/org/rhq/core/pc/plugin/PluginLifecycleListenerManager.java | 73 modules/core/plugin-container/src/main/java/org/rhq/core/pc/plugin/PluginLifecycleListenerManagerImpl.java | 115 + modules/core/plugin-container/src/main/java/org/rhq/core/pc/plugin/PluginManager.java | 132 - modules/core/plugin-container/src/main/java/org/rhq/core/pc/util/ComponentService.java | 39 modules/core/plugin-container/src/main/java/org/rhq/core/pc/util/ComponentServiceImpl.java | 51 modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigManagementFactoryImplTest.java | 269 ++ modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigManagementTest.java | 141 + modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigurationManagerTest.java | 431 ++- modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LegacyConfigManagementTest.java | 212 + modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/RawConfigManagementTest.java | 158 + modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/StructuredAndRawConfigManagementTest.java | 211 + modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/StructuredConfigManagementTest.java | 139 + modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/UpdateResourceConfigurationRunnerTest.java | 307 ++ modules/core/plugin-container/src/test/java/org/rhq/core/pc/plugin/PluginManagerTest.java | 370 +++ modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/PluginUpdate.java | 3 modules/enterprise/gui/perspectives/pom.xml | 33 modules/enterprise/gui/perspectives/sample-perspective-war/pom.xml | 143 - modules/enterprise/gui/perspectives/sample-perspective-war/src/main/webapp/WEB-INF/web.xml | 12 modules/enterprise/gui/perspectives/sample-perspective-war/src/main/webapp/index.html | 14 modules/enterprise/gui/pom.xml | 3 modules/enterprise/gui/portal-war/pom.xml | 10 modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/config/SystemConfigForm.java | 205 - modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/AbstractPluginConfigurationUIBean.java | 97 modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/EditPluginConfigurationUIBean.java | 149 + modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/InstalledPluginComponent.java | 86 modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/InstalledPluginsSessionUIBean.java | 51 modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/InstalledPluginsUIBean.java | 145 + modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/PluginConfigurationUIBean.java | 102 modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/PluginFactory.java | 63 modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/GenericAlertStuffUIBean.java | 99 modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/ListNotificationsUIBean.java | 191 + modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/common/tabbar/AbstractTabComponent.java | 8 modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/AbstractConfigurationUIBean.java | 16 modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/AbstractResourceConfigurationUIBean.java | 47 modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ExistingResourceConfigurationUIBean.java | 344 +++ modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/RawConfigCollection.java | 209 - modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/inventory/resource/CreateNewConfigurationChildResourceUIBean.java | 4 modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/inventory/resource/ResourceUIBean.java | 9 modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/ParamConstants.java | 2 modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/action/resource/common/monitor/alerts/config/PortalAction.java | 27 modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/action/resource/common/monitor/alerts/config/SnmpTrapForm.java | 67 modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/action/resource/common/monitor/alerts/config/SnmpTrapFormAction.java | 121 - modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/action/resource/common/monitor/alerts/config/SnmpTrapFormPrepareAction.java | 81 modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/navigation/resource/ResourceTreeStateAdvisor.java | 3 modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/perspectives/PerspectivesMenuUIBean.java | 77 modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/startup/StartupServlet.java | 13 modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/util/EnterpriseFacesContextUtility.java | 8 modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/util/WebUtility.java | 5 modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/classes/messages.properties | 19 modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-managed-beans/admin-beans.xml | 19 modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-managed-beans/alert-beans.xml | 4 modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-managed-beans/configuration-beans.xml | 6 modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-managed-beans/perspectives-beans.xml | 19 modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-navigation/admin-navigation.xml | 76 modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-navigation/configuration-navigation.xml | 41 modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/struts-config.xml | 20 modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/tiles/events-def.xml | 50 modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/validation/validation.xml | 68 modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/web.xml | 1 modules/enterprise/gui/portal-war/src/main/webapp/admin/config/EditServerConfig.jsp | 3 modules/enterprise/gui/portal-war/src/main/webapp/admin/config/SNMPForm.jsp | 171 - modules/enterprise/gui/portal-war/src/main/webapp/admin/test/control.jsp | 6 modules/enterprise/gui/portal-war/src/main/webapp/images/save.png |binary modules/enterprise/gui/portal-war/src/main/webapp/js/iframeSSI.js | 77 modules/enterprise/gui/portal-war/src/main/webapp/resource/common/monitor/alerts/config/SnmpActionProps.jsp | 34 modules/enterprise/gui/portal-war/src/main/webapp/resource/common/monitor/alerts/config/ViewDefinition.jsp | 5 modules/enterprise/gui/portal-war/src/main/webapp/resource/common/monitor/alerts/config/ViewDefinitionNotifications.jsp | 24 modules/enterprise/gui/portal-war/src/main/webapp/resource/common/monitor/alerts/config/ViewDefinitionNotificationsTabs.jsp | 41 modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-config.xhtml | 62 modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-details-edit.xhtml | 24 modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-details-view.xhtml | 28 modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-details.xhtml | 11 modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-edit-add-map.xhtml | 32 modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-edit-map.xhtml | 57 modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-edit-update-map.xhtml | 33 modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-edit-view-map.xhtml | 26 modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-edit.xhtml | 68 modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-list.xhtml | 77 modules/enterprise/gui/portal-war/src/main/webapp/rhq/common/menu/menu.xhtml | 832 ++----- modules/enterprise/gui/portal-war/src/main/webapp/rhq/common/menu/menuitem.xhtml | 255 ++ modules/enterprise/gui/portal-war/src/main/webapp/rhq/common/perspective-main.xhtml | 42 modules/enterprise/gui/portal-war/src/main/webapp/rhq/empty.xhtml | 7 modules/enterprise/gui/portal-war/src/main/webapp/rhq/layout/main-layout.xhtml | 8 modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/alert/notif/listAlertSender.xhtml | 144 + modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/download.jsp | 11 modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit-raw-full.xhtml | 38 modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit-raw.xhtml | 126 - modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit.xhtml | 16 modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/upload.xhtml | 55 modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view-map.xhtml | 4 modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view-raw-full.xhtml | 38 modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view-raw.xhtml | 113 + modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml | 221 + modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/layout/main.xhtml | 72 modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/perspective/index.xhtml | 6 modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/utility/ScriptUtil.java | 14 modules/enterprise/remoting/scripts/src/main/script/configuration/config_util.js | 287 ++ modules/enterprise/remoting/scripts/src/test/script/org/rhq/enterprise/remoting/cli/test_ConfigurationManager.js | 237 +- modules/enterprise/server/container/pom.xml | 7 modules/enterprise/server/container/src/main/scripts/rhq-container.build.xml | 5 modules/enterprise/server/ear/pom.xml | 933 ++++---- modules/enterprise/server/jar/pom.xml | 5 modules/enterprise/server/jar/src/main/java/META-INF/MANIFEST.MF | 14 modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/RHQConstants.java | 18 modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerBean.java | 144 - modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerLocal.java | 30 modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerBean.java | 168 + modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerLocal.java | 68 modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/SnmpTrapSender.java | 789 ------- modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java | 122 - modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerLocal.java | 13 modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerRemote.java | 12 modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationUpdateNotSupportedException.java | 42 modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/TranslationNotSupportedException.java | 48 modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/RepoManagerBean.java | 3 modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/plugin/AgentPluginScanner.java | 2 modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/plugin/PluginDeploymentScanner.java | 19 modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/plugin/ProductPluginDeployer.java | 16 modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/plugin/ServerPluginScanner.java | 413 +-- modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementScheduleManagerBean.java | 176 + modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/perspective/MenuItem.java | 46 modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveException.java | 40 modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveManagerBean.java | 326 ++ modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveManagerHelper.java | 42 modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveManagerLocal.java | 30 modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/perspective/Tab.java | 167 + modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsBean.java | 313 +- modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsLocal.java | 91 modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/AbstractJobWrapper.java | 4 modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/AbstractTypeServerPluginContainer.java | 78 modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ClassLoaderManager.java | 36 modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/MasterServerPluginContainer.java | 70 modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginManager.java | 169 + modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginValidator.java | 59 modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginValidatorUtil.java | 310 ++ modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertBackingBean.java | 34 modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertPluginValidator.java | 90 modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSender.java | 60 modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSenderInfo.java | 78 modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSenderPluginManager.java | 240 ++ modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertServerPluginContainer.java | 8 modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/ResultState.java | 31 modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/SenderResult.java | 103 modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/content/ContentPluginValidator.java | 30 modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/generic/GenericPluginValidator.java | 30 modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/perspective/PerspectivePluginValidator.java | 30 modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/perspective/PerspectiveServerPluginContainer.java | 10 modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/perspective/PerspectiveServerPluginManager.java | 220 + modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/perspective/metadata/PerspectivePluginMetadataManager.java | 467 ++++ modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java | 30 modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerLocal.java | 6 modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerRemote.java | 20 modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/metadata/ResourceMetadataManagerBean.java | 46 modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/webservices/WebservicesManagerBean.java | 17 modules/enterprise/server/jar/src/main/resources/perspectives/admin.xml | 5 modules/enterprise/server/jar/src/main/resources/perspectives/content.xml | 29 modules/enterprise/server/jar/src/main/resources/perspectives/middleware.xml | 5 modules/enterprise/server/jar/src/main/resources/perspectives/root.xml | 5 modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBeanTest.java | 10 modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBeanUnitTest.java | 559 +++++ modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/plugin/ServerPluginsBeanTest.java | 22 modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/plugin/pc/generic/GenericServerPluginTest.java | 2 modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/test/TestAgentClient.java | 10 modules/enterprise/server/license-gen/jar/pom.xml | 2 modules/enterprise/server/license-gen/maven-plugin/pom.xml | 2 modules/enterprise/server/plugins/alert-email/pom.xml | 137 + modules/enterprise/server/plugins/alert-email/src/main/java/org/rhq/enterprise/server/plugins/alertEmail/EmailAlertComponent.java | 50 modules/enterprise/server/plugins/alert-email/src/main/java/org/rhq/enterprise/server/plugins/alertEmail/EmailSender.java | 83 modules/enterprise/server/plugins/alert-email/src/main/resources/META-INF/rhq-serverplugin.xml | 51 modules/enterprise/server/plugins/alert-irc/pom.xml | 195 + modules/enterprise/server/plugins/alert-irc/src/main/java/org/rhq/enterprise/server/plugins/alertIrc/IrcAlertComponent.java | 169 + modules/enterprise/server/plugins/alert-irc/src/main/java/org/rhq/enterprise/server/plugins/alertIrc/IrcSender.java | 72 modules/enterprise/server/plugins/alert-irc/src/main/resources/META-INF/rhq-serverplugin.xml | 49 modules/enterprise/server/plugins/alert-microblog/pom.xml | 196 + modules/enterprise/server/plugins/alert-microblog/src/main/java/org/rhq/enterprise/server/plugins/alertMicroblog/MicroblogSender.java | 73 modules/enterprise/server/plugins/alert-microblog/src/main/resources/META-INF/rhq-serverplugin.xml | 40 modules/enterprise/server/plugins/alert-mobicents/pom.xml | 130 + modules/enterprise/server/plugins/alert-mobicents/src/main/java/org/rhq/enterprise/server/plugins/alertMobicents/MobiKind.java | 30 modules/enterprise/server/plugins/alert-mobicents/src/main/java/org/rhq/enterprise/server/plugins/alertMobicents/MobicentsSender.java | 169 + modules/enterprise/server/plugins/alert-mobicents/src/main/resources/META-INF/rhq-serverplugin.xml | 53 modules/enterprise/server/plugins/alert-roles/pom.xml | 159 + modules/enterprise/server/plugins/alert-roles/src/main/java/org/rhq/enterprise/server/plugins/alertRoles/RolesBackingBean.java | 68 modules/enterprise/server/plugins/alert-roles/src/main/java/org/rhq/enterprise/server/plugins/alertRoles/RolesSender.java | 44 modules/enterprise/server/plugins/alert-roles/src/main/resources/META-INF/rhq-serverplugin.xml | 34 modules/enterprise/server/plugins/alert-roles/src/main/resources/roles.xhtml | 34 modules/enterprise/server/plugins/alert-snmp/pom.xml | 162 + modules/enterprise/server/plugins/alert-snmp/src/main/java/org/rhq/enterprise/server/plugins/alertSnmp/SnmpSender.java | 88 modules/enterprise/server/plugins/alert-snmp/src/main/java/org/rhq/enterprise/server/plugins/alertSnmp/SnmpTrapSender.java | 794 +++++++ modules/enterprise/server/plugins/alert-snmp/src/main/resources/META-INF/rhq-serverplugin.xml | 84 modules/enterprise/server/plugins/disk/src/main/java/org/rhq/enterprise/server/plugins/disk/DiskSource.java | 157 - modules/enterprise/server/plugins/disk/src/main/resources/META-INF/rhq-serverplugin.xml | 62 modules/enterprise/server/plugins/jboss-software/src/main/resources/META-INF/rhq-serverplugin.xml | 4 modules/enterprise/server/plugins/perspectives/core/perspective/pom.xml | 123 + modules/enterprise/server/plugins/perspectives/core/perspective/src/main/resources/META-INF/rhq-serverplugin.xml | 889 ++++++++ modules/enterprise/server/plugins/perspectives/core/pom.xml | 44 modules/enterprise/server/plugins/pom.xml | 76 modules/enterprise/server/plugins/url/src/main/resources/META-INF/rhq-serverplugin.xml | 12 modules/enterprise/server/plugins/validate-all-serverplugins/pom.xml | 70 modules/enterprise/server/plugins/yum/src/main/resources/META-INF/rhq-serverplugin.xml | 4 modules/enterprise/server/pom.xml | 2 modules/enterprise/server/xml-schemas/src/main/java/org/rhq/enterprise/server/xmlschema/ServerPluginDescriptorMetadataParser.java | 57 modules/enterprise/server/xml-schemas/src/main/java/org/rhq/enterprise/server/xmlschema/ServerPluginDescriptorUtil.java | 6 modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-alert.xsd | 66 modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-perspective.xsd | 1106 +++++++++- modules/enterprise/server/xml-schemas/src/test/java/org/rhq/enterprise/server/xmlschema/ServerPluginDescriptorUtilTest.java | 15 modules/enterprise/server/xml-schemas/src/test/resources/test-serverplugin-alert.xml | 4 modules/enterprise/server/xml-schemas/src/test/resources/test-serverplugin-perspective.xml | 14 modules/helpers/pluginGen/pom.xml | 2 modules/plugins/JBossOSGi/jopr-jbossOsgi-plugin.iml | 74 modules/plugins/apt/pom.xml | 199 - modules/plugins/apt/src/main/java/org/rhq/plugins/apt/AptSourcesComponent.java | 144 - modules/plugins/apt/src/main/java/org/rhq/plugins/apt/AptSourcesDiscoveryComponent.java | 50 modules/plugins/apt/src/main/resources/META-INF/rhq-plugin.xml | 48 modules/plugins/apt/src/test/java/org/rhq/plugins/apt/AptSourcesComponentTest.java | 93 modules/plugins/apt/src/test/resources/log4j.xml | 32 modules/plugins/augeas/src/main/java/org/rhq/plugins/augeas/AugeasConfigurationComponent.java | 5 modules/plugins/cron/pom.xml | 1 modules/plugins/cron/src/main/java/org/rhq/plugins/cron/CronComponent.java | 8 modules/plugins/cron/src/main/java/org/rhq/plugins/cron/CronTabComponent.java | 6 modules/plugins/cron/src/main/java/org/rhq/plugins/cron/CronTabDiscoveryComponent.java | 10 modules/plugins/cron/src/test/java/org/rhq/plugins/cron/test/CronComponentTest.java | 116 + modules/plugins/cron/src/test/java/org/rhq/plugins/cron/test/CronTabComponentTest.java | 151 + modules/plugins/cron/src/test/resources/etc/cron.d/another-crontab | 4 modules/plugins/cron/src/test/resources/etc/crontab | 2 modules/plugins/hardware/pom.xml | 3 modules/plugins/irc/pom.xml | 5 modules/plugins/jboss-as-5/pom.xml | 2 modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/helper/JBossInstanceInfo.java | 10 modules/plugins/jboss-as/src/main/java/org/rhq/plugins/jbossas/helper/JBossInstanceInfo.java | 222 -- modules/plugins/jboss-cache-v3/pom.xml | 7 modules/plugins/jira/pom.xml | 4 modules/plugins/onewire/pom.xml | 3 modules/plugins/pom.xml | 6 modules/plugins/postfix/src/main/java/org/rhq/plugins/postfix/PostfixAccessComponent.java | 61 modules/plugins/postfix/src/main/java/org/rhq/plugins/postfix/PostfixAccessDiscoveryComponent.java | 50 modules/plugins/postfix/src/main/java/org/rhq/plugins/postfix/PostfixServerComponent.java | 74 modules/plugins/postfix/src/main/resources/META-INF/rhq-plugin.xml | 34 modules/plugins/postfix/src/test/java/org/rhq/plugins/postfix/PostfixComponentTest.java | 87 modules/plugins/postfix/src/test/resources/etc/postfix/main.cf | 11 modules/plugins/raw-config-test/pom.xml | 165 + modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/LegacyServer.groovy | 12 modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/RawDiscoveryComponent.groovy | 22 modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/RawServer.groovy | 89 modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/StructuredAndRawDiscoveryComponent.groovy | 23 modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/StructuredAndRawServer.groovy | 168 + modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/StructuredDiscoveryComponent.groovy | 24 modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/StructuredServer.groovy | 97 modules/plugins/raw-config-test/src/main/resources/META-INF/rhq-plugin.xml | 45 modules/plugins/raw-config-test/src/test/groovy/org/rhq/plugins/test/rawconfig/RawConfigServerTest.groovy | 12 modules/plugins/raw-config-test/src/test/groovy/org/rhq/plugins/test/rawconfig/RawServerTest.groovy | 29 modules/plugins/samba/src/main/java/org/rhq/plugins/samba/SambaServerComponent.java | 38 modules/plugins/samba/src/main/resources/META-INF/rhq-plugin.xml | 22 modules/plugins/samba/src/test/java/org/rhq/plugins/samba/SambaComponentTest.java | 11 modules/plugins/script2/pom.xml | 195 + modules/plugins/script2/src/main/java/org/rhq/modules/plugins/script2/ScriptComponent.java | 214 + modules/plugins/script2/src/main/java/org/rhq/modules/plugins/script2/ScriptDiscovery.java | 59 modules/plugins/script2/src/main/resources/META-INF/rhq-plugin.xml | 45 modules/plugins/snmptrapd/src/main/java/org/rhq/plugins/snmptrapd/SnmpTrapdDiscovery.java | 33 modules/plugins/snmptrapd/src/main/resources/META-INF/rhq-plugin.xml | 3 modules/plugins/validate-all-plugins/pom.xml | 1 modules/pom.xml | 28 modules/test-utils/pom.xml | 32 modules/test-utils/src/main/java/org/rhq/test/AssertUtils.java | 71 modules/test-utils/src/main/java/org/rhq/test/CollectionEqualsChecker.java | 91 modules/test-utils/src/main/java/org/rhq/test/EqualsResult.java | 44 modules/test-utils/src/main/java/org/rhq/test/JMockTest.java | 51 modules/test-utils/src/main/java/org/rhq/test/MatchResult.java | 44 modules/test-utils/src/main/java/org/rhq/test/PropertyMatchException.java | 43 modules/test-utils/src/main/java/org/rhq/test/PropertyMatcher.java | 88 modules/test-utils/src/main/java/org/rhq/test/jmock/PropertyMatcher.java | 56 pom.xml | 36 temp-testng-customsuite.xml | 8 365 files changed, 24785 insertions(+), 5935 deletions(-)
New commits: commit ec319f6e6e6181fb69efc15db81142e39c1f4845 Merge: c095978... 32b5c0f... Author: John Sanda john@localhost.localdomain Date: Tue Dec 29 08:53:20 2009 -0500
Merge branch 'master' into altlang-plugin
diff --cc modules/plugins/pom.xml index 062f5dc,6e7d53e..207fc6e --- a/modules/plugins/pom.xml +++ b/modules/plugins/pom.xml @@@ -121,9 -120,11 +120,12 @@@ <module>snmptrapd</module> <module>sshd</module> <module>twitter</module> + <module>alt-lang</module> <!--<module>virt</module>-->
+ <!-- this is just for testing raw config --> + <module>raw-config-test</module> + <!-- make this the last - it will validate all the plugins --> <module>validate-all-plugins</module> </modules>
commit 32b5c0f365c765461041b3df40bc01b45e91d9f6 Author: John Sanda john@localhost.localdomain Date: Mon Dec 21 16:24:12 2009 -0500
[BZ 537891] Adding fix for edge case in which id parameter was not passed when leaving raw edit page.
When editing a structured config (that also supports raw) and navigating to the raw edit page via the switch to raw link, the resource id parameter was not getting passed properly. As a result, when navigating to another tab for that resource from the raw edit page would result in an exception since the id parameter was null. Adding a navigation rule so that the parameter is passed.
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ExistingResourceConfigurationUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ExistingResourceConfigurationUIBean.java index b6aa356..fd89fab 100644 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ExistingResourceConfigurationUIBean.java +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ExistingResourceConfigurationUIBean.java @@ -393,7 +393,7 @@ public class ExistingResourceConfigurationUIBean extends AbstractConfigurationUI current = null; setConfiguration(configuration);
- return "/rhq/resource/configuration/edit-raw.xhtml?currentResourceId=" + getResourceId(); + return SUCCESS_OUTCOME; }
void dumpProperties(Configuration conf, Log log) { @@ -423,7 +423,6 @@ public class ExistingResourceConfigurationUIBean extends AbstractConfigurationUI current = null; setConfiguration(configuration);
-// return "/rhq/resource/configuration/edit.xhtml?currentResourceId=" + getResourceId(); return SUCCESS_OUTCOME; }
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-navigation/configuration-navigation.xml b/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-navigation/configuration-navigation.xml index 8f0749c..3c21035 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-navigation/configuration-navigation.xml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-navigation/configuration-navigation.xml @@ -29,6 +29,12 @@ <to-view-id>/rhq/resource/configuration/edit.xhtml?id=#{param.id}</to-view-id> <redirect/> </navigation-case> + + <navigation-case> + <from-action>#{ExistingResourceConfigurationUIBean.switchToraw}</from-action> + <to-view-id>/rhq/resource/configuration/edit-raw.xhtml?id=#{param.id}</to-view-id> + <redirect/> + </navigation-case>
</navigation-rule>
commit 41b03df6aecd682b79b1e725e3b3e2c615afb20b Author: John Sanda john@localhost.localdomain Date: Mon Dec 21 15:44:00 2009 -0500
Removing files from merge that were committed by accident
diff --git a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockServletContext.java.BACKUP.72367.java b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockServletContext.java.BACKUP.72367.java deleted file mode 100644 index 8740aca..0000000 --- a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockServletContext.java.BACKUP.72367.java +++ /dev/null @@ -1,167 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2009 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.core.gui.configuration; - -import java.io.InputStream; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.Map; -import java.util.Properties; -import java.util.Set; - -import javax.servlet.RequestDispatcher; -import javax.servlet.Servlet; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; - -import com.sun.faces.config.WebConfiguration; - -final class MockServletContext implements ServletContext { - public void setAttribute(String arg0, Object arg1) { - this.attributeMap.put(arg0, arg1); - - } - - public void removeAttribute(String arg0) { - attributeMap.remove(arg0); - - } - - public void log(String arg0, Throwable arg1) { - throw new RuntimeException("Function not implemented"); - - } - - public void log(Exception arg0, String arg1) { - throw new RuntimeException("Function not implemented"); - - } - - public void log(String arg0) { - throw new RuntimeException("Function not implemented"); - - } - - public Enumeration getServlets() { - throw new RuntimeException("Function not implemented"); - - } - - public Enumeration getServletNames() { - throw new RuntimeException("Function not implemented"); - - } - - public String getServletContextName() { - return MockServletContext.class.getSimpleName(); - - } - - public Servlet getServlet(String arg0) throws ServletException { - throw new RuntimeException("Function not implemented"); - - } - - public String getServerInfo() { - throw new RuntimeException("Function not implemented"); - - } - - public Set getResourcePaths(String arg0) { - throw new RuntimeException("Function not implemented"); - - } - - public InputStream getResourceAsStream(String arg0) { - throw new RuntimeException("Function not implemented"); - - } - - public URL getResource(String arg0) throws MalformedURLException { - throw new RuntimeException("Function not implemented"); - - } - - public RequestDispatcher getRequestDispatcher(String arg0) { - throw new RuntimeException("Function not implemented"); - - } - - public String getRealPath(String arg0) { - throw new RuntimeException("Function not implemented"); - - } - - public RequestDispatcher getNamedDispatcher(String arg0) { - throw new RuntimeException("Function not implemented"); - - } - - public int getMinorVersion() { - return 4; - } - - public String getMimeType(String arg0) { - throw new RuntimeException("Function not implemented"); - - } - - public int getMajorVersion() { - return 2; - - } - - Properties initParams = new Properties(); - - public Enumeration getInitParameterNames() { - return initParams.elements(); - - } - - public String getInitParameter(String key) { - return initParams.getProperty(key); - - } - - public ServletContext getContext(String arg0) { - throw new RuntimeException("Function not implemented"); - - } - - public Enumeration getAttributeNames() { - throw new RuntimeException("Function not implemented"); - - } - - Map<String, Object> attributeMap; - - public Object getAttribute(String key) { - if (null == attributeMap) { - attributeMap = new HashMap<String, Object>(); - WebConfiguration wc = WebConfiguration.getInstance(this); - - attributeMap.put("com.sun.faces.config.WebConfiguration", wc); - } - - return attributeMap.get(key); - } -} \ No newline at end of file diff --git a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockServletContext.java.BASE.72367.java b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockServletContext.java.BASE.72367.java deleted file mode 100644 index f604d00..0000000 --- a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockServletContext.java.BASE.72367.java +++ /dev/null @@ -1,166 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2009 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.core.gui.configuration; - -import java.io.InputStream; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.Map; -import java.util.Properties; -import java.util.Set; - -import javax.servlet.RequestDispatcher; -import javax.servlet.Servlet; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; - -import com.sun.faces.config.WebConfiguration; -final class MockServletContext implements ServletContext { - public void setAttribute(String arg0, Object arg1) { - this.attributeMap.put(arg0, arg1); - - } - - public void removeAttribute(String arg0) { - attributeMap.remove(arg0); - - } - - public void log(String arg0, Throwable arg1) { - throw new RuntimeException("Function not implemented"); - - } - - public void log(Exception arg0, String arg1) { - throw new RuntimeException("Function not implemented"); - - } - - public void log(String arg0) { - throw new RuntimeException("Function not implemented"); - - } - - public Enumeration getServlets() { - throw new RuntimeException("Function not implemented"); - - } - - public Enumeration getServletNames() { - throw new RuntimeException("Function not implemented"); - - } - - public String getServletContextName() { - return MockServletContext.class.getSimpleName(); - - } - - public Servlet getServlet(String arg0) throws ServletException { - throw new RuntimeException("Function not implemented"); - - } - - public String getServerInfo() { - throw new RuntimeException("Function not implemented"); - - } - - public Set getResourcePaths(String arg0) { - throw new RuntimeException("Function not implemented"); - - } - - public InputStream getResourceAsStream(String arg0) { - throw new RuntimeException("Function not implemented"); - - } - - public URL getResource(String arg0) throws MalformedURLException { - throw new RuntimeException("Function not implemented"); - - } - - public RequestDispatcher getRequestDispatcher(String arg0) { - throw new RuntimeException("Function not implemented"); - - } - - public String getRealPath(String arg0) { - throw new RuntimeException("Function not implemented"); - - } - - public RequestDispatcher getNamedDispatcher(String arg0) { - throw new RuntimeException("Function not implemented"); - - } - - public int getMinorVersion() { - return 4; - } - - public String getMimeType(String arg0) { - throw new RuntimeException("Function not implemented"); - - } - - public int getMajorVersion() { - return 2; - - } - - Properties initParams = new Properties(); - - public Enumeration getInitParameterNames() { - return initParams.elements(); - - } - - public String getInitParameter(String key) { - return initParams.getProperty(key); - - } - - public ServletContext getContext(String arg0) { - throw new RuntimeException("Function not implemented"); - - } - - public Enumeration getAttributeNames() { - throw new RuntimeException("Function not implemented"); - - } - - Map<String, Object> attributeMap; - - public Object getAttribute(String key) { - if (null == attributeMap) { - attributeMap = new HashMap<String, Object>(); - WebConfiguration wc = WebConfiguration.getInstance(this); - - attributeMap.put("com.sun.faces.config.WebConfiguration", wc); - } - - return attributeMap.get(key); - } -} \ No newline at end of file diff --git a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockServletContext.java.REMOTE.72367.java b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockServletContext.java.REMOTE.72367.java deleted file mode 100644 index 8740aca..0000000 --- a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockServletContext.java.REMOTE.72367.java +++ /dev/null @@ -1,167 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2009 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.core.gui.configuration; - -import java.io.InputStream; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.Map; -import java.util.Properties; -import java.util.Set; - -import javax.servlet.RequestDispatcher; -import javax.servlet.Servlet; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; - -import com.sun.faces.config.WebConfiguration; - -final class MockServletContext implements ServletContext { - public void setAttribute(String arg0, Object arg1) { - this.attributeMap.put(arg0, arg1); - - } - - public void removeAttribute(String arg0) { - attributeMap.remove(arg0); - - } - - public void log(String arg0, Throwable arg1) { - throw new RuntimeException("Function not implemented"); - - } - - public void log(Exception arg0, String arg1) { - throw new RuntimeException("Function not implemented"); - - } - - public void log(String arg0) { - throw new RuntimeException("Function not implemented"); - - } - - public Enumeration getServlets() { - throw new RuntimeException("Function not implemented"); - - } - - public Enumeration getServletNames() { - throw new RuntimeException("Function not implemented"); - - } - - public String getServletContextName() { - return MockServletContext.class.getSimpleName(); - - } - - public Servlet getServlet(String arg0) throws ServletException { - throw new RuntimeException("Function not implemented"); - - } - - public String getServerInfo() { - throw new RuntimeException("Function not implemented"); - - } - - public Set getResourcePaths(String arg0) { - throw new RuntimeException("Function not implemented"); - - } - - public InputStream getResourceAsStream(String arg0) { - throw new RuntimeException("Function not implemented"); - - } - - public URL getResource(String arg0) throws MalformedURLException { - throw new RuntimeException("Function not implemented"); - - } - - public RequestDispatcher getRequestDispatcher(String arg0) { - throw new RuntimeException("Function not implemented"); - - } - - public String getRealPath(String arg0) { - throw new RuntimeException("Function not implemented"); - - } - - public RequestDispatcher getNamedDispatcher(String arg0) { - throw new RuntimeException("Function not implemented"); - - } - - public int getMinorVersion() { - return 4; - } - - public String getMimeType(String arg0) { - throw new RuntimeException("Function not implemented"); - - } - - public int getMajorVersion() { - return 2; - - } - - Properties initParams = new Properties(); - - public Enumeration getInitParameterNames() { - return initParams.elements(); - - } - - public String getInitParameter(String key) { - return initParams.getProperty(key); - - } - - public ServletContext getContext(String arg0) { - throw new RuntimeException("Function not implemented"); - - } - - public Enumeration getAttributeNames() { - throw new RuntimeException("Function not implemented"); - - } - - Map<String, Object> attributeMap; - - public Object getAttribute(String key) { - if (null == attributeMap) { - attributeMap = new HashMap<String, Object>(); - WebConfiguration wc = WebConfiguration.getInstance(this); - - attributeMap.put("com.sun.faces.config.WebConfiguration", wc); - } - - return attributeMap.get(key); - } -} \ No newline at end of file
commit 960639d36e208c1d4a872bf9b441842746a73ca2 Merge: a8ff3e9... cfef08f... Author: John Sanda john@localhost.localdomain Date: Mon Dec 21 14:44:31 2009 -0500
Merge branch 'master' into raw-config
Conflicts: modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
diff --cc modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml index 5256543,ccca4f1..b1e873a --- a/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml +++ b/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml @@@ -2029,8 -1980,18 +1987,18 @@@
<schemaSpec version="2.63"> <schema-addColumn table="RHQ_REPO" column="IS_CANDIDATE" columnType="BOOLEAN"/> + + <schema-directSQL> + <statement targetDBVendor="postgresql"> + UPDATE RHQ_REPO SET IS_CANDIDATE = FALSE + </statement> + <statement targetDBVendor="oracle"> + UPDATE RHQ_REPO SET IS_CANDIDATE = 0 + </statement> + </schema-directSQL> + <schema-alterColumn table="RHQ_REPO" column="IS_CANDIDATE" nullable="false" /> - </schemaSpec> + </schemaSpec>
<!-- Generic tagging support --> <schemaSpec version="2.64">
commit a8ff3e996cc73ed811d88127f8b34076a5ef1137 Author: John Sanda john@localhost.localdomain Date: Sun Dec 20 15:54:53 2009 -0500
Refactoring facelets code so that the appropriate ui is rendered for the config type
Refactoring view.xhtml to support both structured and raw. With these changes, we now only see structured UI for a config that supports only structured, we only see the raw ui for a config that supports only raw, and we see both structured and raw for a config that supports that both.
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ExistingResourceConfigurationUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ExistingResourceConfigurationUIBean.java index 3189d79..b6aa356 100644 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ExistingResourceConfigurationUIBean.java +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ExistingResourceConfigurationUIBean.java @@ -311,11 +311,17 @@ public class ExistingResourceConfigurationUIBean extends AbstractConfigurationUI }
public boolean isRawSupported() { - return getConfigurationFormat().isRawSupported(); +// return getConfigurationFormat().isRawSupported(); + return getConfigurationDefinition().getConfigurationFormat() == ConfigurationFormat.RAW; }
public boolean isStructuredSupported() { - return getConfigurationFormat().isStructuredSupported(); +// return getConfigurationFormat().isStructuredSupported(); + return getConfigurationDefinition().getConfigurationFormat() == ConfigurationFormat.STRUCTURED; + } + + public boolean isStructuredAndRawSupported() { + return getConfigurationDefinition().getConfigurationFormat() == ConfigurationFormat.STRUCTURED_AND_RAW; }
void nullify() { diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/navigation/resource/ResourceTreeStateAdvisor.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/navigation/resource/ResourceTreeStateAdvisor.java index 1ed9f52..6fee523 100644 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/navigation/resource/ResourceTreeStateAdvisor.java +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/navigation/resource/ResourceTreeStateAdvisor.java @@ -118,7 +118,8 @@ public class ResourceTreeStateAdvisor implements TreeStateAdvisor { || (path.startsWith("/rhq/resource/events") && !facets.isEvent())) { // This resource doesn't support those facets path = fallbackPath; - } else if (path.startsWith("/rhq/resource/configuration/edit.xhtml") + } else if ((path.startsWith("/rhq/resource/configuration/edit.xhtml") || + path.startsWith("/rhq/resource/configuration/edit-raw.xhtml")) && facets.isConfiguration()) { path = "/rhq/resource/configuration/view.xhtml"; } else if (!path.startsWith("/rhq/resource/content/view.xhtml") diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-navigation/configuration-navigation.xml b/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-navigation/configuration-navigation.xml index 302fdff..8f0749c 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-navigation/configuration-navigation.xml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-navigation/configuration-navigation.xml @@ -14,7 +14,7 @@ </navigation-case>
<navigation-case> - <from-action>#{ExistingResourceConfigurationUIBean.editRawConfiguration}</from-action> + <from-action>#{ExistingResourceConfigurationViewUIBean.editRawConfiguration}</from-action> <to-view-id>/rhq/resource/configuration/edit-raw.xhtml?id=#{param.id}</to-view-id> <redirect/> </navigation-case> @@ -39,7 +39,7 @@ <to-view-id>/rhq/resource/configuration/edit-raw.xhtml?id=#{param.id}</to-view-id> </navigation-case> </navigation-rule> - + <navigation-rule>
<from-view-id>/rhq/resource/configuration/edit-raw.xhtml</from-view-id> @@ -50,11 +50,10 @@ <to-view-id>/rhq/resource/configuration/history.xhtml?id=#{param.id}</to-view-id> <redirect/> </navigation-case> - - - </navigation-rule>
+ </navigation-rule> + <navigation-rule>
<from-view-id>/rhq/resource/configuration/edit.xhtml</from-view-id> diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit-raw.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit-raw.xhtml index bf05c9b..d2b8dac 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit-raw.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit-raw.xhtml @@ -33,9 +33,9 @@ } </script> <a4j:form id="editResourceConfigurationForm"> - - <h:outputText value="#{messages.youareviewingraw}" /> - <h:panelGroup rendered="#{ExistingResourceConfigurationUIBean.structuredSupported}"> + + <h:outputText value="#{messages.youareviewingraw}" /> + <h:panelGroup rendered="#{ExistingResourceConfigurationUIBean.structuredAndRawSupported}"> <h:outputText value=" #{messages.switch2}" /> <h:commandLink action="#{ExistingResourceConfigurationUIBean.switchTostructured}"> <f:param name="conversationId" value="#{conversation.id}"/> diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit.xhtml index d067d8a..9a8dec6 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit.xhtml @@ -30,7 +30,7 @@ THIS TEXT WILL BE REMOVED.
<h:outputText value="#{messages.youareviewingstructured}" /> - <h:panelGroup rendered="#{ExistingResourceConfigurationUIBean.rawSupported}" > + <h:panelGroup rendered="#{ExistingResourceConfigurationUIBean.structuredAndRawSupported}" > <h:outputText value=" #{messages.switch2}" /> <h:commandLink action="#{ExistingResourceConfigurationUIBean.switchToraw}" > <f:param name="conversationId" value="#{conversation.id}"/> @@ -58,7 +58,6 @@ THIS TEXT WILL BE REMOVED. <h:panelGroup layout="block" styleClass="InfoBlock" rendered="#{ExistingResourceConfigurationUIBean.updateInProgress}"> <b>${msg['note']}</b> ${msg['resource.config.Current.updateInProgress']} </h:panelGroup> - </ui:define>
</ui:composition> diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml index 72da244..8a39f83 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml @@ -1,75 +1,188 @@ <?xml version="1.0"?>
<!DOCTYPE html - PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" - "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd%22%3E
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:c="http://java.sun.com/jstl/core" - xmlns:onc="http://jboss.org/on/component%22%3E + xmlns:onc="http://jboss.org/on/component" + xmlns:s="http://jboss.com/products/seam/taglib%22%3E
THIS TEXT WILL BE REMOVED.
<ui:composition template="/rhq/resource/layout/main.xhtml">
- THIS TEXT WILL BE REMOVED AS WELL. - - <ui:param name="pageTitle" value="#{ResourceUIBean.resourceType.name} '#{ResourceUIBean.name}' - View Configuration"/> - - <ui:param name="selectedTabName" value="Configuration.Current"/> - - <ui:define name="content"> - - <h:panelGroup layout="block" styleClass="InfoBlock" rendered="#{ExistingResourceConfigurationUIBean.updateInProgress}"> - <b>${msg['note']}</b> ${msg['resource.config.Current.updateInProgress']} - </h:panelGroup> - - <h:outputText value="#{messages.youareviewingstructured}" /> - <h:panelGroup rendered="#{ExistingResourceConfigurationUIBean.rawSupported}" > - <h:outputText value=" #{messages.switch2}" /> - <h:outputLink value="view-raw.xhtml"> - <f:param name="id" value="#{ResourceUIBean.id}" /> - <h:outputText value=" #{messages.raw}" /> - </h:outputLink> - </h:panelGroup> - - <h:outputText value=" #{messages.nopermissionedit}" rendered="#{!ResourceUIBean.permissions.configure}"/> - - <h:form id="viewResourceConfigurationForm"> - <!-- TODO remove the id version --> - <input type="hidden" name="id" value="#{ResourceUIBean.id}"/> - - <h:panelGrid columns="2" styleClass="buttons-table" columnClasses="button-cell" - rendered="#{ExistingResourceConfigurationViewUIBean.configuration != null and !ExistingResourceConfigurationViewUIBean.updateInProgress}"> - - <h:commandButton value="#{messages.editstructured}" action="#{ExistingResourceConfigurationViewUIBean.editConfiguration}" - title="Edit this Configuration" styleClass="buttonmed" - rendered="${ResourceUIBean.permissions.configure and ExistingResourceConfigurationViewUIBean.structuredSupported and !ExistingResourceConfigurationViewUIBean.updateInProgress}" /> - <h:commandButton value="#{messages.editraw}" action="#{ExistingResourceConfigurationUIBean.editRawConfiguration}" - title="Advanced Mode Edit of Raw Configuration Files" styleClass="buttonmed" - rendered="${ResourceUIBean.permissions.configure and ExistingResourceConfigurationViewUIBean.rawSupported and !ExistingResourceConfigurationViewUIBean.updateInProgress}" /> - </h:panelGrid> - - <onc:config configurationDefinition="#{ExistingResourceConfigurationViewUIBean.configurationDefinition}" - configuration="#{ExistingResourceConfigurationViewUIBean.configuration}" - accessMapActionExpression="#{ExistingResourceConfigurationViewUIBean.accessMap}" - readOnly="true" - nullConfigurationDefinitionMessage="#{ExistingResourceConfigurationViewUIBean.nullConfigurationDefinitionMessage}" - nullConfigurationMessage="#{ExistingResourceConfigurationViewUIBean.nullConfigurationMessage}" - prevalidate="true"/> - - </h:form> - - <h:panelGroup layout="block" styleClass="InfoBlock" rendered="#{ExistingResourceConfigurationViewUIBean.updateInProgress}"> - <b>${msg['note']}</b> ${msg['resource.config.Current.updateInProgress']} - </h:panelGroup> - - - </ui:define> + THIS TEXT WILL BE REMOVED AS WELL. + + <ui:param name="pageTitle" + value="#{ResourceUIBean.resourceType.name} '#{ResourceUIBean.name}' - View Configuration"/> + + <ui:param name="selectedTabName" value="Configuration.Current"/> + + <ui:define name="content"> + <h:panelGroup layout="block" styleClass="InfoBlock" + rendered="#{ExistingResourceConfigurationUIBean.updateInProgress}"> + <b>${msg['note']}</b> ${msg['resource.config.Current.updateInProgress']} + </h:panelGroup> + + <c:choose> + <c:when test="${ExistingResourceConfigurationViewUIBean.rawSupported}"> + <script> + window.onbeforeunload = confirmExit; + + function confirmExit() { + } + </script> + + <h:outputText value="#{messages.youareviewingraw}"/> + <h:outputText value=" #{messages.nopermissionedit}" + rendered="#{!ResourceUIBean.permissions.configure}"/> + <h:form id="viewResourceConfigurationFormRaw"> + <input type="hidden" name="id" value="#{ResourceUIBean.id}"/> + + <h:panelGrid columns="2" + styleClass="buttons-table" + columnClasses="button-cell" + rendered="#{ExistingResourceConfigurationViewUIBean.configuration != null and !ExistingResourceConfigurationViewUIBean.updateInProgress}"> + + <h:commandButton value="#{messages.editraw}" + action="#{ExistingResourceConfigurationViewUIBean.editRawConfiguration}" + title="Advanced Mode Edit of Raw Configuration Files" styleClass="buttonmed" + rendered="${ResourceUIBean.permissions.configure and !ExistingResourceConfigurationUIBean.updateInProgress}"/> + </h:panelGrid> + </h:form> + + <table class="summary-props-table" style=""> + <tr> + <td bgcolor="#a4b2b9" width="25%" valign="top">Files + <h:panelGroup id="changedFiles" layout="vertical"> + <h:form> + <input type="hidden" name="id" value="#{ResourceUIBean.id}"/> + <ui:repeat value="#{ExistingResourceConfigurationViewUIBean.paths}" var="path"> + <div> + <h:commandLink + action="#{ExistingResourceConfigurationViewUIBean.select(path)}" + value="#{path}" + rendered="#{path != ExistingResourceConfigurationViewUIBean.current.path}"> + <f:param name="currentPath" value="#{path}"/> + </h:commandLink> + <h:outputText value="#{path}" + rendered="#{path == ExistingResourceConfigurationViewUIBean.current.path}"/> + </div> + </ui:repeat> + </h:form> + </h:panelGroup> + <div>______________________________________</div> + <div>* File contains uncommitted changes.</div> + </td> + <td> + <div> + Current File: + <h:outputText value="#{ExistingResourceConfigurationViewUIBean.current.path}" + styleClass="outhello"/> + </div> + <h:outputLink value="view-raw-full.xhtml" action="navigateToUpload"> + <img src="/images/viewfullscreen.png"/> + <h:outputText value=" Full Screen "/> + <f:param name="id" value="#{ResourceUIBean.id}"/> + </h:outputLink> + <s:link action="#{ExistingResourceConfigurationViewUIBean.download}"> + <img src="/images/download.png"/> + <h:outputText value=" Download "/> + <f:param name="id" value="#{ResourceUIBean.id}"/> + </s:link> + <div> + <pre><h:outputText + value="#{ExistingResourceConfigurationViewUIBean.currentContents}"/></pre> + </div> + </td> + </tr> + </table> + </c:when> + <c:when test="${ExistingResourceConfigurationViewUIBean.structuredSupported}"> + <h:outputText value="#{messages.youareviewingstructured}"/> + <h:outputText value=" #{messages.nopermissionedit}" + rendered="#{!ResourceUIBean.permissions.configure}"/> + <h:form id="viewResourceConfigurationFormStructured"> + <!-- TODO remove the id version --> + <input type="hidden" name="id" value="#{ResourceUIBean.id}"/> + + <h:panelGrid columns="2" + styleClass="buttons-table" + columnClasses="button-cell" + rendered="#{ExistingResourceConfigurationViewUIBean.configuration != null and !ExistingResourceConfigurationViewUIBean.updateInProgress}"> + + <h:commandButton value="#{messages.editstructured}" + action="#{ExistingResourceConfigurationViewUIBean.editConfiguration}" + title="Edit this Configuration" + styleClass="buttonmed" + rendered="${ResourceUIBean.permissions.configure and !ExistingResourceConfigurationViewUIBean.updateInProgress}"/> + </h:panelGrid> + + <onc:config + configurationDefinition="#{ExistingResourceConfigurationViewUIBean.configurationDefinition}" + configuration="#{ExistingResourceConfigurationViewUIBean.configuration}" + accessMapActionExpression="#{ExistingResourceConfigurationViewUIBean.accessMap}" + readOnly="true" + nullConfigurationDefinitionMessage="#{ExistingResourceConfigurationViewUIBean.nullConfigurationDefinitionMessage}" + nullConfigurationMessage="#{ExistingResourceConfigurationViewUIBean.nullConfigurationMessage}" + prevalidate="true"/> + + </h:form> + </c:when> + <c:when test="${ExistingResourceConfigurationViewUIBean.structuredAndRawSupported}"> + <h:outputText value="#{messages.youareviewingstructured}"/> + <h:panelGroup rendered="#{ExistingResourceConfigurationUIBean.rawSupported}"> + <h:outputText value=" #{messages.switch2}"/> + <h:outputLink value="view-raw.xhtml"> + <f:param name="id" value="#{ResourceUIBean.id}"/> + <h:outputText value=" #{messages.raw}"/> + </h:outputLink> + </h:panelGroup> + <h:outputText value=" #{messages.nopermissionedit}" + rendered="#{!ResourceUIBean.permissions.configure}"/> + <h:form id="viewResourceConfigurationFormStructuredAndRaw"> + <!-- TODO remove the id version --> + <input type="hidden" name="id" value="#{ResourceUIBean.id}"/> + + <h:panelGrid columns="2" styleClass="buttons-table" columnClasses="button-cell" + rendered="#{ExistingResourceConfigurationViewUIBean.configuration != null and !ExistingResourceConfigurationViewUIBean.updateInProgress}"> + + <h:commandButton value="#{messages.editstructured}" + action="#{ExistingResourceConfigurationViewUIBean.editConfiguration}" + title="Edit this Configuration" styleClass="buttonmed" + rendered="${ResourceUIBean.permissions.configure and !ExistingResourceConfigurationViewUIBean.updateInProgress}"/> + <h:commandButton value="#{messages.editraw}" + action="#{ExistingResourceConfigurationViewUIBean.editRawConfiguration}" + title="Advanced Mode Edit of Raw Configuration Files" styleClass="buttonmed" + rendered="${ResourceUIBean.permissions.configure and !ExistingResourceConfigurationViewUIBean.updateInProgress}"/> + </h:panelGrid> + + <onc:config + configurationDefinition="#{ExistingResourceConfigurationViewUIBean.configurationDefinition}" + configuration="#{ExistingResourceConfigurationViewUIBean.configuration}" + accessMapActionExpression="#{ExistingResourceConfigurationViewUIBean.accessMap}" + readOnly="true" + nullConfigurationDefinitionMessage="#{ExistingResourceConfigurationViewUIBean.nullConfigurationDefinitionMessage}" + nullConfigurationMessage="#{ExistingResourceConfigurationViewUIBean.nullConfigurationMessage}" + prevalidate="true"/> + + </h:form> + </c:when> + </c:choose> + + <h:panelGroup layout="block" styleClass="InfoBlock" + rendered="#{ExistingResourceConfigurationViewUIBean.updateInProgress}"> + <b>${msg['note']}</b> ${msg['resource.config.Current.updateInProgress']} + </h:panelGroup> + + + </ui:define>
</ui:composition>
commit b150dcc1c85be1b4df9b3fba3b4849ee3f60b520 Author: John Sanda john@localhost.localdomain Date: Fri Dec 18 16:48:22 2009 -0500
Reverting back to previous functionality (for now)
diff --git a/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/ConfigRenderer.java b/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/ConfigRenderer.java index 2ebbc53..87bd52c 100644 --- a/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/ConfigRenderer.java +++ b/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/ConfigRenderer.java @@ -249,16 +249,14 @@ public class ConfigRenderer extends Renderer { // No index specified means we should add a new map to the list. configurationComponent.setListIndex(addNewMap(configurationComponent)); } - - addListMemberProperty(configurationComponent); - } else { - addConfiguration(configurationComponent); - } - - String id = getInitInputsJavaScriptComponentId(configurationComponent); - PropertyRenderingUtility.addInitInputsJavaScript(configurationComponent, id, configurationComponent - .isFullyEditable(), false); + addListMemberProperty(configurationComponent); + } else { + addConfiguration(configurationComponent); } + + String id = getInitInputsJavaScriptComponentId(configurationComponent); + PropertyRenderingUtility.addInitInputsJavaScript(configurationComponent, id, configurationComponent + .isFullyEditable(), false); }
private void addListMemberProperty(AbstractConfigurationComponent configurationComponent) { diff --git a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockServletContext.java.BACKUP.72367.java b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockServletContext.java.BACKUP.72367.java new file mode 100644 index 0000000..8740aca --- /dev/null +++ b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockServletContext.java.BACKUP.72367.java @@ -0,0 +1,167 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2009 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.core.gui.configuration; + +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; +import java.util.Set; + +import javax.servlet.RequestDispatcher; +import javax.servlet.Servlet; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; + +import com.sun.faces.config.WebConfiguration; + +final class MockServletContext implements ServletContext { + public void setAttribute(String arg0, Object arg1) { + this.attributeMap.put(arg0, arg1); + + } + + public void removeAttribute(String arg0) { + attributeMap.remove(arg0); + + } + + public void log(String arg0, Throwable arg1) { + throw new RuntimeException("Function not implemented"); + + } + + public void log(Exception arg0, String arg1) { + throw new RuntimeException("Function not implemented"); + + } + + public void log(String arg0) { + throw new RuntimeException("Function not implemented"); + + } + + public Enumeration getServlets() { + throw new RuntimeException("Function not implemented"); + + } + + public Enumeration getServletNames() { + throw new RuntimeException("Function not implemented"); + + } + + public String getServletContextName() { + return MockServletContext.class.getSimpleName(); + + } + + public Servlet getServlet(String arg0) throws ServletException { + throw new RuntimeException("Function not implemented"); + + } + + public String getServerInfo() { + throw new RuntimeException("Function not implemented"); + + } + + public Set getResourcePaths(String arg0) { + throw new RuntimeException("Function not implemented"); + + } + + public InputStream getResourceAsStream(String arg0) { + throw new RuntimeException("Function not implemented"); + + } + + public URL getResource(String arg0) throws MalformedURLException { + throw new RuntimeException("Function not implemented"); + + } + + public RequestDispatcher getRequestDispatcher(String arg0) { + throw new RuntimeException("Function not implemented"); + + } + + public String getRealPath(String arg0) { + throw new RuntimeException("Function not implemented"); + + } + + public RequestDispatcher getNamedDispatcher(String arg0) { + throw new RuntimeException("Function not implemented"); + + } + + public int getMinorVersion() { + return 4; + } + + public String getMimeType(String arg0) { + throw new RuntimeException("Function not implemented"); + + } + + public int getMajorVersion() { + return 2; + + } + + Properties initParams = new Properties(); + + public Enumeration getInitParameterNames() { + return initParams.elements(); + + } + + public String getInitParameter(String key) { + return initParams.getProperty(key); + + } + + public ServletContext getContext(String arg0) { + throw new RuntimeException("Function not implemented"); + + } + + public Enumeration getAttributeNames() { + throw new RuntimeException("Function not implemented"); + + } + + Map<String, Object> attributeMap; + + public Object getAttribute(String key) { + if (null == attributeMap) { + attributeMap = new HashMap<String, Object>(); + WebConfiguration wc = WebConfiguration.getInstance(this); + + attributeMap.put("com.sun.faces.config.WebConfiguration", wc); + } + + return attributeMap.get(key); + } +} \ No newline at end of file diff --git a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockServletContext.java.BASE.72367.java b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockServletContext.java.BASE.72367.java new file mode 100644 index 0000000..f604d00 --- /dev/null +++ b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockServletContext.java.BASE.72367.java @@ -0,0 +1,166 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2009 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.core.gui.configuration; + +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; +import java.util.Set; + +import javax.servlet.RequestDispatcher; +import javax.servlet.Servlet; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; + +import com.sun.faces.config.WebConfiguration; +final class MockServletContext implements ServletContext { + public void setAttribute(String arg0, Object arg1) { + this.attributeMap.put(arg0, arg1); + + } + + public void removeAttribute(String arg0) { + attributeMap.remove(arg0); + + } + + public void log(String arg0, Throwable arg1) { + throw new RuntimeException("Function not implemented"); + + } + + public void log(Exception arg0, String arg1) { + throw new RuntimeException("Function not implemented"); + + } + + public void log(String arg0) { + throw new RuntimeException("Function not implemented"); + + } + + public Enumeration getServlets() { + throw new RuntimeException("Function not implemented"); + + } + + public Enumeration getServletNames() { + throw new RuntimeException("Function not implemented"); + + } + + public String getServletContextName() { + return MockServletContext.class.getSimpleName(); + + } + + public Servlet getServlet(String arg0) throws ServletException { + throw new RuntimeException("Function not implemented"); + + } + + public String getServerInfo() { + throw new RuntimeException("Function not implemented"); + + } + + public Set getResourcePaths(String arg0) { + throw new RuntimeException("Function not implemented"); + + } + + public InputStream getResourceAsStream(String arg0) { + throw new RuntimeException("Function not implemented"); + + } + + public URL getResource(String arg0) throws MalformedURLException { + throw new RuntimeException("Function not implemented"); + + } + + public RequestDispatcher getRequestDispatcher(String arg0) { + throw new RuntimeException("Function not implemented"); + + } + + public String getRealPath(String arg0) { + throw new RuntimeException("Function not implemented"); + + } + + public RequestDispatcher getNamedDispatcher(String arg0) { + throw new RuntimeException("Function not implemented"); + + } + + public int getMinorVersion() { + return 4; + } + + public String getMimeType(String arg0) { + throw new RuntimeException("Function not implemented"); + + } + + public int getMajorVersion() { + return 2; + + } + + Properties initParams = new Properties(); + + public Enumeration getInitParameterNames() { + return initParams.elements(); + + } + + public String getInitParameter(String key) { + return initParams.getProperty(key); + + } + + public ServletContext getContext(String arg0) { + throw new RuntimeException("Function not implemented"); + + } + + public Enumeration getAttributeNames() { + throw new RuntimeException("Function not implemented"); + + } + + Map<String, Object> attributeMap; + + public Object getAttribute(String key) { + if (null == attributeMap) { + attributeMap = new HashMap<String, Object>(); + WebConfiguration wc = WebConfiguration.getInstance(this); + + attributeMap.put("com.sun.faces.config.WebConfiguration", wc); + } + + return attributeMap.get(key); + } +} \ No newline at end of file diff --git a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockServletContext.java.REMOTE.72367.java b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockServletContext.java.REMOTE.72367.java new file mode 100644 index 0000000..8740aca --- /dev/null +++ b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockServletContext.java.REMOTE.72367.java @@ -0,0 +1,167 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2009 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.core.gui.configuration; + +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; +import java.util.Set; + +import javax.servlet.RequestDispatcher; +import javax.servlet.Servlet; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; + +import com.sun.faces.config.WebConfiguration; + +final class MockServletContext implements ServletContext { + public void setAttribute(String arg0, Object arg1) { + this.attributeMap.put(arg0, arg1); + + } + + public void removeAttribute(String arg0) { + attributeMap.remove(arg0); + + } + + public void log(String arg0, Throwable arg1) { + throw new RuntimeException("Function not implemented"); + + } + + public void log(Exception arg0, String arg1) { + throw new RuntimeException("Function not implemented"); + + } + + public void log(String arg0) { + throw new RuntimeException("Function not implemented"); + + } + + public Enumeration getServlets() { + throw new RuntimeException("Function not implemented"); + + } + + public Enumeration getServletNames() { + throw new RuntimeException("Function not implemented"); + + } + + public String getServletContextName() { + return MockServletContext.class.getSimpleName(); + + } + + public Servlet getServlet(String arg0) throws ServletException { + throw new RuntimeException("Function not implemented"); + + } + + public String getServerInfo() { + throw new RuntimeException("Function not implemented"); + + } + + public Set getResourcePaths(String arg0) { + throw new RuntimeException("Function not implemented"); + + } + + public InputStream getResourceAsStream(String arg0) { + throw new RuntimeException("Function not implemented"); + + } + + public URL getResource(String arg0) throws MalformedURLException { + throw new RuntimeException("Function not implemented"); + + } + + public RequestDispatcher getRequestDispatcher(String arg0) { + throw new RuntimeException("Function not implemented"); + + } + + public String getRealPath(String arg0) { + throw new RuntimeException("Function not implemented"); + + } + + public RequestDispatcher getNamedDispatcher(String arg0) { + throw new RuntimeException("Function not implemented"); + + } + + public int getMinorVersion() { + return 4; + } + + public String getMimeType(String arg0) { + throw new RuntimeException("Function not implemented"); + + } + + public int getMajorVersion() { + return 2; + + } + + Properties initParams = new Properties(); + + public Enumeration getInitParameterNames() { + return initParams.elements(); + + } + + public String getInitParameter(String key) { + return initParams.getProperty(key); + + } + + public ServletContext getContext(String arg0) { + throw new RuntimeException("Function not implemented"); + + } + + public Enumeration getAttributeNames() { + throw new RuntimeException("Function not implemented"); + + } + + Map<String, Object> attributeMap; + + public Object getAttribute(String key) { + if (null == attributeMap) { + attributeMap = new HashMap<String, Object>(); + WebConfiguration wc = WebConfiguration.getInstance(this); + + attributeMap.put("com.sun.faces.config.WebConfiguration", wc); + } + + return attributeMap.get(key); + } +} \ No newline at end of file diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-navigation/configuration-navigation.xml b/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-navigation/configuration-navigation.xml index bd0f1bf..302fdff 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-navigation/configuration-navigation.xml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-navigation/configuration-navigation.xml @@ -8,7 +8,7 @@
<navigation-case> - <from-action>#{ExistingResourceConfigurationUIBean.editConfiguration}</from-action> + <from-action>#{ExistingResourceConfigurationViewUIBean.editConfiguration}</from-action> <to-view-id>/rhq/resource/configuration/edit.xhtml?id=#{param.id}</to-view-id> <redirect/> </navigation-case> @@ -35,7 +35,7 @@ <navigation-rule> <from-view-id>/rhq/resource/configuration/edit-raw-full.xhtml</from-view-id> <navigation-case> - <from-action> #{RawConfigCollection.update}</from-action> + <from-action>#{RawConfigCollection.update}</from-action> <to-view-id>/rhq/resource/configuration/edit-raw.xhtml?id=#{param.id}</to-view-id> </navigation-case> </navigation-rule>
commit cbf7ccd26f442f75741d246fe4cc476d5bbc89d1 Author: John Sanda john@localhost.localdomain Date: Fri Dec 18 15:35:04 2009 -0500
Removing check for config property definitions in findResourceConfigurationUpdates()
The check does not really make sense in light of adding raw config. With a resource that supports raw config, the config does not have to have any properties.
Conflicts:
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java index fb82e6e..fbae47d 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java @@ -842,10 +842,6 @@ public class ConfigurationManagerBean implements ConfigurationManagerLocal, Conf }
Resource resource = entityManager.find(Resource.class, resourceId); - if (resource.getResourceType().getResourceConfigurationDefinition() == null - || resource.getResourceType().getResourceConfigurationDefinition().getPropertyDefinitions().isEmpty()) { - return new PageList<ResourceConfigurationUpdate>(pc); - }
pc.initDefaultOrderingField("cu.id", PageOrdering.DESC);
commit e101f7c1b57be786bd882aac8a9562d8e1e7634a Author: John Sanda jsanda@redhat.com Date: Tue Dec 15 07:36:52 2009 -0500
[BZ 537891] Fixing bug in which required query parameter was not getted appended to url
The resource id is expected to be a parameter in the request. When on edit-raw.xhtml and clicking the link to go back to structured, the resource id basically gets dropped and then navigating to any other page, tab, etc. that expects the id parameter results in an exception. I added a new navigation rule similar to one already defined for edit.xhtml (structured edit page) that adds the id to the request and does a server side redirect.
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ExistingResourceConfigurationUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ExistingResourceConfigurationUIBean.java index bb93d81..3189d79 100644 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ExistingResourceConfigurationUIBean.java +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ExistingResourceConfigurationUIBean.java @@ -417,7 +417,8 @@ public class ExistingResourceConfigurationUIBean extends AbstractConfigurationUI current = null; setConfiguration(configuration);
- return "/rhq/resource/configuration/edit.xhtml?currentResourceId=" + getResourceId(); +// return "/rhq/resource/configuration/edit.xhtml?currentResourceId=" + getResourceId(); + return SUCCESS_OUTCOME; }
void populateRaws() { @@ -450,4 +451,4 @@ public class ExistingResourceConfigurationUIBean extends AbstractConfigurationUI TreeMap<String, RawConfiguration> modified = new TreeMap<String, RawConfiguration>(); RawConfiguration current = null;
-} \ No newline at end of file +} diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-navigation/configuration-navigation.xml b/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-navigation/configuration-navigation.xml index 4443b36..bd0f1bf 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-navigation/configuration-navigation.xml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-navigation/configuration-navigation.xml @@ -23,6 +23,12 @@ <from-action>#{ConfigHelperUIBean.accessMap}</from-action> <to-view-id>/rhq/resource/configuration/view-map.xhtml</to-view-id> </navigation-case> + + <navigation-case> + <from-action>#{ExistingResourceConfigurationUIBean.switchTostructured}</from-action> + <to-view-id>/rhq/resource/configuration/edit.xhtml?id=#{param.id}</to-view-id> + <redirect/> + </navigation-case>
</navigation-rule>
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit-raw.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit-raw.xhtml index c01694e..bf05c9b 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit-raw.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit-raw.xhtml @@ -35,10 +35,10 @@ <a4j:form id="editResourceConfigurationForm"> <h:outputText value="#{messages.youareviewingraw}" /> - <h:panelGroup rendered="#{ExistingResourceConfigurationUIBean.structuredSupported}"> + <h:panelGroup rendered="#{ExistingResourceConfigurationUIBean.structuredSupported}"> <h:outputText value=" #{messages.switch2}" /> <h:commandLink action="#{ExistingResourceConfigurationUIBean.switchTostructured}"> - <s:conversationId /> + <f:param name="conversationId" value="#{conversation.id}"/> <f:param name="id" value="#{ResourceUIBean.id}" /> <h:outputText value=" #{messages.structured}" /> </h:commandLink>
commit 321252a12867598044449a02a9b9982a0d662b9c Author: John Sanda jsanda@redhat.com Date: Mon Dec 14 22:34:48 2009 -0500
[BZ 538088] Reverting back to using the view ui bean which only has a request scope.
view.xhtml in several places in the JSF code was making calls to ExistingResourceConfigurationUIBean which has session scope. As a result, external config updagtes were not immediately visible because the configuration objects were getting cached for the duration of the session, whereas ExistingResourceConfigurationViewUIBean has a scope of request so every request for the view page results in fetching the latest configuration for the resource.
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml index 0d4899f..72da244 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml @@ -44,27 +44,27 @@ THIS TEXT WILL BE REMOVED. <input type="hidden" name="id" value="#{ResourceUIBean.id}"/>
<h:panelGrid columns="2" styleClass="buttons-table" columnClasses="button-cell" - rendered="#{ExistingResourceConfigurationUIBean.configuration != null and !ExistingResourceConfigurationUIBean.updateInProgress}"> + rendered="#{ExistingResourceConfigurationViewUIBean.configuration != null and !ExistingResourceConfigurationViewUIBean.updateInProgress}">
- <h:commandButton value="#{messages.editstructured}" action="#{ExistingResourceConfigurationUIBean.editConfiguration}" + <h:commandButton value="#{messages.editstructured}" action="#{ExistingResourceConfigurationViewUIBean.editConfiguration}" title="Edit this Configuration" styleClass="buttonmed" - rendered="${ResourceUIBean.permissions.configure and ExistingResourceConfigurationUIBean.structuredSupported and !ExistingResourceConfigurationUIBean.updateInProgress}" /> + rendered="${ResourceUIBean.permissions.configure and ExistingResourceConfigurationViewUIBean.structuredSupported and !ExistingResourceConfigurationViewUIBean.updateInProgress}" /> <h:commandButton value="#{messages.editraw}" action="#{ExistingResourceConfigurationUIBean.editRawConfiguration}" title="Advanced Mode Edit of Raw Configuration Files" styleClass="buttonmed" - rendered="${ResourceUIBean.permissions.configure and ExistingResourceConfigurationUIBean.rawSupported and !ExistingResourceConfigurationUIBean.updateInProgress}" /> + rendered="${ResourceUIBean.permissions.configure and ExistingResourceConfigurationViewUIBean.rawSupported and !ExistingResourceConfigurationViewUIBean.updateInProgress}" /> </h:panelGrid>
- <onc:config configurationDefinition="#{ExistingResourceConfigurationUIBean.configurationDefinition}" - configuration="#{ExistingResourceConfigurationUIBean.configuration}" - accessMapActionExpression="#{ExistingResourceConfigurationUIBean.accessMap}" + <onc:config configurationDefinition="#{ExistingResourceConfigurationViewUIBean.configurationDefinition}" + configuration="#{ExistingResourceConfigurationViewUIBean.configuration}" + accessMapActionExpression="#{ExistingResourceConfigurationViewUIBean.accessMap}" readOnly="true" - nullConfigurationDefinitionMessage="#{ExistingResourceConfigurationUIBean.nullConfigurationDefinitionMessage}" - nullConfigurationMessage="#{ExistingResourceConfigurationUIBean.nullConfigurationMessage}" + nullConfigurationDefinitionMessage="#{ExistingResourceConfigurationViewUIBean.nullConfigurationDefinitionMessage}" + nullConfigurationMessage="#{ExistingResourceConfigurationViewUIBean.nullConfigurationMessage}" prevalidate="true"/>
</h:form>
- <h:panelGroup layout="block" styleClass="InfoBlock" rendered="#{ExistingResourceConfigurationUIBean.updateInProgress}"> + <h:panelGroup layout="block" styleClass="InfoBlock" rendered="#{ExistingResourceConfigurationViewUIBean.updateInProgress}"> <b>${msg['note']}</b> ${msg['resource.config.Current.updateInProgress']} </h:panelGroup>
commit 40d8d126507fd024140f71a2e043eea0346b3ea1 Author: John Sanda jsanda@redhat.com Date: Fri Dec 11 11:14:36 2009 -0500
Renaming script to something more logical
diff --git a/modules/enterprise/remoting/scripts/src/main/script/configuration/config_util.js b/modules/enterprise/remoting/scripts/src/main/script/configuration/config_util.js new file mode 100644 index 0000000..54c39a9 --- /dev/null +++ b/modules/enterprise/remoting/scripts/src/main/script/configuration/config_util.js @@ -0,0 +1,287 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2008 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, version 2, as + * published by the Free Software Foundation, and/or the GNU Lesser + * General Public License, version 2.1, also as published by the Free + * Software Foundation. + * + * 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 and the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * and the GNU Lesser 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. + */ + +var waitInterval = 100; +var structured = true; +var raw = false; + +loadResourceTypes(); + +function loadResourceTypes() { + var resourceTypes = context.getAttribute('resourceTypes'); + if (resourceTypes != null && !resourceTypes.isEmpty()) { + return; + } + + var criteria = ResourceTypeCriteria(); + criteria.fetchResourceConfigurationDefinition(true); + + resourceTypes = ResourceTypeManager.findResourceTypesByCriteria(criteria); + context.setAttribute('resourceTypes', resourceTypes, javax.script.ScriptContext.ENGINE_SCOPE); +} + +function ConfigUtil(resourceName) { + var util = this; + + this.resource = findServer(resourceName); + + this.getLatestConfiguration = function () { + var latestUpdate = ConfigurationManager.getLatestResourceConfigurationUpdate(this.resource.id); + + Assert.assertNotNull( + latestUpdate, + "Failed to load the latest resource configuration update for " + this.resource.name + ); + Assert.assertNotNull( + latestUpdate.configuration, + "No configuration is attached to the latest config update object." + ); + + return latestUpdate.configuration; + } + + this.printLatestConfiguration = function() { + var configuration = this.getLatestConfiguration(); + printConfiguration(configuration); + } + + function printConfiguration(configuration) { + pretty.print(configuration); + + if (util.isRawSupported() || util.isStructuredAndRawSupported()) { + println("\nRaw configuration files:"); + var rawConfigs = java.util.ArrayList(configuration.rawConfigurations); + for (i = 0; i < rawConfigs.size(); i++) { + var rawConfig = rawConfigs.get(i); + println("\n[" + rawConfig.path + "]"); + println(java.lang.String(rawConfig.contents) + "\n\n---------------------"); + } + } + } + + this.translateToRaw = function(update) { + doTranslation(update, true); + } + + this.translateToStructured = function(update) { + doTranslation(update, false); + } + + function doTranslation(update, doStructured) { + println("Loading latest configuration for " + util.resource.name); + var configuration = util.getLatestConfiguration(); + + printConfiguration(configuration) + println(''); + + if (doStructured) { + doStructuredUpdate(util.resource, configuration, update); + } + else { + doRawUpdate(util.resource, configuration, update); + } + + println("Modified configuration..."); + printConfiguration(configuration) + println(''); + + var translatedConfig = ConfigurationManager.translateResourceConfiguration(util.resource.id, configuration, + doStructured); + + println("Translated configuration..."); + printConfiguration(translatedConfig); + println(''); + } + + this.updateConfiguration = function(update, doStructured) { + println("Loading latest configuration for " + this.resource.name); + var configuration = this.getLatestConfiguration(); + + printConfiguration(configuration); + println(''); + + if (this.isStructuredSupported()) { + applyStructuredUpdate(this.resource, configuration, update); + } + else if (this.isRawSupported()) { + applyRawUpdate(this.resource, configuration, update); + } + else if (this.isStructuredAndRawSupported()) { + if (doStructured == null) { + throw "\nMust specify structured or raw when updating a configuration that supports both " + + "structured and raw. Update will abort."; + } + + if (doStructured) { + applyStructuredUpdate(this.resource, configuration, update); + } + else { + applyRawUpdate(this.resource, configuration, update); + } + } + + this.waitForResourceConfigurationUpdateToComplete(); + println("Configuration update has completed."); + + println("Loading latest, updated configuration"); + this.printLatestConfiguration(); + } + + this.waitForResourceConfigurationUpdateToComplete = function() { + print("Waiting for configuration update to complete...") + while (ConfigurationManager.isResourceConfigurationUpdateInProgress(this.resource.id)) { + print("."); + java.lang.Thread.sleep(waitInterval); + } + println(''); + } + + this.isRawSupported = function() { + var configFormat = this.resource.resourceType.resourceConfigurationDefinition.configurationFormat; + return ConfigurationFormat.RAW == configFormat; + } + + this.isStructuredSupported = function() { + var configFormat = this.resource.resourceType.resourceConfigurationDefinition.configurationFormat; + return ConfigurationFormat.STRUCTURED == configFormat; + } + + this.isStructuredAndRawSupported = function() { + var configFormat = this.resource.resourceType.resourceConfigurationDefinition.configurationFormat; + return ConfigurationFormat.STRUCTURED_AND_RAW == configFormat; + } + + function verifyPropertyToUpdateExists(configuration) { + if (!isDefined('propertyName')) { + throw "\nThe 'propertyName' variable must be defined. Update will abort."; + } + + if (!isDefined('propertyValue')) { + throw "\nThe 'propertyValue' variable must be defined. Update will abort."; + } + + if(configuration.getSimple(propertyName) == null) { + throw "\nThe property '" + propertyName + "' is undefined. Update will abort."; + } + } + + function verifyRawContentExists() { + if (!isDefined('contents')) { + throw "\n'contents' argument is required when updating " + serverName; + } + } + + function applyStructuredUpdate(resource, configuration, update) { + println("Applying resource configuration update..."); + doStructuredUpdate(resource, configuration, update); + ConfigurationManager.updateStructuredOrRawConfiguration(resource.id, configuration, structured); + } + + function doStructuredUpdate(resource, configuration, update) { + for (key in update) { + var property = configuration.getSimple(key.toString()); + if (property == null) { + throw "\nThe property '" + key + "' does not exist in the configuration. Update will abort."; + } + property.stringValue = update[key]; + } + } + + function applyRawUpdate(resource, configuration, update) { + println("Applying resource configuration update..."); + doRawUpdate(resource, configuration, update); + ConfigurationManager.updateStructuredOrRawConfiguration(resource.id, configuration, raw); + } + + function doRawUpdate(resourcec, configuration) { + var updates = 0; + var rawConfigs = java.util.ArrayList(configuration.rawConfigurations); + for (path in update) { + var rawConfig = findRawConfig(path, rawConfigs); + if (rawConfig == null) { + println("Failed to find raw config with path ending with " + path); + } + else { + configuration.rawConfigurations.remove(rawConfig); + var contents = java.lang.String(update[path]); + rawConfig.contents = contents.bytes; + configuration.rawConfigurations.add(rawConfig); + updates++; + } + } + + if (updates == 0) { + throw "\nNo matching paths were found. Update will abort."; + } + } + + function findRawConfig(path, rawConfigs) { + for (i = 0; i < rawConfigs.size(); i++) { + var rawConfig = rawConfigs.get(i); + if (rawConfig.path.endsWith(path.toString())) { + return rawConfig; + } + } + return null; + } + +} + +function findServer(name) { + var criteria = ResourceCriteria(); + criteria.strict = true; + criteria.addFilterName(name); + criteria.fetchResourceType(true); + + var resources = ResourceManager.findResourcesByCriteria(criteria); + + Assert.assertTrue(resources.size() == 1, "Expected to get back one resource but got back " + resources.size()); + + var resource = resources.get(0); + var resourceType = findResourceType(resource); + + if (resourceType == null) { + resourceType = loadResourceType(resource); + + if (resourceType == null) { + throw "Failed to initialize resource type for " + resource.name; + } + } + resource.resourceType = resourceType; + + return resource; +} + +function loadResourceType(resource) { + return ResourceTypeManager.getResourceTypeById(resource.resourceType.id); +} + +function findResourceType(resource) { + for (i = 0; i < resourceTypes.size(); i++) { + var resourceType = resourceTypes.get(i); + if (resourceType.id == resource.resourceType.id) { + return resourceType; + } + } + return null; +} diff --git a/modules/enterprise/remoting/scripts/src/main/script/configuration/update_structured.js b/modules/enterprise/remoting/scripts/src/main/script/configuration/update_structured.js deleted file mode 100644 index 54c39a9..0000000 --- a/modules/enterprise/remoting/scripts/src/main/script/configuration/update_structured.js +++ /dev/null @@ -1,287 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2008 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, version 2, as - * published by the Free Software Foundation, and/or the GNU Lesser - * General Public License, version 2.1, also as published by the Free - * Software Foundation. - * - * 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 and the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * and the GNU Lesser 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. - */ - -var waitInterval = 100; -var structured = true; -var raw = false; - -loadResourceTypes(); - -function loadResourceTypes() { - var resourceTypes = context.getAttribute('resourceTypes'); - if (resourceTypes != null && !resourceTypes.isEmpty()) { - return; - } - - var criteria = ResourceTypeCriteria(); - criteria.fetchResourceConfigurationDefinition(true); - - resourceTypes = ResourceTypeManager.findResourceTypesByCriteria(criteria); - context.setAttribute('resourceTypes', resourceTypes, javax.script.ScriptContext.ENGINE_SCOPE); -} - -function ConfigUtil(resourceName) { - var util = this; - - this.resource = findServer(resourceName); - - this.getLatestConfiguration = function () { - var latestUpdate = ConfigurationManager.getLatestResourceConfigurationUpdate(this.resource.id); - - Assert.assertNotNull( - latestUpdate, - "Failed to load the latest resource configuration update for " + this.resource.name - ); - Assert.assertNotNull( - latestUpdate.configuration, - "No configuration is attached to the latest config update object." - ); - - return latestUpdate.configuration; - } - - this.printLatestConfiguration = function() { - var configuration = this.getLatestConfiguration(); - printConfiguration(configuration); - } - - function printConfiguration(configuration) { - pretty.print(configuration); - - if (util.isRawSupported() || util.isStructuredAndRawSupported()) { - println("\nRaw configuration files:"); - var rawConfigs = java.util.ArrayList(configuration.rawConfigurations); - for (i = 0; i < rawConfigs.size(); i++) { - var rawConfig = rawConfigs.get(i); - println("\n[" + rawConfig.path + "]"); - println(java.lang.String(rawConfig.contents) + "\n\n---------------------"); - } - } - } - - this.translateToRaw = function(update) { - doTranslation(update, true); - } - - this.translateToStructured = function(update) { - doTranslation(update, false); - } - - function doTranslation(update, doStructured) { - println("Loading latest configuration for " + util.resource.name); - var configuration = util.getLatestConfiguration(); - - printConfiguration(configuration) - println(''); - - if (doStructured) { - doStructuredUpdate(util.resource, configuration, update); - } - else { - doRawUpdate(util.resource, configuration, update); - } - - println("Modified configuration..."); - printConfiguration(configuration) - println(''); - - var translatedConfig = ConfigurationManager.translateResourceConfiguration(util.resource.id, configuration, - doStructured); - - println("Translated configuration..."); - printConfiguration(translatedConfig); - println(''); - } - - this.updateConfiguration = function(update, doStructured) { - println("Loading latest configuration for " + this.resource.name); - var configuration = this.getLatestConfiguration(); - - printConfiguration(configuration); - println(''); - - if (this.isStructuredSupported()) { - applyStructuredUpdate(this.resource, configuration, update); - } - else if (this.isRawSupported()) { - applyRawUpdate(this.resource, configuration, update); - } - else if (this.isStructuredAndRawSupported()) { - if (doStructured == null) { - throw "\nMust specify structured or raw when updating a configuration that supports both " + - "structured and raw. Update will abort."; - } - - if (doStructured) { - applyStructuredUpdate(this.resource, configuration, update); - } - else { - applyRawUpdate(this.resource, configuration, update); - } - } - - this.waitForResourceConfigurationUpdateToComplete(); - println("Configuration update has completed."); - - println("Loading latest, updated configuration"); - this.printLatestConfiguration(); - } - - this.waitForResourceConfigurationUpdateToComplete = function() { - print("Waiting for configuration update to complete...") - while (ConfigurationManager.isResourceConfigurationUpdateInProgress(this.resource.id)) { - print("."); - java.lang.Thread.sleep(waitInterval); - } - println(''); - } - - this.isRawSupported = function() { - var configFormat = this.resource.resourceType.resourceConfigurationDefinition.configurationFormat; - return ConfigurationFormat.RAW == configFormat; - } - - this.isStructuredSupported = function() { - var configFormat = this.resource.resourceType.resourceConfigurationDefinition.configurationFormat; - return ConfigurationFormat.STRUCTURED == configFormat; - } - - this.isStructuredAndRawSupported = function() { - var configFormat = this.resource.resourceType.resourceConfigurationDefinition.configurationFormat; - return ConfigurationFormat.STRUCTURED_AND_RAW == configFormat; - } - - function verifyPropertyToUpdateExists(configuration) { - if (!isDefined('propertyName')) { - throw "\nThe 'propertyName' variable must be defined. Update will abort."; - } - - if (!isDefined('propertyValue')) { - throw "\nThe 'propertyValue' variable must be defined. Update will abort."; - } - - if(configuration.getSimple(propertyName) == null) { - throw "\nThe property '" + propertyName + "' is undefined. Update will abort."; - } - } - - function verifyRawContentExists() { - if (!isDefined('contents')) { - throw "\n'contents' argument is required when updating " + serverName; - } - } - - function applyStructuredUpdate(resource, configuration, update) { - println("Applying resource configuration update..."); - doStructuredUpdate(resource, configuration, update); - ConfigurationManager.updateStructuredOrRawConfiguration(resource.id, configuration, structured); - } - - function doStructuredUpdate(resource, configuration, update) { - for (key in update) { - var property = configuration.getSimple(key.toString()); - if (property == null) { - throw "\nThe property '" + key + "' does not exist in the configuration. Update will abort."; - } - property.stringValue = update[key]; - } - } - - function applyRawUpdate(resource, configuration, update) { - println("Applying resource configuration update..."); - doRawUpdate(resource, configuration, update); - ConfigurationManager.updateStructuredOrRawConfiguration(resource.id, configuration, raw); - } - - function doRawUpdate(resourcec, configuration) { - var updates = 0; - var rawConfigs = java.util.ArrayList(configuration.rawConfigurations); - for (path in update) { - var rawConfig = findRawConfig(path, rawConfigs); - if (rawConfig == null) { - println("Failed to find raw config with path ending with " + path); - } - else { - configuration.rawConfigurations.remove(rawConfig); - var contents = java.lang.String(update[path]); - rawConfig.contents = contents.bytes; - configuration.rawConfigurations.add(rawConfig); - updates++; - } - } - - if (updates == 0) { - throw "\nNo matching paths were found. Update will abort."; - } - } - - function findRawConfig(path, rawConfigs) { - for (i = 0; i < rawConfigs.size(); i++) { - var rawConfig = rawConfigs.get(i); - if (rawConfig.path.endsWith(path.toString())) { - return rawConfig; - } - } - return null; - } - -} - -function findServer(name) { - var criteria = ResourceCriteria(); - criteria.strict = true; - criteria.addFilterName(name); - criteria.fetchResourceType(true); - - var resources = ResourceManager.findResourcesByCriteria(criteria); - - Assert.assertTrue(resources.size() == 1, "Expected to get back one resource but got back " + resources.size()); - - var resource = resources.get(0); - var resourceType = findResourceType(resource); - - if (resourceType == null) { - resourceType = loadResourceType(resource); - - if (resourceType == null) { - throw "Failed to initialize resource type for " + resource.name; - } - } - resource.resourceType = resourceType; - - return resource; -} - -function loadResourceType(resource) { - return ResourceTypeManager.getResourceTypeById(resource.resourceType.id); -} - -function findResourceType(resource) { - for (i = 0; i < resourceTypes.size(); i++) { - var resourceType = resourceTypes.get(i); - if (resourceType.id == resource.resourceType.id) { - return resourceType; - } - } - return null; -}
commit ab2d09793f5f45cf66ba5a88e589a88a76d7cf0e Author: John Sanda john@localhost.localdomain Date: Fri Dec 18 15:03:13 2009 -0500
Revert "Renaming script to something more logical"
This reverts commit d10220faf2c617cd75b242a4077cc47422ab9a72.
diff --git a/modules/enterprise/remoting/scripts/src/main/script/configuration/config_util.js b/modules/enterprise/remoting/scripts/src/main/script/configuration/config_util.js deleted file mode 100644 index 54c39a9..0000000 --- a/modules/enterprise/remoting/scripts/src/main/script/configuration/config_util.js +++ /dev/null @@ -1,287 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2008 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, version 2, as - * published by the Free Software Foundation, and/or the GNU Lesser - * General Public License, version 2.1, also as published by the Free - * Software Foundation. - * - * 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 and the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * and the GNU Lesser 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. - */ - -var waitInterval = 100; -var structured = true; -var raw = false; - -loadResourceTypes(); - -function loadResourceTypes() { - var resourceTypes = context.getAttribute('resourceTypes'); - if (resourceTypes != null && !resourceTypes.isEmpty()) { - return; - } - - var criteria = ResourceTypeCriteria(); - criteria.fetchResourceConfigurationDefinition(true); - - resourceTypes = ResourceTypeManager.findResourceTypesByCriteria(criteria); - context.setAttribute('resourceTypes', resourceTypes, javax.script.ScriptContext.ENGINE_SCOPE); -} - -function ConfigUtil(resourceName) { - var util = this; - - this.resource = findServer(resourceName); - - this.getLatestConfiguration = function () { - var latestUpdate = ConfigurationManager.getLatestResourceConfigurationUpdate(this.resource.id); - - Assert.assertNotNull( - latestUpdate, - "Failed to load the latest resource configuration update for " + this.resource.name - ); - Assert.assertNotNull( - latestUpdate.configuration, - "No configuration is attached to the latest config update object." - ); - - return latestUpdate.configuration; - } - - this.printLatestConfiguration = function() { - var configuration = this.getLatestConfiguration(); - printConfiguration(configuration); - } - - function printConfiguration(configuration) { - pretty.print(configuration); - - if (util.isRawSupported() || util.isStructuredAndRawSupported()) { - println("\nRaw configuration files:"); - var rawConfigs = java.util.ArrayList(configuration.rawConfigurations); - for (i = 0; i < rawConfigs.size(); i++) { - var rawConfig = rawConfigs.get(i); - println("\n[" + rawConfig.path + "]"); - println(java.lang.String(rawConfig.contents) + "\n\n---------------------"); - } - } - } - - this.translateToRaw = function(update) { - doTranslation(update, true); - } - - this.translateToStructured = function(update) { - doTranslation(update, false); - } - - function doTranslation(update, doStructured) { - println("Loading latest configuration for " + util.resource.name); - var configuration = util.getLatestConfiguration(); - - printConfiguration(configuration) - println(''); - - if (doStructured) { - doStructuredUpdate(util.resource, configuration, update); - } - else { - doRawUpdate(util.resource, configuration, update); - } - - println("Modified configuration..."); - printConfiguration(configuration) - println(''); - - var translatedConfig = ConfigurationManager.translateResourceConfiguration(util.resource.id, configuration, - doStructured); - - println("Translated configuration..."); - printConfiguration(translatedConfig); - println(''); - } - - this.updateConfiguration = function(update, doStructured) { - println("Loading latest configuration for " + this.resource.name); - var configuration = this.getLatestConfiguration(); - - printConfiguration(configuration); - println(''); - - if (this.isStructuredSupported()) { - applyStructuredUpdate(this.resource, configuration, update); - } - else if (this.isRawSupported()) { - applyRawUpdate(this.resource, configuration, update); - } - else if (this.isStructuredAndRawSupported()) { - if (doStructured == null) { - throw "\nMust specify structured or raw when updating a configuration that supports both " + - "structured and raw. Update will abort."; - } - - if (doStructured) { - applyStructuredUpdate(this.resource, configuration, update); - } - else { - applyRawUpdate(this.resource, configuration, update); - } - } - - this.waitForResourceConfigurationUpdateToComplete(); - println("Configuration update has completed."); - - println("Loading latest, updated configuration"); - this.printLatestConfiguration(); - } - - this.waitForResourceConfigurationUpdateToComplete = function() { - print("Waiting for configuration update to complete...") - while (ConfigurationManager.isResourceConfigurationUpdateInProgress(this.resource.id)) { - print("."); - java.lang.Thread.sleep(waitInterval); - } - println(''); - } - - this.isRawSupported = function() { - var configFormat = this.resource.resourceType.resourceConfigurationDefinition.configurationFormat; - return ConfigurationFormat.RAW == configFormat; - } - - this.isStructuredSupported = function() { - var configFormat = this.resource.resourceType.resourceConfigurationDefinition.configurationFormat; - return ConfigurationFormat.STRUCTURED == configFormat; - } - - this.isStructuredAndRawSupported = function() { - var configFormat = this.resource.resourceType.resourceConfigurationDefinition.configurationFormat; - return ConfigurationFormat.STRUCTURED_AND_RAW == configFormat; - } - - function verifyPropertyToUpdateExists(configuration) { - if (!isDefined('propertyName')) { - throw "\nThe 'propertyName' variable must be defined. Update will abort."; - } - - if (!isDefined('propertyValue')) { - throw "\nThe 'propertyValue' variable must be defined. Update will abort."; - } - - if(configuration.getSimple(propertyName) == null) { - throw "\nThe property '" + propertyName + "' is undefined. Update will abort."; - } - } - - function verifyRawContentExists() { - if (!isDefined('contents')) { - throw "\n'contents' argument is required when updating " + serverName; - } - } - - function applyStructuredUpdate(resource, configuration, update) { - println("Applying resource configuration update..."); - doStructuredUpdate(resource, configuration, update); - ConfigurationManager.updateStructuredOrRawConfiguration(resource.id, configuration, structured); - } - - function doStructuredUpdate(resource, configuration, update) { - for (key in update) { - var property = configuration.getSimple(key.toString()); - if (property == null) { - throw "\nThe property '" + key + "' does not exist in the configuration. Update will abort."; - } - property.stringValue = update[key]; - } - } - - function applyRawUpdate(resource, configuration, update) { - println("Applying resource configuration update..."); - doRawUpdate(resource, configuration, update); - ConfigurationManager.updateStructuredOrRawConfiguration(resource.id, configuration, raw); - } - - function doRawUpdate(resourcec, configuration) { - var updates = 0; - var rawConfigs = java.util.ArrayList(configuration.rawConfigurations); - for (path in update) { - var rawConfig = findRawConfig(path, rawConfigs); - if (rawConfig == null) { - println("Failed to find raw config with path ending with " + path); - } - else { - configuration.rawConfigurations.remove(rawConfig); - var contents = java.lang.String(update[path]); - rawConfig.contents = contents.bytes; - configuration.rawConfigurations.add(rawConfig); - updates++; - } - } - - if (updates == 0) { - throw "\nNo matching paths were found. Update will abort."; - } - } - - function findRawConfig(path, rawConfigs) { - for (i = 0; i < rawConfigs.size(); i++) { - var rawConfig = rawConfigs.get(i); - if (rawConfig.path.endsWith(path.toString())) { - return rawConfig; - } - } - return null; - } - -} - -function findServer(name) { - var criteria = ResourceCriteria(); - criteria.strict = true; - criteria.addFilterName(name); - criteria.fetchResourceType(true); - - var resources = ResourceManager.findResourcesByCriteria(criteria); - - Assert.assertTrue(resources.size() == 1, "Expected to get back one resource but got back " + resources.size()); - - var resource = resources.get(0); - var resourceType = findResourceType(resource); - - if (resourceType == null) { - resourceType = loadResourceType(resource); - - if (resourceType == null) { - throw "Failed to initialize resource type for " + resource.name; - } - } - resource.resourceType = resourceType; - - return resource; -} - -function loadResourceType(resource) { - return ResourceTypeManager.getResourceTypeById(resource.resourceType.id); -} - -function findResourceType(resource) { - for (i = 0; i < resourceTypes.size(); i++) { - var resourceType = resourceTypes.get(i); - if (resourceType.id == resource.resourceType.id) { - return resourceType; - } - } - return null; -} diff --git a/modules/enterprise/remoting/scripts/src/main/script/configuration/update_structured.js b/modules/enterprise/remoting/scripts/src/main/script/configuration/update_structured.js new file mode 100644 index 0000000..54c39a9 --- /dev/null +++ b/modules/enterprise/remoting/scripts/src/main/script/configuration/update_structured.js @@ -0,0 +1,287 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2008 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, version 2, as + * published by the Free Software Foundation, and/or the GNU Lesser + * General Public License, version 2.1, also as published by the Free + * Software Foundation. + * + * 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 and the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * and the GNU Lesser 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. + */ + +var waitInterval = 100; +var structured = true; +var raw = false; + +loadResourceTypes(); + +function loadResourceTypes() { + var resourceTypes = context.getAttribute('resourceTypes'); + if (resourceTypes != null && !resourceTypes.isEmpty()) { + return; + } + + var criteria = ResourceTypeCriteria(); + criteria.fetchResourceConfigurationDefinition(true); + + resourceTypes = ResourceTypeManager.findResourceTypesByCriteria(criteria); + context.setAttribute('resourceTypes', resourceTypes, javax.script.ScriptContext.ENGINE_SCOPE); +} + +function ConfigUtil(resourceName) { + var util = this; + + this.resource = findServer(resourceName); + + this.getLatestConfiguration = function () { + var latestUpdate = ConfigurationManager.getLatestResourceConfigurationUpdate(this.resource.id); + + Assert.assertNotNull( + latestUpdate, + "Failed to load the latest resource configuration update for " + this.resource.name + ); + Assert.assertNotNull( + latestUpdate.configuration, + "No configuration is attached to the latest config update object." + ); + + return latestUpdate.configuration; + } + + this.printLatestConfiguration = function() { + var configuration = this.getLatestConfiguration(); + printConfiguration(configuration); + } + + function printConfiguration(configuration) { + pretty.print(configuration); + + if (util.isRawSupported() || util.isStructuredAndRawSupported()) { + println("\nRaw configuration files:"); + var rawConfigs = java.util.ArrayList(configuration.rawConfigurations); + for (i = 0; i < rawConfigs.size(); i++) { + var rawConfig = rawConfigs.get(i); + println("\n[" + rawConfig.path + "]"); + println(java.lang.String(rawConfig.contents) + "\n\n---------------------"); + } + } + } + + this.translateToRaw = function(update) { + doTranslation(update, true); + } + + this.translateToStructured = function(update) { + doTranslation(update, false); + } + + function doTranslation(update, doStructured) { + println("Loading latest configuration for " + util.resource.name); + var configuration = util.getLatestConfiguration(); + + printConfiguration(configuration) + println(''); + + if (doStructured) { + doStructuredUpdate(util.resource, configuration, update); + } + else { + doRawUpdate(util.resource, configuration, update); + } + + println("Modified configuration..."); + printConfiguration(configuration) + println(''); + + var translatedConfig = ConfigurationManager.translateResourceConfiguration(util.resource.id, configuration, + doStructured); + + println("Translated configuration..."); + printConfiguration(translatedConfig); + println(''); + } + + this.updateConfiguration = function(update, doStructured) { + println("Loading latest configuration for " + this.resource.name); + var configuration = this.getLatestConfiguration(); + + printConfiguration(configuration); + println(''); + + if (this.isStructuredSupported()) { + applyStructuredUpdate(this.resource, configuration, update); + } + else if (this.isRawSupported()) { + applyRawUpdate(this.resource, configuration, update); + } + else if (this.isStructuredAndRawSupported()) { + if (doStructured == null) { + throw "\nMust specify structured or raw when updating a configuration that supports both " + + "structured and raw. Update will abort."; + } + + if (doStructured) { + applyStructuredUpdate(this.resource, configuration, update); + } + else { + applyRawUpdate(this.resource, configuration, update); + } + } + + this.waitForResourceConfigurationUpdateToComplete(); + println("Configuration update has completed."); + + println("Loading latest, updated configuration"); + this.printLatestConfiguration(); + } + + this.waitForResourceConfigurationUpdateToComplete = function() { + print("Waiting for configuration update to complete...") + while (ConfigurationManager.isResourceConfigurationUpdateInProgress(this.resource.id)) { + print("."); + java.lang.Thread.sleep(waitInterval); + } + println(''); + } + + this.isRawSupported = function() { + var configFormat = this.resource.resourceType.resourceConfigurationDefinition.configurationFormat; + return ConfigurationFormat.RAW == configFormat; + } + + this.isStructuredSupported = function() { + var configFormat = this.resource.resourceType.resourceConfigurationDefinition.configurationFormat; + return ConfigurationFormat.STRUCTURED == configFormat; + } + + this.isStructuredAndRawSupported = function() { + var configFormat = this.resource.resourceType.resourceConfigurationDefinition.configurationFormat; + return ConfigurationFormat.STRUCTURED_AND_RAW == configFormat; + } + + function verifyPropertyToUpdateExists(configuration) { + if (!isDefined('propertyName')) { + throw "\nThe 'propertyName' variable must be defined. Update will abort."; + } + + if (!isDefined('propertyValue')) { + throw "\nThe 'propertyValue' variable must be defined. Update will abort."; + } + + if(configuration.getSimple(propertyName) == null) { + throw "\nThe property '" + propertyName + "' is undefined. Update will abort."; + } + } + + function verifyRawContentExists() { + if (!isDefined('contents')) { + throw "\n'contents' argument is required when updating " + serverName; + } + } + + function applyStructuredUpdate(resource, configuration, update) { + println("Applying resource configuration update..."); + doStructuredUpdate(resource, configuration, update); + ConfigurationManager.updateStructuredOrRawConfiguration(resource.id, configuration, structured); + } + + function doStructuredUpdate(resource, configuration, update) { + for (key in update) { + var property = configuration.getSimple(key.toString()); + if (property == null) { + throw "\nThe property '" + key + "' does not exist in the configuration. Update will abort."; + } + property.stringValue = update[key]; + } + } + + function applyRawUpdate(resource, configuration, update) { + println("Applying resource configuration update..."); + doRawUpdate(resource, configuration, update); + ConfigurationManager.updateStructuredOrRawConfiguration(resource.id, configuration, raw); + } + + function doRawUpdate(resourcec, configuration) { + var updates = 0; + var rawConfigs = java.util.ArrayList(configuration.rawConfigurations); + for (path in update) { + var rawConfig = findRawConfig(path, rawConfigs); + if (rawConfig == null) { + println("Failed to find raw config with path ending with " + path); + } + else { + configuration.rawConfigurations.remove(rawConfig); + var contents = java.lang.String(update[path]); + rawConfig.contents = contents.bytes; + configuration.rawConfigurations.add(rawConfig); + updates++; + } + } + + if (updates == 0) { + throw "\nNo matching paths were found. Update will abort."; + } + } + + function findRawConfig(path, rawConfigs) { + for (i = 0; i < rawConfigs.size(); i++) { + var rawConfig = rawConfigs.get(i); + if (rawConfig.path.endsWith(path.toString())) { + return rawConfig; + } + } + return null; + } + +} + +function findServer(name) { + var criteria = ResourceCriteria(); + criteria.strict = true; + criteria.addFilterName(name); + criteria.fetchResourceType(true); + + var resources = ResourceManager.findResourcesByCriteria(criteria); + + Assert.assertTrue(resources.size() == 1, "Expected to get back one resource but got back " + resources.size()); + + var resource = resources.get(0); + var resourceType = findResourceType(resource); + + if (resourceType == null) { + resourceType = loadResourceType(resource); + + if (resourceType == null) { + throw "Failed to initialize resource type for " + resource.name; + } + } + resource.resourceType = resourceType; + + return resource; +} + +function loadResourceType(resource) { + return ResourceTypeManager.getResourceTypeById(resource.resourceType.id); +} + +function findResourceType(resource) { + for (i = 0; i < resourceTypes.size(); i++) { + var resourceType = resourceTypes.get(i); + if (resourceType.id == resource.resourceType.id) { + return resourceType; + } + } + return null; +}
commit 94eb322b31c661d5d7b94c27864ecf9aaba831bc Author: John Sanda john@localhost.localdomain Date: Fri Dec 18 14:42:21 2009 -0500
Revert "Cleaned up icons and sidebar navigation, toggles between edit in view"
This reverts commit c02a8fe5b89142966494cf564e15a9ed10d77591.
Conflicts:
modules/core/gui/src/main/java/org/rhq/core/gui/configuration/AbstractConfigurationComponent.java modules/core/gui/src/main/java/org/rhq/core/gui/configuration/ConfigRenderer.java modules/core/gui/src/main/java/org/rhq/core/gui/configuration/RawConfigUIComponent.java modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml
diff --git a/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/AbstractConfigurationComponent.java b/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/AbstractConfigurationComponent.java index 3cda4bd..91185e6 100644 --- a/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/AbstractConfigurationComponent.java +++ b/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/AbstractConfigurationComponent.java @@ -213,4 +213,4 @@ public abstract class AbstractConfigurationComponent extends UIComponentBase imp this.isGroup = (Boolean) this.stateValues[6]; }
-} \ No newline at end of file +} diff --git a/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/ConfigRenderer.java b/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/ConfigRenderer.java index 20abbcd..2ebbc53 100644 --- a/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/ConfigRenderer.java +++ b/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/ConfigRenderer.java @@ -250,14 +250,15 @@ public class ConfigRenderer extends Renderer { configurationComponent.setListIndex(addNewMap(configurationComponent)); }
- addListMemberProperty(configurationComponent); - } else { - addConfiguration(configurationComponent); - } + addListMemberProperty(configurationComponent); + } else { + addConfiguration(configurationComponent); + }
- String id = getInitInputsJavaScriptComponentId(configurationComponent); - PropertyRenderingUtility.addInitInputsJavaScript(configurationComponent, id, configurationComponent - .isFullyEditable(), false); + String id = getInitInputsJavaScriptComponentId(configurationComponent); + PropertyRenderingUtility.addInitInputsJavaScript(configurationComponent, id, configurationComponent + .isFullyEditable(), false); + } }
private void addListMemberProperty(AbstractConfigurationComponent configurationComponent) {
commit e19f91fda6b797c9422b5d9e4736ae0854828453 Author: John Sanda john@localhost.localdomain Date: Fri Dec 18 14:36:36 2009 -0500
Revert "started pushing the decode and encode stuff into the appropriate portion of the jsf lifecycle."
This reverts commit 6cbb7df18da1585103d5b819f80c1b00ad019aab.
Conflicts:
modules/core/gui/src/main/java/org/rhq/core/gui/configuration/ConfigRenderer.java modules/core/gui/src/main/java/org/rhq/core/gui/configuration/RawConfigUIComponent.java modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml
diff --git a/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/ConfigRenderer.java b/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/ConfigRenderer.java index b5e67a3..20abbcd 100644 --- a/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/ConfigRenderer.java +++ b/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/ConfigRenderer.java @@ -615,4 +615,4 @@ public class ConfigRenderer extends Renderer { } throw new IllegalStateException("Unable to determine index of component " + component); } -} \ No newline at end of file +}
commit 49b83ff2cb4ca990a2ca82a32ae8e1cdd34693af Author: John Sanda john@localhost.localdomain Date: Fri Dec 18 14:27:11 2009 -0500
Revert "[BZ 544136] Fixing bug that prevented see history for raw config updates"
This reverts commit c73d40ce3406a3cc904fb34429b9248b48f8e531.
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java index 586d603..fb82e6e 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java @@ -842,9 +842,8 @@ public class ConfigurationManagerBean implements ConfigurationManagerLocal, Conf }
Resource resource = entityManager.find(Resource.class, resourceId); - ConfigurationDefinition configDef = resource.getResourceType().getResourceConfigurationDefinition(); - if ((configDef == null || configDef.getPropertyDefinitions().isEmpty()) - && configDef.getConfigurationFormat() == ConfigurationFormat.STRUCTURED) { + if (resource.getResourceType().getResourceConfigurationDefinition() == null + || resource.getResourceType().getResourceConfigurationDefinition().getPropertyDefinitions().isEmpty()) { return new PageList<ResourceConfigurationUpdate>(pc); }
commit 1bdffa21a58116ee0dcd086408c0098e2709e7e8 Author: John Sanda john@localhost.localdomain Date: Fri Dec 18 14:26:48 2009 -0500
Revert "[BZ 538088] Reverting back to using the view ui bean which only has a request scope."
This reverts commit cb18055cfd528342fda2ddeed570ef5b15fd4183.
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml index 72da244..0d4899f 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml @@ -44,27 +44,27 @@ THIS TEXT WILL BE REMOVED. <input type="hidden" name="id" value="#{ResourceUIBean.id}"/>
<h:panelGrid columns="2" styleClass="buttons-table" columnClasses="button-cell" - rendered="#{ExistingResourceConfigurationViewUIBean.configuration != null and !ExistingResourceConfigurationViewUIBean.updateInProgress}"> + rendered="#{ExistingResourceConfigurationUIBean.configuration != null and !ExistingResourceConfigurationUIBean.updateInProgress}">
- <h:commandButton value="#{messages.editstructured}" action="#{ExistingResourceConfigurationViewUIBean.editConfiguration}" + <h:commandButton value="#{messages.editstructured}" action="#{ExistingResourceConfigurationUIBean.editConfiguration}" title="Edit this Configuration" styleClass="buttonmed" - rendered="${ResourceUIBean.permissions.configure and ExistingResourceConfigurationViewUIBean.structuredSupported and !ExistingResourceConfigurationViewUIBean.updateInProgress}" /> + rendered="${ResourceUIBean.permissions.configure and ExistingResourceConfigurationUIBean.structuredSupported and !ExistingResourceConfigurationUIBean.updateInProgress}" /> <h:commandButton value="#{messages.editraw}" action="#{ExistingResourceConfigurationUIBean.editRawConfiguration}" title="Advanced Mode Edit of Raw Configuration Files" styleClass="buttonmed" - rendered="${ResourceUIBean.permissions.configure and ExistingResourceConfigurationViewUIBean.rawSupported and !ExistingResourceConfigurationViewUIBean.updateInProgress}" /> + rendered="${ResourceUIBean.permissions.configure and ExistingResourceConfigurationUIBean.rawSupported and !ExistingResourceConfigurationUIBean.updateInProgress}" /> </h:panelGrid>
- <onc:config configurationDefinition="#{ExistingResourceConfigurationViewUIBean.configurationDefinition}" - configuration="#{ExistingResourceConfigurationViewUIBean.configuration}" - accessMapActionExpression="#{ExistingResourceConfigurationViewUIBean.accessMap}" + <onc:config configurationDefinition="#{ExistingResourceConfigurationUIBean.configurationDefinition}" + configuration="#{ExistingResourceConfigurationUIBean.configuration}" + accessMapActionExpression="#{ExistingResourceConfigurationUIBean.accessMap}" readOnly="true" - nullConfigurationDefinitionMessage="#{ExistingResourceConfigurationViewUIBean.nullConfigurationDefinitionMessage}" - nullConfigurationMessage="#{ExistingResourceConfigurationViewUIBean.nullConfigurationMessage}" + nullConfigurationDefinitionMessage="#{ExistingResourceConfigurationUIBean.nullConfigurationDefinitionMessage}" + nullConfigurationMessage="#{ExistingResourceConfigurationUIBean.nullConfigurationMessage}" prevalidate="true"/>
</h:form>
- <h:panelGroup layout="block" styleClass="InfoBlock" rendered="#{ExistingResourceConfigurationViewUIBean.updateInProgress}"> + <h:panelGroup layout="block" styleClass="InfoBlock" rendered="#{ExistingResourceConfigurationUIBean.updateInProgress}"> <b>${msg['note']}</b> ${msg['resource.config.Current.updateInProgress']} </h:panelGroup>
commit 830710ae0069b34325aae5eaaca595bb8d1c9db8 Author: John Sanda john@localhost.localdomain Date: Fri Dec 18 14:26:30 2009 -0500
Revert "[BZ 537891] Fixing bug in which required query parameter was not getted appended to url"
This reverts commit 4e7f1939c4cc1388d3cf9a5b35647684a3d7b033.
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ExistingResourceConfigurationUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ExistingResourceConfigurationUIBean.java index 3189d79..bb93d81 100644 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ExistingResourceConfigurationUIBean.java +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ExistingResourceConfigurationUIBean.java @@ -417,8 +417,7 @@ public class ExistingResourceConfigurationUIBean extends AbstractConfigurationUI current = null; setConfiguration(configuration);
-// return "/rhq/resource/configuration/edit.xhtml?currentResourceId=" + getResourceId(); - return SUCCESS_OUTCOME; + return "/rhq/resource/configuration/edit.xhtml?currentResourceId=" + getResourceId(); }
void populateRaws() { @@ -451,4 +450,4 @@ public class ExistingResourceConfigurationUIBean extends AbstractConfigurationUI TreeMap<String, RawConfiguration> modified = new TreeMap<String, RawConfiguration>(); RawConfiguration current = null;
-} +} \ No newline at end of file diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-navigation/configuration-navigation.xml b/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-navigation/configuration-navigation.xml index bd0f1bf..4443b36 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-navigation/configuration-navigation.xml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-navigation/configuration-navigation.xml @@ -23,12 +23,6 @@ <from-action>#{ConfigHelperUIBean.accessMap}</from-action> <to-view-id>/rhq/resource/configuration/view-map.xhtml</to-view-id> </navigation-case> - - <navigation-case> - <from-action>#{ExistingResourceConfigurationUIBean.switchTostructured}</from-action> - <to-view-id>/rhq/resource/configuration/edit.xhtml?id=#{param.id}</to-view-id> - <redirect/> - </navigation-case>
</navigation-rule>
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit-raw.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit-raw.xhtml index bf05c9b..c01694e 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit-raw.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit-raw.xhtml @@ -35,10 +35,10 @@ <a4j:form id="editResourceConfigurationForm"> <h:outputText value="#{messages.youareviewingraw}" /> - <h:panelGroup rendered="#{ExistingResourceConfigurationUIBean.structuredSupported}"> + <h:panelGroup rendered="#{ExistingResourceConfigurationUIBean.structuredSupported}"> <h:outputText value=" #{messages.switch2}" /> <h:commandLink action="#{ExistingResourceConfigurationUIBean.switchTostructured}"> - <f:param name="conversationId" value="#{conversation.id}"/> + <s:conversationId /> <f:param name="id" value="#{ResourceUIBean.id}" /> <h:outputText value=" #{messages.structured}" /> </h:commandLink>
commit 53055b7f043746f3c2fb596e02d9c727182ae07e Author: John Sanda john@localhost.localdomain Date: Fri Dec 18 14:26:02 2009 -0500
Revert "Removing check for config property definitions in findResourceConfigurationUpdates()"
This reverts commit 0050ae7cdf3e8e226f728b1d64f9effde315fa76.
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java index fbae47d..586d603 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java @@ -842,6 +842,11 @@ public class ConfigurationManagerBean implements ConfigurationManagerLocal, Conf }
Resource resource = entityManager.find(Resource.class, resourceId); + ConfigurationDefinition configDef = resource.getResourceType().getResourceConfigurationDefinition(); + if ((configDef == null || configDef.getPropertyDefinitions().isEmpty()) + && configDef.getConfigurationFormat() == ConfigurationFormat.STRUCTURED) { + return new PageList<ResourceConfigurationUpdate>(pc); + }
pc.initDefaultOrderingField("cu.id", PageOrdering.DESC);
commit 156dce2a3eeeb7e6e56ec354db55a30e76c3d65f Author: John Sanda john@localhost.localdomain Date: Fri Dec 18 14:25:46 2009 -0500
Revert "removed temporary file."
This reverts commit ed7ba67209643e53b1fcd94fbb1a9c74e89bb80a.
diff --git a/temp-testng-customsuite.xml b/temp-testng-customsuite.xml new file mode 100644 index 0000000..b4645bb --- /dev/null +++ b/temp-testng-customsuite.xml @@ -0,0 +1,8 @@ +<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd"> +<suite name="rhq" parallel=""> + <test verbose="2" name="org.rhq.core.gui.configuration.ConfigRendererTest" annotations="JDK"> + <classes> + <class name="org.rhq.core.gui.configuration.ConfigRendererTest"/> + </classes> + </test> +</suite>
commit 74f91f74d5b6f7ab5219a280cde3a3b849bd37b6 Author: John Sanda john@localhost.localdomain Date: Fri Dec 18 14:25:25 2009 -0500
Revert "Merge of current raw work with remote branch"
This reverts commit 2d4e562f32814f683a754eabe829531b0b8e40df, reversing changes made to 0050ae7cdf3e8e226f728b1d64f9effde315fa76.
diff --git a/.classpath b/.classpath index 27f5303..4ae348c 100644 --- a/.classpath +++ b/.classpath @@ -1,7 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <classpath> <classpathentry kind="src" path="modules/common/jboss-as/src/main/java"/> - <classpathentry kind="src" path="modules/test-utils/src/main/java"/> <classpathentry kind="src" path="modules/common/jboss-as/src/test/java"/> <classpathentry kind="src" path="modules/plugins/jboss-as/src/main/java"/> <classpathentry kind="src" path="modules/plugins/jboss-as/src/test/java"/> @@ -14,9 +13,7 @@ <classpathentry kind="src" path="modules/plugins/tomcat/src/test/java"/> <classpathentry kind="src" path="modules/plugins/jboss-cache/src/main/java"/> <classpathentry kind="src" path="modules/plugins/jboss-cache-v3/src/main/java"/> - <classpathentry kind="src" path="modules/plugins/antlr-config/src/main/java"/> - <classpathentry kind="src" path="modules/core/gui/src/test/java"/> - <classpathentry kind="src" path="modules/plugins/antlr-config/target/generated-sources/antlr3"/> + <classpathentry excluding="org/rhq/plugins/antlrconfig/" kind="src" path="modules/plugins/antlr-config/src/main/java"/> <classpathentry kind="var" path="M2_REPO/org/jboss/integration/jboss-profileservice-spi/5.1.0.SP1/jboss-profileservice-spi-5.1.0.SP1.jar"/> <classpathentry kind="var" path="M2_REPO/org/jboss/man/jboss-managed/2.1.1.GA/jboss-managed-2.1.1.GA.jar"/> <classpathentry kind="var" path="M2_REPO/org/jboss/man/jboss-metatype/2.1.1.GA/jboss-metatype-2.1.1.GA.jar"/> @@ -105,6 +102,7 @@ <classpathentry kind="src" path="modules/plugins/snmptrapd/src/main/java"/> <classpathentry kind="src" path="modules/plugins/script/src/main/java"/> <classpathentry kind="src" path="modules/plugins/antlr-config/src/main/antlr3"/> + <classpathentry kind="src" path="modules/plugins/antlr-config/target/generated-sources/antlr3"/> <classpathentry kind="src" path="modules/helpers/rtfilter/src/main/java"/> <classpathentry kind="src" path="modules/helpers/pluginAnnotations/src/main/java"/> <classpathentry kind="src" path="modules/helpers/pluginGen/src/main/java"/> @@ -205,8 +203,5 @@ <classpathentry exported="true" kind="var" path="M2_REPO/commons-digester/commons-digester/1.8/commons-digester-1.8.jar"/> <classpathentry exported="true" kind="var" path="M2_REPO/commons-codec/commons-codec/1.4/commons-codec-1.4.jar"/> <classpathentry exported="true" kind="lib" path="modules/enterprise/remoting/webservices/target/rhq-remoting-webservices-1.4.0-SNAPSHOT/wsconsume-output"/> - <classpathentry kind="var" path="M2_REPO/org/jmock/jmock/2.5.1/jmock-2.5.1.jar" sourcepath="/M2_REPO/org/jmock/jmock/2.5.1/jmock-2.5.1-sources.jar"/> - <classpathentry kind="var" path="M2_REPO/org/hamcrest/hamcrest-core/1.1/hamcrest-core-1.1.jar" sourcepath="/M2_REPO/org/hamcrest/hamcrest-core/1.1/hamcrest-core-1.1-sources.jar"/> - <classpathentry kind="var" path="M2_REPO/org/hamcrest/hamcrest-library/1.1/hamcrest-library-1.1.jar" sourcepath="M2_REPO/org/hamcrest/hamcrest-library/1.1/hamcrest-library-1.1-sources.jar"/> <classpathentry kind="output" path="eclipse-classes"/> </classpath> diff --git a/.gitignore b/.gitignore index bca5c45..1d53abe 100644 --- a/.gitignore +++ b/.gitignore @@ -18,4 +18,3 @@ dev-container dev-agent antlr-generated/ *.tokens -test-output/* diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/RawConfiguration.java b/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/RawConfiguration.java index 069ca34..1bb27c9 100644 --- a/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/RawConfiguration.java +++ b/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/RawConfiguration.java @@ -23,7 +23,7 @@
package org.rhq.core.domain.configuration;
-import java.io.Serializable; +import org.rhq.core.util.MessageDigestGenerator;
import javax.persistence.Column; import javax.persistence.Entity; @@ -36,8 +36,7 @@ import javax.persistence.PrePersist; import javax.persistence.PreUpdate; import javax.persistence.SequenceGenerator; import javax.persistence.Table; - -import org.rhq.core.util.MessageDigestGenerator; +import java.io.Serializable;
/** * Resources support structured configuration as well as raw configuration which is represented by this class. A raw @@ -123,14 +122,6 @@ public class RawConfiguration implements Serializable, DeepCopyable<RawConfigura updateSha256(); }
- public String getContentString() { - return new String(getContents()); - } - - public void setContentString(String newValue) { - setContents(newValue.getBytes()); - } - private byte[] copy(byte[] original) { byte[] copy = new byte[original.length]; for (int i = 0; i < original.length; ++i) { @@ -215,7 +206,7 @@ public class RawConfiguration implements Serializable, DeepCopyable<RawConfigura if (this.path == null && that.path == null) { return true; } - if ((this.path != null && that.path != null) && this.path.equals(that.path)) { + if ((this.path !=null && that.path != null) && this.path.equals(that.path)) { return true; } } @@ -239,9 +230,14 @@ public class RawConfiguration implements Serializable, DeepCopyable<RawConfigura
@Override public String toString() { - return new StringBuilder().append(getClass().getSimpleName()).append("[id=").append(id).append(", path=") - .append(path).append(", sha256=").append(sha256).append(", configuration=").append(configuration).append( - "]").toString(); + return new StringBuilder() + .append(getClass().getSimpleName()) + .append("[id=").append(id) + .append(", path=").append(path) + .append(", sha256=").append(sha256) + .append(", configuration=").append(configuration) + .append("]") + .toString(); }
public RawConfiguration deepCopy(boolean keepId) { @@ -251,7 +247,7 @@ public class RawConfiguration implements Serializable, DeepCopyable<RawConfigura }
copy.path = this.path; - + if (this.contents != null) { copy.setContents(this.getContents()); } @@ -260,3 +256,4 @@ public class RawConfiguration implements Serializable, DeepCopyable<RawConfigura }
} + diff --git a/modules/core/gui/pom.xml b/modules/core/gui/pom.xml index eaddceb..96a3212 100644 --- a/modules/core/gui/pom.xml +++ b/modules/core/gui/pom.xml @@ -138,14 +138,6 @@ </exclusions> </dependency>
- - <dependency> - <groupId>javax.faces</groupId> - <artifactId>jsf-impl</artifactId> - <scope>provided</scope> - </dependency> - - </dependencies>
<repositories> @@ -229,4 +221,4 @@
</profiles>
-</project> +</project> \ No newline at end of file diff --git a/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/AbstractConfigurationComponent.java b/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/AbstractConfigurationComponent.java index 2fe72ee..3cda4bd 100644 --- a/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/AbstractConfigurationComponent.java +++ b/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/AbstractConfigurationComponent.java @@ -29,11 +29,9 @@ import javax.faces.context.FacesContext;
import org.rhq.core.domain.configuration.Configuration; import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; -import org.rhq.core.domain.configuration.definition.ConfigurationFormat; import org.rhq.core.gui.configuration.propset.ConfigurationSetComponent; import org.rhq.core.gui.util.FacesComponentIdFactory; import org.rhq.core.gui.util.FacesComponentUtility; -import org.rhq.core.gui.util.FacesContextUtility;
/** * An abstract base class for the {@link ConfigUIComponent} and the {@link ConfigurationSetComponent} JSF component @@ -52,7 +50,7 @@ public abstract class AbstractConfigurationComponent extends UIComponentBase imp private static final String READ_ONLY_ATTRIBUTE = "readOnly"; private static final String FULLY_EDITABLE_ATTRIBUTE = "fullyEditable";
- private Boolean readOnly = true; + private Boolean readOnly; private Boolean fullyEditable; private String listName; private Integer listIndex; @@ -215,19 +213,4 @@ public abstract class AbstractConfigurationComponent extends UIComponentBase imp this.isGroup = (Boolean) this.stateValues[6]; }
- public boolean getShouldShowRaw() { - return Boolean.valueOf(FacesContextUtility.getOptionalRequestParameter("showRaw", String.class, "unset")) - || (this.getConfigurationDefinition().getConfigurationFormat().equals(ConfigurationFormat.RAW)); - } - - RawConfigUIComponent rawConfigUIComponent; - - RawConfigUIComponent getRawConfigUIComponent() { - if (null == rawConfigUIComponent) { - rawConfigUIComponent = new RawConfigUIComponent(getConfiguration(), getConfigurationDefinition(), this, - isReadOnly()); - } - return rawConfigUIComponent; - } - } \ No newline at end of file diff --git a/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/ConfigRenderer.java b/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/ConfigRenderer.java index e3f0c16..b5e67a3 100644 --- a/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/ConfigRenderer.java +++ b/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/ConfigRenderer.java @@ -31,10 +31,7 @@ import javax.faces.application.FacesMessage; import javax.faces.component.UIComponent; import javax.faces.component.UIForm; import javax.faces.component.UIInput; -import javax.faces.component.UIOutput; -import javax.faces.component.UIPanel; import javax.faces.component.UIParameter; -import javax.faces.component.html.HtmlCommandLink; import javax.faces.component.html.HtmlForm; import javax.faces.component.html.HtmlOutputLink; import javax.faces.component.html.HtmlPanelGrid; @@ -57,7 +54,6 @@ 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.configuration.definition.ConfigurationFormat; import org.rhq.core.domain.configuration.definition.PropertyDefinition; import org.rhq.core.domain.configuration.definition.PropertyDefinitionMap; import org.rhq.core.domain.configuration.definition.PropertyDefinitionSimple; @@ -88,7 +84,7 @@ public class ConfigRenderer extends Renderer { protected static final String GROUP_DESCRIPTION_PANEL_STYLE_CLASS = "group-description-panel"; protected static final String GROUP_DESCRIPTION_TEXT_PANEL_STYLE_CLASS = "group-description-text-panel";
- private static final Log LOG = LogFactory.getLog(ConfigRenderer.class); + private final Log LOG = LogFactory.getLog(ConfigRenderer.class); private static final String INIT_INPUTS_JAVA_SCRIPT_COMPONENT_ID_SUFFIX = "-initInputsJavaScript";
/** @@ -121,20 +117,6 @@ public class ConfigRenderer extends Renderer { .isFullyEditable(), true); } } - - Boolean readOnly = Boolean.valueOf(FacesContextUtility.getOptionalRequestParameter("readOnly")); - Boolean save = Boolean.valueOf(FacesContextUtility.getOptionalRequestParameter("save")); - configurationComponent.setReadOnly(readOnly); - - if (component.getChildCount() == 0) - addChildComponents(configurationComponent); - for (UIComponent kid : configurationComponent.getChildren()) { - if (kid instanceof RawConfigUIComponent) { - kid.decode(facesContext); - } - - } - }
/** @@ -213,16 +195,12 @@ public class ConfigRenderer extends Renderer { writer.writeText("\n", component, null); writer.endElement("div"); writer.writeComment("********** End of " + component.getClass().getSimpleName() + " component **********"); - - component.getChildren().clear(); }
public void addChildComponents(AbstractConfigurationComponent configurationComponent) { - if ((configurationComponent.getConfigurationDefinition() == null) || ((configurationComponent.getConfiguration() != null) && configurationComponent.getConfiguration() - .getMap().isEmpty()) - && !configurationComponent.getConfigurationDefinition().getConfigurationFormat().isRawSupported()) { + .getMap().isEmpty())) { if (configurationComponent.getNullConfigurationDefinitionMessage() != null) { String styleClass = (configurationComponent.getNullConfigurationStyle() == null) ? "ErrorBlock" : configurationComponent.getNullConfigurationStyle(); @@ -263,43 +241,6 @@ public class ConfigRenderer extends Renderer { } }
- Boolean shouldShowRawNow = configurationComponent.getShouldShowRaw(); - - if (shouldShowRawNow) { - configurationComponent.getChildren().add( - new RawConfigUIComponent(configurationComponent.getConfiguration(), configurationComponent - .getConfigurationDefinition(), configurationComponent, configurationComponent.isReadOnly())); - } else { - addStructuredConfig(configurationComponent); - } - } - - private void addStructuredConfig(AbstractConfigurationComponent configurationComponent) { - UIPanel toolbarPanel = FacesComponentUtility.addBlockPanel(configurationComponent, configurationComponent, - "summary-props-table"); - if (configurationComponent.isReadOnly()) { - HtmlCommandLink editLink = FacesComponentUtility.addCommandLink(toolbarPanel, configurationComponent); - FacesComponentUtility.addGraphicImage(editLink, configurationComponent, "/images/edit.png", "Edit"); - FacesComponentUtility.addOutputText(editLink, configurationComponent, "Edit", ""); - FacesComponentUtility.addParameter(editLink, configurationComponent, "readOnly", Boolean.toString(false)); - - } else { - HtmlCommandLink saveLink = FacesComponentUtility.addCommandLink(toolbarPanel, configurationComponent); - FacesComponentUtility.addGraphicImage(saveLink, configurationComponent, "/images/save.png", "Save"); - FacesComponentUtility.addOutputText(saveLink, configurationComponent, "Save", ""); - FacesComponentUtility.addParameter(saveLink, configurationComponent, "save", Boolean.toString(true)); - FacesComponentUtility.addParameter(saveLink, configurationComponent, "readOnly", Boolean.toString(true)); - } - - if (configurationComponent.getConfigurationDefinition().getConfigurationFormat().isRawSupported()) { - HtmlCommandLink toRawLink = FacesComponentUtility.addCommandLink(toolbarPanel, configurationComponent); - FacesComponentUtility.addGraphicImage(toRawLink, configurationComponent, "/images/raw.png", "showRaw"); - FacesComponentUtility.addOutputText(toRawLink, configurationComponent, "showRaw", ""); - FacesComponentUtility.addParameter(toRawLink, configurationComponent, "showRaw", Boolean.TRUE.toString()); - FacesComponentUtility.addParameter(toRawLink, configurationComponent, "readOnly", Boolean - .toString(configurationComponent.isReadOnly())); - } - if (!configurationComponent.isReadOnly()) addRequiredNotationsKey(configurationComponent);
@@ -319,27 +260,6 @@ public class ConfigRenderer extends Renderer { .isFullyEditable(), false); }
- private void addStructuredRawToggle(AbstractConfigurationComponent configurationComponent, boolean showRaw) { - if (configurationComponent.getConfigurationDefinition().getConfigurationFormat().equals( - ConfigurationFormat.STRUCTURED_AND_RAW)) { - - HtmlPanelGroup toRawLinkPanel = FacesComponentUtility.addBlockPanel(configurationComponent, - configurationComponent, UNGROUPED_PROPERTIES_STYLE_CLASS); - - FacesComponentUtility.addOutputText(toRawLinkPanel, configurationComponent, - "internationalized Message goes here", UNGROUPED_PROPERTIES_STYLE_CLASS); - - HtmlCommandLink commandLink = FacesComponentUtility.addCommandLink(toRawLinkPanel, configurationComponent); - - UIOutput output = new UIOutput(); - output.setValue(showRaw ? "Show Structured" : " Show Raw"); - commandLink.getChildren().add(output); - //output.setParent(commandLink); - FacesComponentUtility.addParameter(commandLink, configurationComponent, "showRaw", Boolean - .toString(!showRaw)); - } - } - private void addListMemberProperty(AbstractConfigurationComponent configurationComponent) { // Update member Configurations if this is a group config. if (configurationComponent instanceof ConfigurationSetComponent) { @@ -458,7 +378,7 @@ public class ConfigRenderer extends Renderer { + mapName + "'."); }
- private static void addRequiredNotationsKey(AbstractConfigurationComponent config) { + private void addRequiredNotationsKey(AbstractConfigurationComponent config) { addDebug(config, true, ".addNotePanel()"); HtmlPanelGroup footnotesPanel = FacesComponentUtility.addBlockPanel(config, config, NOTE_PANEL_STYLE_CLASS); FacesComponentUtility.addOutputText(footnotesPanel, config, "*", REQUIRED_MARKER_TEXT_STYLE_CLASS); @@ -573,11 +493,11 @@ public class ConfigRenderer extends Renderer { * @param start true if this is the "START" comment, false if it is the "END" comment * @param methodName the name of the method this is calling from */ - private static void addDebug(UIComponent component, boolean start, String methodName) { + private void addDebug(UIComponent component, boolean start, String methodName) { if (LOG.isDebugEnabled()) { StringBuilder msg = new StringBuilder("\n<!--"); msg.append(start ? " START " : " END "); - msg.append(ConfigRenderer.class.getSimpleName()); + msg.append(this.getClass().getSimpleName()); msg.append(methodName); msg.append(" -->\n "); FacesComponentUtility.addVerbatimText(component, msg); diff --git a/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/RawConfigUIComponent.java b/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/RawConfigUIComponent.java deleted file mode 100644 index ce42a54..0000000 --- a/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/RawConfigUIComponent.java +++ /dev/null @@ -1,209 +0,0 @@ -package org.rhq.core.gui.configuration; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import java.util.Vector; - -import javax.faces.component.UIComponent; -import javax.faces.component.UIComponentBase; -import javax.faces.component.UIPanel; -import javax.faces.component.UIParameter; -import javax.faces.component.html.HtmlCommandLink; -import javax.faces.component.html.HtmlInputTextarea; -import javax.faces.component.html.HtmlOutputLink; -import javax.faces.component.html.HtmlPanelGrid; -import javax.faces.context.FacesContext; - -import org.rhq.core.domain.configuration.Configuration; -import org.rhq.core.domain.configuration.RawConfiguration; -import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; -import org.rhq.core.gui.util.FacesComponentIdFactory; -import org.rhq.core.gui.util.FacesComponentUtility; -import org.rhq.core.gui.util.FacesContextUtility; - -public class RawConfigUIComponent extends UIComponentBase { - - private boolean readOnly; - private boolean showRaw; - - @Override - public void decode(FacesContext context) { - super.decode(context); - setSelectedPath(FacesContextUtility.getOptionalRequestParameter("path")); - readOnly = Boolean.valueOf(FacesContextUtility.getOptionalRequestParameter("readOnly")); - - } - - @Override - public String getFamily() { - return "rhq"; - } - - private Configuration configuration; - private ConfigurationDefinition configurationDefinition; - private FacesComponentIdFactory idFactory; - private String selectedPath; - private HtmlInputTextarea inputTextarea; - private Map<String, RawConfiguration> rawMap; - - public String getSelectedPath() { - if (null == selectedPath) { - if (configuration.getRawConfigurations().iterator().hasNext()) { - selectedPath = configuration.getRawConfigurations().iterator().next().getPath(); - } else { - selectedPath = ""; - } - } - return selectedPath; - } - - public void setSelectedPath(String selectedPath) { - if (selectedPath == null) - return; - for (RawConfiguration raw : configuration.getRawConfigurations()) { - if (raw.getPath().equals(selectedPath)) { - this.selectedPath = selectedPath; - } - } - } - - @Override - public boolean getRendersChildren() { - return true; - } - - @Override - public void encodeChildren(FacesContext context) throws IOException { - for (UIComponent kid : getChildren()) { - kid.encodeAll(context); - } - } - - @Override - public boolean isTransient() { - return true; - } - - Vector<UIParameter> readOnlyParms = new Vector<UIParameter>(); - - public RawConfigUIComponent(Configuration configuration, ConfigurationDefinition configurationDefinition, - FacesComponentIdFactory componentIdFactory, boolean readOnly) { - - this.configuration = configuration; - this.configurationDefinition = configurationDefinition; - this.idFactory = componentIdFactory; - this.readOnly = readOnly; - - UIPanel rawPanel = FacesComponentUtility.addBlockPanel(this, idFactory, ""); - - addToolbar(configurationDefinition, rawPanel); - - HtmlPanelGrid grid = FacesComponentUtility.addPanelGrid(rawPanel, idFactory, "summary-props-table"); - grid.setParent(this); - grid.setColumns(2); - grid.setColumnClasses("raw-config-table"); - - HtmlPanelGrid panelLeft = FacesComponentUtility.addPanelGrid(grid, idFactory, "summary-props-table"); - panelLeft.setBgcolor("#a4b2b9"); - panelLeft.setColumns(1); - - FacesComponentUtility.addOutputText(panelLeft, idFactory, "Raw Configurations Paths", ""); - - int rawCount = 0; - - ArrayList<String> configPathList = new ArrayList<String>(); - - rawMap = new HashMap<String, RawConfiguration>(); - - for (RawConfiguration raw : configuration.getRawConfigurations()) { - configPathList.add(raw.getPath()); - rawMap.put(raw.getPath(), raw); - } - Collections.sort(configPathList); - String oldDirname = ""; - for (String s : configPathList) { - RawConfiguration raw = rawMap.get(s); - String dirname = raw.getPath().substring(0, raw.getPath().lastIndexOf("/") + 1); - String basename = raw.getPath().substring(raw.getPath().lastIndexOf("/") + 1, raw.getPath().length()); - if (!dirname.equals(oldDirname)) { - FacesComponentUtility.addOutputText(panelLeft, idFactory, dirname, ""); - oldDirname = dirname; - } - UIPanel nextPath = FacesComponentUtility.addBlockPanel(panelLeft, idFactory, ""); - HtmlCommandLink link = FacesComponentUtility.addCommandLink(nextPath, idFactory); - FacesComponentUtility.addOutputText(link, idFactory, "[]" + basename, ""); - FacesComponentUtility.addParameter(link, idFactory, "path", raw.getPath()); - FacesComponentUtility.addParameter(link, idFactory, "whichRaw", Integer.toString(rawCount++)); - FacesComponentUtility.addParameter(link, idFactory, "showRaw", Boolean.TRUE.toString()); - readOnlyParms.add(FacesComponentUtility.addParameter(link, idFactory, "readOnly", Boolean - .toString(readOnly))); - - } - - UIPanel panelRight = FacesComponentUtility.addBlockPanel(grid, idFactory, "summary-props-table"); - - UIPanel editPanel = FacesComponentUtility.addBlockPanel(panelRight, idFactory, "summary-props-table"); - inputTextarea = new HtmlInputTextarea(); - editPanel.getChildren().add(inputTextarea); - inputTextarea.setParent(editPanel); - inputTextarea.setCols(80); - inputTextarea.setRows(40); - inputTextarea.setValue(rawMap.get(getSelectedPath()).getContentString()); - inputTextarea.setReadonly(readOnly); - } - - private void addToolbar(ConfigurationDefinition configurationDefinition, UIPanel parent) { - UIPanel toolbarPanel = FacesComponentUtility.addBlockPanel(parent, idFactory, "config-toolbar"); - if (readOnly) { - HtmlCommandLink editLink = FacesComponentUtility.addCommandLink(toolbarPanel, idFactory); - FacesComponentUtility.addGraphicImage(editLink, idFactory, "/images/edit.png", "Edit"); - FacesComponentUtility.addOutputText(editLink, idFactory, "Edit", ""); - FacesComponentUtility.addParameter(editLink, idFactory, "showStructured", Boolean.FALSE.toString()); - } else { - HtmlCommandLink saveLink = FacesComponentUtility.addCommandLink(toolbarPanel, idFactory); - FacesComponentUtility.addGraphicImage(saveLink, idFactory, "/images/save.png", "Save"); - FacesComponentUtility.addOutputText(saveLink, idFactory, "Save", ""); - FacesComponentUtility.addParameter(saveLink, idFactory, "showStructured", Boolean.FALSE.toString()); - } - { - HtmlCommandLink saveCommandLink = FacesComponentUtility.addCommandLink(toolbarPanel, idFactory); - FacesComponentUtility.addGraphicImage(saveCommandLink, idFactory, "/images/viewfullscreen.png", - "FullScreen"); - FacesComponentUtility.addOutputText(saveCommandLink, idFactory, "Full Screen", ""); - } - if (!readOnly) { - HtmlOutputLink uploadLink = FacesComponentUtility.addOutputLink(toolbarPanel, idFactory, "upload.xhtml"); - FacesComponentUtility.addGraphicImage(uploadLink, idFactory, "/images/upload.png", "Upload"); - FacesComponentUtility.addOutputText(uploadLink, idFactory, "Upload", ""); - } - { - HtmlOutputLink downloadLink = FacesComponentUtility - .addOutputLink(toolbarPanel, idFactory, "download.xhtml"); - FacesComponentUtility.addGraphicImage(downloadLink, idFactory, "/images/download.png", "download"); - FacesComponentUtility.addOutputText(downloadLink, idFactory, "Download", ""); - } - if (configurationDefinition.getConfigurationFormat().isStructuredSupported()) { - HtmlCommandLink toStructureLink = FacesComponentUtility.addCommandLink(toolbarPanel, idFactory); - FacesComponentUtility.addGraphicImage(toStructureLink, idFactory, "/images/structured.png", - "showStructured"); - FacesComponentUtility.addOutputText(toStructureLink, idFactory, "showStructured", ""); - FacesComponentUtility.addParameter(toStructureLink, idFactory, "showRaw", Boolean.FALSE.toString()); - readOnlyParms.add(FacesComponentUtility.addParameter(toStructureLink, idFactory, "readOnly", Boolean - .toString(readOnly))); - } - } - - @Override - public void encodeBegin(FacesContext context) throws IOException { - // TODO Auto-generated method stub - super.encodeBegin(context); - inputTextarea.setValue(rawMap.get(getSelectedPath()).getContentString()); - for (UIParameter param : readOnlyParms) { - param.setValue(Boolean.toString(readOnly)); - } - - } -} diff --git a/modules/core/gui/src/main/java/org/rhq/core/gui/util/FacesComponentUtility.java b/modules/core/gui/src/main/java/org/rhq/core/gui/util/FacesComponentUtility.java index ad2274b..a3c2257 100644 --- a/modules/core/gui/src/main/java/org/rhq/core/gui/util/FacesComponentUtility.java +++ b/modules/core/gui/src/main/java/org/rhq/core/gui/util/FacesComponentUtility.java @@ -1,25 +1,25 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2008 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, version 2, as - * published by the Free Software Foundation, and/or the GNU Lesser - * General Public License, version 2.1, also as published by the Free - * Software Foundation. - * - * 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 and the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * and the GNU Lesser 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. - */ + /* + * RHQ Management Platform + * Copyright (C) 2005-2008 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, version 2, as + * published by the Free Software Foundation, and/or the GNU Lesser + * General Public License, version 2.1, also as published by the Free + * Software Foundation. + * + * 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 and the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * and the GNU Lesser 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.core.gui.util;
import java.util.ArrayList; @@ -32,10 +32,10 @@ import java.util.UUID; import javax.el.ValueExpression; import javax.faces.application.Application; import javax.faces.component.UIComponent; -import javax.faces.component.UIForm; import javax.faces.component.UIInput; import javax.faces.component.UIOutput; import javax.faces.component.UIParameter; +import javax.faces.component.UIForm; import javax.faces.component.UIViewRoot; import javax.faces.component.html.HtmlColumn; import javax.faces.component.html.HtmlCommandButton; @@ -50,17 +50,16 @@ import javax.faces.component.html.HtmlOutputText; import javax.faces.component.html.HtmlPanelGrid; import javax.faces.component.html.HtmlPanelGroup; import javax.faces.context.FacesContext; - import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.richfaces.component.html.HtmlSeparator; import org.richfaces.component.html.HtmlSimpleTogglePanel;
-/** -* A set of utility methods for working with JSF {@link UIComponent}s. -* -* @author Ian Springer -*/ + /** + * A set of utility methods for working with JSF {@link UIComponent}s. + * + * @author Ian Springer + */ public abstract class FacesComponentUtility { public static final String NO_STYLE_CLASS = null;
@@ -78,31 +77,16 @@ public abstract class FacesComponentUtility { }
@NotNull - public static HtmlPanelGrid createPanelGrid(FacesComponentIdFactory idFactory, String styleClass) { - HtmlPanelGrid panel = createComponent(HtmlPanelGrid.class, idFactory); - panel.setStyleClass(styleClass); - return panel; - } - - @NotNull - public static HtmlPanelGroup addBlockPanel(@NotNull UIComponent parent, FacesComponentIdFactory idFactory, - String styleClass) { + public static HtmlPanelGroup addBlockPanel(@NotNull + UIComponent parent, FacesComponentIdFactory idFactory, String styleClass) { HtmlPanelGroup panel = createBlockPanel(idFactory, styleClass); parent.getChildren().add(panel); return panel; }
@NotNull - public static HtmlPanelGrid addPanelGrid(@NotNull UIComponent parent, FacesComponentIdFactory idFactory, - String styleClass) { - HtmlPanelGrid panel = createPanelGrid(idFactory, styleClass); - parent.getChildren().add(panel); - return panel; - } - - @NotNull - public static HtmlPanelGroup addInlinePanel(@NotNull UIComponent parent, FacesComponentIdFactory idFactory, - String styleClass) { + public static HtmlPanelGroup addInlinePanel(@NotNull + UIComponent parent, FacesComponentIdFactory idFactory, String styleClass) { HtmlPanelGroup panel = createComponent(HtmlPanelGroup.class, idFactory); panel.setStyleClass(styleClass); parent.getChildren().add(panel); @@ -110,8 +94,8 @@ public abstract class FacesComponentUtility { }
@NotNull - public static HtmlSimpleTogglePanel addSimpleTogglePanel(@NotNull UIComponent parent, - FacesComponentIdFactory idFactory, String label) { + public static HtmlSimpleTogglePanel addSimpleTogglePanel(@NotNull + UIComponent parent, FacesComponentIdFactory idFactory, String label) { HtmlSimpleTogglePanel panel = createComponent(HtmlSimpleTogglePanel.class, idFactory); panel.setLabel(label);
@@ -122,15 +106,16 @@ public abstract class FacesComponentUtility { }
@NotNull - public static HtmlSeparator addSeparator(@NotNull UIComponent parent, FacesComponentIdFactory idFactory) { + public static HtmlSeparator addSeparator(@NotNull + UIComponent parent, FacesComponentIdFactory idFactory) { HtmlSeparator separator = createComponent(HtmlSeparator.class, idFactory); parent.getChildren().add(separator); return separator; }
@NotNull - public static HtmlOutputText addOutputText(@NotNull UIComponent parent, FacesComponentIdFactory idFactory, - CharSequence value, String styleClass) { + public static HtmlOutputText addOutputText(@NotNull + UIComponent parent, FacesComponentIdFactory idFactory, CharSequence value, String styleClass) { HtmlOutputText text = createComponent(HtmlOutputText.class, idFactory); text.setValue(value); text.setStyleClass(styleClass); @@ -150,8 +135,8 @@ public abstract class FacesComponentUtility { }
@NotNull - public static HtmlColumn addColumn(@NotNull UIComponent parent, FacesComponentIdFactory idFactory, - CharSequence headerText, String headerStyle) { + public static HtmlColumn addColumn(@NotNull + UIComponent parent, FacesComponentIdFactory idFactory, CharSequence headerText, String headerStyle) { HtmlColumn column = createComponent(HtmlColumn.class, idFactory); HtmlOutputText header = new HtmlOutputText(); header.setValue(headerText); @@ -162,7 +147,8 @@ public abstract class FacesComponentUtility { }
@NotNull - public static HtmlOutputText addVerbatimText(@NotNull UIComponent parent, CharSequence html) { + public static HtmlOutputText addVerbatimText(@NotNull + UIComponent parent, CharSequence html) { HtmlOutputText outputText = createComponent(HtmlOutputText.class, null); outputText.setEscape(false); outputText.setValue(html); @@ -177,8 +163,10 @@ public abstract class FacesComponentUtility { }
@NotNull - public static UIOutput addJavaScript(@NotNull UIComponent parent, FacesComponentIdFactory idFactory, - @Nullable CharSequence src, @Nullable CharSequence script) { + public static UIOutput addJavaScript(@NotNull + UIComponent parent, FacesComponentIdFactory idFactory, @Nullable + CharSequence src, @Nullable + CharSequence script) { UIOutput output = createComponent(UIOutput.class, idFactory); output.getAttributes().put("escape", Boolean.FALSE); StringBuilder value = new StringBuilder(); @@ -232,8 +220,8 @@ public abstract class FacesComponentUtility { }
@NotNull - public static HtmlOutputLabel addLabel(@NotNull UIComponent parent, FacesComponentIdFactory idFactory, - UIInput associatedInput, String value, String styleClass) { + public static HtmlOutputLabel addLabel(@NotNull + UIComponent parent, FacesComponentIdFactory idFactory, UIInput associatedInput, String value, String styleClass) { HtmlOutputLabel label = createComponent(HtmlOutputLabel.class, idFactory); label.setFor(associatedInput.getId()); label.setValue(value); @@ -243,8 +231,8 @@ public abstract class FacesComponentUtility { }
@NotNull - public static HtmlGraphicImage addGraphicImage(@NotNull UIComponent parent, FacesComponentIdFactory idFactory, - String url, String alt) { + public static HtmlGraphicImage addGraphicImage(@NotNull + UIComponent parent, FacesComponentIdFactory idFactory, String url, String alt) { HtmlGraphicImage image = FacesComponentUtility.createComponent(HtmlGraphicImage.class, idFactory); image.setUrl(url); image.setAlt(alt); @@ -254,8 +242,8 @@ public abstract class FacesComponentUtility { }
@NotNull - public static HtmlOutputLink addOutputLink(@NotNull UIComponent parent, FacesComponentIdFactory idFactory, - String value) { + public static HtmlOutputLink addOutputLink(@NotNull + UIComponent parent, FacesComponentIdFactory idFactory, String value) { HtmlOutputLink link = FacesComponentUtility.createComponent(HtmlOutputLink.class, idFactory); link.setValue(value); parent.getChildren().add(link); @@ -263,8 +251,8 @@ public abstract class FacesComponentUtility { }
@NotNull - public static UIParameter addParameter(@NotNull UIComponent parent, FacesComponentIdFactory idFactory, String name, - String value) { + public static UIParameter addParameter(@NotNull + UIComponent parent, FacesComponentIdFactory idFactory, String name, String value) { UIParameter parameter = createComponent(UIParameter.class, idFactory); parameter.setName(name); parameter.setValue(value); @@ -273,7 +261,8 @@ public abstract class FacesComponentUtility { }
@NotNull - public static HtmlForm addForm(@NotNull UIComponent parent, FacesComponentIdFactory idFactory) { + public static HtmlForm addForm(@NotNull + UIComponent parent, FacesComponentIdFactory idFactory) { HtmlForm form = createComponent(HtmlForm.class, idFactory); form.setPrependId(false); parent.getChildren().add(form); @@ -281,8 +270,8 @@ public abstract class FacesComponentUtility { }
@NotNull - public static HtmlCommandButton addCommandButton(@NotNull UIComponent parent, FacesComponentIdFactory idFactory, - String value, String styleClass) { + public static HtmlCommandButton addCommandButton(@NotNull + UIComponent parent, FacesComponentIdFactory idFactory, String value, String styleClass) { HtmlCommandButton button = createComponent(HtmlCommandButton.class, idFactory); button.setValue(value); button.setStyleClass(styleClass); @@ -291,15 +280,16 @@ public abstract class FacesComponentUtility { }
@NotNull - public static HtmlCommandLink addCommandLink(@NotNull UIComponent parent, FacesComponentIdFactory idFactory) { + public static HtmlCommandLink addCommandLink(@NotNull + UIComponent parent, FacesComponentIdFactory idFactory) { HtmlCommandLink link = FacesComponentUtility.createComponent(HtmlCommandLink.class, idFactory); parent.getChildren().add(link); return link; }
@NotNull - public static HtmlMessage addMessage(@NotNull UIComponent parent, FacesComponentIdFactory idFactory, - String associatedComponentId, String styleClass) { + public static HtmlMessage addMessage(@NotNull + UIComponent parent, FacesComponentIdFactory idFactory, String associatedComponentId, String styleClass) { HtmlMessage message = FacesComponentUtility.createComponent(HtmlMessage.class, idFactory); message.setFor(associatedComponentId); message.setShowDetail(true); @@ -312,8 +302,8 @@ public abstract class FacesComponentUtility { }
@NotNull - public static HtmlPanelGrid addPanelGrid(@NotNull UIComponent parent, FacesComponentIdFactory idFactory, - int columns, String styleClass) { + public static HtmlPanelGrid addPanelGrid(@NotNull + UIComponent parent, FacesComponentIdFactory idFactory, int columns, String styleClass) { HtmlPanelGrid panelGrid = FacesComponentUtility.createComponent(HtmlPanelGrid.class, idFactory); panelGrid.setColumns(columns); panelGrid.setStyleClass(styleClass); @@ -322,8 +312,8 @@ public abstract class FacesComponentUtility { }
@NotNull - public static HtmlDataTable addDataTable(@NotNull UIComponent parent, FacesComponentIdFactory idFactory, - String styleClass) { + public static HtmlDataTable addDataTable(@NotNull + UIComponent parent, FacesComponentIdFactory idFactory, String styleClass) { HtmlDataTable dataTable = FacesComponentUtility.createComponent(HtmlDataTable.class, idFactory); dataTable.setStyleClass(styleClass); parent.getChildren().add(dataTable); @@ -331,13 +321,17 @@ public abstract class FacesComponentUtility { }
@Nullable - public static String getExpressionAttribute(@NotNull UIComponent component, @NotNull String attribName) { + public static String getExpressionAttribute(@NotNull + UIComponent component, @NotNull + String attribName) { return getExpressionAttribute(component, attribName, String.class); }
@Nullable - public static <T> T getExpressionAttribute(@NotNull UIComponent component, @NotNull String attribName, - @NotNull Class<T> expectedType) { + public static <T> T getExpressionAttribute(@NotNull + UIComponent component, @NotNull + String attribName, @NotNull + Class<T> expectedType) { ValueExpression valueExpression = component.getValueExpression(attribName); T attribValue = (valueExpression != null) ? FacesExpressionUtility.getValue(valueExpression, expectedType) : null; @@ -345,7 +339,8 @@ public abstract class FacesComponentUtility { }
@NotNull - public static Map<String, String> getParameters(@NotNull UIComponent component) { + public static Map<String, String> getParameters(@NotNull + UIComponent component) { // Use a LinkedHashMap, so the order of the parameters is maintained. Map<String, String> params = new LinkedHashMap<String, String>(); List<UIComponent> children = component.getChildren(); @@ -380,8 +375,8 @@ public abstract class FacesComponentUtility { * @return a {@link UIComponent} of the specified type */ @SuppressWarnings("unchecked") - public static <T extends UIComponent> T createComponent(Class<T> componentClass, - @Nullable FacesComponentIdFactory idFactory) { + public static <T extends UIComponent> T createComponent(Class<T> componentClass, @Nullable + FacesComponentIdFactory idFactory) { Application application = FacesContext.getCurrentInstance().getApplication(); String componentType = getComponentType(componentClass); T component = (T) application.createComponent(componentType); @@ -505,20 +500,25 @@ public abstract class FacesComponentUtility { * @throws IllegalArgumentException if more than one UIForm is found in the component's ancestry */ @Nullable - public static UIForm getEnclosingForm(UIComponent component) throws IllegalArgumentException { - UIForm ret = null; - while (component != null) { - if (component instanceof UIForm) { - if (ret != null) { - // Cannot have a doubly-nested form! - throw new IllegalArgumentException(); - } - ret = (UIForm) component; - } - component = component.getParent(); - } - return ret; - } + public static UIForm getEnclosingForm(UIComponent component) + throws IllegalArgumentException + { + UIForm ret = null; + while (component != null) + { + if (component instanceof UIForm) + { + if (ret != null) + { + // Cannot have a doubly-nested form! + throw new IllegalArgumentException(); + } + ret = (UIForm) component; + } + component = component.getParent(); + } + return ret; + }
private static <T extends UIComponent> String getComponentType(Class<T> componentClass) { String componentType; @@ -531,8 +531,9 @@ public abstract class FacesComponentUtility { return componentType; }
- private static class DefaultFacesComponentIdFactory implements FacesComponentIdFactory { - public String createUniqueId() { + private static class DefaultFacesComponentIdFactory implements FacesComponentIdFactory { + public String createUniqueId() + { // NOTE: Our id's *must* begin with UIViewRoot.UNIQUE_ID_PREFIX ("j_id") to prevent HtmlOutputText // components from being rendered as SPAN elements // (see com.sun.faces.renderkit.html_basic.TextRenderer#getEndTextToRender()). diff --git a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/ConfigRendererTest.java b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/ConfigRendererTest.java deleted file mode 100644 index d3db839..0000000 --- a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/ConfigRendererTest.java +++ /dev/null @@ -1,165 +0,0 @@ -package org.rhq.core.gui.configuration; - -import java.io.IOException; -import java.io.StringWriter; -import java.util.HashMap; - -import javax.faces.FactoryFinder; -import javax.faces.component.UIForm; -import javax.faces.context.FacesContext; -import javax.faces.lifecycle.Lifecycle; - -import com.sun.faces.context.FacesContextImpl; - -import org.ajax4jsf.context.AjaxContext; -import org.testng.Assert; -import org.testng.annotations.BeforeMethod; -import org.testng.annotations.Test; - -import org.rhq.core.domain.configuration.Configuration; -import org.rhq.core.domain.configuration.Property; -import org.rhq.core.domain.configuration.RawConfiguration; -import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; -import org.rhq.core.domain.configuration.definition.ConfigurationFormat; - -public class ConfigRendererTest { - - ConfigUIComponent configUIComponent; - ConfigRenderer configRenderer; - FacesContext facesContext; - MockExternalContext externalContext; - AjaxContext ajaxContext; - MockResponseWriter mockResponseWriter; - Lifecycle lifecycle; - ConfigurationDefinition configurationDefinition; - private Configuration configuration; - - @BeforeMethod - protected void setUp() throws Exception { - //Order is pretty important here - FactoryFinder.setFactory(FactoryFinder.RENDER_KIT_FACTORY, MockRenderKitFactory.class.getName()); - FactoryFinder.setFactory(FactoryFinder.APPLICATION_FACTORY, MockApplicationFactory.class.getName()); - - externalContext = new MockExternalContext(); - lifecycle = new MockLifecycle(); - mockResponseWriter = new MockResponseWriter(); - configUIComponent = new ConfigUIComponent(); - configRenderer = new ConfigRenderer(); - - FacesContextImpl impl = new FacesContextImpl(externalContext, lifecycle); - HashMap<Object, Object> map = new HashMap<Object, Object>(); - map.put("com.sun.faces.FacesContextImpl", impl); - - //Whichever one gets created last wins the - //"I'm registered with thread local storage and you are not" game - facesContext = new MockFacesContext(externalContext, mockResponseWriter); - facesContext.getExternalContext().getRequestMap().put("com.sun.faces.util.RequestStateManager", map); - ajaxContext = AjaxContext.getCurrentInstance(facesContext); - - configUIComponent.setId("ID"); - configuration = new Configuration(); - configUIComponent.setValueExpression("configuration", new MockValueExpression(configuration)); - configUIComponent.setValueExpression("configurationDefinition", - new MockValueExpression(buildConfigDefinition())); - configUIComponent.setRendererType(ConfigRenderer.class.getName()); - - } - - private ConfigurationDefinition buildConfigDefinition() { - ConfigurationDefinition def = new ConfigurationDefinition("MockDef", "Mock Configuration definition"); - - return def; - } - - //@Test - public void testUIComponentDecode() { - configUIComponent.setRendererType(ConfigRenderer.class.getName()); - configUIComponent.decode(facesContext); - } - - @Test - public void testUIComponentEncode() throws IOException { - Property value; - value = new Property(); - value.setName("test1"); - value.setConfiguration(configuration); - value.setId(3); - - configuration.getMap().put(value.getName(), value); - configuration.getRawConfigurations().add(buildMockRawConfig()); - - Assert.assertNotNull(configUIComponent.getConfigurationDefinition()); - - UIForm form = new UIForm(); - form.setId("form"); - form.getChildren().add(configUIComponent); - configUIComponent.setParent(form); - - configUIComponent.getConfigurationDefinition().setConfigurationFormat(ConfigurationFormat.STRUCTURED_AND_RAW); - - Assert.assertNotNull(configUIComponent.getConfigurationDefinition().getConfigurationFormat()); - Assert.assertTrue(configUIComponent.getConfigurationDefinition().getConfigurationFormat().isRawSupported()); - Assert.assertTrue(configUIComponent.getConfigurationDefinition().getConfigurationFormat() - .isStructuredSupported()); - - externalContext.requestParameterMap.put("showRaw", "true"); - - configUIComponent.encodeAll(facesContext); - - String s2 = mockResponseWriter.stringWriter.getBuffer().toString(); - - System.out.println(s2); - - } - - private RawConfiguration buildMockRawConfig() { - RawConfiguration raw = new RawConfiguration(); - - raw.setContents("a=1".getBytes()); - return raw; - } - - //@Test - public void testDecode() { - configUIComponent.setReadOnly(false); - Assert.assertNotNull(configUIComponent.getConfiguration()); - configRenderer.decode(facesContext, configUIComponent); - } - - //@Test - public void testEncode() throws IOException { - configUIComponent.setReadOnly(true); - configUIComponent.setPrevalidate(false); - /* - <onc:config - configurationDefinition="#{ExistingResourceConfigurationUIBean.configurationDefinition}" - configuration="#{ExistingResourceConfigurationUIBean.configuration}" - accessMapActionExpression="#{ExistingResourceConfigurationUIBean.accessMap}" - readOnly="true" - nullConfigurationDefinitionMessage="#{ExistingResourceConfigurationUIBean.nullConfigurationDefinitionMessage}" - nullConfigurationMessage="#{ExistingResourceConfigurationUIBean.nullConfigurationMessage}" - prevalidate="true"/> - */ - - configRenderer.encodeBegin(this.facesContext, configUIComponent); - configRenderer.encodeChildren(facesContext, configUIComponent); - configRenderer.encodeEnd(facesContext, configUIComponent); - String s1 = mockResponseWriter.stringWriter.getBuffer().toString(); - - mockResponseWriter.stringWriter = new StringWriter(); - - configUIComponent.setReadOnly(false); - configUIComponent.setPrevalidate(false); - - configRenderer.encodeBegin(this.facesContext, configUIComponent); - configRenderer.encodeChildren(facesContext, configUIComponent); - configRenderer.encodeEnd(facesContext, configUIComponent); - String s2 = mockResponseWriter.stringWriter.getBuffer().toString(); - - Assert.assertTrue(!s1.equals(s2)); - - System.out.println(s1); - - } - -} diff --git a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockApplication.java b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockApplication.java deleted file mode 100644 index 94f5bc8..0000000 --- a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockApplication.java +++ /dev/null @@ -1,269 +0,0 @@ -package org.rhq.core.gui.configuration; - -import java.util.Collection; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Locale; -import java.util.Map; - -import javax.faces.FacesException; -import javax.faces.application.Application; -import javax.faces.application.NavigationHandler; -import javax.faces.application.StateManager; -import javax.faces.application.ViewHandler; -import javax.faces.component.UIComponent; -import javax.faces.component.UIParameter; -import javax.faces.component.html.HtmlCommandLink; -import javax.faces.component.html.HtmlGraphicImage; -import javax.faces.component.html.HtmlOutputFormat; -import javax.faces.component.html.HtmlOutputText; -import javax.faces.component.html.HtmlPanelGrid; -import javax.faces.component.html.HtmlPanelGroup; -import javax.faces.context.FacesContext; -import javax.faces.convert.Converter; -import javax.faces.el.MethodBinding; -import javax.faces.el.PropertyResolver; -import javax.faces.el.ReferenceSyntaxException; -import javax.faces.el.ValueBinding; -import javax.faces.el.VariableResolver; -import javax.faces.event.ActionListener; -import javax.faces.validator.Validator; - -public class MockApplication extends Application { - - Map<String, Class> componentTypeMap; - - @Override - public void addComponent(String componentType, String componentClass) { - throw new RuntimeException("Function not implemented"); - - } - - @Override - public void addConverter(Class targetClass, String converterClass) { - throw new RuntimeException("Function not implemented"); - - } - - @Override - public void addConverter(String converterId, String converterClass) { - throw new RuntimeException("Function not implemented"); - - } - - @Override - public void addValidator(String validatorId, String validatorClass) { - throw new RuntimeException("Function not implemented"); - - } - - @Override - public UIComponent createComponent(String componentType) throws FacesException { - try { - return (UIComponent) getComponentTypeMap().get(componentType).newInstance(); - } catch (Exception e) { - e.printStackTrace(); - throw new FacesException("can't create component " + componentType); - } - - } - - @Override - public UIComponent createComponent(ValueBinding componentBinding, FacesContext context, String componentType) - throws FacesException { - throw new RuntimeException("Function not implemented"); - - } - - @Override - public Converter createConverter(Class targetClass) { - throw new RuntimeException("Function not implemented"); - - } - - @Override - public Converter createConverter(String converterId) { - throw new RuntimeException("Function not implemented"); - - } - - @Override - public MethodBinding createMethodBinding(String ref, Class[] params) throws ReferenceSyntaxException { - throw new RuntimeException("Function not implemented"); - - } - - @Override - public Validator createValidator(String validatorId) throws FacesException { - throw new RuntimeException("Function not implemented"); - - } - - @Override - public ValueBinding createValueBinding(String ref) throws ReferenceSyntaxException { - throw new RuntimeException("Function not implemented"); - - } - - @Override - public ActionListener getActionListener() { - throw new RuntimeException("Function not implemented"); - - } - - Map<String, Class> getComponentTypeMap() { - if (null == componentTypeMap) { - - componentTypeMap = new HashMap<String, Class>(); - componentTypeMap.put("javax.faces.HtmlOutputText", HtmlOutputText.class); - componentTypeMap.put("javax.faces.HtmlPanelGroup", HtmlPanelGroup.class); - componentTypeMap.put("javax.faces.Output", HtmlOutputFormat.class); - componentTypeMap.put("javax.faces.HtmlCommandLink", HtmlCommandLink.class); - componentTypeMap.put("javax.faces.Parameter", UIParameter.class); - componentTypeMap.put("javax.faces.HtmlGraphicImage", HtmlGraphicImage.class); - componentTypeMap.put("javax.faces.HtmlPanelGrid", HtmlPanelGrid.class); - } - return componentTypeMap; - } - - @Override - public Iterator<String> getComponentTypes() { - throw new RuntimeException("Function not implemented"); - - } - - @Override - public Iterator<String> getConverterIds() { - throw new RuntimeException("Function not implemented"); - - } - - @Override - public Iterator<Class> getConverterTypes() { - throw new RuntimeException("Function not implemented"); - - } - - @Override - public Locale getDefaultLocale() { - throw new RuntimeException("Function not implemented"); - - } - - @Override - public String getDefaultRenderKitId() { - throw new RuntimeException("Function not implemented"); - - } - - @Override - public String getMessageBundle() { - throw new RuntimeException("Function not implemented"); - - } - - @Override - public NavigationHandler getNavigationHandler() { - throw new RuntimeException("Function not implemented"); - - } - - @Override - public PropertyResolver getPropertyResolver() { - throw new RuntimeException("Function not implemented"); - - } - - @Override - public StateManager getStateManager() { - throw new RuntimeException("Function not implemented"); - - } - - @Override - public Iterator<Locale> getSupportedLocales() { - throw new RuntimeException("Function not implemented"); - - } - - @Override - public Iterator<String> getValidatorIds() { - throw new RuntimeException("Function not implemented"); - - } - - @Override - public VariableResolver getVariableResolver() { - throw new RuntimeException("Function not implemented"); - - } - - MockViewHandler mockViewHandler = new MockViewHandler(); - - @Override - public ViewHandler getViewHandler() { - return mockViewHandler; - - } - - @Override - public void setActionListener(ActionListener listener) { - throw new RuntimeException("Function not implemented"); - - } - - @Override - public void setDefaultLocale(Locale locale) { - throw new RuntimeException("Function not implemented"); - - } - - @Override - public void setDefaultRenderKitId(String renderKitId) { - throw new RuntimeException("Function not implemented"); - - } - - @Override - public void setMessageBundle(String bundle) { - throw new RuntimeException("Function not implemented"); - - } - - @Override - public void setNavigationHandler(NavigationHandler handler) { - throw new RuntimeException("Function not implemented"); - - } - - @Override - public void setPropertyResolver(PropertyResolver resolver) { - throw new RuntimeException("Function not implemented"); - - } - - @Override - public void setStateManager(StateManager manager) { - throw new RuntimeException("Function not implemented"); - - } - - @Override - public void setSupportedLocales(Collection<Locale> locales) { - throw new RuntimeException("Function not implemented"); - - } - - @Override - public void setVariableResolver(VariableResolver resolver) { - throw new RuntimeException("Function not implemented"); - - } - - @Override - public void setViewHandler(ViewHandler handler) { - throw new RuntimeException("Function not implemented"); - - } - -} diff --git a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockApplicationFactory.java b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockApplicationFactory.java deleted file mode 100644 index ba180a3..0000000 --- a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockApplicationFactory.java +++ /dev/null @@ -1,20 +0,0 @@ -package org.rhq.core.gui.configuration; - -import javax.faces.application.Application; -import javax.faces.application.ApplicationFactory; - -public class MockApplicationFactory extends ApplicationFactory { - - Application application = new MockApplication(); - - @Override - public Application getApplication() { - return application; - } - - @Override - public void setApplication(Application application) { - this.application = application; - } - -} diff --git a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockExternalContext.java b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockExternalContext.java deleted file mode 100644 index ed0af06..0000000 --- a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockExternalContext.java +++ /dev/null @@ -1,235 +0,0 @@ -package org.rhq.core.gui.configuration; - -import java.io.IOException; -import java.io.InputStream; -import java.net.MalformedURLException; -import java.net.URL; -import java.security.Principal; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Locale; -import java.util.Map; -import java.util.Set; - -import javax.faces.context.ExternalContext; - -import com.sun.faces.application.ApplicationImpl; - -public class MockExternalContext extends ExternalContext { - - @Override - public void dispatch(String path) throws IOException { - throw new RuntimeException("Function not implemented"); - - } - - @Override - public String encodeActionURL(String url) { - throw new RuntimeException("Function not implemented"); - - } - - @Override - public String encodeNamespace(String name) { - throw new RuntimeException("Function not implemented"); - - } - - @Override - public String encodeResourceURL(String url) { - - return "encodedUrl:" + url; - - } - - public Map<String, Object> applicationMap; - - @Override - public Map<String, Object> getApplicationMap() { - if (null == applicationMap) { - applicationMap = new HashMap<String, Object>(); - applicationMap.put("com.sun.faces.ApplicationImpl", new ApplicationImpl()); - applicationMap.put("com.sun.faces.sunJsfJs", "Javascript goes here".toCharArray()); - } - - return applicationMap; - } - - @Override - public String getAuthType() { - throw new RuntimeException("Function not implemented"); - - } - - MockServletContext servletContext = new MockServletContext(); - - @Override - public Object getContext() { - return servletContext; - } - - @Override - public String getInitParameter(String name) { - throw new RuntimeException("Function not implemented"); - - } - - @Override - public Map getInitParameterMap() { - throw new RuntimeException("Function not implemented"); - - } - - @Override - public String getRemoteUser() { - throw new RuntimeException("Function not implemented"); - - } - - @Override - public Object getRequest() { - throw new RuntimeException("Function not implemented"); - - } - - @Override - public String getRequestContextPath() { - throw new RuntimeException("Function not implemented"); - - } - - @Override - public Map<String, Object> getRequestCookieMap() { - throw new RuntimeException("Function not implemented"); - - } - - @Override - public Map<String, String> getRequestHeaderMap() { - throw new RuntimeException("Function not implemented"); - - } - - @Override - public Map<String, String[]> getRequestHeaderValuesMap() { - throw new RuntimeException("Function not implemented"); - - } - - @Override - public Locale getRequestLocale() { - throw new RuntimeException("Function not implemented"); - - } - - @Override - public Iterator<Locale> getRequestLocales() { - throw new RuntimeException("Function not implemented"); - - } - - Map<String, Object> requestMap = new HashMap<String, Object>(); - - @Override - public Map<String, Object> getRequestMap() { - return requestMap; - } - - public Map<String, String> requestParameterMap = new HashMap<String, String>(); - - @Override - public Map<String, String> getRequestParameterMap() { - return requestParameterMap; - } - - @Override - public Iterator<String> getRequestParameterNames() { - throw new RuntimeException("Function not implemented"); - - } - - @Override - public Map<String, String[]> getRequestParameterValuesMap() { - throw new RuntimeException("Function not implemented"); - - } - - @Override - public String getRequestPathInfo() { - throw new RuntimeException("Function not implemented"); - - } - - @Override - public String getRequestServletPath() { - throw new RuntimeException("Function not implemented"); - - } - - @Override - public URL getResource(String path) throws MalformedURLException { - throw new RuntimeException("Function not implemented"); - - } - - @Override - public InputStream getResourceAsStream(String path) { - throw new RuntimeException("Function not implemented"); - - } - - @Override - public Set<String> getResourcePaths(String path) { - throw new RuntimeException("Function not implemented"); - - } - - @Override - public Object getResponse() { - throw new RuntimeException("Function not implemented"); - - } - - @Override - public Object getSession(boolean create) { - throw new RuntimeException("Function not implemented"); - - } - - @Override - public Map<String, Object> getSessionMap() { - throw new RuntimeException("Function not implemented"); - - } - - @Override - public Principal getUserPrincipal() { - throw new RuntimeException("Function not implemented"); - - } - - @Override - public boolean isUserInRole(String role) { - throw new RuntimeException("Function not implemented"); - - } - - @Override - public void log(String message) { - throw new RuntimeException("Function not implemented"); - - } - - @Override - public void log(String message, Throwable exception) { - throw new RuntimeException("Function not implemented"); - - } - - @Override - public void redirect(String url) throws IOException { - throw new RuntimeException("Function not implemented"); - - } - -} diff --git a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockFacesContext.java b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockFacesContext.java deleted file mode 100644 index c61465d..0000000 --- a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockFacesContext.java +++ /dev/null @@ -1,150 +0,0 @@ -package org.rhq.core.gui.configuration; - -import java.util.Iterator; - -import javax.faces.application.Application; -import javax.faces.application.FacesMessage; -import javax.faces.application.FacesMessage.Severity; -import javax.faces.component.UIViewRoot; -import javax.faces.context.ExternalContext; -import javax.faces.context.FacesContext; -import javax.faces.context.ResponseStream; -import javax.faces.context.ResponseWriter; -import javax.faces.render.RenderKit; - -import com.sun.faces.renderkit.RenderKitImpl; - -public class MockFacesContext extends FacesContext { - - private ExternalContext externalContext; - private MockResponseWriter responseWriter; - - public MockFacesContext(ExternalContext externalContext, MockResponseWriter responseWriter) { - this.externalContext = externalContext; - this.responseWriter = responseWriter; - FacesContext.setCurrentInstance(this); - } - - @Override - public void addMessage(String clientId, FacesMessage message) { - throw new RuntimeException("Function not implemented"); - } - - MockApplication mockApp; - - @Override - public Application getApplication() { - if (null == mockApp) { - mockApp = new MockApplication(); - } - return mockApp; - } - - @Override - public Iterator<String> getClientIdsWithMessages() { - throw new RuntimeException("Function not implemented"); - - } - - @Override - public ExternalContext getExternalContext() { - return externalContext; - - } - - @Override - public Severity getMaximumSeverity() { - throw new RuntimeException("Function not implemented"); - - } - - @Override - public Iterator<FacesMessage> getMessages() { - throw new RuntimeException("Function not implemented"); - - } - - @Override - public Iterator<FacesMessage> getMessages(String clientId) { - throw new RuntimeException("Function not implemented"); - - } - - RenderKit renderKit = new MockRenderKit(); - - @Override - public RenderKit getRenderKit() { - if (null == renderKit) { - renderKit = new RenderKitImpl(); - renderKit.addRenderer("rhq", ConfigRenderer.class.getName(), new ConfigRenderer()); - } - return renderKit; - } - - @Override - public boolean getRenderResponse() { - throw new RuntimeException("Function not implemented"); - - } - - @Override - public boolean getResponseComplete() { - throw new RuntimeException("Function not implemented"); - - } - - @Override - public ResponseStream getResponseStream() { - throw new RuntimeException("Function not implemented"); - - } - - @Override - public ResponseWriter getResponseWriter() { - return responseWriter; - } - - @Override - public UIViewRoot getViewRoot() { - return null; - //throw new RuntimeException("Function not implemented"); - - } - - @Override - public void release() { - throw new RuntimeException("Function not implemented"); - - } - - @Override - public void renderResponse() { - throw new RuntimeException("Function not implemented"); - - } - - @Override - public void responseComplete() { - throw new RuntimeException("Function not implemented"); - - } - - @Override - public void setResponseStream(ResponseStream responseStream) { - throw new RuntimeException("Function not implemented"); - - } - - @Override - public void setResponseWriter(ResponseWriter responseWriter) { - throw new RuntimeException("Function not implemented"); - - } - - @Override - public void setViewRoot(UIViewRoot root) { - throw new RuntimeException("Function not implemented"); - - } - -} diff --git a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockLifecycle.java b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockLifecycle.java deleted file mode 100644 index c48708d..0000000 --- a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockLifecycle.java +++ /dev/null @@ -1,40 +0,0 @@ -package org.rhq.core.gui.configuration; - -import javax.faces.FacesException; -import javax.faces.context.FacesContext; -import javax.faces.event.PhaseListener; -import javax.faces.lifecycle.Lifecycle; - -public class MockLifecycle extends Lifecycle { - - @Override - public void addPhaseListener(PhaseListener listener) { - throw new RuntimeException("Function not implemented"); - - } - - @Override - public void execute(FacesContext context) throws FacesException { - throw new RuntimeException("Function not implemented"); - - } - - @Override - public PhaseListener[] getPhaseListeners() { - throw new RuntimeException("Function not implemented"); - - } - - @Override - public void removePhaseListener(PhaseListener listener) { - throw new RuntimeException("Function not implemented"); - - } - - @Override - public void render(FacesContext context) throws FacesException { - throw new RuntimeException("Function not implemented"); - - } - -} diff --git a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockRenderKit.java b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockRenderKit.java deleted file mode 100644 index 2d1981f..0000000 --- a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockRenderKit.java +++ /dev/null @@ -1,88 +0,0 @@ -package org.rhq.core.gui.configuration; - -import java.io.OutputStream; -import java.io.Writer; -import java.util.HashMap; -import java.util.HashSet; - -import javax.faces.context.ResponseStream; -import javax.faces.context.ResponseWriter; -import javax.faces.render.RenderKit; -import javax.faces.render.Renderer; -import javax.faces.render.ResponseStateManager; - -import com.sun.faces.renderkit.html_basic.GroupRenderer; -import com.sun.faces.renderkit.html_basic.OutputMessageRenderer; -import com.sun.faces.renderkit.html_basic.TextRenderer; - -public class MockRenderKit extends RenderKit { - - @Override - public void addRenderer(String family, String rendererType, Renderer renderer) { - throw new RuntimeException("Function not implemented"); - - } - - @Override - public ResponseStream createResponseStream(OutputStream out) { - throw new RuntimeException("Function not implemented"); - - } - - @Override - public ResponseWriter createResponseWriter(Writer writer, String contentTypeList, String characterEncoding) { - throw new RuntimeException("Function not implemented"); - - } - - HashSet<String> noRendererSet; - - public HashSet<String> getNoRendererSet() { - if (null == noRendererSet) { - noRendererSet = new HashSet<String>(); - noRendererSet.add("javax.faces.HtmlCommandLink"); - noRendererSet.add("javax.faces.Form"); - noRendererSet.add("javax.faces.Textarea"); - } - return noRendererSet; - } - - HashMap<String, Class> rendererMap; - - @Override - public Renderer getRenderer(String family, String rendererType) { - - if (getNoRendererSet().contains(rendererType)) - return null; - - try { - if (null == rendererMap) { - rendererMap = new HashMap<String, Class>(); - rendererMap.put("javax.faces.Text", TextRenderer.class); - rendererMap.put("javax.faces.Format", OutputMessageRenderer.class); - rendererMap.put("javax.faces.Group", GroupRenderer.class); - rendererMap.put(ConfigRenderer.class.getName(), ConfigRenderer.class); - rendererMap.put("javax.faces.Link", com.sun.faces.renderkit.html_basic.CommandLinkRenderer.class); - rendererMap.put("javax.faces.Image", com.sun.faces.renderkit.html_basic.ImageRenderer.class); - rendererMap.put("javax.faces.Grid", com.sun.faces.renderkit.html_basic.GridRenderer.class); - - } - Class c = rendererMap.get(rendererType); - if (c == null) { - System.out.println("MockRenderKit request for unsupported type " + rendererType); - } - return (Renderer) c.newInstance(); - - } catch (Exception e) { - throw new RuntimeException(e); - } - - } - - @Override - public ResponseStateManager getResponseStateManager() { - throw new RuntimeException("Function not implemented"); - - } - -} diff --git a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockRenderKitFactory.java b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockRenderKitFactory.java deleted file mode 100644 index 760e703..0000000 --- a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockRenderKitFactory.java +++ /dev/null @@ -1,31 +0,0 @@ -package org.rhq.core.gui.configuration; - -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; - -import javax.faces.context.FacesContext; -import javax.faces.render.RenderKit; -import javax.faces.render.RenderKitFactory; - -public class MockRenderKitFactory extends RenderKitFactory { - - Map<String, RenderKit> kits = new HashMap<String, RenderKit>(); - - @Override - public void addRenderKit(String renderKitId, RenderKit renderKit) { - kits.put(renderKitId, renderKit); - } - - @Override - public RenderKit getRenderKit(FacesContext context, String renderKitId) { - return kits.get(renderKitId); - - } - - @Override - public Iterator<String> getRenderKitIds() { - return kits.keySet().iterator(); - } - -} diff --git a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockResponseWriter.java b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockResponseWriter.java deleted file mode 100644 index 85247fb..0000000 --- a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockResponseWriter.java +++ /dev/null @@ -1,99 +0,0 @@ -package org.rhq.core.gui.configuration; - -import java.io.IOException; -import java.io.StringWriter; -import java.io.Writer; - -import javax.faces.component.UIComponent; -import javax.faces.context.ResponseWriter; - -public class MockResponseWriter extends ResponseWriter { - - public StringWriter stringWriter = new StringWriter(); - - @Override - public ResponseWriter cloneWithWriter(Writer writer) { - throw new RuntimeException("Function not implemented"); - - } - - @Override - public void endDocument() throws IOException { - throw new RuntimeException("Function not implemented"); - - } - - @Override - public void endElement(String name) throws IOException { - stringWriter.write("end element:" + name + "\n"); - - } - - @Override - public void flush() throws IOException { - - stringWriter.flush(); - - } - - @Override - public String getCharacterEncoding() { - throw new RuntimeException("Function not implemented"); - - } - - @Override - public String getContentType() { - return "contenttype:"; - } - - @Override - public void startDocument() throws IOException { - throw new RuntimeException("Function not implemented"); - - } - - @Override - public void startElement(String name, UIComponent component) throws IOException { - stringWriter.write("startElement: " + name + ": component:" - + (component != null ? component.getId() : "componenet is null") + "\n"); - } - - @Override - public void writeAttribute(String name, Object value, String property) throws IOException { - stringWriter.write("attribute:" + name + " value = " + value.toString() + " property = " + property + "\n"); - - } - - @Override - public void writeComment(Object comment) throws IOException { - stringWriter.write("comment:" + comment + "\n"); - - } - - @Override - public void writeText(Object text, String property) throws IOException { - stringWriter.write("text:" + text + ":" + property + "\n"); - } - - @Override - public void writeText(char[] text, int off, int len) throws IOException { - write(text, off, len); - } - - @Override - public void writeURIAttribute(String name, Object value, String property) throws IOException { - stringWriter.write("attributename:" + name + ", value:" + value.toString() + ", property:" + property); - } - - @Override - public void close() throws IOException { - //stringWriter.close(); - } - - @Override - public void write(char[] cbuf, int off, int len) throws IOException { - stringWriter.write(cbuf, off, len); - } - -} diff --git a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockServletContext.java b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockServletContext.java deleted file mode 100644 index f604d00..0000000 --- a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockServletContext.java +++ /dev/null @@ -1,166 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2009 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.core.gui.configuration; - -import java.io.InputStream; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.Map; -import java.util.Properties; -import java.util.Set; - -import javax.servlet.RequestDispatcher; -import javax.servlet.Servlet; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; - -import com.sun.faces.config.WebConfiguration; -final class MockServletContext implements ServletContext { - public void setAttribute(String arg0, Object arg1) { - this.attributeMap.put(arg0, arg1); - - } - - public void removeAttribute(String arg0) { - attributeMap.remove(arg0); - - } - - public void log(String arg0, Throwable arg1) { - throw new RuntimeException("Function not implemented"); - - } - - public void log(Exception arg0, String arg1) { - throw new RuntimeException("Function not implemented"); - - } - - public void log(String arg0) { - throw new RuntimeException("Function not implemented"); - - } - - public Enumeration getServlets() { - throw new RuntimeException("Function not implemented"); - - } - - public Enumeration getServletNames() { - throw new RuntimeException("Function not implemented"); - - } - - public String getServletContextName() { - return MockServletContext.class.getSimpleName(); - - } - - public Servlet getServlet(String arg0) throws ServletException { - throw new RuntimeException("Function not implemented"); - - } - - public String getServerInfo() { - throw new RuntimeException("Function not implemented"); - - } - - public Set getResourcePaths(String arg0) { - throw new RuntimeException("Function not implemented"); - - } - - public InputStream getResourceAsStream(String arg0) { - throw new RuntimeException("Function not implemented"); - - } - - public URL getResource(String arg0) throws MalformedURLException { - throw new RuntimeException("Function not implemented"); - - } - - public RequestDispatcher getRequestDispatcher(String arg0) { - throw new RuntimeException("Function not implemented"); - - } - - public String getRealPath(String arg0) { - throw new RuntimeException("Function not implemented"); - - } - - public RequestDispatcher getNamedDispatcher(String arg0) { - throw new RuntimeException("Function not implemented"); - - } - - public int getMinorVersion() { - return 4; - } - - public String getMimeType(String arg0) { - throw new RuntimeException("Function not implemented"); - - } - - public int getMajorVersion() { - return 2; - - } - - Properties initParams = new Properties(); - - public Enumeration getInitParameterNames() { - return initParams.elements(); - - } - - public String getInitParameter(String key) { - return initParams.getProperty(key); - - } - - public ServletContext getContext(String arg0) { - throw new RuntimeException("Function not implemented"); - - } - - public Enumeration getAttributeNames() { - throw new RuntimeException("Function not implemented"); - - } - - Map<String, Object> attributeMap; - - public Object getAttribute(String key) { - if (null == attributeMap) { - attributeMap = new HashMap<String, Object>(); - WebConfiguration wc = WebConfiguration.getInstance(this); - - attributeMap.put("com.sun.faces.config.WebConfiguration", wc); - } - - return attributeMap.get(key); - } -} \ No newline at end of file diff --git a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockValueExpression.java b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockValueExpression.java deleted file mode 100644 index cb3dc63..0000000 --- a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockValueExpression.java +++ /dev/null @@ -1,71 +0,0 @@ -package org.rhq.core.gui.configuration; - -import javax.el.ELContext; -import javax.el.ValueExpression; - -public class MockValueExpression extends ValueExpression { - - /** - * - */ - private static final long serialVersionUID = 1L; - - public MockValueExpression(Object value) { - this.value = value; - } - - public Object value; - - public boolean literalText = false; - - @Override - public boolean equals(Object arg0) { - throw new RuntimeException("Function not implemented"); - - } - - @Override - public Class<?> getExpectedType() { - throw new RuntimeException("Function not implemented"); - - } - - @Override - public String getExpressionString() { - return "#{" + value.getClass().getSimpleName() + "}"; - } - - @Override - public Class<?> getType(ELContext arg0) { - throw new RuntimeException("Function not implemented"); - - } - - @Override - public Object getValue(ELContext arg0) { - return value; - } - - @Override - public int hashCode() { - throw new RuntimeException("Function not implemented"); - - } - - @Override - public boolean isLiteralText() { - return literalText; - } - - @Override - public boolean isReadOnly(ELContext arg0) { - throw new RuntimeException("Function not implemented"); - - } - - @Override - public void setValue(ELContext arg0, Object arg1) { - this.value = arg1; - } - -} diff --git a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockViewHandler.java b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockViewHandler.java deleted file mode 100644 index 0074169..0000000 --- a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockViewHandler.java +++ /dev/null @@ -1,53 +0,0 @@ -package org.rhq.core.gui.configuration; - -import java.io.IOException; -import java.util.Locale; - -import javax.faces.FacesException; -import javax.faces.application.ViewHandler; -import javax.faces.component.UIViewRoot; -import javax.faces.context.FacesContext; - -public class MockViewHandler extends ViewHandler { - - @Override - public Locale calculateLocale(FacesContext context) { - throw new RuntimeException("Function not implemented"); - } - - @Override - public String calculateRenderKitId(FacesContext context) { - throw new RuntimeException("Function not implemented"); - } - - @Override - public UIViewRoot createView(FacesContext context, String viewId) { - throw new RuntimeException("Function not implemented"); - } - - @Override - public String getActionURL(FacesContext context, String viewId) { - throw new RuntimeException("Function not implemented"); - } - - @Override - public String getResourceURL(FacesContext context, String path) { - return "uri://" + path; - } - - @Override - public void renderView(FacesContext context, UIViewRoot viewToRender) throws IOException, FacesException { - throw new RuntimeException("Function not implemented"); - } - - @Override - public UIViewRoot restoreView(FacesContext context, String viewId) { - throw new RuntimeException("Function not implemented"); - } - - @Override - public void writeState(FacesContext context) throws IOException { - throw new RuntimeException("Function not implemented"); - } - -} diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ExistingResourceConfigurationUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ExistingResourceConfigurationUIBean.java index 2f11e11..3189d79 100644 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ExistingResourceConfigurationUIBean.java +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ExistingResourceConfigurationUIBean.java @@ -51,20 +51,16 @@ import org.rhq.enterprise.server.util.LookupUtil; /** * @author Ian Springer */ +//@ Name(value = "ExistingResourceConfigurationUIBean") +//@ Scope(ScopeType.PAGE) public class ExistingResourceConfigurationUIBean extends AbstractConfigurationUIBean { public static final String MANAGED_BEAN_NAME = "ExistingResourceConfigurationUIBean";
- private String selectedPath; - private TreeMap<String, RawConfiguration> raws; - private TreeMap<String, RawConfiguration> modified = new TreeMap<String, RawConfiguration>(); - private RawConfiguration current = null; - // =========== actions ===========
public ExistingResourceConfigurationUIBean() { removeSessionScopedBeanIfInView("/rhq/resource/configuration/view.xhtml", ExistingResourceConfigurationUIBean.class); - }
public String editConfiguration() { @@ -85,9 +81,6 @@ public class ExistingResourceConfigurationUIBean extends AbstractConfigurationUI }
public String updateConfiguration() { - - modified = null; - return updateConfiguration(true);
} @@ -101,9 +94,9 @@ public class ExistingResourceConfigurationUIBean extends AbstractConfigurationUI ConfigurationMaskingUtility.unmaskConfiguration(getConfiguration(), getConfigurationDefinition()); int resourceId = EnterpriseFacesContextUtility.getResource().getId();
- AbstractResourceConfigurationUpdate updateRequest = this.configurationManager - .updateStructuredOrRawConfiguration(EnterpriseFacesContextUtility.getSubject(), resourceId, - getMergedConfiguration(), fromStructured); + AbstractResourceConfigurationUpdate updateRequest = + this.configurationManager.updateStructuredOrRawConfiguration(EnterpriseFacesContextUtility.getSubject(), + resourceId, getMergedConfiguration(), fromStructured); if (updateRequest != null) { switch (updateRequest.getStatus()) { case SUCCESS: @@ -190,6 +183,9 @@ public class ExistingResourceConfigurationUIBean extends AbstractConfigurationUI private Configuration getMergedConfiguration() { for (RawConfiguration raw : getModified().values()) { getRaws().put(raw.getPath(), raw); + log.error("Just merged in raw path =[" + raw.getPath() + "]"); + log.error(" file =[" + new String(raw.getContents()) + "]"); + } getConfiguration().getRawConfigurations().clear(); getConfiguration().getRawConfigurations().addAll(getRaws().values()); @@ -203,6 +199,7 @@ public class ExistingResourceConfigurationUIBean extends AbstractConfigurationUI
public void fileUploadListener(UploadEvent event) throws Exception { File uploadFile; + log.error("fileUploadListener called"); uploadFile = event.getUploadItem().getFile(); if (uploadFile != null) { log.debug("fileUploadListener got file named " + event.getUploadItem().getFileName()); @@ -227,6 +224,27 @@ public class ExistingResourceConfigurationUIBean extends AbstractConfigurationUI return getConfiguration().getId(); }
+ /* + public Configuration getConfiguration() { + if (null == configuration) { + + Subject subject = EnterpriseFacesContextUtility.getSubject(); + int resourceId = EnterpriseFacesContextUtility.getResource().getId(); + AbstractResourceConfigurationUpdate configurationUpdate = LookupUtil.getConfigurationManager() + .getLatestResourceConfigurationUpdate(subject, resourceId); + Configuration configuration = (configurationUpdate != null) ? configurationUpdate.getConfiguration() : null; + if (configuration != null) { + //ConfigurationMaskingUtility.maskConfiguration(configuration, getConfigurationDefinition()); + } + + return configuration; + + } + return configuration; + + } + */ + private ConfigurationFormat getConfigurationFormat() { return getConfigurationDefinition().getConfigurationFormat(); } @@ -315,10 +333,10 @@ public class ExistingResourceConfigurationUIBean extends AbstractConfigurationUI
public void setCurrentContents(String updated) {
- String original = getCurrent().getContentString(); + String original = new String(getCurrent().getContents()); if (!updated.equals(original)) { current = current.deepCopy(false); - current.setContentString(updated); + current.setContents(updated.getBytes()); //TODO update other values like MD5 getModified().put(current.getPath(), current); } @@ -340,6 +358,14 @@ public class ExistingResourceConfigurationUIBean extends AbstractConfigurationUI
/** * This is a no-op, since the upload work was done by upload file + * But is kept as a target for the "save" icon from the full screen page + */ + public String update() { + return "/rhq/resource/configuration/edit-raw.xhtml?currentResourceId=" + getResourceId(); + } + + /** + * This is a no-op, since the upload work was done by upload file * But is kept as a target for the "action" value */ public String upload() { @@ -347,8 +373,12 @@ public class ExistingResourceConfigurationUIBean extends AbstractConfigurationUI }
public String switchToraw() { + log.error("switch2raw called"); + dumpProperties(getConfiguration(), log); Configuration configuration = LookupUtil.getConfigurationManager().translateResourceConfiguration( EnterpriseFacesContextUtility.getSubject(), getResourceId(), getMergedConfiguration(), true); + log.error("switch2raw post merge"); + dumpProperties(getConfiguration(), log);
setConfiguration(configuration); for (RawConfiguration raw : configuration.getRawConfigurations()) { @@ -360,10 +390,21 @@ public class ExistingResourceConfigurationUIBean extends AbstractConfigurationUI return "/rhq/resource/configuration/edit-raw.xhtml?currentResourceId=" + getResourceId(); }
+ void dumpProperties(Configuration conf, Log log) { + for (String key : conf.getAllProperties().keySet()) { + log.error("property=" + conf.getAllProperties().get(key)); + } + } + public String switchTostructured() { + log.error("switch2structured called");
+ dumpProperties(getConfiguration(), log); Configuration configuration = LookupUtil.getConfigurationManager().translateResourceConfiguration( EnterpriseFacesContextUtility.getSubject(), getResourceId(), getMergedConfiguration(), false); + log.error("switch2structured post merge"); + + dumpProperties(configuration, log);
for (Property property : configuration.getAllProperties().values()) { property.setConfiguration(configuration); @@ -402,4 +443,12 @@ public class ExistingResourceConfigurationUIBean extends AbstractConfigurationUI return raws; }
+ /** + * + */ + String selectedPath; + private TreeMap<String, RawConfiguration> raws; + TreeMap<String, RawConfiguration> modified = new TreeMap<String, RawConfiguration>(); + RawConfiguration current = null; + } diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-navigation/configuration-navigation.xml b/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-navigation/configuration-navigation.xml index b6767e4..bd0f1bf 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-navigation/configuration-navigation.xml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-navigation/configuration-navigation.xml @@ -6,6 +6,7 @@
<navigation-rule>
+ <navigation-case> <from-action>#{ExistingResourceConfigurationUIBean.editConfiguration}</from-action> <to-view-id>/rhq/resource/configuration/edit.xhtml?id=#{param.id}</to-view-id> @@ -31,6 +32,13 @@
</navigation-rule>
+ <navigation-rule> + <from-view-id>/rhq/resource/configuration/edit-raw-full.xhtml</from-view-id> + <navigation-case> + <from-action> #{RawConfigCollection.update}</from-action> + <to-view-id>/rhq/resource/configuration/edit-raw.xhtml?id=#{param.id}</to-view-id> + </navigation-case> + </navigation-rule>
<navigation-rule>
@@ -42,7 +50,8 @@ <to-view-id>/rhq/resource/configuration/history.xhtml?id=#{param.id}</to-view-id> <redirect/> </navigation-case> - + + </navigation-rule>
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/images/edit.png b/modules/enterprise/gui/portal-war/src/main/webapp/images/edit.png deleted file mode 100644 index b1c3c61..0000000 Binary files a/modules/enterprise/gui/portal-war/src/main/webapp/images/edit.png and /dev/null differ diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/images/raw.png b/modules/enterprise/gui/portal-war/src/main/webapp/images/raw.png deleted file mode 100644 index 9ccae0e..0000000 Binary files a/modules/enterprise/gui/portal-war/src/main/webapp/images/raw.png and /dev/null differ diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/images/structured.png b/modules/enterprise/gui/portal-war/src/main/webapp/images/structured.png deleted file mode 100644 index 94fcf83..0000000 Binary files a/modules/enterprise/gui/portal-war/src/main/webapp/images/structured.png and /dev/null differ diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit.xhtml index a85f409..d067d8a 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit.xhtml @@ -22,12 +22,6 @@ THIS TEXT WILL BE REMOVED. <ui:param name="selectedTabName" value="Configuration.Current"/>
<ui:define name="content"> - <style type="text/css"> - td.raw-config-table { - vertical-align: top; - valign: top; - } - </style>
<h:form id="editResourceConfigurationForm" onsubmit="prepareInputsForSubmission(this)" rendered="#{!ViewResourceConfigurationUIBean.updateInProgress}">
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml index d0cfa5c..72da244 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml @@ -24,40 +24,47 @@ THIS TEXT WILL BE REMOVED.
<ui:define name="content">
- -<style type="text/css"> - td.raw-config-table { - vertical-align: top; - valign: top; - } - config-toolbar{ - float: right; - } -</style> - - <h:panelGroup layout="block" styleClass="InfoBlock" rendered="#{ExistingResourceConfigurationUIBean.updateInProgress}"> <b>${msg['note']}</b> ${msg['resource.config.Current.updateInProgress']} </h:panelGroup>
+ <h:outputText value="#{messages.youareviewingstructured}" /> + <h:panelGroup rendered="#{ExistingResourceConfigurationUIBean.rawSupported}" > + <h:outputText value=" #{messages.switch2}" /> + <h:outputLink value="view-raw.xhtml"> + <f:param name="id" value="#{ResourceUIBean.id}" /> + <h:outputText value=" #{messages.raw}" /> + </h:outputLink> + </h:panelGroup>
<h:outputText value=" #{messages.nopermissionedit}" rendered="#{!ResourceUIBean.permissions.configure}"/>
<h:form id="viewResourceConfigurationForm"> <!-- TODO remove the id version --> <input type="hidden" name="id" value="#{ResourceUIBean.id}"/> + + <h:panelGrid columns="2" styleClass="buttons-table" columnClasses="button-cell" + rendered="#{ExistingResourceConfigurationViewUIBean.configuration != null and !ExistingResourceConfigurationViewUIBean.updateInProgress}"> + + <h:commandButton value="#{messages.editstructured}" action="#{ExistingResourceConfigurationViewUIBean.editConfiguration}" + title="Edit this Configuration" styleClass="buttonmed" + rendered="${ResourceUIBean.permissions.configure and ExistingResourceConfigurationViewUIBean.structuredSupported and !ExistingResourceConfigurationViewUIBean.updateInProgress}" /> + <h:commandButton value="#{messages.editraw}" action="#{ExistingResourceConfigurationUIBean.editRawConfiguration}" + title="Advanced Mode Edit of Raw Configuration Files" styleClass="buttonmed" + rendered="${ResourceUIBean.permissions.configure and ExistingResourceConfigurationViewUIBean.rawSupported and !ExistingResourceConfigurationViewUIBean.updateInProgress}" /> + </h:panelGrid>
- <onc:config configurationDefinition="#{ExistingResourceConfigurationUIBean.configurationDefinition}" - configuration="#{ExistingResourceConfigurationUIBean.configuration}" - accessMapActionExpression="#{ExistingResourceConfigurationUIBean.accessMap}" - nullConfigurationDefinitionMessage="#{ExistingResourceConfigurationUIBean.nullConfigurationDefinitionMessage}" - nullConfigurationMessage="#{ExistingResourceConfigurationUIBean.nullConfigurationMessage}" + <onc:config configurationDefinition="#{ExistingResourceConfigurationViewUIBean.configurationDefinition}" + configuration="#{ExistingResourceConfigurationViewUIBean.configuration}" + accessMapActionExpression="#{ExistingResourceConfigurationViewUIBean.accessMap}" + readOnly="true" + nullConfigurationDefinitionMessage="#{ExistingResourceConfigurationViewUIBean.nullConfigurationDefinitionMessage}" + nullConfigurationMessage="#{ExistingResourceConfigurationViewUIBean.nullConfigurationMessage}" prevalidate="true"/> - <input type="hidden" name="id" value="#{ResourceUIBean.id}"/>
</h:form>
- <h:panelGroup layout="block" styleClass="InfoBlock" rendered="#{ExistingResourceConfigurationUIBean.updateInProgress}"> + <h:panelGroup layout="block" styleClass="InfoBlock" rendered="#{ExistingResourceConfigurationViewUIBean.updateInProgress}"> <b>${msg['note']}</b> ${msg['resource.config.Current.updateInProgress']} </h:panelGroup>
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/webservices/WebservicesManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/webservices/WebservicesManagerBean.java index 8703ae0..88858cf 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/webservices/WebservicesManagerBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/webservices/WebservicesManagerBean.java @@ -287,7 +287,7 @@ public class WebservicesManagerBean implements WebservicesRemote { return repoManager.findPackageVersionsInRepoByCriteria(subject, criteria); }
- //@Override + @Override public int synchronizeRepos(Subject subject, Integer[] repoIds) { return repoManager.synchronizeRepos(subject, repoIds); } @@ -372,8 +372,8 @@ public class WebservicesManagerBean implements WebservicesRemote { }
public ResourceConfigurationUpdate updateStructuredOrRawConfiguration(Subject subject, int resourceId, - Configuration newConfiguration, boolean fromStructured) throws ResourceNotFoundException, - ConfigurationUpdateStillInProgressException { + Configuration newConfiguration, boolean fromStructured) + throws ResourceNotFoundException, ConfigurationUpdateStillInProgressException { return configurationManager.updateStructuredOrRawConfiguration(subject, resourceId, newConfiguration, fromStructured); } diff --git a/modules/enterprise/server/plugins/rhnhosted/src/main/java/org/rhq/enterprise/server/plugins/rhnhosted/xmlrpc/ApacheXmlRpcExecutor.java b/modules/enterprise/server/plugins/rhnhosted/src/main/java/org/rhq/enterprise/server/plugins/rhnhosted/xmlrpc/ApacheXmlRpcExecutor.java index 004608a..f3c75e2 100644 --- a/modules/enterprise/server/plugins/rhnhosted/src/main/java/org/rhq/enterprise/server/plugins/rhnhosted/xmlrpc/ApacheXmlRpcExecutor.java +++ b/modules/enterprise/server/plugins/rhnhosted/src/main/java/org/rhq/enterprise/server/plugins/rhnhosted/xmlrpc/ApacheXmlRpcExecutor.java @@ -32,10 +32,12 @@ public class ApacheXmlRpcExecutor implements XmlRpcExecutor { this.client = clientIn; }
+ @Override public Object execute(String methodName, Object[] params) throws XmlRpcException { return client.execute(methodName, params); }
+ @Override public Object execute(String pMethodName, List pParams) throws XmlRpcException { return client.execute(pMethodName, pParams); } diff --git a/modules/enterprise/server/plugins/rhnhosted/src/test/java/org/rhq/enterprise/server/plugins/rhnhosted/xmlrpc/MockRhnXmlRpcExecutor.java b/modules/enterprise/server/plugins/rhnhosted/src/test/java/org/rhq/enterprise/server/plugins/rhnhosted/xmlrpc/MockRhnXmlRpcExecutor.java index 9a033d5..bcdfe41 100644 --- a/modules/enterprise/server/plugins/rhnhosted/src/test/java/org/rhq/enterprise/server/plugins/rhnhosted/xmlrpc/MockRhnXmlRpcExecutor.java +++ b/modules/enterprise/server/plugins/rhnhosted/src/test/java/org/rhq/enterprise/server/plugins/rhnhosted/xmlrpc/MockRhnXmlRpcExecutor.java @@ -70,7 +70,7 @@ public class MockRhnXmlRpcExecutor implements XmlRpcExecutor { /* (non-Javadoc) * @see org.rhq.enterprise.server.plugins.rhnhosted.xmlrpc.XmlRpcExecutor#execute(java.lang.String, java.lang.Object[]) */ - //@Override + @Override public Object execute(String methodName, Object[] params) throws XmlRpcException { //for (Object object : params) { // System.out.println("parm: " + object); @@ -242,7 +242,7 @@ public class MockRhnXmlRpcExecutor implements XmlRpcExecutor {
}
- //@Override + @Override public Object execute(String pMethodName, List pParams) throws XmlRpcException { return execute(pMethodName, pParams.toArray()); } diff --git a/modules/plugins/augeas/src/test/java/README b/modules/plugins/augeas/src/test/java/README deleted file mode 100644 index db73645..0000000 --- a/modules/plugins/augeas/src/test/java/README +++ /dev/null @@ -1 +0,0 @@ -Delete this file once there is source in this tree
commit e7727d0343e19d467e4e591cfa0205f9b8e8c2b3 Author: John Sanda john@localhost.localdomain Date: Fri Dec 18 14:24:54 2009 -0500
Revert " ability to turn off toolbar. Read only is set from render. replaced some String literals with symbolic constants."
This reverts commit 5d7c13ae3bbbdce1ebd05796fc7c6528537efe29.
diff --git a/.classpath b/.classpath index a3aef1e..27f5303 100644 --- a/.classpath +++ b/.classpath @@ -92,8 +92,8 @@ <classpathentry kind="src" path="modules/plugins/samba/src/test/java"/> <classpathentry kind="src" path="modules/plugins/sudoers/src/main/java"/> <classpathentry kind="src" path="modules/plugins/sudoers/src/test/java"/> - <classpathentry kind="src" path="modules/plugins/postfix/src/main/java"/> - <classpathentry kind="src" path="modules/plugins/postfix/src/test/java"/> + <classpathentry kind="src" path="modules/plugins/postfix/src/main/java"/> + <classpathentry kind="src" path="modules/plugins/postfix/src/test/java"/> <classpathentry kind="src" path="modules/plugins/cron/src/main/java"/> <classpathentry kind="src" path="modules/plugins/hudson/src/main/java"/> <classpathentry kind="src" path="modules/plugins/platform/src/test/java"/> @@ -165,8 +165,8 @@ <classpathentry exported="true" kind="var" path="M2_REPO/commons-lang/commons-lang/2.4/commons-lang-2.4.jar"/> <classpathentry exported="true" kind="var" path="M2_REPO/javax/faces/jsf-api/1.2_12/jsf-api-1.2_12.jar" sourcepath="/M2_REPO/javax/faces/jsf-api/1.2_12/jsf-api-1.2_12-sources.jar"/> <classpathentry exported="true" kind="var" path="M2_REPO/javax/faces/jsf-impl/1.2_12/jsf-impl-1.2_12.jar" sourcepath="/M2_REPO/javax/faces/jsf-impl/1.2_12/jsf-impl-1.2_12-sources.jar"/> - <classpathentry exported="true" kind="var" path="M2_REPO/javax/el/el-api/1.0/el-api-1.0.jar" sourcepath="/M2_REPO/javax/el/el-api/1.0/el-api-1.0-sources.jar"/> - <classpathentry exported="true" kind="var" path="M2_REPO/com/sun/facelets/jsf-facelets/1.1.14/jsf-facelets-1.1.14.jar" sourcepath="/M2_REPO/com/sun/facelets/jsf-facelets/1.1.14/jsf-facelets-1.1.14-sources.jar"/> + <classpathentry exported="true" kind="var" path="M2_REPO/javax/el/el-api/1.0/el-api-1.0.jar"/> + <classpathentry exported="true" kind="var" path="M2_REPO/com/sun/facelets/jsf-facelets/1.1.14/jsf-facelets-1.1.14.jar" sourcepath="/M2_REPO/com/sun/facelets/jsf-facelets/1.1.13/jsf-facelets-1.1.13-sources.jar"/> <classpathentry exported="true" kind="var" path="M2_REPO/mc4j/org-mc4j-ems/1.2.11/org-mc4j-ems-1.2.11.jar" sourcepath="/M2_REPO/mc4j/org-mc4j-ems/1.2.11/org-mc4j-ems-1.2.11-sources.jar"/> <classpathentry exported="true" kind="var" path="M2_REPO/org/opensymphony/quartz/quartz/1.6.5/quartz-1.6.5.jar" sourcepath="/M2_REPO/org/opensymphony/quartz/quartz/1.6.5/quartz-1.6.5-sources.jar"/> <classpathentry exported="true" kind="var" path="M2_REPO/javax/mail/mail/1.3.1/mail-1.3.1.jar"/> diff --git a/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/AbstractConfigurationComponent.java b/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/AbstractConfigurationComponent.java index e49ead1..2fe72ee 100644 --- a/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/AbstractConfigurationComponent.java +++ b/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/AbstractConfigurationComponent.java @@ -24,7 +24,6 @@ package org.rhq.core.gui.configuration;
import java.util.UUID;
-import javax.faces.component.UIComponent; import javax.faces.component.UIComponentBase; import javax.faces.context.FacesContext;
@@ -50,30 +49,18 @@ public abstract class AbstractConfigurationComponent extends UIComponentBase imp private static final String NULL_CONFIGURATION_STYLE_ATTRIBUTE = "nullConfigurationStyle"; private static final String LIST_NAME_ATTRIBUTE = "listName"; private static final String LIST_INDEX_ATTRIBUTE = "listIndex"; - public static final String READ_ONLY_ATTRIBUTE = "readOnly"; - public static final String SHOW_TOOLBAR_ATTRIBUTE = "readOnly"; + private static final String READ_ONLY_ATTRIBUTE = "readOnly"; private static final String FULLY_EDITABLE_ATTRIBUTE = "fullyEditable";
- private Boolean showToolbar; - private Boolean readOnly; + private Boolean readOnly = true; private Boolean fullyEditable; private String listName; private Integer listIndex; - - public UIComponent getToolbar() { - return toolbar; - } - - public void setToolbar(UIComponent toolbar) { - this.toolbar = toolbar; - } - private String nullConfigurationDefinitionMessage; private String nullConfigurationMessage; private String nullConfigurationStyle; private boolean prevalidate; private boolean isGroup; - private UIComponent toolbar;
public String getFamily() { return COMPONENT_FAMILY; @@ -106,21 +93,6 @@ public abstract class AbstractConfigurationComponent extends UIComponentBase imp this.readOnly = readOnly; }
- public Boolean getShowToolbar() { - if (this.showToolbar == null) { - this.showToolbar = FacesComponentUtility - .getExpressionAttribute(this, SHOW_TOOLBAR_ATTRIBUTE, Boolean.class); - } - if (this.showToolbar == null) { - this.showToolbar = false; - } - return showToolbar; - } - - public void setShowToolbar(Boolean showToolbar) { - this.showToolbar = showToolbar; - } - public boolean isFullyEditable() { if (this.fullyEditable == null) { this.fullyEditable = FacesComponentUtility.getExpressionAttribute(this, FULLY_EDITABLE_ATTRIBUTE, @@ -218,7 +190,7 @@ public abstract class AbstractConfigurationComponent extends UIComponentBase imp @Override public Object saveState(FacesContext facesContext) { if (this.stateValues == null) { - this.stateValues = new Object[8]; + this.stateValues = new Object[7]; }
this.stateValues[0] = super.saveState(facesContext); @@ -228,7 +200,6 @@ public abstract class AbstractConfigurationComponent extends UIComponentBase imp this.stateValues[4] = this.listIndex; this.stateValues[5] = this.prevalidate; this.stateValues[6] = this.isGroup; - this.stateValues[7] = this.getShowToolbar(); return this.stateValues; }
@@ -242,7 +213,6 @@ public abstract class AbstractConfigurationComponent extends UIComponentBase imp this.listIndex = (Integer) this.stateValues[4]; this.prevalidate = (Boolean) this.stateValues[5]; this.isGroup = (Boolean) this.stateValues[6]; - this.showToolbar = (Boolean) this.stateValues[7]; }
public boolean getShouldShowRaw() { diff --git a/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/ConfigRenderer.java b/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/ConfigRenderer.java index 278d619..e3f0c16 100644 --- a/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/ConfigRenderer.java +++ b/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/ConfigRenderer.java @@ -26,7 +26,6 @@ import java.io.IOException; import java.util.List; import java.util.Map;
-import javax.el.MethodExpression; import javax.el.ValueExpression; import javax.faces.application.FacesMessage; import javax.faces.component.UIComponent; @@ -123,12 +122,9 @@ public class ConfigRenderer extends Renderer { } }
- String readOnly = FacesContextUtility.getOptionalRequestParameter("readOnly"); - if (null != readOnly) { - configurationComponent.setReadOnly(Boolean.valueOf(readOnly)); - } - + Boolean readOnly = Boolean.valueOf(FacesContextUtility.getOptionalRequestParameter("readOnly")); Boolean save = Boolean.valueOf(FacesContextUtility.getOptionalRequestParameter("save")); + configurationComponent.setReadOnly(readOnly);
if (component.getChildCount() == 0) addChildComponents(configurationComponent); @@ -182,9 +178,6 @@ public class ConfigRenderer extends Renderer { // Only create the child components the first time around (i.e. once per JSF lifecycle). if (component.getChildCount() == 0) addChildComponents(configurationComponent); - if (configurationComponent.getToolbar() != null) { - configurationComponent.getToolbar().setRendered(configurationComponent.getShowToolbar()); - } }
private boolean isAjaxRefresh(AbstractConfigurationComponent configurationComponent) { @@ -282,39 +275,29 @@ public class ConfigRenderer extends Renderer { }
private void addStructuredConfig(AbstractConfigurationComponent configurationComponent) { - { - UIPanel toolbarPanel = FacesComponentUtility.addBlockPanel(configurationComponent, configurationComponent, - "summary-props-table"); - if (configurationComponent.isReadOnly()) { - HtmlOutputLink editLink = FacesComponentUtility.addOutputLink(toolbarPanel, configurationComponent, - "edit.xhtml"); - FacesComponentUtility.addGraphicImage(editLink, configurationComponent, "/images/edit.png", "Edit"); - FacesComponentUtility.addOutputText(editLink, configurationComponent, "Edit", ""); - FacesComponentUtility.addParameter(editLink, configurationComponent, "readOnly", Boolean - .toString(false)); - FacesComponentUtility.addParameter(editLink, configurationComponent, "id", FacesContextUtility - .getRequiredRequestParameter("id")); - } else { - HtmlCommandLink saveLink = FacesComponentUtility.addCommandLink(toolbarPanel, configurationComponent); - FacesComponentUtility.addGraphicImage(saveLink, configurationComponent, "/images/save.png", "Save"); - FacesComponentUtility.addOutputText(saveLink, configurationComponent, "Save", ""); - FacesComponentUtility.addParameter(saveLink, configurationComponent, "save", Boolean.toString(true)); - FacesComponentUtility - .addParameter(saveLink, configurationComponent, "readOnly", Boolean.toString(true)); - - saveLink.setActionExpression(getSaveActionExpression()); + UIPanel toolbarPanel = FacesComponentUtility.addBlockPanel(configurationComponent, configurationComponent, + "summary-props-table"); + if (configurationComponent.isReadOnly()) { + HtmlCommandLink editLink = FacesComponentUtility.addCommandLink(toolbarPanel, configurationComponent); + FacesComponentUtility.addGraphicImage(editLink, configurationComponent, "/images/edit.png", "Edit"); + FacesComponentUtility.addOutputText(editLink, configurationComponent, "Edit", ""); + FacesComponentUtility.addParameter(editLink, configurationComponent, "readOnly", Boolean.toString(false));
- } - if (configurationComponent.getConfigurationDefinition().getConfigurationFormat().isRawSupported()) { - HtmlCommandLink toRawLink = FacesComponentUtility.addCommandLink(toolbarPanel, configurationComponent); - FacesComponentUtility.addGraphicImage(toRawLink, configurationComponent, "/images/raw.png", "showRaw"); - FacesComponentUtility.addOutputText(toRawLink, configurationComponent, "showRaw", ""); - FacesComponentUtility.addParameter(toRawLink, configurationComponent, "showRaw", Boolean.TRUE - .toString()); - FacesComponentUtility.addParameter(toRawLink, configurationComponent, "readOnly", Boolean - .toString(configurationComponent.isReadOnly())); - } - configurationComponent.setToolbar(toolbarPanel); + } else { + HtmlCommandLink saveLink = FacesComponentUtility.addCommandLink(toolbarPanel, configurationComponent); + FacesComponentUtility.addGraphicImage(saveLink, configurationComponent, "/images/save.png", "Save"); + FacesComponentUtility.addOutputText(saveLink, configurationComponent, "Save", ""); + FacesComponentUtility.addParameter(saveLink, configurationComponent, "save", Boolean.toString(true)); + FacesComponentUtility.addParameter(saveLink, configurationComponent, "readOnly", Boolean.toString(true)); + } + + if (configurationComponent.getConfigurationDefinition().getConfigurationFormat().isRawSupported()) { + HtmlCommandLink toRawLink = FacesComponentUtility.addCommandLink(toolbarPanel, configurationComponent); + FacesComponentUtility.addGraphicImage(toRawLink, configurationComponent, "/images/raw.png", "showRaw"); + FacesComponentUtility.addOutputText(toRawLink, configurationComponent, "showRaw", ""); + FacesComponentUtility.addParameter(toRawLink, configurationComponent, "showRaw", Boolean.TRUE.toString()); + FacesComponentUtility.addParameter(toRawLink, configurationComponent, "readOnly", Boolean + .toString(configurationComponent.isReadOnly())); }
if (!configurationComponent.isReadOnly()) @@ -336,13 +319,6 @@ public class ConfigRenderer extends Renderer { .isFullyEditable(), false); }
- private MethodExpression getSaveActionExpression() { - - MethodExpression actionExpression = null; - - return actionExpression; - } - private void addStructuredRawToggle(AbstractConfigurationComponent configurationComponent, boolean showRaw) { if (configurationComponent.getConfigurationDefinition().getConfigurationFormat().equals( ConfigurationFormat.STRUCTURED_AND_RAW)) { diff --git a/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/RawConfigUIComponent.java b/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/RawConfigUIComponent.java index 2c9a1be..ce42a54 100644 --- a/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/RawConfigUIComponent.java +++ b/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/RawConfigUIComponent.java @@ -138,8 +138,8 @@ public class RawConfigUIComponent extends UIComponentBase { FacesComponentUtility.addParameter(link, idFactory, "path", raw.getPath()); FacesComponentUtility.addParameter(link, idFactory, "whichRaw", Integer.toString(rawCount++)); FacesComponentUtility.addParameter(link, idFactory, "showRaw", Boolean.TRUE.toString()); - readOnlyParms.add(FacesComponentUtility.addParameter(link, idFactory, - AbstractConfigurationComponent.READ_ONLY_ATTRIBUTE, Boolean.toString(readOnly))); + readOnlyParms.add(FacesComponentUtility.addParameter(link, idFactory, "readOnly", Boolean + .toString(readOnly)));
}
@@ -155,32 +155,24 @@ public class RawConfigUIComponent extends UIComponentBase { inputTextarea.setReadonly(readOnly); }
- private HtmlOutputLink fullscreenLink; - private UIParameter fullScreenResourceIdParam; - private void addToolbar(ConfigurationDefinition configurationDefinition, UIPanel parent) { UIPanel toolbarPanel = FacesComponentUtility.addBlockPanel(parent, idFactory, "config-toolbar"); if (readOnly) { HtmlCommandLink editLink = FacesComponentUtility.addCommandLink(toolbarPanel, idFactory); FacesComponentUtility.addGraphicImage(editLink, idFactory, "/images/edit.png", "Edit"); FacesComponentUtility.addOutputText(editLink, idFactory, "Edit", ""); - FacesComponentUtility.addParameter(editLink, idFactory, "showRaw", Boolean.TRUE.toString()); - FacesComponentUtility.addParameter(editLink, idFactory, AbstractConfigurationComponent.READ_ONLY_ATTRIBUTE, - Boolean.FALSE.toString()); + FacesComponentUtility.addParameter(editLink, idFactory, "showStructured", Boolean.FALSE.toString()); } else { HtmlCommandLink saveLink = FacesComponentUtility.addCommandLink(toolbarPanel, idFactory); FacesComponentUtility.addGraphicImage(saveLink, idFactory, "/images/save.png", "Save"); FacesComponentUtility.addOutputText(saveLink, idFactory, "Save", ""); - FacesComponentUtility.addParameter(saveLink, idFactory, "showRaw", Boolean.FALSE.toString()); - FacesComponentUtility.addParameter(saveLink, idFactory, AbstractConfigurationComponent.READ_ONLY_ATTRIBUTE, - Boolean.TRUE.toString()); + FacesComponentUtility.addParameter(saveLink, idFactory, "showStructured", Boolean.FALSE.toString()); } { - fullscreenLink = FacesComponentUtility.addOutputLink(toolbarPanel, idFactory, "view-full.xhtml"); - FacesComponentUtility - .addGraphicImage(fullscreenLink, idFactory, "/images/viewfullscreen.png", "FullScreen"); - FacesComponentUtility.addOutputText(fullscreenLink, idFactory, "Full Screen", ""); - fullScreenResourceIdParam = FacesComponentUtility.addParameter(fullscreenLink, idFactory, "id", ""); + HtmlCommandLink saveCommandLink = FacesComponentUtility.addCommandLink(toolbarPanel, idFactory); + FacesComponentUtility.addGraphicImage(saveCommandLink, idFactory, "/images/viewfullscreen.png", + "FullScreen"); + FacesComponentUtility.addOutputText(saveCommandLink, idFactory, "Full Screen", ""); } if (!readOnly) { HtmlOutputLink uploadLink = FacesComponentUtility.addOutputLink(toolbarPanel, idFactory, "upload.xhtml"); @@ -208,23 +200,10 @@ public class RawConfigUIComponent extends UIComponentBase { public void encodeBegin(FacesContext context) throws IOException { // TODO Auto-generated method stub super.encodeBegin(context); - inputTextarea.setValue(rawMap.get(getSelectedPath()).getContentString()); for (UIParameter param : readOnlyParms) { param.setValue(Boolean.toString(readOnly)); }
- String resourceId = FacesContextUtility.getOptionalRequestParameter("id"); - - if (null == resourceId) { - if (fullscreenLink != null) { - fullscreenLink.setRendered(false); - } - } else { - if (fullScreenResourceIdParam != null) { - fullScreenResourceIdParam.setValue(resourceId); - } - } - } } diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit.xhtml index dffd02b..a85f409 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit.xhtml @@ -49,10 +49,7 @@ THIS TEXT WILL BE REMOVED. configuration="#{ExistingResourceConfigurationUIBean.configuration}" nullConfigurationDefinitionMessage="#{ExistingResourceConfigurationUIBean.nullConfigurationDefinitionMessage}" nullConfigurationMessage="#{ExistingResourceConfigurationUIBean.nullConfigurationMessage}" - prevalidate="true" - showToolbar="true" - readOnly="false" - /> + prevalidate="true"/>
<h:panelGrid columns="2" styleClass="buttons-table" columnClasses="button-cell" rendered="#{ExistingResourceConfigurationUIBean.configuration != null}"> <h:commandButton value="SAVE" action="#{ExistingResourceConfigurationUIBean.updateConfiguration}" diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view-full.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view-full.xhtml deleted file mode 100644 index 0491cf8..0000000 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view-full.xhtml +++ /dev/null @@ -1,48 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> - -<html xmlns="http://www.w3.org/1999/xhtml" - xmlns:h="http://java.sun.com/jsf/html" - xmlns:f="http://java.sun.com/jsf/core" - xmlns:ui="http://java.sun.com/jsf/facelets" - xmlns:c="http://java.sun.com/jstl/core" - xmlns:onc="http://jboss.org/on/component" - xmlns:a4j="http://richfaces.org/a4j" - xmlns:rich="http://richfaces.ajax4jsf.org/rich" - xmlns:s="http://jboss.com/products/seam/taglib%22%3E - -<ui:composition template="/rhq/layout/main.xhtml"> -<ui:param name="pageTitle" value="TODO Internationalize this"/> - -<ui:define name="breadcrumbs" > -<h:outputLink value="view.xhtml" action="navigateToUpload" > - <h:outputText value=" Back " /> - <f:param name="id" value="#{ResourceUIBean.id}" /> -</h:outputLink> - -</ui:define> - -<ui:define name="body"> - -<h:form id="editResourceConfigurationForm" > -<input type="hidden" name="id" value="#{ResourceUIBean.id}" /> - - <onc:config configurationDefinition="#{ExistingResourceConfigurationUIBean.configurationDefinition}" - configuration="#{ExistingResourceConfigurationUIBean.configuration}" - accessMapActionExpression="#{ExistingResourceConfigurationUIBean.accessMap}" - nullConfigurationDefinitionMessage="#{ExistingResourceConfigurationUIBean.nullConfigurationDefinitionMessage}" - nullConfigurationMessage="#{ExistingResourceConfigurationUIBean.nullConfigurationMessage}" - readOnly="true" - showToolbar="true" - prevalidate="true" - showRaw="true" - fullscreen="true" /> - - -</h:form> -</ui:define> - -</ui:composition> - -</html> - - diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view-raw-full.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view-raw-full.xhtml new file mode 100644 index 0000000..e9e8c1a --- /dev/null +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view-raw-full.xhtml @@ -0,0 +1,38 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<html xmlns="http://www.w3.org/1999/xhtml" + xmlns:h="http://java.sun.com/jsf/html" + xmlns:f="http://java.sun.com/jsf/core" + xmlns:ui="http://java.sun.com/jsf/facelets" + xmlns:c="http://java.sun.com/jstl/core" + xmlns:onc="http://jboss.org/on/component" + xmlns:a4j="http://richfaces.org/a4j" + xmlns:rich="http://richfaces.ajax4jsf.org/rich" + xmlns:s="http://jboss.com/products/seam/taglib%22%3E + +<ui:composition template="/rhq/layout/main.xhtml"> +<ui:param name="pageTitle" value="TODO Internationalize this"/> + +<ui:define name="breadcrumbs" > +<h:outputLink value="view-raw.xhtml" action="navigateToUpload" > + <h:outputText value=" Back " /> + <f:param name="id" value="#{ResourceUIBean.id}" /> +</h:outputLink> + +</ui:define> + +<ui:define name="body"> + +<h:form id="editResourceConfigurationForm" > +<input type="hidden" name="id" value="#{ResourceUIBean.id}" /> +<div> +<pre><h:outputText value="#{ExistingResourceConfigurationUIBean.currentContents}" /></pre> +</div> +</h:form> +</ui:define> + +</ui:composition> + +</html> + + diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml index 40a917d..d0cfa5c 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml @@ -47,14 +47,12 @@ THIS TEXT WILL BE REMOVED. <!-- TODO remove the id version --> <input type="hidden" name="id" value="#{ResourceUIBean.id}"/>
- <onc:config configurationDefinition="#{ExistingResourceConfigurationViewUIBean.configurationDefinition}" - configuration="#{ExistingResourceConfigurationViewUIBean.configuration}" - accessMapActionExpression="#{ExistingResourceConfigurationViewUIBean.accessMap}" - nullConfigurationDefinitionMessage="#{ExistingResourceConfigurationViewUIBean.nullConfigurationDefinitionMessage}" - nullConfigurationMessage="#{ExistingResourceConfigurationViewUIBean.nullConfigurationMessage}" - readOnly="true" - showToolbar="true" - prevalidate="true"/> + <onc:config configurationDefinition="#{ExistingResourceConfigurationUIBean.configurationDefinition}" + configuration="#{ExistingResourceConfigurationUIBean.configuration}" + accessMapActionExpression="#{ExistingResourceConfigurationUIBean.accessMap}" + nullConfigurationDefinitionMessage="#{ExistingResourceConfigurationUIBean.nullConfigurationDefinitionMessage}" + nullConfigurationMessage="#{ExistingResourceConfigurationUIBean.nullConfigurationMessage}" + prevalidate="true"/> <input type="hidden" name="id" value="#{ResourceUIBean.id}"/>
</h:form>
commit 7a7504dc9e3f49340bc8418b36fdc18b537c8533 Author: John Sanda john@localhost.localdomain Date: Fri Dec 18 14:24:31 2009 -0500
Revert "Still broken. Major refactroing of the config renderer so that the structured config is contained inside a panel. Might have broken something not visible from the test. Still working on re-enabling the save."
This reverts commit 30d9312e87182ebcc711428585ba51da3c64f3c9.
diff --git a/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/StructuredConfigUIComponent.java b/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/StructuredConfigUIComponent.java deleted file mode 100644 index c7aa459..0000000 --- a/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/StructuredConfigUIComponent.java +++ /dev/null @@ -1,146 +0,0 @@ -package org.rhq.core.gui.configuration; - -import java.util.List; - -import javax.faces.component.UIComponent; -import javax.faces.component.UIPanel; -import javax.faces.component.html.HtmlPanelGroup; - -import org.richfaces.component.html.HtmlSimpleTogglePanel; - -import org.rhq.core.domain.configuration.definition.PropertyGroupDefinition; -import org.rhq.core.gui.configuration.helper.PropertyRenderingUtility; -import org.rhq.core.gui.configuration.propset.ConfigurationSetComponent; -import org.rhq.core.gui.util.FacesComponentIdFactory; -import org.rhq.core.gui.util.FacesComponentUtility; - -public class StructuredConfigUIComponent extends UIPanel { - - FacesComponentIdFactory idFactory; - boolean isGroup; - - public StructuredConfigUIComponent(AbstractConfigurationComponent configurationComponent) { - super(); - this.idFactory = configurationComponent; - this.isGroup = configurationComponent.isGroup(); - if (!configurationComponent.isReadOnly()) - addRequiredNotationsKey(); - - if (configurationComponent.getListName() != null) { - if (configurationComponent.getListIndex() == null) { - // No index specified means we should add a new map to the list. - configurationComponent.setListIndex(ConfigRenderer.addNewMap(configurationComponent)); - } - // Update member Configurations if this is a group config. - updateGroupMemberConfigurations(configurationComponent); - addListMemberProperty(configurationComponent, configurationComponent.getListIndex()); - } else { - addNonGroupedProperties(configurationComponent); - addGroupedProperties(configurationComponent); - } - String id = ConfigRenderer.getInitInputsJavaScriptComponentId(configurationComponent); - PropertyRenderingUtility.addInitInputsJavaScript(this, id, configurationComponent.isFullyEditable(), false); - } - - public void addRequiredNotationsKey() { - ConfigRenderer.addDebug(this, true, ".addNotePanel()"); - HtmlPanelGroup footnotesPanel = FacesComponentUtility.addBlockPanel(this, idFactory, - ConfigRenderer.NOTE_PANEL_STYLE_CLASS); - FacesComponentUtility.addOutputText(footnotesPanel, idFactory, "*", - ConfigRenderer.REQUIRED_MARKER_TEXT_STYLE_CLASS); - FacesComponentUtility.addOutputText(footnotesPanel, idFactory, " denotes a required field.", - FacesComponentUtility.NO_STYLE_CLASS); - if (isGroup) { - HtmlPanelGroup overridePanel = FacesComponentUtility.addBlockPanel(this, idFactory, - ConfigRenderer.NOTE_PANEL_STYLE_CLASS); - FacesComponentUtility.addOutputText(overridePanel, idFactory, - "note: if override is not checked, that property will not be altered on any group members", - FacesComponentUtility.NO_STYLE_CLASS); - } - ConfigRenderer.addDebug(this, false, ".addNotePanel()"); - } - - @Override - public String getFamily() { - // TODO Auto-generated method stub - return "rhq"; - } - - private void addListMemberProperty(AbstractConfigurationComponent configurationComponent, Integer listIndex) { - HtmlPanelGroup propertiesPanel = FacesComponentUtility.addBlockPanel(this, idFactory, - ConfigRenderer.UNGROUPED_PROPERTIES_STYLE_CLASS); - propertiesPanel.getChildren() - .add( - new MapInListUIComponentTreeFactory(configurationComponent, configurationComponent.getListName(), - listIndex).createUIComponentTree(null)); - } - - private void updateGroupMemberConfigurations(AbstractConfigurationComponent configurationComponent) { - if (configurationComponent instanceof ConfigurationSetComponent) { - ConfigurationSetComponent configurationSetComponent = ((ConfigurationSetComponent) configurationComponent); - configurationSetComponent.getConfigurationSet().applyGroupConfiguration(); - } - } - - void addGroupedProperties(AbstractConfigurationComponent config) { - ConfigRenderer.addDebug(config, true, ".addGroupedProperties()"); - List<PropertyGroupDefinition> groups = config.getConfigurationDefinition().getGroupDefinitions(); - for (PropertyGroupDefinition group : groups) { - HtmlSimpleTogglePanel groupPanel = addGroupPanel(group); - AbstractPropertyBagUIComponentTreeFactory propertyListUIComponentTreeFactory = new GroupUIComponentTreeFactory( - config, group.getName()); - groupPanel.getChildren().add(propertyListUIComponentTreeFactory.createUIComponentTree(null)); - } - - ConfigRenderer.addDebug(config, false, ".addGroupedProperties()"); - } - - void addNonGroupedProperties(AbstractConfigurationComponent config) { - - ConfigRenderer.addDebug(this, true, ".addNonGroupedProperties()"); - HtmlPanelGroup propertiesPanel = FacesComponentUtility.addBlockPanel(this, idFactory, - ConfigRenderer.UNGROUPED_PROPERTIES_STYLE_CLASS); - AbstractPropertyBagUIComponentTreeFactory propertyListUIComponentTreeFactory = new GroupUIComponentTreeFactory( - config, GroupUIComponentTreeFactory.NO_GROUP); - - UIComponent createUIComponentTree = propertyListUIComponentTreeFactory.createUIComponentTree(null); - propertiesPanel.getChildren().add(createUIComponentTree); - - ConfigRenderer.addDebug(this, false, ".addNonGroupedProperties()"); - } - - HtmlSimpleTogglePanel addGroupPanel(PropertyGroupDefinition group) { - ConfigRenderer.addDebug(this, true, ".addGroupPanel()"); - HtmlSimpleTogglePanel groupPanel = FacesComponentUtility.addSimpleTogglePanel(this, idFactory, null); - // TODO: On AJAX requests, set "opened" attribute to its previous state. - groupPanel.setOpened(!group.isDefaultHidden()); - groupPanel.setHeaderClass(ConfigRenderer.PROPERTY_GROUP_HEADER_STYLE_CLASS); - groupPanel.setBodyClass(ConfigRenderer.PROPERTY_GROUP_BODY_STYLE_CLASS); - - // Custom header that includes the name and description - HtmlPanelGroup headerPanel = FacesComponentUtility.createBlockPanel(idFactory, null); - FacesComponentUtility.addOutputText(headerPanel, idFactory, group.getDisplayName(), null); - FacesComponentUtility.addOutputText(headerPanel, idFactory, group.getDescription(), - "group-description-text-panel"); - groupPanel.getFacets().put("header", headerPanel); - - // custom "close" widget - HtmlPanelGroup closePanel = FacesComponentUtility.createBlockPanel(idFactory, null); - closePanel.setStyle("text-align: right; font-weight: normal; font-size: 0.8em; whitespace: nowrap;"); - FacesComponentUtility - .addGraphicImage(closePanel, idFactory, "/images/ico_trigger_wht_collapse.gif", "collapse"); - FacesComponentUtility.addOutputText(closePanel, idFactory, " Collapse", null); - groupPanel.getFacets().put("closeMarker", closePanel); - - // custom "open" widget - HtmlPanelGroup openPanel = FacesComponentUtility.createBlockPanel(idFactory, null); - openPanel.setStyle("text-align: right; font-weight: normal; font-size: 0.8em; whitespace: nowrap;"); - FacesComponentUtility.addGraphicImage(openPanel, idFactory, "/images/ico_trigger_wht_expand.gif", "expand"); - FacesComponentUtility.addOutputText(openPanel, idFactory, " Expand", null); - groupPanel.getFacets().put("openMarker", openPanel); - ConfigRenderer.addDebug(this, true, ".addGroupPanel()"); - - return groupPanel; - } - -} diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/test/RawTestConfigurationUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/test/RawTestConfigurationUIBean.java deleted file mode 100644 index 919a4ad..0000000 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/test/RawTestConfigurationUIBean.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2008 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.gui.configuration.test; - -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; - -import javax.faces.application.FacesMessage; - -import org.rhq.core.domain.configuration.Configuration; -import org.rhq.core.domain.configuration.Property; -import org.rhq.core.domain.configuration.PropertySimple; -import org.rhq.core.domain.configuration.RawConfiguration; -import org.rhq.core.domain.configuration.definition.ConfigurationFormat; -import org.rhq.core.gui.configuration.propset.ConfigurationSet; -import org.rhq.core.gui.configuration.propset.ConfigurationSetMember; -import org.rhq.core.gui.util.FacesContextUtility; -import org.rhq.enterprise.gui.common.Outcomes; - -/** - * @author Ian Springer - */ -public class RawTestConfigurationUIBean extends AbstractTestConfigurationUIBean { - public RawTestConfigurationUIBean() { - setConfigurationDefinition(TestConfigurationFactory.createConfigurationDefinition()); - setConfiguration(TestConfigurationFactory.createConfiguration()); - List<ConfigurationSetMember> members = new ArrayList(GROUP_SIZE); - for (int i = 0; i < GROUP_SIZE; i++) { - Configuration configuration = getConfiguration().deepCopy(true); - configuration.setId(i + 1); - configuration.getSimple("String1").setStringValue(UUID.randomUUID().toString()); - configuration.getSimple("Integer").setStringValue(String.valueOf(i + 1)); - configuration.getSimple("Boolean").setStringValue(String.valueOf(i % 2 == 0)); - if (i == 0) - configuration.getMap("OpenMapOfSimples").put(new PropertySimple("PROCESSOR_CORES", "4")); - ConfigurationSetMember memberInfo = new ConfigurationSetMember(LABELS[GROUP_SIZE % LABELS.length], - configuration); - members.add(memberInfo); - } - setConfigurationSet(new ConfigurationSet(getConfigurationDefinition(), members)); - // Unwrap the Hibernate proxy objects, which Facelets appears not to be able to handle. - setProperties(new ArrayList<Property>(this.getConfiguration().getProperties())); - - getConfigurationDefinition().setConfigurationFormat(ConfigurationFormat.STRUCTURED_AND_RAW); - - RawConfiguration rawConfiguration = new RawConfiguration(); - rawConfiguration.setPath("/tmp/nowhere.txt"); - rawConfiguration.setContents("A=1".getBytes()); - getConfiguration().addRawConfiguration(rawConfiguration); - - } - - public static final String MANAGED_BEAN_NAME = RawTestConfigurationUIBean.class.getSimpleName(); - protected static final String SUCCESS_OUTCOME = "success"; - protected static final String FAILURE_OUTCOME = "failure"; - - public String updateConfiguration() { - // Any values changed in the group config (i.e. via the inputs on the main page) need to be - // applied to all member configs before persisting them. - //getConfigurationSet().applyGroupConfiguration(); - // TODO (low priority): Persist the test config somewhere. - FacesContextUtility.addMessage(FacesMessage.SEVERITY_INFO, "Configuration updated."); - return Outcomes.SUCCESS; - } -} \ No newline at end of file diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/test/config/edit.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/test/config/edit.xhtml deleted file mode 100644 index 1e4c156..0000000 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/test/config/edit.xhtml +++ /dev/null @@ -1,51 +0,0 @@ -<?xml version="1.0"?> - -<!DOCTYPE html - PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" - "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> - -<html xmlns="http://www.w3.org/1999/xhtml" - xmlns:h="http://java.sun.com/jsf/html" - xmlns:f="http://java.sun.com/jsf/core" - xmlns:ui="http://java.sun.com/jsf/facelets" - xmlns:rich="http://richfaces.ajax4jsf.org/rich" - xmlns:onc="http://jboss.org/on/component%22%3E - -THIS TEXT WILL BE REMOVED. - -<ui:composition template="/rhq/layout/main.xhtml"> - - THIS TEXT WILL BE REMOVED AS WELL. - - <ui:param name="pageTitle" value="Test Raw Configuration"/> - - <ui:define name="body"> - - <h:messages showSummary="true" - showDetail="true" - errorClass="ErrorBlock" - warnClass="ErrorBlock" - infoClass="ConfirmationBlock" - globalOnly="true" - layout="table" - width="100%"/> - - <h:form id="viewTestConfigurationForm"> - - <onc:config configurationDefinition="#{RawTestConfigurationUIBean.configurationDefinition}" - configuration="#{RawTestConfigurationUIBean.configuration}" - accessMapActionExpression="#{RawTestConfigurationUIBean.accessMap}" - readOnly="true" /> - <h:panelGrid columns="1" styleClass="buttons-table" columnClasses="button-cell"> - <h:commandButton type="submit" action="#{RawTestConfigurationUIBean.editConfiguration}" - value="Edit this Configuration"/> - </h:panelGrid> - </h:form> - - </ui:define> - -</ui:composition> - -THIS TEXT WILL BE REMOVED AS WELL. - -</html> diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/test/config/view.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/test/config/view.xhtml deleted file mode 100644 index c543ca7..0000000 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/test/config/view.xhtml +++ /dev/null @@ -1,52 +0,0 @@ -<?xml version="1.0"?> - -<!DOCTYPE html - PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" - "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> - -<html xmlns="http://www.w3.org/1999/xhtml" - xmlns:h="http://java.sun.com/jsf/html" - xmlns:f="http://java.sun.com/jsf/core" - xmlns:ui="http://java.sun.com/jsf/facelets" - xmlns:rich="http://richfaces.ajax4jsf.org/rich" - xmlns:onc="http://jboss.org/on/component%22%3E - -THIS TEXT WILL BE REMOVED. - -<ui:composition template="/rhq/layout/main.xhtml"> - - THIS TEXT WILL BE REMOVED AS WELL. - - <ui:param name="pageTitle" value="Test Raw Configuration"/> - - <ui:define name="body"> - - <h:messages showSummary="true" - showDetail="true" - errorClass="ErrorBlock" - warnClass="ErrorBlock" - infoClass="ConfirmationBlock" - globalOnly="true" - layout="table" - width="100%"/> - - <h:form id="viewTestConfigurationForm"> - - <onc:config configurationDefinition="#{RawTestConfigurationUIBean.configurationDefinition}" - configuration="#{RawTestConfigurationUIBean.configuration}" - accessMapActionExpression="#{RawTestConfigurationUIBean.accessMap}" - readOnly="true" - showToolbar="true" /> - <h:panelGrid columns="1" styleClass="buttons-table" columnClasses="button-cell"> - <h:commandButton type="submit" action="#{RawTestConfigurationUIBean.editConfiguration}" - value="Edit this Configuration"/> - </h:panelGrid> - </h:form> - - </ui:define> - -</ui:composition> - -THIS TEXT WILL BE REMOVED AS WELL. - -</html>
commit 3eb729e227a8424b50635d7eaaf244c230fc1277 Author: John Sanda john@localhost.localdomain Date: Fri Dec 18 14:24:14 2009 -0500
Revert "added toolbar in xhtml, removed it from tests, still broken"
This reverts commit 8215954aefb1a23e492cbcaee04d628d247349ec.
diff --git a/.classpath b/.classpath index e53c4a4..a3aef1e 100644 --- a/.classpath +++ b/.classpath @@ -189,7 +189,7 @@ <classpathentry exported="true" kind="var" path="M2_REPO/org/json/json/20080701/json-20080701.jar"/> <classpathentry exported="true" kind="var" path="M2_REPO/com/sun/jna/jna/3.0.1/jna-3.0.1.jar"/> <classpathentry exported="true" kind="var" path="M2_REPO/org/freemarker/freemarker/2.3.11/freemarker-2.3.11.jar"/> - <classpathentry exported="true" kind="var" path="M2_REPO/org/jboss/seam/jboss-seam/2.1.0.SP1/jboss-seam-2.1.0.SP1.jar" sourcepath="/M2_REPO/org/jboss/seam/jboss-seam/2.1.0.SP1/jboss-seam-2.1.0.SP1-sources.jar"/> + <classpathentry exported="true" kind="var" path="M2_REPO/org/jboss/seam/jboss-seam/2.1.0.SP1/jboss-seam-2.1.0.SP1.jar"/> <classpathentry exported="true" kind="var" path="M2_REPO/org/jboss/seam/jboss-seam-ui/2.1.0.SP1/jboss-seam-ui-2.1.0.SP1.jar"/> <classpathentry exported="true" kind="var" path="M2_REPO/hibernate/hibernate3/3.2.r14201-2/hibernate3-3.2.r14201-2.jar"/> <classpathentry exported="true" kind="var" path="M2_REPO/jline/jline/0.9.94/jline-0.9.94.jar"/> diff --git a/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/AbstractConfigurationComponent.java b/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/AbstractConfigurationComponent.java index 5d5f894..e49ead1 100644 --- a/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/AbstractConfigurationComponent.java +++ b/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/AbstractConfigurationComponent.java @@ -24,7 +24,6 @@ package org.rhq.core.gui.configuration;
import java.util.UUID;
-import javax.el.ValueExpression; import javax.faces.component.UIComponent; import javax.faces.component.UIComponentBase; import javax.faces.context.FacesContext; @@ -60,7 +59,6 @@ public abstract class AbstractConfigurationComponent extends UIComponentBase imp private Boolean fullyEditable; private String listName; private Integer listIndex; - RawConfigUIComponent rawConfigUIComponent;
public UIComponent getToolbar() { return toolbar; @@ -89,16 +87,6 @@ public abstract class AbstractConfigurationComponent extends UIComponentBase imp
public abstract String getConfigurationExpressionString();
- private ValueExpression saveValueExpression; - - public ValueExpression getSaveValueExpression() { - return saveValueExpression; - } - - public void setSaveValueExpression(ValueExpression saveValueExpression) { - this.saveValueExpression = saveValueExpression; - } - public String createUniqueId() { return UNIQUE_ID_PREFIX + UUID.randomUUID(); } @@ -227,12 +215,10 @@ public abstract class AbstractConfigurationComponent extends UIComponentBase imp
private Object[] stateValues;
- public StructuredConfigUIComponent structuredConfig; - @Override public Object saveState(FacesContext facesContext) { if (this.stateValues == null) { - this.stateValues = new Object[12]; + this.stateValues = new Object[8]; }
this.stateValues[0] = super.saveState(facesContext); @@ -243,12 +229,6 @@ public abstract class AbstractConfigurationComponent extends UIComponentBase imp this.stateValues[5] = this.prevalidate; this.stateValues[6] = this.isGroup; this.stateValues[7] = this.getShowToolbar(); - if (rawConfigUIComponent != null) { - this.stateValues[8] = this.rawConfigUIComponent; - this.stateValues[9] = structuredConfig; - this.stateValues[10] = this.rawConfigUIComponent.saveState(facesContext); - this.stateValues[11] = this.structuredConfig.saveState(facesContext); - } return this.stateValues; }
@@ -263,33 +243,20 @@ public abstract class AbstractConfigurationComponent extends UIComponentBase imp this.prevalidate = (Boolean) this.stateValues[5]; this.isGroup = (Boolean) this.stateValues[6]; this.showToolbar = (Boolean) this.stateValues[7]; - - this.rawConfigUIComponent = (RawConfigUIComponent) this.stateValues[8]; - this.structuredConfig = (StructuredConfigUIComponent) this.stateValues[9]; - - if (this.rawConfigUIComponent != null) { - this.rawConfigUIComponent.restoreState(facesContext, this.stateValues[10]); - } - if (this.structuredConfig != null) { - this.structuredConfig.restoreState(facesContext, this.stateValues[11]); - } - - //getChildren().add(structuredConfig); - //getChildren().add(rawConfigUIComponent); - }
public boolean getShouldShowRaw() { return Boolean.valueOf(FacesContextUtility.getOptionalRequestParameter("showRaw", String.class, "unset")) - && (!this.getConfigurationDefinition().getConfigurationFormat().equals(ConfigurationFormat.STRUCTURED)); + || (this.getConfigurationDefinition().getConfigurationFormat().equals(ConfigurationFormat.RAW)); }
+ RawConfigUIComponent rawConfigUIComponent; + RawConfigUIComponent getRawConfigUIComponent() { if (null == rawConfigUIComponent) { rawConfigUIComponent = new RawConfigUIComponent(getConfiguration(), getConfigurationDefinition(), this, isReadOnly()); } - return rawConfigUIComponent; }
diff --git a/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/ConfigRenderer.java b/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/ConfigRenderer.java index be2feac..278d619 100644 --- a/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/ConfigRenderer.java +++ b/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/ConfigRenderer.java @@ -26,12 +26,16 @@ import java.io.IOException; import java.util.List; import java.util.Map;
+import javax.el.MethodExpression; import javax.el.ValueExpression; import javax.faces.application.FacesMessage; import javax.faces.component.UIComponent; import javax.faces.component.UIForm; import javax.faces.component.UIInput; +import javax.faces.component.UIOutput; +import javax.faces.component.UIPanel; import javax.faces.component.UIParameter; +import javax.faces.component.html.HtmlCommandLink; import javax.faces.component.html.HtmlForm; import javax.faces.component.html.HtmlOutputLink; import javax.faces.component.html.HtmlPanelGrid; @@ -47,15 +51,18 @@ import org.ajax4jsf.context.AjaxContext; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.richfaces.component.html.HtmlModalPanel; +import org.richfaces.component.html.HtmlSimpleTogglePanel;
import org.rhq.core.clientapi.agent.configuration.ConfigurationUtility; 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.configuration.definition.ConfigurationFormat; import org.rhq.core.domain.configuration.definition.PropertyDefinition; import org.rhq.core.domain.configuration.definition.PropertyDefinitionMap; import org.rhq.core.domain.configuration.definition.PropertyDefinitionSimple; +import org.rhq.core.domain.configuration.definition.PropertyGroupDefinition; import org.rhq.core.gui.RequestParameterNameConstants; import org.rhq.core.gui.configuration.helper.PropertyRenderingUtility; import org.rhq.core.gui.configuration.propset.ConfigurationSetComponent; @@ -177,9 +184,7 @@ public class ConfigRenderer extends Renderer { addChildComponents(configurationComponent); if (configurationComponent.getToolbar() != null) { configurationComponent.getToolbar().setRendered(configurationComponent.getShowToolbar()); - } - }
private boolean isAjaxRefresh(AbstractConfigurationComponent configurationComponent) { @@ -265,20 +270,113 @@ public class ConfigRenderer extends Renderer { } }
- configurationComponent.rawConfigUIComponent = new RawConfigUIComponent(configurationComponent - .getConfiguration(), configurationComponent.getConfigurationDefinition(), configurationComponent, - configurationComponent.isReadOnly()); + Boolean shouldShowRawNow = configurationComponent.getShouldShowRaw(); + + if (shouldShowRawNow) { + configurationComponent.getChildren().add( + new RawConfigUIComponent(configurationComponent.getConfiguration(), configurationComponent + .getConfigurationDefinition(), configurationComponent, configurationComponent.isReadOnly())); + } else { + addStructuredConfig(configurationComponent); + } + }
- configurationComponent.getChildren().add(configurationComponent.rawConfigUIComponent); + private void addStructuredConfig(AbstractConfigurationComponent configurationComponent) { + { + UIPanel toolbarPanel = FacesComponentUtility.addBlockPanel(configurationComponent, configurationComponent, + "summary-props-table"); + if (configurationComponent.isReadOnly()) { + HtmlOutputLink editLink = FacesComponentUtility.addOutputLink(toolbarPanel, configurationComponent, + "edit.xhtml"); + FacesComponentUtility.addGraphicImage(editLink, configurationComponent, "/images/edit.png", "Edit"); + FacesComponentUtility.addOutputText(editLink, configurationComponent, "Edit", ""); + FacesComponentUtility.addParameter(editLink, configurationComponent, "readOnly", Boolean + .toString(false)); + FacesComponentUtility.addParameter(editLink, configurationComponent, "id", FacesContextUtility + .getRequiredRequestParameter("id")); + } else { + HtmlCommandLink saveLink = FacesComponentUtility.addCommandLink(toolbarPanel, configurationComponent); + FacesComponentUtility.addGraphicImage(saveLink, configurationComponent, "/images/save.png", "Save"); + FacesComponentUtility.addOutputText(saveLink, configurationComponent, "Save", ""); + FacesComponentUtility.addParameter(saveLink, configurationComponent, "save", Boolean.toString(true)); + FacesComponentUtility + .addParameter(saveLink, configurationComponent, "readOnly", Boolean.toString(true)); + + saveLink.setActionExpression(getSaveActionExpression());
- configurationComponent.structuredConfig = new StructuredConfigUIComponent(configurationComponent); + } + if (configurationComponent.getConfigurationDefinition().getConfigurationFormat().isRawSupported()) { + HtmlCommandLink toRawLink = FacesComponentUtility.addCommandLink(toolbarPanel, configurationComponent); + FacesComponentUtility.addGraphicImage(toRawLink, configurationComponent, "/images/raw.png", "showRaw"); + FacesComponentUtility.addOutputText(toRawLink, configurationComponent, "showRaw", ""); + FacesComponentUtility.addParameter(toRawLink, configurationComponent, "showRaw", Boolean.TRUE + .toString()); + FacesComponentUtility.addParameter(toRawLink, configurationComponent, "readOnly", Boolean + .toString(configurationComponent.isReadOnly())); + } + configurationComponent.setToolbar(toolbarPanel); + }
- configurationComponent.getChildren().add(configurationComponent.structuredConfig); + if (!configurationComponent.isReadOnly()) + addRequiredNotationsKey(configurationComponent);
- Boolean shouldShowRawNow = configurationComponent.getShouldShowRaw(); + if (configurationComponent.getListName() != null) { + if (configurationComponent.getListIndex() == null) { + // No index specified means we should add a new map to the list. + configurationComponent.setListIndex(addNewMap(configurationComponent)); + }
- configurationComponent.rawConfigUIComponent.setRendered(shouldShowRawNow); - configurationComponent.structuredConfig.setRendered(!shouldShowRawNow); + addListMemberProperty(configurationComponent); + } else { + addConfiguration(configurationComponent); + } + + String id = getInitInputsJavaScriptComponentId(configurationComponent); + PropertyRenderingUtility.addInitInputsJavaScript(configurationComponent, id, configurationComponent + .isFullyEditable(), false); + } + + private MethodExpression getSaveActionExpression() { + + MethodExpression actionExpression = null; + + return actionExpression; + } + + private void addStructuredRawToggle(AbstractConfigurationComponent configurationComponent, boolean showRaw) { + if (configurationComponent.getConfigurationDefinition().getConfigurationFormat().equals( + ConfigurationFormat.STRUCTURED_AND_RAW)) { + + HtmlPanelGroup toRawLinkPanel = FacesComponentUtility.addBlockPanel(configurationComponent, + configurationComponent, UNGROUPED_PROPERTIES_STYLE_CLASS); + + FacesComponentUtility.addOutputText(toRawLinkPanel, configurationComponent, + "internationalized Message goes here", UNGROUPED_PROPERTIES_STYLE_CLASS); + + HtmlCommandLink commandLink = FacesComponentUtility.addCommandLink(toRawLinkPanel, configurationComponent); + + UIOutput output = new UIOutput(); + output.setValue(showRaw ? "Show Structured" : " Show Raw"); + commandLink.getChildren().add(output); + //output.setParent(commandLink); + FacesComponentUtility.addParameter(commandLink, configurationComponent, "showRaw", Boolean + .toString(!showRaw)); + } + } + + private void addListMemberProperty(AbstractConfigurationComponent configurationComponent) { + // Update member Configurations if this is a group config. + if (configurationComponent instanceof ConfigurationSetComponent) { + ConfigurationSetComponent configurationSetComponent = ((ConfigurationSetComponent) configurationComponent); + configurationSetComponent.getConfigurationSet().applyGroupConfiguration(); + } + + // Now add a new component to the JSF component tree. + AbstractPropertyBagUIComponentTreeFactory propertyListUIComponentTreeFactory = new MapInListUIComponentTreeFactory( + configurationComponent, configurationComponent.getListName(), configurationComponent.getListIndex()); + HtmlPanelGroup propertiesPanel = FacesComponentUtility.addBlockPanel(configurationComponent, + configurationComponent, UNGROUPED_PROPERTIES_STYLE_CLASS); + propertiesPanel.getChildren().add(propertyListUIComponentTreeFactory.createUIComponentTree(null)); }
private void deleteListMemberProperty(AbstractConfigurationComponent configurationComponent) { @@ -384,6 +482,83 @@ public class ConfigRenderer extends Renderer { + mapName + "'."); }
+ private static void addRequiredNotationsKey(AbstractConfigurationComponent config) { + addDebug(config, true, ".addNotePanel()"); + HtmlPanelGroup footnotesPanel = FacesComponentUtility.addBlockPanel(config, config, NOTE_PANEL_STYLE_CLASS); + FacesComponentUtility.addOutputText(footnotesPanel, config, "*", REQUIRED_MARKER_TEXT_STYLE_CLASS); + FacesComponentUtility.addOutputText(footnotesPanel, config, " denotes a required field.", + FacesComponentUtility.NO_STYLE_CLASS); + if (config.isGroup()) { + HtmlPanelGroup overridePanel = FacesComponentUtility.addBlockPanel(config, config, NOTE_PANEL_STYLE_CLASS); + FacesComponentUtility.addOutputText(overridePanel, config, + "note: if override is not checked, that property will not be altered on any group members", + FacesComponentUtility.NO_STYLE_CLASS); + } + + addDebug(config, false, ".addNotePanel()"); + } + + private void addConfiguration(AbstractConfigurationComponent config) { + addNonGroupedProperties(config); + addGroupedProperties(config); + } + + private void addNonGroupedProperties(AbstractConfigurationComponent config) { + addDebug(config, true, ".addNonGroupedProperties()"); + HtmlPanelGroup propertiesPanel = FacesComponentUtility.addBlockPanel(config, config, + UNGROUPED_PROPERTIES_STYLE_CLASS); + AbstractPropertyBagUIComponentTreeFactory propertyListUIComponentTreeFactory = new GroupUIComponentTreeFactory( + config, GroupUIComponentTreeFactory.NO_GROUP); + propertiesPanel.getChildren().add(propertyListUIComponentTreeFactory.createUIComponentTree(null)); + addDebug(config, false, ".addNonGroupedProperties()"); + } + + private void addGroupedProperties(AbstractConfigurationComponent config) { + addDebug(config, true, ".addGroupedProperties()"); + List<PropertyGroupDefinition> groups = config.getConfigurationDefinition().getGroupDefinitions(); + for (PropertyGroupDefinition group : groups) { + HtmlSimpleTogglePanel groupPanel = addGroupPanel(config, group); + AbstractPropertyBagUIComponentTreeFactory propertyListUIComponentTreeFactory = new GroupUIComponentTreeFactory( + config, group.getName()); + groupPanel.getChildren().add(propertyListUIComponentTreeFactory.createUIComponentTree(null)); + } + + addDebug(config, false, ".addGroupedProperties()"); + } + + private HtmlSimpleTogglePanel addGroupPanel(AbstractConfigurationComponent config, PropertyGroupDefinition group) { + addDebug(config, true, ".addGroupPanel()"); + HtmlSimpleTogglePanel groupPanel = FacesComponentUtility.addSimpleTogglePanel(config, config, null); + // TODO: On AJAX requests, set "opened" attribute to its previous state. + groupPanel.setOpened(!group.isDefaultHidden()); + groupPanel.setHeaderClass(PROPERTY_GROUP_HEADER_STYLE_CLASS); + groupPanel.setBodyClass(PROPERTY_GROUP_BODY_STYLE_CLASS); + + // Custom header that includes the name and description + HtmlPanelGroup headerPanel = FacesComponentUtility.createBlockPanel(config, null); + FacesComponentUtility.addOutputText(headerPanel, config, group.getDisplayName(), null); + FacesComponentUtility + .addOutputText(headerPanel, config, group.getDescription(), "group-description-text-panel"); + groupPanel.getFacets().put("header", headerPanel); + + // custom "close" widget + HtmlPanelGroup closePanel = FacesComponentUtility.createBlockPanel(config, null); + closePanel.setStyle("text-align: right; font-weight: normal; font-size: 0.8em; whitespace: nowrap;"); + FacesComponentUtility.addGraphicImage(closePanel, config, "/images/ico_trigger_wht_collapse.gif", "collapse"); + FacesComponentUtility.addOutputText(closePanel, config, " Collapse", null); + groupPanel.getFacets().put("closeMarker", closePanel); + + // custom "open" widget + HtmlPanelGroup openPanel = FacesComponentUtility.createBlockPanel(config, null); + openPanel.setStyle("text-align: right; font-weight: normal; font-size: 0.8em; whitespace: nowrap;"); + FacesComponentUtility.addGraphicImage(openPanel, config, "/images/ico_trigger_wht_expand.gif", "expand"); + FacesComponentUtility.addOutputText(openPanel, config, " Expand", null); + groupPanel.getFacets().put("openMarker", openPanel); + addDebug(config, true, ".addGroupPanel()"); + + return groupPanel; + } + private void validateAttributes(AbstractConfigurationComponent configurationComponent) { // TODO: Add back attribute validation - remember config and configSet components require different attributes. /*if (configurationComponent.getValueExpression("configurationDefinition") == null) { @@ -397,7 +572,7 @@ public class ConfigRenderer extends Renderer { }*/ }
- static int addNewMap(AbstractConfigurationComponent config) { + private int addNewMap(AbstractConfigurationComponent config) { String listName = config.getListName(); PropertyDefinitionMap mapDefinition = (PropertyDefinitionMap) config.getConfigurationDefinition() .getPropertyDefinitionList(listName).getMemberDefinition(); @@ -422,7 +597,7 @@ public class ConfigRenderer extends Renderer { * @param start true if this is the "START" comment, false if it is the "END" comment * @param methodName the name of the method this is calling from */ - static void addDebug(UIComponent component, boolean start, String methodName) { + private static void addDebug(UIComponent component, boolean start, String methodName) { if (LOG.isDebugEnabled()) { StringBuilder msg = new StringBuilder("\n<!--"); msg.append(start ? " START " : " END "); @@ -433,7 +608,7 @@ public class ConfigRenderer extends Renderer { } }
- static String getInitInputsJavaScriptComponentId(AbstractConfigurationComponent configUIComponent) { + private String getInitInputsJavaScriptComponentId(AbstractConfigurationComponent configUIComponent) { return configUIComponent.getId() + INIT_INPUTS_JAVA_SCRIPT_COMPONENT_ID_SUFFIX; }
diff --git a/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/RawConfigUIComponent.java b/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/RawConfigUIComponent.java index 5b86352..2c9a1be 100644 --- a/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/RawConfigUIComponent.java +++ b/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/RawConfigUIComponent.java @@ -34,7 +34,7 @@ public class RawConfigUIComponent extends UIComponentBase { super.decode(context); setSelectedPath(FacesContextUtility.getOptionalRequestParameter("path")); readOnly = Boolean.valueOf(FacesContextUtility.getOptionalRequestParameter("readOnly")); - this.inputTextarea.decode(context); + }
@Override @@ -99,7 +99,7 @@ public class RawConfigUIComponent extends UIComponentBase {
UIPanel rawPanel = FacesComponentUtility.addBlockPanel(this, idFactory, "");
- //addToolbar(configurationDefinition, rawPanel); + addToolbar(configurationDefinition, rawPanel);
HtmlPanelGrid grid = FacesComponentUtility.addPanelGrid(rawPanel, idFactory, "summary-props-table"); grid.setParent(this); @@ -122,14 +122,6 @@ public class RawConfigUIComponent extends UIComponentBase { configPathList.add(raw.getPath()); rawMap.put(raw.getPath(), raw); } - - if (rawMap.isEmpty()) { - RawConfiguration raw = new RawConfiguration(); - raw.setContentString(""); - raw.setPath(""); - rawMap.put("", raw); - } - Collections.sort(configPathList); String oldDirname = ""; for (String s : configPathList) { @@ -148,11 +140,12 @@ public class RawConfigUIComponent extends UIComponentBase { FacesComponentUtility.addParameter(link, idFactory, "showRaw", Boolean.TRUE.toString()); readOnlyParms.add(FacesComponentUtility.addParameter(link, idFactory, AbstractConfigurationComponent.READ_ONLY_ATTRIBUTE, Boolean.toString(readOnly))); + }
UIPanel panelRight = FacesComponentUtility.addBlockPanel(grid, idFactory, "summary-props-table");
- editPanel = FacesComponentUtility.addBlockPanel(panelRight, idFactory, "summary-props-table"); + UIPanel editPanel = FacesComponentUtility.addBlockPanel(panelRight, idFactory, "summary-props-table"); inputTextarea = new HtmlInputTextarea(); editPanel.getChildren().add(inputTextarea); inputTextarea.setParent(editPanel); @@ -164,8 +157,52 @@ public class RawConfigUIComponent extends UIComponentBase {
private HtmlOutputLink fullscreenLink; private UIParameter fullScreenResourceIdParam; - public HtmlCommandLink saveLink; - private UIPanel editPanel; + + private void addToolbar(ConfigurationDefinition configurationDefinition, UIPanel parent) { + UIPanel toolbarPanel = FacesComponentUtility.addBlockPanel(parent, idFactory, "config-toolbar"); + if (readOnly) { + HtmlCommandLink editLink = FacesComponentUtility.addCommandLink(toolbarPanel, idFactory); + FacesComponentUtility.addGraphicImage(editLink, idFactory, "/images/edit.png", "Edit"); + FacesComponentUtility.addOutputText(editLink, idFactory, "Edit", ""); + FacesComponentUtility.addParameter(editLink, idFactory, "showRaw", Boolean.TRUE.toString()); + FacesComponentUtility.addParameter(editLink, idFactory, AbstractConfigurationComponent.READ_ONLY_ATTRIBUTE, + Boolean.FALSE.toString()); + } else { + HtmlCommandLink saveLink = FacesComponentUtility.addCommandLink(toolbarPanel, idFactory); + FacesComponentUtility.addGraphicImage(saveLink, idFactory, "/images/save.png", "Save"); + FacesComponentUtility.addOutputText(saveLink, idFactory, "Save", ""); + FacesComponentUtility.addParameter(saveLink, idFactory, "showRaw", Boolean.FALSE.toString()); + FacesComponentUtility.addParameter(saveLink, idFactory, AbstractConfigurationComponent.READ_ONLY_ATTRIBUTE, + Boolean.TRUE.toString()); + } + { + fullscreenLink = FacesComponentUtility.addOutputLink(toolbarPanel, idFactory, "view-full.xhtml"); + FacesComponentUtility + .addGraphicImage(fullscreenLink, idFactory, "/images/viewfullscreen.png", "FullScreen"); + FacesComponentUtility.addOutputText(fullscreenLink, idFactory, "Full Screen", ""); + fullScreenResourceIdParam = FacesComponentUtility.addParameter(fullscreenLink, idFactory, "id", ""); + } + if (!readOnly) { + HtmlOutputLink uploadLink = FacesComponentUtility.addOutputLink(toolbarPanel, idFactory, "upload.xhtml"); + FacesComponentUtility.addGraphicImage(uploadLink, idFactory, "/images/upload.png", "Upload"); + FacesComponentUtility.addOutputText(uploadLink, idFactory, "Upload", ""); + } + { + HtmlOutputLink downloadLink = FacesComponentUtility + .addOutputLink(toolbarPanel, idFactory, "download.xhtml"); + FacesComponentUtility.addGraphicImage(downloadLink, idFactory, "/images/download.png", "download"); + FacesComponentUtility.addOutputText(downloadLink, idFactory, "Download", ""); + } + if (configurationDefinition.getConfigurationFormat().isStructuredSupported()) { + HtmlCommandLink toStructureLink = FacesComponentUtility.addCommandLink(toolbarPanel, idFactory); + FacesComponentUtility.addGraphicImage(toStructureLink, idFactory, "/images/structured.png", + "showStructured"); + FacesComponentUtility.addOutputText(toStructureLink, idFactory, "showStructured", ""); + FacesComponentUtility.addParameter(toStructureLink, idFactory, "showRaw", Boolean.FALSE.toString()); + readOnlyParms.add(FacesComponentUtility.addParameter(toStructureLink, idFactory, "readOnly", Boolean + .toString(readOnly))); + } + }
@Override public void encodeBegin(FacesContext context) throws IOException { diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ExistingResourceConfigurationUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ExistingResourceConfigurationUIBean.java index 44d005a..2f11e11 100644 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ExistingResourceConfigurationUIBean.java +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ExistingResourceConfigurationUIBean.java @@ -54,30 +54,6 @@ import org.rhq.enterprise.server.util.LookupUtil; public class ExistingResourceConfigurationUIBean extends AbstractConfigurationUIBean { public static final String MANAGED_BEAN_NAME = "ExistingResourceConfigurationUIBean";
- Boolean showRawConfig; - - public Boolean getShowRawConfig() { - if (null == showRawConfig) { - showRawConfig = this.getConfigurationDefinition().getConfigurationFormat().equals(ConfigurationFormat.RAW); - } - - return showRawConfig; - } - - public void setShowRawConfig(Boolean showRawConfig) { - this.showRawConfig = showRawConfig; - } - - public Boolean getShowRawButton() { - return !getShowRawConfig(); - //&& getConfigurationDefinition().getConfigurationFormat().equals(ConfigurationFormat.STRUCTURED_AND_RAW); - } - - public Boolean getShowStructuredButton() { - return getShowRawConfig(); - //&& getConfigurationDefinition().getConfigurationFormat().equals(ConfigurationFormat.STRUCTURED_AND_RAW); - } - private String selectedPath; private TreeMap<String, RawConfiguration> raws; private TreeMap<String, RawConfiguration> modified = new TreeMap<String, RawConfiguration>(); @@ -99,6 +75,15 @@ public class ExistingResourceConfigurationUIBean extends AbstractConfigurationUI return SUCCESS_OUTCOME; }
+ public String switchToRaw() { + ConfigurationMaskingUtility.unmaskConfiguration(getConfiguration(), getConfigurationDefinition()); + int resourceId = EnterpriseFacesContextUtility.getResource().getId(); + this.configurationManager.translateResourceConfiguration(EnterpriseFacesContextUtility.getSubject(), + resourceId, getConfiguration(), true); + + return SUCCESS_OUTCOME; + } + public String updateConfiguration() {
modified = null; @@ -358,53 +343,41 @@ public class ExistingResourceConfigurationUIBean extends AbstractConfigurationUI * But is kept as a target for the "action" value */ public String upload() { - return "/rhq/resource/configuration/edit.xhtml?currentResourceId=" + getResourceId(); + return "/rhq/resource/configuration/edit-raw.xhtml?currentResourceId=" + getResourceId(); }
- public String switchToRaw() { - - try { - Configuration configuration; - configuration = LookupUtil.getConfigurationManager().translateResourceConfiguration( - EnterpriseFacesContextUtility.getSubject(), getResourceId(), getMergedConfiguration(), true); + public String switchToraw() { + Configuration configuration = LookupUtil.getConfigurationManager().translateResourceConfiguration( + EnterpriseFacesContextUtility.getSubject(), getResourceId(), getMergedConfiguration(), true);
- setConfiguration(configuration); - for (RawConfiguration raw : configuration.getRawConfigurations()) { - getRaws().put(raw.getPath(), raw); - } - current = null; - setConfiguration(configuration); - - setShowRawConfig(true); - - return "edit.xhtml?showRaw="true"&id=" + getResourceId(); - } catch (Exception e) { - return "overview.xhtml"; + setConfiguration(configuration); + for (RawConfiguration raw : configuration.getRawConfigurations()) { + getRaws().put(raw.getPath(), raw); } + current = null; + setConfiguration(configuration); + + return "/rhq/resource/configuration/edit-raw.xhtml?currentResourceId=" + getResourceId(); }
- public String switchToStructured() { - try { - Configuration configuration = LookupUtil.getConfigurationManager().translateResourceConfiguration( - EnterpriseFacesContextUtility.getSubject(), getResourceId(), getMergedConfiguration(), false); + public String switchTostructured() {
- for (Property property : configuration.getAllProperties().values()) { - property.setConfiguration(configuration); - } + Configuration configuration = LookupUtil.getConfigurationManager().translateResourceConfiguration( + EnterpriseFacesContextUtility.getSubject(), getResourceId(), getMergedConfiguration(), false);
- for (RawConfiguration raw : configuration.getRawConfigurations()) { - getRaws().put(raw.getPath(), raw); - setConfiguration(configuration); - } - current = null; - setConfiguration(configuration); - setShowRawConfig(false); + for (Property property : configuration.getAllProperties().values()) { + property.setConfiguration(configuration); + }
- return "edit.xhtml?id=" + getResourceId(); - } catch (Exception e) { - return "overview.xhtml"; + for (RawConfiguration raw : configuration.getRawConfigurations()) { + getRaws().put(raw.getPath(), raw); + setConfiguration(configuration); } + current = null; + setConfiguration(configuration);
+// return "/rhq/resource/configuration/edit.xhtml?currentResourceId=" + getResourceId(); + return SUCCESS_OUTCOME; }
void populateRaws() { diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/test/AbstractTestConfigurationUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/test/AbstractTestConfigurationUIBean.java index f1ff041..4bbd064 100644 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/test/AbstractTestConfigurationUIBean.java +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/test/AbstractTestConfigurationUIBean.java @@ -24,7 +24,6 @@ import java.util.UUID;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; - import org.rhq.core.domain.configuration.Configuration; import org.rhq.core.domain.configuration.Property; import org.rhq.core.domain.configuration.PropertySimple; @@ -37,8 +36,7 @@ import org.rhq.enterprise.gui.common.Outcomes; * @author Ian Springer */ public abstract class AbstractTestConfigurationUIBean { - public static final String[] LABELS = new String[] { "AAA", "ZZZ", "BBB", "YYY", "AAA", "AAA", "ZZZ", "ZZZ", "YYY", - "BBB" }; + public static final String [] LABELS = new String[] { "AAA", "ZZZ", "BBB", "YYY","AAA", "AAA", "ZZZ", "ZZZ", "YYY", "BBB"};
public static final int GROUP_SIZE = 100;
@@ -47,7 +45,8 @@ public abstract class AbstractTestConfigurationUIBean { private List<Property> properties; private ConfigurationSet configurationSet;
- protected AbstractTestConfigurationUIBean() { + protected AbstractTestConfigurationUIBean() + { this.configurationDefinition = TestConfigurationFactory.createConfigurationDefinition(); this.configuration = TestConfigurationFactory.createConfiguration(); List<ConfigurationSetMember> members = new ArrayList(GROUP_SIZE); @@ -59,8 +58,8 @@ public abstract class AbstractTestConfigurationUIBean { configuration.getSimple("Boolean").setStringValue(String.valueOf(i % 2 == 0)); if (i == 0) configuration.getMap("OpenMapOfSimples").put(new PropertySimple("PROCESSOR_CORES", "4")); - ConfigurationSetMember memberInfo = new ConfigurationSetMember(LABELS[GROUP_SIZE % LABELS.length], - configuration); + ConfigurationSetMember memberInfo = + new ConfigurationSetMember(LABELS[GROUP_SIZE % LABELS.length], configuration); members.add(memberInfo); } this.configurationSet = new ConfigurationSet(this.configurationDefinition, members); @@ -77,7 +76,8 @@ public abstract class AbstractTestConfigurationUIBean { return this.configurationDefinition; }
- public void setConfigurationDefinition(@NotNull ConfigurationDefinition configurationDefinition) { + public void setConfigurationDefinition(@NotNull + ConfigurationDefinition configurationDefinition) { this.configurationDefinition = configurationDefinition; }
@@ -86,26 +86,26 @@ public abstract class AbstractTestConfigurationUIBean { return this.configuration; }
- public void setConfiguration(@NotNull Configuration configuration) { + public void setConfiguration(@NotNull + Configuration configuration) { this.configuration = configuration; }
- public ConfigurationSet getConfigurationSet() { + public ConfigurationSet getConfigurationSet() + { return configurationSet; }
- public void setConfigurationSet(ConfigurationSet configurationSet) { + public void setConfigurationSet(ConfigurationSet configurationSet) + { this.configurationSet = configurationSet; }
- public List<Property> getProperties() { + public List<Property> getProperties() + { return this.properties; }
- public void setProperties(@NotNull List<Property> properties) { - this.properties = properties; - } - public String getNullConfigurationDefinitionMessage() { return "Test config def is null (should never happen)."; } diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-managed-beans/test-beans.xml b/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-managed-beans/test-beans.xml index fbfad37..3ec6058 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-managed-beans/test-beans.xml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-managed-beans/test-beans.xml @@ -17,14 +17,6 @@ </managed-bean>
<managed-bean> - <managed-bean-name>RawTestConfigurationUIBean</managed-bean-name> - <managed-bean-class>org.rhq.enterprise.gui.configuration.test.RawTestConfigurationUIBean</managed-bean-class> - <managed-bean-scope>session</managed-bean-scope> - </managed-bean> - - - - <managed-bean> <managed-bean-name>AddNewOpenMapMemberPropertyToTestConfigurationUIBean</managed-bean-name> <managed-bean-class> org.rhq.enterprise.gui.configuration.test.EditTestConfigurationAddNewOpenMapMemberPropertyUIBean diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit.xhtml index 228e612..dffd02b 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit.xhtml @@ -31,47 +31,19 @@ THIS TEXT WILL BE REMOVED.
<h:form id="editResourceConfigurationForm" onsubmit="prepareInputsForSubmission(this)" rendered="#{!ViewResourceConfigurationUIBean.updateInProgress}">
- <input type="hidden" name="id" value="#{ResourceUIBean.id}"/> - - <h:panelGroup> - <h:commandLink action="#{ExistingResourceConfigurationUIBean.updateConfiguration}"> - <h:graphicImage value="Save" url="/images/save.png" /> - <h:outputText value="Save Junk" /> - <f:param name="showRaw" value="true"/> - </h:commandLink> - - <h:commandLink rendered="#{ExistingResourceConfigurationUIBean.showRawButton}" action="#{ExistingResourceConfigurationUIBean.switchToRaw}" > - <h:graphicImage value="Raw" url="/images/raw.png" /> - <h:outputText value="Raw " /> - </h:commandLink> - - <h:commandLink rendered="#{ExistingResourceConfigurationUIBean.showStructuredButton}" action="#{ExistingResourceConfigurationUIBean.switchToStructured}"> - <h:graphicImage value="Structured" url="/images/structured.png" /> - <h:outputText value="Structured " /> - <f:param name="showRaw" value="false"/> - </h:commandLink> - - <h:outputLink value="fullscreen.xhtml"> - <h:graphicImage value="Full Screen" url="/images/viewfullscreen.png" /> - <h:outputText value="Full Screen" /> - <f:param name="showRaw" value="true"/> - </h:outputLink> - - <h:outputLink value="download.xhtml"> - <h:graphicImage value="Download" url="/images/download.png" /> - <h:outputText value="Download " /> - <f:param name="showRaw" value="false"/> - </h:outputLink> - - <h:outputLink value="upload.xhtml" rendered="#{!showReadOnly}"> - <h:graphicImage value="Upload" url="/images/upload.png" /> - <h:outputText value="Upload " /> - <f:param name="showRaw" value="false"/> - </h:outputLink> - - - </h:panelGroup> - + + <input type="hidden" name="id" value="#{ResourceUIBean.id}"/> + + <h:outputText value="#{messages.youareviewingstructured}" /> + + <h:panelGroup rendered="#{ExistingResourceConfigurationUIBean.rawSupported}" > + <h:outputText value=" #{messages.switch2}" /> + <h:commandLink action="#{ExistingResourceConfigurationUIBean.switchToraw}" > + <f:param name="conversationId" value="#{conversation.id}"/> + <f:param name="id" value="#{ResourceUIBean.id}"/> + <h:outputText value=" files mode"/> + </h:commandLink> + </h:panelGroup> <onc:config configurationDefinition="#{ExistingResourceConfigurationUIBean.configurationDefinition}" configuration="#{ExistingResourceConfigurationUIBean.configuration}" @@ -80,7 +52,6 @@ THIS TEXT WILL BE REMOVED. prevalidate="true" showToolbar="true" readOnly="false" - action="#{ExistingResourceConfigurationUIBean.updateRawConfiguration}" />
<h:panelGrid columns="2" styleClass="buttons-table" columnClasses="button-cell" rendered="#{ExistingResourceConfigurationUIBean.configuration != null}"> diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml index ea44edd..40a917d 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml @@ -41,56 +41,20 @@ THIS TEXT WILL BE REMOVED. </h:panelGroup>
+ <h:outputText value=" #{messages.nopermissionedit}" rendered="#{!ResourceUIBean.permissions.configure}"/> + <h:form id="viewResourceConfigurationForm"> <!-- TODO remove the id version --> <input type="hidden" name="id" value="#{ResourceUIBean.id}"/> - - <ui:include src="/WEB-INF/fragments/config-view-toolbar.xhtml" /> - - <h:panelGroup> - <h:outputLink value="edit.xhtml"> - <h:graphicImage value="Edit" url="/images/edit.png" /> - <h:outputText value="Edit " /> - <f:param name="showRaw" value="#{showRawConfig}"/> - <f:param name="id" value="#{ResourceUIBean.id}"/> - </h:outputLink> - - <h:commandLink rendered="#{ExistingResourceConfigurationViewUIBean.showRawButton}"> - <h:graphicImage value="Raw" url="/images/raw.png" /> - <h:outputText value="Raw " /> - <f:param name="showRaw" value="true"/> - </h:commandLink> - - <h:commandLink rendered="#{ExistingResourceConfigurationViewUIBean.showStructuredButton}"> - <h:graphicImage value="Structured" url="/images/structured.png" /> - <h:outputText value="Structured " /> - <f:param name="showRaw" value="false"/> - </h:commandLink> - - <h:commandLink rendered="#{showRawConfig}"> - <h:graphicImage value="Full Screen" url="/images/viewfullscreen.png" /> - <h:outputText value="Full Screen" /> - <f:param name="showRaw" value="true"/> - </h:commandLink> - - <h:outputLink value="download.xhtml" rendered="#{showRawConfig}"> - <h:graphicImage value="Download" url="/images/download.png" /> - <h:outputText value="Download " /> - </h:outputLink> - - </h:panelGroup> - - - - + <onc:config configurationDefinition="#{ExistingResourceConfigurationViewUIBean.configurationDefinition}" configuration="#{ExistingResourceConfigurationViewUIBean.configuration}" accessMapActionExpression="#{ExistingResourceConfigurationViewUIBean.accessMap}" nullConfigurationDefinitionMessage="#{ExistingResourceConfigurationViewUIBean.nullConfigurationDefinitionMessage}" nullConfigurationMessage="#{ExistingResourceConfigurationViewUIBean.nullConfigurationMessage}" readOnly="true" - prevalidate="true" - /> + showToolbar="true" + prevalidate="true"/> <input type="hidden" name="id" value="#{ResourceUIBean.id}"/>
</h:form> diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/test/config/edit.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/test/config/edit.xhtml index da51088..1e4c156 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/test/config/edit.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/test/config/edit.xhtml @@ -37,7 +37,7 @@ THIS TEXT WILL BE REMOVED. accessMapActionExpression="#{RawTestConfigurationUIBean.accessMap}" readOnly="true" /> <h:panelGrid columns="1" styleClass="buttons-table" columnClasses="button-cell"> - <h:commandButton type="submit" action="#{RawTestConfigurationUIBean.updateConfiguration}" + <h:commandButton type="submit" action="#{RawTestConfigurationUIBean.editConfiguration}" value="Edit this Configuration"/> </h:panelGrid> </h:form>
commit 8215954aefb1a23e492cbcaee04d628d247349ec Author: Adam Young ayoung@redhat.com Date: Fri Dec 18 10:37:49 2009 -0500
added toolbar in xhtml, removed it from tests, still broken
diff --git a/.classpath b/.classpath index a3aef1e..e53c4a4 100644 --- a/.classpath +++ b/.classpath @@ -189,7 +189,7 @@ <classpathentry exported="true" kind="var" path="M2_REPO/org/json/json/20080701/json-20080701.jar"/> <classpathentry exported="true" kind="var" path="M2_REPO/com/sun/jna/jna/3.0.1/jna-3.0.1.jar"/> <classpathentry exported="true" kind="var" path="M2_REPO/org/freemarker/freemarker/2.3.11/freemarker-2.3.11.jar"/> - <classpathentry exported="true" kind="var" path="M2_REPO/org/jboss/seam/jboss-seam/2.1.0.SP1/jboss-seam-2.1.0.SP1.jar"/> + <classpathentry exported="true" kind="var" path="M2_REPO/org/jboss/seam/jboss-seam/2.1.0.SP1/jboss-seam-2.1.0.SP1.jar" sourcepath="/M2_REPO/org/jboss/seam/jboss-seam/2.1.0.SP1/jboss-seam-2.1.0.SP1-sources.jar"/> <classpathentry exported="true" kind="var" path="M2_REPO/org/jboss/seam/jboss-seam-ui/2.1.0.SP1/jboss-seam-ui-2.1.0.SP1.jar"/> <classpathentry exported="true" kind="var" path="M2_REPO/hibernate/hibernate3/3.2.r14201-2/hibernate3-3.2.r14201-2.jar"/> <classpathentry exported="true" kind="var" path="M2_REPO/jline/jline/0.9.94/jline-0.9.94.jar"/> diff --git a/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/AbstractConfigurationComponent.java b/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/AbstractConfigurationComponent.java index e49ead1..5d5f894 100644 --- a/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/AbstractConfigurationComponent.java +++ b/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/AbstractConfigurationComponent.java @@ -24,6 +24,7 @@ package org.rhq.core.gui.configuration;
import java.util.UUID;
+import javax.el.ValueExpression; import javax.faces.component.UIComponent; import javax.faces.component.UIComponentBase; import javax.faces.context.FacesContext; @@ -59,6 +60,7 @@ public abstract class AbstractConfigurationComponent extends UIComponentBase imp private Boolean fullyEditable; private String listName; private Integer listIndex; + RawConfigUIComponent rawConfigUIComponent;
public UIComponent getToolbar() { return toolbar; @@ -87,6 +89,16 @@ public abstract class AbstractConfigurationComponent extends UIComponentBase imp
public abstract String getConfigurationExpressionString();
+ private ValueExpression saveValueExpression; + + public ValueExpression getSaveValueExpression() { + return saveValueExpression; + } + + public void setSaveValueExpression(ValueExpression saveValueExpression) { + this.saveValueExpression = saveValueExpression; + } + public String createUniqueId() { return UNIQUE_ID_PREFIX + UUID.randomUUID(); } @@ -215,10 +227,12 @@ public abstract class AbstractConfigurationComponent extends UIComponentBase imp
private Object[] stateValues;
+ public StructuredConfigUIComponent structuredConfig; + @Override public Object saveState(FacesContext facesContext) { if (this.stateValues == null) { - this.stateValues = new Object[8]; + this.stateValues = new Object[12]; }
this.stateValues[0] = super.saveState(facesContext); @@ -229,6 +243,12 @@ public abstract class AbstractConfigurationComponent extends UIComponentBase imp this.stateValues[5] = this.prevalidate; this.stateValues[6] = this.isGroup; this.stateValues[7] = this.getShowToolbar(); + if (rawConfigUIComponent != null) { + this.stateValues[8] = this.rawConfigUIComponent; + this.stateValues[9] = structuredConfig; + this.stateValues[10] = this.rawConfigUIComponent.saveState(facesContext); + this.stateValues[11] = this.structuredConfig.saveState(facesContext); + } return this.stateValues; }
@@ -243,20 +263,33 @@ public abstract class AbstractConfigurationComponent extends UIComponentBase imp this.prevalidate = (Boolean) this.stateValues[5]; this.isGroup = (Boolean) this.stateValues[6]; this.showToolbar = (Boolean) this.stateValues[7]; + + this.rawConfigUIComponent = (RawConfigUIComponent) this.stateValues[8]; + this.structuredConfig = (StructuredConfigUIComponent) this.stateValues[9]; + + if (this.rawConfigUIComponent != null) { + this.rawConfigUIComponent.restoreState(facesContext, this.stateValues[10]); + } + if (this.structuredConfig != null) { + this.structuredConfig.restoreState(facesContext, this.stateValues[11]); + } + + //getChildren().add(structuredConfig); + //getChildren().add(rawConfigUIComponent); + }
public boolean getShouldShowRaw() { return Boolean.valueOf(FacesContextUtility.getOptionalRequestParameter("showRaw", String.class, "unset")) - || (this.getConfigurationDefinition().getConfigurationFormat().equals(ConfigurationFormat.RAW)); + && (!this.getConfigurationDefinition().getConfigurationFormat().equals(ConfigurationFormat.STRUCTURED)); }
- RawConfigUIComponent rawConfigUIComponent; - RawConfigUIComponent getRawConfigUIComponent() { if (null == rawConfigUIComponent) { rawConfigUIComponent = new RawConfigUIComponent(getConfiguration(), getConfigurationDefinition(), this, isReadOnly()); } + return rawConfigUIComponent; }
diff --git a/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/ConfigRenderer.java b/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/ConfigRenderer.java index 278d619..be2feac 100644 --- a/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/ConfigRenderer.java +++ b/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/ConfigRenderer.java @@ -26,16 +26,12 @@ import java.io.IOException; import java.util.List; import java.util.Map;
-import javax.el.MethodExpression; import javax.el.ValueExpression; import javax.faces.application.FacesMessage; import javax.faces.component.UIComponent; import javax.faces.component.UIForm; import javax.faces.component.UIInput; -import javax.faces.component.UIOutput; -import javax.faces.component.UIPanel; import javax.faces.component.UIParameter; -import javax.faces.component.html.HtmlCommandLink; import javax.faces.component.html.HtmlForm; import javax.faces.component.html.HtmlOutputLink; import javax.faces.component.html.HtmlPanelGrid; @@ -51,18 +47,15 @@ import org.ajax4jsf.context.AjaxContext; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.richfaces.component.html.HtmlModalPanel; -import org.richfaces.component.html.HtmlSimpleTogglePanel;
import org.rhq.core.clientapi.agent.configuration.ConfigurationUtility; 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.configuration.definition.ConfigurationFormat; import org.rhq.core.domain.configuration.definition.PropertyDefinition; import org.rhq.core.domain.configuration.definition.PropertyDefinitionMap; import org.rhq.core.domain.configuration.definition.PropertyDefinitionSimple; -import org.rhq.core.domain.configuration.definition.PropertyGroupDefinition; import org.rhq.core.gui.RequestParameterNameConstants; import org.rhq.core.gui.configuration.helper.PropertyRenderingUtility; import org.rhq.core.gui.configuration.propset.ConfigurationSetComponent; @@ -184,7 +177,9 @@ public class ConfigRenderer extends Renderer { addChildComponents(configurationComponent); if (configurationComponent.getToolbar() != null) { configurationComponent.getToolbar().setRendered(configurationComponent.getShowToolbar()); + } + }
private boolean isAjaxRefresh(AbstractConfigurationComponent configurationComponent) { @@ -270,113 +265,20 @@ public class ConfigRenderer extends Renderer { } }
- Boolean shouldShowRawNow = configurationComponent.getShouldShowRaw(); - - if (shouldShowRawNow) { - configurationComponent.getChildren().add( - new RawConfigUIComponent(configurationComponent.getConfiguration(), configurationComponent - .getConfigurationDefinition(), configurationComponent, configurationComponent.isReadOnly())); - } else { - addStructuredConfig(configurationComponent); - } - } - - private void addStructuredConfig(AbstractConfigurationComponent configurationComponent) { - { - UIPanel toolbarPanel = FacesComponentUtility.addBlockPanel(configurationComponent, configurationComponent, - "summary-props-table"); - if (configurationComponent.isReadOnly()) { - HtmlOutputLink editLink = FacesComponentUtility.addOutputLink(toolbarPanel, configurationComponent, - "edit.xhtml"); - FacesComponentUtility.addGraphicImage(editLink, configurationComponent, "/images/edit.png", "Edit"); - FacesComponentUtility.addOutputText(editLink, configurationComponent, "Edit", ""); - FacesComponentUtility.addParameter(editLink, configurationComponent, "readOnly", Boolean - .toString(false)); - FacesComponentUtility.addParameter(editLink, configurationComponent, "id", FacesContextUtility - .getRequiredRequestParameter("id")); - } else { - HtmlCommandLink saveLink = FacesComponentUtility.addCommandLink(toolbarPanel, configurationComponent); - FacesComponentUtility.addGraphicImage(saveLink, configurationComponent, "/images/save.png", "Save"); - FacesComponentUtility.addOutputText(saveLink, configurationComponent, "Save", ""); - FacesComponentUtility.addParameter(saveLink, configurationComponent, "save", Boolean.toString(true)); - FacesComponentUtility - .addParameter(saveLink, configurationComponent, "readOnly", Boolean.toString(true)); - - saveLink.setActionExpression(getSaveActionExpression()); - - } - if (configurationComponent.getConfigurationDefinition().getConfigurationFormat().isRawSupported()) { - HtmlCommandLink toRawLink = FacesComponentUtility.addCommandLink(toolbarPanel, configurationComponent); - FacesComponentUtility.addGraphicImage(toRawLink, configurationComponent, "/images/raw.png", "showRaw"); - FacesComponentUtility.addOutputText(toRawLink, configurationComponent, "showRaw", ""); - FacesComponentUtility.addParameter(toRawLink, configurationComponent, "showRaw", Boolean.TRUE - .toString()); - FacesComponentUtility.addParameter(toRawLink, configurationComponent, "readOnly", Boolean - .toString(configurationComponent.isReadOnly())); - } - configurationComponent.setToolbar(toolbarPanel); - } - - if (!configurationComponent.isReadOnly()) - addRequiredNotationsKey(configurationComponent); - - if (configurationComponent.getListName() != null) { - if (configurationComponent.getListIndex() == null) { - // No index specified means we should add a new map to the list. - configurationComponent.setListIndex(addNewMap(configurationComponent)); - } - - addListMemberProperty(configurationComponent); - } else { - addConfiguration(configurationComponent); - } - - String id = getInitInputsJavaScriptComponentId(configurationComponent); - PropertyRenderingUtility.addInitInputsJavaScript(configurationComponent, id, configurationComponent - .isFullyEditable(), false); - } - - private MethodExpression getSaveActionExpression() { - - MethodExpression actionExpression = null; - - return actionExpression; - } - - private void addStructuredRawToggle(AbstractConfigurationComponent configurationComponent, boolean showRaw) { - if (configurationComponent.getConfigurationDefinition().getConfigurationFormat().equals( - ConfigurationFormat.STRUCTURED_AND_RAW)) { + configurationComponent.rawConfigUIComponent = new RawConfigUIComponent(configurationComponent + .getConfiguration(), configurationComponent.getConfigurationDefinition(), configurationComponent, + configurationComponent.isReadOnly());
- HtmlPanelGroup toRawLinkPanel = FacesComponentUtility.addBlockPanel(configurationComponent, - configurationComponent, UNGROUPED_PROPERTIES_STYLE_CLASS); + configurationComponent.getChildren().add(configurationComponent.rawConfigUIComponent);
- FacesComponentUtility.addOutputText(toRawLinkPanel, configurationComponent, - "internationalized Message goes here", UNGROUPED_PROPERTIES_STYLE_CLASS); + configurationComponent.structuredConfig = new StructuredConfigUIComponent(configurationComponent);
- HtmlCommandLink commandLink = FacesComponentUtility.addCommandLink(toRawLinkPanel, configurationComponent); + configurationComponent.getChildren().add(configurationComponent.structuredConfig);
- UIOutput output = new UIOutput(); - output.setValue(showRaw ? "Show Structured" : " Show Raw"); - commandLink.getChildren().add(output); - //output.setParent(commandLink); - FacesComponentUtility.addParameter(commandLink, configurationComponent, "showRaw", Boolean - .toString(!showRaw)); - } - } - - private void addListMemberProperty(AbstractConfigurationComponent configurationComponent) { - // Update member Configurations if this is a group config. - if (configurationComponent instanceof ConfigurationSetComponent) { - ConfigurationSetComponent configurationSetComponent = ((ConfigurationSetComponent) configurationComponent); - configurationSetComponent.getConfigurationSet().applyGroupConfiguration(); - } + Boolean shouldShowRawNow = configurationComponent.getShouldShowRaw();
- // Now add a new component to the JSF component tree. - AbstractPropertyBagUIComponentTreeFactory propertyListUIComponentTreeFactory = new MapInListUIComponentTreeFactory( - configurationComponent, configurationComponent.getListName(), configurationComponent.getListIndex()); - HtmlPanelGroup propertiesPanel = FacesComponentUtility.addBlockPanel(configurationComponent, - configurationComponent, UNGROUPED_PROPERTIES_STYLE_CLASS); - propertiesPanel.getChildren().add(propertyListUIComponentTreeFactory.createUIComponentTree(null)); + configurationComponent.rawConfigUIComponent.setRendered(shouldShowRawNow); + configurationComponent.structuredConfig.setRendered(!shouldShowRawNow); }
private void deleteListMemberProperty(AbstractConfigurationComponent configurationComponent) { @@ -482,83 +384,6 @@ public class ConfigRenderer extends Renderer { + mapName + "'."); }
- private static void addRequiredNotationsKey(AbstractConfigurationComponent config) { - addDebug(config, true, ".addNotePanel()"); - HtmlPanelGroup footnotesPanel = FacesComponentUtility.addBlockPanel(config, config, NOTE_PANEL_STYLE_CLASS); - FacesComponentUtility.addOutputText(footnotesPanel, config, "*", REQUIRED_MARKER_TEXT_STYLE_CLASS); - FacesComponentUtility.addOutputText(footnotesPanel, config, " denotes a required field.", - FacesComponentUtility.NO_STYLE_CLASS); - if (config.isGroup()) { - HtmlPanelGroup overridePanel = FacesComponentUtility.addBlockPanel(config, config, NOTE_PANEL_STYLE_CLASS); - FacesComponentUtility.addOutputText(overridePanel, config, - "note: if override is not checked, that property will not be altered on any group members", - FacesComponentUtility.NO_STYLE_CLASS); - } - - addDebug(config, false, ".addNotePanel()"); - } - - private void addConfiguration(AbstractConfigurationComponent config) { - addNonGroupedProperties(config); - addGroupedProperties(config); - } - - private void addNonGroupedProperties(AbstractConfigurationComponent config) { - addDebug(config, true, ".addNonGroupedProperties()"); - HtmlPanelGroup propertiesPanel = FacesComponentUtility.addBlockPanel(config, config, - UNGROUPED_PROPERTIES_STYLE_CLASS); - AbstractPropertyBagUIComponentTreeFactory propertyListUIComponentTreeFactory = new GroupUIComponentTreeFactory( - config, GroupUIComponentTreeFactory.NO_GROUP); - propertiesPanel.getChildren().add(propertyListUIComponentTreeFactory.createUIComponentTree(null)); - addDebug(config, false, ".addNonGroupedProperties()"); - } - - private void addGroupedProperties(AbstractConfigurationComponent config) { - addDebug(config, true, ".addGroupedProperties()"); - List<PropertyGroupDefinition> groups = config.getConfigurationDefinition().getGroupDefinitions(); - for (PropertyGroupDefinition group : groups) { - HtmlSimpleTogglePanel groupPanel = addGroupPanel(config, group); - AbstractPropertyBagUIComponentTreeFactory propertyListUIComponentTreeFactory = new GroupUIComponentTreeFactory( - config, group.getName()); - groupPanel.getChildren().add(propertyListUIComponentTreeFactory.createUIComponentTree(null)); - } - - addDebug(config, false, ".addGroupedProperties()"); - } - - private HtmlSimpleTogglePanel addGroupPanel(AbstractConfigurationComponent config, PropertyGroupDefinition group) { - addDebug(config, true, ".addGroupPanel()"); - HtmlSimpleTogglePanel groupPanel = FacesComponentUtility.addSimpleTogglePanel(config, config, null); - // TODO: On AJAX requests, set "opened" attribute to its previous state. - groupPanel.setOpened(!group.isDefaultHidden()); - groupPanel.setHeaderClass(PROPERTY_GROUP_HEADER_STYLE_CLASS); - groupPanel.setBodyClass(PROPERTY_GROUP_BODY_STYLE_CLASS); - - // Custom header that includes the name and description - HtmlPanelGroup headerPanel = FacesComponentUtility.createBlockPanel(config, null); - FacesComponentUtility.addOutputText(headerPanel, config, group.getDisplayName(), null); - FacesComponentUtility - .addOutputText(headerPanel, config, group.getDescription(), "group-description-text-panel"); - groupPanel.getFacets().put("header", headerPanel); - - // custom "close" widget - HtmlPanelGroup closePanel = FacesComponentUtility.createBlockPanel(config, null); - closePanel.setStyle("text-align: right; font-weight: normal; font-size: 0.8em; whitespace: nowrap;"); - FacesComponentUtility.addGraphicImage(closePanel, config, "/images/ico_trigger_wht_collapse.gif", "collapse"); - FacesComponentUtility.addOutputText(closePanel, config, " Collapse", null); - groupPanel.getFacets().put("closeMarker", closePanel); - - // custom "open" widget - HtmlPanelGroup openPanel = FacesComponentUtility.createBlockPanel(config, null); - openPanel.setStyle("text-align: right; font-weight: normal; font-size: 0.8em; whitespace: nowrap;"); - FacesComponentUtility.addGraphicImage(openPanel, config, "/images/ico_trigger_wht_expand.gif", "expand"); - FacesComponentUtility.addOutputText(openPanel, config, " Expand", null); - groupPanel.getFacets().put("openMarker", openPanel); - addDebug(config, true, ".addGroupPanel()"); - - return groupPanel; - } - private void validateAttributes(AbstractConfigurationComponent configurationComponent) { // TODO: Add back attribute validation - remember config and configSet components require different attributes. /*if (configurationComponent.getValueExpression("configurationDefinition") == null) { @@ -572,7 +397,7 @@ public class ConfigRenderer extends Renderer { }*/ }
- private int addNewMap(AbstractConfigurationComponent config) { + static int addNewMap(AbstractConfigurationComponent config) { String listName = config.getListName(); PropertyDefinitionMap mapDefinition = (PropertyDefinitionMap) config.getConfigurationDefinition() .getPropertyDefinitionList(listName).getMemberDefinition(); @@ -597,7 +422,7 @@ public class ConfigRenderer extends Renderer { * @param start true if this is the "START" comment, false if it is the "END" comment * @param methodName the name of the method this is calling from */ - private static void addDebug(UIComponent component, boolean start, String methodName) { + static void addDebug(UIComponent component, boolean start, String methodName) { if (LOG.isDebugEnabled()) { StringBuilder msg = new StringBuilder("\n<!--"); msg.append(start ? " START " : " END "); @@ -608,7 +433,7 @@ public class ConfigRenderer extends Renderer { } }
- private String getInitInputsJavaScriptComponentId(AbstractConfigurationComponent configUIComponent) { + static String getInitInputsJavaScriptComponentId(AbstractConfigurationComponent configUIComponent) { return configUIComponent.getId() + INIT_INPUTS_JAVA_SCRIPT_COMPONENT_ID_SUFFIX; }
diff --git a/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/RawConfigUIComponent.java b/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/RawConfigUIComponent.java index 2c9a1be..5b86352 100644 --- a/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/RawConfigUIComponent.java +++ b/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/RawConfigUIComponent.java @@ -34,7 +34,7 @@ public class RawConfigUIComponent extends UIComponentBase { super.decode(context); setSelectedPath(FacesContextUtility.getOptionalRequestParameter("path")); readOnly = Boolean.valueOf(FacesContextUtility.getOptionalRequestParameter("readOnly")); - + this.inputTextarea.decode(context); }
@Override @@ -99,7 +99,7 @@ public class RawConfigUIComponent extends UIComponentBase {
UIPanel rawPanel = FacesComponentUtility.addBlockPanel(this, idFactory, "");
- addToolbar(configurationDefinition, rawPanel); + //addToolbar(configurationDefinition, rawPanel);
HtmlPanelGrid grid = FacesComponentUtility.addPanelGrid(rawPanel, idFactory, "summary-props-table"); grid.setParent(this); @@ -122,6 +122,14 @@ public class RawConfigUIComponent extends UIComponentBase { configPathList.add(raw.getPath()); rawMap.put(raw.getPath(), raw); } + + if (rawMap.isEmpty()) { + RawConfiguration raw = new RawConfiguration(); + raw.setContentString(""); + raw.setPath(""); + rawMap.put("", raw); + } + Collections.sort(configPathList); String oldDirname = ""; for (String s : configPathList) { @@ -140,12 +148,11 @@ public class RawConfigUIComponent extends UIComponentBase { FacesComponentUtility.addParameter(link, idFactory, "showRaw", Boolean.TRUE.toString()); readOnlyParms.add(FacesComponentUtility.addParameter(link, idFactory, AbstractConfigurationComponent.READ_ONLY_ATTRIBUTE, Boolean.toString(readOnly))); - }
UIPanel panelRight = FacesComponentUtility.addBlockPanel(grid, idFactory, "summary-props-table");
- UIPanel editPanel = FacesComponentUtility.addBlockPanel(panelRight, idFactory, "summary-props-table"); + editPanel = FacesComponentUtility.addBlockPanel(panelRight, idFactory, "summary-props-table"); inputTextarea = new HtmlInputTextarea(); editPanel.getChildren().add(inputTextarea); inputTextarea.setParent(editPanel); @@ -157,52 +164,8 @@ public class RawConfigUIComponent extends UIComponentBase {
private HtmlOutputLink fullscreenLink; private UIParameter fullScreenResourceIdParam; - - private void addToolbar(ConfigurationDefinition configurationDefinition, UIPanel parent) { - UIPanel toolbarPanel = FacesComponentUtility.addBlockPanel(parent, idFactory, "config-toolbar"); - if (readOnly) { - HtmlCommandLink editLink = FacesComponentUtility.addCommandLink(toolbarPanel, idFactory); - FacesComponentUtility.addGraphicImage(editLink, idFactory, "/images/edit.png", "Edit"); - FacesComponentUtility.addOutputText(editLink, idFactory, "Edit", ""); - FacesComponentUtility.addParameter(editLink, idFactory, "showRaw", Boolean.TRUE.toString()); - FacesComponentUtility.addParameter(editLink, idFactory, AbstractConfigurationComponent.READ_ONLY_ATTRIBUTE, - Boolean.FALSE.toString()); - } else { - HtmlCommandLink saveLink = FacesComponentUtility.addCommandLink(toolbarPanel, idFactory); - FacesComponentUtility.addGraphicImage(saveLink, idFactory, "/images/save.png", "Save"); - FacesComponentUtility.addOutputText(saveLink, idFactory, "Save", ""); - FacesComponentUtility.addParameter(saveLink, idFactory, "showRaw", Boolean.FALSE.toString()); - FacesComponentUtility.addParameter(saveLink, idFactory, AbstractConfigurationComponent.READ_ONLY_ATTRIBUTE, - Boolean.TRUE.toString()); - } - { - fullscreenLink = FacesComponentUtility.addOutputLink(toolbarPanel, idFactory, "view-full.xhtml"); - FacesComponentUtility - .addGraphicImage(fullscreenLink, idFactory, "/images/viewfullscreen.png", "FullScreen"); - FacesComponentUtility.addOutputText(fullscreenLink, idFactory, "Full Screen", ""); - fullScreenResourceIdParam = FacesComponentUtility.addParameter(fullscreenLink, idFactory, "id", ""); - } - if (!readOnly) { - HtmlOutputLink uploadLink = FacesComponentUtility.addOutputLink(toolbarPanel, idFactory, "upload.xhtml"); - FacesComponentUtility.addGraphicImage(uploadLink, idFactory, "/images/upload.png", "Upload"); - FacesComponentUtility.addOutputText(uploadLink, idFactory, "Upload", ""); - } - { - HtmlOutputLink downloadLink = FacesComponentUtility - .addOutputLink(toolbarPanel, idFactory, "download.xhtml"); - FacesComponentUtility.addGraphicImage(downloadLink, idFactory, "/images/download.png", "download"); - FacesComponentUtility.addOutputText(downloadLink, idFactory, "Download", ""); - } - if (configurationDefinition.getConfigurationFormat().isStructuredSupported()) { - HtmlCommandLink toStructureLink = FacesComponentUtility.addCommandLink(toolbarPanel, idFactory); - FacesComponentUtility.addGraphicImage(toStructureLink, idFactory, "/images/structured.png", - "showStructured"); - FacesComponentUtility.addOutputText(toStructureLink, idFactory, "showStructured", ""); - FacesComponentUtility.addParameter(toStructureLink, idFactory, "showRaw", Boolean.FALSE.toString()); - readOnlyParms.add(FacesComponentUtility.addParameter(toStructureLink, idFactory, "readOnly", Boolean - .toString(readOnly))); - } - } + public HtmlCommandLink saveLink; + private UIPanel editPanel;
@Override public void encodeBegin(FacesContext context) throws IOException { diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ExistingResourceConfigurationUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ExistingResourceConfigurationUIBean.java index 2f11e11..44d005a 100644 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ExistingResourceConfigurationUIBean.java +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ExistingResourceConfigurationUIBean.java @@ -54,6 +54,30 @@ import org.rhq.enterprise.server.util.LookupUtil; public class ExistingResourceConfigurationUIBean extends AbstractConfigurationUIBean { public static final String MANAGED_BEAN_NAME = "ExistingResourceConfigurationUIBean";
+ Boolean showRawConfig; + + public Boolean getShowRawConfig() { + if (null == showRawConfig) { + showRawConfig = this.getConfigurationDefinition().getConfigurationFormat().equals(ConfigurationFormat.RAW); + } + + return showRawConfig; + } + + public void setShowRawConfig(Boolean showRawConfig) { + this.showRawConfig = showRawConfig; + } + + public Boolean getShowRawButton() { + return !getShowRawConfig(); + //&& getConfigurationDefinition().getConfigurationFormat().equals(ConfigurationFormat.STRUCTURED_AND_RAW); + } + + public Boolean getShowStructuredButton() { + return getShowRawConfig(); + //&& getConfigurationDefinition().getConfigurationFormat().equals(ConfigurationFormat.STRUCTURED_AND_RAW); + } + private String selectedPath; private TreeMap<String, RawConfiguration> raws; private TreeMap<String, RawConfiguration> modified = new TreeMap<String, RawConfiguration>(); @@ -75,15 +99,6 @@ public class ExistingResourceConfigurationUIBean extends AbstractConfigurationUI return SUCCESS_OUTCOME; }
- public String switchToRaw() { - ConfigurationMaskingUtility.unmaskConfiguration(getConfiguration(), getConfigurationDefinition()); - int resourceId = EnterpriseFacesContextUtility.getResource().getId(); - this.configurationManager.translateResourceConfiguration(EnterpriseFacesContextUtility.getSubject(), - resourceId, getConfiguration(), true); - - return SUCCESS_OUTCOME; - } - public String updateConfiguration() {
modified = null; @@ -343,41 +358,53 @@ public class ExistingResourceConfigurationUIBean extends AbstractConfigurationUI * But is kept as a target for the "action" value */ public String upload() { - return "/rhq/resource/configuration/edit-raw.xhtml?currentResourceId=" + getResourceId(); + return "/rhq/resource/configuration/edit.xhtml?currentResourceId=" + getResourceId(); }
- public String switchToraw() { - Configuration configuration = LookupUtil.getConfigurationManager().translateResourceConfiguration( - EnterpriseFacesContextUtility.getSubject(), getResourceId(), getMergedConfiguration(), true); + public String switchToRaw() {
- setConfiguration(configuration); - for (RawConfiguration raw : configuration.getRawConfigurations()) { - getRaws().put(raw.getPath(), raw); - } - current = null; - setConfiguration(configuration); + try { + Configuration configuration; + configuration = LookupUtil.getConfigurationManager().translateResourceConfiguration( + EnterpriseFacesContextUtility.getSubject(), getResourceId(), getMergedConfiguration(), true);
- return "/rhq/resource/configuration/edit-raw.xhtml?currentResourceId=" + getResourceId(); - } - - public String switchTostructured() { + setConfiguration(configuration); + for (RawConfiguration raw : configuration.getRawConfigurations()) { + getRaws().put(raw.getPath(), raw); + } + current = null; + setConfiguration(configuration);
- Configuration configuration = LookupUtil.getConfigurationManager().translateResourceConfiguration( - EnterpriseFacesContextUtility.getSubject(), getResourceId(), getMergedConfiguration(), false); + setShowRawConfig(true);
- for (Property property : configuration.getAllProperties().values()) { - property.setConfiguration(configuration); + return "edit.xhtml?showRaw="true"&id=" + getResourceId(); + } catch (Exception e) { + return "overview.xhtml"; } + }
- for (RawConfiguration raw : configuration.getRawConfigurations()) { - getRaws().put(raw.getPath(), raw); + public String switchToStructured() { + try { + Configuration configuration = LookupUtil.getConfigurationManager().translateResourceConfiguration( + EnterpriseFacesContextUtility.getSubject(), getResourceId(), getMergedConfiguration(), false); + + for (Property property : configuration.getAllProperties().values()) { + property.setConfiguration(configuration); + } + + for (RawConfiguration raw : configuration.getRawConfigurations()) { + getRaws().put(raw.getPath(), raw); + setConfiguration(configuration); + } + current = null; setConfiguration(configuration); + setShowRawConfig(false); + + return "edit.xhtml?id=" + getResourceId(); + } catch (Exception e) { + return "overview.xhtml"; } - current = null; - setConfiguration(configuration);
-// return "/rhq/resource/configuration/edit.xhtml?currentResourceId=" + getResourceId(); - return SUCCESS_OUTCOME; }
void populateRaws() { diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/test/AbstractTestConfigurationUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/test/AbstractTestConfigurationUIBean.java index 4bbd064..f1ff041 100644 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/test/AbstractTestConfigurationUIBean.java +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/test/AbstractTestConfigurationUIBean.java @@ -24,6 +24,7 @@ import java.util.UUID;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; + import org.rhq.core.domain.configuration.Configuration; import org.rhq.core.domain.configuration.Property; import org.rhq.core.domain.configuration.PropertySimple; @@ -36,7 +37,8 @@ import org.rhq.enterprise.gui.common.Outcomes; * @author Ian Springer */ public abstract class AbstractTestConfigurationUIBean { - public static final String [] LABELS = new String[] { "AAA", "ZZZ", "BBB", "YYY","AAA", "AAA", "ZZZ", "ZZZ", "YYY", "BBB"}; + public static final String[] LABELS = new String[] { "AAA", "ZZZ", "BBB", "YYY", "AAA", "AAA", "ZZZ", "ZZZ", "YYY", + "BBB" };
public static final int GROUP_SIZE = 100;
@@ -45,8 +47,7 @@ public abstract class AbstractTestConfigurationUIBean { private List<Property> properties; private ConfigurationSet configurationSet;
- protected AbstractTestConfigurationUIBean() - { + protected AbstractTestConfigurationUIBean() { this.configurationDefinition = TestConfigurationFactory.createConfigurationDefinition(); this.configuration = TestConfigurationFactory.createConfiguration(); List<ConfigurationSetMember> members = new ArrayList(GROUP_SIZE); @@ -58,8 +59,8 @@ public abstract class AbstractTestConfigurationUIBean { configuration.getSimple("Boolean").setStringValue(String.valueOf(i % 2 == 0)); if (i == 0) configuration.getMap("OpenMapOfSimples").put(new PropertySimple("PROCESSOR_CORES", "4")); - ConfigurationSetMember memberInfo = - new ConfigurationSetMember(LABELS[GROUP_SIZE % LABELS.length], configuration); + ConfigurationSetMember memberInfo = new ConfigurationSetMember(LABELS[GROUP_SIZE % LABELS.length], + configuration); members.add(memberInfo); } this.configurationSet = new ConfigurationSet(this.configurationDefinition, members); @@ -76,8 +77,7 @@ public abstract class AbstractTestConfigurationUIBean { return this.configurationDefinition; }
- public void setConfigurationDefinition(@NotNull - ConfigurationDefinition configurationDefinition) { + public void setConfigurationDefinition(@NotNull ConfigurationDefinition configurationDefinition) { this.configurationDefinition = configurationDefinition; }
@@ -86,26 +86,26 @@ public abstract class AbstractTestConfigurationUIBean { return this.configuration; }
- public void setConfiguration(@NotNull - Configuration configuration) { + public void setConfiguration(@NotNull Configuration configuration) { this.configuration = configuration; }
- public ConfigurationSet getConfigurationSet() - { + public ConfigurationSet getConfigurationSet() { return configurationSet; }
- public void setConfigurationSet(ConfigurationSet configurationSet) - { + public void setConfigurationSet(ConfigurationSet configurationSet) { this.configurationSet = configurationSet; }
- public List<Property> getProperties() - { + public List<Property> getProperties() { return this.properties; }
+ public void setProperties(@NotNull List<Property> properties) { + this.properties = properties; + } + public String getNullConfigurationDefinitionMessage() { return "Test config def is null (should never happen)."; } diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-managed-beans/test-beans.xml b/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-managed-beans/test-beans.xml index 3ec6058..fbfad37 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-managed-beans/test-beans.xml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-managed-beans/test-beans.xml @@ -17,6 +17,14 @@ </managed-bean>
<managed-bean> + <managed-bean-name>RawTestConfigurationUIBean</managed-bean-name> + <managed-bean-class>org.rhq.enterprise.gui.configuration.test.RawTestConfigurationUIBean</managed-bean-class> + <managed-bean-scope>session</managed-bean-scope> + </managed-bean> + + + + <managed-bean> <managed-bean-name>AddNewOpenMapMemberPropertyToTestConfigurationUIBean</managed-bean-name> <managed-bean-class> org.rhq.enterprise.gui.configuration.test.EditTestConfigurationAddNewOpenMapMemberPropertyUIBean diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit.xhtml index dffd02b..228e612 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit.xhtml @@ -31,19 +31,47 @@ THIS TEXT WILL BE REMOVED.
<h:form id="editResourceConfigurationForm" onsubmit="prepareInputsForSubmission(this)" rendered="#{!ViewResourceConfigurationUIBean.updateInProgress}">
- - <input type="hidden" name="id" value="#{ResourceUIBean.id}"/> - - <h:outputText value="#{messages.youareviewingstructured}" /> - - <h:panelGroup rendered="#{ExistingResourceConfigurationUIBean.rawSupported}" > - <h:outputText value=" #{messages.switch2}" /> - <h:commandLink action="#{ExistingResourceConfigurationUIBean.switchToraw}" > - <f:param name="conversationId" value="#{conversation.id}"/> - <f:param name="id" value="#{ResourceUIBean.id}"/> - <h:outputText value=" files mode"/> - </h:commandLink> - </h:panelGroup> + <input type="hidden" name="id" value="#{ResourceUIBean.id}"/> + + <h:panelGroup> + <h:commandLink action="#{ExistingResourceConfigurationUIBean.updateConfiguration}"> + <h:graphicImage value="Save" url="/images/save.png" /> + <h:outputText value="Save Junk" /> + <f:param name="showRaw" value="true"/> + </h:commandLink> + + <h:commandLink rendered="#{ExistingResourceConfigurationUIBean.showRawButton}" action="#{ExistingResourceConfigurationUIBean.switchToRaw}" > + <h:graphicImage value="Raw" url="/images/raw.png" /> + <h:outputText value="Raw " /> + </h:commandLink> + + <h:commandLink rendered="#{ExistingResourceConfigurationUIBean.showStructuredButton}" action="#{ExistingResourceConfigurationUIBean.switchToStructured}"> + <h:graphicImage value="Structured" url="/images/structured.png" /> + <h:outputText value="Structured " /> + <f:param name="showRaw" value="false"/> + </h:commandLink> + + <h:outputLink value="fullscreen.xhtml"> + <h:graphicImage value="Full Screen" url="/images/viewfullscreen.png" /> + <h:outputText value="Full Screen" /> + <f:param name="showRaw" value="true"/> + </h:outputLink> + + <h:outputLink value="download.xhtml"> + <h:graphicImage value="Download" url="/images/download.png" /> + <h:outputText value="Download " /> + <f:param name="showRaw" value="false"/> + </h:outputLink> + + <h:outputLink value="upload.xhtml" rendered="#{!showReadOnly}"> + <h:graphicImage value="Upload" url="/images/upload.png" /> + <h:outputText value="Upload " /> + <f:param name="showRaw" value="false"/> + </h:outputLink> + + + </h:panelGroup> + <onc:config configurationDefinition="#{ExistingResourceConfigurationUIBean.configurationDefinition}" configuration="#{ExistingResourceConfigurationUIBean.configuration}" @@ -52,6 +80,7 @@ THIS TEXT WILL BE REMOVED. prevalidate="true" showToolbar="true" readOnly="false" + action="#{ExistingResourceConfigurationUIBean.updateRawConfiguration}" />
<h:panelGrid columns="2" styleClass="buttons-table" columnClasses="button-cell" rendered="#{ExistingResourceConfigurationUIBean.configuration != null}"> diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml index 40a917d..ea44edd 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml @@ -41,20 +41,56 @@ THIS TEXT WILL BE REMOVED. </h:panelGroup>
- <h:outputText value=" #{messages.nopermissionedit}" rendered="#{!ResourceUIBean.permissions.configure}"/> - <h:form id="viewResourceConfigurationForm"> <!-- TODO remove the id version --> <input type="hidden" name="id" value="#{ResourceUIBean.id}"/> - + + <ui:include src="/WEB-INF/fragments/config-view-toolbar.xhtml" /> + + <h:panelGroup> + <h:outputLink value="edit.xhtml"> + <h:graphicImage value="Edit" url="/images/edit.png" /> + <h:outputText value="Edit " /> + <f:param name="showRaw" value="#{showRawConfig}"/> + <f:param name="id" value="#{ResourceUIBean.id}"/> + </h:outputLink> + + <h:commandLink rendered="#{ExistingResourceConfigurationViewUIBean.showRawButton}"> + <h:graphicImage value="Raw" url="/images/raw.png" /> + <h:outputText value="Raw " /> + <f:param name="showRaw" value="true"/> + </h:commandLink> + + <h:commandLink rendered="#{ExistingResourceConfigurationViewUIBean.showStructuredButton}"> + <h:graphicImage value="Structured" url="/images/structured.png" /> + <h:outputText value="Structured " /> + <f:param name="showRaw" value="false"/> + </h:commandLink> + + <h:commandLink rendered="#{showRawConfig}"> + <h:graphicImage value="Full Screen" url="/images/viewfullscreen.png" /> + <h:outputText value="Full Screen" /> + <f:param name="showRaw" value="true"/> + </h:commandLink> + + <h:outputLink value="download.xhtml" rendered="#{showRawConfig}"> + <h:graphicImage value="Download" url="/images/download.png" /> + <h:outputText value="Download " /> + </h:outputLink> + + </h:panelGroup> + + + + <onc:config configurationDefinition="#{ExistingResourceConfigurationViewUIBean.configurationDefinition}" configuration="#{ExistingResourceConfigurationViewUIBean.configuration}" accessMapActionExpression="#{ExistingResourceConfigurationViewUIBean.accessMap}" nullConfigurationDefinitionMessage="#{ExistingResourceConfigurationViewUIBean.nullConfigurationDefinitionMessage}" nullConfigurationMessage="#{ExistingResourceConfigurationViewUIBean.nullConfigurationMessage}" readOnly="true" - showToolbar="true" - prevalidate="true"/> + prevalidate="true" + /> <input type="hidden" name="id" value="#{ResourceUIBean.id}"/>
</h:form> diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/test/config/edit.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/test/config/edit.xhtml index 1e4c156..da51088 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/test/config/edit.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/test/config/edit.xhtml @@ -37,7 +37,7 @@ THIS TEXT WILL BE REMOVED. accessMapActionExpression="#{RawTestConfigurationUIBean.accessMap}" readOnly="true" /> <h:panelGrid columns="1" styleClass="buttons-table" columnClasses="button-cell"> - <h:commandButton type="submit" action="#{RawTestConfigurationUIBean.editConfiguration}" + <h:commandButton type="submit" action="#{RawTestConfigurationUIBean.updateConfiguration}" value="Edit this Configuration"/> </h:panelGrid> </h:form>
commit 30d9312e87182ebcc711428585ba51da3c64f3c9 Author: Adam Young ayoung@redhat.com Date: Thu Dec 17 21:25:09 2009 -0500
Still broken. Major refactroing of the config renderer so that the structured config is contained inside a panel. Might have broken something not visible from the test. Still working on re-enabling the save.
diff --git a/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/StructuredConfigUIComponent.java b/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/StructuredConfigUIComponent.java new file mode 100644 index 0000000..c7aa459 --- /dev/null +++ b/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/StructuredConfigUIComponent.java @@ -0,0 +1,146 @@ +package org.rhq.core.gui.configuration; + +import java.util.List; + +import javax.faces.component.UIComponent; +import javax.faces.component.UIPanel; +import javax.faces.component.html.HtmlPanelGroup; + +import org.richfaces.component.html.HtmlSimpleTogglePanel; + +import org.rhq.core.domain.configuration.definition.PropertyGroupDefinition; +import org.rhq.core.gui.configuration.helper.PropertyRenderingUtility; +import org.rhq.core.gui.configuration.propset.ConfigurationSetComponent; +import org.rhq.core.gui.util.FacesComponentIdFactory; +import org.rhq.core.gui.util.FacesComponentUtility; + +public class StructuredConfigUIComponent extends UIPanel { + + FacesComponentIdFactory idFactory; + boolean isGroup; + + public StructuredConfigUIComponent(AbstractConfigurationComponent configurationComponent) { + super(); + this.idFactory = configurationComponent; + this.isGroup = configurationComponent.isGroup(); + if (!configurationComponent.isReadOnly()) + addRequiredNotationsKey(); + + if (configurationComponent.getListName() != null) { + if (configurationComponent.getListIndex() == null) { + // No index specified means we should add a new map to the list. + configurationComponent.setListIndex(ConfigRenderer.addNewMap(configurationComponent)); + } + // Update member Configurations if this is a group config. + updateGroupMemberConfigurations(configurationComponent); + addListMemberProperty(configurationComponent, configurationComponent.getListIndex()); + } else { + addNonGroupedProperties(configurationComponent); + addGroupedProperties(configurationComponent); + } + String id = ConfigRenderer.getInitInputsJavaScriptComponentId(configurationComponent); + PropertyRenderingUtility.addInitInputsJavaScript(this, id, configurationComponent.isFullyEditable(), false); + } + + public void addRequiredNotationsKey() { + ConfigRenderer.addDebug(this, true, ".addNotePanel()"); + HtmlPanelGroup footnotesPanel = FacesComponentUtility.addBlockPanel(this, idFactory, + ConfigRenderer.NOTE_PANEL_STYLE_CLASS); + FacesComponentUtility.addOutputText(footnotesPanel, idFactory, "*", + ConfigRenderer.REQUIRED_MARKER_TEXT_STYLE_CLASS); + FacesComponentUtility.addOutputText(footnotesPanel, idFactory, " denotes a required field.", + FacesComponentUtility.NO_STYLE_CLASS); + if (isGroup) { + HtmlPanelGroup overridePanel = FacesComponentUtility.addBlockPanel(this, idFactory, + ConfigRenderer.NOTE_PANEL_STYLE_CLASS); + FacesComponentUtility.addOutputText(overridePanel, idFactory, + "note: if override is not checked, that property will not be altered on any group members", + FacesComponentUtility.NO_STYLE_CLASS); + } + ConfigRenderer.addDebug(this, false, ".addNotePanel()"); + } + + @Override + public String getFamily() { + // TODO Auto-generated method stub + return "rhq"; + } + + private void addListMemberProperty(AbstractConfigurationComponent configurationComponent, Integer listIndex) { + HtmlPanelGroup propertiesPanel = FacesComponentUtility.addBlockPanel(this, idFactory, + ConfigRenderer.UNGROUPED_PROPERTIES_STYLE_CLASS); + propertiesPanel.getChildren() + .add( + new MapInListUIComponentTreeFactory(configurationComponent, configurationComponent.getListName(), + listIndex).createUIComponentTree(null)); + } + + private void updateGroupMemberConfigurations(AbstractConfigurationComponent configurationComponent) { + if (configurationComponent instanceof ConfigurationSetComponent) { + ConfigurationSetComponent configurationSetComponent = ((ConfigurationSetComponent) configurationComponent); + configurationSetComponent.getConfigurationSet().applyGroupConfiguration(); + } + } + + void addGroupedProperties(AbstractConfigurationComponent config) { + ConfigRenderer.addDebug(config, true, ".addGroupedProperties()"); + List<PropertyGroupDefinition> groups = config.getConfigurationDefinition().getGroupDefinitions(); + for (PropertyGroupDefinition group : groups) { + HtmlSimpleTogglePanel groupPanel = addGroupPanel(group); + AbstractPropertyBagUIComponentTreeFactory propertyListUIComponentTreeFactory = new GroupUIComponentTreeFactory( + config, group.getName()); + groupPanel.getChildren().add(propertyListUIComponentTreeFactory.createUIComponentTree(null)); + } + + ConfigRenderer.addDebug(config, false, ".addGroupedProperties()"); + } + + void addNonGroupedProperties(AbstractConfigurationComponent config) { + + ConfigRenderer.addDebug(this, true, ".addNonGroupedProperties()"); + HtmlPanelGroup propertiesPanel = FacesComponentUtility.addBlockPanel(this, idFactory, + ConfigRenderer.UNGROUPED_PROPERTIES_STYLE_CLASS); + AbstractPropertyBagUIComponentTreeFactory propertyListUIComponentTreeFactory = new GroupUIComponentTreeFactory( + config, GroupUIComponentTreeFactory.NO_GROUP); + + UIComponent createUIComponentTree = propertyListUIComponentTreeFactory.createUIComponentTree(null); + propertiesPanel.getChildren().add(createUIComponentTree); + + ConfigRenderer.addDebug(this, false, ".addNonGroupedProperties()"); + } + + HtmlSimpleTogglePanel addGroupPanel(PropertyGroupDefinition group) { + ConfigRenderer.addDebug(this, true, ".addGroupPanel()"); + HtmlSimpleTogglePanel groupPanel = FacesComponentUtility.addSimpleTogglePanel(this, idFactory, null); + // TODO: On AJAX requests, set "opened" attribute to its previous state. + groupPanel.setOpened(!group.isDefaultHidden()); + groupPanel.setHeaderClass(ConfigRenderer.PROPERTY_GROUP_HEADER_STYLE_CLASS); + groupPanel.setBodyClass(ConfigRenderer.PROPERTY_GROUP_BODY_STYLE_CLASS); + + // Custom header that includes the name and description + HtmlPanelGroup headerPanel = FacesComponentUtility.createBlockPanel(idFactory, null); + FacesComponentUtility.addOutputText(headerPanel, idFactory, group.getDisplayName(), null); + FacesComponentUtility.addOutputText(headerPanel, idFactory, group.getDescription(), + "group-description-text-panel"); + groupPanel.getFacets().put("header", headerPanel); + + // custom "close" widget + HtmlPanelGroup closePanel = FacesComponentUtility.createBlockPanel(idFactory, null); + closePanel.setStyle("text-align: right; font-weight: normal; font-size: 0.8em; whitespace: nowrap;"); + FacesComponentUtility + .addGraphicImage(closePanel, idFactory, "/images/ico_trigger_wht_collapse.gif", "collapse"); + FacesComponentUtility.addOutputText(closePanel, idFactory, " Collapse", null); + groupPanel.getFacets().put("closeMarker", closePanel); + + // custom "open" widget + HtmlPanelGroup openPanel = FacesComponentUtility.createBlockPanel(idFactory, null); + openPanel.setStyle("text-align: right; font-weight: normal; font-size: 0.8em; whitespace: nowrap;"); + FacesComponentUtility.addGraphicImage(openPanel, idFactory, "/images/ico_trigger_wht_expand.gif", "expand"); + FacesComponentUtility.addOutputText(openPanel, idFactory, " Expand", null); + groupPanel.getFacets().put("openMarker", openPanel); + ConfigRenderer.addDebug(this, true, ".addGroupPanel()"); + + return groupPanel; + } + +} diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/test/RawTestConfigurationUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/test/RawTestConfigurationUIBean.java new file mode 100644 index 0000000..919a4ad --- /dev/null +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/test/RawTestConfigurationUIBean.java @@ -0,0 +1,82 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2008 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.gui.configuration.test; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +import javax.faces.application.FacesMessage; + +import org.rhq.core.domain.configuration.Configuration; +import org.rhq.core.domain.configuration.Property; +import org.rhq.core.domain.configuration.PropertySimple; +import org.rhq.core.domain.configuration.RawConfiguration; +import org.rhq.core.domain.configuration.definition.ConfigurationFormat; +import org.rhq.core.gui.configuration.propset.ConfigurationSet; +import org.rhq.core.gui.configuration.propset.ConfigurationSetMember; +import org.rhq.core.gui.util.FacesContextUtility; +import org.rhq.enterprise.gui.common.Outcomes; + +/** + * @author Ian Springer + */ +public class RawTestConfigurationUIBean extends AbstractTestConfigurationUIBean { + public RawTestConfigurationUIBean() { + setConfigurationDefinition(TestConfigurationFactory.createConfigurationDefinition()); + setConfiguration(TestConfigurationFactory.createConfiguration()); + List<ConfigurationSetMember> members = new ArrayList(GROUP_SIZE); + for (int i = 0; i < GROUP_SIZE; i++) { + Configuration configuration = getConfiguration().deepCopy(true); + configuration.setId(i + 1); + configuration.getSimple("String1").setStringValue(UUID.randomUUID().toString()); + configuration.getSimple("Integer").setStringValue(String.valueOf(i + 1)); + configuration.getSimple("Boolean").setStringValue(String.valueOf(i % 2 == 0)); + if (i == 0) + configuration.getMap("OpenMapOfSimples").put(new PropertySimple("PROCESSOR_CORES", "4")); + ConfigurationSetMember memberInfo = new ConfigurationSetMember(LABELS[GROUP_SIZE % LABELS.length], + configuration); + members.add(memberInfo); + } + setConfigurationSet(new ConfigurationSet(getConfigurationDefinition(), members)); + // Unwrap the Hibernate proxy objects, which Facelets appears not to be able to handle. + setProperties(new ArrayList<Property>(this.getConfiguration().getProperties())); + + getConfigurationDefinition().setConfigurationFormat(ConfigurationFormat.STRUCTURED_AND_RAW); + + RawConfiguration rawConfiguration = new RawConfiguration(); + rawConfiguration.setPath("/tmp/nowhere.txt"); + rawConfiguration.setContents("A=1".getBytes()); + getConfiguration().addRawConfiguration(rawConfiguration); + + } + + public static final String MANAGED_BEAN_NAME = RawTestConfigurationUIBean.class.getSimpleName(); + protected static final String SUCCESS_OUTCOME = "success"; + protected static final String FAILURE_OUTCOME = "failure"; + + public String updateConfiguration() { + // Any values changed in the group config (i.e. via the inputs on the main page) need to be + // applied to all member configs before persisting them. + //getConfigurationSet().applyGroupConfiguration(); + // TODO (low priority): Persist the test config somewhere. + FacesContextUtility.addMessage(FacesMessage.SEVERITY_INFO, "Configuration updated."); + return Outcomes.SUCCESS; + } +} \ No newline at end of file diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/test/config/edit.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/test/config/edit.xhtml new file mode 100644 index 0000000..1e4c156 --- /dev/null +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/test/config/edit.xhtml @@ -0,0 +1,51 @@ +<?xml version="1.0"?> + +<!DOCTYPE html + PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<html xmlns="http://www.w3.org/1999/xhtml" + xmlns:h="http://java.sun.com/jsf/html" + xmlns:f="http://java.sun.com/jsf/core" + xmlns:ui="http://java.sun.com/jsf/facelets" + xmlns:rich="http://richfaces.ajax4jsf.org/rich" + xmlns:onc="http://jboss.org/on/component%22%3E + +THIS TEXT WILL BE REMOVED. + +<ui:composition template="/rhq/layout/main.xhtml"> + + THIS TEXT WILL BE REMOVED AS WELL. + + <ui:param name="pageTitle" value="Test Raw Configuration"/> + + <ui:define name="body"> + + <h:messages showSummary="true" + showDetail="true" + errorClass="ErrorBlock" + warnClass="ErrorBlock" + infoClass="ConfirmationBlock" + globalOnly="true" + layout="table" + width="100%"/> + + <h:form id="viewTestConfigurationForm"> + + <onc:config configurationDefinition="#{RawTestConfigurationUIBean.configurationDefinition}" + configuration="#{RawTestConfigurationUIBean.configuration}" + accessMapActionExpression="#{RawTestConfigurationUIBean.accessMap}" + readOnly="true" /> + <h:panelGrid columns="1" styleClass="buttons-table" columnClasses="button-cell"> + <h:commandButton type="submit" action="#{RawTestConfigurationUIBean.editConfiguration}" + value="Edit this Configuration"/> + </h:panelGrid> + </h:form> + + </ui:define> + +</ui:composition> + +THIS TEXT WILL BE REMOVED AS WELL. + +</html> diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/test/config/view.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/test/config/view.xhtml new file mode 100644 index 0000000..c543ca7 --- /dev/null +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/test/config/view.xhtml @@ -0,0 +1,52 @@ +<?xml version="1.0"?> + +<!DOCTYPE html + PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<html xmlns="http://www.w3.org/1999/xhtml" + xmlns:h="http://java.sun.com/jsf/html" + xmlns:f="http://java.sun.com/jsf/core" + xmlns:ui="http://java.sun.com/jsf/facelets" + xmlns:rich="http://richfaces.ajax4jsf.org/rich" + xmlns:onc="http://jboss.org/on/component%22%3E + +THIS TEXT WILL BE REMOVED. + +<ui:composition template="/rhq/layout/main.xhtml"> + + THIS TEXT WILL BE REMOVED AS WELL. + + <ui:param name="pageTitle" value="Test Raw Configuration"/> + + <ui:define name="body"> + + <h:messages showSummary="true" + showDetail="true" + errorClass="ErrorBlock" + warnClass="ErrorBlock" + infoClass="ConfirmationBlock" + globalOnly="true" + layout="table" + width="100%"/> + + <h:form id="viewTestConfigurationForm"> + + <onc:config configurationDefinition="#{RawTestConfigurationUIBean.configurationDefinition}" + configuration="#{RawTestConfigurationUIBean.configuration}" + accessMapActionExpression="#{RawTestConfigurationUIBean.accessMap}" + readOnly="true" + showToolbar="true" /> + <h:panelGrid columns="1" styleClass="buttons-table" columnClasses="button-cell"> + <h:commandButton type="submit" action="#{RawTestConfigurationUIBean.editConfiguration}" + value="Edit this Configuration"/> + </h:panelGrid> + </h:form> + + </ui:define> + +</ui:composition> + +THIS TEXT WILL BE REMOVED AS WELL. + +</html>
commit cfef08f3e2709d21eff761d8079bb5e587e78346 Merge: f33274d... a100923... Author: Justin Harris jharris@redhat.com Date: Thu Dec 17 12:37:45 2009 -0500
Merge branch 'alertPlugin'
commit a100923bbf28491cad34f211e34a7f85cdad070e Author: John Mazzitelli mazz@redhat.com Date: Thu Dec 17 01:22:00 2009 -0500
loadPlugin now throws exception if there is something wrong with the plugin it also only validates the plugin when enabled is true - disabled plugins do not need to validate since they won't be started reuse the superclass' instantiatePluginClass
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSenderPluginManager.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSenderPluginManager.java index dbfb1f3..acd9550 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSenderPluginManager.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSenderPluginManager.java @@ -63,81 +63,89 @@ public class AlertSenderPluginManager extends ServerPluginManager { * in the super class. * Here we verify that the passed <plugin-class> is valid and build the * list of plugins that can be queried by the UI etc. + * * @param env the environment of the plugin to be loaded - * - * @throws Exception + * @param enabled if <code>true</code>, the plugin is to be enabled and will be started soon + * + * @throws Exception if the alert plugin could not be loaded due to errors such as the alert class being invalid */ @Override - public void loadPlugin(ServerPluginEnvironment env, boolean enable) throws Exception { - log.debug("Start loading alert plugin " + env.getPluginKey().getPluginName()); - super.loadPlugin(env, enable); + public void loadPlugin(ServerPluginEnvironment env, boolean enabled) throws Exception {
- AlertPluginDescriptorType type = (AlertPluginDescriptorType) env.getPluginDescriptor(); + super.loadPlugin(env, enabled);
- String className = type.getPluginClass(); - try { - loadPluginClass(env, className, false); - } catch (Exception e) { - log.error("Can't find pluginClass [" + className + "]. Plugin [" + env.getPluginKey().getPluginName() - + "] will be ignored. Cause: " + ThrowableUtil.getAllMessages(e)); - try { - unloadPlugin(env.getPluginKey().getPluginName()); - } catch (Throwable t) { - log.warn(" +--> unload failed too. Cause: " + ThrowableUtil.getAllMessages(t)); - } - return; - } - - // The short name is basically the key into the plugin - String shortName = type.getShortName(); - pluginClassByName.put(shortName, className); - - // - // Ok, we have a valid plugin class, so we can look for other things - // and store the info - // + if (enabled) {
- String uiSnippetPath; - URL uiSnippetUrl = null; - CustomUi customUI = type.getCustomUi(); - if (customUI != null) { - uiSnippetPath = customUI.getUiSnippetName(); + AlertPluginDescriptorType type = (AlertPluginDescriptorType) env.getPluginDescriptor();
+ // make sure the alert sender class name is valid + String className = type.getPluginClass(); try { - uiSnippetUrl = env.getPluginClassLoader().getResource(uiSnippetPath); - log.info("Alert plugin UI snipped for [" + shortName + "] is at: " + uiSnippetUrl); + loadPluginClass(env, className, false); } catch (Exception e) { - log.error("No valid ui snippet provided, but <custom-ui> given for sender plugin " + shortName - + "Error is " + e.getMessage()); - log.error("Plugin will be ignored"); - return; + log.error("Alert sender class [" + className + "] defined in plugin [" + + env.getPluginKey().getPluginName() + "] is invalid and will be ignored. Cause: " + + ThrowableUtil.getAllMessages(e)); + try { + unloadPlugin(env.getPluginKey().getPluginName()); + } catch (Throwable t) { + log.warn(" +--> unload failed too. Cause: " + ThrowableUtil.getAllMessages(t)); + } + throw e; }
- // Get the backing bean class - className = customUI.getBackingBeanName(); - if (!className.contains(".")) { - className = type.getPackage() + "." + className; + // + // Ok, we have a valid plugin class, so we can look for other things and store the info + // + + // The short name is basically the key into the plugin + String shortName = type.getShortName(); + pluginClassByName.put(shortName, className); + + // UI snippet path allows the plugin to inject user interface fragments to the alert pages + String uiSnippetPath; + URL uiSnippetUrl = null; + CustomUi customUI = type.getCustomUi(); + if (customUI != null) { + uiSnippetPath = customUI.getUiSnippetName(); + + try { + uiSnippetUrl = env.getPluginClassLoader().getResource(uiSnippetPath); + if (uiSnippetUrl == null) { + throw new Exception("plugin is missing alert ui snippet named [" + uiSnippetPath + "]"); + } + log.debug("Alert plugin UI snippet for [" + shortName + "] is at: " + uiSnippetUrl); + } catch (Exception e) { + log.error("Invalid alert UI snippet provided inside <custom-ui> for alert plugin [" + shortName + + "]. Plugin will be ignored. Cause: " + ThrowableUtil.getAllMessages(e)); + throw e; + } + + // Get the backing bean class + className = customUI.getBackingBeanName(); + try { + loadPluginClass(env, className, true); // TODO how make this available to Seam and the Web-CL ? + backingBeanByName.put(shortName, className); + } catch (Throwable t) { + String errMsg = "Backing bean [" + className + "] not found for plugin [" + shortName + ']'; + log.error(errMsg); + throw new Exception(errMsg, t); + } } - try { - loadPluginClass(env, className, true); // TODO how make this available to Seam and the Web-CL ? - backingBeanByName.put(shortName, className); - } catch (Throwable t) { - log.error("Backing bean [" + className + "] not found for plugin [" + shortName + ']'); - } - } - - AlertSenderInfo info = new AlertSenderInfo(shortName, type.getDescription(), env.getPluginKey()); - info.setUiSnippetUrl(uiSnippetUrl); - senderInfoByName.put(shortName, info);
- pluginEnvByName.put(shortName, env); + AlertSenderInfo info = new AlertSenderInfo(shortName, type.getDescription(), env.getPluginKey()); + info.setUiSnippetUrl(uiSnippetUrl); + senderInfoByName.put(shortName, info);
+ pluginEnvByName.put(shortName, env); + } }
@Override protected void unloadPlugin(String pluginName) throws Exception { - log.info("Unloading plugin " + pluginName); + super.unloadPlugin(pluginName); + String shortName = null; for (AlertSenderInfo info : senderInfoByName.values()) { if (info.getPluginName().equals(pluginName)) { @@ -145,10 +153,13 @@ public class AlertSenderPluginManager extends ServerPluginManager { break; } } - pluginClassByName.remove(shortName); - senderInfoByName.remove(shortName); - pluginEnvByName.remove(shortName); - backingBeanByName.remove(shortName); + + if (shortName != null) { + pluginClassByName.remove(shortName); + senderInfoByName.remove(shortName); + pluginEnvByName.remove(shortName); + backingBeanByName.remove(shortName); + } }
/** @@ -163,29 +174,18 @@ public class AlertSenderPluginManager extends ServerPluginManager { String senderName = notification.getSenderName(); String className = pluginClassByName.get(senderName); if (className == null) { - log.error("getAlertSender: No pluginClass found for sender: " + senderName); + log.error("getAlertSenderForNotification: No pluginClass found for sender: " + senderName); return null; } ServerPluginEnvironment env = pluginEnvByName.get(senderName); - Class<?> clazz; + AlertSender sender; try { - clazz = loadPluginClass(env, className, true); + sender = (AlertSender) instantiatePluginClass(env, className); } catch (Exception e) { log.error(e); // TODO return null; }
- AlertSender sender; - try { - sender = (AlertSender) clazz.newInstance(); - } catch (InstantiationException e) { - e.printStackTrace(); // TODO: Customise this generated block - return null; - } catch (IllegalAccessException e) { - e.printStackTrace(); // TODO: Customise this generated block - return null; - } - // We have no entityManager lying around here, which means // Configuration is an uninitialized Proxy and we'd get a LazyInit // Exception later. @@ -227,20 +227,13 @@ public class AlertSenderPluginManager extends ServerPluginManager { }
public AlertBackingBean getBackingBeanForSender(String shortName) { - String name = backingBeanByName.get(shortName); + String className = backingBeanByName.get(shortName); ServerPluginEnvironment env = pluginEnvByName.get(shortName); - Class<?> clazz; - try { - clazz = loadPluginClass(env, name, true); - } catch (Exception e) { - log.error("Can't load class " + name + ": " + e.getMessage()); - return null; - } AlertBackingBean bean = null; try { - bean = (AlertBackingBean) clazz.newInstance(); + bean = (AlertBackingBean) instantiatePluginClass(env, className); } catch (Exception e) { - log.error("Can't instantiate " + name + ": " + e.getMessage()); + log.error("Can't instantiate alert sender backing bean [" + className + "]. Cause: " + e.getMessage()); } return bean; }
commit fc2c98d30c7dc532cd9cbc0ef5b213d1f6a567a6 Author: John Mazzitelli mazz@redhat.com Date: Thu Dec 17 01:17:39 2009 -0500
remove the unnecessary delegate methods - don't think we need them right now
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertServerPluginContainer.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertServerPluginContainer.java index b7e65a0..c4aca5e 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertServerPluginContainer.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertServerPluginContainer.java @@ -42,32 +42,6 @@ public class AlertServerPluginContainer extends AbstractTypeServerPluginContaine }
@Override - public ServerPluginManager getPluginManager() { - return super.getPluginManager(); // TODO: Customise this generated block - } - - @Override - public void initialize() throws Exception { - super.initialize(); // TODO: Customise this generated block - } - - @Override - public void start() { - super.start(); // TODO: Customise this generated block - } - - @Override - public synchronized void stop() { - super.stop(); // TODO: Customise this generated block - } - - @Override - public void shutdown() { - //getPluginManager().un - super.shutdown(); // TODO: Customise this generated block - } - - @Override protected ServerPluginManager createPluginManager() { return new AlertSenderPluginManager(this); }
commit 23ddc6a48e3bb4112226feeb6711b4a3b22cb6e6 Author: John Mazzitelli mazz@redhat.com Date: Thu Dec 17 00:29:27 2009 -0500
workaround what is probably a bug or poor defensive programming in the irc 3rd party lib if the irc bot failed to connect, some internal fields are still null thus causing an NPE if you call dispose. wrap the call to dispose to catch any exception in order to complete our shutdown method
diff --git a/modules/enterprise/server/plugins/alert-irc/src/main/java/org/rhq/enterprise/server/plugins/alertIrc/IrcAlertComponent.java b/modules/enterprise/server/plugins/alert-irc/src/main/java/org/rhq/enterprise/server/plugins/alertIrc/IrcAlertComponent.java index 13c910b..7f43570 100644 --- a/modules/enterprise/server/plugins/alert-irc/src/main/java/org/rhq/enterprise/server/plugins/alertIrc/IrcAlertComponent.java +++ b/modules/enterprise/server/plugins/alert-irc/src/main/java/org/rhq/enterprise/server/plugins/alertIrc/IrcAlertComponent.java @@ -23,9 +23,11 @@ package org.rhq.enterprise.server.plugins.alertIrc;
import java.util.Arrays; + import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.jibble.pircbot.PircBot; + import org.rhq.core.domain.configuration.Configuration; import org.rhq.enterprise.server.plugin.pc.ServerPluginComponent; import org.rhq.enterprise.server.plugin.pc.ServerPluginContext; @@ -88,8 +90,13 @@ public class IrcAlertComponent implements ServerPluginComponent { }
public void shutdown() { - this.ircBot.dispose(); - this.ircBot = null; + try { + this.ircBot.dispose(); + } catch (Exception e) { + log.warn("Failed to dispose of the IRC bot object: " + e.getMessage()); + } finally { + this.ircBot = null; + } }
/** @@ -116,7 +123,7 @@ public class IrcAlertComponent implements ServerPluginComponent { this.ircBot.joinChannel(channel); }
- return new String[]{channel}; + return new String[] { channel }; } else { return this.ircBot.getChannels(); } @@ -148,8 +155,7 @@ public class IrcAlertComponent implements ServerPluginComponent { * @param message */ @Override - public void onMessage(String channel, String sender, String login, - String hostname, String message) { + public void onMessage(String channel, String sender, String login, String hostname, String message) {
if (this.response != null && message.startsWith(nick)) { if (channel != null && channel.length() > 0) {
commit 25b8d852aee2d361ad322b86dfb47e589b4c4ab2 Author: John Mazzitelli mazz@redhat.com Date: Thu Dec 17 00:27:32 2009 -0500
trivial - just stub out delegator method for stop
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertServerPluginContainer.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertServerPluginContainer.java index 3de6d0d..b7e65a0 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertServerPluginContainer.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertServerPluginContainer.java @@ -43,23 +43,28 @@ public class AlertServerPluginContainer extends AbstractTypeServerPluginContaine
@Override public ServerPluginManager getPluginManager() { - return super.getPluginManager(); // TODO: Customise this generated block + return super.getPluginManager(); // TODO: Customise this generated block }
@Override public void initialize() throws Exception { - super.initialize(); // TODO: Customise this generated block + super.initialize(); // TODO: Customise this generated block }
@Override public void start() { - super.start(); // TODO: Customise this generated block + super.start(); // TODO: Customise this generated block + } + + @Override + public synchronized void stop() { + super.stop(); // TODO: Customise this generated block }
@Override public void shutdown() { //getPluginManager().un - super.shutdown(); // TODO: Customise this generated block + super.shutdown(); // TODO: Customise this generated block }
@Override
commit 102d91c377a1b6f48bcefa34a0c47a63dac56d29 Author: John Mazzitelli mazz@redhat.com Date: Thu Dec 17 00:10:46 2009 -0500
add alert server plugin sources and deps to eclipse classpath
diff --git a/.classpath b/.classpath index 8844225..d9f559e 100644 --- a/.classpath +++ b/.classpath @@ -54,6 +54,12 @@ <classpathentry kind="src" path="modules/enterprise/server/plugins/rhnhosted/src/main/java"/> <classpathentry kind="src" path="modules/enterprise/server/plugins/rhnhosted/src/test/java"/> <classpathentry kind="src" path="modules/enterprise/server/plugins/rhnhosted/target/classes/generated-source"/> + <classpathentry kind="src" path="modules/enterprise/server/plugins/alert-email/src/main/java"/> + <classpathentry kind="src" path="modules/enterprise/server/plugins/alert-roles/src/main/java"/> + <classpathentry kind="src" path="modules/enterprise/server/plugins/alert-snmp/src/main/java"/> + <classpathentry kind="src" path="modules/enterprise/server/plugins/alert-irc/src/main/java"/> + <classpathentry kind="src" path="modules/enterprise/server/plugins/alert-microblog/src/main/java"/> + <classpathentry kind="src" path="modules/enterprise/server/plugins/alert-mobicents/src/main/java"/> <classpathentry kind="src" path="modules/enterprise/gui/portal-war/src/main/java"/> <classpathentry kind="src" path="modules/enterprise/gui/portal-war/src/test/java"/> <classpathentry kind="src" path="modules/enterprise/gui/installer-war/src/main/java"/> @@ -89,8 +95,8 @@ <classpathentry kind="src" path="modules/plugins/samba/src/test/java"/> <classpathentry kind="src" path="modules/plugins/sudoers/src/main/java"/> <classpathentry kind="src" path="modules/plugins/sudoers/src/test/java"/> - <classpathentry kind="src" path="modules/plugins/postfix/src/main/java"/> - <classpathentry kind="src" path="modules/plugins/postfix/src/test/java"/> + <classpathentry kind="src" path="modules/plugins/postfix/src/main/java"/> + <classpathentry kind="src" path="modules/plugins/postfix/src/test/java"/> <classpathentry kind="src" path="modules/plugins/cron/src/main/java"/> <classpathentry kind="src" path="modules/plugins/hudson/src/main/java"/> <classpathentry kind="src" path="modules/plugins/platform/src/test/java"/> @@ -103,11 +109,11 @@ <classpathentry kind="src" path="modules/plugins/script/src/main/java"/> <classpathentry kind="src" path="modules/plugins/antlr-config/src/main/antlr3"/> <classpathentry kind="src" path="modules/plugins/antlr-config/target/generated-sources/antlr3"/> + <classpathentry kind="src" path="modules/plugins/augeas/src/main/java"/> + <classpathentry kind="src" path="modules/plugins/augeas/src/test/java"/> <classpathentry kind="src" path="modules/helpers/rtfilter/src/main/java"/> <classpathentry kind="src" path="modules/helpers/pluginAnnotations/src/main/java"/> <classpathentry kind="src" path="modules/helpers/pluginGen/src/main/java"/> - <classpathentry kind="src" path="modules/plugins/augeas/src/main/java"/> - <classpathentry kind="src" path="modules/plugins/augeas/src/test/java"/> <classpathentry kind="src" path="etc/samples/skeleton-plugin/src/main/java"/> <classpathentry kind="src" path="etc/samples/custom-serverplugin/src/main/java"/> <classpathentry kind="src" path="etc/samples/simplereport-serverplugin/src/main/java"/> @@ -202,6 +208,8 @@ <classpathentry exported="true" kind="var" path="M2_REPO/org/antlr/antlr-runtime/3.2/antlr-runtime-3.2.jar"/> <classpathentry exported="true" kind="var" path="M2_REPO/commons-digester/commons-digester/1.8/commons-digester-1.8.jar"/> <classpathentry exported="true" kind="var" path="M2_REPO/commons-codec/commons-codec/1.4/commons-codec-1.4.jar"/> + <classpathentry exported="true" kind="var" path="M2_REPO/pircbot/pircbot/1.4.2/pircbot-1.4.2.jar"/> + <classpathentry exported="true" kind="var" path="M2_REPO/net/homeip/yusuke/twitter4j/2.0.9/twitter4j-2.0.9.jar"/> <classpathentry exported="true" kind="lib" path="modules/enterprise/remoting/webservices/target/rhq-remoting-webservices-1.4.0-SNAPSHOT/wsconsume-output"/> <classpathentry kind="output" path="eclipse-classes"/> </classpath>
commit 962cb01970b9d2238624f4cb7068ac04fa2cd2a3 Author: John Mazzitelli mazz@redhat.com Date: Wed Dec 16 23:49:47 2009 -0500
add method to load plugin class for subclasses to use
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginManager.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginManager.java index e86e687..768162f 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginManager.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginManager.java @@ -184,7 +184,7 @@ public class ServerPluginManager { Thread.currentThread().setContextClassLoader(env.getPluginClassLoader()); component.initialize(context); } catch (Throwable t) { - throw new Exception("Plugin component failed to initialize server plugin", t); + throw new Exception("Plugin component failed to initialize server plugin [" + pluginName + "]", t); } finally { Thread.currentThread().setContextClassLoader(originalContextClassLoader); } @@ -284,13 +284,13 @@ public class ServerPluginManager { // tell the plugin we are unloading it ServerPluginComponent component = this.pluginComponentCache.get(pluginName); if (component != null) { - log.debug("Shutting down plugin componentfor server plugin [" + pluginName + "]"); + log.debug("Shutting down plugin component for server plugin [" + pluginName + "]"); ClassLoader originalContextClassLoader = Thread.currentThread().getContextClassLoader(); try { Thread.currentThread().setContextClassLoader(env.getPluginClassLoader()); component.shutdown(); } catch (Throwable t) { - throw new Exception("Plugin plugin componentfailed to initialize plugin", t); + throw new Exception("Plugin component failed to shutdown server plugin [" + pluginName + "]", t); } finally { Thread.currentThread().setContextClassLoader(originalContextClassLoader); this.pluginComponentCache.remove(pluginName); @@ -512,6 +512,38 @@ public class ServerPluginManager { }
/** + * Loads a class with the given name within the given environment's classloader. + * The class will only be initialized if <code>initialize</code> is <code>true</code>. + * + * @param environment the environment that has the classloader where the class will be loaded + * @param className the class to load + * @param initialize whether the class must be initialized + * @return the new class that has been loaded + * @throws Exception if failed to load the class + */ + protected Class<?> loadPluginClass(ServerPluginEnvironment environment, String className, boolean initialize) + throws Exception { + + ClassLoader loader = environment.getPluginClassLoader(); + + ServerPluginDescriptorType descriptor = environment.getPluginDescriptor(); + className = ServerPluginDescriptorMetadataParser.getFullyQualifiedClassName(descriptor, className); + + log.debug("Loading server plugin class [" + className + "]..."); + + try { + Class<?> clazz = Class.forName(className, initialize, loader); + log.debug("Loaded server plugin class [" + clazz + "]. initialized=[" + initialize + ']'); + return clazz; + } catch (ClassNotFoundException e) { + throw new Exception("Could not find plugin class [" + className + "] from plugin environment [" + + environment + "]", e); + } catch (NullPointerException npe) { + throw new Exception("Plugin class was 'null' in plugin environment [" + environment + "]", npe); + } + } + + /** * Instantiates a class with the given name within the given environment's classloader using * the class' no-arg constructor. * @@ -521,14 +553,9 @@ public class ServerPluginManager { * @throws Exception if failed to instantiate the class */ protected Object instantiatePluginClass(ServerPluginEnvironment environment, String className) throws Exception { - - ClassLoader loader = environment.getPluginClassLoader(); - - log.debug("Loading server plugin class [" + className + "]..."); - try { - Class<?> clazz = Class.forName(className, true, loader); - log.debug("Loaded server plugin class [" + clazz + "]."); + Class<?> clazz = loadPluginClass(environment, className, true); + log.debug("Instantiating server plugin class [" + clazz + "]"); return clazz.newInstance(); } catch (InstantiationException e) { throw new Exception("Could not instantiate plugin class [" + className + "] from plugin environment [" @@ -536,11 +563,6 @@ public class ServerPluginManager { } catch (IllegalAccessException e) { throw new Exception("Could not access plugin class [" + className + "] from plugin environment [" + environment + "]", e); - } catch (ClassNotFoundException e) { - throw new Exception("Could not find plugin class [" + className + "] from plugin environment [" - + environment + "]", e); - } catch (NullPointerException npe) { - throw new Exception("Plugin class was 'null' in plugin environment [" + environment + "]", npe); } } } diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSenderPluginManager.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSenderPluginManager.java index cd4e072..dbfb1f3 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSenderPluginManager.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSenderPluginManager.java @@ -30,6 +30,7 @@ import org.rhq.core.domain.alert.notification.AlertNotification; import org.rhq.core.domain.configuration.Configuration; import org.rhq.core.domain.plugin.PluginKey; import org.rhq.core.domain.plugin.ServerPlugin; +import org.rhq.core.util.exception.ThrowableUtil; import org.rhq.enterprise.server.alert.AlertNotificationManagerLocal; import org.rhq.enterprise.server.plugin.ServerPluginsLocal; import org.rhq.enterprise.server.plugin.pc.AbstractTypeServerPluginContainer; @@ -68,24 +69,21 @@ public class AlertSenderPluginManager extends ServerPluginManager { */ @Override public void loadPlugin(ServerPluginEnvironment env, boolean enable) throws Exception { - log.info("Start loading alert plugin " + env.getPluginKey().getPluginName()); + log.debug("Start loading alert plugin " + env.getPluginKey().getPluginName()); super.loadPlugin(env, enable);
AlertPluginDescriptorType type = (AlertPluginDescriptorType) env.getPluginDescriptor();
String className = type.getPluginClass(); - if (!className.contains(".")) { - className = type.getPackage() + "." + className; - } try { - Class.forName(className, false, env.getPluginClassLoader()); + loadPluginClass(env, className, false); } catch (Exception e) { - log.error("Can't find pluginClass " + className + ". Plugin " + env.getPluginKey().getPluginName() - + " will be ignored"); + log.error("Can't find pluginClass [" + className + "]. Plugin [" + env.getPluginKey().getPluginName() + + "] will be ignored. Cause: " + ThrowableUtil.getAllMessages(e)); try { unloadPlugin(env.getPluginKey().getPluginName()); } catch (Throwable t) { - log.warn(" +--> unload failed too " + t.getMessage()); + log.warn(" +--> unload failed too. Cause: " + ThrowableUtil.getAllMessages(t)); } return; } @@ -107,7 +105,7 @@ public class AlertSenderPluginManager extends ServerPluginManager {
try { uiSnippetUrl = env.getPluginClassLoader().getResource(uiSnippetPath); - log.info("UI snipped for " + shortName + " is at " + uiSnippetUrl); + log.info("Alert plugin UI snipped for [" + shortName + "] is at: " + uiSnippetUrl); } catch (Exception e) { log.error("No valid ui snippet provided, but <custom-ui> given for sender plugin " + shortName + "Error is " + e.getMessage()); @@ -121,10 +119,10 @@ public class AlertSenderPluginManager extends ServerPluginManager { className = type.getPackage() + "." + className; } try { - Class.forName(className, true, env.getPluginClassLoader()); // TODO how make this available to Seam and the Web-CL ? + loadPluginClass(env, className, true); // TODO how make this available to Seam and the Web-CL ? backingBeanByName.put(shortName, className); } catch (Throwable t) { - log.error("Backing bean " + className + " not found for plugin " + shortName); + log.error("Backing bean [" + className + "] not found for plugin [" + shortName + ']'); } }
@@ -169,9 +167,9 @@ public class AlertSenderPluginManager extends ServerPluginManager { return null; } ServerPluginEnvironment env = pluginEnvByName.get(senderName); - Class clazz; + Class<?> clazz; try { - clazz = Class.forName(className, true, env.getPluginClassLoader()); + clazz = loadPluginClass(env, className, true); } catch (Exception e) { log.error(e); // TODO return null; @@ -231,9 +229,9 @@ public class AlertSenderPluginManager extends ServerPluginManager { public AlertBackingBean getBackingBeanForSender(String shortName) { String name = backingBeanByName.get(shortName); ServerPluginEnvironment env = pluginEnvByName.get(shortName); - Class clazz; + Class<?> clazz; try { - clazz = Class.forName(name, true, env.getPluginClassLoader()); + clazz = loadPluginClass(env, name, true); } catch (Exception e) { log.error("Can't load class " + name + ": " + e.getMessage()); return null;
commit 3f95647a3db1bf733540e4646d1cad511248c66d Author: John Mazzitelli mazz@redhat.com Date: Wed Dec 16 17:00:22 2009 -0500
when a server plugin is updated, retain the original data. note: problems may occur if metadata changed, should probably try to fix that in the future
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsBean.java index f3ac46b..35f3fec 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsBean.java @@ -422,6 +422,11 @@ public class ServerPluginsBean implements ServerPluginsLocal { } ServerPlugin obsolete = ServerPluginDescriptorUtil.determineObsoletePlugin(plugin, existingPlugin); if (obsolete == existingPlugin) { // yes use == for reference equality + + // in order to keep the same configuration that the old plugin had, let's set the new plugin's config objects + // TODO: what happens if the plugin's metadata changes? we should clean the old config of old properties. + plugin.setPluginConfiguration(existingPlugin.getPluginConfiguration()); + plugin.setScheduledJobsConfiguration(existingPlugin.getScheduledJobsConfiguration()); newOrUpdated = true; } plugin.setId(existingPlugin.getId());
commit 23bf08f5d43f9a29ff25300dbc6887098874dcf7 Author: John Mazzitelli mazz@redhat.com Date: Wed Dec 16 16:56:13 2009 -0500
fix the plugin config ui 1) be able to get back to the details page from any selected tree node 2) do not enable a plugin after changing config - in HA mode this won't work as you'd expect 3) put the edit button at the top in addition to the bottom so its easy to get to
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/EditPluginConfigurationUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/EditPluginConfigurationUIBean.java index f85269f..34b24a6 100644 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/EditPluginConfigurationUIBean.java +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/EditPluginConfigurationUIBean.java @@ -21,7 +21,9 @@ package org.rhq.enterprise.gui.admin.plugin; import java.io.Serializable; import java.util.ArrayList; import java.util.List; + import javax.faces.application.FacesMessage; + import org.jboss.seam.ScopeType; import org.jboss.seam.annotations.Create; import org.jboss.seam.annotations.In; @@ -30,6 +32,7 @@ import org.jboss.seam.annotations.Name; import org.jboss.seam.annotations.Scope; import org.jboss.seam.annotations.web.RequestParameter; import org.jboss.seam.log.Log; + import org.rhq.core.domain.auth.Subject; import org.rhq.core.domain.configuration.Configuration; import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; @@ -105,17 +108,27 @@ public class EditPluginConfigurationUIBean extends AbstractPluginConfigurationUI try { ServerPluginsLocal serverPlugins = LookupUtil.getServerPlugins(); Subject subject = EnterpriseFacesContextUtility.getSubject(); - serverPlugins.updateServerPluginExceptContent(subject, getPlugin());
- // rekick the updated plugin so that any config changes take effect - serverPlugins.disableServerPlugins(subject, getPluginIdList()); - serverPlugins.enableServerPlugins(subject, getPluginIdList()); + ServerPlugin plugin = serverPlugins.updateServerPluginExceptContent(subject, getPlugin()); + setPlugin(plugin); + + // the config has changed. we would like to restart the plugin, but we would need to ensure + // ALL servers in the rhq server cloud restart. today we have no easy way to inform all servers + // that they should do this. So, for now, disable the plugin (since if it is running, it is doing + // so with a now-invalid configuration. Let the user go in and re-enable the plugin later. + // TODO: right now, if the user re-enables the plugin too fast, some of the other servers + // will not have seen the state change and won't restart the plugin. Need a way to do this... + // perhaps use the mtime column to denote that state changed (this would affect whether or not + // the plugin needs to be upgraded, so we need to be careful re-using the mtime column for this purpose). + if (plugin.isEnabled()) { + serverPlugins.disableServerPlugins(subject, getPluginIdList()); + }
FacesContextUtility.addMessage(FacesMessage.SEVERITY_INFO, "Configuration settings saved."); } catch (Exception e) { log.error("Error updating the plugin configurations.", e); FacesContextUtility.addMessage(FacesMessage.SEVERITY_ERROR, - "There was an error changing the configuration settings.", e); + "There was an error changing the configuration settings.", e);
return null; } diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-config.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-config.xhtml index f0cca1b..8bf0a28 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-config.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-config.xhtml @@ -30,6 +30,10 @@ <h:outputText value="Server Settings"/> </h:outputLink> > + <h:outputLink value="plugin-list.xhtml" > + ${msg["manage-plugins.installed-plugins.breadcrumb"]} + </h:outputLink> + > <h:outputLink value="plugin-config.xhtml"> <h:outputText value="Server Plugins Configuration"/> </h:outputLink> @@ -76,6 +80,36 @@ </rich:panel>
<h:panelGroup id="pluginConfig"> + <rich:panel id="detailsLink" + style="background: #EEEEEE;" + rendered="#{pluginConfigUIBean.plugin != null}" > + <h:outputText value="See the " /> + <h:outputLink value="/rhq/admin/plugin/plugin-details.xhtml"> + <f:param name="plugin" value="#{pluginConfigUIBean.plugin.name}"/> + <f:param name="deployment" value="#{pluginConfigUIBean.plugin.deployment}"/> + <f:param name="pluginType" value="#{pluginConfigUIBean.plugin.type}"/> + <h:outputText value="'#{pluginConfigUIBean.plugin.displayName}' details page"/> + </h:outputLink> + <h:outputText value=" for more plugin information." /> + </rich:panel> + + <rich:panel id="noConfigMessage" + style="background: #EEEEEE;" + rendered="#{not pluginConfigUIBean.editable and pluginConfigUIBean.plugin != null}" > + <h:outputText escape="true" value="Plugin '#{pluginConfigUIBean.plugin.displayName}' has no configuration." /> + </rich:panel> + + <rich:panel id="pluginButtonsTopPanel" rendered="#{pluginConfigUIBean.editable}"> + <h:panelGroup id="pluginButtonsTop"> + <h:outputLink value="/rhq/admin/plugin/plugin-edit.xhtml" styleClass="buttonmed"> + <f:param name="plugin" value="#{pluginConfigUIBean.plugin.name}"/> + <f:param name="deployment" value="#{pluginConfigUIBean.plugin.deployment}"/> + <f:param name="pluginType" value="#{pluginConfigUIBean.plugin.type}"/> + <h:outputText value="EDIT"/> + </h:outputLink> + </h:panelGroup> + </rich:panel> + <rich:panel rendered="#{pluginConfigUIBean.plugin.pluginConfiguration != null}"> <f:facet name="header"> <h:outputText value="Plugin Configuration"/> @@ -94,30 +128,17 @@ readOnly="true" /> </rich:panel>
- <rich:panel id="noConfigMessage" - rendered="#{not pluginConfigUIBean.editable and pluginConfigUIBean.plugin != null}" - style="background: #EEEEEE;"> - <h:outputText escape="true" value="#{pluginConfigUIBean.plugin.displayName} has no configuration. " /> - <br /> - <br /> - <h:outputText value="See the " /> - <h:outputLink value="/rhq/admin/plugin/plugin-details.xhtml"> - <f:param name="plugin" value="#{pluginConfigUIBean.plugin.name}"/> - <f:param name="deployment" value="#{pluginConfigUIBean.plugin.deployment}"/> - <f:param name="pluginType" value="#{pluginConfigUIBean.plugin.type}"/> - <h:outputText value="#{pluginConfigUIBean.plugin.displayName} details page"/> - </h:outputLink> - <h:outputText value=" for more plugin information." /> + <rich:panel id="pluginButtonsBottomPanel" rendered="#{pluginConfigUIBean.editable}"> + <h:panelGroup id="pluginButtonsBottom"> + <h:outputLink value="/rhq/admin/plugin/plugin-edit.xhtml" styleClass="buttonmed"> + <f:param name="plugin" value="#{pluginConfigUIBean.plugin.name}"/> + <f:param name="deployment" value="#{pluginConfigUIBean.plugin.deployment}"/> + <f:param name="pluginType" value="#{pluginConfigUIBean.plugin.type}"/> + <h:outputText value="EDIT"/> + </h:outputLink> + </h:panelGroup> </rich:panel>
- <h:panelGroup id="pluginButtons" rendered="#{pluginConfigUIBean.editable}"> - <h:outputLink value="/rhq/admin/plugin/plugin-edit.xhtml" styleClass="buttonmed"> - <f:param name="plugin" value="#{pluginConfigUIBean.plugin.name}"/> - <f:param name="deployment" value="#{pluginConfigUIBean.plugin.deployment}"/> - <f:param name="pluginType" value="#{pluginConfigUIBean.plugin.type}"/> - <h:outputText value="EDIT"/> - </h:outputLink> - </h:panelGroup> </h:panelGroup> </h:panelGrid> </h:form>
commit e6eda24d7b38af940a7f9f4dd1c01c9695c87f29 Author: John Mazzitelli mazz@redhat.com Date: Wed Dec 16 15:33:37 2009 -0500
fix the error checking code for scanning dropbox
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/plugin/PluginDeploymentScanner.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/plugin/PluginDeploymentScanner.java index 7ec0020..9f22d2c 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/plugin/PluginDeploymentScanner.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/plugin/PluginDeploymentScanner.java @@ -204,21 +204,25 @@ public class PluginDeploymentScanner implements PluginDeploymentScannerMBean { File destinationDirectory; if (file.getName().endsWith(".jar")) { try { - AgentPluginDescriptorUtil.loadPluginDescriptorFromUrl(file.toURI().toURL()); + if (null == AgentPluginDescriptorUtil.loadPluginDescriptorFromUrl(file.toURI().toURL())) { + throw new NullPointerException("no xml descriptor found in jar"); + } destinationDirectory = getAgentPluginDir(); } catch (Exception e) { try { log.debug("[" + file.getAbsolutePath() + "] is not an agent plugin jar (Cause: " + ThrowableUtil.getAllMessages(e) + "). Will see if its a server plugin jar");
- ServerPluginDescriptorUtil.loadPluginDescriptorFromUrl(file.toURI().toURL()); + if (null == ServerPluginDescriptorUtil.loadPluginDescriptorFromUrl(file.toURI().toURL())) { + throw new NullPointerException("no xml descriptor found in jar"); + } destinationDirectory = getServerPluginDir(); } catch (Exception e1) { // skip it, doesn't look like a valid plugin jar File fixmeFile = new File(file.getAbsolutePath() + ".fixme"); boolean renamed = file.renameTo(fixmeFile); log.warn("Does not look like [" + (renamed ? fixmeFile : file).getAbsolutePath() - + "] is a plugin jar -(Cause: " + ThrowableUtil.getAllMessages(e) + + "] is a plugin jar -(Cause: " + ThrowableUtil.getAllMessages(e1) + "). It will be ignored. Please fix that file or remove it."); continue; }
commit 7b8e679d0d7007e9322b528087071bdbfe805abd Author: Heiko W. Rupp pilhuhn@fedorapeople.org Date: Wed Dec 16 21:15:07 2009 +0100
Return the status id for a successful status update.
diff --git a/modules/enterprise/server/plugins/alert-microblog/src/main/java/org/rhq/enterprise/server/plugins/alertMicroblog/MicroblogSender.java b/modules/enterprise/server/plugins/alert-microblog/src/main/java/org/rhq/enterprise/server/plugins/alertMicroblog/MicroblogSender.java index e95b6f0..cf7136b 100644 --- a/modules/enterprise/server/plugins/alert-microblog/src/main/java/org/rhq/enterprise/server/plugins/alertMicroblog/MicroblogSender.java +++ b/modules/enterprise/server/plugins/alert-microblog/src/main/java/org/rhq/enterprise/server/plugins/alertMicroblog/MicroblogSender.java @@ -18,6 +18,7 @@ */ package org.rhq.enterprise.server.plugins.alertMicroblog;
+import twitter4j.Status; import twitter4j.Twitter; import twitter4j.TwitterException;
@@ -61,8 +62,8 @@ public class MicroblogSender extends AlertSender {
SenderResult result ; try { - twitter.updateStatus(b.toString()); - result = new SenderResult(ResultState.SUCCESS,"Send notification to " + baseUrl + " as user " + user); + Status status = twitter.updateStatus(b.toString()); + result = new SenderResult(ResultState.SUCCESS,"Send notification to " + baseUrl + " as user " + user + " id: " + status.getId()); } catch (TwitterException e) { log.warn("Notification via Microblog failed: ", e); result = new SenderResult(ResultState.FAILURE,"Sending failed :" + e.getMessage());
commit 7969a2e17abd15898ad4cb598490dda50cc045b6 Merge: 989b5a2... b68a663... Author: Heiko W. Rupp pilhuhn@fedorapeople.org Date: Wed Dec 16 21:14:16 2009 +0100
Merge branch 'alertPlugin' of ssh://git.fedorahosted.org/git/rhq/rhq into alertPlugin
commit b68a66338f9b216c525851df7aa638c6f113a89a Author: John Mazzitelli mazz@redhat.com Date: Wed Dec 16 15:10:02 2009 -0500
opps.. show not show the link if plugin is undeployed, but still show if its just disabled
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-list.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-list.xhtml index bca336f..230098e 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-list.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-list.xhtml @@ -162,13 +162,13 @@ <h:outputText styleClass="headerText" value="Name"/> </f:facet>
- <h:outputLink value="/rhq/admin/plugin/plugin-details-view.xhtml" rendered="#{serverPlugin.enabled}"> + <h:outputLink value="/rhq/admin/plugin/plugin-details-view.xhtml" rendered="#{serverPlugin.status eq 'INSTALLED'}"> <f:param name="plugin" value="#{serverPlugin.name}"/> <f:param name="deployment" value="SERVER"/> <f:param name="pluginType" value="#{serverPlugin.type}"/> <h:outputText value="#{serverPlugin.displayName}"/> </h:outputLink> - <h:outputText value="#{serverPlugin.displayName}" rendered="#{!serverPlugin.enabled}"/> + <h:outputText value="#{serverPlugin.displayName}" rendered="#{serverPlugin.status ne 'INSTALLED'}"/>
</rich:column>
commit f33274d83b86b881088cbb6ffe93578714153497 Author: Partha Aji paji@redhat.com Date: Wed Dec 16 13:04:48 2009 -0500
Remote apt dependencies from maven pom's since apt got moved to /etc
diff --git a/modules/enterprise/server/ear/pom.xml b/modules/enterprise/server/ear/pom.xml index a622266..92d255c 100644 --- a/modules/enterprise/server/ear/pom.xml +++ b/modules/enterprise/server/ear/pom.xml @@ -232,12 +232,6 @@
<artifactItem> <groupId>org.rhq</groupId> - <artifactId>rhq-apt-plugin</artifactId> - <version>${project.version}</version> - </artifactItem> - - <artifactItem> - <groupId>org.rhq</groupId> <artifactId>rhq-augeas-plugin</artifactId> <version>${project.version}</version> </artifactItem> diff --git a/modules/plugins/validate-all-plugins/pom.xml b/modules/plugins/validate-all-plugins/pom.xml index e668600..287ccd1 100644 --- a/modules/plugins/validate-all-plugins/pom.xml +++ b/modules/plugins/validate-all-plugins/pom.xml @@ -39,7 +39,6 @@ <classpath> <pathelement path="${test.classpath}" /> <pathelement location="../apache/target/rhq-apache-plugin-${project.version}.jar" /> - <pathelement location="../apt/target/rhq-apt-plugin-${project.version}.jar" /> <pathelement location="../augeas/target/rhq-augeas-plugin-${project.version}.jar" /> <pathelement location="../database/target/rhq-database-plugin-${project.version}.jar" /> <pathelement location="../grub/target/rhq-grub-plugin-${project.version}.jar" />
commit 3375f7f7725d2a25beac33cbd43277e622623ef8 Author: John Mazzitelli mazz@redhat.com Date: Wed Dec 16 13:00:18 2009 -0500
indent to match the rest of the file
diff --git a/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml b/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml index 53a8895..ccca4f1 100644 --- a/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml +++ b/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml @@ -2162,43 +2162,44 @@ <!-- add the new column that indicates what type of plugin this is (e.g. alert, generic, content) - for server plugins only --> <schema-addColumn table="RHQ_PLUGIN" column="PTYPE" columnType="VARCHAR2" precision="200"/> </schemaSpec> - <schemaSpec version="2.70"> - <schema-addColumn table="RHQ_ALERT" column="ACK_TIME" columnType="LONG" /> - <schema-addColumn table="RHQ_ALERT" column="ACK_BY_ID" columnType="INTEGER" /> - <schema-directSQL> - <statement> - ALTER TABLE RHQ_ALERT - ADD CONSTRAINT RHQ_ALERT_SUBJECT_ID_FKEY - FOREIGN KEY (ACK_BY_ID) - REFERENCES RHQ_SUBJECT(ID) - </statement> - </schema-directSQL> - <schema-addColumn table="RHQ_ALERT_NOTIFICATION" column="ALERT_SENDER_NAME" columnType="VARCHAR2"/> - <schema-addColumn table="RHQ_ALERT_NOTIFICATION" column="ALERT_CONFIG_ID" columnType="INTEGER"/> - <schema-directSQL> - <statement> - ALTER TABLE RHQ_ALERT_NOTIFICATION - ADD CONSTRAINT RHQ_ALERT_CONFIG_ID_FKEY - FOREIGN KEY (ALERT_CONFIG_ID) - REFERENCES RHQ_CONFIG(ID) - </statement> - </schema-directSQL> - - </schemaSpec> - <schemaSpec version="2.70.1"> - <schema-directSQL> - <statement> - CREATE TABLE RHQ_ALERT_NOTIF_TEMPL ( ID INTEGER ) - </statement> - <statement> - ALTER TABLE RHQ_ALERT_NOTIF_TEMPL - ADD CONSTRAINT RHQ_ALERT_NOTIF_TEMPL_KEY - PRIMARY KEY ( ID ) - </statement> - </schema-directSQL> - <schema-addColumn table="RHQ_ALERT_NOTIF_TEMPL" column="NAME" columnType="VARCHAR2"/> - <schema-addColumn table="RHQ_ALERT_NOTIF_TEMPL" column="DESCRIPTION" columnType="VARCHAR2"/> - </schemaSpec> + + <schemaSpec version="2.70"> + <schema-addColumn table="RHQ_ALERT" column="ACK_TIME" columnType="LONG" /> + <schema-addColumn table="RHQ_ALERT" column="ACK_BY_ID" columnType="INTEGER" /> + <schema-directSQL> + <statement> + ALTER TABLE RHQ_ALERT + ADD CONSTRAINT RHQ_ALERT_SUBJECT_ID_FKEY + FOREIGN KEY (ACK_BY_ID) + REFERENCES RHQ_SUBJECT(ID) + </statement> + </schema-directSQL> + <schema-addColumn table="RHQ_ALERT_NOTIFICATION" column="ALERT_SENDER_NAME" columnType="VARCHAR2"/> + <schema-addColumn table="RHQ_ALERT_NOTIFICATION" column="ALERT_CONFIG_ID" columnType="INTEGER"/> + <schema-directSQL> + <statement> + ALTER TABLE RHQ_ALERT_NOTIFICATION + ADD CONSTRAINT RHQ_ALERT_CONFIG_ID_FKEY + FOREIGN KEY (ALERT_CONFIG_ID) + REFERENCES RHQ_CONFIG(ID) + </statement> + </schema-directSQL> + </schemaSpec> + + <schemaSpec version="2.70.1"> + <schema-directSQL> + <statement> + CREATE TABLE RHQ_ALERT_NOTIF_TEMPL ( ID INTEGER ) + </statement> + <statement> + ALTER TABLE RHQ_ALERT_NOTIF_TEMPL + ADD CONSTRAINT RHQ_ALERT_NOTIF_TEMPL_KEY + PRIMARY KEY ( ID ) + </statement> + </schema-directSQL> + <schema-addColumn table="RHQ_ALERT_NOTIF_TEMPL" column="NAME" columnType="VARCHAR2"/> + <schema-addColumn table="RHQ_ALERT_NOTIF_TEMPL" column="DESCRIPTION" columnType="VARCHAR2"/> + </schemaSpec>
</dbupgrade> </target>
commit 9157fa4cc332f16f736a21c714d04d91b3eb7303 Author: John Mazzitelli mazz@redhat.com Date: Wed Dec 16 12:57:23 2009 -0500
fixing dbsetup - need to set version in pom
diff --git a/modules/core/dbutils/pom.xml b/modules/core/dbutils/pom.xml index 0ab3e72..271beee 100644 --- a/modules/core/dbutils/pom.xml +++ b/modules/core/dbutils/pom.xml @@ -22,7 +22,7 @@
<properties> <scm.module.path>modules/core/dbutils/</scm.module.path> - <db.schema.version>2.70</db.schema.version> + <db.schema.version>2.70.1</db.schema.version> </properties>
<dependencies>
commit e3804770fa5096454f514cd5682722e60b0b7e72 Merge: dee3640... d79070a... Author: John Mazzitelli mazz@redhat.com Date: Wed Dec 16 12:01:10 2009 -0500
Merge branch 'master' into alertPlugin
commit 989b5a2029a35786878edfcf4c242cc3e2fabde8 Author: Heiko W. Rupp pilhuhn@fedorapeople.org Date: Wed Dec 16 17:42:43 2009 +0100
Don't refresh() as this loses the notification logs
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerBean.java index 20fa9c8..7f4477f 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerBean.java @@ -777,7 +777,6 @@ public class AlertManagerBean implements AlertManagerLocal, AlertManagerRemote { * @return human readable condition log */ public String prettyPrintAlertConditions(Alert alert) { - entityManager.refresh(alert); return prettyPrintAlertConditions(alert.getConditionLogs()); }
commit dee3640e72f92ec0c4f537be07812db8a704f519 Author: John Mazzitelli mazz@redhat.com Date: Wed Dec 16 10:29:36 2009 -0500
fix misspelling in "backinBean"
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSenderPluginManager.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSenderPluginManager.java index 5d1a125..cd4e072 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSenderPluginManager.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSenderPluginManager.java @@ -24,9 +24,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map;
- import org.apache.commons.logging.Log; -import org.w3c.dom.Element;
import org.rhq.core.domain.alert.notification.AlertNotification; import org.rhq.core.domain.configuration.Configuration; @@ -50,10 +48,10 @@ import org.rhq.enterprise.server.xmlschema.generated.serverplugin.alert.CustomUi public class AlertSenderPluginManager extends ServerPluginManager {
private final Log log = getLog(); - private Map<String,String> pluginClassByName = new HashMap<String, String>(); - private Map<String,ServerPluginEnvironment> pluginEnvByName = new HashMap<String, ServerPluginEnvironment>(); - private Map<String,AlertSenderInfo> senderInfoByName = new HashMap<String, AlertSenderInfo>(); - private Map<String,String> backinBeanByName = new HashMap<String, String>(); + private Map<String, String> pluginClassByName = new HashMap<String, String>(); + private Map<String, ServerPluginEnvironment> pluginEnvByName = new HashMap<String, ServerPluginEnvironment>(); + private Map<String, AlertSenderInfo> senderInfoByName = new HashMap<String, AlertSenderInfo>(); + private Map<String, String> backingBeanByName = new HashMap<String, String>();
public AlertSenderPluginManager(AbstractTypeServerPluginContainer pc) { super(pc); @@ -69,9 +67,9 @@ public class AlertSenderPluginManager extends ServerPluginManager { * @throws Exception */ @Override - public void loadPlugin(ServerPluginEnvironment env,boolean enable) throws Exception { + public void loadPlugin(ServerPluginEnvironment env, boolean enable) throws Exception { log.info("Start loading alert plugin " + env.getPluginKey().getPluginName()); - super.loadPlugin(env,enable); + super.loadPlugin(env, enable);
AlertPluginDescriptorType type = (AlertPluginDescriptorType) env.getPluginDescriptor();
@@ -80,14 +78,13 @@ public class AlertSenderPluginManager extends ServerPluginManager { className = type.getPackage() + "." + className; } try { - Class.forName(className,false,env.getPluginClassLoader()); - } - catch (Exception e) { - log.error("Can't find pluginClass " + className + ". Plugin " + env.getPluginKey().getPluginName() + " will be ignored"); + Class.forName(className, false, env.getPluginClassLoader()); + } catch (Exception e) { + log.error("Can't find pluginClass " + className + ". Plugin " + env.getPluginKey().getPluginName() + + " will be ignored"); try { unloadPlugin(env.getPluginKey().getPluginName()); - } - catch (Throwable t) { + } catch (Throwable t) { log.warn(" +--> unload failed too " + t.getMessage()); } return; @@ -95,7 +92,7 @@ public class AlertSenderPluginManager extends ServerPluginManager {
// The short name is basically the key into the plugin String shortName = type.getShortName(); - pluginClassByName.put(shortName,className); + pluginClassByName.put(shortName, className);
// // Ok, we have a valid plugin class, so we can look for other things @@ -105,15 +102,15 @@ public class AlertSenderPluginManager extends ServerPluginManager { String uiSnippetPath; URL uiSnippetUrl = null; CustomUi customUI = type.getCustomUi(); - if (customUI!=null) { + if (customUI != null) { uiSnippetPath = customUI.getUiSnippetName();
try { uiSnippetUrl = env.getPluginClassLoader().getResource(uiSnippetPath); log.info("UI snipped for " + shortName + " is at " + uiSnippetUrl); - } - catch (Exception e) { - log.error("No valid ui snippet provided, but <custom-ui> given for sender plugin " + shortName + "Error is "+ e.getMessage()); + } catch (Exception e) { + log.error("No valid ui snippet provided, but <custom-ui> given for sender plugin " + shortName + + "Error is " + e.getMessage()); log.error("Plugin will be ignored"); return; } @@ -124,10 +121,9 @@ public class AlertSenderPluginManager extends ServerPluginManager { className = type.getPackage() + "." + className; } try { - Class.forName(className,true,env.getPluginClassLoader()); // TODO how make this available to Seam and the Web-CL ? - backinBeanByName.put(shortName,className); - } - catch (Throwable t ) { + Class.forName(className, true, env.getPluginClassLoader()); // TODO how make this available to Seam and the Web-CL ? + backingBeanByName.put(shortName, className); + } catch (Throwable t) { log.error("Backing bean " + className + " not found for plugin " + shortName); } } @@ -136,16 +132,16 @@ public class AlertSenderPluginManager extends ServerPluginManager { info.setUiSnippetUrl(uiSnippetUrl); senderInfoByName.put(shortName, info);
- pluginEnvByName.put(shortName,env); + pluginEnvByName.put(shortName, env);
}
@Override protected void unloadPlugin(String pluginName) throws Exception { - log.info("Unloading plugin " + pluginName ); + log.info("Unloading plugin " + pluginName); super.unloadPlugin(pluginName); - String shortName=null; - for (AlertSenderInfo info: senderInfoByName.values()) { + String shortName = null; + for (AlertSenderInfo info : senderInfoByName.values()) { if (info.getPluginName().equals(pluginName)) { shortName = info.getShortName(); break; @@ -154,7 +150,7 @@ public class AlertSenderPluginManager extends ServerPluginManager { pluginClassByName.remove(shortName); senderInfoByName.remove(shortName); pluginEnvByName.remove(shortName); - backinBeanByName.remove(shortName); + backingBeanByName.remove(shortName); }
/** @@ -168,16 +164,15 @@ public class AlertSenderPluginManager extends ServerPluginManager {
String senderName = notification.getSenderName(); String className = pluginClassByName.get(senderName); - if (className==null) { + if (className == null) { log.error("getAlertSender: No pluginClass found for sender: " + senderName); return null; } ServerPluginEnvironment env = pluginEnvByName.get(senderName); Class clazz; try { - clazz = Class.forName(className,true,env.getPluginClassLoader()); - } - catch (Exception e) { + clazz = Class.forName(className, true, env.getPluginClassLoader()); + } catch (Exception e) { log.error(e); // TODO return null; } @@ -186,10 +181,10 @@ public class AlertSenderPluginManager extends ServerPluginManager { try { sender = (AlertSender) clazz.newInstance(); } catch (InstantiationException e) { - e.printStackTrace(); // TODO: Customise this generated block + e.printStackTrace(); // TODO: Customise this generated block return null; } catch (IllegalAccessException e) { - e.printStackTrace(); // TODO: Customise this generated block + e.printStackTrace(); // TODO: Customise this generated block return null; }
@@ -212,7 +207,7 @@ public class AlertSenderPluginManager extends ServerPluginManager { plugin = pluginsMgr.getServerPluginRelationships(plugin);
sender.preferences = plugin.getPluginConfiguration(); - if (sender.preferences==null) { + if (sender.preferences == null) { sender.preferences = new Configuration(); // Safety measure }
@@ -234,21 +229,19 @@ public class AlertSenderPluginManager extends ServerPluginManager { }
public AlertBackingBean getBackingBeanForSender(String shortName) { - String name = backinBeanByName.get(shortName); + String name = backingBeanByName.get(shortName); ServerPluginEnvironment env = pluginEnvByName.get(shortName); Class clazz; try { - clazz = Class.forName(name,true,env.getPluginClassLoader()); - } - catch (Exception e) { + clazz = Class.forName(name, true, env.getPluginClassLoader()); + } catch (Exception e) { log.error("Can't load class " + name + ": " + e.getMessage()); return null; } - AlertBackingBean bean = null ; + AlertBackingBean bean = null; try { bean = (AlertBackingBean) clazz.newInstance(); - } - catch (Exception e) { + } catch (Exception e) { log.error("Can't instantiate " + name + ": " + e.getMessage()); } return bean;
commit d79070afb50423de65d6d0af0fdc92f3ea1a8e65 Author: John Mazzitelli mazz@redhat.com Date: Wed Dec 16 10:08:15 2009 -0500
new eclipse tool
diff --git a/etc/eclipse-tools/maven/RHQ Maven Build - Dev Profile Full Enterprise with DBSetup.launch b/etc/eclipse-tools/maven/RHQ Maven Build - Dev Profile Full Enterprise with DBSetup.launch new file mode 100644 index 0000000..1b1ed7c --- /dev/null +++ b/etc/eclipse-tools/maven/RHQ Maven Build - Dev Profile Full Enterprise with DBSetup.launch @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<launchConfiguration type="org.eclipse.ui.externaltools.ProgramLaunchConfigurationType"> +<stringAttribute key="bad_container_name" value="\rhq\etc\eclipse-tools\maven"/> +<booleanAttribute key="org.eclipse.debug.core.appendEnvironmentVariables" value="true"/> +<listAttribute key="org.eclipse.debug.ui.favoriteGroups"> +<listEntry value="org.eclipse.ui.externaltools.launchGroup"/> +</listAttribute> +<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="${env_var:M2_HOME}/bin/${MAVEN_EXE}"/> +<stringAttribute key="org.eclipse.ui.externaltools.ATTR_TOOL_ARGUMENTS" value="-o -Dmaven.test.skip=true -Pdev,enterprise -Ddbsetup install"/> +<stringAttribute key="org.eclipse.ui.externaltools.ATTR_WORKING_DIRECTORY" value="${workspace_loc:/rhq}"/> +</launchConfiguration>
commit 58839f7f625020099761b0b64fa247b45568d1fb Author: John Mazzitelli mazz@redhat.com Date: Wed Dec 16 10:04:27 2009 -0500
fix log message format
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginManager.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginManager.java index acef4cf..e86e687 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginManager.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginManager.java @@ -534,10 +534,10 @@ public class ServerPluginManager { throw new Exception("Could not instantiate plugin class [" + className + "] from plugin environment [" + environment + "]", e); } catch (IllegalAccessException e) { - throw new Exception("Could not access plugin class " + className + "] from plugin environment [" + throw new Exception("Could not access plugin class [" + className + "] from plugin environment [" + environment + "]", e); } catch (ClassNotFoundException e) { - throw new Exception("Could not find plugin class " + className + "] from plugin environment [" + throw new Exception("Could not find plugin class [" + className + "] from plugin environment [" + environment + "]", e); } catch (NullPointerException npe) { throw new Exception("Plugin class was 'null' in plugin environment [" + environment + "]", npe);
commit 5d7c13ae3bbbdce1ebd05796fc7c6528537efe29 Author: Adam Young ayoung@redhat.com Date: Wed Dec 16 09:15:33 2009 -0500
ability to turn off toolbar. Read only is set from render. replaced some String literals with symbolic constants.
diff --git a/.classpath b/.classpath index 27f5303..a3aef1e 100644 --- a/.classpath +++ b/.classpath @@ -92,8 +92,8 @@ <classpathentry kind="src" path="modules/plugins/samba/src/test/java"/> <classpathentry kind="src" path="modules/plugins/sudoers/src/main/java"/> <classpathentry kind="src" path="modules/plugins/sudoers/src/test/java"/> - <classpathentry kind="src" path="modules/plugins/postfix/src/main/java"/> - <classpathentry kind="src" path="modules/plugins/postfix/src/test/java"/> + <classpathentry kind="src" path="modules/plugins/postfix/src/main/java"/> + <classpathentry kind="src" path="modules/plugins/postfix/src/test/java"/> <classpathentry kind="src" path="modules/plugins/cron/src/main/java"/> <classpathentry kind="src" path="modules/plugins/hudson/src/main/java"/> <classpathentry kind="src" path="modules/plugins/platform/src/test/java"/> @@ -165,8 +165,8 @@ <classpathentry exported="true" kind="var" path="M2_REPO/commons-lang/commons-lang/2.4/commons-lang-2.4.jar"/> <classpathentry exported="true" kind="var" path="M2_REPO/javax/faces/jsf-api/1.2_12/jsf-api-1.2_12.jar" sourcepath="/M2_REPO/javax/faces/jsf-api/1.2_12/jsf-api-1.2_12-sources.jar"/> <classpathentry exported="true" kind="var" path="M2_REPO/javax/faces/jsf-impl/1.2_12/jsf-impl-1.2_12.jar" sourcepath="/M2_REPO/javax/faces/jsf-impl/1.2_12/jsf-impl-1.2_12-sources.jar"/> - <classpathentry exported="true" kind="var" path="M2_REPO/javax/el/el-api/1.0/el-api-1.0.jar"/> - <classpathentry exported="true" kind="var" path="M2_REPO/com/sun/facelets/jsf-facelets/1.1.14/jsf-facelets-1.1.14.jar" sourcepath="/M2_REPO/com/sun/facelets/jsf-facelets/1.1.13/jsf-facelets-1.1.13-sources.jar"/> + <classpathentry exported="true" kind="var" path="M2_REPO/javax/el/el-api/1.0/el-api-1.0.jar" sourcepath="/M2_REPO/javax/el/el-api/1.0/el-api-1.0-sources.jar"/> + <classpathentry exported="true" kind="var" path="M2_REPO/com/sun/facelets/jsf-facelets/1.1.14/jsf-facelets-1.1.14.jar" sourcepath="/M2_REPO/com/sun/facelets/jsf-facelets/1.1.14/jsf-facelets-1.1.14-sources.jar"/> <classpathentry exported="true" kind="var" path="M2_REPO/mc4j/org-mc4j-ems/1.2.11/org-mc4j-ems-1.2.11.jar" sourcepath="/M2_REPO/mc4j/org-mc4j-ems/1.2.11/org-mc4j-ems-1.2.11-sources.jar"/> <classpathentry exported="true" kind="var" path="M2_REPO/org/opensymphony/quartz/quartz/1.6.5/quartz-1.6.5.jar" sourcepath="/M2_REPO/org/opensymphony/quartz/quartz/1.6.5/quartz-1.6.5-sources.jar"/> <classpathentry exported="true" kind="var" path="M2_REPO/javax/mail/mail/1.3.1/mail-1.3.1.jar"/> diff --git a/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/AbstractConfigurationComponent.java b/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/AbstractConfigurationComponent.java index 2fe72ee..e49ead1 100644 --- a/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/AbstractConfigurationComponent.java +++ b/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/AbstractConfigurationComponent.java @@ -24,6 +24,7 @@ package org.rhq.core.gui.configuration;
import java.util.UUID;
+import javax.faces.component.UIComponent; import javax.faces.component.UIComponentBase; import javax.faces.context.FacesContext;
@@ -49,18 +50,30 @@ public abstract class AbstractConfigurationComponent extends UIComponentBase imp private static final String NULL_CONFIGURATION_STYLE_ATTRIBUTE = "nullConfigurationStyle"; private static final String LIST_NAME_ATTRIBUTE = "listName"; private static final String LIST_INDEX_ATTRIBUTE = "listIndex"; - private static final String READ_ONLY_ATTRIBUTE = "readOnly"; + public static final String READ_ONLY_ATTRIBUTE = "readOnly"; + public static final String SHOW_TOOLBAR_ATTRIBUTE = "readOnly"; private static final String FULLY_EDITABLE_ATTRIBUTE = "fullyEditable";
- private Boolean readOnly = true; + private Boolean showToolbar; + private Boolean readOnly; private Boolean fullyEditable; private String listName; private Integer listIndex; + + public UIComponent getToolbar() { + return toolbar; + } + + public void setToolbar(UIComponent toolbar) { + this.toolbar = toolbar; + } + private String nullConfigurationDefinitionMessage; private String nullConfigurationMessage; private String nullConfigurationStyle; private boolean prevalidate; private boolean isGroup; + private UIComponent toolbar;
public String getFamily() { return COMPONENT_FAMILY; @@ -93,6 +106,21 @@ public abstract class AbstractConfigurationComponent extends UIComponentBase imp this.readOnly = readOnly; }
+ public Boolean getShowToolbar() { + if (this.showToolbar == null) { + this.showToolbar = FacesComponentUtility + .getExpressionAttribute(this, SHOW_TOOLBAR_ATTRIBUTE, Boolean.class); + } + if (this.showToolbar == null) { + this.showToolbar = false; + } + return showToolbar; + } + + public void setShowToolbar(Boolean showToolbar) { + this.showToolbar = showToolbar; + } + public boolean isFullyEditable() { if (this.fullyEditable == null) { this.fullyEditable = FacesComponentUtility.getExpressionAttribute(this, FULLY_EDITABLE_ATTRIBUTE, @@ -190,7 +218,7 @@ public abstract class AbstractConfigurationComponent extends UIComponentBase imp @Override public Object saveState(FacesContext facesContext) { if (this.stateValues == null) { - this.stateValues = new Object[7]; + this.stateValues = new Object[8]; }
this.stateValues[0] = super.saveState(facesContext); @@ -200,6 +228,7 @@ public abstract class AbstractConfigurationComponent extends UIComponentBase imp this.stateValues[4] = this.listIndex; this.stateValues[5] = this.prevalidate; this.stateValues[6] = this.isGroup; + this.stateValues[7] = this.getShowToolbar(); return this.stateValues; }
@@ -213,6 +242,7 @@ public abstract class AbstractConfigurationComponent extends UIComponentBase imp this.listIndex = (Integer) this.stateValues[4]; this.prevalidate = (Boolean) this.stateValues[5]; this.isGroup = (Boolean) this.stateValues[6]; + this.showToolbar = (Boolean) this.stateValues[7]; }
public boolean getShouldShowRaw() { diff --git a/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/ConfigRenderer.java b/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/ConfigRenderer.java index e3f0c16..278d619 100644 --- a/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/ConfigRenderer.java +++ b/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/ConfigRenderer.java @@ -26,6 +26,7 @@ import java.io.IOException; import java.util.List; import java.util.Map;
+import javax.el.MethodExpression; import javax.el.ValueExpression; import javax.faces.application.FacesMessage; import javax.faces.component.UIComponent; @@ -122,9 +123,12 @@ public class ConfigRenderer extends Renderer { } }
- Boolean readOnly = Boolean.valueOf(FacesContextUtility.getOptionalRequestParameter("readOnly")); + String readOnly = FacesContextUtility.getOptionalRequestParameter("readOnly"); + if (null != readOnly) { + configurationComponent.setReadOnly(Boolean.valueOf(readOnly)); + } + Boolean save = Boolean.valueOf(FacesContextUtility.getOptionalRequestParameter("save")); - configurationComponent.setReadOnly(readOnly);
if (component.getChildCount() == 0) addChildComponents(configurationComponent); @@ -178,6 +182,9 @@ public class ConfigRenderer extends Renderer { // Only create the child components the first time around (i.e. once per JSF lifecycle). if (component.getChildCount() == 0) addChildComponents(configurationComponent); + if (configurationComponent.getToolbar() != null) { + configurationComponent.getToolbar().setRendered(configurationComponent.getShowToolbar()); + } }
private boolean isAjaxRefresh(AbstractConfigurationComponent configurationComponent) { @@ -275,29 +282,39 @@ public class ConfigRenderer extends Renderer { }
private void addStructuredConfig(AbstractConfigurationComponent configurationComponent) { - UIPanel toolbarPanel = FacesComponentUtility.addBlockPanel(configurationComponent, configurationComponent, - "summary-props-table"); - if (configurationComponent.isReadOnly()) { - HtmlCommandLink editLink = FacesComponentUtility.addCommandLink(toolbarPanel, configurationComponent); - FacesComponentUtility.addGraphicImage(editLink, configurationComponent, "/images/edit.png", "Edit"); - FacesComponentUtility.addOutputText(editLink, configurationComponent, "Edit", ""); - FacesComponentUtility.addParameter(editLink, configurationComponent, "readOnly", Boolean.toString(false)); - - } else { - HtmlCommandLink saveLink = FacesComponentUtility.addCommandLink(toolbarPanel, configurationComponent); - FacesComponentUtility.addGraphicImage(saveLink, configurationComponent, "/images/save.png", "Save"); - FacesComponentUtility.addOutputText(saveLink, configurationComponent, "Save", ""); - FacesComponentUtility.addParameter(saveLink, configurationComponent, "save", Boolean.toString(true)); - FacesComponentUtility.addParameter(saveLink, configurationComponent, "readOnly", Boolean.toString(true)); - } + { + UIPanel toolbarPanel = FacesComponentUtility.addBlockPanel(configurationComponent, configurationComponent, + "summary-props-table"); + if (configurationComponent.isReadOnly()) { + HtmlOutputLink editLink = FacesComponentUtility.addOutputLink(toolbarPanel, configurationComponent, + "edit.xhtml"); + FacesComponentUtility.addGraphicImage(editLink, configurationComponent, "/images/edit.png", "Edit"); + FacesComponentUtility.addOutputText(editLink, configurationComponent, "Edit", ""); + FacesComponentUtility.addParameter(editLink, configurationComponent, "readOnly", Boolean + .toString(false)); + FacesComponentUtility.addParameter(editLink, configurationComponent, "id", FacesContextUtility + .getRequiredRequestParameter("id")); + } else { + HtmlCommandLink saveLink = FacesComponentUtility.addCommandLink(toolbarPanel, configurationComponent); + FacesComponentUtility.addGraphicImage(saveLink, configurationComponent, "/images/save.png", "Save"); + FacesComponentUtility.addOutputText(saveLink, configurationComponent, "Save", ""); + FacesComponentUtility.addParameter(saveLink, configurationComponent, "save", Boolean.toString(true)); + FacesComponentUtility + .addParameter(saveLink, configurationComponent, "readOnly", Boolean.toString(true)); + + saveLink.setActionExpression(getSaveActionExpression());
- if (configurationComponent.getConfigurationDefinition().getConfigurationFormat().isRawSupported()) { - HtmlCommandLink toRawLink = FacesComponentUtility.addCommandLink(toolbarPanel, configurationComponent); - FacesComponentUtility.addGraphicImage(toRawLink, configurationComponent, "/images/raw.png", "showRaw"); - FacesComponentUtility.addOutputText(toRawLink, configurationComponent, "showRaw", ""); - FacesComponentUtility.addParameter(toRawLink, configurationComponent, "showRaw", Boolean.TRUE.toString()); - FacesComponentUtility.addParameter(toRawLink, configurationComponent, "readOnly", Boolean - .toString(configurationComponent.isReadOnly())); + } + if (configurationComponent.getConfigurationDefinition().getConfigurationFormat().isRawSupported()) { + HtmlCommandLink toRawLink = FacesComponentUtility.addCommandLink(toolbarPanel, configurationComponent); + FacesComponentUtility.addGraphicImage(toRawLink, configurationComponent, "/images/raw.png", "showRaw"); + FacesComponentUtility.addOutputText(toRawLink, configurationComponent, "showRaw", ""); + FacesComponentUtility.addParameter(toRawLink, configurationComponent, "showRaw", Boolean.TRUE + .toString()); + FacesComponentUtility.addParameter(toRawLink, configurationComponent, "readOnly", Boolean + .toString(configurationComponent.isReadOnly())); + } + configurationComponent.setToolbar(toolbarPanel); }
if (!configurationComponent.isReadOnly()) @@ -319,6 +336,13 @@ public class ConfigRenderer extends Renderer { .isFullyEditable(), false); }
+ private MethodExpression getSaveActionExpression() { + + MethodExpression actionExpression = null; + + return actionExpression; + } + private void addStructuredRawToggle(AbstractConfigurationComponent configurationComponent, boolean showRaw) { if (configurationComponent.getConfigurationDefinition().getConfigurationFormat().equals( ConfigurationFormat.STRUCTURED_AND_RAW)) { diff --git a/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/RawConfigUIComponent.java b/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/RawConfigUIComponent.java index ce42a54..2c9a1be 100644 --- a/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/RawConfigUIComponent.java +++ b/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/RawConfigUIComponent.java @@ -138,8 +138,8 @@ public class RawConfigUIComponent extends UIComponentBase { FacesComponentUtility.addParameter(link, idFactory, "path", raw.getPath()); FacesComponentUtility.addParameter(link, idFactory, "whichRaw", Integer.toString(rawCount++)); FacesComponentUtility.addParameter(link, idFactory, "showRaw", Boolean.TRUE.toString()); - readOnlyParms.add(FacesComponentUtility.addParameter(link, idFactory, "readOnly", Boolean - .toString(readOnly))); + readOnlyParms.add(FacesComponentUtility.addParameter(link, idFactory, + AbstractConfigurationComponent.READ_ONLY_ATTRIBUTE, Boolean.toString(readOnly)));
}
@@ -155,24 +155,32 @@ public class RawConfigUIComponent extends UIComponentBase { inputTextarea.setReadonly(readOnly); }
+ private HtmlOutputLink fullscreenLink; + private UIParameter fullScreenResourceIdParam; + private void addToolbar(ConfigurationDefinition configurationDefinition, UIPanel parent) { UIPanel toolbarPanel = FacesComponentUtility.addBlockPanel(parent, idFactory, "config-toolbar"); if (readOnly) { HtmlCommandLink editLink = FacesComponentUtility.addCommandLink(toolbarPanel, idFactory); FacesComponentUtility.addGraphicImage(editLink, idFactory, "/images/edit.png", "Edit"); FacesComponentUtility.addOutputText(editLink, idFactory, "Edit", ""); - FacesComponentUtility.addParameter(editLink, idFactory, "showStructured", Boolean.FALSE.toString()); + FacesComponentUtility.addParameter(editLink, idFactory, "showRaw", Boolean.TRUE.toString()); + FacesComponentUtility.addParameter(editLink, idFactory, AbstractConfigurationComponent.READ_ONLY_ATTRIBUTE, + Boolean.FALSE.toString()); } else { HtmlCommandLink saveLink = FacesComponentUtility.addCommandLink(toolbarPanel, idFactory); FacesComponentUtility.addGraphicImage(saveLink, idFactory, "/images/save.png", "Save"); FacesComponentUtility.addOutputText(saveLink, idFactory, "Save", ""); - FacesComponentUtility.addParameter(saveLink, idFactory, "showStructured", Boolean.FALSE.toString()); + FacesComponentUtility.addParameter(saveLink, idFactory, "showRaw", Boolean.FALSE.toString()); + FacesComponentUtility.addParameter(saveLink, idFactory, AbstractConfigurationComponent.READ_ONLY_ATTRIBUTE, + Boolean.TRUE.toString()); } { - HtmlCommandLink saveCommandLink = FacesComponentUtility.addCommandLink(toolbarPanel, idFactory); - FacesComponentUtility.addGraphicImage(saveCommandLink, idFactory, "/images/viewfullscreen.png", - "FullScreen"); - FacesComponentUtility.addOutputText(saveCommandLink, idFactory, "Full Screen", ""); + fullscreenLink = FacesComponentUtility.addOutputLink(toolbarPanel, idFactory, "view-full.xhtml"); + FacesComponentUtility + .addGraphicImage(fullscreenLink, idFactory, "/images/viewfullscreen.png", "FullScreen"); + FacesComponentUtility.addOutputText(fullscreenLink, idFactory, "Full Screen", ""); + fullScreenResourceIdParam = FacesComponentUtility.addParameter(fullscreenLink, idFactory, "id", ""); } if (!readOnly) { HtmlOutputLink uploadLink = FacesComponentUtility.addOutputLink(toolbarPanel, idFactory, "upload.xhtml"); @@ -200,10 +208,23 @@ public class RawConfigUIComponent extends UIComponentBase { public void encodeBegin(FacesContext context) throws IOException { // TODO Auto-generated method stub super.encodeBegin(context); + inputTextarea.setValue(rawMap.get(getSelectedPath()).getContentString()); for (UIParameter param : readOnlyParms) { param.setValue(Boolean.toString(readOnly)); }
+ String resourceId = FacesContextUtility.getOptionalRequestParameter("id"); + + if (null == resourceId) { + if (fullscreenLink != null) { + fullscreenLink.setRendered(false); + } + } else { + if (fullScreenResourceIdParam != null) { + fullScreenResourceIdParam.setValue(resourceId); + } + } + } } diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit.xhtml index a85f409..dffd02b 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit.xhtml @@ -49,7 +49,10 @@ THIS TEXT WILL BE REMOVED. configuration="#{ExistingResourceConfigurationUIBean.configuration}" nullConfigurationDefinitionMessage="#{ExistingResourceConfigurationUIBean.nullConfigurationDefinitionMessage}" nullConfigurationMessage="#{ExistingResourceConfigurationUIBean.nullConfigurationMessage}" - prevalidate="true"/> + prevalidate="true" + showToolbar="true" + readOnly="false" + />
<h:panelGrid columns="2" styleClass="buttons-table" columnClasses="button-cell" rendered="#{ExistingResourceConfigurationUIBean.configuration != null}"> <h:commandButton value="SAVE" action="#{ExistingResourceConfigurationUIBean.updateConfiguration}" diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view-full.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view-full.xhtml new file mode 100644 index 0000000..0491cf8 --- /dev/null +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view-full.xhtml @@ -0,0 +1,48 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<html xmlns="http://www.w3.org/1999/xhtml" + xmlns:h="http://java.sun.com/jsf/html" + xmlns:f="http://java.sun.com/jsf/core" + xmlns:ui="http://java.sun.com/jsf/facelets" + xmlns:c="http://java.sun.com/jstl/core" + xmlns:onc="http://jboss.org/on/component" + xmlns:a4j="http://richfaces.org/a4j" + xmlns:rich="http://richfaces.ajax4jsf.org/rich" + xmlns:s="http://jboss.com/products/seam/taglib%22%3E + +<ui:composition template="/rhq/layout/main.xhtml"> +<ui:param name="pageTitle" value="TODO Internationalize this"/> + +<ui:define name="breadcrumbs" > +<h:outputLink value="view.xhtml" action="navigateToUpload" > + <h:outputText value=" Back " /> + <f:param name="id" value="#{ResourceUIBean.id}" /> +</h:outputLink> + +</ui:define> + +<ui:define name="body"> + +<h:form id="editResourceConfigurationForm" > +<input type="hidden" name="id" value="#{ResourceUIBean.id}" /> + + <onc:config configurationDefinition="#{ExistingResourceConfigurationUIBean.configurationDefinition}" + configuration="#{ExistingResourceConfigurationUIBean.configuration}" + accessMapActionExpression="#{ExistingResourceConfigurationUIBean.accessMap}" + nullConfigurationDefinitionMessage="#{ExistingResourceConfigurationUIBean.nullConfigurationDefinitionMessage}" + nullConfigurationMessage="#{ExistingResourceConfigurationUIBean.nullConfigurationMessage}" + readOnly="true" + showToolbar="true" + prevalidate="true" + showRaw="true" + fullscreen="true" /> + + +</h:form> +</ui:define> + +</ui:composition> + +</html> + + diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view-raw-full.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view-raw-full.xhtml deleted file mode 100644 index e9e8c1a..0000000 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view-raw-full.xhtml +++ /dev/null @@ -1,38 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> - -<html xmlns="http://www.w3.org/1999/xhtml" - xmlns:h="http://java.sun.com/jsf/html" - xmlns:f="http://java.sun.com/jsf/core" - xmlns:ui="http://java.sun.com/jsf/facelets" - xmlns:c="http://java.sun.com/jstl/core" - xmlns:onc="http://jboss.org/on/component" - xmlns:a4j="http://richfaces.org/a4j" - xmlns:rich="http://richfaces.ajax4jsf.org/rich" - xmlns:s="http://jboss.com/products/seam/taglib%22%3E - -<ui:composition template="/rhq/layout/main.xhtml"> -<ui:param name="pageTitle" value="TODO Internationalize this"/> - -<ui:define name="breadcrumbs" > -<h:outputLink value="view-raw.xhtml" action="navigateToUpload" > - <h:outputText value=" Back " /> - <f:param name="id" value="#{ResourceUIBean.id}" /> -</h:outputLink> - -</ui:define> - -<ui:define name="body"> - -<h:form id="editResourceConfigurationForm" > -<input type="hidden" name="id" value="#{ResourceUIBean.id}" /> -<div> -<pre><h:outputText value="#{ExistingResourceConfigurationUIBean.currentContents}" /></pre> -</div> -</h:form> -</ui:define> - -</ui:composition> - -</html> - - diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml index d0cfa5c..40a917d 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml @@ -47,12 +47,14 @@ THIS TEXT WILL BE REMOVED. <!-- TODO remove the id version --> <input type="hidden" name="id" value="#{ResourceUIBean.id}"/>
- <onc:config configurationDefinition="#{ExistingResourceConfigurationUIBean.configurationDefinition}" - configuration="#{ExistingResourceConfigurationUIBean.configuration}" - accessMapActionExpression="#{ExistingResourceConfigurationUIBean.accessMap}" - nullConfigurationDefinitionMessage="#{ExistingResourceConfigurationUIBean.nullConfigurationDefinitionMessage}" - nullConfigurationMessage="#{ExistingResourceConfigurationUIBean.nullConfigurationMessage}" - prevalidate="true"/> + <onc:config configurationDefinition="#{ExistingResourceConfigurationViewUIBean.configurationDefinition}" + configuration="#{ExistingResourceConfigurationViewUIBean.configuration}" + accessMapActionExpression="#{ExistingResourceConfigurationViewUIBean.accessMap}" + nullConfigurationDefinitionMessage="#{ExistingResourceConfigurationViewUIBean.nullConfigurationDefinitionMessage}" + nullConfigurationMessage="#{ExistingResourceConfigurationViewUIBean.nullConfigurationMessage}" + readOnly="true" + showToolbar="true" + prevalidate="true"/> <input type="hidden" name="id" value="#{ResourceUIBean.id}"/>
</h:form>
commit d2c4a2d3799f627a61f006c73b5b51ba0e0550b2 Author: John Mazzitelli mazz@redhat.com Date: Tue Dec 15 15:36:57 2009 -0500
add some error messages to make it clear what's happening
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/plugin/PluginDeploymentScanner.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/plugin/PluginDeploymentScanner.java index 641d90e..7ec0020 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/plugin/PluginDeploymentScanner.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/plugin/PluginDeploymentScanner.java @@ -208,11 +208,18 @@ public class PluginDeploymentScanner implements PluginDeploymentScannerMBean { destinationDirectory = getAgentPluginDir(); } catch (Exception e) { try { + log.debug("[" + file.getAbsolutePath() + "] is not an agent plugin jar (Cause: " + + ThrowableUtil.getAllMessages(e) + "). Will see if its a server plugin jar"); + ServerPluginDescriptorUtil.loadPluginDescriptorFromUrl(file.toURI().toURL()); destinationDirectory = getServerPluginDir(); } catch (Exception e1) { // skip it, doesn't look like a valid plugin jar - log.warn("Does not look like [" + file.getAbsolutePath() + "] is a plugin jar - ignoring"); + File fixmeFile = new File(file.getAbsolutePath() + ".fixme"); + boolean renamed = file.renameTo(fixmeFile); + log.warn("Does not look like [" + (renamed ? fixmeFile : file).getAbsolutePath() + + "] is a plugin jar -(Cause: " + ThrowableUtil.getAllMessages(e) + + "). It will be ignored. Please fix that file or remove it."); continue; } }
commit 2d4e562f32814f683a754eabe829531b0b8e40df Merge: ed7ba67... 0050ae7... Author: Adam Young ayoung@redhat.com Date: Tue Dec 15 12:07:24 2009 -0500
Merge of current raw work with remote branch
diff --cc modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ExistingResourceConfigurationUIBean.java index c6d9b18,3189d79..2f11e11 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ExistingResourceConfigurationUIBean.java +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ExistingResourceConfigurationUIBean.java @@@ -401,4 -443,12 +402,4 @@@ public class ExistingResourceConfigurat return raws; }
- } - /** - * - */ - String selectedPath; - private TreeMap<String, RawConfiguration> raws; - TreeMap<String, RawConfiguration> modified = new TreeMap<String, RawConfiguration>(); - RawConfiguration current = null; - + }
commit ed7ba67209643e53b1fcd94fbb1a9c74e89bb80a Author: Adam Young ayoung@redhat.com Date: Tue Dec 15 10:48:47 2009 -0500
removed temporary file.
diff --git a/temp-testng-customsuite.xml b/temp-testng-customsuite.xml deleted file mode 100644 index b4645bb..0000000 --- a/temp-testng-customsuite.xml +++ /dev/null @@ -1,8 +0,0 @@ -<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd"> -<suite name="rhq" parallel=""> - <test verbose="2" name="org.rhq.core.gui.configuration.ConfigRendererTest" annotations="JDK"> - <classes> - <class name="org.rhq.core.gui.configuration.ConfigRendererTest"/> - </classes> - </test> -</suite>
commit 0050ae7cdf3e8e226f728b1d64f9effde315fa76 Author: John Sanda jsanda@redhat.com Date: Tue Dec 15 10:16:43 2009 -0500
Removing check for config property definitions in findResourceConfigurationUpdates()
The check does not really make sense in light of adding raw config. With a resource that supports raw config, the config does not have to have any properties.
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java index 586d603..fbae47d 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java @@ -842,11 +842,6 @@ public class ConfigurationManagerBean implements ConfigurationManagerLocal, Conf }
Resource resource = entityManager.find(Resource.class, resourceId); - ConfigurationDefinition configDef = resource.getResourceType().getResourceConfigurationDefinition(); - if ((configDef == null || configDef.getPropertyDefinitions().isEmpty()) - && configDef.getConfigurationFormat() == ConfigurationFormat.STRUCTURED) { - return new PageList<ResourceConfigurationUpdate>(pc); - }
pc.initDefaultOrderingField("cu.id", PageOrdering.DESC);
commit b9d47ee5c181247093123b4ad79b316cf28bc5bf Merge: 1ceec65... c5c871b... Author: Heiko W. Rupp pilhuhn@fedorapeople.org Date: Tue Dec 15 13:50:42 2009 +0100
Merge branch 'master' into alertPlugin
commit c5c871b003308b19ffbfd1b49dd65acb6d4e55e5 Author: Heiko W. Rupp pilhuhn@fedorapeople.org Date: Tue Dec 15 13:49:41 2009 +0100
Evaluate the script on each call to prevent issues with multi-threading.
diff --git a/modules/plugins/script2/src/main/java/org/rhq/modules/plugins/script2/ScriptComponent.java b/modules/plugins/script2/src/main/java/org/rhq/modules/plugins/script2/ScriptComponent.java index e388595..1df7f29 100644 --- a/modules/plugins/script2/src/main/java/org/rhq/modules/plugins/script2/ScriptComponent.java +++ b/modules/plugins/script2/src/main/java/org/rhq/modules/plugins/script2/ScriptComponent.java @@ -5,7 +5,7 @@ import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.Reader; -import java.util.HashSet; +import java.io.StringWriter; import java.util.Set;
import javax.script.Invocable; @@ -18,7 +18,6 @@ import org.apache.commons.logging.LogFactory;
import org.rhq.core.domain.configuration.Configuration; import org.rhq.core.domain.measurement.DataType; -import org.rhq.core.domain.measurement.MeasurementData; import org.rhq.core.domain.measurement.MeasurementDataTrait; import org.rhq.core.pluginapi.inventory.InvalidPluginConfigurationException; import org.rhq.core.domain.measurement.AvailabilityType; @@ -32,17 +31,21 @@ import org.rhq.core.pluginapi.operation.OperationContext; import org.rhq.core.pluginapi.operation.OperationFacet; import org.rhq.core.pluginapi.operation.OperationResult;
- +/** + * Run the show for the script2 plugin. + * + * We eval() the script for each call to getAvailability and getValues , as + * otherwise we may see failures, when evaluated script was evaluated on + * a different thread than the execution of invokeFunction. + * + * @author Heiko W. Rupp + */ public class ScriptComponent implements ResourceComponent, MeasurementFacet, OperationFacet { private final Log log = LogFactory.getLog(this.getClass());
- private static final int CHANGEME = 1; // TODO remove or change this - - private String scriptName; ScriptEngine engine; - Object scriptObject; - + private String theScript;
@@ -52,11 +55,10 @@ public class ScriptComponent implements ResourceComponent, MeasurementFacet, Ope */ public AvailabilityType getAvailability() {
- Object ret = null; - try { + engine.eval(theScript); Invocable inv = (Invocable) engine; - ret = inv.invokeFunction("avail"); + Object ret = inv.invokeFunction("avail"); if (ret instanceof Number) { int tmp = ((Number)ret).intValue(); if (tmp>0) @@ -78,7 +80,6 @@ public class ScriptComponent implements ResourceComponent, MeasurementFacet, Ope public void start(ResourceContext context) throws InvalidPluginConfigurationException, Exception {
Configuration conf = context.getPluginConfiguration(); - // TODO add code to start the resource / connection to it
String engineName = conf.getSimpleValue("language",null); if (engineName==null) @@ -87,8 +88,8 @@ public class ScriptComponent implements ResourceComponent, MeasurementFacet, Ope ScriptEngineManager seMgr = new ScriptEngineManager(); engine = seMgr.getEngineByName(engineName);
- scriptName = conf.getSimpleValue("scriptName",null); - if (scriptName==null) + String scriptName = conf.getSimpleValue("scriptName", null); + if (scriptName ==null) throw new InvalidPluginConfigurationException("No (valid) script name given");
File dataDir = context.getDataDirectory(); @@ -96,15 +97,23 @@ public class ScriptComponent implements ResourceComponent, MeasurementFacet, Ope if (!scriptFile.exists()) throw new InvalidPluginConfigurationException("Script does not exist at " + scriptFile.getAbsolutePath());
+ Reader reader; try { - Reader reader = new BufferedReader(new FileReader(scriptFile)); - engine.eval(reader); -// scriptObject = engine.get("new MyClass"); + reader = new BufferedReader(new FileReader(scriptFile)); + StringWriter writer = new StringWriter(); + int tmp; + while ((tmp=reader.read())!=-1) + writer.write(tmp); + + reader.close(); + theScript = writer.toString(); + writer.close(); + + engine.eval(theScript); } catch (ScriptException se) { throw new InvalidPluginConfigurationException(se.getMessage()); } - }
@@ -125,6 +134,15 @@ public class ScriptComponent implements ResourceComponent, MeasurementFacet, Ope */ public void getValues(MeasurementReport report, Set<MeasurementScheduleRequest> metrics) throws Exception {
+ try { + engine.eval(theScript); + } + catch (ScriptException se) { + log.debug(se.getMessage()); + return; + } + + for (MeasurementScheduleRequest req : metrics) {
Invocable inv = (Invocable) engine;
commit 4e7f1939c4cc1388d3cf9a5b35647684a3d7b033 Author: John Sanda jsanda@redhat.com Date: Tue Dec 15 07:36:52 2009 -0500
[BZ 537891] Fixing bug in which required query parameter was not getted appended to url
The resource id is expected to be a parameter in the request. When on edit-raw.xhtml and clicking the link to go back to structured, the resource id basically gets dropped and then navigating to any other page, tab, etc. that expects the id parameter results in an exception. I added a new navigation rule similar to one already defined for edit.xhtml (structured edit page) that adds the id to the request and does a server side redirect.
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ExistingResourceConfigurationUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ExistingResourceConfigurationUIBean.java index bb93d81..3189d79 100644 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ExistingResourceConfigurationUIBean.java +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ExistingResourceConfigurationUIBean.java @@ -417,7 +417,8 @@ public class ExistingResourceConfigurationUIBean extends AbstractConfigurationUI current = null; setConfiguration(configuration);
- return "/rhq/resource/configuration/edit.xhtml?currentResourceId=" + getResourceId(); +// return "/rhq/resource/configuration/edit.xhtml?currentResourceId=" + getResourceId(); + return SUCCESS_OUTCOME; }
void populateRaws() { @@ -450,4 +451,4 @@ public class ExistingResourceConfigurationUIBean extends AbstractConfigurationUI TreeMap<String, RawConfiguration> modified = new TreeMap<String, RawConfiguration>(); RawConfiguration current = null;
-} \ No newline at end of file +} diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-navigation/configuration-navigation.xml b/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-navigation/configuration-navigation.xml index 4443b36..bd0f1bf 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-navigation/configuration-navigation.xml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-navigation/configuration-navigation.xml @@ -23,6 +23,12 @@ <from-action>#{ConfigHelperUIBean.accessMap}</from-action> <to-view-id>/rhq/resource/configuration/view-map.xhtml</to-view-id> </navigation-case> + + <navigation-case> + <from-action>#{ExistingResourceConfigurationUIBean.switchTostructured}</from-action> + <to-view-id>/rhq/resource/configuration/edit.xhtml?id=#{param.id}</to-view-id> + <redirect/> + </navigation-case>
</navigation-rule>
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit-raw.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit-raw.xhtml index c01694e..bf05c9b 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit-raw.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit-raw.xhtml @@ -35,10 +35,10 @@ <a4j:form id="editResourceConfigurationForm"> <h:outputText value="#{messages.youareviewingraw}" /> - <h:panelGroup rendered="#{ExistingResourceConfigurationUIBean.structuredSupported}"> + <h:panelGroup rendered="#{ExistingResourceConfigurationUIBean.structuredSupported}"> <h:outputText value=" #{messages.switch2}" /> <h:commandLink action="#{ExistingResourceConfigurationUIBean.switchTostructured}"> - <s:conversationId /> + <f:param name="conversationId" value="#{conversation.id}"/> <f:param name="id" value="#{ResourceUIBean.id}" /> <h:outputText value=" #{messages.structured}" /> </h:commandLink>
commit bb02829fa61a25af1c848480482581cf260a8f36 Author: Heiko W. Rupp pilhuhn@fedorapeople.org Date: Tue Dec 15 12:31:32 2009 +0100
Prevent NPE on stop() if Augeas is not present on a system.
diff --git a/modules/plugins/augeas/src/main/java/org/rhq/plugins/augeas/AugeasConfigurationComponent.java b/modules/plugins/augeas/src/main/java/org/rhq/plugins/augeas/AugeasConfigurationComponent.java index a47423e..fa4e00a 100644 --- a/modules/plugins/augeas/src/main/java/org/rhq/plugins/augeas/AugeasConfigurationComponent.java +++ b/modules/plugins/augeas/src/main/java/org/rhq/plugins/augeas/AugeasConfigurationComponent.java @@ -89,7 +89,7 @@ public class AugeasConfigurationComponent<T extends ResourceComponent> implement private Augeas augeas; private AugeasNode resourceConfigRootNode; private String augeasRootPath; - + public void start(ResourceContext<T> resourceContext) throws InvalidPluginConfigurationException, Exception { this.resourceContext = resourceContext; this.resourceDescription = this.resourceContext.getResourceType() + " Resource with key [" @@ -112,7 +112,8 @@ public class AugeasConfigurationComponent<T extends ResourceComponent> implement }
public void stop() { - this.augeas.close(); + if (this.augeas!=null) + this.augeas.close(); }
public AvailabilityType getAvailability() {
commit 1ceec6560585faec09cda809f41cca543462a786 Author: Heiko W. Rupp pilhuhn@fedorapeople.org Date: Tue Dec 15 11:25:26 2009 +0100
More support for custom UI snippets and a custom backing bean of them. Still WIP
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/GenericAlertStuffUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/GenericAlertStuffUIBean.java new file mode 100644 index 0000000..4ec8173 --- /dev/null +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/GenericAlertStuffUIBean.java @@ -0,0 +1,99 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2009 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.gui.alert; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.jboss.seam.ScopeType; +import org.jboss.seam.annotations.Name; +import org.jboss.seam.annotations.Scope; +import org.jboss.seam.annotations.web.RequestParameter; + +import org.rhq.core.domain.alert.notification.AlertNotificationLog; +import org.rhq.enterprise.server.alert.AlertNotificationManagerLocal; +import org.rhq.enterprise.server.plugin.pc.alert.AlertBackingBean; +import org.rhq.enterprise.server.plugin.pc.alert.AlertSenderPluginManager; +import org.rhq.enterprise.server.util.LookupUtil; + +/** + * // TODO: Document this + * @author Heiko W. Rupp + */ +@Name("GenericAlertStuffUIBean") +//@Scope(ScopeType.STATELESS) +public class GenericAlertStuffUIBean { + + private final Log log = LogFactory.getLog(GenericAlertStuffUIBean.class); + + + @RequestParameter("sender") + String sender; + String value; + + public GenericAlertStuffUIBean() { + } + + public Map<String,String> getTheMap() { + + AlertNotificationManagerLocal mgr = LookupUtil.getAlertNotificationManager(); + AlertBackingBean bean = mgr.getBackingBeanForSender("Roles"); + Map<String, String> map ; + if (bean!=null) + map = bean.getMap(); + else + map = new HashMap<String,String>(); + + return map; + } + + + public String getTheString() { + + AlertNotificationManagerLocal mgr = LookupUtil.getAlertNotificationManager(); + AlertBackingBean bean = mgr.getBackingBeanForSender("Roles"); + + String res = ""; + if (bean !=null) + res = bean.getString(); + + return res; + } + + public String submitForm() { + + AlertNotificationManagerLocal mgr = LookupUtil.getAlertNotificationManager(); + AlertBackingBean bean = mgr.getBackingBeanForSender("Roles"); + + bean.submit(); + + return "OK"; + } + + public String getTheValue() { + return value; + } + + public void setTheValue(String value) { + this.value = value; + } +} diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerBean.java index 89d1cc1..9763b17 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerBean.java @@ -61,6 +61,7 @@ import org.rhq.enterprise.server.authz.RoleManagerLocal; import org.rhq.enterprise.server.configuration.ConfigurationManagerLocal; import org.rhq.enterprise.server.configuration.metadata.ConfigurationMetadataManagerLocal; import org.rhq.enterprise.server.plugin.ServerPluginsLocal; +import org.rhq.enterprise.server.plugin.pc.alert.AlertBackingBean; import org.rhq.enterprise.server.plugin.pc.alert.AlertSenderInfo; import org.rhq.enterprise.server.plugin.pc.alert.AlertSenderPluginManager; import org.rhq.enterprise.server.xmlschema.generated.serverplugin.ServerPluginDescriptorType; @@ -486,6 +487,19 @@ public class AlertNotificationManagerBean implements AlertNotificationManagerLoc return info; }
+ + /** + * Return the backing bean for the AlertSender with the passed shortNama + * @param shortName name of a sender + * @return an initialized BackingBean or null in case of error + */ + public AlertBackingBean getBackingBeanForSender(String shortName) { + AlertSenderPluginManager pluginmanager = alertManager.getAlertPluginManager(); + AlertBackingBean bean = pluginmanager.getBackingBeanForSender(shortName); + return bean; + + } + /** * Add a new AlertNotification to the passed definition * @param user subject of the caller diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerLocal.java index 7c458f4..c0b5ff2 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerLocal.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerLocal.java @@ -35,6 +35,7 @@ import org.rhq.core.domain.configuration.Configuration; import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; import org.rhq.core.domain.util.PageControl; import org.rhq.core.domain.util.PageList; +import org.rhq.enterprise.server.plugin.pc.alert.AlertBackingBean; import org.rhq.enterprise.server.plugin.pc.alert.AlertSenderInfo;
/** @@ -119,4 +120,11 @@ public interface AlertNotificationManagerLocal { * @param removeOldNotifications Shall old Notifications on the Definition be removed? */ void applyNotificationTemplateToAlertDefinition(NotificationTemplate template, AlertDefinition def, boolean removeOldNotifications); + + /** + * Return the backing bean for the AlertSender with the passed shortNama + * @param shortName name of a sender + * @return an initialized BackingBean or null in case of error + */ + AlertBackingBean getBackingBeanForSender(String shortName); } \ No newline at end of file diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertBackingBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertBackingBean.java new file mode 100644 index 0000000..523190d --- /dev/null +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertBackingBean.java @@ -0,0 +1,34 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2009 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.plugin.pc.alert; + +import java.util.Map; + +/** + * Interface that backing beans for AlertSender custom UI need to implement + * @author Heiko W. Rupp + */ +public interface AlertBackingBean { + + public String getString() ; + + public Map<String,String>getMap(); + + public void submit(); +} diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSenderPluginManager.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSenderPluginManager.java index e29e9b5..5d1a125 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSenderPluginManager.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSenderPluginManager.java @@ -53,6 +53,7 @@ public class AlertSenderPluginManager extends ServerPluginManager { private Map<String,String> pluginClassByName = new HashMap<String, String>(); private Map<String,ServerPluginEnvironment> pluginEnvByName = new HashMap<String, ServerPluginEnvironment>(); private Map<String,AlertSenderInfo> senderInfoByName = new HashMap<String, AlertSenderInfo>(); + private Map<String,String> backinBeanByName = new HashMap<String, String>();
public AlertSenderPluginManager(AbstractTypeServerPluginContainer pc) { super(pc); @@ -124,6 +125,7 @@ public class AlertSenderPluginManager extends ServerPluginManager { } try { Class.forName(className,true,env.getPluginClassLoader()); // TODO how make this available to Seam and the Web-CL ? + backinBeanByName.put(shortName,className); } catch (Throwable t ) { log.error("Backing bean " + className + " not found for plugin " + shortName); @@ -152,6 +154,7 @@ public class AlertSenderPluginManager extends ServerPluginManager { pluginClassByName.remove(shortName); senderInfoByName.remove(shortName); pluginEnvByName.remove(shortName); + backinBeanByName.remove(shortName); }
/** @@ -229,4 +232,25 @@ public class AlertSenderPluginManager extends ServerPluginManager { public AlertSenderInfo getAlertSenderInfo(String shortName) { return senderInfoByName.get(shortName); } + + public AlertBackingBean getBackingBeanForSender(String shortName) { + String name = backinBeanByName.get(shortName); + ServerPluginEnvironment env = pluginEnvByName.get(shortName); + Class clazz; + try { + clazz = Class.forName(name,true,env.getPluginClassLoader()); + } + catch (Exception e) { + log.error("Can't load class " + name + ": " + e.getMessage()); + return null; + } + AlertBackingBean bean = null ; + try { + bean = (AlertBackingBean) clazz.newInstance(); + } + catch (Exception e) { + log.error("Can't instantiate " + name + ": " + e.getMessage()); + } + return bean; + } } diff --git a/modules/enterprise/server/plugins/alert-mobicents/src/main/java/org/rhq/enterprise/server/plugins/alertMobicents/MobicentsSender.java b/modules/enterprise/server/plugins/alert-mobicents/src/main/java/org/rhq/enterprise/server/plugins/alertMobicents/MobicentsSender.java index 6111d7e..7444052 100644 --- a/modules/enterprise/server/plugins/alert-mobicents/src/main/java/org/rhq/enterprise/server/plugins/alertMobicents/MobicentsSender.java +++ b/modules/enterprise/server/plugins/alert-mobicents/src/main/java/org/rhq/enterprise/server/plugins/alertMobicents/MobicentsSender.java @@ -150,6 +150,7 @@ public class MobicentsSender extends AlertSender { code = conn.getResponseCode(); } catch (Exception e) { log.warn("Notification via VoIP failed: " + e); + return new SenderResult(ResultState.FAILURE,"Sending failed " + e.getMessage()); } finally { if (conn!=null) diff --git a/modules/enterprise/server/plugins/alert-roles/pom.xml b/modules/enterprise/server/plugins/alert-roles/pom.xml index 5747fe2..b572a53 100644 --- a/modules/enterprise/server/plugins/alert-roles/pom.xml +++ b/modules/enterprise/server/plugins/alert-roles/pom.xml @@ -69,6 +69,14 @@ <!-- needed for referenced domain entities that use Hibernate annotations --> </dependency>
+ <dependency> + <groupId>jboss.jboss-embeddable-ejb3</groupId> + <artifactId>jboss-ejb3-all</artifactId> + <version>1.0.0.Alpha9</version> + <scope>compile</scope> + </dependency> + + </dependencies>
<build> @@ -148,4 +156,4 @@
-</project> \ No newline at end of file +</project> diff --git a/modules/enterprise/server/plugins/alert-roles/src/main/java/org/rhq/enterprise/server/plugins/alertRoles/RolesBackingBean.java b/modules/enterprise/server/plugins/alert-roles/src/main/java/org/rhq/enterprise/server/plugins/alertRoles/RolesBackingBean.java index a83c9cf..f0a7b96 100644 --- a/modules/enterprise/server/plugins/alert-roles/src/main/java/org/rhq/enterprise/server/plugins/alertRoles/RolesBackingBean.java +++ b/modules/enterprise/server/plugins/alert-roles/src/main/java/org/rhq/enterprise/server/plugins/alertRoles/RolesBackingBean.java @@ -18,21 +18,51 @@ */ package org.rhq.enterprise.server.plugins.alertRoles;
+import java.util.HashMap; +import java.util.Map; + +import javax.annotation.PostConstruct; +import javax.ejb.Stateless; + import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory;
import org.jboss.seam.annotations.Name;
+import org.rhq.core.domain.authz.Role; +import org.rhq.core.domain.util.PageControl; +import org.rhq.core.domain.util.PageList; +import org.rhq.enterprise.server.authz.RoleManagerLocal; +import org.rhq.enterprise.server.plugin.pc.alert.AlertBackingBean; +import org.rhq.enterprise.server.util.LookupUtil; + /** * // TODO: Document this * @author Heiko W. Rupp */ -@Name("RolesBackingBean") -public class RolesBackingBean { +public class RolesBackingBean implements AlertBackingBean {
private final Log log = LogFactory.getLog(RolesBackingBean.class);
- public String getMessage() { + public String getString() { return "Hello BackingBean"; } + + public Map<String,String> getMap() { + Map<String,String> map = new HashMap(); + + RoleManagerLocal mgr = LookupUtil.getRoleManager(); + PageList<Role> roles = mgr.findRoles(new PageControl()); + + for (Role role : roles) { + map.put(role.getName(),role.getName()); + } + return map; + } + + public void submit() { + + System.out.println("In Submit"); + // TODO: Customise this generated block + } } diff --git a/modules/enterprise/server/plugins/alert-roles/src/main/resources/roles.xhtml b/modules/enterprise/server/plugins/alert-roles/src/main/resources/roles.xhtml index 49dcf0b..2a90ab9 100644 --- a/modules/enterprise/server/plugins/alert-roles/src/main/resources/roles.xhtml +++ b/modules/enterprise/server/plugins/alert-roles/src/main/resources/roles.xhtml @@ -9,8 +9,26 @@ xmlns:a4j="https://richfaces.org/a4j" xmlns:rich="http://richfaces.ajax4jsf.org/rich%22%3E
- <h:outputText value="Hello New Facelet roles world"/> + <h:outputText value="Hello New Facelet roles world: #{ListNotificationsUIBean.selectedSender}"/> + +
<br/> - <h:outputText value="#{RolesBackingBean.message}"/> + <h:outputText value="#{GenericAlertStuffUIBean.theString}"> + <f:param name="sender" value="Roles"/> + </h:outputText> + + <p/> + Select a user:<br/> + <h:selectOneMenu id="mySenderList" value="#{GenericAlertStuffUIBean.theValue}"> + <f:selectItems value="#{GenericAlertStuffUIBean.theMap}"/> + </h:selectOneMenu> + + <h:commandButton + id="roles_submit" + value="Add them" + type="submit" + action="#{GenericAlertStuffUIBean.submitForm}" + /> + </html> \ No newline at end of file
commit cb18055cfd528342fda2ddeed570ef5b15fd4183 Author: John Sanda jsanda@redhat.com Date: Mon Dec 14 22:34:48 2009 -0500
[BZ 538088] Reverting back to using the view ui bean which only has a request scope.
view.xhtml in several places in the JSF code was making calls to ExistingResourceConfigurationUIBean which has session scope. As a result, external config updagtes were not immediately visible because the configuration objects were getting cached for the duration of the session, whereas ExistingResourceConfigurationViewUIBean has a scope of request so every request for the view page results in fetching the latest configuration for the resource.
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml index 0d4899f..72da244 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml @@ -44,27 +44,27 @@ THIS TEXT WILL BE REMOVED. <input type="hidden" name="id" value="#{ResourceUIBean.id}"/>
<h:panelGrid columns="2" styleClass="buttons-table" columnClasses="button-cell" - rendered="#{ExistingResourceConfigurationUIBean.configuration != null and !ExistingResourceConfigurationUIBean.updateInProgress}"> + rendered="#{ExistingResourceConfigurationViewUIBean.configuration != null and !ExistingResourceConfigurationViewUIBean.updateInProgress}">
- <h:commandButton value="#{messages.editstructured}" action="#{ExistingResourceConfigurationUIBean.editConfiguration}" + <h:commandButton value="#{messages.editstructured}" action="#{ExistingResourceConfigurationViewUIBean.editConfiguration}" title="Edit this Configuration" styleClass="buttonmed" - rendered="${ResourceUIBean.permissions.configure and ExistingResourceConfigurationUIBean.structuredSupported and !ExistingResourceConfigurationUIBean.updateInProgress}" /> + rendered="${ResourceUIBean.permissions.configure and ExistingResourceConfigurationViewUIBean.structuredSupported and !ExistingResourceConfigurationViewUIBean.updateInProgress}" /> <h:commandButton value="#{messages.editraw}" action="#{ExistingResourceConfigurationUIBean.editRawConfiguration}" title="Advanced Mode Edit of Raw Configuration Files" styleClass="buttonmed" - rendered="${ResourceUIBean.permissions.configure and ExistingResourceConfigurationUIBean.rawSupported and !ExistingResourceConfigurationUIBean.updateInProgress}" /> + rendered="${ResourceUIBean.permissions.configure and ExistingResourceConfigurationViewUIBean.rawSupported and !ExistingResourceConfigurationViewUIBean.updateInProgress}" /> </h:panelGrid>
- <onc:config configurationDefinition="#{ExistingResourceConfigurationUIBean.configurationDefinition}" - configuration="#{ExistingResourceConfigurationUIBean.configuration}" - accessMapActionExpression="#{ExistingResourceConfigurationUIBean.accessMap}" + <onc:config configurationDefinition="#{ExistingResourceConfigurationViewUIBean.configurationDefinition}" + configuration="#{ExistingResourceConfigurationViewUIBean.configuration}" + accessMapActionExpression="#{ExistingResourceConfigurationViewUIBean.accessMap}" readOnly="true" - nullConfigurationDefinitionMessage="#{ExistingResourceConfigurationUIBean.nullConfigurationDefinitionMessage}" - nullConfigurationMessage="#{ExistingResourceConfigurationUIBean.nullConfigurationMessage}" + nullConfigurationDefinitionMessage="#{ExistingResourceConfigurationViewUIBean.nullConfigurationDefinitionMessage}" + nullConfigurationMessage="#{ExistingResourceConfigurationViewUIBean.nullConfigurationMessage}" prevalidate="true"/>
</h:form>
- <h:panelGroup layout="block" styleClass="InfoBlock" rendered="#{ExistingResourceConfigurationUIBean.updateInProgress}"> + <h:panelGroup layout="block" styleClass="InfoBlock" rendered="#{ExistingResourceConfigurationViewUIBean.updateInProgress}"> <b>${msg['note']}</b> ${msg['resource.config.Current.updateInProgress']} </h:panelGroup>
commit c73d40ce3406a3cc904fb34429b9248b48f8e531 Author: John Sanda jsanda@redhat.com Date: Mon Dec 14 22:17:14 2009 -0500
[BZ 544136] Fixing bug that prevented see history for raw config updates
The UI code, ListConfigurationUpdateUIBean, calls ConfigurationManagerBean.findResourceConfigurationUpdates(). That method has logic which checks that the configuration definition actually supports updates. It does this by checking that there exists property definitions. If none exists, the method returns immediately. That logic of course applies to structured only configurations. It has been modified for raw.
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java index fb82e6e..586d603 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java @@ -842,8 +842,9 @@ public class ConfigurationManagerBean implements ConfigurationManagerLocal, Conf }
Resource resource = entityManager.find(Resource.class, resourceId); - if (resource.getResourceType().getResourceConfigurationDefinition() == null - || resource.getResourceType().getResourceConfigurationDefinition().getPropertyDefinitions().isEmpty()) { + ConfigurationDefinition configDef = resource.getResourceType().getResourceConfigurationDefinition(); + if ((configDef == null || configDef.getPropertyDefinitions().isEmpty()) + && configDef.getConfigurationFormat() == ConfigurationFormat.STRUCTURED) { return new PageList<ResourceConfigurationUpdate>(pc); }
commit 6f448b4bcfb4f9aef80221b9fee3b10f15a7b291 Merge: 313a721... 10dbcf9... Author: Jay Shaughnessy jshaughn@redhat.com Date: Mon Dec 14 22:05:07 2009 -0500
Merge branch 'master-dev'
commit 10dbcf9a05766c2d2cfda7040176d51655e22c16 Author: Jay Shaughnessy jshaughn@redhat.com Date: Mon Dec 14 22:04:01 2009 -0500
Several changes to 2.61 for logic/sql. Also 2.63 and 2.68. Now runs to completion and is hopefully correct. But, the content team should review to ensure it's matching the results of dbsetup.
diff --git a/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml b/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml index f70f2fa..c84b55e 100644 --- a/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml +++ b/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml @@ -1867,12 +1867,34 @@ </schemaSpec>
<schemaSpec version="2.61"> - <schema-directSQL> + <schema-directSQL> + <statement> + CREATE TABLE RHQ_DISTRIBUTION_TYPE ( ID INTEGER PRIMARY KEY ) + </statement> + </schema-directSQL> + <schema-alterColumn table="RHQ_DISTRIBUTION_TYPE" column="ID" nullable="false" /> + <schema-addColumn table="RHQ_DISTRIBUTION_TYPE" column="NAME" precision="200" columnType="VARCHAR2" /> + <schema-alterColumn table="RHQ_DISTRIBUTION_TYPE" column="NAME" nullable="false" /> + <schema-addColumn table="RHQ_DISTRIBUTION_TYPE" column="DESCRIPTION" precision="500" columnType="VARCHAR2" /> + <schema-directSQL> + <statement> + INSERT INTO + RHQ_DISTRIBUTION_TYPE ( ID, NAME, DESCRIPTION ) + VALUES ( 1, 'kickstart', 'Linux kickstart distribution' ) + </statement> + <statement> + INSERT INTO + RHQ_DISTRIBUTION_TYPE ( ID, NAME, DESCRIPTION ) + VALUES ( 2, 'jumpstart', 'solaris jumpstart distribution' ) + </statement> + </schema-directSQL> + + <schema-directSQL> <statement desc="Creating table RHQ_DISTRIBUTION"> CREATE TABLE RHQ_DISTRIBUTION ( ID INTEGER PRIMARY KEY ) </statement> </schema-directSQL> - <schema-addColumn table="RHQ_DISTRIBUTION" column="DISTRIBUTION_TYPE_ID" nullable="false" columnType="INTEGER"/> + <schema-addColumn table="RHQ_DISTRIBUTION" column="DISTRIBUTION_TYPE_ID" columnType="INTEGER"/> <schema-alterColumn table="RHQ_DISTRIBUTION" column="DISTRIBUTION_TYPE_ID" nullable="false"/> <schema-addColumn table="RHQ_DISTRIBUTION" column="LABEL" precision="64" columnType="VARCHAR2" /> <schema-alterColumn table="RHQ_DISTRIBUTION" column="LABEL" nullable="false" /> @@ -1885,19 +1907,20 @@ CREATE UNIQUE INDEX RHQ_DISTRIBUTION_IDX ON RHQ_DISTRIBUTION ( LABEL, BASE_PATH ) </statement> </schema-directSQL> - <statement targetDBVendor="postgresql"> - ALTER TABLE RHQ_DISTRIBUTION - ADD CONSTRAINT RHQ_DIST_TYPE_FKEY - FOREIGN KEY ( DISTRIBUTION_TYPE_ID ) - REFERENCES RHQ_DISTRIBUTION_TYPE ( ID ) - </statement> - <statement targetDBVendor="oracle"> - ALTER TABLE RHQ_DISTRIBUTION - ADD FOREIGN KEY ( DISTRIBUTION_TYPE_ID ) - REFERENCES RHQ_DISTRIBUTION_TYPE ( ID ) - </statement> - - + <schema-directSQL> + <statement targetDBVendor="postgresql"> + ALTER TABLE RHQ_DISTRIBUTION + ADD CONSTRAINT RHQ_DIST_TYPE_FKEY + FOREIGN KEY ( DISTRIBUTION_TYPE_ID ) + REFERENCES RHQ_DISTRIBUTION_TYPE ( ID ) + </statement> + <statement targetDBVendor="oracle"> + ALTER TABLE RHQ_DISTRIBUTION + ADD FOREIGN KEY ( DISTRIBUTION_TYPE_ID ) + REFERENCES RHQ_DISTRIBUTION_TYPE ( ID ) + </statement> + </schema-directSQL> + <schema-directSQL> <statement desc="Creating table RHQ_REPO_DISTRIBUTION"> CREATE TABLE RHQ_REPO_DISTRIBUTION ( REPO_ID INTEGER ) @@ -1910,13 +1933,13 @@ <schema-alterColumn table="RHQ_REPO_DISTRIBUTION" column="LAST_MODIFIED" nullable="false" /> <schema-directSQL> <statement> - ALTER TABLE RHQ_REPO_DISTRIBUTION - ADD CONSTRAINT RHQ_REPO_DIST_MAP_KEY + ALTER TABLE RHQ_REPO_DISTRIBUTION ADD CONSTRAINT RHQ_REPO_DIST_MAP_KEY PRIMARY KEY ( REPO_ID, DISTRIBUTION_ID ) </statement> - <statement targetDBVendor="postgresql"> + + <statement targetDBVendor="postgresql"> ALTER TABLE RHQ_REPO_DISTRIBUTION - ADD CONSTRAINT RHQ_DIST_REPO_ID_FKEY + ADD CONSTRAINT RHQ_REPO_DIST_REPO_ID_FKEY FOREIGN KEY ( REPO_ID ) REFERENCES RHQ_REPO ( ID ) </statement> @@ -1924,56 +1947,20 @@ ALTER TABLE RHQ_REPO_DISTRIBUTION ADD FOREIGN KEY ( REPO_ID ) REFERENCES RHQ_REPO ( ID ) - </statement> + </statement> + <statement targetDBVendor="postgresql"> ALTER TABLE RHQ_REPO_DISTRIBUTION - ADD CONSTRAINT RHQ_REPO_DIST_ID_FKEY + ADD CONSTRAINT RHQ_REPO_DIST_DIST_ID_FKEY FOREIGN KEY ( DISTRIBUTION_ID ) REFERENCES RHQ_DISTRIBUTION ( ID ) - </statement> + </statement> <statement targetDBVendor="oracle"> ALTER TABLE RHQ_REPO_DISTRIBUTION ADD FOREIGN KEY ( DISTRIBUTION_ID ) REFERENCES RHQ_DISTRIBUTION ( ID ) </statement> </schema-directSQL> - - <schema-directSQL> - <statement> - CREATE TABLE RHQ_DISTRIBUTION_TYPE ( ID INTEGER PRIMARY KEY ) - </statement> - </schema-directSQL> - <schema-alterColumn table="RHQ_DISTRIBUTION_TYPE" column="ID" nullable="false" /> - <schema-addColumn table="RHQ_DISTRIBUTION_TYPE" column="NAME" precision="200" columnType="VARCHAR2" /> - <schema-alterColumn table="RHQ_DISTRIBUTION_TYPE" column="NAME" nullable="false" /> - <schema-addColumn table="RHQ_DISTRIBUTION_TYPE" column="DESCRIPTION" precision="500" columnType="VARCHAR2" /> - <schema-directSQL> - <statement> - INSERT INTO - RHQ_DISTRIBUTION_TYPE ( ID, NAME, DESCRIPTION ) - VALUES ( 1, 'kickstart', 'Linux kickstart distribution' ) - </statement> - <statement> - INSERT INTO - RHQ_DISTRIBUTION_TYPE ( ID, NAME, DESCRIPTION ) - VALUES ( 2, 'jumpstart', 'solaris jumpstart distribution' ) - </statement> - </schema-directSQL> - - <schema-directSQL> - <statement targetDBVendor="oracle"> - ALTER TABLE RHQ_DISTRIBUTION - ADD CONSTRAINT RHQ_DIST_FKEY - FOREIGN KEY ( DISTRIBUTION_TYPE_ID) - REFERENCES RHQ_DISTRIBUTION_TYPE ( ID ) - </statement> - <statement targetDBVendor="postgresql"> - ALTER TABLE RHQ_DISTRIBUTION - ADD CONSTRAINT RHQ_DIST_FKEY - FOREIGN KEY ( DISTRIBUTION_TYPE_ID) - REFERENCES RHQ_DISTRIBUTION_TYPE ( ID ) - </statement> - </schema-directSQL> </schemaSpec>
<schemaSpec version="2.62"> @@ -1993,6 +1980,16 @@
<schemaSpec version="2.63"> <schema-addColumn table="RHQ_REPO" column="IS_CANDIDATE" columnType="BOOLEAN"/> + + <schema-directSQL> + <statement targetDBVendor="postgresql"> + UPDATE RHQ_REPO SET IS_CANDIDATE = FALSE + </statement> + <statement targetDBVendor="oracle"> + UPDATE RHQ_REPO SET IS_CANDIDATE = 0 + </statement> + </schema-directSQL> + <schema-alterColumn table="RHQ_REPO" column="IS_CANDIDATE" nullable="false" /> </schemaSpec>
@@ -2092,12 +2089,7 @@ </schemaSpec>
<schemaSpec version="2.68"> - <schema-createSequence name="RHQ_DISTRIBUTION_FILE_SEQ" initial="10001" /> - <schema-directSQL> - <statement> - ALTER TABLE RHQ_DISTRIBUTION_FILE DROP CONSTRAINT RHQ_DISTRIBUTION_FILE_PKEY - </statement> - </schema-directSQL> + <schema-createSequence name="RHQ_DISTRIBUTION_FILE_ID_SEQ" initial="10001" />
<schema-addColumn table="RHQ_DISTRIBUTION_FILE" column="ID" columnType="INTEGER" /> <schema-alterColumn table="RHQ_DISTRIBUTION_FILE" column="ID" nullable="false" />
commit 7aa739874e164edff47e01d4ff390ff8ac7f26a6 Author: Jay Shaughnessy jshaughn@redhat.com Date: Mon Dec 14 18:27:04 2009 -0500
Multiple changes to try and repair 2.61. Removing unnecessary steps and invalid syntax.
diff --git a/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml b/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml index cfab5a8..f70f2fa 100644 --- a/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml +++ b/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml @@ -1868,68 +1868,76 @@
<schemaSpec version="2.61"> <schema-directSQL> - <statement desc="Creating table RHQ_KICKSTARTABLE_TREE"> - CREATE TABLE RHQ_KICKSTARTABLE_TREE ( ID INTEGER PRIMARY KEY ) - </statement> - </schema-directSQL> - <schema-alterColumn table="RHQ_KICKSTARTABLE_TREE" column="ID" nullable="false" columnType="INTEGER"/> - <schema-addColumn table="RHQ_KICKSTARTABLE_TREE" column="LABEL" precision="64" columnType="VARCHAR2" /> - <schema-alterColumn table="RHQ_KICKSTARTABLE_TREE" column="LABEL" nullable="false" /> - <schema-addColumn table="RHQ_KICKSTARTABLE_TREE" column="BASE_PATH" precision="256" columnType="VARCHAR2" /> - <schema-alterColumn table="RHQ_KICKSTARTABLE_TREE" column="BASE_PATH" nullable="false" /> - <schema-addColumn table="RHQ_KICKSTARTABLE_TREE" column="LAST_MODIFIED" columnType="LONG" /> - <schema-alterColumn table="RHQ_KICKSTARTABLE_TREE" column="LAST_MODIFIED" nullable="false" /> - <schema-directSQL> - <statement targetDBVendor="postgresql"> - CREATE UNIQUE INDEX RHQ_KICKSTART_IDX - ON RHQ_KICKSTARTABLE_TREE ( LABEL, BASE_PATH ) - </statement> - <statement targetDBVendor="oracle"> - CREATE UNIQUE INDEX RHQ_KICKSTART_IDX - ON RHQ_KICKSTARTABLE_TREE ( LABEL, BASE_PATH ) - </statement> - </schema-directSQL> + <statement desc="Creating table RHQ_DISTRIBUTION"> + CREATE TABLE RHQ_DISTRIBUTION ( ID INTEGER PRIMARY KEY ) + </statement> + </schema-directSQL> + <schema-addColumn table="RHQ_DISTRIBUTION" column="DISTRIBUTION_TYPE_ID" nullable="false" columnType="INTEGER"/> + <schema-alterColumn table="RHQ_DISTRIBUTION" column="DISTRIBUTION_TYPE_ID" nullable="false"/> + <schema-addColumn table="RHQ_DISTRIBUTION" column="LABEL" precision="64" columnType="VARCHAR2" /> + <schema-alterColumn table="RHQ_DISTRIBUTION" column="LABEL" nullable="false" /> + <schema-addColumn table="RHQ_DISTRIBUTION" column="BASE_PATH" precision="256" columnType="VARCHAR2" /> + <schema-alterColumn table="RHQ_DISTRIBUTION" column="BASE_PATH" nullable="false" /> + <schema-addColumn table="RHQ_DISTRIBUTION" column="LAST_MODIFIED" columnType="LONG" /> + <schema-alterColumn table="RHQ_DISTRIBUTION" column="LAST_MODIFIED" nullable="false" /> + <schema-directSQL> + <statement> + CREATE UNIQUE INDEX RHQ_DISTRIBUTION_IDX ON RHQ_DISTRIBUTION ( LABEL, BASE_PATH ) + </statement> + </schema-directSQL> + <statement targetDBVendor="postgresql"> + ALTER TABLE RHQ_DISTRIBUTION + ADD CONSTRAINT RHQ_DIST_TYPE_FKEY + FOREIGN KEY ( DISTRIBUTION_TYPE_ID ) + REFERENCES RHQ_DISTRIBUTION_TYPE ( ID ) + </statement> + <statement targetDBVendor="oracle"> + ALTER TABLE RHQ_DISTRIBUTION + ADD FOREIGN KEY ( DISTRIBUTION_TYPE_ID ) + REFERENCES RHQ_DISTRIBUTION_TYPE ( ID ) + </statement>
- <schema-directSQL> - <statement desc="Creating table RHQ_REPO_KS_TREE"> - CREATE TABLE RHQ_REPO_KS_TREE ( REPO_ID INTEGER ) + + <schema-directSQL> + <statement desc="Creating table RHQ_REPO_DISTRIBUTION"> + CREATE TABLE RHQ_REPO_DISTRIBUTION ( REPO_ID INTEGER ) </statement> </schema-directSQL> - - <schema-alterColumn table="RHQ_REPO_KS_TREE" column="REPO_ID" nullable="false" columnType="INTEGER"/> - <schema-addColumn table="RHQ_REPO_KS_TREE" column="KICKSTART_TREE_ID" columnType="INTEGER" /> - <schema-alterColumn table="RHQ_REPO_KS_TREE" column="KICKSTART_TREE_ID" nullable="false" /> - <schema-addColumn table="RHQ_REPO_KS_TREE" column="LAST_MODIFIED" columnType="LONG" /> - <schema-alterColumn table="RHQ_REPO_KS_TREE" column="LAST_MODIFIED" nullable="false" /> + <schema-alterColumn table="RHQ_REPO_DISTRIBUTION" column="REPO_ID" nullable="false"/> + <schema-addColumn table="RHQ_REPO_DISTRIBUTION" column="DISTRIBUTION_ID" columnType="INTEGER" /> + <schema-alterColumn table="RHQ_REPO_DISTRIBUTION" column="DISTRIBUTION_ID" nullable="false" /> + <schema-addColumn table="RHQ_REPO_DISTRIBUTION" column="LAST_MODIFIED" columnType="LONG" /> + <schema-alterColumn table="RHQ_REPO_DISTRIBUTION" column="LAST_MODIFIED" nullable="false" /> <schema-directSQL> <statement> - ALTER TABLE RHQ_REPO_KS_TREE - ADD CONSTRAINT RHQ_REPO_KS_MAP_KEY - PRIMARY KEY ( REPO_ID, KICKSTART_TREE_ID ) - </statement> + ALTER TABLE RHQ_REPO_DISTRIBUTION + ADD CONSTRAINT RHQ_REPO_DIST_MAP_KEY + PRIMARY KEY ( REPO_ID, DISTRIBUTION_ID ) + </statement> <statement targetDBVendor="postgresql"> - ALTER TABLE RHQ_REPO_KS_TREE - ADD CONSTRAINT RHQ_KS_REPO_ID_FKEY + ALTER TABLE RHQ_REPO_DISTRIBUTION + ADD CONSTRAINT RHQ_DIST_REPO_ID_FKEY FOREIGN KEY ( REPO_ID ) REFERENCES RHQ_REPO ( ID ) - </statement> + </statement> <statement targetDBVendor="oracle"> - ALTER TABLE RHQ_REPO_KS_TREE + ALTER TABLE RHQ_REPO_DISTRIBUTION ADD FOREIGN KEY ( REPO_ID ) REFERENCES RHQ_REPO ( ID ) - </statement> + </statement> <statement targetDBVendor="postgresql"> - ALTER TABLE RHQ_REPO_KS_TREE - ADD CONSTRAINT RHQ_REPO_KS_TREE_ID_FKEY - FOREIGN KEY ( KICKSTART_TREE_ID ) - REFERENCES RHQ_KICKSTARTABLE_TREE ( ID ) - </statement> + ALTER TABLE RHQ_REPO_DISTRIBUTION + ADD CONSTRAINT RHQ_REPO_DIST_ID_FKEY + FOREIGN KEY ( DISTRIBUTION_ID ) + REFERENCES RHQ_DISTRIBUTION ( ID ) + </statement> <statement targetDBVendor="oracle"> - ALTER TABLE RHQ_REPO_KS_TREE - ADD FOREIGN KEY ( KICKSTART_TREE_ID ) - REFERENCES RHQ_KICKSTARTABLE_TREE ( ID ) - </statement> + ALTER TABLE RHQ_REPO_DISTRIBUTION + ADD FOREIGN KEY ( DISTRIBUTION_ID ) + REFERENCES RHQ_DISTRIBUTION ( ID ) + </statement> </schema-directSQL> + <schema-directSQL> <statement> CREATE TABLE RHQ_DISTRIBUTION_TYPE ( ID INTEGER PRIMARY KEY ) @@ -1940,7 +1948,6 @@ <schema-alterColumn table="RHQ_DISTRIBUTION_TYPE" column="NAME" nullable="false" /> <schema-addColumn table="RHQ_DISTRIBUTION_TYPE" column="DESCRIPTION" precision="500" columnType="VARCHAR2" /> <schema-directSQL> - <statement> INSERT INTO RHQ_DISTRIBUTION_TYPE ( ID, NAME, DESCRIPTION ) @@ -1952,42 +1959,6 @@ VALUES ( 2, 'jumpstart', 'solaris jumpstart distribution' ) </statement> </schema-directSQL> - <schema-directSQL> - <statement targetDBVendor="oracle"> - ALTER TABLE RHQ_REPO_KS_TREE RENAME TO RHQ_REPO_DISTRIBUTION - </statement> - <statement targetDBVendor="postgresql"> - ALTER TABLE RHQ_REPO_KS_TREE RENAME TO RHQ_REPO_DISTRIBUTION - </statement> - <statement targetDBVendor="oracle"> - ALTER TABLE RHQ_KICKSTARTABLE_TREE RENAME TO RHQ_DISTRIBUTION - </statement> - <statement targetDBVendor="postgresql"> - ALTER TABLE RHQ_KICKSTARTABLE_TREE RENAME TO RHQ_DISTRIBUTION - </statement> - <statement targetDBVendor="oracle"> - ALTER TABLE RHQ_REPO_DISTRIBUTION RENAME CONSTRAINT - RHQ_REPO_KS_TREE_ID_FKEY TO RHQ_REPO_DIST_ID_FKEY - </statement> - <statement targetDBVendor="postgresql"> - ALTER TABLE RHQ_REPO_DISTRIBUTION RENAME CONSTRAINT - RHQ_REPO_KS_TREE_ID_FKEY TO RHQ_REPO_DIST_ID_FKEY - </statement> - <statement targetDBVendor="oracle"> - ALTER TABLE RHQ_REPO_DISTRIBUTION RENAME CONSTRAINT - RHQ_REPO_KS_MAP_KEY TO RHQ_REPO_DIST_MAP_KEY - </statement> - <statement targetDBVendor="postgresql"> - ALTER TABLE RHQ_REPO_DISTRIBUTION RENAME CONSTRAINT - RHQ_REPO_KS_MAP_KEY TO RHQ_REPO_DIST_MAP_KEY - </statement> - <statement targetDBVendor="oracle"> - ALTER INDEX RHQ_KICKSTART_IDX RENAME TO RHQ_DISTRIBUTION_IDX - </statement> - <statement targetDBVendor="postgresql"> - ALTER INDEX RHQ_KICKSTART_IDX RENAME TO RHQ_DISTRIBUTION_IDX - </statement> - </schema-directSQL>
<schema-directSQL> <statement targetDBVendor="oracle">
commit 6cbb7df18da1585103d5b819f80c1b00ad019aab Author: Adam Young ayoung@redhat.com Date: Mon Dec 14 17:48:32 2009 -0500
started pushing the decode and encode stuff into the appropriate portion of the jsf lifecycle.
diff --git a/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/ConfigRenderer.java b/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/ConfigRenderer.java index b4f76f1..e3f0c16 100644 --- a/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/ConfigRenderer.java +++ b/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/ConfigRenderer.java @@ -88,7 +88,7 @@ public class ConfigRenderer extends Renderer { protected static final String GROUP_DESCRIPTION_PANEL_STYLE_CLASS = "group-description-panel"; protected static final String GROUP_DESCRIPTION_TEXT_PANEL_STYLE_CLASS = "group-description-text-panel";
- private final Log LOG = LogFactory.getLog(ConfigRenderer.class); + private static final Log LOG = LogFactory.getLog(ConfigRenderer.class); private static final String INIT_INPUTS_JAVA_SCRIPT_COMPONENT_ID_SUFFIX = "-initInputsJavaScript";
/** @@ -264,7 +264,7 @@ public class ConfigRenderer extends Renderer { }
Boolean shouldShowRawNow = configurationComponent.getShouldShowRaw(); - //addStructuredRawToggle(configurationComponent, shouldShowRawNow); + if (shouldShowRawNow) { configurationComponent.getChildren().add( new RawConfigUIComponent(configurationComponent.getConfiguration(), configurationComponent @@ -458,7 +458,7 @@ public class ConfigRenderer extends Renderer { + mapName + "'."); }
- private void addRequiredNotationsKey(AbstractConfigurationComponent config) { + private static void addRequiredNotationsKey(AbstractConfigurationComponent config) { addDebug(config, true, ".addNotePanel()"); HtmlPanelGroup footnotesPanel = FacesComponentUtility.addBlockPanel(config, config, NOTE_PANEL_STYLE_CLASS); FacesComponentUtility.addOutputText(footnotesPanel, config, "*", REQUIRED_MARKER_TEXT_STYLE_CLASS); @@ -573,11 +573,11 @@ public class ConfigRenderer extends Renderer { * @param start true if this is the "START" comment, false if it is the "END" comment * @param methodName the name of the method this is calling from */ - private void addDebug(UIComponent component, boolean start, String methodName) { + private static void addDebug(UIComponent component, boolean start, String methodName) { if (LOG.isDebugEnabled()) { StringBuilder msg = new StringBuilder("\n<!--"); msg.append(start ? " START " : " END "); - msg.append(this.getClass().getSimpleName()); + msg.append(ConfigRenderer.class.getSimpleName()); msg.append(methodName); msg.append(" -->\n "); FacesComponentUtility.addVerbatimText(component, msg); diff --git a/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/RawConfigUIComponent.java b/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/RawConfigUIComponent.java index 5280cb0..ce42a54 100644 --- a/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/RawConfigUIComponent.java +++ b/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/RawConfigUIComponent.java @@ -5,12 +5,15 @@ import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.Map; +import java.util.Vector;
import javax.faces.component.UIComponent; import javax.faces.component.UIComponentBase; import javax.faces.component.UIPanel; +import javax.faces.component.UIParameter; import javax.faces.component.html.HtmlCommandLink; import javax.faces.component.html.HtmlInputTextarea; +import javax.faces.component.html.HtmlOutputLink; import javax.faces.component.html.HtmlPanelGrid; import javax.faces.context.FacesContext;
@@ -24,11 +27,13 @@ import org.rhq.core.gui.util.FacesContextUtility; public class RawConfigUIComponent extends UIComponentBase {
private boolean readOnly; + private boolean showRaw;
@Override public void decode(FacesContext context) { super.decode(context); setSelectedPath(FacesContextUtility.getOptionalRequestParameter("path")); + readOnly = Boolean.valueOf(FacesContextUtility.getOptionalRequestParameter("readOnly"));
}
@@ -82,6 +87,8 @@ public class RawConfigUIComponent extends UIComponentBase { return true; }
+ Vector<UIParameter> readOnlyParms = new Vector<UIParameter>(); + public RawConfigUIComponent(Configuration configuration, ConfigurationDefinition configurationDefinition, FacesComponentIdFactory componentIdFactory, boolean readOnly) {
@@ -91,7 +98,8 @@ public class RawConfigUIComponent extends UIComponentBase { this.readOnly = readOnly;
UIPanel rawPanel = FacesComponentUtility.addBlockPanel(this, idFactory, ""); - addToolbarIcons(rawPanel, configurationDefinition.getConfigurationFormat().isStructuredSupported()); + + addToolbar(configurationDefinition, rawPanel);
HtmlPanelGrid grid = FacesComponentUtility.addPanelGrid(rawPanel, idFactory, "summary-props-table"); grid.setParent(this); @@ -130,6 +138,9 @@ public class RawConfigUIComponent extends UIComponentBase { FacesComponentUtility.addParameter(link, idFactory, "path", raw.getPath()); FacesComponentUtility.addParameter(link, idFactory, "whichRaw", Integer.toString(rawCount++)); FacesComponentUtility.addParameter(link, idFactory, "showRaw", Boolean.TRUE.toString()); + readOnlyParms.add(FacesComponentUtility.addParameter(link, idFactory, "readOnly", Boolean + .toString(readOnly))); + }
UIPanel panelRight = FacesComponentUtility.addBlockPanel(grid, idFactory, "summary-props-table"); @@ -144,8 +155,8 @@ public class RawConfigUIComponent extends UIComponentBase { inputTextarea.setReadonly(readOnly); }
- private void addToolbarIcons(UIPanel toolbarPanel, boolean supportsStructured) { - + private void addToolbar(ConfigurationDefinition configurationDefinition, UIPanel parent) { + UIPanel toolbarPanel = FacesComponentUtility.addBlockPanel(parent, idFactory, "config-toolbar"); if (readOnly) { HtmlCommandLink editLink = FacesComponentUtility.addCommandLink(toolbarPanel, idFactory); FacesComponentUtility.addGraphicImage(editLink, idFactory, "/images/edit.png", "Edit"); @@ -157,24 +168,31 @@ public class RawConfigUIComponent extends UIComponentBase { FacesComponentUtility.addOutputText(saveLink, idFactory, "Save", ""); FacesComponentUtility.addParameter(saveLink, idFactory, "showStructured", Boolean.FALSE.toString()); } - HtmlCommandLink saveCommandLink = FacesComponentUtility.addCommandLink(toolbarPanel, idFactory); - FacesComponentUtility.addGraphicImage(saveCommandLink, idFactory, "/images/viewfullscreen.png", "FullScreen"); - FacesComponentUtility.addOutputText(saveCommandLink, idFactory, "Full Screen", ""); - - HtmlCommandLink uploadCommandLink = FacesComponentUtility.addCommandLink(toolbarPanel, idFactory); - FacesComponentUtility.addGraphicImage(uploadCommandLink, idFactory, "/images/upload.png", "Upload"); - FacesComponentUtility.addOutputText(uploadCommandLink, idFactory, "Upload", ""); - - HtmlCommandLink downloadCommandLink = FacesComponentUtility.addCommandLink(toolbarPanel, idFactory); - FacesComponentUtility.addGraphicImage(downloadCommandLink, idFactory, "/images/download.png", "download"); - FacesComponentUtility.addOutputText(downloadCommandLink, idFactory, "Download", ""); - - if (supportsStructured) { + { + HtmlCommandLink saveCommandLink = FacesComponentUtility.addCommandLink(toolbarPanel, idFactory); + FacesComponentUtility.addGraphicImage(saveCommandLink, idFactory, "/images/viewfullscreen.png", + "FullScreen"); + FacesComponentUtility.addOutputText(saveCommandLink, idFactory, "Full Screen", ""); + } + if (!readOnly) { + HtmlOutputLink uploadLink = FacesComponentUtility.addOutputLink(toolbarPanel, idFactory, "upload.xhtml"); + FacesComponentUtility.addGraphicImage(uploadLink, idFactory, "/images/upload.png", "Upload"); + FacesComponentUtility.addOutputText(uploadLink, idFactory, "Upload", ""); + } + { + HtmlOutputLink downloadLink = FacesComponentUtility + .addOutputLink(toolbarPanel, idFactory, "download.xhtml"); + FacesComponentUtility.addGraphicImage(downloadLink, idFactory, "/images/download.png", "download"); + FacesComponentUtility.addOutputText(downloadLink, idFactory, "Download", ""); + } + if (configurationDefinition.getConfigurationFormat().isStructuredSupported()) { HtmlCommandLink toStructureLink = FacesComponentUtility.addCommandLink(toolbarPanel, idFactory); FacesComponentUtility.addGraphicImage(toStructureLink, idFactory, "/images/structured.png", "showStructured"); FacesComponentUtility.addOutputText(toStructureLink, idFactory, "showStructured", ""); - FacesComponentUtility.addParameter(toStructureLink, idFactory, "showStructured", Boolean.FALSE.toString()); + FacesComponentUtility.addParameter(toStructureLink, idFactory, "showRaw", Boolean.FALSE.toString()); + readOnlyParms.add(FacesComponentUtility.addParameter(toStructureLink, idFactory, "readOnly", Boolean + .toString(readOnly))); } }
@@ -183,6 +201,9 @@ public class RawConfigUIComponent extends UIComponentBase { // TODO Auto-generated method stub super.encodeBegin(context); inputTextarea.setValue(rawMap.get(getSelectedPath()).getContentString()); + for (UIParameter param : readOnlyParms) { + param.setValue(Boolean.toString(readOnly)); + }
} } diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml index dabda7e..d0cfa5c 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml @@ -30,6 +30,9 @@ THIS TEXT WILL BE REMOVED. vertical-align: top; valign: top; } + config-toolbar{ + float: right; + } </style>
commit 313a721af141da069e9441398b12ef2cb09a9cb6 Merge: e420319... feb99dc... Author: John Mazzitelli mazz@redhat.com Date: Mon Dec 14 17:26:37 2009 -0500
Merge branch 'mazz'
commit feb99dcf385d61c3ddc09e7b032b6755063d5b3b Author: John Mazzitelli mazz@redhat.com Date: Mon Dec 14 17:25:15 2009 -0500
if a plugin was undeployed, enabled or disabled on another server in the cloud, all other servers will update themselves within a few minutes.
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/plugin/AgentPluginScanner.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/plugin/AgentPluginScanner.java index 5112347..6beb1f7 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/plugin/AgentPluginScanner.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/plugin/AgentPluginScanner.java @@ -154,7 +154,7 @@ public class AgentPluginScanner { for (File filesystemPluginFile : pluginJars) { if (cachedPluginFile.equals(filesystemPluginFile)) { existsOnFileSystem = true; - continue; // our cached jar still exists on the file system + break; // our cached jar still exists on the file system } } if (!existsOnFileSystem) { diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/plugin/ServerPluginScanner.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/plugin/ServerPluginScanner.java index a6ff24c..a58afb2 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/plugin/ServerPluginScanner.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/plugin/ServerPluginScanner.java @@ -27,6 +27,7 @@ import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.ArrayList; +import java.util.Arrays; import java.util.Date; import java.util.HashMap; import java.util.List; @@ -49,6 +50,8 @@ import org.rhq.core.util.jdbc.JDBCUtil; import org.rhq.core.util.stream.StreamUtil; import org.rhq.enterprise.server.auth.SubjectManagerLocal; import org.rhq.enterprise.server.plugin.ServerPluginsLocal; +import org.rhq.enterprise.server.plugin.pc.AbstractTypeServerPluginContainer; +import org.rhq.enterprise.server.plugin.pc.MasterServerPluginContainer; import org.rhq.enterprise.server.plugin.pc.ServerPluginType; import org.rhq.enterprise.server.util.LookupUtil; import org.rhq.enterprise.server.xmlschema.ServerPluginDescriptorMetadataParser; @@ -87,6 +90,8 @@ public class ServerPluginScanner { * This should be called after a call to {@link #serverPluginScan()} to register * plugins that were found in the scan. * + * This will also check to see if previously registered plugins changed their state. + * * @throws Exception */ void registerServerPlugins() throws Exception { @@ -95,6 +100,52 @@ public class ServerPluginScanner { registerServerPlugin(file); } this.scanned.clear(); + + // we now have to see if the state of existing plugins have changed in the DB + ServerPluginsLocal serverPluginsManager = LookupUtil.getServerPlugins(); + List<ServerPlugin> allPlugins = serverPluginsManager.getAllServerPlugins(); + List<ServerPlugin> installedPlugins = new ArrayList<ServerPlugin>(); + List<ServerPlugin> undeployedPlugins = new ArrayList<ServerPlugin>(); + for (ServerPlugin allPlugin : allPlugins) { + if (allPlugin.getStatus() == PluginStatusType.INSTALLED) { + installedPlugins.add(allPlugin); + } else { + undeployedPlugins.add(allPlugin); + } + } + + // first, have any plugins been undeployed since we last checked? + for (ServerPlugin undeployedPlugin : undeployedPlugins) { + File undeployedFile = new File(this.getServerPluginDir(), undeployedPlugin.getPath()); + PluginWithDescriptor pluginWithDescriptor = this.serverPluginsOnFilesystem.get(undeployedFile); + if (pluginWithDescriptor != null) { + try { + log.info("Plugin file [" + undeployedFile + "] has been undeployed. It will be deleted."); + List<Integer> id = Arrays.asList(new Integer(undeployedPlugin.getId())); + serverPluginsManager.undeployServerPlugins(LookupUtil.getSubjectManager().getOverlord(), id); + } finally { + this.serverPluginsOnFilesystem.remove(undeployedFile); + } + } + } + + // now see if any plugins changed state from enabled->disabled or vice versa + MasterServerPluginContainer master = LookupUtil.getServerPluginService().getMasterPluginContainer(); + if (master != null) { + for (ServerPlugin installedPlugin : installedPlugins) { + PluginKey key = PluginKey.createServerPluginKey(installedPlugin.getType(), installedPlugin.getName()); + AbstractTypeServerPluginContainer pc = master.getPluginContainerByPlugin(key); + if (pc != null && pc.isPluginLoaded(key)) { + boolean currentlyEnabled = pc.isPluginEnabled(key); + if (installedPlugin.isEnabled() != currentlyEnabled) { + log.info("Detected a change to plugin [" + key + "]. It will now be " + + ((installedPlugin.isEnabled()) ? "[enabled]" : "[disabled]")); + pc.reloadPlugin(key, installedPlugin.isEnabled()); + } + } + } + } + return; }
@@ -231,7 +282,7 @@ public class ServerPluginScanner { for (File filesystemPluginFile : pluginJars) { if (cachedPluginFile.equals(filesystemPluginFile)) { existsOnFileSystem = true; - continue; // our cached jar still exists on the file system + break; // our cached jar still exists on the file system } } if (!existsOnFileSystem) { @@ -353,7 +404,7 @@ public class ServerPluginScanner { // the same list as above, only they are the files that are written to the filesystem and no longer missing List<File> updatedFiles = new ArrayList<File>();
- // get all the plugins + // process all the installed plugins ServerPluginsLocal serverPluginsManager = LookupUtil.getServerPlugins(); List<ServerPlugin> installedPlugins = serverPluginsManager.getServerPlugins(); for (ServerPlugin installedPlugin : installedPlugins) { diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/AbstractTypeServerPluginContainer.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/AbstractTypeServerPluginContainer.java index b5572be..17b60ca 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/AbstractTypeServerPluginContainer.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/AbstractTypeServerPluginContainer.java @@ -84,6 +84,32 @@ public abstract class AbstractTypeServerPluginContainer { }
/** + * Determines if the given plugin is loaded in the plugin container. + * The plugin may be loaded but not enabled. + * + * @param pluginKey + * + * @return <code>true</code> if the plugin is loaded in this plugin container; <code>false</code> otherwise + */ + public boolean isPluginLoaded(PluginKey pluginKey) { + return this.pluginManager.isPluginLoaded(pluginKey.getPluginName()); + } + + /** + * Determines if the given plugin is enabled in the plugin container. + * <code>true</code> implies the plugin is also loaded. If <code>false</code> is returned, + * it is either because the plugin is loaded but disabled, or the plugin is just + * not loaded. Use {@link #isPluginLoaded(PluginKey)} to know if the plugin is loaded or not. + * + * @param pluginKey + * + * @return <code>true</code> if the plugin is enabled in this plugin container; <code>false</code> otherwise + */ + public boolean isPluginEnabled(PluginKey pluginKey) { + return this.pluginManager.isPluginEnabled(pluginKey.getPluginName()); + } + + /** * The initialize method that prepares the plugin container. This should get the plugin * container ready to accept plugins. *
commit 83ec25d69ccf72369ef005c2b90b48dcc7986d0e Author: John Mazzitelli mazz@redhat.com Date: Mon Dec 14 17:23:08 2009 -0500
only link to the details page if the plugin is installed
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-list.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-list.xhtml index 15b3601..bca336f 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-list.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-list.xhtml @@ -162,12 +162,13 @@ <h:outputText styleClass="headerText" value="Name"/> </f:facet>
- <h:outputLink value="/rhq/admin/plugin/plugin-details-view.xhtml"> + <h:outputLink value="/rhq/admin/plugin/plugin-details-view.xhtml" rendered="#{serverPlugin.enabled}"> <f:param name="plugin" value="#{serverPlugin.name}"/> <f:param name="deployment" value="SERVER"/> <f:param name="pluginType" value="#{serverPlugin.type}"/> <h:outputText value="#{serverPlugin.displayName}"/> </h:outputLink> + <h:outputText value="#{serverPlugin.displayName}" rendered="#{!serverPlugin.enabled}"/>
</rich:column>
commit 546c68abe21d035952aab368fe65492065a30a58 Author: Jay Shaughnessy jshaughn@redhat.com Date: Mon Dec 14 17:16:08 2009 -0500
Fix up direct SQL error in 2.61
diff --git a/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml b/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml index a2182a7..cfab5a8 100644 --- a/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml +++ b/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml @@ -1943,12 +1943,12 @@
<statement> INSERT INTO - RHQ_DISTRIBUTION_TYPE ( ID, NAME ) + RHQ_DISTRIBUTION_TYPE ( ID, NAME, DESCRIPTION ) VALUES ( 1, 'kickstart', 'Linux kickstart distribution' ) </statement> <statement> INSERT INTO - RHQ_DISTRIBUTION_TYPE ( ID, NAME ) + RHQ_DISTRIBUTION_TYPE ( ID, NAME, DESCRIPTION ) VALUES ( 2, 'jumpstart', 'solaris jumpstart distribution' ) </statement> </schema-directSQL>
commit e420319f056a06b3aed5c37c4a09f4d4c17a4101 Author: Jason Dobies jason.dobies@redhat.com Date: Mon Dec 14 15:04:00 2009 -0500
1054 - BZ 537216 - Need to reload the repo to get around HHH-2864.
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/RepoManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/RepoManagerBean.java index 9f89050..7e96a7b 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/RepoManagerBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/RepoManagerBean.java @@ -300,6 +300,9 @@ public class RepoManagerBean implements RepoManagerLocal, RepoManagerRemote { throw new RepoException("Repo name is required"); }
+ // HHH-2864 - Leave this in until we move to hibernate > 3.2.r14201-2 + getRepo(subject, repo.getId()); + // should we check non-null repo relationships and warn that we aren't changing them? log.debug("User [" + subject + "] is updating repo [" + repo + "]"); repo = entityManager.merge(repo);
commit 4d88d5859f468ff0c973786cdebca0336c212609 Author: John Mazzitelli mazz@redhat.com Date: Mon Dec 14 14:46:56 2009 -0500
use SLSB to get plugins, not jdbc
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/plugin/ServerPluginScanner.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/plugin/ServerPluginScanner.java index d39c8ef..a6ff24c 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/plugin/ServerPluginScanner.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/plugin/ServerPluginScanner.java @@ -347,139 +347,139 @@ public class ServerPluginScanner { * @return a list of files that appear to be new or updated and should be deployed */ private List<File> serverPluginScanDatabase() throws Exception { - Connection conn = null; - PreparedStatement ps = null; - ResultSet rs = null; - // these are plugins (name/path/md5/mtime) that have changed in the DB but are missing from the file system List<ServerPlugin> updatedPlugins = new ArrayList<ServerPlugin>();
// the same list as above, only they are the files that are written to the filesystem and no longer missing List<File> updatedFiles = new ArrayList<File>();
- try { - DataSource ds = LookupUtil.getDataSource(); - conn = ds.getConnection(); - - // get all the plugins - ps = conn.prepareStatement("SELECT NAME, PATH, MD5, MTIME, VERSION, PTYPE FROM " + ServerPlugin.TABLE_NAME - + " WHERE DEPLOYMENT = 'SERVER' AND STATUS = 'INSTALLED' "); - rs = ps.executeQuery(); - while (rs.next()) { - String name = rs.getString(1); - String path = rs.getString(2); - String md5 = rs.getString(3); - long mtime = rs.getLong(4); - String version = rs.getString(5); - ServerPluginType pluginType = new ServerPluginType(rs.getString(6)); - - // let's see if we have this logical plugin on the filesystem (it may or may not be under the same filename) - File expectedFile = new File(this.getServerPluginDir(), path); - File currentFile = null; // will be non-null if we find that we have this plugin on the filesystem already - PluginWithDescriptor pluginWithDescriptor = this.serverPluginsOnFilesystem.get(expectedFile); - - if (pluginWithDescriptor != null) { - currentFile = expectedFile; // we have it where we are expected to have it - if (!pluginWithDescriptor.plugin.getName().equals(name) - || !pluginType.equals(pluginWithDescriptor.pluginType)) { - // Happens if someone wrote a plugin of one type but later changed it to a different type (or changed names) - log.warn("For some reason, the server plugin file [" + expectedFile + "] is plugin [" - + pluginWithDescriptor.plugin.getName() + "] of type [" + pluginWithDescriptor.pluginType - + "] but the database says it should be [" + name + "] of type [" + pluginType + "]"); - } else { - log.debug("File system and db agree on server plugin location for [" + expectedFile + "]"); - } + // get all the plugins + ServerPluginsLocal serverPluginsManager = LookupUtil.getServerPlugins(); + List<ServerPlugin> installedPlugins = serverPluginsManager.getServerPlugins(); + for (ServerPlugin installedPlugin : installedPlugins) { + String name = installedPlugin.getName(); + String path = installedPlugin.getPath(); + String md5 = installedPlugin.getMd5(); + long mtime = installedPlugin.getMtime(); + String version = installedPlugin.getVersion(); + ServerPluginType pluginType = new ServerPluginType(installedPlugin.getType()); + + // let's see if we have this logical plugin on the filesystem (it may or may not be under the same filename) + File expectedFile = new File(this.getServerPluginDir(), path); + File currentFile = null; // will be non-null if we find that we have this plugin on the filesystem already + PluginWithDescriptor pluginWithDescriptor = this.serverPluginsOnFilesystem.get(expectedFile); + + if (pluginWithDescriptor != null) { + currentFile = expectedFile; // we have it where we are expected to have it + if (!pluginWithDescriptor.plugin.getName().equals(name) + || !pluginType.equals(pluginWithDescriptor.pluginType)) { + // Happens if someone wrote a plugin of one type but later changed it to a different type (or changed names) + log.warn("For some reason, the server plugin file [" + expectedFile + "] is plugin [" + + pluginWithDescriptor.plugin.getName() + "] of type [" + pluginWithDescriptor.pluginType + + "] but the database says it should be [" + name + "] of type [" + pluginType + "]"); } else { - // the plugin might still be on the file system but under a different filename, see if we can find it - for (Map.Entry<File, PluginWithDescriptor> cacheEntry : this.serverPluginsOnFilesystem.entrySet()) { - if (cacheEntry.getValue().plugin.getName().equals(name) - && cacheEntry.getValue().pluginType.equals(pluginType)) { - currentFile = cacheEntry.getKey(); - pluginWithDescriptor = cacheEntry.getValue(); - log.info("Filesystem has a server plugin [" + name + "] at the file [" + currentFile - + "] which is different than where the DB thinks it should be [" + expectedFile + "]"); - break; // we found it, no need to continue the loop - } + log.debug("File system and db agree on server plugin location for [" + expectedFile + "]"); + } + } else { + // the plugin might still be on the file system but under a different filename, see if we can find it + for (Map.Entry<File, PluginWithDescriptor> cacheEntry : this.serverPluginsOnFilesystem.entrySet()) { + if (cacheEntry.getValue().plugin.getName().equals(name) + && cacheEntry.getValue().pluginType.equals(pluginType)) { + currentFile = cacheEntry.getKey(); + pluginWithDescriptor = cacheEntry.getValue(); + log.info("Filesystem has a server plugin [" + name + "] at the file [" + currentFile + + "] which is different than where the DB thinks it should be [" + expectedFile + "]"); + break; // we found it, no need to continue the loop } } + }
- if (pluginWithDescriptor != null && currentFile != null && currentFile.exists()) { - ServerPlugin dbPlugin = new ServerPlugin(name, path); - dbPlugin.setType(pluginType.stringify()); - dbPlugin.setMd5(md5); - dbPlugin.setVersion(version); - dbPlugin.setMtime(mtime); - - ServerPlugin obsoletePlugin = ServerPluginDescriptorUtil.determineObsoletePlugin(dbPlugin, - pluginWithDescriptor.plugin); - - if (obsoletePlugin == pluginWithDescriptor.plugin) { // yes use == for reference equality! - StringBuilder logMsg = new StringBuilder(); - logMsg.append("Found server plugin [").append(name); - logMsg.append("] in the DB that is newer than the one on the filesystem: "); - logMsg.append("DB path=[").append(path); - logMsg.append("]; file path=[").append(currentFile.getName()); - logMsg.append("]; DB MD5=[").append(md5); - logMsg.append("]; file MD5=[").append(pluginWithDescriptor.plugin.getMd5()); - logMsg.append("]; DB version=[").append(version); - logMsg.append("]; file version=[").append(pluginWithDescriptor.plugin.getVersion()); - logMsg.append("]; DB timestamp=[").append(new Date(mtime)); - logMsg.append("]; file timestamp=[").append(new Date(pluginWithDescriptor.plugin.getMtime())); - logMsg.append("]"); - log.info(logMsg.toString()); - - updatedPlugins.add(dbPlugin); - - if (currentFile.delete()) { - log.info("Deleted the obsolete server plugin file to be updated: " + currentFile); - this.serverPluginsOnFilesystem.remove(currentFile); - } else { - log.warn("Failed to delete the obsolete (to-be-updated) server plugin: " + currentFile); - } - currentFile = null; - } else if (obsoletePlugin == null) { - // the db is up-to-date, but update the cache so we don't check MD5 or parse the descriptor again - currentFile.setLastModified(mtime); - pluginWithDescriptor.plugin.setMtime(mtime); - pluginWithDescriptor.plugin.setVersion(version); - pluginWithDescriptor.plugin.setMd5(md5); + if (pluginWithDescriptor != null && currentFile != null && currentFile.exists()) { + ServerPlugin dbPlugin = new ServerPlugin(name, path); + dbPlugin.setType(pluginType.stringify()); + dbPlugin.setMd5(md5); + dbPlugin.setVersion(version); + dbPlugin.setMtime(mtime); + + ServerPlugin obsoletePlugin = ServerPluginDescriptorUtil.determineObsoletePlugin(dbPlugin, + pluginWithDescriptor.plugin); + + if (obsoletePlugin == pluginWithDescriptor.plugin) { // yes use == for reference equality! + StringBuilder logMsg = new StringBuilder(); + logMsg.append("Found server plugin [").append(name); + logMsg.append("] in the DB that is newer than the one on the filesystem: "); + logMsg.append("DB path=[").append(path); + logMsg.append("]; file path=[").append(currentFile.getName()); + logMsg.append("]; DB MD5=[").append(md5); + logMsg.append("]; file MD5=[").append(pluginWithDescriptor.plugin.getMd5()); + logMsg.append("]; DB version=[").append(version); + logMsg.append("]; file version=[").append(pluginWithDescriptor.plugin.getVersion()); + logMsg.append("]; DB timestamp=[").append(new Date(mtime)); + logMsg.append("]; file timestamp=[").append(new Date(pluginWithDescriptor.plugin.getMtime())); + logMsg.append("]"); + log.info(logMsg.toString()); + + updatedPlugins.add(dbPlugin); + + if (currentFile.delete()) { + log.info("Deleted the obsolete server plugin file to be updated: " + currentFile); + this.serverPluginsOnFilesystem.remove(currentFile); } else { - log.info("It appears that the server plugin [" + dbPlugin - + "] in the database may be obsolete. If so, it will be updated later."); + log.warn("Failed to delete the obsolete (to-be-updated) server plugin: " + currentFile); } + currentFile = null; + } else if (obsoletePlugin == null) { + // the db is up-to-date, but update the cache so we don't check MD5 or parse the descriptor again + currentFile.setLastModified(mtime); + pluginWithDescriptor.plugin.setMtime(mtime); + pluginWithDescriptor.plugin.setVersion(version); + pluginWithDescriptor.plugin.setMd5(md5); } else { - log.info("Found server plugin in the DB that we do not yet have: " + name); - ServerPlugin plugin = new ServerPlugin(name, path, md5); - plugin.setType(pluginType.stringify()); - plugin.setMtime(mtime); - plugin.setVersion(version); - updatedPlugins.add(plugin); - this.serverPluginsOnFilesystem.remove(expectedFile); // paranoia, make sure the cache doesn't have this + log.info("It appears that the server plugin [" + dbPlugin + + "] in the database may be obsolete. If so, it will be updated later."); } + } else { + log.info("Found server plugin in the DB that we do not yet have: " + name); + ServerPlugin plugin = new ServerPlugin(name, path, md5); + plugin.setType(pluginType.stringify()); + plugin.setMtime(mtime); + plugin.setVersion(version); + updatedPlugins.add(plugin); + this.serverPluginsOnFilesystem.remove(expectedFile); // paranoia, make sure the cache doesn't have this } - JDBCUtil.safeClose(ps, rs); - - // write all our updated plugins to the file system - ps = conn.prepareStatement("SELECT CONTENT FROM " + ServerPlugin.TABLE_NAME - + " WHERE DEPLOYMENT = 'SERVER' AND STATUS = 'INSTALLED' AND NAME = ? AND PTYPE = ?"); - for (ServerPlugin plugin : updatedPlugins) { - File file = new File(this.getServerPluginDir(), plugin.getPath()); - - ps.setString(1, plugin.getName()); - ps.setString(2, plugin.getType()); - rs = ps.executeQuery(); - rs.next(); - InputStream content = rs.getBinaryStream(1); - StreamUtil.copy(content, new FileOutputStream(file)); - rs.close(); - file.setLastModified(plugin.getMtime()); // so our file matches the database mtime - updatedFiles.add(file); - - // we are writing a new file to the filesystem, cache it since we know about it now - cacheFilesystemServerPluginJar(file, null); + } + + // write all our updated plugins to the file system + if (!updatedPlugins.isEmpty()) { + Connection conn = null; + PreparedStatement ps = null; + ResultSet rs = null; + + try { + DataSource ds = LookupUtil.getDataSource(); + conn = ds.getConnection(); + + ps = conn.prepareStatement("SELECT CONTENT FROM " + ServerPlugin.TABLE_NAME + + " WHERE DEPLOYMENT = 'SERVER' AND STATUS = 'INSTALLED' AND NAME = ? AND PTYPE = ?"); + for (ServerPlugin plugin : updatedPlugins) { + File file = new File(this.getServerPluginDir(), plugin.getPath()); + + ps.setString(1, plugin.getName()); + ps.setString(2, plugin.getType()); + rs = ps.executeQuery(); + rs.next(); + InputStream content = rs.getBinaryStream(1); + StreamUtil.copy(content, new FileOutputStream(file)); + rs.close(); + file.setLastModified(plugin.getMtime()); // so our file matches the database mtime + updatedFiles.add(file); + + // we are writing a new file to the filesystem, cache it since we know about it now + cacheFilesystemServerPluginJar(file, null); + } + } finally { + JDBCUtil.safeClose(conn, ps, rs); } - } finally { - JDBCUtil.safeClose(conn, ps, rs); }
return updatedFiles;
commit b2b5fcf609bce798d289458d54df039f289b68a0 Author: John Mazzitelli mazz@redhat.com Date: Mon Dec 14 14:31:12 2009 -0500
remove some unused methods ; use type when comparing plugin data
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/plugin/ServerPluginScanner.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/plugin/ServerPluginScanner.java index 96cd3a2..d39c8ef 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/plugin/ServerPluginScanner.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/plugin/ServerPluginScanner.java @@ -18,10 +18,7 @@ */ package org.rhq.enterprise.server.core.plugin;
-import java.io.BufferedInputStream; -import java.io.ByteArrayInputStream; import java.io.File; -import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.FilenameFilter; import java.io.InputStream; @@ -37,18 +34,11 @@ import java.util.Map; import java.util.Map.Entry;
import javax.sql.DataSource; -import javax.transaction.TransactionManager;
import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.maven.artifact.versioning.ComparableVersion;
-import org.rhq.core.db.DatabaseType; -import org.rhq.core.db.DatabaseTypeFactory; -import org.rhq.core.db.H2DatabaseType; -import org.rhq.core.db.OracleDatabaseType; -import org.rhq.core.db.PostgresqlDatabaseType; -import org.rhq.core.db.SQLServerDatabaseType; import org.rhq.core.domain.configuration.Configuration; import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; import org.rhq.core.domain.plugin.PluginKey; @@ -73,14 +63,13 @@ import org.rhq.enterprise.server.xmlschema.generated.serverplugin.ServerPluginDe public class ServerPluginScanner { private Log log = LogFactory.getLog(ServerPluginScanner.class);
- private DatabaseType dbType = null; - /** a list of server plugins found on previous scans that have not yet been processed */ private List<File> scanned = new ArrayList<File>();
/** Maintains a cache of what we had on the filesystem during the last scan */ private Map<File, PluginWithDescriptor> serverPluginsOnFilesystem = new HashMap<File, PluginWithDescriptor>();
+ /** directory where the server plugin jar files are found */ private File serverPluginDir;
public ServerPluginScanner() { @@ -290,13 +279,13 @@ public class ServerPluginScanner { // Let's check to see if there are any obsolete plugins that need to be deleted. // This is needed if plugin-A-1.0.jar exists and someone deployed plugin-A-1.1.jar but fails to delete plugin-A-1.0.jar. doomedPluginFiles.clear(); - HashMap<String, ServerPlugin> pluginsByName = new HashMap<String, ServerPlugin>(); + HashMap<String, ServerPlugin> pluginsByName = new HashMap<String, ServerPlugin>(); // key on (name+type), not just name for (Entry<File, PluginWithDescriptor> currentPluginFileEntry : this.serverPluginsOnFilesystem.entrySet()) { ServerPlugin currentPlugin = currentPluginFileEntry.getValue().plugin; - ServerPlugin existingPlugin = pluginsByName.get(currentPlugin.getName()); + ServerPlugin existingPlugin = pluginsByName.get(currentPlugin.getName() + currentPlugin.getType()); if (existingPlugin == null) { // this is the usual case - this is the only plugin with the given name we've seen - pluginsByName.put(currentPlugin.getName(), currentPlugin); + pluginsByName.put(currentPlugin.getName() + currentPlugin.getType(), currentPlugin); } else { ServerPlugin obsolete = ServerPluginDescriptorUtil.determineObsoletePlugin(currentPlugin, existingPlugin); @@ -305,7 +294,7 @@ public class ServerPluginScanner { } doomedPluginFiles.add(new File(this.getServerPluginDir(), obsolete.getPath())); if (obsolete == existingPlugin) { // yes use == for reference equality! - pluginsByName.put(currentPlugin.getName(), currentPlugin); // override the original one we saw with this latest one + pluginsByName.put(currentPlugin.getName() + currentPlugin.getType(), currentPlugin); // override the original one we saw with this latest one } } } @@ -340,6 +329,7 @@ public class ServerPluginScanner { String version = ServerPluginDescriptorUtil.getPluginVersion(pluginJar, descriptor).toString(); String name = descriptor.getName(); ServerPlugin plugin = new ServerPlugin(name, pluginJar.getName()); + plugin.setType(new ServerPluginType(descriptor).stringify()); plugin.setMd5(md5); plugin.setVersion(version); plugin.setMtime(pluginJar.lastModified()); @@ -372,7 +362,7 @@ public class ServerPluginScanner { conn = ds.getConnection();
// get all the plugins - ps = conn.prepareStatement("SELECT NAME, PATH, MD5, MTIME, VERSION FROM " + ServerPlugin.TABLE_NAME + ps = conn.prepareStatement("SELECT NAME, PATH, MD5, MTIME, VERSION, PTYPE FROM " + ServerPlugin.TABLE_NAME + " WHERE DEPLOYMENT = 'SERVER' AND STATUS = 'INSTALLED' "); rs = ps.executeQuery(); while (rs.next()) { @@ -381,6 +371,7 @@ public class ServerPluginScanner { String md5 = rs.getString(3); long mtime = rs.getLong(4); String version = rs.getString(5); + ServerPluginType pluginType = new ServerPluginType(rs.getString(6));
// let's see if we have this logical plugin on the filesystem (it may or may not be under the same filename) File expectedFile = new File(this.getServerPluginDir(), path); @@ -389,19 +380,20 @@ public class ServerPluginScanner {
if (pluginWithDescriptor != null) { currentFile = expectedFile; // we have it where we are expected to have it - if (!pluginWithDescriptor.plugin.getName().equals(name)) { - // I have no idea when or if this would ever happen, but at least log it so we'll see it if it does happen + if (!pluginWithDescriptor.plugin.getName().equals(name) + || !pluginType.equals(pluginWithDescriptor.pluginType)) { + // Happens if someone wrote a plugin of one type but later changed it to a different type (or changed names) log.warn("For some reason, the server plugin file [" + expectedFile + "] is plugin [" - + pluginWithDescriptor.plugin.getName() + "] but the database says it should be [" + name - + "]"); + + pluginWithDescriptor.plugin.getName() + "] of type [" + pluginWithDescriptor.pluginType + + "] but the database says it should be [" + name + "] of type [" + pluginType + "]"); } else { - log.debug("File system and database agree on a server plugin location for [" + expectedFile - + "]"); + log.debug("File system and db agree on server plugin location for [" + expectedFile + "]"); } } else { // the plugin might still be on the file system but under a different filename, see if we can find it for (Map.Entry<File, PluginWithDescriptor> cacheEntry : this.serverPluginsOnFilesystem.entrySet()) { - if (cacheEntry.getValue().plugin.getName().equals(name)) { + if (cacheEntry.getValue().plugin.getName().equals(name) + && cacheEntry.getValue().pluginType.equals(pluginType)) { currentFile = cacheEntry.getKey(); pluginWithDescriptor = cacheEntry.getValue(); log.info("Filesystem has a server plugin [" + name + "] at the file [" + currentFile @@ -413,6 +405,7 @@ public class ServerPluginScanner {
if (pluginWithDescriptor != null && currentFile != null && currentFile.exists()) { ServerPlugin dbPlugin = new ServerPlugin(name, path); + dbPlugin.setType(pluginType.stringify()); dbPlugin.setMd5(md5); dbPlugin.setVersion(version); dbPlugin.setMtime(mtime); @@ -441,9 +434,7 @@ public class ServerPluginScanner { log.info("Deleted the obsolete server plugin file to be updated: " + currentFile); this.serverPluginsOnFilesystem.remove(currentFile); } else { - log - .warn("Failed to delete the obsolete (to-be-updated) server plugin file: " - + currentFile); + log.warn("Failed to delete the obsolete (to-be-updated) server plugin: " + currentFile); } currentFile = null; } else if (obsoletePlugin == null) { @@ -459,6 +450,7 @@ public class ServerPluginScanner { } else { log.info("Found server plugin in the DB that we do not yet have: " + name); ServerPlugin plugin = new ServerPlugin(name, path, md5); + plugin.setType(pluginType.stringify()); plugin.setMtime(mtime); plugin.setVersion(version); updatedPlugins.add(plugin); @@ -469,11 +461,12 @@ public class ServerPluginScanner {
// write all our updated plugins to the file system ps = conn.prepareStatement("SELECT CONTENT FROM " + ServerPlugin.TABLE_NAME - + " WHERE DEPLOYMENT = 'SERVER' AND STATUS = 'INSTALLED' AND NAME = ?"); + + " WHERE DEPLOYMENT = 'SERVER' AND STATUS = 'INSTALLED' AND NAME = ? AND PTYPE = ?"); for (ServerPlugin plugin : updatedPlugins) { File file = new File(this.getServerPluginDir(), plugin.getPath());
ps.setString(1, plugin.getName()); + ps.setString(2, plugin.getType()); rs = ps.executeQuery(); rs.next(); InputStream content = rs.getBinaryStream(1); @@ -492,101 +485,15 @@ public class ServerPluginScanner { return updatedFiles; }
- private void setEnabledFlag(Connection conn, PreparedStatement ps, int index, boolean enabled) throws Exception { - if (null == this.dbType) { - this.dbType = DatabaseTypeFactory.getDatabaseType(conn); - } - if (dbType instanceof PostgresqlDatabaseType || dbType instanceof H2DatabaseType) { - ps.setBoolean(index, enabled); - } else if (dbType instanceof OracleDatabaseType || dbType instanceof SQLServerDatabaseType) { - ps.setInt(index, (enabled ? 1 : 0)); - } else { - throw new RuntimeException("Unknown database type : " + dbType); - } - } - - /** - * This will write the contents of the given plugin file to the database. - * This will store both the contents and the MD5 in an atomic transaction - * so they remain insync. - * - * When <code>different</code> is <code>false</code>, it means the original - * plugin and the one currently found on the file system are the same. - * - * When <code>different</code> is <code>true</code>, it means the plugin - * is most likely a different one than the one that originally existed. - * When this happens, it is assumed that the we need - * to see the plugin on the file system as new and needing to be processed, therefore - * the MD5, CONTENT and MTIME columns will be updated to ensure the deployer - * will process this plugin and thus update all the metadata for this plugin. - * - * @param name the name of the plugin whose content is being updated - * @param file the plugin file whose content will be streamed to the database - * @param different this will be <code>true</code> if the given file has a different filename - * that the plugin's "path" as found in the database. - * - * - * @throws Exception - */ - private void streamPluginFileContentToDatabase(String name, File file, boolean different) throws Exception { - Connection conn = null; - PreparedStatement ps = null; - ResultSet rs = null; - TransactionManager tm = null; - - String sql = "UPDATE " - + ServerPlugin.TABLE_NAME - + " SET CONTENT = ?, MD5 = ?, MTIME = ?, PATH = ? WHERE DEPLOYMENT = 'SERVER' AND STATUS = 'INSTALLED' AND NAME = ?"; - - // if 'different' is true, give bogus data so the plugin deployer will think the plugin on the file system is new - String md5 = (!different) ? MessageDigestGenerator.getDigestString(file) : "TO BE UPDATED"; - long mtime = (!different) ? file.lastModified() : 0L; - InputStream fis = (!different) ? new FileInputStream(file) : new ByteArrayInputStream(new byte[0]); - int contentSize = (int) ((!different) ? file.length() : 0); - - try { - tm = LookupUtil.getTransactionManager(); - tm.begin(); - DataSource ds = LookupUtil.getDataSource(); - conn = ds.getConnection(); - ps = conn.prepareStatement(sql); - ps.setBinaryStream(1, new BufferedInputStream(fis), contentSize); - ps.setString(2, md5); - ps.setLong(3, mtime); - ps.setString(4, file.getName()); - ps.setString(5, name); - int updateResults = ps.executeUpdate(); - if (updateResults == 1) { - log.info("Stored content for plugin [" + name + "] in the db. file=" + file); - } else { - throw new Exception("Failed to update content for plugin [" + name + "] from [" + file + "]"); - } - } catch (Exception e) { - tm.rollback(); - tm = null; - throw e; - } finally { - JDBCUtil.safeClose(conn, ps, rs); - - try { - fis.close(); - } catch (Throwable t) { - } - - if (tm != null) { - tm.commit(); - } - } - return; - } - private class PluginWithDescriptor { public PluginWithDescriptor(ServerPlugin plugin, ServerPluginDescriptorType descriptor) { this.plugin = plugin; this.descriptor = descriptor; + this.pluginType = new ServerPluginType(descriptor); }
- public ServerPlugin plugin; - public ServerPluginDescriptorType descriptor; + public final ServerPlugin plugin; + public final ServerPluginDescriptorType descriptor; + public final ServerPluginType pluginType; } } diff --git a/modules/enterprise/server/xml-schemas/src/main/java/org/rhq/enterprise/server/xmlschema/ServerPluginDescriptorUtil.java b/modules/enterprise/server/xml-schemas/src/main/java/org/rhq/enterprise/server/xmlschema/ServerPluginDescriptorUtil.java index 0487d19..675a076 100644 --- a/modules/enterprise/server/xml-schemas/src/main/java/org/rhq/enterprise/server/xmlschema/ServerPluginDescriptorUtil.java +++ b/modules/enterprise/server/xml-schemas/src/main/java/org/rhq/enterprise/server/xmlschema/ServerPluginDescriptorUtil.java @@ -101,13 +101,17 @@ public abstract class ServerPluginDescriptorUtil { * @param plugin2 * @return a reference to the obsolete plugin (plugin1 or plugin2 reference will be returned) * <code>null</code> is returned if they are the same (i.e. they have the same MD5) - * @throws IllegalArgumentException if the two plugins have different logical names + * @throws IllegalArgumentException if the two plugins have different logical names or different types */ public static ServerPlugin determineObsoletePlugin(ServerPlugin plugin1, ServerPlugin plugin2) { if (!plugin1.getName().equals(plugin2.getName())) { throw new IllegalArgumentException("The two plugins don't have the same name:" + plugin1 + ":" + plugin2); }
+ if (!plugin1.getType().equals(plugin2.getType())) { + throw new IllegalArgumentException("The two plugins don't have the same type:" + plugin1 + ":" + plugin2); + } + if (plugin1.getMd5().equals(plugin2.getMd5())) { return null; } else {
commit c02a8fe5b89142966494cf564e15a9ed10d77591 Author: Adam Young ayoung@redhat.com Date: Mon Dec 14 14:12:24 2009 -0500
Cleaned up icons and sidebar navigation, toggles between edit in view
diff --git a/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/AbstractConfigurationComponent.java b/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/AbstractConfigurationComponent.java index 11a4672..2fe72ee 100644 --- a/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/AbstractConfigurationComponent.java +++ b/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/AbstractConfigurationComponent.java @@ -52,7 +52,7 @@ public abstract class AbstractConfigurationComponent extends UIComponentBase imp private static final String READ_ONLY_ATTRIBUTE = "readOnly"; private static final String FULLY_EDITABLE_ATTRIBUTE = "fullyEditable";
- private Boolean readOnly; + private Boolean readOnly = true; private Boolean fullyEditable; private String listName; private Integer listIndex; @@ -224,7 +224,8 @@ public abstract class AbstractConfigurationComponent extends UIComponentBase imp
RawConfigUIComponent getRawConfigUIComponent() { if (null == rawConfigUIComponent) { - rawConfigUIComponent = new RawConfigUIComponent(getConfiguration(), getConfigurationDefinition(), this); + rawConfigUIComponent = new RawConfigUIComponent(getConfiguration(), getConfigurationDefinition(), this, + isReadOnly()); } return rawConfigUIComponent; } diff --git a/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/ConfigRenderer.java b/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/ConfigRenderer.java index c779dda..b4f76f1 100644 --- a/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/ConfigRenderer.java +++ b/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/ConfigRenderer.java @@ -32,6 +32,7 @@ import javax.faces.component.UIComponent; import javax.faces.component.UIForm; import javax.faces.component.UIInput; import javax.faces.component.UIOutput; +import javax.faces.component.UIPanel; import javax.faces.component.UIParameter; import javax.faces.component.html.HtmlCommandLink; import javax.faces.component.html.HtmlForm; @@ -121,6 +122,19 @@ public class ConfigRenderer extends Renderer { } }
+ Boolean readOnly = Boolean.valueOf(FacesContextUtility.getOptionalRequestParameter("readOnly")); + Boolean save = Boolean.valueOf(FacesContextUtility.getOptionalRequestParameter("save")); + configurationComponent.setReadOnly(readOnly); + + if (component.getChildCount() == 0) + addChildComponents(configurationComponent); + for (UIComponent kid : configurationComponent.getChildren()) { + if (kid instanceof RawConfigUIComponent) { + kid.decode(facesContext); + } + + } + }
/** @@ -249,31 +263,60 @@ public class ConfigRenderer extends Renderer { } }
- if (!configurationComponent.isReadOnly()) - addRequiredNotationsKey(configurationComponent); - Boolean shouldShowRawNow = configurationComponent.getShouldShowRaw(); - addStructuredRawToggle(configurationComponent, shouldShowRawNow); + //addStructuredRawToggle(configurationComponent, shouldShowRawNow); if (shouldShowRawNow) { configurationComponent.getChildren().add( new RawConfigUIComponent(configurationComponent.getConfiguration(), configurationComponent - .getConfigurationDefinition(), configurationComponent)); + .getConfigurationDefinition(), configurationComponent, configurationComponent.isReadOnly())); } else { - if (configurationComponent.getListName() != null) { - if (configurationComponent.getListIndex() == null) { - // No index specified means we should add a new map to the list. - configurationComponent.setListIndex(addNewMap(configurationComponent)); - } + addStructuredConfig(configurationComponent); + } + }
- addListMemberProperty(configurationComponent); - } else { - addConfiguration(configurationComponent); + private void addStructuredConfig(AbstractConfigurationComponent configurationComponent) { + UIPanel toolbarPanel = FacesComponentUtility.addBlockPanel(configurationComponent, configurationComponent, + "summary-props-table"); + if (configurationComponent.isReadOnly()) { + HtmlCommandLink editLink = FacesComponentUtility.addCommandLink(toolbarPanel, configurationComponent); + FacesComponentUtility.addGraphicImage(editLink, configurationComponent, "/images/edit.png", "Edit"); + FacesComponentUtility.addOutputText(editLink, configurationComponent, "Edit", ""); + FacesComponentUtility.addParameter(editLink, configurationComponent, "readOnly", Boolean.toString(false)); + + } else { + HtmlCommandLink saveLink = FacesComponentUtility.addCommandLink(toolbarPanel, configurationComponent); + FacesComponentUtility.addGraphicImage(saveLink, configurationComponent, "/images/save.png", "Save"); + FacesComponentUtility.addOutputText(saveLink, configurationComponent, "Save", ""); + FacesComponentUtility.addParameter(saveLink, configurationComponent, "save", Boolean.toString(true)); + FacesComponentUtility.addParameter(saveLink, configurationComponent, "readOnly", Boolean.toString(true)); + } + + if (configurationComponent.getConfigurationDefinition().getConfigurationFormat().isRawSupported()) { + HtmlCommandLink toRawLink = FacesComponentUtility.addCommandLink(toolbarPanel, configurationComponent); + FacesComponentUtility.addGraphicImage(toRawLink, configurationComponent, "/images/raw.png", "showRaw"); + FacesComponentUtility.addOutputText(toRawLink, configurationComponent, "showRaw", ""); + FacesComponentUtility.addParameter(toRawLink, configurationComponent, "showRaw", Boolean.TRUE.toString()); + FacesComponentUtility.addParameter(toRawLink, configurationComponent, "readOnly", Boolean + .toString(configurationComponent.isReadOnly())); + } + + if (!configurationComponent.isReadOnly()) + addRequiredNotationsKey(configurationComponent); + + if (configurationComponent.getListName() != null) { + if (configurationComponent.getListIndex() == null) { + // No index specified means we should add a new map to the list. + configurationComponent.setListIndex(addNewMap(configurationComponent)); }
- String id = getInitInputsJavaScriptComponentId(configurationComponent); - PropertyRenderingUtility.addInitInputsJavaScript(configurationComponent, id, configurationComponent - .isFullyEditable(), false); + addListMemberProperty(configurationComponent); + } else { + addConfiguration(configurationComponent); } + + String id = getInitInputsJavaScriptComponentId(configurationComponent); + PropertyRenderingUtility.addInitInputsJavaScript(configurationComponent, id, configurationComponent + .isFullyEditable(), false); }
private void addStructuredRawToggle(AbstractConfigurationComponent configurationComponent, boolean showRaw) { diff --git a/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/RawConfigUIComponent.java b/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/RawConfigUIComponent.java index 1b7bf89..5280cb0 100644 --- a/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/RawConfigUIComponent.java +++ b/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/RawConfigUIComponent.java @@ -1,6 +1,10 @@ package org.rhq.core.gui.configuration;
import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map;
import javax.faces.component.UIComponent; import javax.faces.component.UIComponentBase; @@ -15,12 +19,16 @@ import org.rhq.core.domain.configuration.RawConfiguration; import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; import org.rhq.core.gui.util.FacesComponentIdFactory; import org.rhq.core.gui.util.FacesComponentUtility; +import org.rhq.core.gui.util.FacesContextUtility;
public class RawConfigUIComponent extends UIComponentBase {
+ private boolean readOnly; + @Override public void decode(FacesContext context) { super.decode(context); + setSelectedPath(FacesContextUtility.getOptionalRequestParameter("path"));
}
@@ -29,9 +37,33 @@ public class RawConfigUIComponent extends UIComponentBase { return "rhq"; }
- Configuration configuration; - ConfigurationDefinition configurationDefinition; - FacesComponentIdFactory idFactory; + private Configuration configuration; + private ConfigurationDefinition configurationDefinition; + private FacesComponentIdFactory idFactory; + private String selectedPath; + private HtmlInputTextarea inputTextarea; + private Map<String, RawConfiguration> rawMap; + + public String getSelectedPath() { + if (null == selectedPath) { + if (configuration.getRawConfigurations().iterator().hasNext()) { + selectedPath = configuration.getRawConfigurations().iterator().next().getPath(); + } else { + selectedPath = ""; + } + } + return selectedPath; + } + + public void setSelectedPath(String selectedPath) { + if (selectedPath == null) + return; + for (RawConfiguration raw : configuration.getRawConfigurations()) { + if (raw.getPath().equals(selectedPath)) { + this.selectedPath = selectedPath; + } + } + }
@Override public boolean getRendersChildren() { @@ -51,14 +83,15 @@ public class RawConfigUIComponent extends UIComponentBase { }
public RawConfigUIComponent(Configuration configuration, ConfigurationDefinition configurationDefinition, - FacesComponentIdFactory componentIdFactory) { + FacesComponentIdFactory componentIdFactory, boolean readOnly) {
this.configuration = configuration; this.configurationDefinition = configurationDefinition; this.idFactory = componentIdFactory; + this.readOnly = readOnly;
UIPanel rawPanel = FacesComponentUtility.addBlockPanel(this, idFactory, ""); - addToolbarIcons(rawPanel); + addToolbarIcons(rawPanel, configurationDefinition.getConfigurationFormat().isStructuredSupported());
HtmlPanelGrid grid = FacesComponentUtility.addPanelGrid(rawPanel, idFactory, "summary-props-table"); grid.setParent(this); @@ -72,11 +105,28 @@ public class RawConfigUIComponent extends UIComponentBase { FacesComponentUtility.addOutputText(panelLeft, idFactory, "Raw Configurations Paths", "");
int rawCount = 0; + + ArrayList<String> configPathList = new ArrayList<String>(); + + rawMap = new HashMap<String, RawConfiguration>(); + for (RawConfiguration raw : configuration.getRawConfigurations()) { + configPathList.add(raw.getPath()); + rawMap.put(raw.getPath(), raw); + } + Collections.sort(configPathList); + String oldDirname = ""; + for (String s : configPathList) { + RawConfiguration raw = rawMap.get(s); + String dirname = raw.getPath().substring(0, raw.getPath().lastIndexOf("/") + 1); + String basename = raw.getPath().substring(raw.getPath().lastIndexOf("/") + 1, raw.getPath().length()); + if (!dirname.equals(oldDirname)) { + FacesComponentUtility.addOutputText(panelLeft, idFactory, dirname, ""); + oldDirname = dirname; + } UIPanel nextPath = FacesComponentUtility.addBlockPanel(panelLeft, idFactory, ""); HtmlCommandLink link = FacesComponentUtility.addCommandLink(nextPath, idFactory); - - FacesComponentUtility.addOutputText(link, idFactory, raw.getPath(), ""); + FacesComponentUtility.addOutputText(link, idFactory, "[]" + basename, ""); FacesComponentUtility.addParameter(link, idFactory, "path", raw.getPath()); FacesComponentUtility.addParameter(link, idFactory, "whichRaw", Integer.toString(rawCount++)); FacesComponentUtility.addParameter(link, idFactory, "showRaw", Boolean.TRUE.toString()); @@ -85,29 +135,54 @@ public class RawConfigUIComponent extends UIComponentBase { UIPanel panelRight = FacesComponentUtility.addBlockPanel(grid, idFactory, "summary-props-table");
UIPanel editPanel = FacesComponentUtility.addBlockPanel(panelRight, idFactory, "summary-props-table"); - HtmlInputTextarea inputTextarea = new HtmlInputTextarea(); + inputTextarea = new HtmlInputTextarea(); editPanel.getChildren().add(inputTextarea); inputTextarea.setParent(editPanel); inputTextarea.setCols(80); inputTextarea.setRows(40); - inputTextarea.setValue(configuration.getRawConfigurations().iterator().next().getContentString()); + inputTextarea.setValue(rawMap.get(getSelectedPath()).getContentString()); + inputTextarea.setReadonly(readOnly); }
- private void addToolbarIcons(UIPanel panelRight) { - HtmlCommandLink fullScreenCommandLink = FacesComponentUtility.addCommandLink(panelRight, idFactory); - FacesComponentUtility.addGraphicImage(fullScreenCommandLink, idFactory, "/images/save.png", "Save"); - FacesComponentUtility.addOutputText(fullScreenCommandLink, idFactory, "Save", ""); - - HtmlCommandLink saveCommandLink = FacesComponentUtility.addCommandLink(panelRight, idFactory); + private void addToolbarIcons(UIPanel toolbarPanel, boolean supportsStructured) { + + if (readOnly) { + HtmlCommandLink editLink = FacesComponentUtility.addCommandLink(toolbarPanel, idFactory); + FacesComponentUtility.addGraphicImage(editLink, idFactory, "/images/edit.png", "Edit"); + FacesComponentUtility.addOutputText(editLink, idFactory, "Edit", ""); + FacesComponentUtility.addParameter(editLink, idFactory, "showStructured", Boolean.FALSE.toString()); + } else { + HtmlCommandLink saveLink = FacesComponentUtility.addCommandLink(toolbarPanel, idFactory); + FacesComponentUtility.addGraphicImage(saveLink, idFactory, "/images/save.png", "Save"); + FacesComponentUtility.addOutputText(saveLink, idFactory, "Save", ""); + FacesComponentUtility.addParameter(saveLink, idFactory, "showStructured", Boolean.FALSE.toString()); + } + HtmlCommandLink saveCommandLink = FacesComponentUtility.addCommandLink(toolbarPanel, idFactory); FacesComponentUtility.addGraphicImage(saveCommandLink, idFactory, "/images/viewfullscreen.png", "FullScreen"); FacesComponentUtility.addOutputText(saveCommandLink, idFactory, "Full Screen", "");
- HtmlCommandLink uploadCommandLink = FacesComponentUtility.addCommandLink(panelRight, idFactory); + HtmlCommandLink uploadCommandLink = FacesComponentUtility.addCommandLink(toolbarPanel, idFactory); FacesComponentUtility.addGraphicImage(uploadCommandLink, idFactory, "/images/upload.png", "Upload"); FacesComponentUtility.addOutputText(uploadCommandLink, idFactory, "Upload", "");
- HtmlCommandLink downloadCommandLink = FacesComponentUtility.addCommandLink(panelRight, idFactory); + HtmlCommandLink downloadCommandLink = FacesComponentUtility.addCommandLink(toolbarPanel, idFactory); FacesComponentUtility.addGraphicImage(downloadCommandLink, idFactory, "/images/download.png", "download"); FacesComponentUtility.addOutputText(downloadCommandLink, idFactory, "Download", ""); + + if (supportsStructured) { + HtmlCommandLink toStructureLink = FacesComponentUtility.addCommandLink(toolbarPanel, idFactory); + FacesComponentUtility.addGraphicImage(toStructureLink, idFactory, "/images/structured.png", + "showStructured"); + FacesComponentUtility.addOutputText(toStructureLink, idFactory, "showStructured", ""); + FacesComponentUtility.addParameter(toStructureLink, idFactory, "showStructured", Boolean.FALSE.toString()); + } + } + + @Override + public void encodeBegin(FacesContext context) throws IOException { + // TODO Auto-generated method stub + super.encodeBegin(context); + inputTextarea.setValue(rawMap.get(getSelectedPath()).getContentString()); + } } diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/images/edit.png b/modules/enterprise/gui/portal-war/src/main/webapp/images/edit.png new file mode 100644 index 0000000..b1c3c61 Binary files /dev/null and b/modules/enterprise/gui/portal-war/src/main/webapp/images/edit.png differ diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/images/raw.png b/modules/enterprise/gui/portal-war/src/main/webapp/images/raw.png new file mode 100644 index 0000000..9ccae0e Binary files /dev/null and b/modules/enterprise/gui/portal-war/src/main/webapp/images/raw.png differ diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/images/structured.png b/modules/enterprise/gui/portal-war/src/main/webapp/images/structured.png new file mode 100644 index 0000000..94fcf83 Binary files /dev/null and b/modules/enterprise/gui/portal-war/src/main/webapp/images/structured.png differ diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit.xhtml index d067d8a..a85f409 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit.xhtml @@ -22,6 +22,12 @@ THIS TEXT WILL BE REMOVED. <ui:param name="selectedTabName" value="Configuration.Current"/>
<ui:define name="content"> + <style type="text/css"> + td.raw-config-table { + vertical-align: top; + valign: top; + } + </style>
<h:form id="editResourceConfigurationForm" onsubmit="prepareInputsForSubmission(this)" rendered="#{!ViewResourceConfigurationUIBean.updateInProgress}">
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml index 12156e4..dabda7e 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml @@ -25,7 +25,7 @@ THIS TEXT WILL BE REMOVED. <ui:define name="content">
- <style type="text/css"> +<style type="text/css"> td.raw-config-table { vertical-align: top; valign: top; @@ -43,22 +43,10 @@ THIS TEXT WILL BE REMOVED. <h:form id="viewResourceConfigurationForm"> <!-- TODO remove the id version --> <input type="hidden" name="id" value="#{ResourceUIBean.id}"/> - - <h:panelGrid columns="2" styleClass="buttons-table" columnClasses="button-cell" - rendered="#{ExistingResourceConfigurationUIBean.configuration != null and !ExistingResourceConfigurationUIBean.updateInProgress}"> - - <h:commandButton value="#{messages.editstructured}" action="#{ExistingResourceConfigurationUIBean.editConfiguration}" - title="Edit this Configuration" styleClass="buttonmed" - rendered="${ResourceUIBean.permissions.configure and ExistingResourceConfigurationUIBean.structuredSupported and !ExistingResourceConfigurationUIBean.updateInProgress}" /> - <h:commandButton value="#{messages.editraw}" action="#{ExistingResourceConfigurationUIBean.editRawConfiguration}" - title="Advanced Mode Edit of Raw Configuration Files" styleClass="buttonmed" - rendered="${ResourceUIBean.permissions.configure and ExistingResourceConfigurationUIBean.rawSupported and !ExistingResourceConfigurationUIBean.updateInProgress}" /> - </h:panelGrid>
<onc:config configurationDefinition="#{ExistingResourceConfigurationUIBean.configurationDefinition}" configuration="#{ExistingResourceConfigurationUIBean.configuration}" accessMapActionExpression="#{ExistingResourceConfigurationUIBean.accessMap}" - readOnly="true" nullConfigurationDefinitionMessage="#{ExistingResourceConfigurationUIBean.nullConfigurationDefinitionMessage}" nullConfigurationMessage="#{ExistingResourceConfigurationUIBean.nullConfigurationMessage}" prevalidate="true"/>
commit 3b562fa0f9ba67fd10cbe8ebc51719f9dafa9520 Author: Justin Harris jharris@redhat.com Date: Mon Dec 14 12:56:09 2009 -0500
Fixing scoping bug that affected editing the incorrect plugin.
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/EditPluginConfigurationUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/EditPluginConfigurationUIBean.java index 7fad490..f85269f 100644 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/EditPluginConfigurationUIBean.java +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/EditPluginConfigurationUIBean.java @@ -39,7 +39,7 @@ import org.rhq.enterprise.gui.util.EnterpriseFacesContextUtility; import org.rhq.enterprise.server.plugin.ServerPluginsLocal; import org.rhq.enterprise.server.util.LookupUtil;
-@Scope(ScopeType.SESSION) +@Scope(ScopeType.PAGE) @Name("editPluginConfigurationUIBean") public class EditPluginConfigurationUIBean extends AbstractPluginConfigurationUIBean implements Serializable {
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/PluginFactory.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/PluginFactory.java index 8ea565e..8ebd73d 100644 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/PluginFactory.java +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/PluginFactory.java @@ -47,7 +47,7 @@ public class PluginFactory { @RequestParameter("pluginType") private String pluginType;
- @Factory(value = "plugin", autoCreate = true) + @Factory(value = "plugin", autoCreate = true, scope = ScopeType.EVENT) public AbstractPlugin lookupPlugin() { if (this.deployment == PluginDeploymentType.AGENT) { return LookupUtil.getResourceMetadataManager().getPlugin(this.name);
commit 9bbb1e9dfe93f7ccced605748fae28c0b0a13080 Author: Justin Harris jharris@redhat.com Date: Mon Dec 14 12:38:40 2009 -0500
Disabling and re-enabling a plugin when configuration settings are saved.
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/EditPluginConfigurationUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/EditPluginConfigurationUIBean.java index 6dab242..7fad490 100644 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/EditPluginConfigurationUIBean.java +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/EditPluginConfigurationUIBean.java @@ -19,6 +19,8 @@ package org.rhq.enterprise.gui.admin.plugin;
import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; import javax.faces.application.FacesMessage; import org.jboss.seam.ScopeType; import org.jboss.seam.annotations.Create; @@ -104,6 +106,11 @@ public class EditPluginConfigurationUIBean extends AbstractPluginConfigurationUI ServerPluginsLocal serverPlugins = LookupUtil.getServerPlugins(); Subject subject = EnterpriseFacesContextUtility.getSubject(); serverPlugins.updateServerPluginExceptContent(subject, getPlugin()); + + // rekick the updated plugin so that any config changes take effect + serverPlugins.disableServerPlugins(subject, getPluginIdList()); + serverPlugins.enableServerPlugins(subject, getPluginIdList()); + FacesContextUtility.addMessage(FacesMessage.SEVERITY_INFO, "Configuration settings saved."); } catch (Exception e) { log.error("Error updating the plugin configurations.", e); @@ -115,4 +122,15 @@ public class EditPluginConfigurationUIBean extends AbstractPluginConfigurationUI
return "success"; } + + private List<Integer> getPluginIdList() { + List<Integer> idList = new ArrayList<Integer>(1); + ServerPlugin plugin = getPlugin(); + + if (plugin != null) { + idList.add(plugin.getId()); + } + + return idList; + } } diff --git a/modules/enterprise/server/plugins/alert-irc/src/main/java/org/rhq/enterprise/server/plugins/alertIrc/IrcAlertComponent.java b/modules/enterprise/server/plugins/alert-irc/src/main/java/org/rhq/enterprise/server/plugins/alertIrc/IrcAlertComponent.java index f8716d6..13c910b 100644 --- a/modules/enterprise/server/plugins/alert-irc/src/main/java/org/rhq/enterprise/server/plugins/alertIrc/IrcAlertComponent.java +++ b/modules/enterprise/server/plugins/alert-irc/src/main/java/org/rhq/enterprise/server/plugins/alertIrc/IrcAlertComponent.java @@ -151,10 +151,7 @@ public class IrcAlertComponent implements ServerPluginComponent { public void onMessage(String channel, String sender, String login, String hostname, String message) {
- if (!message.contains(nick)) - return; - - if (this.response != null) { + if (this.response != null && message.startsWith(nick)) { if (channel != null && channel.length() > 0) { sendMessage(channel, sender + ": " + this.response); } else {
commit c5fb24fc44954ff14c38ca444d90fee7707ab76b Author: Adam Young ayoung@redhat.com Date: Sun Dec 13 15:53:48 2009 -0500
Extended the unit test to run through additional components such as grid and image.
diff --git a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/ConfigRendererTest.java b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/ConfigRendererTest.java index 660933b..d3db839 100644 --- a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/ConfigRendererTest.java +++ b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/ConfigRendererTest.java @@ -5,6 +5,7 @@ import java.io.StringWriter; import java.util.HashMap;
import javax.faces.FactoryFinder; +import javax.faces.component.UIForm; import javax.faces.context.FacesContext; import javax.faces.lifecycle.Lifecycle;
@@ -83,10 +84,17 @@ public class ConfigRendererTest { value.setName("test1"); value.setConfiguration(configuration); value.setId(3); + configuration.getMap().put(value.getName(), value); configuration.getRawConfigurations().add(buildMockRawConfig());
Assert.assertNotNull(configUIComponent.getConfigurationDefinition()); + + UIForm form = new UIForm(); + form.setId("form"); + form.getChildren().add(configUIComponent); + configUIComponent.setParent(form); + configUIComponent.getConfigurationDefinition().setConfigurationFormat(ConfigurationFormat.STRUCTURED_AND_RAW);
Assert.assertNotNull(configUIComponent.getConfigurationDefinition().getConfigurationFormat()); diff --git a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockApplication.java b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockApplication.java index abe95ee..94f5bc8 100644 --- a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockApplication.java +++ b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockApplication.java @@ -198,9 +198,11 @@ public class MockApplication extends Application {
}
+ MockViewHandler mockViewHandler = new MockViewHandler(); + @Override public ViewHandler getViewHandler() { - throw new RuntimeException("Function not implemented"); + return mockViewHandler;
}
diff --git a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockExternalContext.java b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockExternalContext.java index cd8500c..ed0af06 100644 --- a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockExternalContext.java +++ b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockExternalContext.java @@ -37,7 +37,8 @@ public class MockExternalContext extends ExternalContext {
@Override public String encodeResourceURL(String url) { - throw new RuntimeException("Function not implemented"); + + return "encodedUrl:" + url;
}
@@ -48,6 +49,7 @@ public class MockExternalContext extends ExternalContext { if (null == applicationMap) { applicationMap = new HashMap<String, Object>(); applicationMap.put("com.sun.faces.ApplicationImpl", new ApplicationImpl()); + applicationMap.put("com.sun.faces.sunJsfJs", "Javascript goes here".toCharArray()); }
return applicationMap; diff --git a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockFacesContext.java b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockFacesContext.java index 77e410d..c61465d 100644 --- a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockFacesContext.java +++ b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockFacesContext.java @@ -106,7 +106,8 @@ public class MockFacesContext extends FacesContext {
@Override public UIViewRoot getViewRoot() { - throw new RuntimeException("Function not implemented"); + return null; + //throw new RuntimeException("Function not implemented");
}
diff --git a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockRenderKit.java b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockRenderKit.java index 6f490f2..2d1981f 100644 --- a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockRenderKit.java +++ b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockRenderKit.java @@ -3,6 +3,7 @@ package org.rhq.core.gui.configuration; import java.io.OutputStream; import java.io.Writer; import java.util.HashMap; +import java.util.HashSet;
import javax.faces.context.ResponseStream; import javax.faces.context.ResponseWriter; @@ -34,10 +35,26 @@ public class MockRenderKit extends RenderKit {
}
+ HashSet<String> noRendererSet; + + public HashSet<String> getNoRendererSet() { + if (null == noRendererSet) { + noRendererSet = new HashSet<String>(); + noRendererSet.add("javax.faces.HtmlCommandLink"); + noRendererSet.add("javax.faces.Form"); + noRendererSet.add("javax.faces.Textarea"); + } + return noRendererSet; + } + HashMap<String, Class> rendererMap;
@Override public Renderer getRenderer(String family, String rendererType) { + + if (getNoRendererSet().contains(rendererType)) + return null; + try { if (null == rendererMap) { rendererMap = new HashMap<String, Class>(); @@ -45,16 +62,17 @@ public class MockRenderKit extends RenderKit { rendererMap.put("javax.faces.Format", OutputMessageRenderer.class); rendererMap.put("javax.faces.Group", GroupRenderer.class); rendererMap.put(ConfigRenderer.class.getName(), ConfigRenderer.class); - //HtmlCommandLink has no renderer. It renders itself + rendererMap.put("javax.faces.Link", com.sun.faces.renderkit.html_basic.CommandLinkRenderer.class); + rendererMap.put("javax.faces.Image", com.sun.faces.renderkit.html_basic.ImageRenderer.class); + rendererMap.put("javax.faces.Grid", com.sun.faces.renderkit.html_basic.GridRenderer.class); + } Class c = rendererMap.get(rendererType); if (c == null) { System.out.println("MockRenderKit request for unsupported type " + rendererType); - return null; - } else { - - return (Renderer) c.newInstance(); } + return (Renderer) c.newInstance(); + } catch (Exception e) { throw new RuntimeException(e); } diff --git a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockResponseWriter.java b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockResponseWriter.java index d1b6e56..85247fb 100644 --- a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockResponseWriter.java +++ b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockResponseWriter.java @@ -31,7 +31,8 @@ public class MockResponseWriter extends ResponseWriter {
@Override public void flush() throws IOException { - throw new RuntimeException("Function not implemented"); + + stringWriter.flush();
}
@@ -43,8 +44,7 @@ public class MockResponseWriter extends ResponseWriter {
@Override public String getContentType() { - throw new RuntimeException("Function not implemented"); - + return "contenttype:"; }
@Override @@ -55,7 +55,8 @@ public class MockResponseWriter extends ResponseWriter {
@Override public void startElement(String name, UIComponent component) throws IOException { - stringWriter.write("startElement: " + name + ": componenet:" + component.getId() + "\n"); + stringWriter.write("startElement: " + name + ": component:" + + (component != null ? component.getId() : "componenet is null") + "\n"); }
@Override @@ -82,8 +83,7 @@ public class MockResponseWriter extends ResponseWriter {
@Override public void writeURIAttribute(String name, Object value, String property) throws IOException { - throw new RuntimeException("Function not implemented"); - + stringWriter.write("attributename:" + name + ", value:" + value.toString() + ", property:" + property); }
@Override diff --git a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockViewHandler.java b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockViewHandler.java new file mode 100644 index 0000000..0074169 --- /dev/null +++ b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockViewHandler.java @@ -0,0 +1,53 @@ +package org.rhq.core.gui.configuration; + +import java.io.IOException; +import java.util.Locale; + +import javax.faces.FacesException; +import javax.faces.application.ViewHandler; +import javax.faces.component.UIViewRoot; +import javax.faces.context.FacesContext; + +public class MockViewHandler extends ViewHandler { + + @Override + public Locale calculateLocale(FacesContext context) { + throw new RuntimeException("Function not implemented"); + } + + @Override + public String calculateRenderKitId(FacesContext context) { + throw new RuntimeException("Function not implemented"); + } + + @Override + public UIViewRoot createView(FacesContext context, String viewId) { + throw new RuntimeException("Function not implemented"); + } + + @Override + public String getActionURL(FacesContext context, String viewId) { + throw new RuntimeException("Function not implemented"); + } + + @Override + public String getResourceURL(FacesContext context, String path) { + return "uri://" + path; + } + + @Override + public void renderView(FacesContext context, UIViewRoot viewToRender) throws IOException, FacesException { + throw new RuntimeException("Function not implemented"); + } + + @Override + public UIViewRoot restoreView(FacesContext context, String viewId) { + throw new RuntimeException("Function not implemented"); + } + + @Override + public void writeState(FacesContext context) throws IOException { + throw new RuntimeException("Function not implemented"); + } + +} diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit-raw.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit-raw.xhtml index c01694e..6ccfaab 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit-raw.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit-raw.xhtml @@ -34,15 +34,6 @@ </script> <a4j:form id="editResourceConfigurationForm"> - <h:outputText value="#{messages.youareviewingraw}" /> - <h:panelGroup rendered="#{ExistingResourceConfigurationUIBean.structuredSupported}"> - <h:outputText value=" #{messages.switch2}" /> - <h:commandLink action="#{ExistingResourceConfigurationUIBean.switchTostructured}"> - <s:conversationId /> - <f:param name="id" value="#{ResourceUIBean.id}" /> - <h:outputText value=" #{messages.structured}" /> - </h:commandLink> - </h:panelGroup> <table class="summary-props-table" style=""> <input type="hidden" name="id" value="#{ResourceUIBean.id}" />
commit 4d08d8f6188243555cf5dcf4c8cf2e00a95f44b8 Author: Adam Young ayoung@redhat.com Date: Sun Dec 13 14:22:13 2009 -0500
Fixed unit test
diff --git a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/ConfigRendererTest.java b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/ConfigRendererTest.java index 9c57ad4..660933b 100644 --- a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/ConfigRendererTest.java +++ b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/ConfigRendererTest.java @@ -17,6 +17,7 @@ import org.testng.annotations.Test;
import org.rhq.core.domain.configuration.Configuration; import org.rhq.core.domain.configuration.Property; +import org.rhq.core.domain.configuration.RawConfiguration; import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; import org.rhq.core.domain.configuration.definition.ConfigurationFormat;
@@ -83,6 +84,7 @@ public class ConfigRendererTest { value.setConfiguration(configuration); value.setId(3); configuration.getMap().put(value.getName(), value); + configuration.getRawConfigurations().add(buildMockRawConfig());
Assert.assertNotNull(configUIComponent.getConfigurationDefinition()); configUIComponent.getConfigurationDefinition().setConfigurationFormat(ConfigurationFormat.STRUCTURED_AND_RAW); @@ -102,6 +104,13 @@ public class ConfigRendererTest {
}
+ private RawConfiguration buildMockRawConfig() { + RawConfiguration raw = new RawConfiguration(); + + raw.setContents("a=1".getBytes()); + return raw; + } + //@Test public void testDecode() { configUIComponent.setReadOnly(false); diff --git a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockApplication.java b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockApplication.java index d89eb86..abe95ee 100644 --- a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockApplication.java +++ b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockApplication.java @@ -14,8 +14,10 @@ import javax.faces.application.ViewHandler; import javax.faces.component.UIComponent; import javax.faces.component.UIParameter; import javax.faces.component.html.HtmlCommandLink; +import javax.faces.component.html.HtmlGraphicImage; import javax.faces.component.html.HtmlOutputFormat; import javax.faces.component.html.HtmlOutputText; +import javax.faces.component.html.HtmlPanelGrid; import javax.faces.component.html.HtmlPanelGroup; import javax.faces.context.FacesContext; import javax.faces.convert.Converter; @@ -118,6 +120,8 @@ public class MockApplication extends Application { componentTypeMap.put("javax.faces.Output", HtmlOutputFormat.class); componentTypeMap.put("javax.faces.HtmlCommandLink", HtmlCommandLink.class); componentTypeMap.put("javax.faces.Parameter", UIParameter.class); + componentTypeMap.put("javax.faces.HtmlGraphicImage", HtmlGraphicImage.class); + componentTypeMap.put("javax.faces.HtmlPanelGrid", HtmlPanelGrid.class); } return componentTypeMap; } diff --git a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockServletContext.java b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockServletContext.java index 8740aca..f604d00 100644 --- a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockServletContext.java +++ b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockServletContext.java @@ -34,7 +34,6 @@ import javax.servlet.ServletContext; import javax.servlet.ServletException;
import com.sun.faces.config.WebConfiguration; - final class MockServletContext implements ServletContext { public void setAttribute(String arg0, Object arg1) { this.attributeMap.put(arg0, arg1);
commit e1105e2cee84559602c932dcd87bd00832f6b77e Author: Adam Young ayoung@redhat.com Date: Fri Dec 11 18:47:28 2009 -0500
Merging the raw config work into the JSF components, and removing from the facelet code.
diff --git a/.classpath b/.classpath index 55ab9f4..91f0343 100644 --- a/.classpath +++ b/.classpath @@ -1,6 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> <classpath> <classpathentry kind="src" path="modules/common/jboss-as/src/main/java"/> + <classpathentry kind="src" path="modules/test-utils/src/main/java"/> <classpathentry kind="src" path="modules/common/jboss-as/src/test/java"/> <classpathentry kind="src" path="modules/plugins/jboss-as/src/main/java"/> <classpathentry kind="src" path="modules/plugins/jboss-as/src/test/java"/> @@ -13,8 +14,9 @@ <classpathentry kind="src" path="modules/plugins/tomcat/src/test/java"/> <classpathentry kind="src" path="modules/plugins/jboss-cache/src/main/java"/> <classpathentry kind="src" path="modules/plugins/jboss-cache-v3/src/main/java"/> - <classpathentry excluding="org/rhq/plugins/antlrconfig/" kind="src" path="modules/plugins/antlr-config/src/main/java"/> + <classpathentry kind="src" path="modules/plugins/antlr-config/src/main/java"/> <classpathentry kind="src" path="modules/core/gui/src/test/java"/> + <classpathentry kind="src" path="modules/plugins/antlr-config/target/generated-sources/antlr3"/> <classpathentry kind="var" path="M2_REPO/org/jboss/integration/jboss-profileservice-spi/5.1.0.SP1/jboss-profileservice-spi-5.1.0.SP1.jar"/> <classpathentry kind="var" path="M2_REPO/org/jboss/man/jboss-managed/2.1.1.GA/jboss-managed-2.1.1.GA.jar"/> <classpathentry kind="var" path="M2_REPO/org/jboss/man/jboss-metatype/2.1.1.GA/jboss-metatype-2.1.1.GA.jar"/> @@ -104,7 +106,6 @@ <classpathentry kind="src" path="modules/plugins/snmptrapd/src/main/java"/> <classpathentry kind="src" path="modules/plugins/script/src/main/java"/> <classpathentry kind="src" path="modules/plugins/antlr-config/src/main/antlr3"/> - <classpathentry kind="src" path="modules/plugins/antlr-config/target/generated-sources/antlr3"/> <classpathentry kind="src" path="modules/helpers/rtfilter/src/main/java"/> <classpathentry kind="src" path="modules/helpers/pluginAnnotations/src/main/java"/> <classpathentry kind="src" path="modules/helpers/pluginGen/src/main/java"/> @@ -204,5 +205,8 @@ <classpathentry exported="true" kind="var" path="M2_REPO/commons-digester/commons-digester/1.8/commons-digester-1.8.jar"/> <classpathentry exported="true" kind="var" path="M2_REPO/commons-codec/commons-codec/1.4/commons-codec-1.4.jar"/> <classpathentry exported="true" kind="lib" path="modules/enterprise/remoting/webservices/target/rhq-remoting-webservices-1.4.0-SNAPSHOT/wsconsume-output"/> + <classpathentry kind="var" path="M2_REPO/org/jmock/jmock/2.5.1/jmock-2.5.1.jar" sourcepath="/M2_REPO/org/jmock/jmock/2.5.1/jmock-2.5.1-sources.jar"/> + <classpathentry kind="var" path="M2_REPO/org/hamcrest/hamcrest-core/1.1/hamcrest-core-1.1.jar" sourcepath="/M2_REPO/org/hamcrest/hamcrest-core/1.1/hamcrest-core-1.1-sources.jar"/> + <classpathentry kind="var" path="M2_REPO/org/hamcrest/hamcrest-library/1.1/hamcrest-library-1.1.jar" sourcepath="M2_REPO/org/hamcrest/hamcrest-library/1.1/hamcrest-library-1.1-sources.jar"/> <classpathentry kind="output" path="eclipse-classes"/> </classpath> diff --git a/.gitignore b/.gitignore index 1d53abe..bca5c45 100644 --- a/.gitignore +++ b/.gitignore @@ -18,3 +18,4 @@ dev-container dev-agent antlr-generated/ *.tokens +test-output/* diff --git a/modules/core/gui/pom.xml b/modules/core/gui/pom.xml index 96a3212..eaddceb 100644 --- a/modules/core/gui/pom.xml +++ b/modules/core/gui/pom.xml @@ -138,6 +138,14 @@ </exclusions> </dependency>
+ + <dependency> + <groupId>javax.faces</groupId> + <artifactId>jsf-impl</artifactId> + <scope>provided</scope> + </dependency> + + </dependencies>
<repositories> @@ -221,4 +229,4 @@
</profiles>
-</project> \ No newline at end of file +</project> diff --git a/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/AbstractConfigurationComponent.java b/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/AbstractConfigurationComponent.java index 3cda4bd..11a4672 100644 --- a/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/AbstractConfigurationComponent.java +++ b/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/AbstractConfigurationComponent.java @@ -29,9 +29,11 @@ import javax.faces.context.FacesContext;
import org.rhq.core.domain.configuration.Configuration; import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; +import org.rhq.core.domain.configuration.definition.ConfigurationFormat; import org.rhq.core.gui.configuration.propset.ConfigurationSetComponent; import org.rhq.core.gui.util.FacesComponentIdFactory; import org.rhq.core.gui.util.FacesComponentUtility; +import org.rhq.core.gui.util.FacesContextUtility;
/** * An abstract base class for the {@link ConfigUIComponent} and the {@link ConfigurationSetComponent} JSF component @@ -213,4 +215,18 @@ public abstract class AbstractConfigurationComponent extends UIComponentBase imp this.isGroup = (Boolean) this.stateValues[6]; }
+ public boolean getShouldShowRaw() { + return Boolean.valueOf(FacesContextUtility.getOptionalRequestParameter("showRaw", String.class, "unset")) + || (this.getConfigurationDefinition().getConfigurationFormat().equals(ConfigurationFormat.RAW)); + } + + RawConfigUIComponent rawConfigUIComponent; + + RawConfigUIComponent getRawConfigUIComponent() { + if (null == rawConfigUIComponent) { + rawConfigUIComponent = new RawConfigUIComponent(getConfiguration(), getConfigurationDefinition(), this); + } + return rawConfigUIComponent; + } + } \ No newline at end of file diff --git a/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/ConfigRenderer.java b/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/ConfigRenderer.java index b5e67a3..c779dda 100644 --- a/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/ConfigRenderer.java +++ b/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/ConfigRenderer.java @@ -31,7 +31,9 @@ import javax.faces.application.FacesMessage; import javax.faces.component.UIComponent; import javax.faces.component.UIForm; import javax.faces.component.UIInput; +import javax.faces.component.UIOutput; import javax.faces.component.UIParameter; +import javax.faces.component.html.HtmlCommandLink; import javax.faces.component.html.HtmlForm; import javax.faces.component.html.HtmlOutputLink; import javax.faces.component.html.HtmlPanelGrid; @@ -54,6 +56,7 @@ 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.configuration.definition.ConfigurationFormat; import org.rhq.core.domain.configuration.definition.PropertyDefinition; import org.rhq.core.domain.configuration.definition.PropertyDefinitionMap; import org.rhq.core.domain.configuration.definition.PropertyDefinitionSimple; @@ -117,6 +120,7 @@ public class ConfigRenderer extends Renderer { .isFullyEditable(), true); } } + }
/** @@ -195,12 +199,16 @@ public class ConfigRenderer extends Renderer { writer.writeText("\n", component, null); writer.endElement("div"); writer.writeComment("********** End of " + component.getClass().getSimpleName() + " component **********"); + + component.getChildren().clear(); }
public void addChildComponents(AbstractConfigurationComponent configurationComponent) { + if ((configurationComponent.getConfigurationDefinition() == null) || ((configurationComponent.getConfiguration() != null) && configurationComponent.getConfiguration() - .getMap().isEmpty())) { + .getMap().isEmpty()) + && !configurationComponent.getConfigurationDefinition().getConfigurationFormat().isRawSupported()) { if (configurationComponent.getNullConfigurationDefinitionMessage() != null) { String styleClass = (configurationComponent.getNullConfigurationStyle() == null) ? "ErrorBlock" : configurationComponent.getNullConfigurationStyle(); @@ -244,20 +252,49 @@ public class ConfigRenderer extends Renderer { if (!configurationComponent.isReadOnly()) addRequiredNotationsKey(configurationComponent);
- if (configurationComponent.getListName() != null) { - if (configurationComponent.getListIndex() == null) { - // No index specified means we should add a new map to the list. - configurationComponent.setListIndex(addNewMap(configurationComponent)); + Boolean shouldShowRawNow = configurationComponent.getShouldShowRaw(); + addStructuredRawToggle(configurationComponent, shouldShowRawNow); + if (shouldShowRawNow) { + configurationComponent.getChildren().add( + new RawConfigUIComponent(configurationComponent.getConfiguration(), configurationComponent + .getConfigurationDefinition(), configurationComponent)); + } else { + if (configurationComponent.getListName() != null) { + if (configurationComponent.getListIndex() == null) { + // No index specified means we should add a new map to the list. + configurationComponent.setListIndex(addNewMap(configurationComponent)); + } + + addListMemberProperty(configurationComponent); + } else { + addConfiguration(configurationComponent); }
- addListMemberProperty(configurationComponent); - } else { - addConfiguration(configurationComponent); + String id = getInitInputsJavaScriptComponentId(configurationComponent); + PropertyRenderingUtility.addInitInputsJavaScript(configurationComponent, id, configurationComponent + .isFullyEditable(), false); } + } + + private void addStructuredRawToggle(AbstractConfigurationComponent configurationComponent, boolean showRaw) { + if (configurationComponent.getConfigurationDefinition().getConfigurationFormat().equals( + ConfigurationFormat.STRUCTURED_AND_RAW)) { + + HtmlPanelGroup toRawLinkPanel = FacesComponentUtility.addBlockPanel(configurationComponent, + configurationComponent, UNGROUPED_PROPERTIES_STYLE_CLASS);
- String id = getInitInputsJavaScriptComponentId(configurationComponent); - PropertyRenderingUtility.addInitInputsJavaScript(configurationComponent, id, configurationComponent - .isFullyEditable(), false); + FacesComponentUtility.addOutputText(toRawLinkPanel, configurationComponent, + "internationalized Message goes here", UNGROUPED_PROPERTIES_STYLE_CLASS); + + HtmlCommandLink commandLink = FacesComponentUtility.addCommandLink(toRawLinkPanel, configurationComponent); + + UIOutput output = new UIOutput(); + output.setValue(showRaw ? "Show Structured" : " Show Raw"); + commandLink.getChildren().add(output); + //output.setParent(commandLink); + FacesComponentUtility.addParameter(commandLink, configurationComponent, "showRaw", Boolean + .toString(!showRaw)); + } }
private void addListMemberProperty(AbstractConfigurationComponent configurationComponent) { diff --git a/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/RawConfigUIComponent.java b/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/RawConfigUIComponent.java new file mode 100644 index 0000000..1b7bf89 --- /dev/null +++ b/modules/core/gui/src/main/java/org/rhq/core/gui/configuration/RawConfigUIComponent.java @@ -0,0 +1,113 @@ +package org.rhq.core.gui.configuration; + +import java.io.IOException; + +import javax.faces.component.UIComponent; +import javax.faces.component.UIComponentBase; +import javax.faces.component.UIPanel; +import javax.faces.component.html.HtmlCommandLink; +import javax.faces.component.html.HtmlInputTextarea; +import javax.faces.component.html.HtmlPanelGrid; +import javax.faces.context.FacesContext; + +import org.rhq.core.domain.configuration.Configuration; +import org.rhq.core.domain.configuration.RawConfiguration; +import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; +import org.rhq.core.gui.util.FacesComponentIdFactory; +import org.rhq.core.gui.util.FacesComponentUtility; + +public class RawConfigUIComponent extends UIComponentBase { + + @Override + public void decode(FacesContext context) { + super.decode(context); + + } + + @Override + public String getFamily() { + return "rhq"; + } + + Configuration configuration; + ConfigurationDefinition configurationDefinition; + FacesComponentIdFactory idFactory; + + @Override + public boolean getRendersChildren() { + return true; + } + + @Override + public void encodeChildren(FacesContext context) throws IOException { + for (UIComponent kid : getChildren()) { + kid.encodeAll(context); + } + } + + @Override + public boolean isTransient() { + return true; + } + + public RawConfigUIComponent(Configuration configuration, ConfigurationDefinition configurationDefinition, + FacesComponentIdFactory componentIdFactory) { + + this.configuration = configuration; + this.configurationDefinition = configurationDefinition; + this.idFactory = componentIdFactory; + + UIPanel rawPanel = FacesComponentUtility.addBlockPanel(this, idFactory, ""); + addToolbarIcons(rawPanel); + + HtmlPanelGrid grid = FacesComponentUtility.addPanelGrid(rawPanel, idFactory, "summary-props-table"); + grid.setParent(this); + grid.setColumns(2); + grid.setColumnClasses("raw-config-table"); + + HtmlPanelGrid panelLeft = FacesComponentUtility.addPanelGrid(grid, idFactory, "summary-props-table"); + panelLeft.setBgcolor("#a4b2b9"); + panelLeft.setColumns(1); + + FacesComponentUtility.addOutputText(panelLeft, idFactory, "Raw Configurations Paths", ""); + + int rawCount = 0; + for (RawConfiguration raw : configuration.getRawConfigurations()) { + UIPanel nextPath = FacesComponentUtility.addBlockPanel(panelLeft, idFactory, ""); + HtmlCommandLink link = FacesComponentUtility.addCommandLink(nextPath, idFactory); + + FacesComponentUtility.addOutputText(link, idFactory, raw.getPath(), ""); + FacesComponentUtility.addParameter(link, idFactory, "path", raw.getPath()); + FacesComponentUtility.addParameter(link, idFactory, "whichRaw", Integer.toString(rawCount++)); + FacesComponentUtility.addParameter(link, idFactory, "showRaw", Boolean.TRUE.toString()); + } + + UIPanel panelRight = FacesComponentUtility.addBlockPanel(grid, idFactory, "summary-props-table"); + + UIPanel editPanel = FacesComponentUtility.addBlockPanel(panelRight, idFactory, "summary-props-table"); + HtmlInputTextarea inputTextarea = new HtmlInputTextarea(); + editPanel.getChildren().add(inputTextarea); + inputTextarea.setParent(editPanel); + inputTextarea.setCols(80); + inputTextarea.setRows(40); + inputTextarea.setValue(configuration.getRawConfigurations().iterator().next().getContentString()); + } + + private void addToolbarIcons(UIPanel panelRight) { + HtmlCommandLink fullScreenCommandLink = FacesComponentUtility.addCommandLink(panelRight, idFactory); + FacesComponentUtility.addGraphicImage(fullScreenCommandLink, idFactory, "/images/save.png", "Save"); + FacesComponentUtility.addOutputText(fullScreenCommandLink, idFactory, "Save", ""); + + HtmlCommandLink saveCommandLink = FacesComponentUtility.addCommandLink(panelRight, idFactory); + FacesComponentUtility.addGraphicImage(saveCommandLink, idFactory, "/images/viewfullscreen.png", "FullScreen"); + FacesComponentUtility.addOutputText(saveCommandLink, idFactory, "Full Screen", ""); + + HtmlCommandLink uploadCommandLink = FacesComponentUtility.addCommandLink(panelRight, idFactory); + FacesComponentUtility.addGraphicImage(uploadCommandLink, idFactory, "/images/upload.png", "Upload"); + FacesComponentUtility.addOutputText(uploadCommandLink, idFactory, "Upload", ""); + + HtmlCommandLink downloadCommandLink = FacesComponentUtility.addCommandLink(panelRight, idFactory); + FacesComponentUtility.addGraphicImage(downloadCommandLink, idFactory, "/images/download.png", "download"); + FacesComponentUtility.addOutputText(downloadCommandLink, idFactory, "Download", ""); + } +} diff --git a/modules/core/gui/src/main/java/org/rhq/core/gui/util/FacesComponentUtility.java b/modules/core/gui/src/main/java/org/rhq/core/gui/util/FacesComponentUtility.java index a3c2257..ad2274b 100644 --- a/modules/core/gui/src/main/java/org/rhq/core/gui/util/FacesComponentUtility.java +++ b/modules/core/gui/src/main/java/org/rhq/core/gui/util/FacesComponentUtility.java @@ -1,25 +1,25 @@ - /* - * RHQ Management Platform - * Copyright (C) 2005-2008 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, version 2, as - * published by the Free Software Foundation, and/or the GNU Lesser - * General Public License, version 2.1, also as published by the Free - * Software Foundation. - * - * 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 and the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * and the GNU Lesser 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. - */ +/* + * RHQ Management Platform + * Copyright (C) 2005-2008 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, version 2, as + * published by the Free Software Foundation, and/or the GNU Lesser + * General Public License, version 2.1, also as published by the Free + * Software Foundation. + * + * 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 and the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * and the GNU Lesser 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.core.gui.util;
import java.util.ArrayList; @@ -32,10 +32,10 @@ import java.util.UUID; import javax.el.ValueExpression; import javax.faces.application.Application; import javax.faces.component.UIComponent; +import javax.faces.component.UIForm; import javax.faces.component.UIInput; import javax.faces.component.UIOutput; import javax.faces.component.UIParameter; -import javax.faces.component.UIForm; import javax.faces.component.UIViewRoot; import javax.faces.component.html.HtmlColumn; import javax.faces.component.html.HtmlCommandButton; @@ -50,16 +50,17 @@ import javax.faces.component.html.HtmlOutputText; import javax.faces.component.html.HtmlPanelGrid; import javax.faces.component.html.HtmlPanelGroup; import javax.faces.context.FacesContext; + import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.richfaces.component.html.HtmlSeparator; import org.richfaces.component.html.HtmlSimpleTogglePanel;
- /** - * A set of utility methods for working with JSF {@link UIComponent}s. - * - * @author Ian Springer - */ +/** +* A set of utility methods for working with JSF {@link UIComponent}s. +* +* @author Ian Springer +*/ public abstract class FacesComponentUtility { public static final String NO_STYLE_CLASS = null;
@@ -77,16 +78,31 @@ public abstract class FacesComponentUtility { }
@NotNull - public static HtmlPanelGroup addBlockPanel(@NotNull - UIComponent parent, FacesComponentIdFactory idFactory, String styleClass) { + public static HtmlPanelGrid createPanelGrid(FacesComponentIdFactory idFactory, String styleClass) { + HtmlPanelGrid panel = createComponent(HtmlPanelGrid.class, idFactory); + panel.setStyleClass(styleClass); + return panel; + } + + @NotNull + public static HtmlPanelGroup addBlockPanel(@NotNull UIComponent parent, FacesComponentIdFactory idFactory, + String styleClass) { HtmlPanelGroup panel = createBlockPanel(idFactory, styleClass); parent.getChildren().add(panel); return panel; }
@NotNull - public static HtmlPanelGroup addInlinePanel(@NotNull - UIComponent parent, FacesComponentIdFactory idFactory, String styleClass) { + public static HtmlPanelGrid addPanelGrid(@NotNull UIComponent parent, FacesComponentIdFactory idFactory, + String styleClass) { + HtmlPanelGrid panel = createPanelGrid(idFactory, styleClass); + parent.getChildren().add(panel); + return panel; + } + + @NotNull + public static HtmlPanelGroup addInlinePanel(@NotNull UIComponent parent, FacesComponentIdFactory idFactory, + String styleClass) { HtmlPanelGroup panel = createComponent(HtmlPanelGroup.class, idFactory); panel.setStyleClass(styleClass); parent.getChildren().add(panel); @@ -94,8 +110,8 @@ public abstract class FacesComponentUtility { }
@NotNull - public static HtmlSimpleTogglePanel addSimpleTogglePanel(@NotNull - UIComponent parent, FacesComponentIdFactory idFactory, String label) { + public static HtmlSimpleTogglePanel addSimpleTogglePanel(@NotNull UIComponent parent, + FacesComponentIdFactory idFactory, String label) { HtmlSimpleTogglePanel panel = createComponent(HtmlSimpleTogglePanel.class, idFactory); panel.setLabel(label);
@@ -106,16 +122,15 @@ public abstract class FacesComponentUtility { }
@NotNull - public static HtmlSeparator addSeparator(@NotNull - UIComponent parent, FacesComponentIdFactory idFactory) { + public static HtmlSeparator addSeparator(@NotNull UIComponent parent, FacesComponentIdFactory idFactory) { HtmlSeparator separator = createComponent(HtmlSeparator.class, idFactory); parent.getChildren().add(separator); return separator; }
@NotNull - public static HtmlOutputText addOutputText(@NotNull - UIComponent parent, FacesComponentIdFactory idFactory, CharSequence value, String styleClass) { + public static HtmlOutputText addOutputText(@NotNull UIComponent parent, FacesComponentIdFactory idFactory, + CharSequence value, String styleClass) { HtmlOutputText text = createComponent(HtmlOutputText.class, idFactory); text.setValue(value); text.setStyleClass(styleClass); @@ -135,8 +150,8 @@ public abstract class FacesComponentUtility { }
@NotNull - public static HtmlColumn addColumn(@NotNull - UIComponent parent, FacesComponentIdFactory idFactory, CharSequence headerText, String headerStyle) { + public static HtmlColumn addColumn(@NotNull UIComponent parent, FacesComponentIdFactory idFactory, + CharSequence headerText, String headerStyle) { HtmlColumn column = createComponent(HtmlColumn.class, idFactory); HtmlOutputText header = new HtmlOutputText(); header.setValue(headerText); @@ -147,8 +162,7 @@ public abstract class FacesComponentUtility { }
@NotNull - public static HtmlOutputText addVerbatimText(@NotNull - UIComponent parent, CharSequence html) { + public static HtmlOutputText addVerbatimText(@NotNull UIComponent parent, CharSequence html) { HtmlOutputText outputText = createComponent(HtmlOutputText.class, null); outputText.setEscape(false); outputText.setValue(html); @@ -163,10 +177,8 @@ public abstract class FacesComponentUtility { }
@NotNull - public static UIOutput addJavaScript(@NotNull - UIComponent parent, FacesComponentIdFactory idFactory, @Nullable - CharSequence src, @Nullable - CharSequence script) { + public static UIOutput addJavaScript(@NotNull UIComponent parent, FacesComponentIdFactory idFactory, + @Nullable CharSequence src, @Nullable CharSequence script) { UIOutput output = createComponent(UIOutput.class, idFactory); output.getAttributes().put("escape", Boolean.FALSE); StringBuilder value = new StringBuilder(); @@ -220,8 +232,8 @@ public abstract class FacesComponentUtility { }
@NotNull - public static HtmlOutputLabel addLabel(@NotNull - UIComponent parent, FacesComponentIdFactory idFactory, UIInput associatedInput, String value, String styleClass) { + public static HtmlOutputLabel addLabel(@NotNull UIComponent parent, FacesComponentIdFactory idFactory, + UIInput associatedInput, String value, String styleClass) { HtmlOutputLabel label = createComponent(HtmlOutputLabel.class, idFactory); label.setFor(associatedInput.getId()); label.setValue(value); @@ -231,8 +243,8 @@ public abstract class FacesComponentUtility { }
@NotNull - public static HtmlGraphicImage addGraphicImage(@NotNull - UIComponent parent, FacesComponentIdFactory idFactory, String url, String alt) { + public static HtmlGraphicImage addGraphicImage(@NotNull UIComponent parent, FacesComponentIdFactory idFactory, + String url, String alt) { HtmlGraphicImage image = FacesComponentUtility.createComponent(HtmlGraphicImage.class, idFactory); image.setUrl(url); image.setAlt(alt); @@ -242,8 +254,8 @@ public abstract class FacesComponentUtility { }
@NotNull - public static HtmlOutputLink addOutputLink(@NotNull - UIComponent parent, FacesComponentIdFactory idFactory, String value) { + public static HtmlOutputLink addOutputLink(@NotNull UIComponent parent, FacesComponentIdFactory idFactory, + String value) { HtmlOutputLink link = FacesComponentUtility.createComponent(HtmlOutputLink.class, idFactory); link.setValue(value); parent.getChildren().add(link); @@ -251,8 +263,8 @@ public abstract class FacesComponentUtility { }
@NotNull - public static UIParameter addParameter(@NotNull - UIComponent parent, FacesComponentIdFactory idFactory, String name, String value) { + public static UIParameter addParameter(@NotNull UIComponent parent, FacesComponentIdFactory idFactory, String name, + String value) { UIParameter parameter = createComponent(UIParameter.class, idFactory); parameter.setName(name); parameter.setValue(value); @@ -261,8 +273,7 @@ public abstract class FacesComponentUtility { }
@NotNull - public static HtmlForm addForm(@NotNull - UIComponent parent, FacesComponentIdFactory idFactory) { + public static HtmlForm addForm(@NotNull UIComponent parent, FacesComponentIdFactory idFactory) { HtmlForm form = createComponent(HtmlForm.class, idFactory); form.setPrependId(false); parent.getChildren().add(form); @@ -270,8 +281,8 @@ public abstract class FacesComponentUtility { }
@NotNull - public static HtmlCommandButton addCommandButton(@NotNull - UIComponent parent, FacesComponentIdFactory idFactory, String value, String styleClass) { + public static HtmlCommandButton addCommandButton(@NotNull UIComponent parent, FacesComponentIdFactory idFactory, + String value, String styleClass) { HtmlCommandButton button = createComponent(HtmlCommandButton.class, idFactory); button.setValue(value); button.setStyleClass(styleClass); @@ -280,16 +291,15 @@ public abstract class FacesComponentUtility { }
@NotNull - public static HtmlCommandLink addCommandLink(@NotNull - UIComponent parent, FacesComponentIdFactory idFactory) { + public static HtmlCommandLink addCommandLink(@NotNull UIComponent parent, FacesComponentIdFactory idFactory) { HtmlCommandLink link = FacesComponentUtility.createComponent(HtmlCommandLink.class, idFactory); parent.getChildren().add(link); return link; }
@NotNull - public static HtmlMessage addMessage(@NotNull - UIComponent parent, FacesComponentIdFactory idFactory, String associatedComponentId, String styleClass) { + public static HtmlMessage addMessage(@NotNull UIComponent parent, FacesComponentIdFactory idFactory, + String associatedComponentId, String styleClass) { HtmlMessage message = FacesComponentUtility.createComponent(HtmlMessage.class, idFactory); message.setFor(associatedComponentId); message.setShowDetail(true); @@ -302,8 +312,8 @@ public abstract class FacesComponentUtility { }
@NotNull - public static HtmlPanelGrid addPanelGrid(@NotNull - UIComponent parent, FacesComponentIdFactory idFactory, int columns, String styleClass) { + public static HtmlPanelGrid addPanelGrid(@NotNull UIComponent parent, FacesComponentIdFactory idFactory, + int columns, String styleClass) { HtmlPanelGrid panelGrid = FacesComponentUtility.createComponent(HtmlPanelGrid.class, idFactory); panelGrid.setColumns(columns); panelGrid.setStyleClass(styleClass); @@ -312,8 +322,8 @@ public abstract class FacesComponentUtility { }
@NotNull - public static HtmlDataTable addDataTable(@NotNull - UIComponent parent, FacesComponentIdFactory idFactory, String styleClass) { + public static HtmlDataTable addDataTable(@NotNull UIComponent parent, FacesComponentIdFactory idFactory, + String styleClass) { HtmlDataTable dataTable = FacesComponentUtility.createComponent(HtmlDataTable.class, idFactory); dataTable.setStyleClass(styleClass); parent.getChildren().add(dataTable); @@ -321,17 +331,13 @@ public abstract class FacesComponentUtility { }
@Nullable - public static String getExpressionAttribute(@NotNull - UIComponent component, @NotNull - String attribName) { + public static String getExpressionAttribute(@NotNull UIComponent component, @NotNull String attribName) { return getExpressionAttribute(component, attribName, String.class); }
@Nullable - public static <T> T getExpressionAttribute(@NotNull - UIComponent component, @NotNull - String attribName, @NotNull - Class<T> expectedType) { + public static <T> T getExpressionAttribute(@NotNull UIComponent component, @NotNull String attribName, + @NotNull Class<T> expectedType) { ValueExpression valueExpression = component.getValueExpression(attribName); T attribValue = (valueExpression != null) ? FacesExpressionUtility.getValue(valueExpression, expectedType) : null; @@ -339,8 +345,7 @@ public abstract class FacesComponentUtility { }
@NotNull - public static Map<String, String> getParameters(@NotNull - UIComponent component) { + public static Map<String, String> getParameters(@NotNull UIComponent component) { // Use a LinkedHashMap, so the order of the parameters is maintained. Map<String, String> params = new LinkedHashMap<String, String>(); List<UIComponent> children = component.getChildren(); @@ -375,8 +380,8 @@ public abstract class FacesComponentUtility { * @return a {@link UIComponent} of the specified type */ @SuppressWarnings("unchecked") - public static <T extends UIComponent> T createComponent(Class<T> componentClass, @Nullable - FacesComponentIdFactory idFactory) { + public static <T extends UIComponent> T createComponent(Class<T> componentClass, + @Nullable FacesComponentIdFactory idFactory) { Application application = FacesContext.getCurrentInstance().getApplication(); String componentType = getComponentType(componentClass); T component = (T) application.createComponent(componentType); @@ -500,25 +505,20 @@ public abstract class FacesComponentUtility { * @throws IllegalArgumentException if more than one UIForm is found in the component's ancestry */ @Nullable - public static UIForm getEnclosingForm(UIComponent component) - throws IllegalArgumentException - { - UIForm ret = null; - while (component != null) - { - if (component instanceof UIForm) - { - if (ret != null) - { - // Cannot have a doubly-nested form! - throw new IllegalArgumentException(); - } - ret = (UIForm) component; - } - component = component.getParent(); - } - return ret; - } + public static UIForm getEnclosingForm(UIComponent component) throws IllegalArgumentException { + UIForm ret = null; + while (component != null) { + if (component instanceof UIForm) { + if (ret != null) { + // Cannot have a doubly-nested form! + throw new IllegalArgumentException(); + } + ret = (UIForm) component; + } + component = component.getParent(); + } + return ret; + }
private static <T extends UIComponent> String getComponentType(Class<T> componentClass) { String componentType; @@ -531,9 +531,8 @@ public abstract class FacesComponentUtility { return componentType; }
- private static class DefaultFacesComponentIdFactory implements FacesComponentIdFactory { - public String createUniqueId() - { + private static class DefaultFacesComponentIdFactory implements FacesComponentIdFactory { + public String createUniqueId() { // NOTE: Our id's *must* begin with UIViewRoot.UNIQUE_ID_PREFIX ("j_id") to prevent HtmlOutputText // components from being rendered as SPAN elements // (see com.sun.faces.renderkit.html_basic.TextRenderer#getEndTextToRender()). diff --git a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/ConfigRendererTest.java b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/ConfigRendererTest.java index 63c1d52..9c57ad4 100644 --- a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/ConfigRendererTest.java +++ b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/ConfigRendererTest.java @@ -5,10 +5,8 @@ import java.io.StringWriter; import java.util.HashMap;
import javax.faces.FactoryFinder; -import javax.faces.context.ExternalContext; import javax.faces.context.FacesContext; import javax.faces.lifecycle.Lifecycle; -import javax.faces.render.RenderKitFactory;
import com.sun.faces.context.FacesContextImpl;
@@ -18,19 +16,21 @@ import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test;
import org.rhq.core.domain.configuration.Configuration; +import org.rhq.core.domain.configuration.Property; import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; +import org.rhq.core.domain.configuration.definition.ConfigurationFormat;
public class ConfigRendererTest {
- RenderKitFactory rkf; ConfigUIComponent configUIComponent; ConfigRenderer configRenderer; FacesContext facesContext; - ExternalContext externalContext; + MockExternalContext externalContext; AjaxContext ajaxContext; MockResponseWriter mockResponseWriter; Lifecycle lifecycle; ConfigurationDefinition configurationDefinition; + private Configuration configuration;
@BeforeMethod protected void setUp() throws Exception { @@ -55,10 +55,12 @@ public class ConfigRendererTest { ajaxContext = AjaxContext.getCurrentInstance(facesContext);
configUIComponent.setId("ID"); - - configUIComponent.setValueExpression("configuration", new MockValueExpression(new Configuration())); + configuration = new Configuration(); + configUIComponent.setValueExpression("configuration", new MockValueExpression(configuration)); configUIComponent.setValueExpression("configurationDefinition", new MockValueExpression(buildConfigDefinition())); + configUIComponent.setRendererType(ConfigRenderer.class.getName()); + }
private ConfigurationDefinition buildConfigDefinition() { @@ -75,8 +77,29 @@ public class ConfigRendererTest {
@Test public void testUIComponentEncode() throws IOException { - configUIComponent.setRendererType(ConfigRenderer.class.getName()); + Property value; + value = new Property(); + value.setName("test1"); + value.setConfiguration(configuration); + value.setId(3); + configuration.getMap().put(value.getName(), value); + + Assert.assertNotNull(configUIComponent.getConfigurationDefinition()); + configUIComponent.getConfigurationDefinition().setConfigurationFormat(ConfigurationFormat.STRUCTURED_AND_RAW); + + Assert.assertNotNull(configUIComponent.getConfigurationDefinition().getConfigurationFormat()); + Assert.assertTrue(configUIComponent.getConfigurationDefinition().getConfigurationFormat().isRawSupported()); + Assert.assertTrue(configUIComponent.getConfigurationDefinition().getConfigurationFormat() + .isStructuredSupported()); + + externalContext.requestParameterMap.put("showRaw", "true"); + configUIComponent.encodeAll(facesContext); + + String s2 = mockResponseWriter.stringWriter.getBuffer().toString(); + + System.out.println(s2); + }
//@Test diff --git a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockApplication.java b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockApplication.java index 335eb88..d89eb86 100644 --- a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockApplication.java +++ b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockApplication.java @@ -1,8 +1,10 @@ package org.rhq.core.gui.configuration;
import java.util.Collection; +import java.util.HashMap; import java.util.Iterator; import java.util.Locale; +import java.util.Map;
import javax.faces.FacesException; import javax.faces.application.Application; @@ -10,6 +12,11 @@ import javax.faces.application.NavigationHandler; import javax.faces.application.StateManager; import javax.faces.application.ViewHandler; import javax.faces.component.UIComponent; +import javax.faces.component.UIParameter; +import javax.faces.component.html.HtmlCommandLink; +import javax.faces.component.html.HtmlOutputFormat; +import javax.faces.component.html.HtmlOutputText; +import javax.faces.component.html.HtmlPanelGroup; import javax.faces.context.FacesContext; import javax.faces.convert.Converter; import javax.faces.el.MethodBinding; @@ -22,6 +29,8 @@ import javax.faces.validator.Validator;
public class MockApplication extends Application {
+ Map<String, Class> componentTypeMap; + @Override public void addComponent(String componentType, String componentClass) { throw new RuntimeException("Function not implemented"); @@ -29,13 +38,13 @@ public class MockApplication extends Application { }
@Override - public void addConverter(String converterId, String converterClass) { + public void addConverter(Class targetClass, String converterClass) { throw new RuntimeException("Function not implemented");
}
@Override - public void addConverter(Class targetClass, String converterClass) { + public void addConverter(String converterId, String converterClass) { throw new RuntimeException("Function not implemented");
} @@ -48,7 +57,12 @@ public class MockApplication extends Application {
@Override public UIComponent createComponent(String componentType) throws FacesException { - throw new RuntimeException("Function not implemented"); + try { + return (UIComponent) getComponentTypeMap().get(componentType).newInstance(); + } catch (Exception e) { + e.printStackTrace(); + throw new FacesException("can't create component " + componentType); + }
}
@@ -60,13 +74,13 @@ public class MockApplication extends Application { }
@Override - public Converter createConverter(String converterId) { + public Converter createConverter(Class targetClass) { throw new RuntimeException("Function not implemented");
}
@Override - public Converter createConverter(Class targetClass) { + public Converter createConverter(String converterId) { throw new RuntimeException("Function not implemented");
} @@ -95,6 +109,19 @@ public class MockApplication extends Application {
}
+ Map<String, Class> getComponentTypeMap() { + if (null == componentTypeMap) { + + componentTypeMap = new HashMap<String, Class>(); + componentTypeMap.put("javax.faces.HtmlOutputText", HtmlOutputText.class); + componentTypeMap.put("javax.faces.HtmlPanelGroup", HtmlPanelGroup.class); + componentTypeMap.put("javax.faces.Output", HtmlOutputFormat.class); + componentTypeMap.put("javax.faces.HtmlCommandLink", HtmlCommandLink.class); + componentTypeMap.put("javax.faces.Parameter", UIParameter.class); + } + return componentTypeMap; + } + @Override public Iterator<String> getComponentTypes() { throw new RuntimeException("Function not implemented"); diff --git a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockExternalContext.java b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockExternalContext.java index 8fb6172..cd8500c 100644 --- a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockExternalContext.java +++ b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockExternalContext.java @@ -133,7 +133,7 @@ public class MockExternalContext extends ExternalContext { return requestMap; }
- Map<String, String> requestParameterMap = new HashMap<String, String>(); + public Map<String, String> requestParameterMap = new HashMap<String, String>();
@Override public Map<String, String> getRequestParameterMap() { diff --git a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockFacesContext.java b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockFacesContext.java index 73097d6..77e410d 100644 --- a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockFacesContext.java +++ b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockFacesContext.java @@ -12,6 +12,8 @@ import javax.faces.context.ResponseStream; import javax.faces.context.ResponseWriter; import javax.faces.render.RenderKit;
+import com.sun.faces.renderkit.RenderKitImpl; + public class MockFacesContext extends FacesContext {
private ExternalContext externalContext; @@ -26,13 +28,16 @@ public class MockFacesContext extends FacesContext { @Override public void addMessage(String clientId, FacesMessage message) { throw new RuntimeException("Function not implemented"); - }
+ MockApplication mockApp; + @Override public Application getApplication() { - throw new RuntimeException("Function not implemented"); - + if (null == mockApp) { + mockApp = new MockApplication(); + } + return mockApp; }
@Override @@ -65,11 +70,15 @@ public class MockFacesContext extends FacesContext {
}
- RenderKit mockRenderKit = new MockRenderKit(); + RenderKit renderKit = new MockRenderKit();
@Override public RenderKit getRenderKit() { - return mockRenderKit; + if (null == renderKit) { + renderKit = new RenderKitImpl(); + renderKit.addRenderer("rhq", ConfigRenderer.class.getName(), new ConfigRenderer()); + } + return renderKit; }
@Override diff --git a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockRenderKit.java b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockRenderKit.java index 56df905..6f490f2 100644 --- a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockRenderKit.java +++ b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockRenderKit.java @@ -2,6 +2,7 @@ package org.rhq.core.gui.configuration;
import java.io.OutputStream; import java.io.Writer; +import java.util.HashMap;
import javax.faces.context.ResponseStream; import javax.faces.context.ResponseWriter; @@ -9,6 +10,10 @@ import javax.faces.render.RenderKit; import javax.faces.render.Renderer; import javax.faces.render.ResponseStateManager;
+import com.sun.faces.renderkit.html_basic.GroupRenderer; +import com.sun.faces.renderkit.html_basic.OutputMessageRenderer; +import com.sun.faces.renderkit.html_basic.TextRenderer; + public class MockRenderKit extends RenderKit {
@Override @@ -29,12 +34,29 @@ public class MockRenderKit extends RenderKit {
}
+ HashMap<String, Class> rendererMap; + @Override public Renderer getRenderer(String family, String rendererType) { try { - return (Renderer) Class.forName(rendererType).newInstance(); + if (null == rendererMap) { + rendererMap = new HashMap<String, Class>(); + rendererMap.put("javax.faces.Text", TextRenderer.class); + rendererMap.put("javax.faces.Format", OutputMessageRenderer.class); + rendererMap.put("javax.faces.Group", GroupRenderer.class); + rendererMap.put(ConfigRenderer.class.getName(), ConfigRenderer.class); + //HtmlCommandLink has no renderer. It renders itself + } + Class c = rendererMap.get(rendererType); + if (c == null) { + System.out.println("MockRenderKit request for unsupported type " + rendererType); + return null; + } else { + + return (Renderer) c.newInstance(); + } } catch (Exception e) { - return null; + throw new RuntimeException(e); }
} diff --git a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockValueExpression.java b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockValueExpression.java index 45d2993..cb3dc63 100644 --- a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockValueExpression.java +++ b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockValueExpression.java @@ -32,8 +32,7 @@ public class MockValueExpression extends ValueExpression {
@Override public String getExpressionString() { - throw new RuntimeException("Function not implemented"); - + return "#{" + value.getClass().getSimpleName() + "}"; }
@Override diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml index 0d4899f..12156e4 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml @@ -24,18 +24,19 @@ THIS TEXT WILL BE REMOVED.
<ui:define name="content">
+ + <style type="text/css"> + td.raw-config-table { + vertical-align: top; + valign: top; + } +</style> + + <h:panelGroup layout="block" styleClass="InfoBlock" rendered="#{ExistingResourceConfigurationUIBean.updateInProgress}"> <b>${msg['note']}</b> ${msg['resource.config.Current.updateInProgress']} </h:panelGroup>
- <h:outputText value="#{messages.youareviewingstructured}" /> - <h:panelGroup rendered="#{ExistingResourceConfigurationUIBean.rawSupported}" > - <h:outputText value=" #{messages.switch2}" /> - <h:outputLink value="view-raw.xhtml"> - <f:param name="id" value="#{ResourceUIBean.id}" /> - <h:outputText value=" #{messages.raw}" /> - </h:outputLink> - </h:panelGroup>
<h:outputText value=" #{messages.nopermissionedit}" rendered="#{!ResourceUIBean.permissions.configure}"/>
@@ -61,6 +62,7 @@ THIS TEXT WILL BE REMOVED. nullConfigurationDefinitionMessage="#{ExistingResourceConfigurationUIBean.nullConfigurationDefinitionMessage}" nullConfigurationMessage="#{ExistingResourceConfigurationUIBean.nullConfigurationMessage}" prevalidate="true"/> + <input type="hidden" name="id" value="#{ResourceUIBean.id}"/>
</h:form>
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/webservices/WebservicesManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/webservices/WebservicesManagerBean.java index 8916b19..ad4ab27 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/webservices/WebservicesManagerBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/webservices/WebservicesManagerBean.java @@ -286,7 +286,7 @@ public class WebservicesManagerBean implements WebservicesRemote { return repoManager.findPackageVersionsInRepoByCriteria(subject, criteria); }
- @Override + //@Override public int synchronizeRepos(Subject subject, Integer[] repoIds) { return repoManager.synchronizeRepos(subject, repoIds); } @@ -371,8 +371,8 @@ public class WebservicesManagerBean implements WebservicesRemote { }
public ResourceConfigurationUpdate updateStructuredOrRawConfiguration(Subject subject, int resourceId, - Configuration newConfiguration, boolean fromStructured) - throws ResourceNotFoundException, ConfigurationUpdateStillInProgressException { + Configuration newConfiguration, boolean fromStructured) throws ResourceNotFoundException, + ConfigurationUpdateStillInProgressException { return configurationManager.updateStructuredOrRawConfiguration(subject, resourceId, newConfiguration, fromStructured); } diff --git a/modules/enterprise/server/plugins/rhnhosted/src/main/java/org/rhq/enterprise/server/plugins/rhnhosted/xmlrpc/ApacheXmlRpcExecutor.java b/modules/enterprise/server/plugins/rhnhosted/src/main/java/org/rhq/enterprise/server/plugins/rhnhosted/xmlrpc/ApacheXmlRpcExecutor.java index f3c75e2..004608a 100644 --- a/modules/enterprise/server/plugins/rhnhosted/src/main/java/org/rhq/enterprise/server/plugins/rhnhosted/xmlrpc/ApacheXmlRpcExecutor.java +++ b/modules/enterprise/server/plugins/rhnhosted/src/main/java/org/rhq/enterprise/server/plugins/rhnhosted/xmlrpc/ApacheXmlRpcExecutor.java @@ -32,12 +32,10 @@ public class ApacheXmlRpcExecutor implements XmlRpcExecutor { this.client = clientIn; }
- @Override public Object execute(String methodName, Object[] params) throws XmlRpcException { return client.execute(methodName, params); }
- @Override public Object execute(String pMethodName, List pParams) throws XmlRpcException { return client.execute(pMethodName, pParams); } diff --git a/modules/enterprise/server/plugins/rhnhosted/src/test/java/org/rhq/enterprise/server/plugins/rhnhosted/xmlrpc/MockRhnXmlRpcExecutor.java b/modules/enterprise/server/plugins/rhnhosted/src/test/java/org/rhq/enterprise/server/plugins/rhnhosted/xmlrpc/MockRhnXmlRpcExecutor.java index bcdfe41..9a033d5 100644 --- a/modules/enterprise/server/plugins/rhnhosted/src/test/java/org/rhq/enterprise/server/plugins/rhnhosted/xmlrpc/MockRhnXmlRpcExecutor.java +++ b/modules/enterprise/server/plugins/rhnhosted/src/test/java/org/rhq/enterprise/server/plugins/rhnhosted/xmlrpc/MockRhnXmlRpcExecutor.java @@ -70,7 +70,7 @@ public class MockRhnXmlRpcExecutor implements XmlRpcExecutor { /* (non-Javadoc) * @see org.rhq.enterprise.server.plugins.rhnhosted.xmlrpc.XmlRpcExecutor#execute(java.lang.String, java.lang.Object[]) */ - @Override + //@Override public Object execute(String methodName, Object[] params) throws XmlRpcException { //for (Object object : params) { // System.out.println("parm: " + object); @@ -242,7 +242,7 @@ public class MockRhnXmlRpcExecutor implements XmlRpcExecutor {
}
- @Override + //@Override public Object execute(String pMethodName, List pParams) throws XmlRpcException { return execute(pMethodName, pParams.toArray()); }
commit dadf978f748092ae95ec8cf36d31ddd15241ef17 Author: Heiko W. Rupp pilhuhn@fedorapeople.org Date: Fri Dec 11 21:10:05 2009 +0100
Implement plugin validation for alerts.
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertPluginValidator.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertPluginValidator.java index 9117447..7391723 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertPluginValidator.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertPluginValidator.java @@ -19,12 +19,72 @@
package org.rhq.enterprise.server.plugin.pc.alert;
+import java.net.URL; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + import org.rhq.enterprise.server.plugin.pc.ServerPluginEnvironment; import org.rhq.enterprise.server.plugin.pc.ServerPluginValidator; +import org.rhq.enterprise.server.xmlschema.generated.serverplugin.alert.AlertPluginDescriptorType; +import org.rhq.enterprise.server.xmlschema.generated.serverplugin.alert.CustomUi;
public class AlertPluginValidator implements ServerPluginValidator { + public boolean validate(ServerPluginEnvironment env) { - // TODO test validate env.getPluginDescriptor() + + Log log = LogFactory.getLog(AlertPluginValidator.class); + + AlertPluginDescriptorType type = (AlertPluginDescriptorType) env.getPluginDescriptor(); + + String className = type.getPluginClass(); + if (!className.contains(".")) { + className = type.getPackage() + "." + className; + } + try { + Class.forName(className,false,env.getPluginClassLoader()); + } + catch (Exception e) { + log.error("Can't find pluginClass " + className + " for plugin " + env.getPluginKey().getPluginName() ); + return false; + } + + // The short name is basically the key into the plugin + String shortName = type.getShortName(); + + // + // Ok, we have a valid plugin class, so we can look for other things + // and store the info + // + + String uiSnippetPath; + URL uiSnippetUrl = null; + CustomUi customUI = type.getCustomUi(); + if (customUI!=null) { + uiSnippetPath = customUI.getUiSnippetName(); + + try { + uiSnippetUrl = env.getPluginClassLoader().getResource(uiSnippetPath); + log.info("UI snipped for " + shortName + " is at " + uiSnippetUrl); + } + catch (Exception e) { + log.error("No valid ui snippet provided, but <custom-ui> given for sender plugin " + shortName + "Error is "+ e.getMessage()); + return false; + } + + // Get the backing bean class + className = customUI.getBackingBeanName(); + if (!className.contains(".")) { + className = type.getPackage() + "." + className; + } + try { + Class.forName(className,true,env.getPluginClassLoader()); // TODO how make this available to Seam and the Web-CL ? + } + catch (Throwable t ) { + log.error("Backing bean " + className + " not found for plugin " + shortName); + return false; + } + } return true; } } diff --git a/modules/enterprise/server/plugins/validate-all-serverplugins/pom.xml b/modules/enterprise/server/plugins/validate-all-serverplugins/pom.xml index 6576a1a..80b4634 100644 --- a/modules/enterprise/server/plugins/validate-all-serverplugins/pom.xml +++ b/modules/enterprise/server/plugins/validate-all-serverplugins/pom.xml @@ -26,7 +26,7 @@
<build> <plugins> - <plugin> + <plugin> <artifactId>maven-antrun-plugin</artifactId> <executions> <execution> @@ -43,6 +43,12 @@ <pathelement location="../rhnhosted/target/rhq-serverplugin-rhnhosted-${project.version}.jar" /> <pathelement location="../url/target/rhq-serverplugin-url-${project.version}.jar" /> <pathelement location="../yum/target/rhq-serverplugin-yum-${project.version}.jar" /> + <pathelement location="../alert-email/target/alert-email-${project.version}.jar" /> + <pathelement location="../alert-irc/target/alert-irc-${project.version}.jar" /> + <pathelement location="../alert-microblog/target/alert-microblog-${project.version}.jar" /> + <pathelement location="../alert-mobicents/target/alert-mobicents-${project.version}.jar" /> + <pathelement location="../alert-roles/target/alert-roles-${project.version}.jar" /> + <pathelement location="../alert-snmp/target/alert-snmp-${project.version}.jar" /> </classpath> <sysproperty key="org.apache.commons.logging.Log" value="org.apache.commons.logging.impl.SimpleLog" /> <sysproperty key="rhq.test.serverplugins" value="${rhq.test.serverplugins}" />
commit 92858cb608fdb1e0be43df73dbf3095cea3f66b8 Merge: 112dbac... 237b442... Author: Heiko W. Rupp pilhuhn@fedorapeople.org Date: Fri Dec 11 19:39:30 2009 +0100
Merge branch 'master' into alertPlugin
diff --cc modules/core/dbutils/src/main/scripts/dbsetup/alert-schema.xml index c9f03a8,e71ea82..a13e2c6 --- a/modules/core/dbutils/src/main/scripts/dbsetup/alert-schema.xml +++ b/modules/core/dbutils/src/main/scripts/dbsetup/alert-schema.xml @@@ -130,16 -130,7 +130,16 @@@ <column name="SNMP_PORT" type="INTEGER"/> <column name="SNMP_OID" size="250" type="VARCHAR2"/> <column name="ALERT_CONFIG_ID" required="false" type="INTEGER" references="RHQ_CONFIG(ID)"/> - <column name="ALERT_SENDER_NAME" required="false" type="VARCHAR2" /> <!-- TODO make required = true --> + <column name="ALERT_SENDER_NAME" required="false" size="100" type="VARCHAR2" /> <!-- TODO make required = true --> </table>
+ <table name="RHQ_ALERT_NOTIF_TEMPL" tablespace="@@@LARGE_TABLESPACE_FOR_DATA@@@" + storage-options="freelists 5" cache="true" logging="false"> + <column name="ID" default="sequence-only" initial="10001" + primarykey="true" required="true" type="INTEGER"/> + <column name="NAME" required="true" size="40" type="VARCHAR2"/> + <column name="DESCRIPTION" required="false" size="250" type="VARCHAR2"/> + + </table> + </dbsetup>
commit 237b4421775f5a72388f8c8d9a7c0dcc631be149 Author: Heiko W. Rupp pilhuhn@fedorapeople.org Date: Fri Dec 11 17:57:44 2009 +0100
Replace hardcoded version dependencies, as the release plugin screws them up
diff --git a/modules/enterprise/server/plugins/alert-email/pom.xml b/modules/enterprise/server/plugins/alert-email/pom.xml index 85dbd6d..d2455b4 100644 --- a/modules/enterprise/server/plugins/alert-email/pom.xml +++ b/modules/enterprise/server/plugins/alert-email/pom.xml @@ -35,7 +35,7 @@ <dependency> <groupId>org.rhq</groupId> <artifactId>rhq-enterprise-server</artifactId> - <version>1.4.0-SNAPSHOT</version> + <version>${project.version}</version> <scope>provided</scope> <!-- by JBossAS --> </dependency>
diff --git a/modules/enterprise/server/plugins/alert-irc/pom.xml b/modules/enterprise/server/plugins/alert-irc/pom.xml index 76b3b72..aba01fc 100644 --- a/modules/enterprise/server/plugins/alert-irc/pom.xml +++ b/modules/enterprise/server/plugins/alert-irc/pom.xml @@ -30,7 +30,7 @@ <dependency> <groupId>org.rhq</groupId> <artifactId>rhq-enterprise-server</artifactId> - <version>1.4.0-SNAPSHOT</version> + <version>${project.version}</version> <scope>provided</scope> <!-- by JBossAS --> </dependency>
diff --git a/modules/enterprise/server/plugins/alert-microblog/pom.xml b/modules/enterprise/server/plugins/alert-microblog/pom.xml index f35ae52..7af42ac 100644 --- a/modules/enterprise/server/plugins/alert-microblog/pom.xml +++ b/modules/enterprise/server/plugins/alert-microblog/pom.xml @@ -30,7 +30,7 @@ <dependency> <groupId>org.rhq</groupId> <artifactId>rhq-enterprise-server</artifactId> - <version>1.4.0-SNAPSHOT</version> + <version>${project.version}</version> <scope>provided</scope> <!-- by JBossAS --> </dependency>
diff --git a/modules/enterprise/server/plugins/alert-mobicents/pom.xml b/modules/enterprise/server/plugins/alert-mobicents/pom.xml index d231484..c169069 100644 --- a/modules/enterprise/server/plugins/alert-mobicents/pom.xml +++ b/modules/enterprise/server/plugins/alert-mobicents/pom.xml @@ -29,7 +29,7 @@ <dependency> <groupId>org.rhq</groupId> <artifactId>rhq-enterprise-server</artifactId> - <version>1.4.0-SNAPSHOT</version> + <version>${project.version}</version> <scope>provided</scope> <!-- by JBossAS --> </dependency>
diff --git a/modules/enterprise/server/plugins/alert-roles/pom.xml b/modules/enterprise/server/plugins/alert-roles/pom.xml index dc4e8b4..5747fe2 100644 --- a/modules/enterprise/server/plugins/alert-roles/pom.xml +++ b/modules/enterprise/server/plugins/alert-roles/pom.xml @@ -36,7 +36,7 @@ <dependency> <groupId>org.rhq</groupId> <artifactId>rhq-enterprise-server</artifactId> - <version>1.4.0-SNAPSHOT</version> + <version>${project.version}</version> <scope>provided</scope> <!-- by JBossAS --> </dependency>
@@ -50,7 +50,7 @@ <artifactId>xml-apis</artifactId> </exclusion> </exclusions> - </dependency> + </dependency>
<!-- TODO: This is a fix for the Javac bug requiring annotations to be available when compiling dependent classes. It is fixed in JDK 6 --> diff --git a/modules/enterprise/server/plugins/alert-snmp/pom.xml b/modules/enterprise/server/plugins/alert-snmp/pom.xml index 62ec039..e329982 100644 --- a/modules/enterprise/server/plugins/alert-snmp/pom.xml +++ b/modules/enterprise/server/plugins/alert-snmp/pom.xml @@ -29,7 +29,7 @@ <dependency> <groupId>org.rhq</groupId> <artifactId>rhq-enterprise-server</artifactId> - <version>1.4.0-SNAPSHOT</version> + <version>${project.version}</version> <scope>provided</scope> <!-- by JBossAS --> </dependency>
diff --git a/modules/enterprise/server/plugins/perspectives/core/perspective/pom.xml b/modules/enterprise/server/plugins/perspectives/core/perspective/pom.xml index ca5eda3..298c092 100644 --- a/modules/enterprise/server/plugins/perspectives/core/perspective/pom.xml +++ b/modules/enterprise/server/plugins/perspectives/core/perspective/pom.xml @@ -21,7 +21,9 @@ <description>A Perspective defining Core UI Elements</description>
<properties> - <rhq.version>1.4.0-SNAPSHOT</rhq.version> +<!-- + <rhq.version>${project.version}</rhq.version> +--> </properties>
<dependencies> @@ -30,7 +32,7 @@ <dependency> <groupId>org.rhq</groupId> <artifactId>rhq-enterprise-server</artifactId> - <version>${rhq.version}</version> + <version>${project.version}</version> <scope>provided</scope> <!-- provided by the server/plugin-container --> </dependency>
@@ -58,9 +60,9 @@ -->
</dependencies> - + <profiles> - + <profile> <id>dev</id>
@@ -115,7 +117,7 @@ </plugins> </build> </profile> - + </profiles>
</project> diff --git a/modules/helpers/pluginGen/pom.xml b/modules/helpers/pluginGen/pom.xml index 3197e9e..5bc551f 100644 --- a/modules/helpers/pluginGen/pom.xml +++ b/modules/helpers/pluginGen/pom.xml @@ -88,7 +88,7 @@ <dependency> <groupId>org.rhq.helpers</groupId> <artifactId>rhq-pluginAnnotations</artifactId> - <version>1.4.0-SNAPSHOT</version> + <version>${project.version}</version> </dependency> </dependencies> </project>
commit d10220faf2c617cd75b242a4077cc47422ab9a72 Author: John Sanda jsanda@redhat.com Date: Fri Dec 11 11:14:36 2009 -0500
Renaming script to something more logical
diff --git a/modules/enterprise/remoting/scripts/src/main/script/configuration/config_util.js b/modules/enterprise/remoting/scripts/src/main/script/configuration/config_util.js new file mode 100644 index 0000000..54c39a9 --- /dev/null +++ b/modules/enterprise/remoting/scripts/src/main/script/configuration/config_util.js @@ -0,0 +1,287 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2008 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, version 2, as + * published by the Free Software Foundation, and/or the GNU Lesser + * General Public License, version 2.1, also as published by the Free + * Software Foundation. + * + * 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 and the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * and the GNU Lesser 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. + */ + +var waitInterval = 100; +var structured = true; +var raw = false; + +loadResourceTypes(); + +function loadResourceTypes() { + var resourceTypes = context.getAttribute('resourceTypes'); + if (resourceTypes != null && !resourceTypes.isEmpty()) { + return; + } + + var criteria = ResourceTypeCriteria(); + criteria.fetchResourceConfigurationDefinition(true); + + resourceTypes = ResourceTypeManager.findResourceTypesByCriteria(criteria); + context.setAttribute('resourceTypes', resourceTypes, javax.script.ScriptContext.ENGINE_SCOPE); +} + +function ConfigUtil(resourceName) { + var util = this; + + this.resource = findServer(resourceName); + + this.getLatestConfiguration = function () { + var latestUpdate = ConfigurationManager.getLatestResourceConfigurationUpdate(this.resource.id); + + Assert.assertNotNull( + latestUpdate, + "Failed to load the latest resource configuration update for " + this.resource.name + ); + Assert.assertNotNull( + latestUpdate.configuration, + "No configuration is attached to the latest config update object." + ); + + return latestUpdate.configuration; + } + + this.printLatestConfiguration = function() { + var configuration = this.getLatestConfiguration(); + printConfiguration(configuration); + } + + function printConfiguration(configuration) { + pretty.print(configuration); + + if (util.isRawSupported() || util.isStructuredAndRawSupported()) { + println("\nRaw configuration files:"); + var rawConfigs = java.util.ArrayList(configuration.rawConfigurations); + for (i = 0; i < rawConfigs.size(); i++) { + var rawConfig = rawConfigs.get(i); + println("\n[" + rawConfig.path + "]"); + println(java.lang.String(rawConfig.contents) + "\n\n---------------------"); + } + } + } + + this.translateToRaw = function(update) { + doTranslation(update, true); + } + + this.translateToStructured = function(update) { + doTranslation(update, false); + } + + function doTranslation(update, doStructured) { + println("Loading latest configuration for " + util.resource.name); + var configuration = util.getLatestConfiguration(); + + printConfiguration(configuration) + println(''); + + if (doStructured) { + doStructuredUpdate(util.resource, configuration, update); + } + else { + doRawUpdate(util.resource, configuration, update); + } + + println("Modified configuration..."); + printConfiguration(configuration) + println(''); + + var translatedConfig = ConfigurationManager.translateResourceConfiguration(util.resource.id, configuration, + doStructured); + + println("Translated configuration..."); + printConfiguration(translatedConfig); + println(''); + } + + this.updateConfiguration = function(update, doStructured) { + println("Loading latest configuration for " + this.resource.name); + var configuration = this.getLatestConfiguration(); + + printConfiguration(configuration); + println(''); + + if (this.isStructuredSupported()) { + applyStructuredUpdate(this.resource, configuration, update); + } + else if (this.isRawSupported()) { + applyRawUpdate(this.resource, configuration, update); + } + else if (this.isStructuredAndRawSupported()) { + if (doStructured == null) { + throw "\nMust specify structured or raw when updating a configuration that supports both " + + "structured and raw. Update will abort."; + } + + if (doStructured) { + applyStructuredUpdate(this.resource, configuration, update); + } + else { + applyRawUpdate(this.resource, configuration, update); + } + } + + this.waitForResourceConfigurationUpdateToComplete(); + println("Configuration update has completed."); + + println("Loading latest, updated configuration"); + this.printLatestConfiguration(); + } + + this.waitForResourceConfigurationUpdateToComplete = function() { + print("Waiting for configuration update to complete...") + while (ConfigurationManager.isResourceConfigurationUpdateInProgress(this.resource.id)) { + print("."); + java.lang.Thread.sleep(waitInterval); + } + println(''); + } + + this.isRawSupported = function() { + var configFormat = this.resource.resourceType.resourceConfigurationDefinition.configurationFormat; + return ConfigurationFormat.RAW == configFormat; + } + + this.isStructuredSupported = function() { + var configFormat = this.resource.resourceType.resourceConfigurationDefinition.configurationFormat; + return ConfigurationFormat.STRUCTURED == configFormat; + } + + this.isStructuredAndRawSupported = function() { + var configFormat = this.resource.resourceType.resourceConfigurationDefinition.configurationFormat; + return ConfigurationFormat.STRUCTURED_AND_RAW == configFormat; + } + + function verifyPropertyToUpdateExists(configuration) { + if (!isDefined('propertyName')) { + throw "\nThe 'propertyName' variable must be defined. Update will abort."; + } + + if (!isDefined('propertyValue')) { + throw "\nThe 'propertyValue' variable must be defined. Update will abort."; + } + + if(configuration.getSimple(propertyName) == null) { + throw "\nThe property '" + propertyName + "' is undefined. Update will abort."; + } + } + + function verifyRawContentExists() { + if (!isDefined('contents')) { + throw "\n'contents' argument is required when updating " + serverName; + } + } + + function applyStructuredUpdate(resource, configuration, update) { + println("Applying resource configuration update..."); + doStructuredUpdate(resource, configuration, update); + ConfigurationManager.updateStructuredOrRawConfiguration(resource.id, configuration, structured); + } + + function doStructuredUpdate(resource, configuration, update) { + for (key in update) { + var property = configuration.getSimple(key.toString()); + if (property == null) { + throw "\nThe property '" + key + "' does not exist in the configuration. Update will abort."; + } + property.stringValue = update[key]; + } + } + + function applyRawUpdate(resource, configuration, update) { + println("Applying resource configuration update..."); + doRawUpdate(resource, configuration, update); + ConfigurationManager.updateStructuredOrRawConfiguration(resource.id, configuration, raw); + } + + function doRawUpdate(resourcec, configuration) { + var updates = 0; + var rawConfigs = java.util.ArrayList(configuration.rawConfigurations); + for (path in update) { + var rawConfig = findRawConfig(path, rawConfigs); + if (rawConfig == null) { + println("Failed to find raw config with path ending with " + path); + } + else { + configuration.rawConfigurations.remove(rawConfig); + var contents = java.lang.String(update[path]); + rawConfig.contents = contents.bytes; + configuration.rawConfigurations.add(rawConfig); + updates++; + } + } + + if (updates == 0) { + throw "\nNo matching paths were found. Update will abort."; + } + } + + function findRawConfig(path, rawConfigs) { + for (i = 0; i < rawConfigs.size(); i++) { + var rawConfig = rawConfigs.get(i); + if (rawConfig.path.endsWith(path.toString())) { + return rawConfig; + } + } + return null; + } + +} + +function findServer(name) { + var criteria = ResourceCriteria(); + criteria.strict = true; + criteria.addFilterName(name); + criteria.fetchResourceType(true); + + var resources = ResourceManager.findResourcesByCriteria(criteria); + + Assert.assertTrue(resources.size() == 1, "Expected to get back one resource but got back " + resources.size()); + + var resource = resources.get(0); + var resourceType = findResourceType(resource); + + if (resourceType == null) { + resourceType = loadResourceType(resource); + + if (resourceType == null) { + throw "Failed to initialize resource type for " + resource.name; + } + } + resource.resourceType = resourceType; + + return resource; +} + +function loadResourceType(resource) { + return ResourceTypeManager.getResourceTypeById(resource.resourceType.id); +} + +function findResourceType(resource) { + for (i = 0; i < resourceTypes.size(); i++) { + var resourceType = resourceTypes.get(i); + if (resourceType.id == resource.resourceType.id) { + return resourceType; + } + } + return null; +} diff --git a/modules/enterprise/remoting/scripts/src/main/script/configuration/update_structured.js b/modules/enterprise/remoting/scripts/src/main/script/configuration/update_structured.js deleted file mode 100644 index 54c39a9..0000000 --- a/modules/enterprise/remoting/scripts/src/main/script/configuration/update_structured.js +++ /dev/null @@ -1,287 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2008 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, version 2, as - * published by the Free Software Foundation, and/or the GNU Lesser - * General Public License, version 2.1, also as published by the Free - * Software Foundation. - * - * 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 and the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * and the GNU Lesser 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. - */ - -var waitInterval = 100; -var structured = true; -var raw = false; - -loadResourceTypes(); - -function loadResourceTypes() { - var resourceTypes = context.getAttribute('resourceTypes'); - if (resourceTypes != null && !resourceTypes.isEmpty()) { - return; - } - - var criteria = ResourceTypeCriteria(); - criteria.fetchResourceConfigurationDefinition(true); - - resourceTypes = ResourceTypeManager.findResourceTypesByCriteria(criteria); - context.setAttribute('resourceTypes', resourceTypes, javax.script.ScriptContext.ENGINE_SCOPE); -} - -function ConfigUtil(resourceName) { - var util = this; - - this.resource = findServer(resourceName); - - this.getLatestConfiguration = function () { - var latestUpdate = ConfigurationManager.getLatestResourceConfigurationUpdate(this.resource.id); - - Assert.assertNotNull( - latestUpdate, - "Failed to load the latest resource configuration update for " + this.resource.name - ); - Assert.assertNotNull( - latestUpdate.configuration, - "No configuration is attached to the latest config update object." - ); - - return latestUpdate.configuration; - } - - this.printLatestConfiguration = function() { - var configuration = this.getLatestConfiguration(); - printConfiguration(configuration); - } - - function printConfiguration(configuration) { - pretty.print(configuration); - - if (util.isRawSupported() || util.isStructuredAndRawSupported()) { - println("\nRaw configuration files:"); - var rawConfigs = java.util.ArrayList(configuration.rawConfigurations); - for (i = 0; i < rawConfigs.size(); i++) { - var rawConfig = rawConfigs.get(i); - println("\n[" + rawConfig.path + "]"); - println(java.lang.String(rawConfig.contents) + "\n\n---------------------"); - } - } - } - - this.translateToRaw = function(update) { - doTranslation(update, true); - } - - this.translateToStructured = function(update) { - doTranslation(update, false); - } - - function doTranslation(update, doStructured) { - println("Loading latest configuration for " + util.resource.name); - var configuration = util.getLatestConfiguration(); - - printConfiguration(configuration) - println(''); - - if (doStructured) { - doStructuredUpdate(util.resource, configuration, update); - } - else { - doRawUpdate(util.resource, configuration, update); - } - - println("Modified configuration..."); - printConfiguration(configuration) - println(''); - - var translatedConfig = ConfigurationManager.translateResourceConfiguration(util.resource.id, configuration, - doStructured); - - println("Translated configuration..."); - printConfiguration(translatedConfig); - println(''); - } - - this.updateConfiguration = function(update, doStructured) { - println("Loading latest configuration for " + this.resource.name); - var configuration = this.getLatestConfiguration(); - - printConfiguration(configuration); - println(''); - - if (this.isStructuredSupported()) { - applyStructuredUpdate(this.resource, configuration, update); - } - else if (this.isRawSupported()) { - applyRawUpdate(this.resource, configuration, update); - } - else if (this.isStructuredAndRawSupported()) { - if (doStructured == null) { - throw "\nMust specify structured or raw when updating a configuration that supports both " + - "structured and raw. Update will abort."; - } - - if (doStructured) { - applyStructuredUpdate(this.resource, configuration, update); - } - else { - applyRawUpdate(this.resource, configuration, update); - } - } - - this.waitForResourceConfigurationUpdateToComplete(); - println("Configuration update has completed."); - - println("Loading latest, updated configuration"); - this.printLatestConfiguration(); - } - - this.waitForResourceConfigurationUpdateToComplete = function() { - print("Waiting for configuration update to complete...") - while (ConfigurationManager.isResourceConfigurationUpdateInProgress(this.resource.id)) { - print("."); - java.lang.Thread.sleep(waitInterval); - } - println(''); - } - - this.isRawSupported = function() { - var configFormat = this.resource.resourceType.resourceConfigurationDefinition.configurationFormat; - return ConfigurationFormat.RAW == configFormat; - } - - this.isStructuredSupported = function() { - var configFormat = this.resource.resourceType.resourceConfigurationDefinition.configurationFormat; - return ConfigurationFormat.STRUCTURED == configFormat; - } - - this.isStructuredAndRawSupported = function() { - var configFormat = this.resource.resourceType.resourceConfigurationDefinition.configurationFormat; - return ConfigurationFormat.STRUCTURED_AND_RAW == configFormat; - } - - function verifyPropertyToUpdateExists(configuration) { - if (!isDefined('propertyName')) { - throw "\nThe 'propertyName' variable must be defined. Update will abort."; - } - - if (!isDefined('propertyValue')) { - throw "\nThe 'propertyValue' variable must be defined. Update will abort."; - } - - if(configuration.getSimple(propertyName) == null) { - throw "\nThe property '" + propertyName + "' is undefined. Update will abort."; - } - } - - function verifyRawContentExists() { - if (!isDefined('contents')) { - throw "\n'contents' argument is required when updating " + serverName; - } - } - - function applyStructuredUpdate(resource, configuration, update) { - println("Applying resource configuration update..."); - doStructuredUpdate(resource, configuration, update); - ConfigurationManager.updateStructuredOrRawConfiguration(resource.id, configuration, structured); - } - - function doStructuredUpdate(resource, configuration, update) { - for (key in update) { - var property = configuration.getSimple(key.toString()); - if (property == null) { - throw "\nThe property '" + key + "' does not exist in the configuration. Update will abort."; - } - property.stringValue = update[key]; - } - } - - function applyRawUpdate(resource, configuration, update) { - println("Applying resource configuration update..."); - doRawUpdate(resource, configuration, update); - ConfigurationManager.updateStructuredOrRawConfiguration(resource.id, configuration, raw); - } - - function doRawUpdate(resourcec, configuration) { - var updates = 0; - var rawConfigs = java.util.ArrayList(configuration.rawConfigurations); - for (path in update) { - var rawConfig = findRawConfig(path, rawConfigs); - if (rawConfig == null) { - println("Failed to find raw config with path ending with " + path); - } - else { - configuration.rawConfigurations.remove(rawConfig); - var contents = java.lang.String(update[path]); - rawConfig.contents = contents.bytes; - configuration.rawConfigurations.add(rawConfig); - updates++; - } - } - - if (updates == 0) { - throw "\nNo matching paths were found. Update will abort."; - } - } - - function findRawConfig(path, rawConfigs) { - for (i = 0; i < rawConfigs.size(); i++) { - var rawConfig = rawConfigs.get(i); - if (rawConfig.path.endsWith(path.toString())) { - return rawConfig; - } - } - return null; - } - -} - -function findServer(name) { - var criteria = ResourceCriteria(); - criteria.strict = true; - criteria.addFilterName(name); - criteria.fetchResourceType(true); - - var resources = ResourceManager.findResourcesByCriteria(criteria); - - Assert.assertTrue(resources.size() == 1, "Expected to get back one resource but got back " + resources.size()); - - var resource = resources.get(0); - var resourceType = findResourceType(resource); - - if (resourceType == null) { - resourceType = loadResourceType(resource); - - if (resourceType == null) { - throw "Failed to initialize resource type for " + resource.name; - } - } - resource.resourceType = resourceType; - - return resource; -} - -function loadResourceType(resource) { - return ResourceTypeManager.getResourceTypeById(resource.resourceType.id); -} - -function findResourceType(resource) { - for (i = 0; i < resourceTypes.size(); i++) { - var resourceType = resourceTypes.get(i); - if (resourceType.id == resource.resourceType.id) { - return resourceType; - } - } - return null; -}
commit c54676125c0d6cd991bf0ff875518cc3a8547b30 Author: Heiko W. Rupp pilhuhn@fedorapeople.org Date: Thu Dec 10 09:45:03 2009 +0100
Add required elements
diff --git a/modules/enterprise/server/xml-schemas/src/test/resources/test-serverplugin-alert.xml b/modules/enterprise/server/xml-schemas/src/test/resources/test-serverplugin-alert.xml index 74b7ec0..4e321c3 100644 --- a/modules/enterprise/server/xml-schemas/src/test/resources/test-serverplugin-alert.xml +++ b/modules/enterprise/server/xml-schemas/src/test/resources/test-serverplugin-alert.xml @@ -18,4 +18,8 @@ <c:simple-property name="alertprop1" /> </serverplugin:plugin-configuration>
+ <short-name>Test</short-name> + + <plugin-class>MyClass</plugin-class> + </alert-plugin>
commit db58839ac804a515d6d2271d0e305d98950b2449 Author: Heiko W. Rupp pilhuhn@fedorapeople.org Date: Thu Dec 10 13:38:55 2009 +0100
Copy the needed libs also when not in dev profile
diff --git a/modules/enterprise/server/plugins/alert-irc/pom.xml b/modules/enterprise/server/plugins/alert-irc/pom.xml index d2b424d..76b3b72 100644 --- a/modules/enterprise/server/plugins/alert-irc/pom.xml +++ b/modules/enterprise/server/plugins/alert-irc/pom.xml @@ -77,85 +77,119 @@
<profiles>
- <profile> - <id>dev</id> - - <properties> - <rhq.rootDir>../../../../..</rhq.rootDir> - <rhq.containerDir>${rhq.rootDir}/${rhq.defaultDevContainerPath}</rhq.containerDir> - <rhq.deploymentDir>${rhq.containerDir}/jbossas/server/default/deploy/${rhq.earName}/rhq-serverplugins</rhq.deploymentDir> - </properties> - - <build> - <plugins> - - <plugin> - <artifactId>maven-antrun-plugin</artifactId> - <version>1.1</version> - <executions> - - <execution> - <id>deploy</id> - <phase>compile</phase> - <configuration> - <tasks> - <mkdir dir="${rhq.deploymentDir}" /> - <property name="deployment.file" location="${rhq.deploymentDir}/${project.build.finalName}.jar" /> - <echo>*** Updating ${deployment.file}...</echo> - <jar destfile="${deployment.file}" basedir="${project.build.outputDirectory}" /> - </tasks> - </configuration> - <goals> - <goal>run</goal> - </goals> - </execution> - - <execution> - <id>undeploy</id> - <phase>clean</phase> - <configuration> - <tasks> - <property name="deployment.file" location="${rhq.deploymentDir}/${project.build.finalName}.jar" /> - <echo>*** Deleting ${deployment.file}...</echo> - <delete file="${deployment.file}" /> - </tasks> - </configuration> - <goals> - <goal>run</goal> - </goals> - </execution> - - </executions> - </plugin> - <plugin> - <artifactId>maven-dependency-plugin</artifactId> - <version>2.0</version> - <executions> - <execution> - <id>copy-pircbot-jar</id> - <phase>process-resources</phase> - <goals> - <goal>copy</goal> - </goals> - <configuration> - <artifactItems> - <artifactItem> - <groupId>pircbot</groupId> - <artifactId>pircbot</artifactId> - <version>1.4.2</version> - </artifactItem> - </artifactItems> - <outputDirectory>${project.build.outputDirectory}/lib</outputDirectory> - </configuration> - </execution> - </executions> - </plugin> - - - </plugins> - </build> - </profile> - + <profile> + <id>dev</id> + + <properties> + <rhq.rootDir>../../../../..</rhq.rootDir> + <rhq.containerDir>${rhq.rootDir}/${rhq.defaultDevContainerPath}</rhq.containerDir> + <rhq.deploymentDir>${rhq.containerDir}/jbossas/server/default/deploy/${rhq.earName}/rhq-serverplugins</rhq.deploymentDir> + </properties> + + <build> + <plugins> + + <plugin> + <artifactId>maven-antrun-plugin</artifactId> + <version>1.1</version> + <executions> + + <execution> + <id>deploy</id> + <phase>compile</phase> + <configuration> + <tasks> + <mkdir dir="${rhq.deploymentDir}" /> + <property name="deployment.file" location="${rhq.deploymentDir}/${project.build.finalName}.jar" /> + <echo>*** Updating ${deployment.file}...</echo> + <jar destfile="${deployment.file}" basedir="${project.build.outputDirectory}" /> + </tasks> + </configuration> + <goals> + <goal>run</goal> + </goals> + </execution> + + <execution> + <id>undeploy</id> + <phase>clean</phase> + <configuration> + <tasks> + <property name="deployment.file" location="${rhq.deploymentDir}/${project.build.finalName}.jar" /> + <echo>*** Deleting ${deployment.file}...</echo> + <delete file="${deployment.file}" /> + </tasks> + </configuration> + <goals> + <goal>run</goal> + </goals> + </execution> + + </executions> + </plugin> + <plugin> + <artifactId>maven-dependency-plugin</artifactId> + <version>2.0</version> + <executions> + <execution> + <id>copy-pircbot-jar</id> + <phase>process-resources</phase> + <goals> + <goal>copy</goal> + </goals> + <configuration> + <artifactItems> + <artifactItem> + <groupId>pircbot</groupId> + <artifactId>pircbot</artifactId> + <version>1.4.2</version> + </artifactItem> + </artifactItems> + <outputDirectory>${project.build.outputDirectory}/lib</outputDirectory> + </configuration> + </execution> + </executions> + </plugin> + + + </plugins> + </build> + </profile> + + <profile > + <id>overrides</id> + <activation> + <activeByDefault/> + </activation> + <build> + <plugins> + <plugin> + <artifactId>maven-dependency-plugin</artifactId> + <version>2.0</version> + <executions> + <execution> + <id>copy-pircbot-jar</id> + <phase>process-resources</phase> + <goals> + <goal>copy</goal> + </goals> + <configuration> + <artifactItems> + <artifactItem> + <groupId>pircbot</groupId> + <artifactId>pircbot</artifactId> + <version>1.4.2</version> + </artifactItem> + </artifactItems> + <outputDirectory>${project.build.outputDirectory}/lib</outputDirectory> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> + + </profile> </profiles>
</project> diff --git a/modules/enterprise/server/plugins/alert-microblog/pom.xml b/modules/enterprise/server/plugins/alert-microblog/pom.xml index ea1d2eb..f35ae52 100644 --- a/modules/enterprise/server/plugins/alert-microblog/pom.xml +++ b/modules/enterprise/server/plugins/alert-microblog/pom.xml @@ -76,87 +76,121 @@ </plugins> </build>
- <profiles> + <profiles>
<profile> - <id>dev</id> - - <properties> - <rhq.rootDir>../../../../..</rhq.rootDir> - <rhq.containerDir>${rhq.rootDir}/${rhq.defaultDevContainerPath}</rhq.containerDir> - <rhq.deploymentDir>${rhq.containerDir}/jbossas/server/default/deploy/${rhq.earName}/rhq-serverplugins</rhq.deploymentDir> - </properties> - - <build> - <plugins> - - <plugin> - <artifactId>maven-antrun-plugin</artifactId> - <version>1.1</version> - <executions> - - <execution> - <id>deploy</id> - <phase>compile</phase> - <configuration> - <tasks> - <mkdir dir="${rhq.deploymentDir}" /> - <property name="deployment.file" location="${rhq.deploymentDir}/${project.build.finalName}.jar" /> - <echo>*** Updating ${deployment.file}...</echo> - <jar destfile="${deployment.file}" basedir="${project.build.outputDirectory}" /> - </tasks> - </configuration> - <goals> - <goal>run</goal> - </goals> - </execution> - - <execution> - <id>undeploy</id> - <phase>clean</phase> - <configuration> - <tasks> - <property name="deployment.file" location="${rhq.deploymentDir}/${project.build.finalName}.jar" /> - <echo>*** Deleting ${deployment.file}...</echo> - <delete file="${deployment.file}" /> - </tasks> - </configuration> - <goals> - <goal>run</goal> - </goals> - </execution> - - </executions> - </plugin> - <plugin> - <artifactId>maven-dependency-plugin</artifactId> - <version>2.0</version> - <executions> - <execution> - <id>copy-twitter4j-jar</id> - <phase>process-resources</phase> - <goals> - <goal>copy</goal> - </goals> - <configuration> - <artifactItems> - <artifactItem> - <groupId>net.homeip.yusuke</groupId> - <artifactId>twitter4j</artifactId> - <version>2.0.9</version> - </artifactItem> - </artifactItems> - <outputDirectory>${project.build.outputDirectory}/lib</outputDirectory> - </configuration> - </execution> - </executions> - </plugin> - - - </plugins> - </build> + <id>dev</id> + + <properties> + <rhq.rootDir>../../../../..</rhq.rootDir> + <rhq.containerDir>${rhq.rootDir}/${rhq.defaultDevContainerPath}</rhq.containerDir> + <rhq.deploymentDir>${rhq.containerDir}/jbossas/server/default/deploy/${rhq.earName}/rhq-serverplugins</rhq.deploymentDir> + </properties> + + <build> + <plugins> + + <plugin> + <artifactId>maven-antrun-plugin</artifactId> + <version>1.1</version> + <executions> + + <execution> + <id>deploy</id> + <phase>compile</phase> + <configuration> + <tasks> + <mkdir dir="${rhq.deploymentDir}" /> + <property name="deployment.file" location="${rhq.deploymentDir}/${project.build.finalName}.jar" /> + <echo>*** Updating ${deployment.file}...</echo> + <jar destfile="${deployment.file}" basedir="${project.build.outputDirectory}" /> + </tasks> + </configuration> + <goals> + <goal>run</goal> + </goals> + </execution> + + <execution> + <id>undeploy</id> + <phase>clean</phase> + <configuration> + <tasks> + <property name="deployment.file" location="${rhq.deploymentDir}/${project.build.finalName}.jar" /> + <echo>*** Deleting ${deployment.file}...</echo> + <delete file="${deployment.file}" /> + </tasks> + </configuration> + <goals> + <goal>run</goal> + </goals> + </execution> + + </executions> + </plugin> + <plugin> + <artifactId>maven-dependency-plugin</artifactId> + <version>2.0</version> + <executions> + <execution> + <id>copy-twitter4j-jar</id> + <phase>process-resources</phase> + <goals> + <goal>copy</goal> + </goals> + <configuration> + <artifactItems> + <artifactItem> + <groupId>net.homeip.yusuke</groupId> + <artifactId>twitter4j</artifactId> + <version>2.0.9</version> + </artifactItem> + </artifactItems> + <outputDirectory>${project.build.outputDirectory}/lib</outputDirectory> + </configuration> + </execution> + </executions> + </plugin> + + + </plugins> + </build> </profile> + <profile > + <id>overrides</id> + <activation> + <activeByDefault/> + </activation> + <build> + <plugins> + <plugin> + <artifactId>maven-dependency-plugin</artifactId> + <version>2.0</version> + <executions> + <execution> + <id>copy-twitter4j-jar</id> + <phase>process-resources</phase> + <goals> + <goal>copy</goal> + </goals> + <configuration> + <artifactItems> + <artifactItem> + <groupId>net.homeip.yusuke</groupId> + <artifactId>twitter4j</artifactId> + <version>2.0.9</version> + </artifactItem> + </artifactItems> + <outputDirectory>${project.build.outputDirectory}/lib</outputDirectory> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build>
- </profiles> + </profile> + + </profiles>
</project> \ No newline at end of file
commit 2bfffc8bf7a815a67a120ebec8cd0d80fe4b8d71 Author: Jason Dobies jason.dobies@redhat.com Date: Thu Dec 10 15:38:24 2009 -0500
Renamed source -> provider.
diff --git a/modules/enterprise/server/plugins/jboss-software/src/main/resources/META-INF/rhq-serverplugin.xml b/modules/enterprise/server/plugins/jboss-software/src/main/resources/META-INF/rhq-serverplugin.xml index 0597ea1..522bacd 100644 --- a/modules/enterprise/server/plugins/jboss-software/src/main/resources/META-INF/rhq-serverplugin.xml +++ b/modules/enterprise/server/plugins/jboss-software/src/main/resources/META-INF/rhq-serverplugin.xml @@ -7,8 +7,8 @@ xmlns:c="urn:xmlns:rhq-configuration">
<contentSourceType name="JBossASPatchSource" - displayName="JBoss AS Patch Content Source" - description="This content source retrieves packages from the JBoss CSP RSS feed." + displayName="JBoss AS Patch Content Provider" + description="This content provider retrieves packages from the JBoss CSP RSS feed." lazyLoad="true" apiClass="org.rhq.enterprise.server.plugins.jboss.software.JBossSoftwareContentSourceAdapter">
commit 38bd583418aea281d62fa5b723d604319b7c9377 Author: Jason Dobies jason.dobies@redhat.com Date: Thu Dec 10 15:37:56 2009 -0500
Renamed source -> provider.
diff --git a/modules/enterprise/server/plugins/yum/src/main/resources/META-INF/rhq-serverplugin.xml b/modules/enterprise/server/plugins/yum/src/main/resources/META-INF/rhq-serverplugin.xml index 287a6f3..e42102b 100644 --- a/modules/enterprise/server/plugins/yum/src/main/resources/META-INF/rhq-serverplugin.xml +++ b/modules/enterprise/server/plugins/yum/src/main/resources/META-INF/rhq-serverplugin.xml @@ -7,8 +7,8 @@ xmlns:c="urn:xmlns:rhq-configuration">
<contentSourceType name="YumSource" - displayName="Yum Repository Content Source" - description="This content source retrieves packages from a local or remote Yum repository." + displayName="Yum Repository Content Provider" + description="This content provider retrieves packages from a local or remote Yum repository." lazyLoad="true" downloadMode="filesystem" apiClass="org.rhq.enterprise.server.plugins.yum.RepoProvider">
commit 4e945b4751b21bf527641e6f6d9edf2656f047d9 Author: Jason Dobies jason.dobies@redhat.com Date: Thu Dec 10 15:37:33 2009 -0500
Renamed source -> provider.
diff --git a/modules/enterprise/server/plugins/url/src/main/resources/META-INF/rhq-serverplugin.xml b/modules/enterprise/server/plugins/url/src/main/resources/META-INF/rhq-serverplugin.xml index b8e67c2..3202151 100644 --- a/modules/enterprise/server/plugins/url/src/main/resources/META-INF/rhq-serverplugin.xml +++ b/modules/enterprise/server/plugins/url/src/main/resources/META-INF/rhq-serverplugin.xml @@ -7,14 +7,14 @@ xmlns:c="urn:xmlns:rhq-configuration">
<contentSourceType name="UrlSource" - displayName="Remote URL Content Source" - description="This content source retrieves packages from a remote system identified by a URL." + displayName="Remote URL Content Provider" + description="This content provider retrieves packages from a remote system identified by a URL." lazyLoad="true" downloadMode="database" apiClass="org.rhq.enterprise.server.plugins.url.UrlProvider">
<configuration> - <c:simple-property name="rootUrl" type="string" required="true" description="The URL that contains all content that is to be served by this content source."/> + <c:simple-property name="rootUrl" type="string" required="true" description="The URL that contains all content that is to be served by this content provider."/> <c:simple-property name="indexFile" type="string" required="true" default="content-index.txt" description="The index file that defines all the content that can be found on the remote server. If this is not a full URL, it is assumed to be relative to the root URL."/>
<c:list-property name="packageTypes" required="true" min="0" @@ -32,14 +32,14 @@ </contentSourceType>
<contentSourceType name="HttpSource" - displayName="HTTP Content Source" - description="This content source retrieves packages from a remote HTTP server, possibly via a proxy." + displayName="HTTP Content Provider" + description="This content provider retrieves packages from a remote HTTP server, possibly via a proxy." lazyLoad="true" downloadMode="database" apiClass="org.rhq.enterprise.server.plugins.url.HttpProvider">
<configuration> - <c:simple-property name="rootUrl" type="string" required="true" description="The HTTP URL that contains all content that is to be served by this content source."/> + <c:simple-property name="rootUrl" type="string" required="true" description="The HTTP URL that contains all content that is to be served by this content provider."/> <c:simple-property name="indexFile" type="string" required="true" default="content-index.txt" description="The index file that defines all the content that can be found on the remote server. If this is not a full URL, it is assumed to be relative to the root URL."/>
<c:list-property name="packageTypes" required="true" min="0"
commit 0fec19734ecada39194cf4bc21d3c0610706b9f6 Author: Jason Dobies jason.dobies@redhat.com Date: Thu Dec 10 15:36:16 2009 -0500
Renamed source -> provider.
diff --git a/modules/enterprise/server/plugins/disk/src/main/resources/META-INF/rhq-serverplugin.xml b/modules/enterprise/server/plugins/disk/src/main/resources/META-INF/rhq-serverplugin.xml index 45b3aa1..5097fa1 100644 --- a/modules/enterprise/server/plugins/disk/src/main/resources/META-INF/rhq-serverplugin.xml +++ b/modules/enterprise/server/plugins/disk/src/main/resources/META-INF/rhq-serverplugin.xml @@ -7,8 +7,8 @@ xmlns:c="urn:xmlns:rhq-configuration">
<contentSourceType name="DiskSource" - displayName="Local Disk Storage Content Source" - description="This content source retrieves packages from a local file system. If deployed in an HA environment, this must be on a distributed file system that all servers can access." + displayName="Local Disk Storage Content Provider" + description="This content provider retrieves packages from a local file system. If deployed in an HA environment, this must be on a distributed file system that all servers can access." lazyLoad="true" downloadMode="never" apiClass="org.rhq.enterprise.server.plugins.disk.DiskSource"> @@ -17,7 +17,7 @@
<c:group name="General"> <c:simple-property name="rootDirectory" type="directory" required="true" - description="The root directory that contains all content that is to be served by this content source. In an HA environment, this must be on a distributed file system that all servers can access."/> + description="The root directory that contains all content that is to be served by this content provider. In an HA environment, this must be on a distributed file system that all servers can access."/> </c:group>
<c:group name="Package Source">
commit 000ec01859f38e90b11cb77935325374b8509e5d Author: Jason Dobies jason.dobies@redhat.com Date: Fri Dec 4 16:20:08 2009 -0500
Added repo source support. Repos will be determined by directories in the root directory (specified in the plugin configuration). I'll add some docs for this in the wiki soon since this will likely help with QA.
diff --git a/modules/enterprise/server/plugins/disk/src/main/java/org/rhq/enterprise/server/plugins/disk/DiskSource.java b/modules/enterprise/server/plugins/disk/src/main/java/org/rhq/enterprise/server/plugins/disk/DiskSource.java index f70bb69..94f1ad3 100644 --- a/modules/enterprise/server/plugins/disk/src/main/java/org/rhq/enterprise/server/plugins/disk/DiskSource.java +++ b/modules/enterprise/server/plugins/disk/src/main/java/org/rhq/enterprise/server/plugins/disk/DiskSource.java @@ -30,6 +30,7 @@ import java.util.Map; import org.rhq.core.domain.configuration.Configuration; import org.rhq.core.domain.configuration.Property; import org.rhq.core.domain.configuration.PropertyMap; +import org.rhq.core.domain.configuration.PropertySimple; import org.rhq.core.util.MessageDigestGenerator; import org.rhq.core.util.file.ContentFileInfo; import org.rhq.core.util.file.ContentFileInfoFactory; @@ -38,6 +39,9 @@ import org.rhq.enterprise.server.plugin.pc.content.ContentProviderPackageDetails import org.rhq.enterprise.server.plugin.pc.content.ContentProviderPackageDetailsKey; import org.rhq.enterprise.server.plugin.pc.content.PackageSource; import org.rhq.enterprise.server.plugin.pc.content.PackageSyncReport; +import org.rhq.enterprise.server.plugin.pc.content.RepoDetails; +import org.rhq.enterprise.server.plugin.pc.content.RepoImportReport; +import org.rhq.enterprise.server.plugin.pc.content.RepoSource;
/** * This is the most basic <i>reference</i> implementation of a content source. It provides primative package @@ -47,7 +51,7 @@ import org.rhq.enterprise.server.plugin.pc.content.PackageSyncReport; * @author jortel * @author John Mazzitelli */ -public class DiskSource implements ContentProvider, PackageSource { +public class DiskSource implements ContentProvider, PackageSource, RepoSource {
/** * The root path (directory) from which to synchronize content. @@ -65,25 +69,28 @@ public class DiskSource implements ContentProvider, PackageSource { */ private Map<String, SupportedPackageType> supportedPackageTypes;
- protected File getRootDirectory() { - return this.rootDirectory; - } - - protected void setRootDirectory(File path) { - this.rootDirectory = path; - this.rootDirectoryAbsolutePath = this.rootDirectory.getAbsolutePath(); - } + /** + * Configuration for this instance of the plugin. + */ + private Configuration configuration;
- protected Map<String, SupportedPackageType> getSupportedPackageTypes() { - return this.supportedPackageTypes; - } + /** + * Indicates if the repo source functionality of this instance is enabled or disabled. + */ + private boolean isRepoSource;
- protected void setSupportedPackageTypes(Map<String, SupportedPackageType> supportedPackageTypes) { - this.supportedPackageTypes = supportedPackageTypes; - } + /** + * Indicates if the package source functionality of this instance is enabled or disabled. + */ + private boolean isPackageSource;
public void initialize(Configuration configuration) throws Exception { - initializePackageTypes(configuration); + this.configuration = configuration; + + isPackageSource = ((PropertySimple) configuration.get("packageSourceEnabled")).getBooleanValue(); + isRepoSource = ((PropertySimple) configuration.get("repoSourceEnabled")).getBooleanValue(); + + initializePackageTypes(); String pathString = configuration.getSimpleValue("rootDirectory", null); setRootDirectory(new File(pathString)); testConnection(); @@ -95,10 +102,27 @@ public class DiskSource implements ContentProvider, PackageSource { this.supportedPackageTypes = null; }
+ public RepoImportReport importRepos() throws Exception { + RepoImportReport report = new RepoImportReport(); + + if (!isRepoSource) { + return report; + } + + File directory = getRootDirectory(); + generateRepoDetails(report, directory, null); + + return report; + } + public void synchronizePackages(String repoName, PackageSyncReport report, Collection<ContentProviderPackageDetails> existingPackages) throws Exception {
+ if (!isPackageSource) { + return; + } + // put all existing packages in a "to be deleted" list. As we sync, we will remove // packages from this list that still exist on the file system. Any leftover in the list // are packages that no longer exist on the file system and should be removed from the server inventory. @@ -107,7 +131,7 @@ public class DiskSource implements ContentProvider, PackageSource {
// sync now long before = System.currentTimeMillis(); - syncPackages(report, deletedPackages, getRootDirectory()); + syncPackages(report, repoName, deletedPackages, getRootDirectory()); long elapsed = System.currentTimeMillis() - before;
// if there are packages that weren't found on the file system, tell server to remove them from inventory @@ -116,8 +140,6 @@ public class DiskSource implements ContentProvider, PackageSource { }
report.setSummary("Synchronized [" + getRootDirectory() + "]. Elapsed time=[" + elapsed + "] ms"); - - return; }
public void testConnection() throws Exception { @@ -134,52 +156,73 @@ public class DiskSource implements ContentProvider, PackageSource { if (!root.isDirectory()) { throw new Exception("Disk source [" + root + "] is not a directory"); } - - return; // good }
public InputStream getInputStream(String location) throws Exception { return new FileInputStream(new File(getRootDirectory(), location)); }
+ protected File getRootDirectory() { + return this.rootDirectory; + } + + protected void setRootDirectory(File path) { + this.rootDirectory = path; + this.rootDirectoryAbsolutePath = this.rootDirectory.getAbsolutePath(); + } + + protected Map<String, SupportedPackageType> getSupportedPackageTypes() { + return this.supportedPackageTypes; + } + + protected void setSupportedPackageTypes(Map<String, SupportedPackageType> supportedPackageTypes) { + this.supportedPackageTypes = supportedPackageTypes; + } + /** * Recursive function that drills down into subdirectories and builds up the report * of packages for all files found. As files are found, their associated packages * are removed from <code>packages</code> if they exist - leaving only packages * remaining that do not exist on the file system. - * + * * @param report the report that we are building up * @param packages existing packages not yet found on the file system but exist in server inventory * @param directory the directory (and its subdirectories) to scan * @throws Exception if the sync fails */ - protected void syncPackages(PackageSyncReport report, List<ContentProviderPackageDetails> packages, File directory) + protected void syncPackages(PackageSyncReport report, String repoName, + List<ContentProviderPackageDetails> packages, File directory) throws Exception {
for (File file : directory.listFiles()) { if (file.isDirectory()) { - // process the directory recursively - syncPackages(report, packages, file); - } else { - // process the file - ContentProviderPackageDetails details = createPackage(file); - if (details != null) { - ContentProviderPackageDetails existing = findPackage(packages, details); - if (existing == null) { - report.addNewPackage(details); - } else { - packages.remove(existing); // it still exists, remove it from our list - if (details.getFileCreatedDate().compareTo(existing.getFileCreatedDate()) > 0) { - report.addUpdatedPackage(details); + + if (file.getName().equals(repoName)) { + + for (File filePackage : file.listFiles()) { + ContentProviderPackageDetails details = createPackage(filePackage); + if (details != null) { + ContentProviderPackageDetails existing = findPackage(packages, details); + if (existing == null) { + report.addNewPackage(details); + } else { + packages.remove(existing); // it still exists, remove it from our list + if (details.getFileCreatedDate().compareTo(existing.getFileCreatedDate()) > 0) { + report.addUpdatedPackage(details); + } + } + } else { + // file does not match any filter and is therefore an unknown type - ignore it } } - } else { - // file does not match any filter and is therefore an unknown type - ignore it + + break; } + + // Otherwise, keep searching recursively for a directory with the same name + syncPackages(report, repoName, packages, file); } } - - return; }
protected ContentProviderPackageDetails createPackage(File file) throws Exception { @@ -238,16 +281,16 @@ public class DiskSource implements ContentProvider, PackageSource { return relativePath; }
- protected void initializePackageTypes(Configuration config) { + protected void initializePackageTypes() {
Map<String, SupportedPackageType> supportedPackageTypes = new HashMap<String, SupportedPackageType>();
- /* TODO: THE UI CURRENTLY DOES NOT SUPPORT ADDING/EDITING LIST OF MAPS, SO WE CAN ONLY SUPPORT ONE PACKAGE TYPE + /* TODO: THE UI CURRENTLY DOES NOT SUPPORT ADDING/EDITING LIST OF MAPS, SO WE CAN ONLY SUPPORT ONE PACKAGE TYPE * SO FOR NOW, JUST SUPPORT A FLAT SET OF SIMPLE PROPS - WE WILL RE-ENABLE THIS CODE LATER */ if (false) { // All of these properties must exist, any nulls should trigger runtime exceptions which is what we want - // because if the configuration is bad, this content source should not initialize. - List<Property> packageTypesList = config.getList("packageTypes").getList(); + // because if the configuration is bad, this content source should not initialize. + List<Property> packageTypesList = configuration.getList("packageTypes").getList(); for (Property property : packageTypesList) { PropertyMap pkgType = (PropertyMap) property; SupportedPackageType supportedPackageType = new SupportedPackageType(); @@ -262,11 +305,11 @@ public class DiskSource implements ContentProvider, PackageSource { } else { /* THIS CODE IS THE FLAT SET OF PROPS - USE UNTIL WE CAN EDIT MAPS AT WHICH TIME DELETE THIS ELSE CLAUSE */ SupportedPackageType supportedPackageType = new SupportedPackageType(); - supportedPackageType.packageTypeName = config.getSimpleValue("packageTypeName", null); - supportedPackageType.architectureName = config.getSimpleValue("architectureName", null); - supportedPackageType.resourceTypeName = config.getSimpleValue("resourceTypeName", null); - supportedPackageType.resourceTypePluginName = config.getSimpleValue("resourceTypePluginName", null); - String filenameFilter = config.getSimpleValue("filenameFilter", null); + supportedPackageType.packageTypeName = configuration.getSimpleValue("packageTypeName", null); + supportedPackageType.architectureName = configuration.getSimpleValue("architectureName", null); + supportedPackageType.resourceTypeName = configuration.getSimpleValue("resourceTypeName", null); + supportedPackageType.resourceTypePluginName = configuration.getSimpleValue("resourceTypePluginName", null); + String filenameFilter = configuration.getSimpleValue("filenameFilter", null); supportedPackageTypes.put(filenameFilter, supportedPackageType); }
@@ -284,6 +327,22 @@ public class DiskSource implements ContentProvider, PackageSource { return null; // the file doesn't match any known types for this content source }
+ protected void generateRepoDetails(RepoImportReport report, File base, String parentName) { + + for (File file : base.listFiles()) { + + if (file.isDirectory()) { + + // Add this as a new repo + RepoDetails repo = new RepoDetails(file.getName(), parentName); + report.addRepo(repo); + + // Check to see if there are any child repos + generateRepoDetails(report, file, repo.getName()); + } + } + } + protected class SupportedPackageType { public String packageTypeName; public String architectureName; diff --git a/modules/enterprise/server/plugins/disk/src/main/resources/META-INF/rhq-serverplugin.xml b/modules/enterprise/server/plugins/disk/src/main/resources/META-INF/rhq-serverplugin.xml index 9d2b458..45b3aa1 100644 --- a/modules/enterprise/server/plugins/disk/src/main/resources/META-INF/rhq-serverplugin.xml +++ b/modules/enterprise/server/plugins/disk/src/main/resources/META-INF/rhq-serverplugin.xml @@ -6,30 +6,42 @@ xmlns="urn:xmlns:rhq-serverplugin.content" xmlns:c="urn:xmlns:rhq-configuration">
- <contentSourceType name="DiskSource" - displayName="Local Disk Storage Content Source" - description="This content source retrieves packages from a local file system. If deployed in an HA environment, this must be on a distributed file system that all servers can access." - lazyLoad="true" - downloadMode="never" - apiClass="org.rhq.enterprise.server.plugins.disk.DiskSource"> - - <configuration> - <c:simple-property name="rootDirectory" type="directory" required="true" description="The root directory that contains all content that is to be served by this content source. In an HA environment, this must be on a distributed file system that all servers can access."/> - <!-- would like to be able to define multiple package types, but the UI doesn't allow editing maps yet - <c:list-property name="packageTypes" required="true" description="Defines the different package types that can be found on this disk content source"> - <c:map-property name="packageType"> - --> - <c:simple-property name="filenameFilter" required="true" summary="true" default=".*" description="A regular expression that identifies a file of this package type (e.g. '.*.jar', '.*/i686/.*.rpm$')"/> - <c:simple-property name="packageTypeName" required="true" summary="true" description="The name that identifies the kind of package this type represents (e.g. 'ear', 'rpm')"/> - <c:simple-property name="architectureName" required="true" summary="true" default="noarch" description="The specific hardware architecture this type of package can be deployed on. If there is no specific architecture required, use 'noarch'. (e.g. 'i686', 'amd64')"/> - <c:simple-property name="resourceTypeName" required="true" summary="true" description="The name of the resource type on which this package can be deployed. This is the resource type name as defined in the agent plugin. (e.g. 'Linux', 'JBossAS Server')"/> - <c:simple-property name="resourceTypePluginName" required="true" summary="true" description="The name of the plugin that defined the resource type. (e.g. 'Platform', 'JBossAS')"/> - <!-- - </c:map-property> - </c:list-property> - --> - </configuration> - - </contentSourceType> + <contentSourceType name="DiskSource" + displayName="Local Disk Storage Content Source" + description="This content source retrieves packages from a local file system. If deployed in an HA environment, this must be on a distributed file system that all servers can access." + lazyLoad="true" + downloadMode="never" + apiClass="org.rhq.enterprise.server.plugins.disk.DiskSource"> + + <configuration> + + <c:group name="General"> + <c:simple-property name="rootDirectory" type="directory" required="true" + description="The root directory that contains all content that is to be served by this content source. In an HA environment, this must be on a distributed file system that all servers can access."/> + </c:group> + + <c:group name="Package Source"> + <c:simple-property name="packageSourceEnabled" required="true" summary="true" default="true" + type="boolean" description="Indicates if this instance of the plugin should act as a package source"/> + <c:simple-property name="filenameFilter" required="true" summary="true" default=".*" + description="A regular expression that identifies a file of this package type (e.g. '.*.jar', '.*/i686/.*.rpm$')"/> + <c:simple-property name="packageTypeName" required="true" summary="true" + description="The name that identifies the kind of package this type represents (e.g. 'ear', 'rpm')"/> + <c:simple-property name="architectureName" required="true" summary="true" default="noarch" + description="The specific hardware architecture this type of package can be deployed on. If there is no specific architecture required, use 'noarch'. (e.g. 'i686', 'amd64')"/> + <c:simple-property name="resourceTypeName" required="true" summary="true" + description="The name of the resource type on which this package can be deployed. This is the resource type name as defined in the agent plugin. (e.g. 'Linux', 'JBossAS Server')"/> + <c:simple-property name="resourceTypePluginName" required="true" summary="true" + description="The name of the plugin that defined the resource type. (e.g. 'Platform', 'JBossAS')"/> + </c:group> + + <c:group name="Repo Source"> + <c:simple-property name="repoSourceEnabled" required="true" summary="true" default="true" + type="boolean" description="Indicates if this instance of the plugin should act as a repo source"/> + </c:group> + + </configuration> + + </contentSourceType>
</content-plugin> \ No newline at end of file
commit 70d7800c56eff73de20a5171f049d372ac9102f1 Merge: 3663681... 50c100c... Author: John Sanda jsanda@redhat.com Date: Thu Dec 10 11:51:05 2009 -0500
Merge branch 'master' into raw-config
Conflicts: modules/plugins/JBossOSGi/jopr-jbossOsgi-plugin.iml
commit c96ca25c9cdb732370678ac065e067e9b06c095c Author: John Mazzitelli mazz@redhat.com Date: Thu Dec 10 11:14:08 2009 -0500
add sorting to the plugin ui - hide the purge button unless you are viewing undeployed plugins
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-list.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-list.xhtml index 59ccecd..15b3601 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-list.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-list.xhtml @@ -72,8 +72,7 @@ <h:outputText value="#{agentPlugin.id}"/> </rich:column>
- - rich:column + <rich:column sortBy="#{agentPlugin.displayName}"> <f:facet name="header"> <h:outputText styleClass="headerText" value="Name"/> </f:facet> @@ -86,8 +85,7 @@
</rich:column>
- - rich:column + <rich:column sortBy="#{agentPlugin.description}"> <f:facet name="header"> <h:outputText styleClass="headerText" value="Description"/> </f:facet> @@ -95,7 +93,7 @@ <h:outputText value="#{agentPlugin.description}"/> </rich:column>
- rich:column + <rich:column sortBy="#{agentPlugin.mtime}"> <f:facet name="header"> <h:outputText styleClass="headerText" value="Last Update"/> </f:facet> @@ -105,7 +103,6 @@ </h:outputText> </rich:column>
- rich:column <f:facet name="header"> <h:outputText styleClass="headerText" value="Enabled"/> @@ -160,8 +157,7 @@ <h:outputText value="#{serverPlugin.id}"/> </rich:column>
- - rich:column + <rich:column sortBy="#{serverPlugin.displayName}"> <f:facet name="header"> <h:outputText styleClass="headerText" value="Name"/> </f:facet> @@ -175,8 +171,7 @@
</rich:column>
- - rich:column + <rich:column sortBy="#{serverPlugin.description}"> <f:facet name="header"> <h:outputText styleClass="headerText" value="Description"/> </f:facet> @@ -184,7 +179,7 @@ <h:outputText value="#{serverPlugin.description}"/> </rich:column>
- rich:column + <rich:column sortBy="#{serverPlugin.mtime}"> <f:facet name="header"> <h:outputText styleClass="headerText" value="Last Update"/> </f:facet> @@ -195,7 +190,7 @@ </rich:column>
- rich:column + <rich:column sortBy="#{serverPlugin.enabled}"> <f:facet name="header"> <h:outputText styleClass="headerText" value="Enabled"/> </f:facet> @@ -204,7 +199,7 @@ <h:graphicImage value="/images/icons/availability_red_16.png" rendered="#{!serverPlugin.enabled}"/> </rich:column>
- <rich:column rendered="#{InstalledPluginsSessionUIBean.showAllServerPlugins}"> + <rich:column sortBy="#{serverPlugin.status}" rendered="#{InstalledPluginsSessionUIBean.showAllServerPlugins}"> <f:facet name="header"> <h:outputText styleClass="headerText" value="Deployed"/> </f:facet> @@ -226,6 +221,7 @@ value="UNDEPLOY" target="selectedPlugin" styleClass="on-pager-button buttonsmall"> </onc:selectCommandButton> <onc:selectCommandButton action="#{InstalledPluginsUIBean.purgeServerPlugins}" + rendered="#{InstalledPluginsSessionUIBean.showAllServerPlugins}" value="PURGE" target="selectedPlugin" styleClass="on-pager-button buttonsmall"> </onc:selectCommandButton> </rich:column>
commit 50c100c622a4ed0938732a7ff3dd24c453b426ce Author: John Mazzitelli mazz@redhat.com Date: Wed Dec 9 23:45:22 2009 -0500
fix hot-deployment bugs so we can upload and enable plugisn without recycling the master PC
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/AbstractJobWrapper.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/AbstractJobWrapper.java index 4493a2d..24a4572 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/AbstractJobWrapper.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/AbstractJobWrapper.java @@ -33,6 +33,8 @@ import org.rhq.core.util.exception.ThrowableUtil; import org.rhq.enterprise.server.util.LookupUtil; import org.rhq.enterprise.server.xmlschema.AbstractScheduleType; import org.rhq.enterprise.server.xmlschema.ScheduledJobDefinition; +import org.rhq.enterprise.server.xmlschema.ServerPluginDescriptorMetadataParser; +import org.rhq.enterprise.server.xmlschema.generated.serverplugin.ServerPluginDescriptorType;
/** * The superclass to the concurrent and stateful job wrappers. @@ -189,6 +191,8 @@ abstract class AbstractJobWrapper implements Job { } } else { try { + ServerPluginDescriptorType descriptor = pluginEnv.getPluginDescriptor(); + jobClass = ServerPluginDescriptorMetadataParser.getFullyQualifiedClassName(descriptor, jobClass); pluginJobObject = pluginManager.instantiatePluginClass(pluginEnv, jobClass); } catch (Throwable t) { // invalid class - we need to unschedule this, do not refire since it will never work diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/AbstractTypeServerPluginContainer.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/AbstractTypeServerPluginContainer.java index 5c80ce3..b5572be 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/AbstractTypeServerPluginContainer.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/AbstractTypeServerPluginContainer.java @@ -173,7 +173,7 @@ public abstract class AbstractTypeServerPluginContainer { */ public synchronized void unloadPlugin(PluginKey pluginKey) throws Exception { if (this.pluginManager != null) { - this.pluginManager.unloadPlugin(pluginKey.getPluginName()); + this.pluginManager.unloadPlugin(pluginKey.getPluginName(), false); } else { throw new Exception("Cannot unload a plugin; plugin container has been shutdown"); } diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ClassLoaderManager.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ClassLoaderManager.java index ae3bbe4..d62465f 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ClassLoaderManager.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ClassLoaderManager.java @@ -83,9 +83,7 @@ public class ClassLoaderManager {
this.pluginKeysUrls = new HashMap<PluginKey, URL>(plugins.size()); for (Map.Entry<URL, ? extends ServerPluginDescriptorType> entry : plugins.entrySet()) { - ServerPluginType pluginType = new ServerPluginType(entry.getValue()); - PluginKey pluginKey = PluginKey.createServerPluginKey(pluginType.stringify(), entry.getValue().getName()); - this.pluginKeysUrls.put(pluginKey, entry.getKey()); + loadPlugin(entry.getKey(), entry.getValue()); }
return; @@ -108,6 +106,37 @@ public class ClassLoaderManager { return; }
+ /** + * Hot-deploys a plugin into this classloader manager. + * + * @param pluginUrl location of the plugin jar file + * @param descriptor the plugin descriptor + */ + public synchronized void loadPlugin(URL pluginUrl, ServerPluginDescriptorType descriptor) { + ServerPluginType pluginType = new ServerPluginType(descriptor); + PluginKey pluginKey = PluginKey.createServerPluginKey(pluginType.stringify(), descriptor.getName()); + this.pluginKeysUrls.put(pluginKey, pluginUrl); + } + + /** + * Unloads the plugin identified with the current key from this classloader manager and destroys + * that plugin's classloader, if one existed. + * + * @param pluginKey identifies the plugin to be unloaded + */ + public synchronized void unloadPlugin(PluginKey pluginKey) { + this.pluginKeysUrls.remove(pluginKey); + ClassLoader unloadedCL = this.serverPluginClassLoaders.remove(pluginKey); + if (unloadedCL instanceof ServerPluginClassLoader) { + try { + ((ServerPluginClassLoader) unloadedCL).destroy(); + } catch (Exception e) { + log.warn("Failed to destroy classloader [" + unloadedCL + "] for plugin [" + pluginKey + "]", e); + } + } + return; + } + @Override public String toString() { Set<ClassLoader> classLoaders; @@ -216,6 +245,7 @@ public class ClassLoaderManager { } } else { // this is mainly to support tests + log.info("No jar URL, this should only happen in tests! If this is not a test, this is probably a bug"); classLoader = parentClassLoader; }
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/MasterServerPluginContainer.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/MasterServerPluginContainer.java index a59d13b..382432e 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/MasterServerPluginContainer.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/MasterServerPluginContainer.java @@ -21,7 +21,6 @@ package org.rhq.enterprise.server.plugin.pc; import java.io.File; import java.net.URL; import java.util.ArrayList; -import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.List; @@ -225,6 +224,7 @@ public class MasterServerPluginContainer { ServerPluginDescriptorType descriptor = ServerPluginDescriptorUtil.loadPluginDescriptorFromUrl(pluginUrl); ServerPluginType pluginType = new ServerPluginType(descriptor); PluginKey pluginKey = PluginKey.createServerPluginKey(pluginType.stringify(), descriptor.getName()); + this.classLoaderManager.loadPlugin(pluginUrl, descriptor); ClassLoader classLoader = this.classLoaderManager.obtainServerPluginClassLoader(pluginKey); log.debug("Loading server plugin [" + pluginKey + "] from [" + pluginUrl + "] into its plugin container"); try { diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginManager.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginManager.java index 29726f9..acef4cf 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginManager.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginManager.java @@ -31,6 +31,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory;
import org.rhq.core.domain.configuration.Configuration; +import org.rhq.core.domain.plugin.PluginKey; import org.rhq.core.domain.plugin.ServerPlugin; import org.rhq.enterprise.server.plugin.ServerPluginsLocal; import org.rhq.enterprise.server.util.LookupUtil; @@ -264,8 +265,8 @@ public class ServerPluginManager {
/** * Informs the plugin manager that a plugin with the given name is to be unloaded. - * Once this method returns, the plugin's components are should no longer be created or used. - * + * The component's shutdown method will be called. + * * @param pluginName the name of the plugin to be unloaded * * @throws Exception if the plugin manager cannot unload the plugin @@ -305,6 +306,38 @@ public class ServerPluginManager { }
/** + * Informs the plugin manager that a plugin with the given name is to be unloaded. + * Once this method returns, the plugin's components should not be created or used. + * + * If <code>keepClassLoader</code> is <code>true</code>, this is the same as + * {@link #unloadPlugin(String)}. + * + * You want to keep the classloader if you are only temporarily unloading the plugin, and + * will load it back soon. + * + * Subclasses of this plugin manager class will normally not override this method; instead, + * they will typically want to override {@link #unloadPlugin(String)}. + * + * @param pluginName the name of the plugin to be unloaded + * @param keepClassLoader if <code>true</code> the classloader is not destroyed + * @throws Exception if the plugin manager cannot unload the plugin + */ + protected void unloadPlugin(String pluginName, boolean keepClassLoader) throws Exception { + try { + unloadPlugin(pluginName); + } finally { + if (!keepClassLoader) { + String pluginType = getParentPluginContainer().getSupportedServerPluginType().stringify(); + PluginKey pluginKey = PluginKey.createServerPluginKey(pluginType, pluginName); + MasterServerPluginContainer master = this.parentPluginContainer.getMasterServerPluginContainer(); + master.getClassLoaderManager().unloadPlugin(pluginKey); + } + } + + return; + } + + /** * This will reload a plugin allowing you to enable or disable it. * This will {@link #startPlugin(String) start the plugin component} if you enable it. * This will {@link #stopPlugin(String) stop the plugin component} if you disable it. @@ -331,7 +364,7 @@ public class ServerPluginManager { throw new IllegalArgumentException("Server plugin [" + pluginName + "] was never loaded, cannot enable it"); } stopPlugin(pluginName); // under normal circumstances, we should not need to do this, but just in case the plugin is somehow already started, stop it - unloadPlugin(pluginName); // unloading it will clean up old data and force the plugin context to reload if we later re-enable it + unloadPlugin(pluginName, true); // unloading it will clean up old data and force the plugin context to reload env = rebuildServerPluginEnvironment(env); try { // reload it in the enabled state. @@ -352,7 +385,7 @@ public class ServerPluginManager { throw new IllegalArgumentException("Server plugin [" + pluginName + "] was never loaded, cannot disable it"); } stopPlugin(pluginName); - unloadPlugin(pluginName); // unloading it will clean up old data and force the plugin context to reload if we later re-enable it + unloadPlugin(pluginName, true); // unloading it will clean up old data and force the plugin context to reload if we later re-enable it env = rebuildServerPluginEnvironment(env); loadPlugin(env, false); // re-load it in the disabled state return; diff --git a/modules/enterprise/server/xml-schemas/src/main/java/org/rhq/enterprise/server/xmlschema/ServerPluginDescriptorMetadataParser.java b/modules/enterprise/server/xml-schemas/src/main/java/org/rhq/enterprise/server/xmlschema/ServerPluginDescriptorMetadataParser.java index 4c16fee..637c609 100644 --- a/modules/enterprise/server/xml-schemas/src/main/java/org/rhq/enterprise/server/xmlschema/ServerPluginDescriptorMetadataParser.java +++ b/modules/enterprise/server/xml-schemas/src/main/java/org/rhq/enterprise/server/xmlschema/ServerPluginDescriptorMetadataParser.java @@ -76,11 +76,35 @@ public class ServerPluginDescriptorMetadataParser { throw new IllegalArgumentException("Missing plugin component classname for plugin " + descriptor.getName()); }
- String pkg = descriptor.getPackage(); - if ((className.indexOf('.') == -1) && (pkg != null)) { - className = pkg + '.' + className; - } + className = getFullyQualifiedClassName(descriptor, className); + + return className; + }
+ /** + * Given a plugn descriptor that may or may not have defined a {@link ServerPluginDescriptorType#getPackage() package name}, + * this converts the given class name to a fully qualified class name. + * + * If the descriptor does not define a package name, this method does nothing and returns <code>className</code> unchanged. + * + * If <code>className</code> contains at least one "." character, it is assumed to be already fully qualified and so it + * will be returned unchanged. + * + * If <code>className</code> has no "." characters, and the descriptor defines a package name, that package name + * will prefix the given class name and will form the fully qualified class name that is returned. + * + * @param descriptor a plugin descriptor that may or may not define a package name + * @param className a classname that may or may not be fully qualified + * @return the fully qualified class name or <code>null</code> if <code>className</code> is <code>null</code> + */ + public static String getFullyQualifiedClassName(ServerPluginDescriptorType descriptor, String className) { + + if (className != null) { + String pkg = (descriptor != null) ? descriptor.getPackage() : null; + if ((className.indexOf('.') == -1) && (pkg != null)) { + className = pkg + '.' + className; + } + } return className; }
commit 539f8d200cd707af27632e2dde547d5908492cf6 Merge: 96a82c7... 0206871... Author: Partha Aji paji@redhat.com Date: Wed Dec 9 15:24:59 2009 -0500
Merge branch 'master' into dumb
commit 112dbac1938cc6cc8cc9acf64f43655a65357cd9 Merge: 94d9e41... 0206871... Author: Heiko W. Rupp pilhuhn@fedorapeople.org Date: Wed Dec 9 21:14:39 2009 +0100
Merge branch 'master' into alertPlugin
commit 020687190fd6eba1b0c0f0da719d487b2c03b537 Merge: 114a890... 4f84d22... Author: Heiko W. Rupp pilhuhn@fedorapeople.org Date: Wed Dec 9 20:54:19 2009 +0100
Merge branch 'master' of ssh://git.fedorahosted.org/git/rhq/rhq
commit 114a89098cbc30c72dbab6a982499e4edef0cab5 Author: Heiko W. Rupp pilhuhn@fedorapeople.org Date: Wed Dec 9 20:53:20 2009 +0100
Small improvements in area of logging. Also don't reply to each message in the channel.
diff --git a/modules/enterprise/server/plugins/alert-irc/src/main/java/org/rhq/enterprise/server/plugins/alertIrc/IrcAlertComponent.java b/modules/enterprise/server/plugins/alert-irc/src/main/java/org/rhq/enterprise/server/plugins/alertIrc/IrcAlertComponent.java index e6bf730..f8716d6 100644 --- a/modules/enterprise/server/plugins/alert-irc/src/main/java/org/rhq/enterprise/server/plugins/alertIrc/IrcAlertComponent.java +++ b/modules/enterprise/server/plugins/alert-irc/src/main/java/org/rhq/enterprise/server/plugins/alertIrc/IrcAlertComponent.java @@ -71,8 +71,9 @@ public class IrcAlertComponent implements ServerPluginComponent {
try { this.ircBot.connect(server, port); + log.info("Connected to server " + server + ":" + port); } catch (Exception e) { - log.error("Error joining IRC", e); + log.error("Error joining IRC: " + e.getMessage());
return; } @@ -150,6 +151,9 @@ public class IrcAlertComponent implements ServerPluginComponent { public void onMessage(String channel, String sender, String login, String hostname, String message) {
+ if (!message.contains(nick)) + return; + if (this.response != null) { if (channel != null && channel.length() > 0) { sendMessage(channel, sender + ": " + this.response); diff --git a/modules/enterprise/server/plugins/alert-irc/src/main/java/org/rhq/enterprise/server/plugins/alertIrc/IrcSender.java b/modules/enterprise/server/plugins/alert-irc/src/main/java/org/rhq/enterprise/server/plugins/alertIrc/IrcSender.java index 34db27e..8cbd313 100644 --- a/modules/enterprise/server/plugins/alert-irc/src/main/java/org/rhq/enterprise/server/plugins/alertIrc/IrcSender.java +++ b/modules/enterprise/server/plugins/alert-irc/src/main/java/org/rhq/enterprise/server/plugins/alertIrc/IrcSender.java @@ -41,13 +41,15 @@ public class IrcSender extends AlertSender<IrcAlertComponent> { public SenderResult send(Alert alert) { SenderResult result; String channel = this.alertParameters.getSimpleValue("channel", null); + String server = preferences.getSimpleValue("server","-not set-"); + String chan = "irc://" + server + "/" + channel;
try { this.pluginComponent.sendIrcMessage(channel, getIrcMessage(alert)); - result = new SenderResult(ResultState.SUCCESS, "IRC Alert sent."); + result = new SenderResult(ResultState.SUCCESS, "IRC Alert sent to channel [" + chan + "]."); } catch (IllegalStateException e) { - log.error(e.getMessage(), e); - result = new SenderResult(ResultState.FAILURE, "IRC Alert failed!"); + log.error(e.getMessage()); + result = new SenderResult(ResultState.FAILURE, "IRC Alert to [" + chan + "] failed! " + e.getMessage()); }
return result; @@ -62,6 +64,8 @@ public class IrcSender extends AlertSender<IrcAlertComponent> { b.append(alert.getAlertDefinition().getResource().getName()); b.append("): "); b.append(alertManager.prettyPrintAlertURL(alert)); + b.append("\n"); + b.append(alertManager.prettyPrintAlertConditions(alert));
return b.toString(); }
commit 96a82c7ae46062101ea86afa00a412c6aa0c3abf Merge: 7991598... 4f84d22... Author: Partha Aji paji@redhat.com Date: Wed Dec 9 13:41:44 2009 -0500
Fixed merge conflicts
diff --cc modules/enterprise/server/plugins/pom.xml index 2c6472a,d1390e4..1e6a3d7 --- a/modules/enterprise/server/plugins/pom.xml +++ b/modules/enterprise/server/plugins/pom.xml @@@ -41,8 -39,8 +41,9 @@@ <module>yum</module> <module>url</module> <module>rhnhosted</module> + <module>perspectives/core</module> <module>alert-email</module> + <module>alert-irc</module> <module>alert-mobicents</module> <module>alert-microblog</module> <module>alert-roles</module>
commit 4c42a3cfd26575ff207577045e261f3fb8db4bed Author: Heiko W. Rupp pilhuhn@fedorapeople.org Date: Wed Dec 9 19:12:54 2009 +0100
Better handling of invalid input
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSenderPluginManager.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSenderPluginManager.java index 68b4241..e29e9b5 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSenderPluginManager.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSenderPluginManager.java @@ -163,8 +163,13 @@ public class AlertSenderPluginManager extends ServerPluginManager { */ public AlertSender getAlertSenderForNotification(AlertNotification notification) {
- String className = pluginClassByName.get(notification.getSenderName()); - ServerPluginEnvironment env = pluginEnvByName.get(notification.getSenderName()); + String senderName = notification.getSenderName(); + String className = pluginClassByName.get(senderName); + if (className==null) { + log.error("getAlertSender: No pluginClass found for sender: " + senderName); + return null; + } + ServerPluginEnvironment env = pluginEnvByName.get(senderName); Class clazz; try { clazz = Class.forName(className,true,env.getPluginClassLoader());
commit 4f84d2261465ba5b97b1c4ca127722791232107c Author: John Mazzitelli mazz@redhat.com Date: Wed Dec 9 12:18:01 2009 -0500
remove apt plugin source from eclise project
diff --git a/.classpath b/.classpath index c62026e..be48500 100644 --- a/.classpath +++ b/.classpath @@ -93,11 +93,9 @@ <classpathentry kind="src" path="modules/plugins/cron/src/main/java"/> <classpathentry kind="src" path="modules/plugins/hudson/src/main/java"/> <classpathentry kind="src" path="modules/plugins/platform/src/test/java"/> - <classpathentry kind="src" path="modules/plugins/apt/src/main/java"/> - <classpathentry kind="src" path="modules/plugins/apt/src/test/java"/> <classpathentry kind="src" path="modules/plugins/hosts/src/main/java"/> <classpathentry kind="src" path="modules/plugins/hosts/src/test/java"/> - <classpathentry kind="src" path="modules/plugins/virt/src/main/java"/> + <classpathentry kind="src" path="modules/plugins/virt/src/main/java"/> <classpathentry kind="src" path="modules/plugins/aliases/src/main/java"/> <classpathentry kind="src" path="modules/plugins/aliases/src/test/java"/> <classpathentry kind="src" path="modules/plugins/snmptrapd/src/main/java"/>
commit 6dac97c6bd83b481f67c62bbecd6ec0321dc5343 Merge: 47b1f89... 4d4d44e... Author: John Mazzitelli mazz@redhat.com Date: Wed Dec 9 11:30:44 2009 -0500
merged pc into master. fixed conflict in ServerPluginsLocal.java
diff --cc modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsLocal.java index f4bbb7b,7951af5..90bed89 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsLocal.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsLocal.java @@@ -147,15 -147,15 +147,15 @@@ public interface ServerPluginsLocal List<PluginKey> purgeServerPlugins(Subject subject, List<Integer> pluginIds) throws Exception;
/** - * Turns on or off the enabled flag in the database but does NOT restart the server plugin container. + * Turns on or off the enabled flag in the database but does NOT restart the server plugin. * This has "requires new" semantics, so the results are committed immediately upon return. - * + * * @param subject user making the request - * @param pluginIds the plugins to be enabled - * @param enabled the value of the enabled flag for the plugins - * @throws if failed to update a plugin + * @param pluginId the plugin to be enabled + * @param enabled the value of the enabled flag for the plugin + * @throws if failed to update the plugin */ - void setServerPluginEnabledFlag(Subject subject, List<Integer> pluginIds, boolean enabled) throws Exception; + void setServerPluginEnabledFlag(Subject subject, int pluginId, boolean enabled) throws Exception;
/** * Sets the status flag in the database but does NOT restart the server plugin container.
commit 47b1f89bc187679de4b23ce5b0393d8ebaab1730 Author: Jason Dobies jason.dobies@redhat.com Date: Wed Dec 9 10:53:51 2009 -0500
Moved apt plugin to etc, it's not supported enough to treat as a formal plugin.
diff --git a/etc/apt/pom.xml b/etc/apt/pom.xml new file mode 100644 index 0000000..47da3e5 --- /dev/null +++ b/etc/apt/pom.xml @@ -0,0 +1,199 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.rhq</groupId> + <artifactId>rhq-plugins-parent</artifactId> + <version>1.4.0-SNAPSHOT</version> + </parent> + + <groupId>org.rhq</groupId> + <artifactId>rhq-apt-plugin</artifactId> + <packaging>jar</packaging> + + <name>RHQ Apt Plugin</name> + <description>A plugin for managing the apt based features</description> + + <scm> + <connection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/modules/plugins/apt</connection> + <developerConnection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/modules/plugins/apt</developerConnection> + </scm> + + <properties> + <scm.module.path>modules/plugins/apt/</scm.module.path> + </properties> + + <dependencies> + + <dependency> + <groupId>net.augeas</groupId> + <artifactId>augeas</artifactId> + <version>0.0.1</version> + </dependency> + + <dependency> + <groupId>com.sun.jna</groupId> + <artifactId>jna</artifactId> + <version>3.0.1</version> + </dependency> + + </dependencies> + + <profiles> + <profile> + <id>integration-tests</id> + <activation> + <property> + <name>maven.test.skip</name> + <value>!true</value> + </property> + </activation> + + <build> + <plugins> + <plugin> + <artifactId>maven-antrun-plugin</artifactId> + <executions> + <execution> + <phase>pre-integration-test</phase> + <configuration> + <tasks> + <echo>Setting up plugin dependencies for ${project.artifactId}-${project.version}.jar... + </echo> + <property name="settings.localRepository" location="${user.home}/.m2/repository" /> + <mkdir dir="target/itest" /> + <mkdir dir="target/itest/plugins" /> + <mkdir dir="target/itest/lib" /> + <copy toDir="target/itest/plugins" flatten="true"> + <fileset dir="${settings.localRepository}/"> + <include name="org/rhq/rhq-platform-plugin/${project.version}/rhq-platform-plugin-${project.version}.jar" /> + </fileset> + <fileset dir="${project.build.directory}"> + <include name="${project.artifactId}-${project.version}.jar" /> + </fileset> + </copy> + <unzip dest="target/itest/lib"> + <fileset dir="${settings.localRepository}/org/hyperic/sigar-dist/${sigar.version}" includes="*.zip" /> + <patternset> + <include name="**/lib/sigar.jar" /> + <include name="**/lib/bcel*.jar" /> + <include name="**/lib/*.so" /> + <include name="**/lib/*.sl" /> + <include name="**/lib/*.dll" /> + <include name="**/lib/*.dylib" /> + </patternset> + </unzip> + <move todir="target/itest/lib" flatten="true"> + <fileset dir="target/itest/lib"> + <include name="**/lib/*" /> + </fileset> + </move> + <delete dir="target/itest/lib/hyperic-sigar-${sigar.version}" /> + </tasks> + </configuration> + <goals> + <goal>run</goal> + </goals> + </execution> + </executions> + </plugin> + + <!-- Integration testing voodoo to load and test this plugin with its plugin dependencies --> + <plugin> + <artifactId>maven-surefire-plugin</artifactId> + <configuration> + <skip>true</skip> + </configuration> + <executions> + <execution> + <id>surefire-it</id> + <phase>integration-test</phase> + <goals> + <goal>test</goal> + </goals> + <configuration> + <skip>${maven.test.skip}</skip> + <excludedGroups>${rhq.testng.excludedGroups}</excludedGroups> + <useSystemClassLoader>false</useSystemClassLoader> + <argLine>-Dorg.hyperic.sigar.path=${basedir}/target/itest/lib</argLine> + <!--<argLine>-Dorg.hyperic.sigar.path=${basedir}/target/itest/lib -Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=y</argLine>--> + <systemProperties> + <property> + <name>project.artifactId</name> + <value>${project.artifactId}</value> + </property> + <property> + <name>project.version</name> + <value>${project.version}</value> + </property> + </systemProperties> + </configuration> + </execution> + </executions> + </plugin> + + </plugins> + </build> + </profile> + + <profile> + <id>dev</id> + + <properties> + <rhq.rootDir>../../..</rhq.rootDir> + <rhq.containerDir>${rhq.rootDir}/${rhq.defaultDevContainerPath}</rhq.containerDir> + <rhq.deploymentDir> + ${rhq.containerDir}/jbossas/server/default/deploy/${rhq.earName}/rhq-downloads/rhq-plugins + </rhq.deploymentDir> + </properties> + + <build> + <plugins> + + <plugin> + <artifactId>maven-antrun-plugin</artifactId> + <version>1.1</version> + <executions> + + <execution> + <id>deploy</id> + <!--<phase>compile</phase>--> + <configuration> + <tasks> + <mkdir dir="${rhq.deploymentDir}" /> + <property name="deployment.file" location="${rhq.deploymentDir}/${project.build.finalName}.jar" /> + <echo>*** Updating ${deployment.file}...</echo> + <jar destfile="${deployment.file}" basedir="${project.build.outputDirectory}" /> + </tasks> + </configuration> + <goals> + <goal>run</goal> + </goals> + </execution> + + <execution> + <id>undeploy</id> + <!--<phase>clean</phase>--> + <configuration> + <tasks> + <property name="deployment.file" location="${rhq.deploymentDir}/${project.build.finalName}.jar" /> + <echo>*** Deleting ${deployment.file}...</echo> + <delete file="${deployment.file}" /> + </tasks> + </configuration> + <goals> + <goal>run</goal> + </goals> + </execution> + + </executions> + </plugin> + + </plugins> + </build> + </profile> + + </profiles> + +</project> diff --git a/etc/apt/src/main/java/org/rhq/plugins/apt/AptSourcesComponent.java b/etc/apt/src/main/java/org/rhq/plugins/apt/AptSourcesComponent.java new file mode 100644 index 0000000..905caa6 --- /dev/null +++ b/etc/apt/src/main/java/org/rhq/plugins/apt/AptSourcesComponent.java @@ -0,0 +1,144 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2008 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.plugins.apt; + +import java.io.File; +import java.util.Date; +import java.util.List; + +import net.augeas.Augeas; + +import org.rhq.core.domain.configuration.Configuration; +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.measurement.AvailabilityType; +import org.rhq.core.pluginapi.configuration.ConfigurationFacet; +import org.rhq.core.pluginapi.configuration.ConfigurationUpdateReport; +import org.rhq.core.pluginapi.inventory.InvalidPluginConfigurationException; +import org.rhq.core.pluginapi.inventory.ResourceComponent; +import org.rhq.core.pluginapi.inventory.ResourceContext; + +/** + * @author Jason Dobies + */ +public class AptSourcesComponent implements ResourceComponent, ConfigurationFacet { + + private ResourceContext resourceContext; + private File aptSourcesFile; + + public void start(ResourceContext resourceContext) throws InvalidPluginConfigurationException, Exception { + this.resourceContext = resourceContext; + + Configuration pluginConfiguration = resourceContext.getPluginConfiguration(); + + PropertySimple aptSourcesPathProperty = pluginConfiguration.getSimple("apt-sources-path"); + + if (aptSourcesPathProperty == null) { + throw new InvalidPluginConfigurationException( + "Apt sources not found in the plugin configuration, cannot start resource component"); + } + + String aptSourcesPath = aptSourcesPathProperty.getStringValue(); + + aptSourcesFile = new File(aptSourcesPath); + + if (!aptSourcesFile.exists()) { + throw new InvalidPluginConfigurationException("Apt sources file not found at specified location: " + + aptSourcesPath); + } + } + + public void stop() { + } + + public AvailabilityType getAvailability() { + if (aptSourcesFile == null) { + return AvailabilityType.DOWN; + } + + return aptSourcesFile.exists() ? AvailabilityType.UP : AvailabilityType.DOWN; + } + + public Configuration loadResourceConfiguration() throws Exception { + Configuration pluginConfiguration = resourceContext.getPluginConfiguration(); + + return loadResourceConfiguration(pluginConfiguration); + } + + public Configuration loadResourceConfiguration(Configuration pluginConfiguration) throws Exception { + // Gather data necessary to create the Augeas hook + PropertySimple lensesPathProperty = pluginConfiguration.getSimple("lenses-path"); + + if (lensesPathProperty == null) { + throw new Exception("Lenses path not found in plugin configuration, cannot retrieve configuration"); + } + + PropertySimple rootPathProperty = pluginConfiguration.getSimple("root-path"); + + if (rootPathProperty == null) { + throw new Exception("Root path not found in plugin configuration, cannot retrieve configuration"); + } + + String lensesPath = lensesPathProperty.getStringValue(); + String rootPath = rootPathProperty.getStringValue(); + + Augeas augeas = new Augeas(rootPath, lensesPath, Augeas.NONE); + + // Find out where to look for the apt sources tree + PropertySimple augeasTreeNodeProperty = pluginConfiguration.getSimple("augeas-apt-sources-path"); + + if (augeasTreeNodeProperty == null) { + throw new Exception("Augeas tree node not specified for apt sources, cannot retrive configuration"); + } + + String sourcesTreeNode = augeasTreeNodeProperty.getStringValue(); + + // Request data from augeas + List<String> matches = augeas.match(sourcesTreeNode); + if (matches.size() == 0) { + throw new Exception("Unable to load apt sources data from augeas"); + } + + // Parse out the properties + Configuration configuration = new Configuration(); + configuration.setNotes("Loaded from Augeas at " + new Date()); + + PropertyList entriesList = new PropertyList("aptEntries"); + configuration.put(entriesList); + + for (String entryNode : matches) { + String type = augeas.get(entryNode + "/type"); + String uri = augeas.get(entryNode + "/uri"); + String distribution = augeas.get(entryNode + "/distribution"); + + PropertyMap entry = new PropertyMap("aptEntry"); + entry.put(new PropertySimple("type", type)); + entry.put(new PropertySimple("uri", uri)); + entry.put(new PropertySimple("distribution", distribution)); + + entriesList.add(entry); + } + + return configuration; + } + + public void updateResourceConfiguration(ConfigurationUpdateReport report) { + } +} diff --git a/etc/apt/src/main/java/org/rhq/plugins/apt/AptSourcesDiscoveryComponent.java b/etc/apt/src/main/java/org/rhq/plugins/apt/AptSourcesDiscoveryComponent.java new file mode 100644 index 0000000..6ff3691 --- /dev/null +++ b/etc/apt/src/main/java/org/rhq/plugins/apt/AptSourcesDiscoveryComponent.java @@ -0,0 +1,50 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2008 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.plugins.apt; + +import java.io.File; +import java.util.HashSet; +import java.util.Set; +import org.rhq.core.pluginapi.inventory.DiscoveredResourceDetails; +import org.rhq.core.pluginapi.inventory.InvalidPluginConfigurationException; +import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent; +import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext; + +/** + * @author Jason Dobies + */ +public class AptSourcesDiscoveryComponent implements ResourceDiscoveryComponent { + + public Set discoverResources(ResourceDiscoveryContext resourceDiscoveryContext) throws InvalidPluginConfigurationException, Exception { + + Set<DiscoveredResourceDetails> details = new HashSet<DiscoveredResourceDetails>(); + + File sourcesFile = new File("/etc/apt/sources.list"); + + if (sourcesFile.exists()) { + DiscoveredResourceDetails resource = + new DiscoveredResourceDetails(resourceDiscoveryContext.getResourceType(), "apt-sources", "Apt Sources Service", + "1.0", "Apt sources in use on the machine.", null, null); + + details.add(resource); + } + + return details; + } +} diff --git a/etc/apt/src/main/resources/META-INF/rhq-plugin.xml b/etc/apt/src/main/resources/META-INF/rhq-plugin.xml new file mode 100644 index 0000000..a749435 --- /dev/null +++ b/etc/apt/src/main/resources/META-INF/rhq-plugin.xml @@ -0,0 +1,48 @@ +<plugin name="Apt" + displayName="Apt" + description="Support for apt configuration" + package="org.rhq.plugins.apt" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns="urn:xmlns:rhq-plugin" + xmlns:c="urn:xmlns:rhq-configuration"> + + <depends plugin="Augeas"/> + + <server name="Apt Sources" + description="Package list for APT" + discovery="AptSourcesDiscoveryComponent" + class="AptSourcesComponent"> + + <plugin-configuration> + <c:group name="augeas" displayName="Augeas Settings"> + <c:simple-property name="lenses-path" displayName="Augeas Lenses Path" + default="/usr/local/share/augeas/lenses" required="true" + description="Full path to the augeas lenses directory. Example: /usr/local/share/augeas/lenses"/> + <c:simple-property name="root-path" displayName="Augeas Root Path" default="/" required="true" + description="Path from which augeas should begin to search for configuration files. Example: /"/> + </c:group> + <c:group name="apt" displayName="Apt Settings"> + <c:simple-property name="apt-sources-path" displayName="Apt Sources File Path" required="true" + default="/etc/apt/sources.list" description="Location of the apt sources file."/> + <c:simple-property name="augeas-apt-sources-path" displayName="Augeas Apt Sources Tree Path" required="true" + default="/files/etc/apt/sources.list/*" description="Augeas tree location of the apt sources configuration values."/> + </c:group> + </plugin-configuration> + + <resource-configuration> + + <c:list-property name="aptEntries"> + <c:map-property name="aptEntry"> + <c:simple-property name="type" displayName="Type" type="string" required="true" activationPolicy="restart" + description="Type of packages found in the source, typically binaries v. source."/> + <c:simple-property name="uri" displayName="URI" type="string" required="true" activationPolicy="restart" + description="Location of the repository."/> + <c:simple-property name="distribution" displayName="Distribution" type="string" required="true" activationPolicy="restart"/> + </c:map-property> + </c:list-property> + </resource-configuration> + + + </server> + +</plugin> \ No newline at end of file diff --git a/etc/apt/src/test/java/org/rhq/plugins/apt/AptSourcesComponentTest.java b/etc/apt/src/test/java/org/rhq/plugins/apt/AptSourcesComponentTest.java new file mode 100644 index 0000000..c5c1b2e --- /dev/null +++ b/etc/apt/src/test/java/org/rhq/plugins/apt/AptSourcesComponentTest.java @@ -0,0 +1,93 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2008 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.plugins.apt; + +import java.util.Collection; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.testng.annotations.BeforeSuite; +import org.testng.annotations.Test; + +import org.rhq.core.domain.configuration.Configuration; +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; + +/** + * @author Jason Dobies + */ +@Test(groups = "apt-plugin") +public class AptSourcesComponentTest { + + private AptSourcesComponent component = new AptSourcesComponent(); + + private Configuration pluginConfiguration = new Configuration(); + + private final Log log = LogFactory.getLog(this.getClass()); + + @BeforeSuite + public void initPluginConfiguration() throws Exception { + pluginConfiguration.put(new PropertySimple("lenses-path", "/usr/local/share/augeas/lenses")); + pluginConfiguration.put(new PropertySimple("root-path", "/")); + pluginConfiguration.put(new PropertySimple("apt-sources-path", "/etc/apt/sources.list")); + pluginConfiguration.put(new PropertySimple("augeas-apt-sources-path", "/files/etc/apt/sources.list/*")); + } + + public void loadResourceConfiguration() throws Exception { + // Just bail because this test wont work yet + if (true) { + return; + } + Configuration configuration; + try { + configuration = component.loadResourceConfiguration(pluginConfiguration); + } catch (UnsatisfiedLinkError ule) { + // Skip tests if augeas not available + return; + } + + assert configuration != null : "Null configuration returned from load call"; + + Collection<Property> allProperties = configuration.getProperties(); + + assert allProperties.size() == 1 : "Incorrect number of properties found. Expected: 1, Found: " + + allProperties.size(); + + PropertyList entryList = (PropertyList) allProperties.iterator().next(); + + for (Property property : entryList.getList()) { + PropertyMap entry = (PropertyMap) property; + + Property typeProperty = entry.get("type"); + Property uriProperty = entry.get("uri"); + Property distributionProperty = entry.get("distribution"); + + assert typeProperty != null : "Type was null in entry"; + assert uriProperty != null : "URI was null in entry"; + assert distributionProperty != null : "Distribution was null in entry"; + + log.info("Type: " + ((PropertySimple) typeProperty).getStringValue()); + log.info("URI: " + ((PropertySimple) uriProperty).getStringValue()); + log.info("Distribution: " + ((PropertySimple) distributionProperty).getStringValue()); + } + + } +} diff --git a/etc/apt/src/test/resources/log4j.xml b/etc/apt/src/test/resources/log4j.xml new file mode 100644 index 0000000..ef41b92 --- /dev/null +++ b/etc/apt/src/test/resources/log4j.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"> + +<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="true"> + + <appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender"> + <param name="Target" value="System.out"/> + <param name="Threshold" value="DEBUG"/> + + <layout class="org.apache.log4j.PatternLayout"> + <!-- The default pattern: Date Priority [Category] Messagen --> + + <param name="ConversionPattern" value="%d{ABSOLUTE} %-5p [%c{1}] %m%n"/> + </layout> + </appender> + + <appender name="FILE" class="org.apache.log4j.RollingFileAppender"> + <param name="File" value="target/test.log"/> + <param name="Threshold" value="DEBUG"/> + <param name="Append" value="false"/> + + <layout class="org.apache.log4j.PatternLayout"> + <param name="ConversionPattern" value="%-5p %d{dd-MM HH:mm:ss,SSS} (%F:%M:%L) -%m%n"/> + </layout> + </appender> + + <root> + <appender-ref ref="CONSOLE"/> + <appender-ref ref="FILE"/> + </root> + +</log4j:configuration> diff --git a/modules/plugins/apt/pom.xml b/modules/plugins/apt/pom.xml deleted file mode 100644 index 47da3e5..0000000 --- a/modules/plugins/apt/pom.xml +++ /dev/null @@ -1,199 +0,0 @@ -<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> - - <modelVersion>4.0.0</modelVersion> - - <parent> - <groupId>org.rhq</groupId> - <artifactId>rhq-plugins-parent</artifactId> - <version>1.4.0-SNAPSHOT</version> - </parent> - - <groupId>org.rhq</groupId> - <artifactId>rhq-apt-plugin</artifactId> - <packaging>jar</packaging> - - <name>RHQ Apt Plugin</name> - <description>A plugin for managing the apt based features</description> - - <scm> - <connection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/modules/plugins/apt</connection> - <developerConnection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/modules/plugins/apt</developerConnection> - </scm> - - <properties> - <scm.module.path>modules/plugins/apt/</scm.module.path> - </properties> - - <dependencies> - - <dependency> - <groupId>net.augeas</groupId> - <artifactId>augeas</artifactId> - <version>0.0.1</version> - </dependency> - - <dependency> - <groupId>com.sun.jna</groupId> - <artifactId>jna</artifactId> - <version>3.0.1</version> - </dependency> - - </dependencies> - - <profiles> - <profile> - <id>integration-tests</id> - <activation> - <property> - <name>maven.test.skip</name> - <value>!true</value> - </property> - </activation> - - <build> - <plugins> - <plugin> - <artifactId>maven-antrun-plugin</artifactId> - <executions> - <execution> - <phase>pre-integration-test</phase> - <configuration> - <tasks> - <echo>Setting up plugin dependencies for ${project.artifactId}-${project.version}.jar... - </echo> - <property name="settings.localRepository" location="${user.home}/.m2/repository" /> - <mkdir dir="target/itest" /> - <mkdir dir="target/itest/plugins" /> - <mkdir dir="target/itest/lib" /> - <copy toDir="target/itest/plugins" flatten="true"> - <fileset dir="${settings.localRepository}/"> - <include name="org/rhq/rhq-platform-plugin/${project.version}/rhq-platform-plugin-${project.version}.jar" /> - </fileset> - <fileset dir="${project.build.directory}"> - <include name="${project.artifactId}-${project.version}.jar" /> - </fileset> - </copy> - <unzip dest="target/itest/lib"> - <fileset dir="${settings.localRepository}/org/hyperic/sigar-dist/${sigar.version}" includes="*.zip" /> - <patternset> - <include name="**/lib/sigar.jar" /> - <include name="**/lib/bcel*.jar" /> - <include name="**/lib/*.so" /> - <include name="**/lib/*.sl" /> - <include name="**/lib/*.dll" /> - <include name="**/lib/*.dylib" /> - </patternset> - </unzip> - <move todir="target/itest/lib" flatten="true"> - <fileset dir="target/itest/lib"> - <include name="**/lib/*" /> - </fileset> - </move> - <delete dir="target/itest/lib/hyperic-sigar-${sigar.version}" /> - </tasks> - </configuration> - <goals> - <goal>run</goal> - </goals> - </execution> - </executions> - </plugin> - - <!-- Integration testing voodoo to load and test this plugin with its plugin dependencies --> - <plugin> - <artifactId>maven-surefire-plugin</artifactId> - <configuration> - <skip>true</skip> - </configuration> - <executions> - <execution> - <id>surefire-it</id> - <phase>integration-test</phase> - <goals> - <goal>test</goal> - </goals> - <configuration> - <skip>${maven.test.skip}</skip> - <excludedGroups>${rhq.testng.excludedGroups}</excludedGroups> - <useSystemClassLoader>false</useSystemClassLoader> - <argLine>-Dorg.hyperic.sigar.path=${basedir}/target/itest/lib</argLine> - <!--<argLine>-Dorg.hyperic.sigar.path=${basedir}/target/itest/lib -Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=y</argLine>--> - <systemProperties> - <property> - <name>project.artifactId</name> - <value>${project.artifactId}</value> - </property> - <property> - <name>project.version</name> - <value>${project.version}</value> - </property> - </systemProperties> - </configuration> - </execution> - </executions> - </plugin> - - </plugins> - </build> - </profile> - - <profile> - <id>dev</id> - - <properties> - <rhq.rootDir>../../..</rhq.rootDir> - <rhq.containerDir>${rhq.rootDir}/${rhq.defaultDevContainerPath}</rhq.containerDir> - <rhq.deploymentDir> - ${rhq.containerDir}/jbossas/server/default/deploy/${rhq.earName}/rhq-downloads/rhq-plugins - </rhq.deploymentDir> - </properties> - - <build> - <plugins> - - <plugin> - <artifactId>maven-antrun-plugin</artifactId> - <version>1.1</version> - <executions> - - <execution> - <id>deploy</id> - <!--<phase>compile</phase>--> - <configuration> - <tasks> - <mkdir dir="${rhq.deploymentDir}" /> - <property name="deployment.file" location="${rhq.deploymentDir}/${project.build.finalName}.jar" /> - <echo>*** Updating ${deployment.file}...</echo> - <jar destfile="${deployment.file}" basedir="${project.build.outputDirectory}" /> - </tasks> - </configuration> - <goals> - <goal>run</goal> - </goals> - </execution> - - <execution> - <id>undeploy</id> - <!--<phase>clean</phase>--> - <configuration> - <tasks> - <property name="deployment.file" location="${rhq.deploymentDir}/${project.build.finalName}.jar" /> - <echo>*** Deleting ${deployment.file}...</echo> - <delete file="${deployment.file}" /> - </tasks> - </configuration> - <goals> - <goal>run</goal> - </goals> - </execution> - - </executions> - </plugin> - - </plugins> - </build> - </profile> - - </profiles> - -</project> diff --git a/modules/plugins/apt/src/main/java/org/rhq/plugins/apt/AptSourcesComponent.java b/modules/plugins/apt/src/main/java/org/rhq/plugins/apt/AptSourcesComponent.java deleted file mode 100644 index 905caa6..0000000 --- a/modules/plugins/apt/src/main/java/org/rhq/plugins/apt/AptSourcesComponent.java +++ /dev/null @@ -1,144 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2008 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.plugins.apt; - -import java.io.File; -import java.util.Date; -import java.util.List; - -import net.augeas.Augeas; - -import org.rhq.core.domain.configuration.Configuration; -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.measurement.AvailabilityType; -import org.rhq.core.pluginapi.configuration.ConfigurationFacet; -import org.rhq.core.pluginapi.configuration.ConfigurationUpdateReport; -import org.rhq.core.pluginapi.inventory.InvalidPluginConfigurationException; -import org.rhq.core.pluginapi.inventory.ResourceComponent; -import org.rhq.core.pluginapi.inventory.ResourceContext; - -/** - * @author Jason Dobies - */ -public class AptSourcesComponent implements ResourceComponent, ConfigurationFacet { - - private ResourceContext resourceContext; - private File aptSourcesFile; - - public void start(ResourceContext resourceContext) throws InvalidPluginConfigurationException, Exception { - this.resourceContext = resourceContext; - - Configuration pluginConfiguration = resourceContext.getPluginConfiguration(); - - PropertySimple aptSourcesPathProperty = pluginConfiguration.getSimple("apt-sources-path"); - - if (aptSourcesPathProperty == null) { - throw new InvalidPluginConfigurationException( - "Apt sources not found in the plugin configuration, cannot start resource component"); - } - - String aptSourcesPath = aptSourcesPathProperty.getStringValue(); - - aptSourcesFile = new File(aptSourcesPath); - - if (!aptSourcesFile.exists()) { - throw new InvalidPluginConfigurationException("Apt sources file not found at specified location: " - + aptSourcesPath); - } - } - - public void stop() { - } - - public AvailabilityType getAvailability() { - if (aptSourcesFile == null) { - return AvailabilityType.DOWN; - } - - return aptSourcesFile.exists() ? AvailabilityType.UP : AvailabilityType.DOWN; - } - - public Configuration loadResourceConfiguration() throws Exception { - Configuration pluginConfiguration = resourceContext.getPluginConfiguration(); - - return loadResourceConfiguration(pluginConfiguration); - } - - public Configuration loadResourceConfiguration(Configuration pluginConfiguration) throws Exception { - // Gather data necessary to create the Augeas hook - PropertySimple lensesPathProperty = pluginConfiguration.getSimple("lenses-path"); - - if (lensesPathProperty == null) { - throw new Exception("Lenses path not found in plugin configuration, cannot retrieve configuration"); - } - - PropertySimple rootPathProperty = pluginConfiguration.getSimple("root-path"); - - if (rootPathProperty == null) { - throw new Exception("Root path not found in plugin configuration, cannot retrieve configuration"); - } - - String lensesPath = lensesPathProperty.getStringValue(); - String rootPath = rootPathProperty.getStringValue(); - - Augeas augeas = new Augeas(rootPath, lensesPath, Augeas.NONE); - - // Find out where to look for the apt sources tree - PropertySimple augeasTreeNodeProperty = pluginConfiguration.getSimple("augeas-apt-sources-path"); - - if (augeasTreeNodeProperty == null) { - throw new Exception("Augeas tree node not specified for apt sources, cannot retrive configuration"); - } - - String sourcesTreeNode = augeasTreeNodeProperty.getStringValue(); - - // Request data from augeas - List<String> matches = augeas.match(sourcesTreeNode); - if (matches.size() == 0) { - throw new Exception("Unable to load apt sources data from augeas"); - } - - // Parse out the properties - Configuration configuration = new Configuration(); - configuration.setNotes("Loaded from Augeas at " + new Date()); - - PropertyList entriesList = new PropertyList("aptEntries"); - configuration.put(entriesList); - - for (String entryNode : matches) { - String type = augeas.get(entryNode + "/type"); - String uri = augeas.get(entryNode + "/uri"); - String distribution = augeas.get(entryNode + "/distribution"); - - PropertyMap entry = new PropertyMap("aptEntry"); - entry.put(new PropertySimple("type", type)); - entry.put(new PropertySimple("uri", uri)); - entry.put(new PropertySimple("distribution", distribution)); - - entriesList.add(entry); - } - - return configuration; - } - - public void updateResourceConfiguration(ConfigurationUpdateReport report) { - } -} diff --git a/modules/plugins/apt/src/main/java/org/rhq/plugins/apt/AptSourcesDiscoveryComponent.java b/modules/plugins/apt/src/main/java/org/rhq/plugins/apt/AptSourcesDiscoveryComponent.java deleted file mode 100644 index 6ff3691..0000000 --- a/modules/plugins/apt/src/main/java/org/rhq/plugins/apt/AptSourcesDiscoveryComponent.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2008 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.plugins.apt; - -import java.io.File; -import java.util.HashSet; -import java.util.Set; -import org.rhq.core.pluginapi.inventory.DiscoveredResourceDetails; -import org.rhq.core.pluginapi.inventory.InvalidPluginConfigurationException; -import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent; -import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext; - -/** - * @author Jason Dobies - */ -public class AptSourcesDiscoveryComponent implements ResourceDiscoveryComponent { - - public Set discoverResources(ResourceDiscoveryContext resourceDiscoveryContext) throws InvalidPluginConfigurationException, Exception { - - Set<DiscoveredResourceDetails> details = new HashSet<DiscoveredResourceDetails>(); - - File sourcesFile = new File("/etc/apt/sources.list"); - - if (sourcesFile.exists()) { - DiscoveredResourceDetails resource = - new DiscoveredResourceDetails(resourceDiscoveryContext.getResourceType(), "apt-sources", "Apt Sources Service", - "1.0", "Apt sources in use on the machine.", null, null); - - details.add(resource); - } - - return details; - } -} diff --git a/modules/plugins/apt/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/apt/src/main/resources/META-INF/rhq-plugin.xml deleted file mode 100644 index a749435..0000000 --- a/modules/plugins/apt/src/main/resources/META-INF/rhq-plugin.xml +++ /dev/null @@ -1,48 +0,0 @@ -<plugin name="Apt" - displayName="Apt" - description="Support for apt configuration" - package="org.rhq.plugins.apt" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xmlns="urn:xmlns:rhq-plugin" - xmlns:c="urn:xmlns:rhq-configuration"> - - <depends plugin="Augeas"/> - - <server name="Apt Sources" - description="Package list for APT" - discovery="AptSourcesDiscoveryComponent" - class="AptSourcesComponent"> - - <plugin-configuration> - <c:group name="augeas" displayName="Augeas Settings"> - <c:simple-property name="lenses-path" displayName="Augeas Lenses Path" - default="/usr/local/share/augeas/lenses" required="true" - description="Full path to the augeas lenses directory. Example: /usr/local/share/augeas/lenses"/> - <c:simple-property name="root-path" displayName="Augeas Root Path" default="/" required="true" - description="Path from which augeas should begin to search for configuration files. Example: /"/> - </c:group> - <c:group name="apt" displayName="Apt Settings"> - <c:simple-property name="apt-sources-path" displayName="Apt Sources File Path" required="true" - default="/etc/apt/sources.list" description="Location of the apt sources file."/> - <c:simple-property name="augeas-apt-sources-path" displayName="Augeas Apt Sources Tree Path" required="true" - default="/files/etc/apt/sources.list/*" description="Augeas tree location of the apt sources configuration values."/> - </c:group> - </plugin-configuration> - - <resource-configuration> - - <c:list-property name="aptEntries"> - <c:map-property name="aptEntry"> - <c:simple-property name="type" displayName="Type" type="string" required="true" activationPolicy="restart" - description="Type of packages found in the source, typically binaries v. source."/> - <c:simple-property name="uri" displayName="URI" type="string" required="true" activationPolicy="restart" - description="Location of the repository."/> - <c:simple-property name="distribution" displayName="Distribution" type="string" required="true" activationPolicy="restart"/> - </c:map-property> - </c:list-property> - </resource-configuration> - - - </server> - -</plugin> \ No newline at end of file diff --git a/modules/plugins/apt/src/test/java/org/rhq/plugins/apt/AptSourcesComponentTest.java b/modules/plugins/apt/src/test/java/org/rhq/plugins/apt/AptSourcesComponentTest.java deleted file mode 100644 index c5c1b2e..0000000 --- a/modules/plugins/apt/src/test/java/org/rhq/plugins/apt/AptSourcesComponentTest.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2008 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.plugins.apt; - -import java.util.Collection; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.testng.annotations.BeforeSuite; -import org.testng.annotations.Test; - -import org.rhq.core.domain.configuration.Configuration; -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; - -/** - * @author Jason Dobies - */ -@Test(groups = "apt-plugin") -public class AptSourcesComponentTest { - - private AptSourcesComponent component = new AptSourcesComponent(); - - private Configuration pluginConfiguration = new Configuration(); - - private final Log log = LogFactory.getLog(this.getClass()); - - @BeforeSuite - public void initPluginConfiguration() throws Exception { - pluginConfiguration.put(new PropertySimple("lenses-path", "/usr/local/share/augeas/lenses")); - pluginConfiguration.put(new PropertySimple("root-path", "/")); - pluginConfiguration.put(new PropertySimple("apt-sources-path", "/etc/apt/sources.list")); - pluginConfiguration.put(new PropertySimple("augeas-apt-sources-path", "/files/etc/apt/sources.list/*")); - } - - public void loadResourceConfiguration() throws Exception { - // Just bail because this test wont work yet - if (true) { - return; - } - Configuration configuration; - try { - configuration = component.loadResourceConfiguration(pluginConfiguration); - } catch (UnsatisfiedLinkError ule) { - // Skip tests if augeas not available - return; - } - - assert configuration != null : "Null configuration returned from load call"; - - Collection<Property> allProperties = configuration.getProperties(); - - assert allProperties.size() == 1 : "Incorrect number of properties found. Expected: 1, Found: " - + allProperties.size(); - - PropertyList entryList = (PropertyList) allProperties.iterator().next(); - - for (Property property : entryList.getList()) { - PropertyMap entry = (PropertyMap) property; - - Property typeProperty = entry.get("type"); - Property uriProperty = entry.get("uri"); - Property distributionProperty = entry.get("distribution"); - - assert typeProperty != null : "Type was null in entry"; - assert uriProperty != null : "URI was null in entry"; - assert distributionProperty != null : "Distribution was null in entry"; - - log.info("Type: " + ((PropertySimple) typeProperty).getStringValue()); - log.info("URI: " + ((PropertySimple) uriProperty).getStringValue()); - log.info("Distribution: " + ((PropertySimple) distributionProperty).getStringValue()); - } - - } -} diff --git a/modules/plugins/apt/src/test/resources/log4j.xml b/modules/plugins/apt/src/test/resources/log4j.xml deleted file mode 100644 index ef41b92..0000000 --- a/modules/plugins/apt/src/test/resources/log4j.xml +++ /dev/null @@ -1,32 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"> - -<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="true"> - - <appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender"> - <param name="Target" value="System.out"/> - <param name="Threshold" value="DEBUG"/> - - <layout class="org.apache.log4j.PatternLayout"> - <!-- The default pattern: Date Priority [Category] Messagen --> - - <param name="ConversionPattern" value="%d{ABSOLUTE} %-5p [%c{1}] %m%n"/> - </layout> - </appender> - - <appender name="FILE" class="org.apache.log4j.RollingFileAppender"> - <param name="File" value="target/test.log"/> - <param name="Threshold" value="DEBUG"/> - <param name="Append" value="false"/> - - <layout class="org.apache.log4j.PatternLayout"> - <param name="ConversionPattern" value="%-5p %d{dd-MM HH:mm:ss,SSS} (%F:%M:%L) -%m%n"/> - </layout> - </appender> - - <root> - <appender-ref ref="CONSOLE"/> - <appender-ref ref="FILE"/> - </root> - -</log4j:configuration> diff --git a/modules/plugins/pom.xml b/modules/plugins/pom.xml index de81bb2..50f68bb 100644 --- a/modules/plugins/pom.xml +++ b/modules/plugins/pom.xml @@ -101,7 +101,6 @@
<!-- other, possibly experimental plugins --> <module>augeas</module> - <module>apt</module> <module>cron</module> <module>script</module> <module>grub</module>
commit 94d9e41f45e4e4743347c688a6e0d1dcee61cabd Author: Heiko W. Rupp pilhuhn@fedorapeople.org Date: Wed Dec 9 14:30:00 2009 +0100
Start working on template bundles of notifications.
diff --git a/modules/core/dbutils/src/main/scripts/dbsetup/alert-schema.xml b/modules/core/dbutils/src/main/scripts/dbsetup/alert-schema.xml index f9560c1..c9f03a8 100644 --- a/modules/core/dbutils/src/main/scripts/dbsetup/alert-schema.xml +++ b/modules/core/dbutils/src/main/scripts/dbsetup/alert-schema.xml @@ -133,4 +133,13 @@ <column name="ALERT_SENDER_NAME" required="false" type="VARCHAR2" /> <!-- TODO make required = true --> </table>
+ <table name="RHQ_ALERT_NOTIF_TEMPL" tablespace="@@@LARGE_TABLESPACE_FOR_DATA@@@" + storage-options="freelists 5" cache="true" logging="false"> + <column name="ID" default="sequence-only" initial="10001" + primarykey="true" required="true" type="INTEGER"/> + <column name="NAME" required="true" size="40" type="VARCHAR2"/> + <column name="DESCRIPTION" required="false" size="250" type="VARCHAR2"/> + + </table> + </dbsetup> diff --git a/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml b/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml index a2182a7..3441d9c 100644 --- a/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml +++ b/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml @@ -2222,6 +2222,20 @@ </schema-directSQL>
</schemaSpec> + <schemaSpec version="2.70.1"> + <schema-directSQL> + <statement> + CREATE TABLE RHQ_ALERT_NOTIF_TEMPL ( ID INTEGER ) + </statement> + <statement> + ALTER TABLE RHQ_ALERT_NOTIF_TEMPL + ADD CONSTRAINT RHQ_ALERT_NOTIF_TEMPL_KEY + PRIMARY KEY ( ID ) + </statement> + </schema-directSQL> + <schema-addColumn table="RHQ_ALERT_NOTIF_TEMPL" column="NAME" columnType="VARCHAR2"/> + <schema-addColumn table="RHQ_ALERT_NOTIF_TEMPL" column="DESCRIPTION" columnType="VARCHAR2"/> + </schemaSpec>
</dbupgrade> </target> diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/alert/notification/NotificationTemplate.java b/modules/core/domain/src/main/java/org/rhq/core/domain/alert/notification/NotificationTemplate.java new file mode 100644 index 0000000..acf795f --- /dev/null +++ b/modules/core/domain/src/main/java/org/rhq/core/domain/alert/notification/NotificationTemplate.java @@ -0,0 +1,123 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2009 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.core.domain.alert.notification; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.OneToMany; +import javax.persistence.SequenceGenerator; +import javax.persistence.Table; +import javax.persistence.Transient; + +/** + * A template that consists of multiple notifications. This can be used to create + * 'bundles' of preconfigured alert notifications which can then be applied to + * AlertDefinitions directly or via AlertTemplates. + * @author Heiko W. Rupp + */ +@Entity +@Table(name="RHQ_ALERT_NOTIF_TEMPL") +@SequenceGenerator(name="RHQ_ALERT_NOTIF_SEQ", sequenceName = "RHQ_ALERT_NOTIF_SEQ") +public class NotificationTemplate implements Serializable { + + @Column(name="ID", nullable = false) + @GeneratedValue(generator = "RHQ_ALERT_NOTIF_SEQ") + @Id + private int id; + + @Column(name="NAME") + private String name; + + @Column(name="DESCRIPTION") + private String description; + + + // @OneToMany(cascade = CascadeType.ALL) + @Transient + List<AlertNotification> notifications = new ArrayList<AlertNotification>(); + + protected NotificationTemplate() { + // for JPA + } + + public NotificationTemplate(String name, String description) { + this.name = name; + this.description = description; + } + + public int getId() { + return id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public List<AlertNotification> getNotifications() { + return notifications; + } + + public void setNotifications(List<AlertNotification> notifications) { + this.notifications = notifications; + } + + public List<AlertNotification> addNotification(AlertNotification notification) { + this.notifications.add(notification); + return this.notifications; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + NotificationTemplate that = (NotificationTemplate) o; + + if (description != null ? !description.equals(that.description) : that.description != null) return false; + if (!name.equals(that.name)) return false; + + return true; + } + + @Override + public int hashCode() { + int result = name.hashCode(); + result = 31 * result + (description != null ? description.hashCode() : 0); + return result; + } +} diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerBean.java index e948aac..89d1cc1 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerBean.java @@ -40,6 +40,7 @@ import org.rhq.core.domain.alert.AlertDefinition; import org.rhq.core.domain.alert.AlertDefinitionContext; import org.rhq.core.domain.alert.notification.AlertNotification; import org.rhq.core.domain.alert.notification.EmailNotification; +import org.rhq.core.domain.alert.notification.NotificationTemplate; import org.rhq.core.domain.alert.notification.RoleNotification; import org.rhq.core.domain.alert.notification.SnmpNotification; import org.rhq.core.domain.alert.notification.SubjectNotification; @@ -536,4 +537,21 @@ public class AlertNotificationManagerBean implements AlertNotificationManagerLoc } return result; } + + /** + * Take the passed NotificationTemplate and apply its Notifications to the passed AlertDefinition + * @param template NotificationTemplate to apply + * @param def AlertDefinition to apply the template to + * @param removeOldNotifications Shall old Notifications on the Definition be removed? + */ + public void applyNotificationTemplateToAlertDefinition(NotificationTemplate template, AlertDefinition def, boolean removeOldNotifications) { + + if (removeOldNotifications) + def.getAlertNotifications().clear(); + + for (AlertNotification notif : template.getNotifications()) { + def.addAlertNotification(notif.copy(false)); // Attach a copy, as the ones in the template should not be shared + } + + } } \ No newline at end of file diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerLocal.java index f67927f..7c458f4 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerLocal.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerLocal.java @@ -23,8 +23,10 @@ import java.util.List; import javax.ejb.Local;
import org.rhq.core.clientapi.descriptor.configuration.ConfigurationDescriptor; +import org.rhq.core.domain.alert.AlertDefinition; import org.rhq.core.domain.alert.notification.AlertNotification; import org.rhq.core.domain.alert.notification.EmailNotification; +import org.rhq.core.domain.alert.notification.NotificationTemplate; import org.rhq.core.domain.alert.notification.RoleNotification; import org.rhq.core.domain.alert.notification.SnmpNotification; import org.rhq.core.domain.alert.notification.SubjectNotification; @@ -109,4 +111,12 @@ public interface AlertNotificationManagerLocal { List<AlertNotification> getNotificationsForAlertDefinition(Subject user, int alertDefinitionId);
AlertSenderInfo getAlertInfoForSender(String shortName); + + /** + * Take the passed NotificationTemplate and apply its Notifications to the passed AlertDefinition + * @param template NotificationTemplate to apply + * @param def AlertDefinition to apply the template to + * @param removeOldNotifications Shall old Notifications on the Definition be removed? + */ + void applyNotificationTemplateToAlertDefinition(NotificationTemplate template, AlertDefinition def, boolean removeOldNotifications); } \ No newline at end of file
commit f75169ed996d5ae4fff104a0c2bb88734cdb6cbf Author: Heiko W. Rupp pilhuhn@fedorapeople.org Date: Wed Dec 9 09:23:51 2009 +0100
Enable irc alert sender
diff --git a/modules/enterprise/server/plugins/pom.xml b/modules/enterprise/server/plugins/pom.xml index 7be2d7a..d1390e4 100644 --- a/modules/enterprise/server/plugins/pom.xml +++ b/modules/enterprise/server/plugins/pom.xml @@ -40,6 +40,7 @@ <module>url</module> <module>rhnhosted</module> <module>alert-email</module> + <module>alert-irc</module> <module>alert-mobicents</module> <module>alert-microblog</module> <module>alert-roles</module>
commit 6a06285834519a20f91edc3d8e526a06c5b101ca Merge: 1f5b8ad... 254427c... Author: Heiko W. Rupp pilhuhn@fedorapeople.org Date: Wed Dec 9 09:18:11 2009 +0100
Merge branch 'alertPlugin'
commit 1f5b8ad2c49728a54ca655616f9072edbc697460 Author: John Mazzitelli mazz@redhat.com Date: Tue Dec 8 16:57:27 2009 -0500
#545595 - don't send up empty inventory reports and make sure the report has at least the platform plugin
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/AutoDiscoveryExecutor.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/AutoDiscoveryExecutor.java index a1394de..47b552d 100644 --- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/AutoDiscoveryExecutor.java +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/AutoDiscoveryExecutor.java @@ -204,6 +204,15 @@ public class AutoDiscoveryExecutor implements Runnable, Callable<InventoryReport log.error("Error in auto discovery", e); } } + + // if we have nothing, our plugins didn't discovery anything, but we want to at least report the platform + if (report.getAddedRoots().isEmpty()) { + if (platformContainer.getSynchronizationState() == ResourceContainer.SynchronizationState.NEW) { + report.addAddedRoot(platformResource); + } + } + + return; }
private List<ProcessScanResult> performProcessScans(List<ProcessInfo> processInfos, ResourceType serverType) { diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java index 873585b..82c0d51 100644 --- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java @@ -820,6 +820,10 @@ public class InventoryManager extends AgentService implements ContainerService, if (!configuration.isInsideAgent()) { return true; } + if (report.getAddedRoots().isEmpty()) { + return true; // nothing to do + } + ResourceSyncInfo syncInfo; try { String reportType = (report.isRuntimeReport()) ? "runtime" : "server";
commit 4d4d44e11ec0a6daae3a755ce0ba8c7135b8ae75 Author: John Mazzitelli mazz@redhat.com Date: Tue Dec 8 20:50:15 2009 -0500
be able to enable and disable plugins successfully. this fixes a few bugs
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/plugin/ServerPlugin.java b/modules/core/domain/src/main/java/org/rhq/core/domain/plugin/ServerPlugin.java index 0243c49..76c3207 100644 --- a/modules/core/domain/src/main/java/org/rhq/core/domain/plugin/ServerPlugin.java +++ b/modules/core/domain/src/main/java/org/rhq/core/domain/plugin/ServerPlugin.java @@ -230,10 +230,10 @@ import org.rhq.core.domain.configuration.Configuration; + " AND p.status = 'INSTALLED' "), //
// this query is how you enable and disable plugins - @NamedQuery(name = ServerPlugin.UPDATE_PLUGINS_ENABLED_BY_IDS, query = "" // + @NamedQuery(name = ServerPlugin.UPDATE_PLUGIN_ENABLED_BY_ID, query = "" // + "UPDATE ServerPlugin p " // + " SET p.enabled = :enabled " // - + " WHERE p.id IN (:ids)") + + " WHERE p.id = :id)")
}) @Entity @@ -250,7 +250,7 @@ public class ServerPlugin extends AbstractPlugin { public static final String QUERY_FIND_ALL_INSTALLED = "ServerPlugin.findAllInstalled"; public static final String QUERY_FIND_ALL_INSTALLED_KEYS = "ServerPlugin.findAllInstalledKeys"; public static final String QUERY_FIND_KEYS_BY_IDS = "ServerPlugin.findKeysByIds"; - public static final String UPDATE_PLUGINS_ENABLED_BY_IDS = "ServerPlugin.updatePluginsEnabledByIds"; + public static final String UPDATE_PLUGIN_ENABLED_BY_ID = "ServerPlugin.updatePluginEnabledById";
@JoinColumn(name = "JOBS_CONFIG_ID", referencedColumnName = "ID") @OneToOne(cascade = { CascadeType.ALL }, fetch = FetchType.LAZY) diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/InstalledPluginsUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/InstalledPluginsUIBean.java index 52fecb0..1fef765 100644 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/InstalledPluginsUIBean.java +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/InstalledPluginsUIBean.java @@ -38,6 +38,7 @@ import org.rhq.core.domain.auth.Subject; import org.rhq.core.domain.authz.Permission; import org.rhq.core.domain.plugin.AbstractPlugin; import org.rhq.core.domain.plugin.Plugin; +import org.rhq.core.domain.plugin.PluginKey; import org.rhq.core.domain.plugin.PluginStatusType; import org.rhq.core.domain.plugin.ServerPlugin; import org.rhq.core.gui.util.FacesContextUtility; @@ -158,7 +159,7 @@ public class InstalledPluginsUIBean {
for (ServerPlugin selectedPlugin : allSelectedPlugins) { if (!selectedPlugin.isEnabled() && selectedPlugin.getStatus() == PluginStatusType.INSTALLED) { - selectedPluginNames.add(selectedPlugin.getName()); + selectedPluginNames.add(selectedPlugin.getDisplayName()); pluginsToEnable.add(selectedPlugin); } } @@ -171,9 +172,30 @@ public class InstalledPluginsUIBean {
try { Subject subject = EnterpriseFacesContextUtility.getSubject(); - serverPluginsBean.enableServerPlugins(subject, getIds(pluginsToEnable)); - FacesContextUtility - .addMessage(FacesMessage.SEVERITY_INFO, "Enabled server plugins: " + selectedPluginNames); + List<PluginKey> enabled = serverPluginsBean.enableServerPlugins(subject, getIds(pluginsToEnable)); + if (enabled.size() == pluginsToEnable.size()) { + FacesContextUtility.addMessage(FacesMessage.SEVERITY_INFO, "Enabled server plugins: " + + selectedPluginNames); + } else { + List<String> enabledPlugins = new ArrayList<String>(); + List<String> failedPlugins = new ArrayList<String>(); + for (ServerPlugin pluginToEnable : pluginsToEnable) { + PluginKey key = PluginKey.createServerPluginKey(pluginToEnable.getType(), pluginToEnable.getName()); + if (enabled.contains(key)) { + enabledPlugins.add(pluginToEnable.getDisplayName()); + } else { + failedPlugins.add(pluginToEnable.getDisplayName()); + } + } + if (enabledPlugins.size() > 0) { + FacesContextUtility.addMessage(FacesMessage.SEVERITY_INFO, "Enabled server plugins: " + + enabledPlugins); + } + if (failedPlugins.size() > 0) { + FacesContextUtility.addMessage(FacesMessage.SEVERITY_ERROR, "Failed to enable server plugins: " + + failedPlugins); + } + } } catch (Exception e) { processException("Failed to enable server plugins", e); } @@ -187,7 +209,7 @@ public class InstalledPluginsUIBean {
for (ServerPlugin selectedPlugin : allSelectedPlugins) { if (selectedPlugin.isEnabled()) { - selectedPluginNames.add(selectedPlugin.getName()); + selectedPluginNames.add(selectedPlugin.getDisplayName()); pluginsToDisable.add(selectedPlugin); } } @@ -215,7 +237,7 @@ public class InstalledPluginsUIBean { List<ServerPlugin> pluginsToUndeploy = new ArrayList<ServerPlugin>(); for (ServerPlugin selectedPlugin : allSelectedPlugins) { if (selectedPlugin.getStatus() == PluginStatusType.INSTALLED) { - selectedPluginNames.add(selectedPlugin.getName()); + selectedPluginNames.add(selectedPlugin.getDisplayName()); pluginsToUndeploy.add(selectedPlugin); } } @@ -242,7 +264,7 @@ public class InstalledPluginsUIBean { List<String> selectedPluginNames = new ArrayList<String>();
for (ServerPlugin selectedPlugin : allSelectedPlugins) { - selectedPluginNames.add(selectedPlugin.getName()); + selectedPluginNames.add(selectedPlugin.getDisplayName()); }
if (selectedPluginNames.isEmpty()) { diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/startup/StartupServlet.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/startup/StartupServlet.java index 3407392..2697759 100644 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/startup/StartupServlet.java +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/startup/StartupServlet.java @@ -116,7 +116,7 @@ public class StartupServlet extends HttpServlet { // (that is, a scheduled job would more likely need to send a message; as opposed to an incoming message // causing a job to be scheduled), so that explains the ordering of the comm layer and the scheduler. startHibernateStatistics(); - startPluginDeployer(); + startPluginDeployer(); // make sure this is before starting the server plugin container startServerPluginContainer(); // before comm in case an agent wants to talk to it installJaasModules(); startServerCommunicationServices(); @@ -206,6 +206,9 @@ public class StartupServlet extends HttpServlet { * Starts the plugin deployer which will effectively ask the plugin deployer to persist information about all * detected agent and server plugins. * + * Because this will scan and register the initial plugins right now, make sure this is called prior + * to starting the master plugin container; otherwise, the master PC will not have any plugins to start. + * * @throws ServletException */ private void startPluginDeployer() throws ServletException { diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/plugin/PluginDeploymentScanner.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/plugin/PluginDeploymentScanner.java index 9b8df52..641d90e 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/plugin/PluginDeploymentScanner.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/plugin/PluginDeploymentScanner.java @@ -133,6 +133,8 @@ public class PluginDeploymentScanner implements PluginDeploymentScannerMBean { public void startDeployment() { // We are being called by the server's startup servlet which essentially informs us that // the server's internal EJB/SLSBs are ready and can be called. This means we are allowed to start. + // NOTE: Make sure we are called BEFORE the master plugin container is started! + this.agentPluginScanner.getAgentPluginDeployer().startDeployment();
// this is the runnable task that executes each scan period - it runs in our thread pool diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/plugin/ServerPluginScanner.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/plugin/ServerPluginScanner.java index 853ce9c..96cd3a2 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/plugin/ServerPluginScanner.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/plugin/ServerPluginScanner.java @@ -158,7 +158,7 @@ public class ServerPluginScanner { ComparableVersion version; // this must be non-null, the next line ensures this version = ServerPluginDescriptorUtil.getPluginVersion(pluginFile, descriptor);
- log.info("Registering RHQ server plugin [" + pluginName + "], version " + version); + log.debug("Registering server plugin [" + pluginName + "], version " + version);
ServerPlugin plugin = new ServerPlugin(pluginName, pluginFile.getName()); plugin.setDisplayName((displayName != null) ? displayName : pluginName); @@ -179,17 +179,23 @@ public class ServerPluginScanner { ServerPluginsLocal serverPluginsManager = LookupUtil.getServerPlugins();
// see if this plugin has been deleted previously; if so, don't register and delete the file - PluginStatusType status = serverPluginsManager.getServerPluginStatus(new PluginKey(plugin)); + PluginKey newPluginKey = new PluginKey(plugin); + PluginStatusType status = serverPluginsManager.getServerPluginStatus(newPluginKey); + if (PluginStatusType.DELETED == status) { log.warn("Plugin file [" + pluginFile + "] has been detected but that plugin with name [" + pluginName + "] was previously undeployed. Will not re-register that plugin and the file will be deleted."); pluginFile.delete(); } else { + // now attempt to register the plugin. "dbPlugin" will be the new updated plugin; but if + // the scanned plugin does not obsolete the current plugin, then dbPlugin will be the old, still valid, plugin. SubjectManagerLocal subjectManager = LookupUtil.getSubjectManager(); - serverPluginsManager.registerServerPlugin(subjectManager.getOverlord(), plugin, pluginFile); + ServerPlugin dbPlugin = serverPluginsManager.registerServerPlugin(subjectManager.getOverlord(), plugin, + pluginFile); + log.info("Registered server plugin [" + dbPlugin.getName() + "], version " + dbPlugin.getVersion()); } } catch (Exception e) { - log.error("Failed to register RHQ plugin file [" + pluginFile + "]", e); + log.error("Failed to register server plugin file [" + pluginFile + "]", e); } return; } @@ -345,6 +351,9 @@ public class ServerPluginScanner { * This method scans the database for any new or updated server plugins and make sure this server * has a plugin file on the filesystem for each of those new/updated server plugins. * + * This also checks to see if the enabled flag changed for plugins that we already know about. + * If it does, and its plugin container has the plugin already loaded, the plugin will be reloaded. + * * @return a list of files that appear to be new or updated and should be deployed */ private List<File> serverPluginScanDatabase() throws Exception { diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsBean.java index d86e958..be6875f 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsBean.java @@ -123,6 +123,7 @@ public class ServerPluginsBean implements ServerPluginsLocal { return plugin; }
+ @SuppressWarnings("unchecked") public List<ServerPlugin> getServerPluginsById(List<Integer> pluginIds) { if (pluginIds == null || pluginIds.size() == 0) { return new ArrayList<ServerPlugin>(); // nothing to do @@ -132,6 +133,7 @@ public class ServerPluginsBean implements ServerPluginsLocal { return query.getResultList(); }
+ @SuppressWarnings("unchecked") public List<ServerPlugin> getAllServerPluginsById(List<Integer> pluginIds) { if (pluginIds == null || pluginIds.size() == 0) { return new ArrayList<ServerPlugin>(); // nothing to do @@ -150,6 +152,7 @@ public class ServerPluginsBean implements ServerPluginsLocal { return descriptor; }
+ @SuppressWarnings("unchecked") public List<PluginKey> getServerPluginKeysByEnabled(boolean enabled) { Query query = entityManager.createNamedQuery(ServerPlugin.QUERY_GET_KEYS_BY_ENABLED); query.setParameter("enabled", Boolean.valueOf(enabled)); @@ -162,41 +165,59 @@ public class ServerPluginsBean implements ServerPluginsLocal { return new ArrayList<PluginKey>(); // nothing to do }
- serverPluginsBean.setServerPluginEnabledFlag(subject, pluginIds, true); - - ServerPluginServiceManagement serverPluginService = LookupUtil.getServerPluginService(); - MasterServerPluginContainer master = serverPluginService.getMasterPluginContainer(); - - List<PluginKey> enabledPlugins = new ArrayList<PluginKey>(); + List<PluginKey> pluginKeys = new ArrayList<PluginKey>();
for (Integer pluginId : pluginIds) { - ServerPlugin enabledPlugin = null; + serverPluginsBean.setServerPluginEnabledFlag(subject, pluginId, true); + + ServerPlugin plugin = null; try { - enabledPlugin = entityManager.getReference(ServerPlugin.class, pluginId); - } catch (Exception ignore) { + plugin = entityManager.getReference(ServerPlugin.class, pluginId); + } catch (Exception e) { + log.debug("Cannot enable plugin [" + pluginId + "]. Cause: " + ThrowableUtil.getAllMessages(e)); } - if (enabledPlugin != null) { - PluginKey pluginKey = new PluginKey(enabledPlugin); - enabledPlugins.add(pluginKey); - if (master != null) { - AbstractTypeServerPluginContainer pc = master.getPluginContainerByPlugin(pluginKey); - if (pc != null) { - try { - pc.reloadPlugin(pluginKey, true); - } catch (Exception e) { - log.warn("Failed to enable server plugin [" + pluginKey + "]", e); - } - try { - pc.schedulePluginJobs(pluginKey); - } catch (Exception e) { - log.warn("Failed to schedule jobs for plugin [" + pluginKey + "]", e); - } + if (plugin != null) { + PluginKey pluginKey = new PluginKey(plugin); + boolean success = enableServerPluginInMasterContainer(pluginKey); + if (success) { + pluginKeys.add(pluginKey); + } else { + // we can't enable the plugin in the container, there must be a problem with it - disable it + serverPluginsBean.setServerPluginEnabledFlag(subject, pluginId, false); + } + } + } + + return pluginKeys; + } + + private boolean enableServerPluginInMasterContainer(PluginKey pluginKey) { + ServerPluginServiceManagement serverPluginService = LookupUtil.getServerPluginService(); + MasterServerPluginContainer master = serverPluginService.getMasterPluginContainer(); + boolean success = true; // assume everything will be ok + + if (master != null) { + AbstractTypeServerPluginContainer pc = master.getPluginContainerByPlugin(pluginKey); + if (pc != null) { + try { + pc.reloadPlugin(pluginKey, true); + try { + pc.schedulePluginJobs(pluginKey); + } catch (Exception e) { + // note that we still will report this plugin as enabled - its running + // in the plugin container, its just that we couldn't schedule its jobs + log.warn("Failed to schedule jobs for plugin [" + pluginKey + "]", e); } + } catch (Exception e) { + log.warn("Failed to enable server plugin [" + pluginKey + "]", e); + success = false; } } }
- return enabledPlugins; + // If the master PC was not started, we will still say it was successful - the next time someone starts + // the master PC, they will be told then of any errors that might occur + return success; }
@RequiredPermission(Permission.MANAGE_SETTINGS) @@ -205,41 +226,53 @@ public class ServerPluginsBean implements ServerPluginsLocal { return new ArrayList<PluginKey>(); // nothing to do }
- serverPluginsBean.setServerPluginEnabledFlag(subject, pluginIds, false); - - ServerPluginServiceManagement serverPluginService = LookupUtil.getServerPluginService(); - MasterServerPluginContainer master = serverPluginService.getMasterPluginContainer(); - - List<PluginKey> doomedPlugins = new ArrayList<PluginKey>(); + List<PluginKey> pluginKeys = new ArrayList<PluginKey>();
for (Integer pluginId : pluginIds) { - ServerPlugin doomedPlugin = null; + serverPluginsBean.setServerPluginEnabledFlag(subject, pluginId, false); + + ServerPlugin plugin = null; try { - doomedPlugin = entityManager.getReference(ServerPlugin.class, pluginId); - } catch (Exception ignore) { + plugin = entityManager.getReference(ServerPlugin.class, pluginId); + } catch (Exception e) { + log.debug("Cannot disable plugin [" + pluginId + "]. Cause: " + ThrowableUtil.getAllMessages(e)); } - if (doomedPlugin != null) { - PluginKey pluginKey = new PluginKey(doomedPlugin); - doomedPlugins.add(pluginKey); - if (master != null) { - AbstractTypeServerPluginContainer pc = master.getPluginContainerByPlugin(pluginKey); - if (pc != null) { - try { - pc.unschedulePluginJobs(pluginKey); - } catch (Exception e) { - log.warn("Failed to unschedule jobs for plugin [" + pluginKey + "]", e); - } - try { - pc.reloadPlugin(pluginKey, false); - } catch (Exception e) { - log.warn("Failed to disable server plugin [" + pluginKey + "]", e); - } - } + if (plugin != null) { + PluginKey pluginKey = new PluginKey(plugin); + boolean success = disableServerPluginInMasterContainer(pluginKey); + if (success) { + pluginKeys.add(pluginKey); } } }
- return doomedPlugins; + return pluginKeys; + } + + private boolean disableServerPluginInMasterContainer(PluginKey pluginKey) { + ServerPluginServiceManagement serverPluginService = LookupUtil.getServerPluginService(); + MasterServerPluginContainer master = serverPluginService.getMasterPluginContainer(); + boolean success = true; // assume everything will be ok + + if (master != null) { + AbstractTypeServerPluginContainer pc = master.getPluginContainerByPlugin(pluginKey); + if (pc != null) { + try { + pc.unschedulePluginJobs(pluginKey); + } catch (Exception e) { + // even though we can't unschedule jobs, keep going, assume success if the PC disabled it + log.warn("Failed to unschedule jobs for plugin [" + pluginKey + "]", e); + } + try { + pc.reloadPlugin(pluginKey, false); + } catch (Exception e) { + log.warn("Failed to disable server plugin [" + pluginKey + "]", e); + success = false; + } + } + } + + return success; }
@RequiredPermission(Permission.MANAGE_SETTINGS) @@ -248,65 +281,76 @@ public class ServerPluginsBean implements ServerPluginsLocal { return new ArrayList<PluginKey>(); // nothing to do }
- serverPluginsBean.setServerPluginEnabledFlag(subject, pluginIds, false); - - ServerPluginServiceManagement serverPluginService = LookupUtil.getServerPluginService(); - MasterServerPluginContainer master = serverPluginService.getMasterPluginContainer(); - - List<PluginKey> doomedPlugins = new ArrayList<PluginKey>(); + List<PluginKey> pluginKeys = new ArrayList<PluginKey>();
for (Integer pluginId : pluginIds) { - ServerPlugin doomedPlugin = null; + serverPluginsBean.setServerPluginEnabledFlag(subject, pluginId, false); + + ServerPlugin plugin = null; try { - doomedPlugin = entityManager.getReference(ServerPlugin.class, pluginId); - } catch (Exception ignore) { + plugin = entityManager.getReference(ServerPlugin.class, pluginId); + } catch (Exception e) { + log.debug("Cannot undeploy plugin [" + pluginId + "]. Cause: " + ThrowableUtil.getAllMessages(e)); } - if (doomedPlugin != null) { - PluginKey pluginKey = new PluginKey(doomedPlugin); - doomedPlugins.add(pluginKey); - if (master != null) { - AbstractTypeServerPluginContainer pc = master.getPluginContainerByPlugin(pluginKey); - if (pc != null) { - try { - pc.unschedulePluginJobs(pluginKey); - } catch (Exception e) { - log.warn("Failed to unschedule jobs for server plugin [" + pluginKey + "]", e); - } - try { - pc.unloadPlugin(pluginKey); - } catch (Exception e) { - log.warn("Failed to unload server plugin [" + pluginKey + "]", e); - } - } + if (plugin != null) { + PluginKey pluginKey = new PluginKey(plugin); + boolean success = undeployServerPluginInMasterContainer(pluginKey); + if (success) { + pluginKeys.add(pluginKey); }
// if this plugin ever gets re-installed, let's support the use-case where the new plugin // will have different config metadata. Here we null out the old config so the new - // config can be set to the new cofig definition's default values. - if (doomedPlugin.getPluginConfiguration() != null) { - entityManager.remove(doomedPlugin.getPluginConfiguration()); - doomedPlugin.setPluginConfiguration(null); + // config can be set to the new config definition's default values. + if (plugin.getPluginConfiguration() != null) { + entityManager.remove(plugin.getPluginConfiguration()); + plugin.setPluginConfiguration(null); } - if (doomedPlugin.getScheduledJobsConfiguration() != null) { - entityManager.remove(doomedPlugin.getScheduledJobsConfiguration()); - doomedPlugin.setScheduledJobsConfiguration(null); + if (plugin.getScheduledJobsConfiguration() != null) { + entityManager.remove(plugin.getScheduledJobsConfiguration()); + plugin.setScheduledJobsConfiguration(null); } - doomedPlugin.setStatus(PluginStatusType.DELETED); + plugin.setStatus(PluginStatusType.DELETED);
+ // purge the file from the filesystem, we do not want this deployed again try { - File pluginDir = serverPluginService.getServerPluginsDirectory(); - File currentFile = new File(pluginDir, doomedPlugin.getPath()); + File pluginDir = LookupUtil.getServerPluginService().getServerPluginsDirectory(); + File currentFile = new File(pluginDir, plugin.getPath()); currentFile.delete(); } catch (Exception e) { - log.error("Failed to delete the undeployed plugin [" + doomedPlugin.getPath() + "]. Cause: " + log.error("Failed to delete the undeployed plugin file [" + plugin.getPath() + "]. Cause: " + ThrowableUtil.getAllMessages(e)); } + log.info("Server plugin [" + pluginKey + "] has been undeployed"); } }
- log.info("Server plugins " + doomedPlugins + " have been undeployed"); + return pluginKeys; + } + + private boolean undeployServerPluginInMasterContainer(PluginKey pluginKey) { + ServerPluginServiceManagement serverPluginService = LookupUtil.getServerPluginService(); + MasterServerPluginContainer master = serverPluginService.getMasterPluginContainer(); + boolean success = true; // assume everything will be ok
- return doomedPlugins; + if (master != null) { + AbstractTypeServerPluginContainer pc = master.getPluginContainerByPlugin(pluginKey); + if (pc != null) { + try { + pc.unschedulePluginJobs(pluginKey); + } catch (Exception e) { + log.warn("Failed to unschedule jobs for server plugin [" + pluginKey + "]", e); + } + try { + pc.unloadPlugin(pluginKey); + } catch (Exception e) { + log.warn("Failed to unload server plugin [" + pluginKey + "]", e); + success = false; + } + } + } + + return success; }
@RequiredPermission(Permission.MANAGE_SETTINGS) @@ -323,25 +367,18 @@ public class ServerPluginsBean implements ServerPluginsLocal { purgeServerPlugin(subject, pluginKey); // delete the row in the DB }
- log.info("Server plugins " + purgePlugins + " have been undeployed"); + log.info("Server plugins " + purgePlugins + " have been purged"); return purgePlugins; }
@RequiredPermission(Permission.MANAGE_SETTINGS) @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) - public void setServerPluginEnabledFlag(Subject subject, List<Integer> pluginIds, boolean enabled) throws Exception { - if (pluginIds == null || pluginIds.size() == 0) { - return; // nothing to do - } - Query q = entityManager.createNamedQuery(ServerPlugin.UPDATE_PLUGINS_ENABLED_BY_IDS); - q.setParameter("ids", pluginIds); + public void setServerPluginEnabledFlag(Subject subject, int pluginId, boolean enabled) throws Exception { + Query q = entityManager.createNamedQuery(ServerPlugin.UPDATE_PLUGIN_ENABLED_BY_ID); + q.setParameter("id", pluginId); q.setParameter("enabled", Boolean.valueOf(enabled)); - int count = q.executeUpdate(); - if (count != pluginIds.size()) { - throw new Exception("Failed to update [" + pluginIds.size() + "] plugins. Count was [" + count + "]"); - } - - log.info((enabled ? "Enabling" : "Disabling") + " server plugins with plugin IDs of " + pluginIds); + q.executeUpdate(); + log.info((enabled ? "Enabling" : "Disabling") + " server plugin [" + pluginId + "]"); return; }
@@ -368,10 +405,12 @@ public class ServerPluginsBean implements ServerPluginsLocal { + "] must be a server plugin to be registered"); }
+ PluginKey pluginKey = new PluginKey(plugin); ServerPlugin existingPlugin = null; boolean newOrUpdated = false; + try { - existingPlugin = getServerPlugin(new PluginKey(plugin)); + existingPlugin = getServerPlugin(pluginKey); } catch (NoResultException nre) { newOrUpdated = true; // this is expected for new plugins } @@ -388,20 +427,30 @@ public class ServerPluginsBean implements ServerPluginsLocal { plugin.setId(existingPlugin.getId()); }
- // If this is a brand new plugin, it gets "updated" too - which ends up being a simple persist. if (newOrUpdated) { + // prepare some defaults if need be if (plugin.getDisplayName() == null) { plugin.setDisplayName(plugin.getName()); }
+ // if the ID is 0, it means this is a new plugin and we need to add a row to the db + // otherwise, this is an update to an existing plugin so we need to update the existing db row if (plugin.getId() == 0) { - PluginStatusType status = getServerPluginStatus(new PluginKey(plugin)); + PluginStatusType status = (existingPlugin != null) ? existingPlugin.getStatus() : null; if (PluginStatusType.DELETED == status) { throw new IllegalArgumentException("Cannot register plugin [" + plugin.getName() + "], it has been previously marked as deleted."); } entityManager.persist(plugin); + + // load this into the plugin container now + ServerPluginServiceManagement serverPluginService = LookupUtil.getServerPluginService(); + MasterServerPluginContainer master = serverPluginService.getMasterPluginContainer(); + if (master != null) { + master.loadPlugin(pluginFile.toURI().toURL(), false); // we'll enable it down below, if need be + } } else { + disableServerPluginInMasterContainer(pluginKey); plugin = updateServerPluginExceptContent(subject, plugin); }
@@ -409,6 +458,11 @@ public class ServerPluginsBean implements ServerPluginsLocal { entityManager.flush(); streamPluginFileContentToDatabase(plugin.getId(), pluginFile); } + + if (plugin.isEnabled()) { + enableServerPluginInMasterContainer(pluginKey); + } + log.info("Server plugin [" + plugin.getName() + "] has been registered in the database"); }
@@ -426,7 +480,7 @@ public class ServerPluginsBean implements ServerPluginsLocal { doomed = this.entityManager.getReference(ServerPlugin.class, doomed.getId()); this.entityManager.remove(doomed);
- log.debug("Server plugin [" + pluginKey + "] has been purged from the db"); + log.info("Server plugin [" + pluginKey + "] has been purged from the db"); return; }
@@ -491,6 +545,7 @@ public class ServerPluginsBean implements ServerPluginsLocal { return status; }
+ @SuppressWarnings("unchecked") public Map<ServerPluginType, List<PluginKey>> getInstalledServerPluginsGroupedByType() { Query q = entityManager.createNamedQuery(ServerPlugin.QUERY_FIND_ALL_INSTALLED_KEYS); List<PluginKey> keys = q.getResultList(); // all installed plugins, both enabled and disabled @@ -551,6 +606,7 @@ public class ServerPluginsBean implements ServerPluginsLocal { return; }
+ @SuppressWarnings("unchecked") private List<PluginKey> getPluginKeysFromIds(List<Integer> pluginIds) { Query q = entityManager.createNamedQuery(ServerPlugin.QUERY_FIND_KEYS_BY_IDS); q.setParameter("ids", pluginIds); diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsLocal.java index 09323ac..7951af5 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsLocal.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsLocal.java @@ -147,15 +147,15 @@ public interface ServerPluginsLocal { List<PluginKey> purgeServerPlugins(Subject subject, List<Integer> pluginIds) throws Exception;
/** - * Turns on or off the enabled flag in the database but does NOT restart the server plugin container. + * Turns on or off the enabled flag in the database but does NOT restart the server plugin. * This has "requires new" semantics, so the results are committed immediately upon return. * * @param subject user making the request - * @param pluginIds the plugins to be enabled - * @param enabled the value of the enabled flag for the plugins - * @throws if failed to update a plugin + * @param pluginId the plugin to be enabled + * @param enabled the value of the enabled flag for the plugin + * @throws if failed to update the plugin */ - void setServerPluginEnabledFlag(Subject subject, List<Integer> pluginIds, boolean enabled) throws Exception; + void setServerPluginEnabledFlag(Subject subject, int pluginId, boolean enabled) throws Exception;
/** * Sets the status flag in the database but does NOT restart the server plugin container. @@ -171,8 +171,11 @@ public interface ServerPluginsLocal { void setServerPluginStatus(Subject subject, List<Integer> pluginIds, PluginStatusType status) throws Exception;
/** - * Registers the given plugin to the database. This does nothing with the master plugin container, - * all it does is ensure the database is up-to-date with this new plugin. + * Registers the given plugin to the database. This ensures the database is up-to-date with the + * new plugin details. + * + * If the master plugin container is up, it will attempt to restart the plugin so the new + * changes are picked up. * * @param subject the user that needs to have permissions to add a plugin to the system * @param plugin the plugin definition diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/AbstractTypeServerPluginContainer.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/AbstractTypeServerPluginContainer.java index fcebe55..7ccdc95 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/AbstractTypeServerPluginContainer.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/AbstractTypeServerPluginContainer.java @@ -282,8 +282,10 @@ public abstract class AbstractTypeServerPluginContainer { if (jobNames != null) { for (String jobName : jobNames) { boolean deleted = scheduler.deleteJob(jobName, groupName); - if (!deleted) { - log.warn("Plugin [" + pluginKey + "] failed to get its job [" + jobName + "] unscheduled!"); + if (deleted) { + log.info("Job [" + jobName + "] for plugin [" + pluginKey + "] has been unscheduled!"); + } else { + log.warn("Job [" + jobName + "] for plugin [" + pluginKey + "] failed to be unscheduled!"); } } } diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/MasterServerPluginContainer.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/MasterServerPluginContainer.java index d19ee2a..ff7c36d 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/MasterServerPluginContainer.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/MasterServerPluginContainer.java @@ -116,15 +116,15 @@ public class MasterServerPluginContainer { ServerPluginType pluginType = new ServerPluginType(descriptor); PluginKey pluginKey = PluginKey.createServerPluginKey(pluginType.stringify(), pluginName); ClassLoader classLoader = this.classLoaderManager.obtainServerPluginClassLoader(pluginKey); - log.debug("Loading server plugin [" + pluginKey + "] from [" + pluginUrl + log.debug("Pre-loading server plugin [" + pluginKey + "] from [" + pluginUrl + "] into its plugin container"); try { ServerPluginEnvironment env = new ServerPluginEnvironment(pluginUrl, classLoader, descriptor); boolean enabled = !allDisabledPlugins.contains(pluginKey); pc.loadPlugin(env, enabled); - log.info("Loaded server plugin [" + pluginKey.getPluginName() + "]"); + log.info("Preloaded server plugin [" + pluginKey.getPluginName() + "]"); } catch (Exception e) { - log.warn("Failed to load server plugin [" + pluginUrl + "]", e); + log.warn("Failed to preload server plugin [" + pluginUrl + "]", e); } } else { log.warn("There is no server plugin container to support plugin: " + pluginUrl); @@ -207,6 +207,35 @@ public class MasterServerPluginContainer { }
/** + * Loads a plugin into the appropriate plugin container. + * + * @param pluginUrl the location where the new plugin is found + * @param enabled indicates if the plugin should be enabled as soon as its loaded + * @throws Exception if the plugin's descriptor could not be parsed or could not be loaded into the plugin container + */ + public synchronized void loadPlugin(URL pluginUrl, boolean enabled) throws Exception { + ServerPluginDescriptorType descriptor = ServerPluginDescriptorUtil.loadPluginDescriptorFromUrl(pluginUrl); + ServerPluginType pluginType = new ServerPluginType(descriptor); + PluginKey pluginKey = PluginKey.createServerPluginKey(pluginType.stringify(), descriptor.getName()); + ClassLoader classLoader = this.classLoaderManager.obtainServerPluginClassLoader(pluginKey); + log.debug("Loading server plugin [" + pluginKey + "] from [" + pluginUrl + "] into its plugin container"); + try { + ServerPluginEnvironment env = new ServerPluginEnvironment(pluginUrl, classLoader, descriptor); + AbstractTypeServerPluginContainer pc = getPluginContainerByDescriptor(descriptor); + if (pc != null) { + pc.loadPlugin(env, enabled); + log.info("Loaded server plugin [" + pluginKey.getPluginName() + "]"); + } else { + throw new Exception("No plugin container can load server plugin [" + pluginKey + "]"); + } + } catch (Exception e) { + log.warn("Failed to load server plugin file [" + pluginUrl + "]", e); + } + + return; + } + + /** * Asks that all plugin containers schedule jobs now, if needed. * Note that this is separate from the {@link #initialize(MasterServerPluginContainerConfiguration)} * method because it is possible that the master plugin container has been @@ -286,6 +315,7 @@ public class MasterServerPluginContainer { * @param pluginKey * @return the plugin container that is managing the named plugin or <code>null</code> */ + @SuppressWarnings("unchecked") public synchronized <T extends AbstractTypeServerPluginContainer> T getPluginContainerByPlugin(PluginKey pluginKey) { for (AbstractTypeServerPluginContainer pc : this.pluginContainers.values()) { try { diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginManager.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginManager.java index f8cdd5b..10ac43d 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginManager.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginManager.java @@ -163,14 +163,16 @@ public class ServerPluginManager { * @param enabled <code>true</code> if the plugin should be initialized; <code>false</code> if * the plugin's existence should be noted but it should not be initialized or started * - * @throws Exception if the plugin manager cannot load the plugin or deems the plugin invalid + * @throws Exception if the plugin manager cannot load the plugin or deems the plugin invalid. + * Typically, this method will not throw an exception unless enabled is + * <code>true</code> - loading a disabled plugin is trivial and should not + * fail or throw an exception. */ protected void loadPlugin(ServerPluginEnvironment env, boolean enabled) throws Exception { String pluginName = env.getPluginKey().getPluginName(); + log.debug("Loading server plugin [" + pluginName + "] from: " + env.getPluginUrl());
if (enabled) { - log.debug("Loading server plugin [" + pluginName + "] from: " + env.getPluginUrl()); - // tell the plugin we are loading it ServerPluginComponent component = createServerPluginComponent(env); if (component != null) { @@ -181,7 +183,7 @@ public class ServerPluginManager { Thread.currentThread().setContextClassLoader(env.getPluginClassLoader()); component.initialize(context); } catch (Throwable t) { - throw new Exception("Plugin component failed to initialize plugin", t); + throw new Exception("Plugin component failed to initialize server plugin", t); } finally { Thread.currentThread().setContextClassLoader(originalContextClassLoader); } @@ -215,6 +217,9 @@ public class ServerPluginManager { log.debug("Starting plugin component for server plugin [" + pluginName + "]"); ClassLoader originalContextClassLoader = Thread.currentThread().getContextClassLoader(); try { + if (env == null) { + throw new Exception("Plugin [" + pluginName + "] was never loaded"); + } Thread.currentThread().setContextClassLoader(env.getPluginClassLoader()); component.start(); } catch (Throwable t) { @@ -243,6 +248,9 @@ public class ServerPluginManager { log.debug("Stopping plugin component for server plugin [" + pluginName + "]"); ClassLoader originalContextClassLoader = Thread.currentThread().getContextClassLoader(); try { + if (env == null) { + throw new Exception("Plugin [" + pluginName + "] was never loaded"); + } Thread.currentThread().setContextClassLoader(env.getPluginClassLoader()); component.stop(); } catch (Throwable t) { @@ -325,7 +333,14 @@ public class ServerPluginManager { stopPlugin(pluginName); // under normal circumstances, we should not need to do this, but just in case the plugin is somehow already started, stop it unloadPlugin(pluginName); // unloading it will clean up old data and force the plugin context to reload if we later re-enable it env = rebuildServerPluginEnvironment(env); - loadPlugin(env, true); // reload it in the enabled state + try { + // reload it in the enabled state. + loadPlugin(env, true); + } catch (Exception e) { + // we've already unloaded it - so even though we failed to enable it, we need to load it back, albeit disabled + loadPlugin(env, false); + throw e; + } startPlugin(pluginName); // since we are enabling the plugin, immediately start it return; } @@ -343,6 +358,10 @@ public class ServerPluginManager { return; }
+ protected boolean isPluginLoaded(String pluginName) { + return this.loadedPlugins.containsKey(pluginName); + } + protected boolean isPluginEnabled(String pluginName) { return Boolean.TRUE.equals(this.enabledPlugins.get(pluginName)); }
commit 38d2f8c17d678f1281bcbcc77d9a78efc134c1b3 Author: Adam Young ayoung@redhat.com Date: Tue Dec 8 17:22:03 2009 -0500
Increasing the scope of the unit test.
diff --git a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/ConfigRendererTest.java b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/ConfigRendererTest.java index 68afd21..63c1d52 100644 --- a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/ConfigRendererTest.java +++ b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/ConfigRendererTest.java @@ -1,11 +1,10 @@ package org.rhq.core.gui.configuration;
import java.io.IOException; +import java.io.StringWriter; import java.util.HashMap;
-import javax.el.ValueExpression; import javax.faces.FactoryFinder; -import javax.faces.application.ApplicationFactory; import javax.faces.context.ExternalContext; import javax.faces.context.FacesContext; import javax.faces.lifecycle.Lifecycle; @@ -19,7 +18,7 @@ import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test;
import org.rhq.core.domain.configuration.Configuration; -import org.rhq.core.gui.util.FacesContextUtility; +import org.rhq.core.domain.configuration.definition.ConfigurationDefinition;
public class ConfigRendererTest {
@@ -31,50 +30,96 @@ public class ConfigRendererTest { AjaxContext ajaxContext; MockResponseWriter mockResponseWriter; Lifecycle lifecycle; + ConfigurationDefinition configurationDefinition;
@BeforeMethod protected void setUp() throws Exception { - configUIComponent = new ConfigUIComponent(); - configRenderer = new ConfigRenderer(); + //Order is pretty important here + FactoryFinder.setFactory(FactoryFinder.RENDER_KIT_FACTORY, MockRenderKitFactory.class.getName()); + FactoryFinder.setFactory(FactoryFinder.APPLICATION_FACTORY, MockApplicationFactory.class.getName());
externalContext = new MockExternalContext(); + lifecycle = new MockLifecycle(); mockResponseWriter = new MockResponseWriter(); - facesContext = new MockFacesContext(externalContext, mockResponseWriter); - FacesContext.getCurrentInstance(); + configUIComponent = new ConfigUIComponent(); + configRenderer = new ConfigRenderer();
- configUIComponent.setId("ID"); + FacesContextImpl impl = new FacesContextImpl(externalContext, lifecycle); + HashMap<Object, Object> map = new HashMap<Object, Object>(); + map.put("com.sun.faces.FacesContextImpl", impl);
+ //Whichever one gets created last wins the + //"I'm registered with thread local storage and you are not" game + facesContext = new MockFacesContext(externalContext, mockResponseWriter); + facesContext.getExternalContext().getRequestMap().put("com.sun.faces.util.RequestStateManager", map); ajaxContext = AjaxContext.getCurrentInstance(facesContext); - lifecycle = new MockLifecycle();
- ApplicationFactory af = new MockApplicationFactory(); + configUIComponent.setId("ID");
- FactoryFinder.setFactory(FactoryFinder.RENDER_KIT_FACTORY, MockRenderKitFactory.class.getName()); - FactoryFinder.setFactory(FactoryFinder.APPLICATION_FACTORY, MockApplicationFactory.class.getName()); + configUIComponent.setValueExpression("configuration", new MockValueExpression(new Configuration())); + configUIComponent.setValueExpression("configurationDefinition", + new MockValueExpression(buildConfigDefinition())); + }
- HashMap<Object, Object> map = new HashMap(); - facesContext.getExternalContext().getRequestMap().put("com.sun.faces.util.RequestStateManager", map); - FacesContextImpl impl = new FacesContextImpl(externalContext, lifecycle); - map.put("com.sun.faces.FacesContextImpl", impl); - ValueExpression binding = new MockValueExpression(); - binding.setValue(FacesContextUtility.getFacesContext().getELContext(), new Configuration()); - configUIComponent.setValueExpression("configuration", binding); + private ConfigurationDefinition buildConfigDefinition() { + ConfigurationDefinition def = new ConfigurationDefinition("MockDef", "Mock Configuration definition");
+ return def; + } + + //@Test + public void testUIComponentDecode() { + configUIComponent.setRendererType(ConfigRenderer.class.getName()); + configUIComponent.decode(facesContext); }
@Test + public void testUIComponentEncode() throws IOException { + configUIComponent.setRendererType(ConfigRenderer.class.getName()); + configUIComponent.encodeAll(facesContext); + } + + //@Test public void testDecode() { configUIComponent.setReadOnly(false); Assert.assertNotNull(configUIComponent.getConfiguration()); configRenderer.decode(facesContext, configUIComponent); }
- @Test + //@Test public void testEncode() throws IOException { + configUIComponent.setReadOnly(true); + configUIComponent.setPrevalidate(false); + /* + <onc:config + configurationDefinition="#{ExistingResourceConfigurationUIBean.configurationDefinition}" + configuration="#{ExistingResourceConfigurationUIBean.configuration}" + accessMapActionExpression="#{ExistingResourceConfigurationUIBean.accessMap}" + readOnly="true" + nullConfigurationDefinitionMessage="#{ExistingResourceConfigurationUIBean.nullConfigurationDefinitionMessage}" + nullConfigurationMessage="#{ExistingResourceConfigurationUIBean.nullConfigurationMessage}" + prevalidate="true"/> + */ + + configRenderer.encodeBegin(this.facesContext, configUIComponent); + configRenderer.encodeChildren(facesContext, configUIComponent); + configRenderer.encodeEnd(facesContext, configUIComponent); + String s1 = mockResponseWriter.stringWriter.getBuffer().toString(); + + mockResponseWriter.stringWriter = new StringWriter(); + + configUIComponent.setReadOnly(false); + configUIComponent.setPrevalidate(false); + configRenderer.encodeBegin(this.facesContext, configUIComponent); configRenderer.encodeChildren(facesContext, configUIComponent); configRenderer.encodeEnd(facesContext, configUIComponent); - System.out.println(mockResponseWriter.stringWriter.getBuffer().toString()); + String s2 = mockResponseWriter.stringWriter.getBuffer().toString(); + + Assert.assertTrue(!s1.equals(s2)); + + System.out.println(s1); + }
} diff --git a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockFacesContext.java b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockFacesContext.java index 49b007e..73097d6 100644 --- a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockFacesContext.java +++ b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockFacesContext.java @@ -15,12 +15,12 @@ import javax.faces.render.RenderKit; public class MockFacesContext extends FacesContext {
private ExternalContext externalContext; - private Object responseCompleteWriter; - private MockResponseWriter mockResponseWriter; + private MockResponseWriter responseWriter;
- public MockFacesContext(ExternalContext externalContext, ResponseWriter responseWriter) { + public MockFacesContext(ExternalContext externalContext, MockResponseWriter responseWriter) { this.externalContext = externalContext; - this.responseCompleteWriter = responseWriter; + this.responseWriter = responseWriter; + FacesContext.setCurrentInstance(this); }
@Override @@ -65,10 +65,11 @@ public class MockFacesContext extends FacesContext {
}
+ RenderKit mockRenderKit = new MockRenderKit(); + @Override public RenderKit getRenderKit() { - throw new RuntimeException("Function not implemented"); - + return mockRenderKit; }
@Override @@ -91,10 +92,7 @@ public class MockFacesContext extends FacesContext {
@Override public ResponseWriter getResponseWriter() { - if (null == mockResponseWriter) { - mockResponseWriter = new MockResponseWriter(); - } - return mockResponseWriter; + return responseWriter; }
@Override diff --git a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockRenderKit.java b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockRenderKit.java new file mode 100644 index 0000000..56df905 --- /dev/null +++ b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockRenderKit.java @@ -0,0 +1,48 @@ +package org.rhq.core.gui.configuration; + +import java.io.OutputStream; +import java.io.Writer; + +import javax.faces.context.ResponseStream; +import javax.faces.context.ResponseWriter; +import javax.faces.render.RenderKit; +import javax.faces.render.Renderer; +import javax.faces.render.ResponseStateManager; + +public class MockRenderKit extends RenderKit { + + @Override + public void addRenderer(String family, String rendererType, Renderer renderer) { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public ResponseStream createResponseStream(OutputStream out) { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public ResponseWriter createResponseWriter(Writer writer, String contentTypeList, String characterEncoding) { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public Renderer getRenderer(String family, String rendererType) { + try { + return (Renderer) Class.forName(rendererType).newInstance(); + } catch (Exception e) { + return null; + } + + } + + @Override + public ResponseStateManager getResponseStateManager() { + throw new RuntimeException("Function not implemented"); + + } + +} diff --git a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockResponseWriter.java b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockResponseWriter.java index 378ca41..d1b6e56 100644 --- a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockResponseWriter.java +++ b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockResponseWriter.java @@ -25,7 +25,7 @@ public class MockResponseWriter extends ResponseWriter {
@Override public void endElement(String name) throws IOException { - stringWriter.write("end element:" + name); + stringWriter.write("end element:" + name + "\n");
}
@@ -55,24 +55,24 @@ public class MockResponseWriter extends ResponseWriter {
@Override public void startElement(String name, UIComponent component) throws IOException { - stringWriter.write("startElement: " + name + ": componenet:" + component.getId()); + stringWriter.write("startElement: " + name + ": componenet:" + component.getId() + "\n"); }
@Override public void writeAttribute(String name, Object value, String property) throws IOException { - stringWriter.write("attribute:" + name + "value = " + value.toString() + "property = " + property); + stringWriter.write("attribute:" + name + " value = " + value.toString() + " property = " + property + "\n");
}
@Override public void writeComment(Object comment) throws IOException { - stringWriter.write("comment:" + comment); + stringWriter.write("comment:" + comment + "\n");
}
@Override public void writeText(Object text, String property) throws IOException { - write(text + ":" + property); + stringWriter.write("text:" + text + ":" + property + "\n"); }
@Override @@ -88,7 +88,7 @@ public class MockResponseWriter extends ResponseWriter {
@Override public void close() throws IOException { - stringWriter.close(); + //stringWriter.close(); }
@Override diff --git a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockValueExpression.java b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockValueExpression.java index 49bd739..45d2993 100644 --- a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockValueExpression.java +++ b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockValueExpression.java @@ -5,58 +5,68 @@ import javax.el.ValueExpression;
public class MockValueExpression extends ValueExpression {
+ /** + * + */ + private static final long serialVersionUID = 1L; + + public MockValueExpression(Object value) { + this.value = value; + } + + public Object value; + + public boolean literalText = false; + @Override - public Class<?> getExpectedType() { + public boolean equals(Object arg0) { throw new RuntimeException("Function not implemented");
}
@Override - public Class<?> getType(ELContext arg0) { + public Class<?> getExpectedType() { throw new RuntimeException("Function not implemented");
}
@Override - public Object getValue(ELContext arg0) { - return value; + public String getExpressionString() { + throw new RuntimeException("Function not implemented"); + }
@Override - public boolean isReadOnly(ELContext arg0) { + public Class<?> getType(ELContext arg0) { throw new RuntimeException("Function not implemented");
}
- public Object value; - public boolean literalText = false; - @Override - public void setValue(ELContext arg0, Object arg1) { - this.value = arg1; + public Object getValue(ELContext arg0) { + return value; }
@Override - public boolean equals(Object arg0) { + public int hashCode() { throw new RuntimeException("Function not implemented");
}
@Override - public String getExpressionString() { - throw new RuntimeException("Function not implemented"); - + public boolean isLiteralText() { + return literalText; }
@Override - public int hashCode() { + public boolean isReadOnly(ELContext arg0) { throw new RuntimeException("Function not implemented");
}
@Override - public boolean isLiteralText() { - return literalText; + public void setValue(ELContext arg0, Object arg1) { + this.value = arg1; }
} diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ExistingResourceConfigurationUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ExistingResourceConfigurationUIBean.java index b7a781d..c6d9b18 100644 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ExistingResourceConfigurationUIBean.java +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ExistingResourceConfigurationUIBean.java @@ -54,9 +54,6 @@ import org.rhq.enterprise.server.util.LookupUtil; public class ExistingResourceConfigurationUIBean extends AbstractConfigurationUIBean { public static final String MANAGED_BEAN_NAME = "ExistingResourceConfigurationUIBean";
- /** - * - */ private String selectedPath; private TreeMap<String, RawConfiguration> raws; private TreeMap<String, RawConfiguration> modified = new TreeMap<String, RawConfiguration>(); @@ -193,9 +190,6 @@ public class ExistingResourceConfigurationUIBean extends AbstractConfigurationUI private Configuration getMergedConfiguration() { for (RawConfiguration raw : getModified().values()) { getRaws().put(raw.getPath(), raw); - log.error("Just merged in raw path =[" + raw.getPath() + "]"); - log.error(" file =[" + new String(raw.getContents()) + "]"); - } getConfiguration().getRawConfigurations().clear(); getConfiguration().getRawConfigurations().addAll(getRaws().values()); @@ -209,7 +203,6 @@ public class ExistingResourceConfigurationUIBean extends AbstractConfigurationUI
public void fileUploadListener(UploadEvent event) throws Exception { File uploadFile; - log.error("fileUploadListener called"); uploadFile = event.getUploadItem().getFile(); if (uploadFile != null) { log.debug("fileUploadListener got file named " + event.getUploadItem().getFileName()); @@ -354,12 +347,8 @@ public class ExistingResourceConfigurationUIBean extends AbstractConfigurationUI }
public String switchToraw() { - log.error("switch2raw called"); - dumpProperties(getConfiguration(), log); Configuration configuration = LookupUtil.getConfigurationManager().translateResourceConfiguration( EnterpriseFacesContextUtility.getSubject(), getResourceId(), getMergedConfiguration(), true); - log.error("switch2raw post merge"); - dumpProperties(getConfiguration(), log);
setConfiguration(configuration); for (RawConfiguration raw : configuration.getRawConfigurations()) { @@ -371,21 +360,10 @@ public class ExistingResourceConfigurationUIBean extends AbstractConfigurationUI return "/rhq/resource/configuration/edit-raw.xhtml?currentResourceId=" + getResourceId(); }
- void dumpProperties(Configuration conf, Log log) { - for (String key : conf.getAllProperties().keySet()) { - log.error("property=" + conf.getAllProperties().get(key)); - } - } - public String switchTostructured() { - log.error("switch2structured called");
- dumpProperties(getConfiguration(), log); Configuration configuration = LookupUtil.getConfigurationManager().translateResourceConfiguration( EnterpriseFacesContextUtility.getSubject(), getResourceId(), getMergedConfiguration(), false); - log.error("switch2structured post merge"); - - dumpProperties(configuration, log);
for (Property property : configuration.getAllProperties().values()) { property.setConfiguration(configuration); diff --git a/modules/plugins/augeas/src/test/java/README b/modules/plugins/augeas/src/test/java/README new file mode 100644 index 0000000..db73645 --- /dev/null +++ b/modules/plugins/augeas/src/test/java/README @@ -0,0 +1 @@ +Delete this file once there is source in this tree
commit 820344cd31ab1dbe34c65e6f59afff97388f20cb Author: John Mazzitelli mazz@redhat.com Date: Tue Dec 8 16:57:27 2009 -0500
#545595 - don't send up empty inventory reports and make sure the report has at least the platform plugin
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/AutoDiscoveryExecutor.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/AutoDiscoveryExecutor.java index a1394de..47b552d 100644 --- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/AutoDiscoveryExecutor.java +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/AutoDiscoveryExecutor.java @@ -204,6 +204,15 @@ public class AutoDiscoveryExecutor implements Runnable, Callable<InventoryReport log.error("Error in auto discovery", e); } } + + // if we have nothing, our plugins didn't discovery anything, but we want to at least report the platform + if (report.getAddedRoots().isEmpty()) { + if (platformContainer.getSynchronizationState() == ResourceContainer.SynchronizationState.NEW) { + report.addAddedRoot(platformResource); + } + } + + return; }
private List<ProcessScanResult> performProcessScans(List<ProcessInfo> processInfos, ResourceType serverType) { diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java index 873585b..82c0d51 100644 --- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java @@ -820,6 +820,10 @@ public class InventoryManager extends AgentService implements ContainerService, if (!configuration.isInsideAgent()) { return true; } + if (report.getAddedRoots().isEmpty()) { + return true; // nothing to do + } + ResourceSyncInfo syncInfo; try { String reportType = (report.isRuntimeReport()) ? "runtime" : "server";
commit 254427c63bd6cf190078961da26b3d7587c8de2f Author: Justin Harris jharris@redhat.com Date: Tue Dec 8 16:38:50 2009 -0500
Adding IRC Alert Plugin.
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSender.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSender.java index f43173a..0de598d 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSender.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSender.java @@ -18,11 +18,10 @@ */ package org.rhq.enterprise.server.plugin.pc.alert;
-import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory;
import org.rhq.core.domain.alert.Alert; import org.rhq.core.domain.configuration.Configuration; +import org.rhq.enterprise.server.plugin.pc.ServerPluginComponent;
/** * Abstract base class for all Alert senders. In order to implement your @@ -35,7 +34,7 @@ import org.rhq.core.domain.configuration.Configuration; * @author Heiko W. Rupp * */ -public abstract class AlertSender { +public abstract class AlertSender<T extends ServerPluginComponent> {
/** Configuration from the global per plugin type preferences */ protected Configuration preferences; @@ -43,6 +42,8 @@ public abstract class AlertSender { /** Configuration from the per alert definition parameters */ protected Configuration alertParameters;
+ /** Global component holding persistent resources */ + protected T pluginComponent;
/** * This method is called to actually send an alert notification. diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSenderPluginManager.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSenderPluginManager.java index 3a3b724..68b4241 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSenderPluginManager.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSenderPluginManager.java @@ -192,10 +192,10 @@ public class AlertSenderPluginManager extends ServerPluginManager { ServerPluginContext ctx = getServerPluginContext(env); AlertNotificationManagerLocal mgr = LookupUtil.getAlertNotificationManager();
- sender.alertParameters = mgr.getAlertPropertiesConfiguration(notification); - if (sender.alertParameters == null) + if (sender.alertParameters == null) { sender.alertParameters = new Configuration(); // Safety measure + }
ServerPluginsLocal pluginsMgr = LookupUtil.getServerPlugins();
@@ -204,8 +204,11 @@ public class AlertSenderPluginManager extends ServerPluginManager { plugin = pluginsMgr.getServerPluginRelationships(plugin);
sender.preferences = plugin.getPluginConfiguration(); - if (sender.preferences==null) + if (sender.preferences==null) { sender.preferences = new Configuration(); // Safety measure + } + + sender.pluginComponent = getServerPluginComponent(key.getPluginName());
return sender; } diff --git a/modules/enterprise/server/plugins/alert-irc/pom.xml b/modules/enterprise/server/plugins/alert-irc/pom.xml new file mode 100644 index 0000000..d2b424d --- /dev/null +++ b/modules/enterprise/server/plugins/alert-irc/pom.xml @@ -0,0 +1,161 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd%22%3E + <parent> + <artifactId>rhq-enterprise-server-plugins-parent</artifactId> + <groupId>org.rhq</groupId> + <version>1.4.0-SNAPSHOT</version> + </parent> + <modelVersion>4.0.0</modelVersion> + + <groupId>org.rhq</groupId> + <artifactId>alert-irc</artifactId> + <version>1.4.0-SNAPSHOT</version> + + + <name>RHQ Enterprise Server IRC Alert Plugin</name> + + <scm> + <connection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/modules/enterprise/server/plugins/alert-irc/</connection> + <developerConnection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/modules/enterprise/server/plugins/alert-irc/</developerConnection> + </scm> + + <properties> + <scm.module.path>modules/enterprise/server/plugins/alert-irc/</scm.module.path> + </properties> + + <dependencies> + + <dependency> + <groupId>org.rhq</groupId> + <artifactId>rhq-enterprise-server</artifactId> + <version>1.4.0-SNAPSHOT</version> + <scope>provided</scope> <!-- by JBossAS --> + </dependency> + + <!-- TODO: This is a fix for the Javac bug requiring annotations to be + available when compiling dependent classes. It is fixed in JDK 6 --> + <dependency> + <groupId>javax.persistence</groupId> + <artifactId>persistence-api</artifactId> + <version>1.0</version> + <scope>provided</scope> + </dependency> + + <dependency> + <groupId>jboss.jboss-embeddable-ejb3</groupId> + <artifactId>hibernate-all</artifactId> + <version>1.0.0.Alpha9</version> + <scope>provided</scope> + <!-- needed for referenced domain entities that use Hibernate annotations --> + </dependency> + + <dependency> + <groupId>pircbot</groupId> + <artifactId>pircbot</artifactId> + <version>1.4.2</version> + </dependency> + + </dependencies> + + <build> + <plugins> + + <plugin> + <artifactId>maven-surefire-plugin</artifactId> + <configuration> + <excludedGroups>${rhq.testng.excludedGroups}</excludedGroups> + <!-- + <argLine>-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=y</argLine> + --> + </configuration> + </plugin> + + </plugins> + </build> + + <profiles> + + <profile> + <id>dev</id> + + <properties> + <rhq.rootDir>../../../../..</rhq.rootDir> + <rhq.containerDir>${rhq.rootDir}/${rhq.defaultDevContainerPath}</rhq.containerDir> + <rhq.deploymentDir>${rhq.containerDir}/jbossas/server/default/deploy/${rhq.earName}/rhq-serverplugins</rhq.deploymentDir> + </properties> + + <build> + <plugins> + + <plugin> + <artifactId>maven-antrun-plugin</artifactId> + <version>1.1</version> + <executions> + + <execution> + <id>deploy</id> + <phase>compile</phase> + <configuration> + <tasks> + <mkdir dir="${rhq.deploymentDir}" /> + <property name="deployment.file" location="${rhq.deploymentDir}/${project.build.finalName}.jar" /> + <echo>*** Updating ${deployment.file}...</echo> + <jar destfile="${deployment.file}" basedir="${project.build.outputDirectory}" /> + </tasks> + </configuration> + <goals> + <goal>run</goal> + </goals> + </execution> + + <execution> + <id>undeploy</id> + <phase>clean</phase> + <configuration> + <tasks> + <property name="deployment.file" location="${rhq.deploymentDir}/${project.build.finalName}.jar" /> + <echo>*** Deleting ${deployment.file}...</echo> + <delete file="${deployment.file}" /> + </tasks> + </configuration> + <goals> + <goal>run</goal> + </goals> + </execution> + + </executions> + </plugin> + <plugin> + <artifactId>maven-dependency-plugin</artifactId> + <version>2.0</version> + <executions> + <execution> + <id>copy-pircbot-jar</id> + <phase>process-resources</phase> + <goals> + <goal>copy</goal> + </goals> + <configuration> + <artifactItems> + <artifactItem> + <groupId>pircbot</groupId> + <artifactId>pircbot</artifactId> + <version>1.4.2</version> + </artifactItem> + </artifactItems> + <outputDirectory>${project.build.outputDirectory}/lib</outputDirectory> + </configuration> + </execution> + </executions> + </plugin> + + + </plugins> + </build> + </profile> + + </profiles> + +</project> diff --git a/modules/enterprise/server/plugins/alert-irc/src/main/java/org/rhq/enterprise/server/plugins/alertIrc/IrcAlertComponent.java b/modules/enterprise/server/plugins/alert-irc/src/main/java/org/rhq/enterprise/server/plugins/alertIrc/IrcAlertComponent.java new file mode 100644 index 0000000..e6bf730 --- /dev/null +++ b/modules/enterprise/server/plugins/alert-irc/src/main/java/org/rhq/enterprise/server/plugins/alertIrc/IrcAlertComponent.java @@ -0,0 +1,162 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2009 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, version 2, as + * published by the Free Software Foundation, and/or the GNU Lesser + * General Public License, version 2.1, also as published by the Free + * Software Foundation. + * + * 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 and the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * and the GNU Lesser 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.enterprise.server.plugins.alertIrc; + +import java.util.Arrays; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.jibble.pircbot.PircBot; +import org.rhq.core.domain.configuration.Configuration; +import org.rhq.enterprise.server.plugin.pc.ServerPluginComponent; +import org.rhq.enterprise.server.plugin.pc.ServerPluginContext; + +/** + * Persistent component used to send alert notifications via IRC. + * This component is responsible for establishing and maintaining the IRC + * session as well as sending messages. + * + * @author Justin Harris + */ +public class IrcAlertComponent implements ServerPluginComponent { + + private final static String DEFAULT_IRC_PORT = "6667"; + private final Log log = LogFactory.getLog(IrcAlertComponent.class); + private RhqAlertBot ircBot; + private String nick; + private String server; + private int port; + private String[] channels; + private String cannedResponse; + + public void initialize(ServerPluginContext context) throws Exception { + Configuration preferences = context.getPluginConfiguration(); + + this.nick = preferences.getSimpleValue("nick", null); + this.server = preferences.getSimpleValue("server", null); + this.port = Integer.parseInt(preferences.getSimpleValue("port", DEFAULT_IRC_PORT)); + this.channels = parseChannels(preferences.getSimpleValue("initialChannels", null)); + this.cannedResponse = preferences.getSimpleValue("cannedResponse", null); + } + + private String[] parseChannels(String channelList) { + if (channelList != null && channelList.length() > 0) { + return channelList.split(","); + } + + return new String[0]; + } + + public void start() { + this.ircBot = new RhqAlertBot(this.nick, this.cannedResponse); + + try { + this.ircBot.connect(server, port); + } catch (Exception e) { + log.error("Error joining IRC", e); + + return; + } + + for (String channel : channels) { + this.ircBot.joinChannel(channel); + } + } + + public void stop() { + this.ircBot.disconnect(); + } + + public void shutdown() { + this.ircBot.dispose(); + this.ircBot = null; + } + + /** + * Sends a message to the specified channel, or all currently joined channels + * if the channel is not supplied. + * + * @param channel the channel to send the message to, or <code>null</code> if + * the message should be sent to all currently joined channels + * @param message + */ + public void sendIrcMessage(String channel, String message) { + if (this.ircBot != null && this.ircBot.isConnected()) { + for (String sendChannel : getChannelsToSend(channel)) { + this.ircBot.sendMessage(sendChannel, message); + } + } else { + throw new IllegalStateException("IRC bot has not been initialized"); + } + } + + private String[] getChannelsToSend(String channel) { + if (channel != null && channel.length() > 0) { + if (!isInChannel(channel)) { + this.ircBot.joinChannel(channel); + } + + return new String[]{channel}; + } else { + return this.ircBot.getChannels(); + } + } + + private boolean isInChannel(String channel) { + return Arrays.asList(this.ircBot.getChannels()).contains(channel); + } + + /** + * Our alert-centric IRC bot - not too complicated. + */ + private class RhqAlertBot extends PircBot { + + private String response; + + private RhqAlertBot(String name, String defaultResponse) { + this.setName(name); + this.response = defaultResponse; + } + + /** + * Responds to messages with the default response, if one has been defined. + * + * @param channel + * @param sender + * @param login + * @param hostname + * @param message + */ + @Override + public void onMessage(String channel, String sender, String login, + String hostname, String message) { + + if (this.response != null) { + if (channel != null && channel.length() > 0) { + sendMessage(channel, sender + ": " + this.response); + } else { + sendMessage(sender, this.response); + } + } + } + } +} diff --git a/modules/enterprise/server/plugins/alert-irc/src/main/java/org/rhq/enterprise/server/plugins/alertIrc/IrcSender.java b/modules/enterprise/server/plugins/alert-irc/src/main/java/org/rhq/enterprise/server/plugins/alertIrc/IrcSender.java new file mode 100644 index 0000000..34db27e --- /dev/null +++ b/modules/enterprise/server/plugins/alert-irc/src/main/java/org/rhq/enterprise/server/plugins/alertIrc/IrcSender.java @@ -0,0 +1,68 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2009 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.plugins.alertIrc; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.rhq.core.domain.alert.Alert; +import org.rhq.enterprise.server.alert.AlertManagerLocal; +import org.rhq.enterprise.server.plugin.pc.alert.AlertSender; +import org.rhq.enterprise.server.plugin.pc.alert.ResultState; +import org.rhq.enterprise.server.plugin.pc.alert.SenderResult; +import org.rhq.enterprise.server.util.LookupUtil; + +/** + * Sends an alert notification via IRC. + * + * @author Justin Harris + */ +public class IrcSender extends AlertSender<IrcAlertComponent> { + + private final Log log = LogFactory.getLog(IrcSender.class); + + @Override + public SenderResult send(Alert alert) { + SenderResult result; + String channel = this.alertParameters.getSimpleValue("channel", null); + + try { + this.pluginComponent.sendIrcMessage(channel, getIrcMessage(alert)); + result = new SenderResult(ResultState.SUCCESS, "IRC Alert sent."); + } catch (IllegalStateException e) { + log.error(e.getMessage(), e); + result = new SenderResult(ResultState.FAILURE, "IRC Alert failed!"); + } + + return result; + } + + private String getIrcMessage(Alert alert) { + AlertManagerLocal alertManager = LookupUtil.getAlertManager(); + + StringBuilder b = new StringBuilder("Alert -- "); + b.append(alert.getAlertDefinition().getName()); + b.append(" (on "); + b.append(alert.getAlertDefinition().getResource().getName()); + b.append("): "); + b.append(alertManager.prettyPrintAlertURL(alert)); + + return b.toString(); + } +} diff --git a/modules/enterprise/server/plugins/alert-irc/src/main/resources/META-INF/rhq-serverplugin.xml b/modules/enterprise/server/plugins/alert-irc/src/main/resources/META-INF/rhq-serverplugin.xml new file mode 100644 index 0000000..ba0f0ac --- /dev/null +++ b/modules/enterprise/server/plugins/alert-irc/src/main/resources/META-INF/rhq-serverplugin.xml @@ -0,0 +1,49 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<alert-plugin + name="alert-irc" + displayName="Alert:IRC" + xmlns="urn:xmlns:rhq-serverplugin.alert" + xmlns:c="urn:xmlns:rhq-configuration" + xmlns:serverplugin="urn:xmlns:rhq-serverplugin" + package="org.rhq.enterprise.server.plugins.alertIrc" + description="Alert sender plugin that sends alert notifications via IRC" + version="1.0" + > + + serverplugin:help + This alert sender plugin is used to send notifications via Internet Relay Chat + </serverplugin:help> + + <!-- startup & tear down listener, + scheduled jobs --> + <serverplugin:plugin-component class="IrcAlertComponent" /> + + <!-- Global preferences --> + serverplugin:plugin-configuration + <c:simple-property name="nick" type="string" default="rhq_alerts" /> + <c:simple-property name="server" type="string" default="irc.freenode.net" /> + <c:simple-property name="port" type="integer" default="6667" required="false" /> + <c:simple-property name="initialChannels" + type="string" + description="A comma-delimited list of channels that the irc bot will initially join (even if no alerts have fired)." + required="false" /> + <c:simple-property name="cannedResponse" + default="I am only here to notify you of RHQ alerts. I cannot understand you." + required="false" + description="A predefined response to send to users who try to engage in conversation with the IRC bot." /> + </serverplugin:plugin-configuration> + + <!-- How does this sender show up in drop downs etc --> + <short-name>IRC</short-name> + + <!-- Class that does the actual sending --> + <plugin-class>IrcSender</plugin-class> + + <!-- User configuration per alert --> + <alert-configuration> + <c:simple-property name="channel" + type="string" + description="The IRC channel used for notifications (if left blank, the alert will be sent to all joined channels)." + required="false" /> + </alert-configuration> +</alert-plugin>
commit 7991598c368c690b2ba76e338e2a1906120440a4 Merge: 5092e3a... 8d6058c... Author: Jay Shaughnessy jshaughn@redhat.com Date: Tue Dec 8 16:33:14 2009 -0500
Merge branch 'linux-config' into linux-config-dev
Conflicts: modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/perspective/metadata/PerspectivePluginMetadataManager.java
commit 8d6058c2073d6ee3f8782c9b1bd248a33456c189 Author: Jay Shaughnessy jshaughn@redhat.com Date: Tue Dec 8 16:31:24 2009 -0500
a git forced commit
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/common/perspective-main.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/common/perspective-main.xhtml index bebc4e9..3db1171 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/common/perspective-main.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/common/perspective-main.xhtml @@ -1,42 +1,42 @@ -<?xml version="1.0"?> - -<!DOCTYPE html - PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" - "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> - -<html - xmlns="http://www.w3.org/1999/xhtml" - xmlns:h="http://java.sun.com/jsf/html" - xmlns:f="http://java.sun.com/jsf/core" - xmlns:ui="http://java.sun.com/jsf/facelets" - xmlns:c="http://java.sun.com/jstl/core" - xmlns:onc="http://jboss.org/on/component" - xmlns:rich="http://richfaces.ajax4jsf.org/rich%22%3E - -<ui:composition template="/rhq/layout/main.xhtml"> - - <ui:param - name="pageTitle" - value="PERSPECTIVE PAGE" /> - - <ui:define name="breadcrumbs"> - <h:outputLink value="/">Custom</h:outputLink> - </ui:define> - - <ui:define name="body"> - - <iframe - id="perspective-main" - src="#{param.targetUrl}" - scrolling="no" - marginwidth="0" - marginheight="0" - frameborder="0" - style="overflow: visible; width: 100%; height: 100%;"> ERROR: Perspective-defined page could not be - embedded. Please make sure you're using IE6+ or FF2+. </iframe> - - </ui:define> - -</ui:composition> - -</html> +<?xml version="1.0"?> + +<!DOCTYPE html + PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<html + xmlns="http://www.w3.org/1999/xhtml" + xmlns:h="http://java.sun.com/jsf/html" + xmlns:f="http://java.sun.com/jsf/core" + xmlns:ui="http://java.sun.com/jsf/facelets" + xmlns:c="http://java.sun.com/jstl/core" + xmlns:onc="http://jboss.org/on/component" + xmlns:rich="http://richfaces.ajax4jsf.org/rich%22%3E + +<ui:composition template="/rhq/layout/main.xhtml"> + + <ui:param + name="pageTitle" + value="PERSPECTIVE PAGE" /> + + <ui:define name="breadcrumbs"> + <h:outputLink value="/">Custom</h:outputLink> + </ui:define> + + <ui:define name="body"> + + <iframe + id="perspective-main" + src="#{param.targetUrl}" + scrolling="no" + marginwidth="0" + marginheight="0" + frameborder="0" + style="overflow: visible; width: 100%; height: 100%;"> ERROR: Perspective-defined page could not be + embedded. Please make sure you're using IE6+ or FF2+. </iframe> + + </ui:define> + +</ui:composition> + +</html>
commit a7320f8debdb7409fb0e4e50fd16af27ae6a1c3d Author: Ian Springer ian.springer@redhat.com Date: Tue Dec 8 16:25:27 2009 -0500
get custom menu items and tabs working and loading external pages into iframes
diff --git a/etc/samples/perspectives/sample-perspective/perspective/src/main/resources/META-INF/rhq-serverplugin.xml b/etc/samples/perspectives/sample-perspective/perspective/src/main/resources/META-INF/rhq-serverplugin.xml index b5499b2..8151af2 100644 --- a/etc/samples/perspectives/sample-perspective/perspective/src/main/resources/META-INF/rhq-serverplugin.xml +++ b/etc/samples/perspectives/sample-perspective/perspective/src/main/resources/META-INF/rhq-serverplugin.xml @@ -33,7 +33,8 @@ <!-- remove the 'new' menu items from the group menuGroup and move them to the custom menuGroup --> <menuItem action="remove" - name="groups.newGroup"> + name="groups.newGroup" + displayName="New Group"> <position extensionPoint="coreMenu" name="groups.groupDefinitions" @@ -41,7 +42,8 @@ </menuItem> <menuItem action="remove" - name="groups.newGroupDefinition"> + name="groups.newGroupDefinition" + displayName="New Group Definition"> <position extensionPoint="coreMenu" name="groups.newGroup" @@ -67,7 +69,9 @@ </menuItem> <menuItem name="custom.child2" - displayName="Child-2"> + displayName="Child-2" + application="sample" + url="index.html"> <position extensionPoint="coreMenu" name="custom.child1" @@ -79,14 +83,14 @@ application="sample" url="/resource/group/Inventory.do?mode=new" iconUrl="images/create.png"> - <position - extensionPoint="coreMenu" - name="custom.child1" - placement="start" /> <globalPermissionActivatorSet> <globalPermissionActivator permission="MANAGE_INVENTORY" /> </globalPermissionActivatorSet> + <position + extensionPoint="coreMenu" + name="custom.child1" + placement="start" /> </menuItem> <menuItem name="custom.child1.newGroupDefinition" @@ -94,13 +98,30 @@ application="sample" url="/rhq/definition/group/new.xhtml" iconUrl="images/create.png"> + <globalPermissionActivatorSet> + <globalPermissionActivator + permission="MANAGE_INVENTORY" /> + </globalPermissionActivatorSet> <position extensionPoint="coreMenu" name="custom.child1.newGroup" placement="after" /> - <globalPermissionActivatorSet> - <globalPermissionActivator - permission="MANAGE_INVENTORY" /> - </globalPermissionActivatorSet> </menuItem> + + <tab name="Custom" displayName="Custom" iconUrl="/images/icons/Favorite_16.png" + application="sample" url="index.html"> + <position + extensionPoint="coreMenu" + name="Inventory" + placement="after" /> + </tab> + + <tab name="Monitor.Reports" displayName="Reports" + application="sample" url="index.html"> + <position + extensionPoint="coreMenu" + name="Monitor.Tables" + placement="after" /> + </tab> + </perspectivePlugin> \ No newline at end of file diff --git a/modules/core/dbutils/src/main/scripts/dbsetup/alert-schema.xml b/modules/core/dbutils/src/main/scripts/dbsetup/alert-schema.xml index f9560c1..e71ea82 100644 --- a/modules/core/dbutils/src/main/scripts/dbsetup/alert-schema.xml +++ b/modules/core/dbutils/src/main/scripts/dbsetup/alert-schema.xml @@ -130,7 +130,7 @@ <column name="SNMP_PORT" type="INTEGER"/> <column name="SNMP_OID" size="250" type="VARCHAR2"/> <column name="ALERT_CONFIG_ID" required="false" type="INTEGER" references="RHQ_CONFIG(ID)"/> - <column name="ALERT_SENDER_NAME" required="false" type="VARCHAR2" /> <!-- TODO make required = true --> + <column name="ALERT_SENDER_NAME" required="false" size="100" type="VARCHAR2" /> <!-- TODO make required = true --> </table>
</dbsetup> diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/common/tabbar/AbstractTabComponent.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/common/tabbar/AbstractTabComponent.java index fc42a7c..2e74566 100644 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/common/tabbar/AbstractTabComponent.java +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/common/tabbar/AbstractTabComponent.java @@ -48,6 +48,10 @@ public abstract class AbstractTabComponent extends UIComponentBase { }
public String getName() { + if (this.name == null) { + this.name = FacesComponentUtility.getExpressionAttribute(this, "name"); + } + return this.name; }
@@ -56,6 +60,10 @@ public abstract class AbstractTabComponent extends UIComponentBase { }
public String getDisplayName() { + if (this.displayName == null) { + this.displayName = FacesComponentUtility.getExpressionAttribute(this, "displayName"); + } + return this.displayName; }
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/inventory/resource/ResourceUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/inventory/resource/ResourceUIBean.java index edf0f6f..c919f6e 100644 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/inventory/resource/ResourceUIBean.java +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/inventory/resource/ResourceUIBean.java @@ -40,6 +40,8 @@ import org.rhq.core.domain.resource.composite.ResourcePermission; import org.rhq.enterprise.gui.util.EnterpriseFacesContextUtility; import org.rhq.enterprise.server.authz.AuthorizationManagerLocal; import org.rhq.enterprise.server.measurement.AvailabilityManagerLocal; +import org.rhq.enterprise.server.perspective.PerspectiveManagerLocal; +import org.rhq.enterprise.server.perspective.Tab; import org.rhq.enterprise.server.resource.ResourceManagerLocal; import org.rhq.enterprise.server.resource.ResourceTypeManagerLocal; import org.rhq.enterprise.server.util.LookupUtil; @@ -61,6 +63,7 @@ public class ResourceUIBean { private Resource parent; private ResourcePermission permissions; private ResourceFacets facets; + private List<Tab> tabs; private ResourceError invalidPluginConfigurationError; private ResourceAvailabilitySummary availabilitySummary; private AvailabilityType availabilityType; @@ -69,6 +72,7 @@ public class ResourceUIBean { private ResourceManagerLocal resourceManager = LookupUtil.getResourceManager(); private ResourceTypeManagerLocal resourceTypeManager = LookupUtil.getResourceTypeManager(); private AuthorizationManagerLocal authorizationManager = LookupUtil.getAuthorizationManager(); + private PerspectiveManagerLocal perspectiveManager = LookupUtil.getPerspectiveManager();
private String message;
@@ -96,6 +100,7 @@ public class ResourceUIBean { .getId()); this.permissions = new ResourcePermission(resourcePerms); this.facets = this.resourceTypeManager.getResourceFacets(getResourceType().getId()); + this.tabs = this.perspectiveManager.getResourceTabs(subject, this.resource);
//parent can be viewed by user only if he is allowed to see it if (parent != null) @@ -173,6 +178,10 @@ public class ResourceUIBean { return this.facets; }
+ public List<Tab> getTabs() { + return this.tabs; + } + @Nullable public ResourceError getInvalidPluginConfigurationError() { return this.invalidPluginConfigurationError; diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/common/perspective-main.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/common/perspective-main.xhtml new file mode 100644 index 0000000..bebc4e9 --- /dev/null +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/common/perspective-main.xhtml @@ -0,0 +1,42 @@ +<?xml version="1.0"?> + +<!DOCTYPE html + PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<html + xmlns="http://www.w3.org/1999/xhtml" + xmlns:h="http://java.sun.com/jsf/html" + xmlns:f="http://java.sun.com/jsf/core" + xmlns:ui="http://java.sun.com/jsf/facelets" + xmlns:c="http://java.sun.com/jstl/core" + xmlns:onc="http://jboss.org/on/component" + xmlns:rich="http://richfaces.ajax4jsf.org/rich%22%3E + +<ui:composition template="/rhq/layout/main.xhtml"> + + <ui:param + name="pageTitle" + value="PERSPECTIVE PAGE" /> + + <ui:define name="breadcrumbs"> + <h:outputLink value="/">Custom</h:outputLink> + </ui:define> + + <ui:define name="body"> + + <iframe + id="perspective-main" + src="#{param.targetUrl}" + scrolling="no" + marginwidth="0" + marginheight="0" + frameborder="0" + style="overflow: visible; width: 100%; height: 100%;"> ERROR: Perspective-defined page could not be + embedded. Please make sure you're using IE6+ or FF2+. </iframe> + + </ui:define> + +</ui:composition> + +</html> diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/layout/main.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/layout/main.xhtml index 3f5f94e..a21f6d2 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/layout/main.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/layout/main.xhtml @@ -65,63 +65,21 @@ REQUEST PARAMETERS:
<onc:tabBar selectedTabName="#{selectedTabName}">
- <f:param name="id" value="#{param.id}" /> - - <onc:tab name="Summary" image="/images/icons/#{ResourceUIBean.resourceType.category.displayName}_up_16.png"> - <onc:subtab name="Overview" url="/rhq/resource/summary/overview.xhtml" /> - <onc:subtab name="Timeline" url="/rhq/resource/summary/timeline.xhtml" /> - </onc:tab> - - <onc:tab name="Monitor" image="/images/icons/Monitor_grey_16.png" rendered="#{monitorEnabled}"> - <onc:subtab name="Graphs" url="/rhq/resource/monitor/graphs.xhtml" /> - <onc:subtab name="Tables" url="/rhq/resource/monitor/tables.xhtml" /> - <onc:subtab name="Traits" url="/rhq/resource/monitor/traits.xhtml" /> - <onc:subtab name="Availability" url="/rhq/resource/monitor/availabilityHistory.xhtml" /> - <onc:subtab name="Schedules" url="/rhq/resource/monitor/schedules.xhtml" /> - <c:if test="#{ResourceUIBean.facets.callTime}"> - <onc:subtab name="Response" url="/rhq/resource/monitor/response.xhtml" /> - </c:if> - </onc:tab> - - <onc:tab name="Inventory" image="/images/icons/Inventory_grey_16.png"> - <onc:subtab name="Overview" url="/rhq/resource/inventory/view.xhtml" /> - <c:if test="#{ResourceUIBean.facets.pluginConfiguration}"> - <onc:subtab name="Connection" url="/rhq/resource/inventory/view-connection.xhtml" /> - </c:if> - <onc:subtab name="Agent" url="/rhq/resource/inventory/view-agent.xhtml" /> - </onc:tab> - - <onc:tab name="Alert" image="/images/icons/Alert_grey_16.png" rendered="#{monitorEnabled}"> - <onc:subtab name="Definitions" url="/rhq/resource/alert/listAlertDefinitions.xhtml" /> - <onc:subtab name="History" url="/rhq/resource/alert/listAlertHistory.xhtml" /> - </onc:tab> - - <onc:tab name="Configuration" image="/images/icons/Configure_grey_16.png" displayName="Configure" rendered="#{ResourceUIBean.facets.configuration}"> - <onc:subtab name="Current" url="/rhq/resource/configuration/view.xhtml" /> - <onc:subtab name="History" url="/rhq/resource/configuration/history.xhtml" /> - </onc:tab> - - <onc:tab name="Operations" image="/images/icons/Operation_grey_16.png" rendered="#{ResourceUIBean.facets.operation}"> - <onc:subtab name="New" url="/rhq/resource/operation/resourceOperationScheduleNew.xhtml" /> - <onc:subtab name="Schedules" url="/rhq/resource/operation/resourceOperationSchedules.xhtml" /> - <onc:subtab name="History" url="/rhq/resource/operation/resourceOperationHistory.xhtml" /> - </onc:tab> - - <onc:tab name="Events" image="/images/icons/Events_grey_16.png" rendered="#{ResourceUIBean.facets.event}"> - <onc:subtab name="History" url="/rhq/resource/events/history.xhtml" /> - </onc:tab> - - <onc:tab name="Content" image="/images/icons/Content_grey_16.png" - rendered="#{ResourceUIBean.facets.content}"> - <onc:subtab name="Deployed" url="/rhq/resource/content/view.xhtml" /> - <onc:subtab name="New" url="/rhq/resource/content/deploy.xhtml" /> - <onc:subtab name="Subscriptions" url="/rhq/resource/content/subscription.xhtml" /> - <onc:subtab name="History" url="/rhq/resource/content/history.xhtml" /> - </onc:tab> - - <onc:tab name="Custom" image="/images/icons/Subcategory_16.png" - url="/rhq/resource/perspective/index.xhtml"> - </onc:tab> + <f:param name="id" value="#{param.id}" /> + + ui:remove===== Grab the tabs from the perspective manager =====</ui:remove> + + <c:forEach + var="tab" + items="#{ResourceUIBean.tabs}"> + <onc:tab name="#{tab.name}" displayName="#{tab.displayName}" image="#{tab.iconUrl}" url="#{tab.url}"> + <c:forEach + var="subtab" + items="#{tab.children}"> + <onc:subtab name="#{subtab.name}" displayName="#{subtab.displayName}" url="#{subtab.url}" /> + </c:forEach> + </onc:tab> + </c:forEach>
</onc:tabBar>
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/perspective/index.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/perspective/index.xhtml index 8034b2d..4b72ae2 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/perspective/index.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/perspective/index.xhtml @@ -16,9 +16,9 @@ THIS TEXT WILL BE REMOVED. THIS TEXT WILL BE REMOVED AS WELL.
<ui:param name="pageTitle" - value="#{ResourceUIBean.resourceType.name} '#{ResourceUIBean.name}' - Custom Perspective-Defined Tab"/> + value="#{ResourceUIBean.resourceType.name} '#{ResourceUIBean.name}' - Custom Perspective-Defined Page"/>
- <ui:param name="selectedTabName" value="Custom"/> + <ui:param name="selectedTabName" value="#{param.tab}"/>
<ui:define name="content">
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveManagerBean.java index 3d4f220..c74d1a1 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveManagerBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveManagerBean.java @@ -19,7 +19,6 @@ package org.rhq.enterprise.server.perspective;
import java.util.ArrayList; -import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -36,24 +35,33 @@ import org.jetbrains.annotations.NotNull; import org.rhq.core.domain.auth.Subject; import org.rhq.core.domain.authz.Permission; import org.rhq.core.domain.resource.Resource; +import org.rhq.core.domain.resource.composite.ResourceFacets; import org.rhq.enterprise.server.RHQConstants; import org.rhq.enterprise.server.auth.SubjectManagerLocal; import org.rhq.enterprise.server.authz.AuthorizationManagerLocal; +import org.rhq.enterprise.server.resource.ResourceTypeManagerLocal; +import org.rhq.enterprise.server.xmlschema.generated.serverplugin.perspective.FacetActivatorSetType; +import org.rhq.enterprise.server.xmlschema.generated.serverplugin.perspective.FacetActivatorType; import org.rhq.enterprise.server.xmlschema.generated.serverplugin.perspective.GlobalPermissionActivatorSetType; import org.rhq.enterprise.server.xmlschema.generated.serverplugin.perspective.GlobalPermissionActivatorType; import org.rhq.enterprise.server.xmlschema.generated.serverplugin.perspective.GlobalPermissionType; import org.rhq.enterprise.server.xmlschema.generated.serverplugin.perspective.MenuItemType; import org.rhq.enterprise.server.xmlschema.generated.serverplugin.perspective.ResourceActivatorSetType; +import org.rhq.enterprise.server.xmlschema.generated.serverplugin.perspective.ResourceActivatorType;
@Stateless // @WebService(endpointInterface = "org.rhq.enterprise.server.perspective.PerspectiveManagerRemote") +/** + * @author Jay Shaughnessy + * @author Ian Springer + */ public class PerspectiveManagerBean implements PerspectiveManagerLocal, PerspectiveManagerRemote {
private final Log log = LogFactory.getLog(PerspectiveManagerBean.class);
// Map of sessionId to cached menu entry. The cached menu is re-used for the same sessionId. - // This should more appropriately use Subject as the key but since Subject equality is - // based on username it's not quite appropriate. + // This should more appropriately use Subject as the key, but since Subject equality is + // based on username, it's not quite appropriate. // The cache is cleaned anytime there is a new entry. static private Map<Integer, CacheEntry> cache = new HashMap<Integer, CacheEntry>();
@@ -68,6 +76,9 @@ public class PerspectiveManagerBean implements PerspectiveManagerLocal, Perspect @EJB private SubjectManagerLocal subjectManager;
+ @EJB + private ResourceTypeManagerLocal resourceTypeManager; + /* (non-Javadoc) * @see org.rhq.enterprise.server.perspective.PerspectiveManagerLocal#getCoreMenu(org.rhq.core.domain.auth.Subject) */ @@ -106,8 +117,78 @@ public class PerspectiveManagerBean implements PerspectiveManagerLocal, Perspect
@NotNull public List<Tab> getResourceTabs(Subject subject, Resource resource) { - // TODO: implement - return Collections.emptyList(); + List<Tab> resourceTabs; + try + { + resourceTabs = PerspectiveManagerHelper.getPluginMetadataManager().getResourceTabs(); + } + catch (Exception e) + { + throw new RuntimeException(e); + } + + List<Tab> activeResourceTabs = new ArrayList<Tab>(); + ResourceFacets facets = this.resourceTypeManager.getResourceFacets(resource.getResourceType().getId()); + for (Tab resourceTab : resourceTabs) { + if (isActive(resourceTab, facets)) { + activeResourceTabs.add(resourceTab); + List<Tab> subtabs = resourceTab.getChildren(); + List<Tab> activeSubtabs = new ArrayList<Tab>(); + for (Tab subtab : subtabs) + { + if (isActive(subtab, facets)) { + activeSubtabs.add(subtab); + } + } + resourceTab.setChildren(activeSubtabs); + } + } + // TODO: Cache these at some level. + return activeResourceTabs; + } + + private boolean isActive(Tab resourceTab, ResourceFacets facets) + { + // TODO: Check global perm activators. + // TODO: Check monitoring license activator. + List<ResourceActivatorSetType> currentResourceActivatorSets = resourceTab.getCurrentResourceOrGroupActivatorSets(); + if (currentResourceActivatorSets != null) { + for (ResourceActivatorSetType currentResourceActivatorSet : currentResourceActivatorSets) { + List<ResourceActivatorType> resourceActivators = currentResourceActivatorSet.getResourceActivator(); + for (ResourceActivatorType resourceActivator : resourceActivators) { + // TODO: Check resourceType activators. + // TODO: Check resource permission activators. + FacetActivatorSetType facetActivatorSet = resourceActivator.getFacetActivatorSet(); + List<FacetActivatorType> facetActivators = facetActivatorSet.getFacetActivator(); + for (FacetActivatorType facetActivator : facetActivators) { + String facetName = facetActivator.getFacet().value(); + // TODO: Create a Facets enum to avoid these ugly string comparisons. + if (facetName.equals("measurement") && !facets.isMeasurement()) { + return false; + } + if (facetName.equals("event") && !facets.isEvent()) { + return false; + } + if (facetName.equals("pluginConfiguration") && !facets.isPluginConfiguration()) { + return false; + } + if (facetName.equals("configuration") && !facets.isConfiguration()) { + return false; + } + if (facetName.equals("operation") && !facets.isOperation()) { + return false; + } + if (facetName.equals("content") && !facets.isOperation()) { + return false; + } + if (facetName.equals("callTime") && !facets.isCallTime()) { + return false; + } + } + } + } + } + return true; }
/** diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/perspective/Tab.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/perspective/Tab.java index 5090824..f4035ad 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/perspective/Tab.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/perspective/Tab.java @@ -18,8 +18,17 @@ */ package org.rhq.enterprise.server.perspective;
+import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collections; import java.util.List;
+import org.jetbrains.annotations.NotNull; +import org.rhq.enterprise.server.xmlschema.generated.serverplugin.perspective.ResourceActivatorSetType; import org.rhq.enterprise.server.xmlschema.generated.serverplugin.perspective.TabType;
/** @@ -27,22 +36,35 @@ import org.rhq.enterprise.server.xmlschema.generated.serverplugin.perspective.Ta * * @author Ian Springer */ -public class Tab +public class Tab implements Serializable, Cloneable { + private static final long serialVersionUID = 1L; + private List<Tab> children; + private String qualifiedName; private String name; private String displayName; private String url; private String iconUrl; + transient private List<ResourceActivatorSetType> currentResourceOrGroupActivatorSet;
public Tab(TabType tab) { - this.name = tab.getName(); + this.qualifiedName = tab.getName(); + int lastDotIndex = this.qualifiedName.lastIndexOf("."); + this.name = this.qualifiedName.substring(lastDotIndex + 1); this.displayName = tab.getDisplayName(); this.url = tab.getUrl(); + if (tab.getApplication() != null) { + this.url += "&tab=" + this.qualifiedName; + } this.iconUrl = tab.getIconUrl(); + this.currentResourceOrGroupActivatorSet = (tab.getCurrentResourceOrGroupActivatorSet() != null) ? + tab.getCurrentResourceOrGroupActivatorSet() : Collections.<ResourceActivatorSetType>emptyList(); + this.children = new ArrayList<Tab>(); }
+ @NotNull public List<Tab> getChildren() { return children; @@ -50,7 +72,12 @@ public class Tab
public void setChildren(List<Tab> children) { - this.children = children; + this.children = (children != null) ? children : new ArrayList<Tab>(); + } + + public String getQualifiedName() + { + return qualifiedName; }
public String getName() @@ -72,4 +99,69 @@ public class Tab { return iconUrl; } + + @NotNull + public List<ResourceActivatorSetType> getCurrentResourceOrGroupActivatorSets() + { + return currentResourceOrGroupActivatorSet; + } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + Tab tab = (Tab)o; + + if (!name.equals(tab.name)) return false; + + return true; + } + + @Override + public int hashCode() + { + return name.hashCode(); + } + + @Override + public String toString() { + return this.getClass().getSimpleName() + "[name=" + this.name + ", displayName=" + this.displayName + ", url=" + this.url + ", iconUrl=" + + this.iconUrl + "]"; + } + + @Override + public Tab clone() throws CloneNotSupportedException { + Object obj = null; + try { + // Write the object out to a byte array + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + ObjectOutputStream out = new ObjectOutputStream(bos); + out.writeObject(this); + out.flush(); + out.close(); + + // Make an input stream from the byte array and read + // a copy of the object back in. + ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(bos.toByteArray())); + obj = in.readObject(); + } catch (Exception e) { + e.printStackTrace(); + } + + Tab tab = (Tab)obj; + if (tab != null) { + tab.currentResourceOrGroupActivatorSet = this.currentResourceOrGroupActivatorSet; + List<Tab> subtabs = tab.getChildren(); + if (subtabs != null) { + for (int i = 0, subtabsSize = subtabs.size(); i < subtabsSize; i++) + { + Tab subtab = subtabs.get(i); + subtab.currentResourceOrGroupActivatorSet = this.children.get(i).currentResourceOrGroupActivatorSet; + } + } + } + return tab; + } } diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/perspective/metadata/PerspectivePluginMetadataManager.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/perspective/metadata/PerspectivePluginMetadataManager.java index d657ef6..6d56ee3 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/perspective/metadata/PerspectivePluginMetadataManager.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/perspective/metadata/PerspectivePluginMetadataManager.java @@ -27,9 +27,11 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory;
import org.rhq.enterprise.server.perspective.MenuItem; +import org.rhq.enterprise.server.perspective.Tab; import org.rhq.enterprise.server.xmlschema.generated.serverplugin.perspective.ActionType; import org.rhq.enterprise.server.xmlschema.generated.serverplugin.perspective.ApplicationType; import org.rhq.enterprise.server.xmlschema.generated.serverplugin.perspective.ExtensionPointType; +import org.rhq.enterprise.server.xmlschema.generated.serverplugin.perspective.ExtensionType; import org.rhq.enterprise.server.xmlschema.generated.serverplugin.perspective.MenuItemType; import org.rhq.enterprise.server.xmlschema.generated.serverplugin.perspective.PerspectivePluginDescriptorType; import org.rhq.enterprise.server.xmlschema.generated.serverplugin.perspective.PlacementType; @@ -39,7 +41,7 @@ import org.rhq.enterprise.server.xmlschema.generated.serverplugin.perspective.Ta
/** * This loads in all deployed perspective server plugins and maintains the complete set of - * {@link #getMetadataManager() metadata} found in all plugin descriptors. Individual plugin + * metadata found in all plugin descriptors. Individual plugin * metadata is irrelevant and not retrievable. The union of the perspective definitions is * maintained and made available. Conflict resolution rules are applied as needed for * clashing perspective definitions. @@ -48,10 +50,14 @@ import org.rhq.enterprise.server.xmlschema.generated.serverplugin.perspective.Ta * plugin-load-time. * * @author Jay Shaughnessy + * @author Ian Springer */ public class PerspectivePluginMetadataManager { private final String CORE_PERSPECTIVE_NAME = "CorePerspective";
+ private static final String MENU_ITEM_TARGET_URL = "/rhq/common/perspective-main.xhtml?targetUrl="; + private static final String TAB_TARGET_URL = "/rhq/resource/perspective/index.xhtml?targetUrl="; + private Log log = LogFactory.getLog(PerspectivePluginMetadataManager.class);
//private static PerspectivePluginMetadataManager manager = new PerspectivePluginMetadataManager(); @@ -59,10 +65,10 @@ public class PerspectivePluginMetadataManager { private Map<String, PerspectivePluginDescriptorType> loadedPlugins = new HashMap<String, PerspectivePluginDescriptorType>();
private boolean isStarted = false; - private List<TaskType> globalTasks = null; - private List<TaskType> resourceTasks = null; - private List<TabType> tabs; - private List<MenuItem> coreMenu = null; + private List<Tab> resourceTabs; + private List<MenuItem> coreMenu; + +
public PerspectivePluginMetadataManager() { } @@ -71,8 +77,6 @@ public class PerspectivePluginMetadataManager { * Transforms the pluginDescriptor into domain object form and stores those objects. * * @param descriptor the descriptor to transform - * - * @return void */ public synchronized void loadPlugin(PerspectivePluginDescriptorType descriptor) { loadedPlugins.put(descriptor.getName(), descriptor); @@ -101,15 +105,17 @@ public class PerspectivePluginMetadataManager { + CORE_PERSPECTIVE_NAME); }
- this.globalTasks = cp.getGlobalTask(); - this.resourceTasks = cp.getResourceTask(); - this.tabs = cp.getTab(); // TODO + // TODO: Init lists of global tasks and resource tasks.
// Setup core menus if (null == this.coreMenu) { this.coreMenu = new ArrayList<MenuItem>(); }
+ if (null == this.resourceTabs) { + this.resourceTabs = new ArrayList<Tab>(); + } + processPerspective(cp);
// TODO: remove this debug code @@ -127,11 +133,13 @@ public class PerspectivePluginMetadataManager { //printMenu(this.coreMenu, ""); }
- private void processPerspective(PerspectivePluginDescriptorType perspective) { + private void processPerspective(PerspectivePluginDescriptorType perspective) { List<ApplicationType> applications = perspective.getApplication();
+ // TODO: Process global tasks and resource tasks. + for (MenuItemType rawMenuItem : perspective.getMenuItem()) { - resolveUrls(applications, rawMenuItem); + resolveUrls(applications, rawMenuItem, MENU_ITEM_TARGET_URL); ActionType action = rawMenuItem.getAction(); ExtensionPointType extensionPoint = rawMenuItem.getPosition().getExtensionPoint(); if (ExtensionPointType.CORE_MENU == extensionPoint) { @@ -147,22 +155,48 @@ public class PerspectivePluginMetadataManager { + rawMenuItem.getName() + "] : " + extensionPoint); } } + + for (TabType rawTab : perspective.getTab()) { + resolveUrls(applications, rawTab, TAB_TARGET_URL); + ActionType action = rawTab.getAction(); + switch (action) { + case ADD: addTab(rawTab); break; + case REMOVE: removeTab(rawTab); break; + case REPLACE: replaceTab(rawTab); break; + } + } }
/** - * Update the url and iconUrl as needed by applying delclard application information. + * Update the url and iconUrl as needed by applying declared application information. * * @param applications - * @param rawMenuItem + * @param extension */ - private void resolveUrls(List<ApplicationType> applications, MenuItemType rawMenuItem) { - ApplicationType applicationType = getApplicationByName(applications, rawMenuItem.getApplication()); + private void resolveUrls(List<ApplicationType> applications, ExtensionType extension, String targetUrl) { + ApplicationType applicationType = getApplicationByName(applications, extension.getApplication());
- rawMenuItem.setUrl(resolveUrl(applicationType, rawMenuItem.getUrl())); - rawMenuItem.setIconUrl(resolveUrl(applicationType, rawMenuItem.getIconUrl())); + if (extension instanceof TaskType) { + TaskType task = (TaskType)extension; + String resolvedUrl = resolveUrl(applicationType, task.getUrl(), targetUrl); + task.setUrl(resolvedUrl); + } + else if (extension instanceof MenuItemType) { + MenuItemType menuItem = (MenuItemType)extension; + String resolvedUrl = resolveUrl(applicationType, menuItem.getUrl(), targetUrl); + menuItem.setUrl(resolvedUrl); + } + else if (extension instanceof TabType) { + TabType tab = (TabType)extension; + String resolvedUrl = resolveUrl(applicationType, tab.getUrl(), targetUrl); + tab.setUrl(resolvedUrl); + } + + String resolvedIconUrl = resolveUrl(applicationType, extension.getIconUrl(), ""); + extension.setIconUrl(resolvedIconUrl); }
- private String resolveUrl(ApplicationType applicationType, String url) { + private String resolveUrl(ApplicationType applicationType, String url, String targetUrl) { String result = url;
if (null != url) { @@ -176,10 +210,10 @@ public class PerspectivePluginMetadataManager { String baseUrl = applicationType.getBaseUrl(); // fix the baseUrl if it lacks the separator if (!baseUrl.endsWith("/")) { - baseUrl = baseUrl + "/"; + baseUrl += "/"; applicationType.setBaseUrl(baseUrl); } - result = baseUrl + url; + result = targetUrl + baseUrl + url; } }
@@ -218,7 +252,6 @@ public class PerspectivePluginMetadataManager { }
private void menuAdd(List<MenuItem> menu, MenuItemType rawMenuItem) { - PositionType position = rawMenuItem.getPosition(); List<MenuItem> containingMenu = getContainingMenu(menu, rawMenuItem); MenuItem menuItem = new MenuItem(rawMenuItem); @@ -240,7 +273,6 @@ public class PerspectivePluginMetadataManager { }
private void menuRemove(List<MenuItem> menu, MenuItemType rawMenuItem) { - PositionType position = rawMenuItem.getPosition(); List<MenuItem> containingMenu; try { @@ -262,7 +294,6 @@ public class PerspectivePluginMetadataManager { }
private void menuReplace(List<MenuItem> menu, MenuItemType rawMenuItem) { - PositionType position = rawMenuItem.getPosition(); List<MenuItem> containingMenu; try { @@ -320,6 +351,97 @@ public class PerspectivePluginMetadataManager { return result; }
+ private void addTab(TabType rawTab) { + PositionType position = rawTab.getPosition(); + List<Tab> siblingTabs = getSiblingTabs(rawTab); + Tab tab = new Tab(rawTab); + + if (PlacementType.START == position.getPlacement()) { + siblingTabs.add(0, tab); + } else if (PlacementType.END == position.getPlacement()) { + siblingTabs.add(tab); + } else { + int index = getTabIndex(siblingTabs, position.getName()); + if (index == -1) { + throw new IllegalArgumentException("Invalid position defined for tab [" + rawTab.getName() + + "]. Referenced tab not found : " + position.getName() + + ". Make sure supporting tabs are defined for the tab."); + } + siblingTabs.add((PlacementType.AFTER == position.getPlacement() ? ++index : --index), tab); + } + } + + private void removeTab(TabType rawTab) { + PositionType position = rawTab.getPosition(); + List<Tab> siblingTabs; + try { + siblingTabs = getSiblingTabs(rawTab); + int index = getTabIndex(siblingTabs, rawTab.getName()); + if (index == -1) { + throw new IllegalArgumentException("Invalid position defined for menuItem [" + rawTab.getName() + + "]. Referenced menuItem not found : " + position.getName() + + ". Make sure supporting menus are defined for the menuItem."); + } + siblingTabs.remove(index); + } catch (IllegalArgumentException e) { + if (log.isDebugEnabled()) { + log.debug("Tab not found. Ignoring removal of tab [" + rawTab.getName() + "].", e); + } + } + } + + private void replaceTab(TabType rawTab) { + PositionType position = rawTab.getPosition(); + List<Tab> siblingTabs; + try { + siblingTabs = getSiblingTabs(rawTab); + int index = getTabIndex(siblingTabs, rawTab.getName()); + if (-1 == index) { + throw new IllegalArgumentException("Invalid position defined for tab [" + rawTab.getName() + + "]. Referenced tab not found : " + position.getName() + + ". Make sure supporting tabs are defined for the tab."); + } + siblingTabs.set(index, new Tab(rawTab)); + } catch (IllegalArgumentException e) { + if (log.isDebugEnabled()) { + log.debug("Tab not found. Ignoring replacement and attempting add for " + rawTab.getName(), + e); + } + addTab(rawTab); + } + } + + private List<Tab> getSiblingTabs(TabType rawTab) { + String name = rawTab.getName(); + String[] nameTokens = (name != null) ? name.split("\.") : new String[0]; + List<Tab> result = this.resourceTabs; + + for (int i = 0; (i + 1) < nameTokens.length; i++) { + int index = getTabIndex(result, nameTokens[i]); + if (index == -1) { + throw new IllegalArgumentException("Invalid position defined for tab [" + rawTab.getName() + + "]. No parent tab found for : " + name + + ". Make sure supporting tabs are defined for the tab."); + } + Tab parentTab = result.get(index); + result = parentTab.getChildren(); + } + + return result; + } + + private int getTabIndex(List<Tab> menu, String name) { + int result = -1; + + for (int i = 0, size = menu.size(); (i < size); ++i) { + if (menu.get(i).getQualifiedName().endsWith(name)) { + result = i; + break; + } + } + return result; + } + /** * @return the coreMenu */ @@ -327,18 +449,19 @@ public class PerspectivePluginMetadataManager { return coreMenu; }
- public List<TaskType> getGlobalTasks() + public List<Tab> getResourceTabs() { - return globalTasks; - } - - public List<TaskType> getResourceTasks() - { - return resourceTasks; - } - - public List<TabType> getTabs() - { - return tabs; + List<Tab> clone = new ArrayList<Tab>(this.resourceTabs.size()); + for (Tab resourceTab : this.resourceTabs) { + try + { + clone.add(resourceTab.clone()); + } + catch (CloneNotSupportedException e) + { + throw new IllegalStateException(e); + } + } + return clone; } } diff --git a/modules/enterprise/server/plugins/perspectives/core/perspective/src/main/resources/META-INF/rhq-serverplugin.xml b/modules/enterprise/server/plugins/perspectives/core/perspective/src/main/resources/META-INF/rhq-serverplugin.xml index 9ac6738..6c3fc99 100644 --- a/modules/enterprise/server/plugins/perspectives/core/perspective/src/main/resources/META-INF/rhq-serverplugin.xml +++ b/modules/enterprise/server/plugins/perspectives/core/perspective/src/main/resources/META-INF/rhq-serverplugin.xml @@ -57,14 +57,14 @@ name="debug" displayName="Debug" isDebug="true"> + <globalPermissionActivatorSet> + <globalPermissionActivator + permission="SUPERUSER" /> + </globalPermissionActivatorSet> <position extensionPoint="coreMenu" name="administration" placement="after" /> - <globalPermissionActivatorSet> - <globalPermissionActivator - permission="SUPERUSER" /> - </globalPermissionActivatorSet> </menuItem> <menuItem name="help" @@ -201,28 +201,28 @@ name="groups.newGroup" displayName="New Group" url="/resource/group/Inventory.do?mode=new"> + <globalPermissionActivatorSet> + <globalPermissionActivator + permission="MANAGE_INVENTORY" /> + </globalPermissionActivatorSet> <position extensionPoint="coreMenu" name="groups.groupDefinitions" placement="after" addBreak="true" /> - <globalPermissionActivatorSet> - <globalPermissionActivator - permission="MANAGE_INVENTORY" /> - </globalPermissionActivatorSet> </menuItem> <menuItem name="groups.newGroupDefinition" displayName="New Group Definition" url="/rhq/definition/group/new.xhtml"> + <globalPermissionActivatorSet> + <globalPermissionActivator + permission="MANAGE_INVENTORY" /> + </globalPermissionActivatorSet> <position extensionPoint="coreMenu" name="groups.newGroup" placement="after" /> - <globalPermissionActivatorSet> - <globalPermissionActivator - permission="MANAGE_INVENTORY" /> - </globalPermissionActivatorSet> </menuItem> <menuItem name="groups.favoriteGroups" @@ -269,41 +269,41 @@ <menuItem name="administration.systemConfiguration" displayName="System Configuration"> + <globalPermissionActivatorSet + any="true"> + <globalPermissionActivator + permission="MANAGE_INVENTORY" /> + <globalPermissionActivator + permission="MANAGE_SETTINGS" /> + </globalPermissionActivatorSet> <position extensionPoint="coreMenu" name="administration.security" placement="after" /> - <globalPermissionActivatorSet - any="true"> - <globalPermissionActivator - permission="MANAGE_INVENTORY" /> - <globalPermissionActivator - permission="MANAGE_SETTINGS" /> - </globalPermissionActivatorSet> </menuItem> <menuItem name="administration.content" displayName="Content"> + <globalPermissionActivatorSet> + <globalPermissionActivator + permission="MANAGE_INVENTORY" /> + </globalPermissionActivatorSet> <position extensionPoint="coreMenu" name="administration.systemConfiguration" placement="after" /> - <globalPermissionActivatorSet> - <globalPermissionActivator - permission="MANAGE_INVENTORY" /> - </globalPermissionActivatorSet> </menuItem> <menuItem name="administration.highAvailability" displayName="High Availability"> + <globalPermissionActivatorSet> + <globalPermissionActivator + permission="MANAGE_INVENTORY" /> + </globalPermissionActivatorSet> <position extensionPoint="coreMenu" name="administration.content" placement="after" /> - <globalPermissionActivatorSet> - <globalPermissionActivator - permission="MANAGE_INVENTORY" /> - </globalPermissionActivatorSet> </menuItem> <menuItem name="administration.reports" @@ -327,14 +327,14 @@ name="administration.license" displayName="License" url="/admin/license/LicenseAdmin.do?mode=view"> + <globalPermissionActivatorSet> + <globalPermissionActivator + permission="MANAGE_SETTINGS" /> + </globalPermissionActivatorSet> <position extensionPoint="coreMenu" name="administration.download" placement="after" /> - <globalPermissionActivatorSet> - <globalPermissionActivator - permission="MANAGE_SETTINGS" /> - </globalPermissionActivatorSet> </menuItem>
<!-- Core Menu: Debug --> @@ -509,40 +509,40 @@ name="administration.systemConfiguration.settings" displayName="Settings" url="/admin/config/Config.do?mode=edit"> + <globalPermissionActivatorSet> + <globalPermissionActivator + permission="MANAGE_SETTINGS" /> + </globalPermissionActivatorSet> <position extensionPoint="coreMenu" name="administration.systemConfiguration" placement="start" /> - <globalPermissionActivatorSet> - <globalPermissionActivator - permission="MANAGE_SETTINGS" /> - </globalPermissionActivatorSet> </menuItem> <menuItem name="administration.systemConfiguration.plugins" displayName="Plugins" url="/rhq/admin/plugin/plugin-list.xhtml"> + <globalPermissionActivatorSet> + <globalPermissionActivator + permission="MANAGE_SETTINGS" /> + </globalPermissionActivatorSet> <position extensionPoint="coreMenu" name="administration.systemConfiguration.settings" placement="after" /> - <globalPermissionActivatorSet> - <globalPermissionActivator - permission="MANAGE_SETTINGS" /> - </globalPermissionActivatorSet> </menuItem> <menuItem name="administration.systemConfiguration.templates" displayName="Templates" url="/admin/config/EditDefaults.do?mode=monitor&viewMode=all"> + <globalPermissionActivatorSet> + <globalPermissionActivator + permission="MANAGE_INVENTORY" /> + </globalPermissionActivatorSet> <position extensionPoint="coreMenu" name="administration.systemConfiguration.plugins" placement="after" /> - <globalPermissionActivatorSet> - <globalPermissionActivator - permission="MANAGE_INVENTORY" /> - </globalPermissionActivatorSet> </menuItem>
<!-- Core Menu: administration.content --> @@ -615,5 +615,275 @@ </menuItem>
+ <!-- Top-level Tabs --> + <tab name="Summary" displayName="Summary" iconUrl="/images/icons/Service_up_16.png"> + <position + extensionPoint="coreMenu" + placement="start" /> + </tab>
+ <tab name="Monitor" displayName="Monitor" iconUrl="/images/icons/Monitor_grey_16.png"> + <monitoringLicenseActivator/> + <position + extensionPoint="coreMenu" + name="Summary" + placement="after" /> + </tab> + + <tab name="Inventory" displayName="Inventory" iconUrl="/images/icons/Inventory_grey_16.png"> + <position + extensionPoint="coreMenu" + name="Monitor" + placement="after" /> + </tab> + + <tab name="Alert" displayName="Alert" iconUrl="/images/icons/Alert_grey_16.png"> + <monitoringLicenseActivator/> + <position + extensionPoint="coreMenu" + name="Inventory" + placement="after" /> + </tab> + + <tab name="Configuration" displayName="Configuration" iconUrl="/images/icons/Configure_grey_16.png"> + <currentResourceOrGroupActivatorSet> + <resourceActivator> + <facetActivatorSet> + <facetActivator facet="configuration"/> + </facetActivatorSet> + </resourceActivator> + </currentResourceOrGroupActivatorSet> + <position + extensionPoint="coreMenu" + name="Alert" + placement="after" /> + </tab> + + <tab name="Operations" displayName="Operations" iconUrl="/images/icons/Operation_grey_16.png"> + <currentResourceOrGroupActivatorSet> + <resourceActivator> + <facetActivatorSet> + <facetActivator facet="operation"/> + </facetActivatorSet> + </resourceActivator> + </currentResourceOrGroupActivatorSet> + <position + extensionPoint="coreMenu" + name="Configuration" + placement="after" /> + </tab> + + <tab name="Events" displayName="Events" iconUrl="/images/icons/Events_grey_16.png"> + <currentResourceOrGroupActivatorSet> + <resourceActivator> + <facetActivatorSet> + <facetActivator facet="event"/> + </facetActivatorSet> + </resourceActivator> + </currentResourceOrGroupActivatorSet> + <position + extensionPoint="coreMenu" + name="Operations" + placement="after" /> + </tab> + + <tab name="Content" displayName="Content" iconUrl="/images/icons/Content_grey_16.png"> + <currentResourceOrGroupActivatorSet> + <resourceActivator> + <facetActivatorSet> + <facetActivator facet="content"/> + </facetActivatorSet> + </resourceActivator> + </currentResourceOrGroupActivatorSet> + <position + extensionPoint="coreMenu" + name="Events" + placement="after" /> + </tab> + + <!-- Summary Subtabs --> + <tab name="Summary.Overview" displayName="Overview" url="/rhq/resource/summary/overview.xhtml"> + <position + extensionPoint="coreMenu" + name="Summary" + placement="start" /> + </tab> + + <tab name="Summary.Timeline" displayName="Timeline" url="/rhq/resource/summary/timeline.xhtml"> + <position + extensionPoint="coreMenu" + name="Summary.Overview" + placement="after" /> + </tab> + + <!-- Monitor Subtabs --> + <tab name="Monitor.Graphs" displayName="Graphs" url="/rhq/resource/monitor/graphs.xhtml"> + <position + extensionPoint="coreMenu" + name="Monitor" + placement="start" /> + </tab> + + <tab name="Monitor.Tables" displayName="Tables" url="/rhq/resource/monitor/tables.xhtml"> + <position + extensionPoint="coreMenu" + name="Monitor.Graphs" + placement="after" /> + </tab> + + <tab name="Monitor.Traits" displayName="Traits" url="/rhq/resource/monitor/traits.xhtml"> + <position + extensionPoint="coreMenu" + name="Monitor.Tables" + placement="after" /> + </tab> + + <tab name="Monitor.Availability" displayName="Availability" url="/rhq/resource/monitor/availabilityHistory.xhtml"> + <position + extensionPoint="coreMenu" + name="Monitor.Traits" + placement="after" /> + </tab> + + <tab name="Monitor.Schedules" displayName="Schedules" url="/rhq/resource/monitor/schedules.xhtml"> + <position + extensionPoint="coreMenu" + name="Monitor.Availability" + placement="after" /> + </tab> + + <tab name="Monitor.Response" displayName="Response" url="/rhq/resource/monitor/response.xhtml"> + <currentResourceOrGroupActivatorSet> + <resourceActivator> + <facetActivatorSet> + <facetActivator facet="callTime"/> + </facetActivatorSet> + </resourceActivator> + </currentResourceOrGroupActivatorSet> + + <position + extensionPoint="coreMenu" + name="Monitor.Schedules" + placement="after" /> + </tab> + + <!-- Inventory Subtabs --> + <tab name="Inventory.Overview" displayName="Overview" url="/rhq/resource/inventory/view.xhtml"> + <position + extensionPoint="coreMenu" + name="Inventory" + placement="start" /> + </tab> + + <tab name="Inventory.Connection" displayName="Connection" url="/rhq/resource/inventory/view-connection.xhtml"> + <currentResourceOrGroupActivatorSet> + <resourceActivator> + <facetActivatorSet> + <facetActivator facet="pluginConfiguration"/> + </facetActivatorSet> + </resourceActivator> + </currentResourceOrGroupActivatorSet> + + <position + extensionPoint="coreMenu" + name="Inventory.Overview" + placement="after" /> + </tab> + + <tab name="Inventory.Agent" displayName="Agent" url="/rhq/resource/inventory/view-agent.xhtml"> + <position + extensionPoint="coreMenu" + name="Inventory.Connection" + placement="after" /> + </tab> + + <!-- Alert Subtabs --> + <tab name="Alert.Definitions" displayName="Definitions" url="/rhq/resource/alert/listAlertDefinitions.xhtml"> + <position + extensionPoint="coreMenu" + name="Alert" + placement="start" /> + </tab> + + <tab name="Alert.History" displayName="History" url="/rhq/resource/alert/listAlertHistory.xhtml"> + <position + extensionPoint="coreMenu" + name="Alert.Definitions" + placement="after" /> + </tab> + + <!-- Configuration Subtabs --> + <tab name="Configuration.Current" displayName="Current" url="/rhq/resource/configuration/view.xhtml"> + <position + extensionPoint="coreMenu" + name="Configuration" + placement="start" /> + </tab> + + <tab name="Configuration.History" displayName="History" url="/rhq/resource/configuration/history.xhtml"> + <position + extensionPoint="coreMenu" + name="Configuration.Current" + placement="after" /> + </tab> + + <!-- Operations Subtabs --> + <tab name="Operations.New" displayName="New" url="/rhq/resource/operation/resourceOperationScheduleNew.xhtml"> + <position + extensionPoint="coreMenu" + name="Operations" + placement="start" /> + </tab> + + <tab name="Operations.Schedules" displayName="Schedules" url="/rhq/resource/operation/resourceOperationSchedules.xhtml"> + <position + extensionPoint="coreMenu" + name="Operations.New" + placement="after" /> + </tab> + + <tab name="Operations.History" displayName="History" url="/rhq/resource/operation/resourceOperationHistory.xhtml"> + <position + extensionPoint="coreMenu" + name="Operations.Schedules" + placement="after" /> + </tab> + + <!-- Events Subtabs --> + <tab name="Events.History" displayName="History" url="/rhq/resource/events/history.xhtml"> + <position + extensionPoint="coreMenu" + name="Events" + placement="start" /> + </tab> + + <!-- Content Subtabs --> + <tab name="Content.Deployed" displayName="Deployed" url="/rhq/resource/content/view.xhtml"> + <position + extensionPoint="coreMenu" + name="Content" + placement="start" /> + </tab> + + <tab name="Content.New" displayName="New" url="/rhq/resource/content/deploy.xhtml"> + <position + extensionPoint="coreMenu" + name="Content.Deployed" + placement="after" /> + </tab> + + <tab name="Content.Subscriptions" displayName="Subscriptions" url="/rhq/resource/content/subscription.xhtml"> + <position + extensionPoint="coreMenu" + name="Content.New" + placement="after" /> + </tab> + + <tab name="Content.History" displayName="History" url="/rhq/resource/content/history.xhtml"> + <position + extensionPoint="coreMenu" + name="Content.Subscriptions" + placement="after" /> + </tab> + </perspectivePlugin> diff --git a/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-perspective.xsd b/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-perspective.xsd index 851e8e7..d915048 100644 --- a/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-perspective.xsd +++ b/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-perspective.xsd @@ -127,129 +127,164 @@ xs:documentationAdd a Global Task extension.</xs:documentation> xs:appinfo <jaxb:class - name="PerspectiveGlobalTaskElement" /> + name="GlobalTaskElement" /> </xs:appinfo> </xs:annotation> </xs:element>
<xs:element name="resourceTask" - type="perspective:TaskType"> + type="perspective:ResourceTaskType"> xs:annotation xs:documentationAdd a Resource Task extension.</xs:documentation> xs:appinfo <jaxb:class - name="PerspectiveResourceTaskElement" /> + name="ResourceTaskElement" /> </xs:appinfo> </xs:annotation> </xs:element>
+ <xs:complexType name="ExtensionType" abstract="true"> + xs:sequence + <xs:element + ref="perspective:description" + minOccurs="0" + maxOccurs="1"> + xs:annotation + xs:documentationVerbose description for the extension. Displayed via a tooltip in the GUI. + </xs:documentation> + </xs:annotation> + </xs:element> + <xs:element + ref="perspective:globalPermissionActivatorSet" + minOccurs="0" + maxOccurs="unbounded"> + xs:annotation + xs:documentationActivate the extension only if the user has the required global permissions. + </xs:documentation> + </xs:annotation> + </xs:element> + <xs:element + ref="perspective:monitoringLicenseActivator" + minOccurs="0" + maxOccurs="1"> + xs:annotation + xs:documentationActivate the extension only if a monitoring license is installed. + </xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + + <xs:attribute + name="name" + type="perspective:NameType" + use="required"> + xs:annotation + xs:documentation + Internal name for this extension. Unique within extensions of a certain type defined by the perspective. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute + name="displayName" + type="perspective:DisplayNameType" + use="required"> + xs:annotation + xs:documentationThe display name for this extension.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute + name="iconUrl" + type="xs:anyURI" + use="optional"> + xs:annotation + xs:documentationThe request URL for the icon displayed for this extension. If omitted, no icon is + displayed. Required if displayName is an empty string.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute + name="application" + type="xs:string" + use="optional"> + xs:annotation + xs:documentationThe application servicing the URLs for this extension. Default is root (rhq-portal.war). + </xs:documentation> + </xs:annotation> + </xs:attribute> + xs:anyAttribute/ + </xs:complexType> + <xs:complexType name="TaskType"> - xs:sequence - <xs:element - ref="perspective:extensionPoint" - minOccurs="0" - maxOccurs="unbounded"> - xs:annotation - xs:documentationLimit task to the designated task pane extension points. Otherwise, all. - </xs:documentation> - </xs:annotation> - </xs:element> - <xs:element - ref="perspective:inventoriedResourceActivatorSet" - minOccurs="0" - maxOccurs="unbounded"> - xs:annotation - xs:documentationActivate the extension only if the user has resources of the specified type in - inventory. Activated only if the user has the required permissions. At least one resource activator - required for resource task extensions. Activated for resources only if specified trait conditions are - also met.</xs:documentation> - </xs:annotation> - </xs:element> - <xs:element - ref="perspective:globalPermissionActivatorSet" - minOccurs="0" - maxOccurs="unbounded"> - xs:annotation - xs:documentationActivate the extension only if the user has the required global permissions. - </xs:documentation> - </xs:annotation> - </xs:element> - <xs:element - ref="perspective:helpText" - minOccurs="0" - maxOccurs="1"> - xs:annotation - xs:documentationVerbose display help text for the task extension. Displayed on request. - </xs:documentation> - </xs:annotation> - </xs:element> - </xs:sequence> - <xs:attribute - name="name" - type="perspective:NameType" - use="required"> - xs:annotation - xs:documentation - Internal name for the task extension. Unique within extension names defined by the - perspective. - </xs:documentation> - </xs:annotation> - </xs:attribute> - <xs:attribute - name="displayName" - type="perspective:DisplayNameType" - use="required"> - xs:annotation - xs:documentationThe display name for the task extension.</xs:documentation> - </xs:annotation> - </xs:attribute> - <xs:attribute - name="description" - type="perspective:DescriptionType" - use="required"> - xs:annotation - xs:documentationThe display description for the task extension.</xs:documentation> - </xs:annotation> - </xs:attribute> - <xs:attribute - name="application" - type="xs:string" - use="optional"> - xs:annotation - xs:documentationThe application servicing the urls for this extension. Default is root (rhq-portal.war). - </xs:documentation> - </xs:annotation> - </xs:attribute> - <xs:attribute - name="url" - type="xs:anyURI" - use="required"> - xs:annotation - xs:documentationThe request URL for the task extension. Typically kicks off a wizard or similar workflow. - </xs:documentation> - </xs:annotation> - </xs:attribute> - <xs:attribute - name="category" - type="xs:string" - use="optional"> - xs:annotation - xs:documentationThe display category for the task extension (optional). Tasks with the same category will - be grouped together in the task pane.</xs:documentation> - </xs:annotation> - </xs:attribute> + xs:complexContent + <xs:extension base="perspective:ExtensionType"> + xs:sequence + <xs:element + ref="perspective:inventoriedResourceActivatorSet" + minOccurs="0" + maxOccurs="unbounded"> + xs:annotation + xs:documentationActivate the extension only if the user has resources of the specified type in + inventory. Activated only if the user has the required permissions. At least one resource activator + required for resource task extensions. Activated for resources only if specified trait conditions are + also met.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element + ref="perspective:extensionPoint" + minOccurs="0" + maxOccurs="unbounded"> + xs:annotation + xs:documentationLimit task to the designated task pane extension points. Otherwise, all. + </xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + + <xs:attribute + name="url" + type="xs:anyURI" + use="required"> + xs:annotation + xs:documentationThe request URL for this task. Typically kicks off a wizard or similar workflow. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute + name="category" + type="xs:string" + use="optional"> + xs:annotation + xs:documentationThe display category for the task extension (optional). Tasks with the same category will + be grouped together in the task pane.</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:extension> + </xs:complexContent> </xs:complexType>
+ <xs:complexType + name="ResourceTaskType"> + xs:complexContent + <xs:extension base="perspective:TaskType"> + xs:sequence + <xs:element + ref="perspective:currentResourceOrGroupActivatorSet" + minOccurs="0" + maxOccurs="unbounded"/> + </xs:sequence> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:element name="extensionPoint" type="perspective:ExtensionPointType"> </xs:element>
<xs:element - name="helpText" - type="perspective:HelpTextType"> + name="description" + type="perspective:DescriptionType"> </xs:element>
<xs:element @@ -267,129 +302,79 @@
<xs:complexType name="MenuItemType"> - xs:sequence - <xs:element - ref="perspective:position" - minOccurs="1" - maxOccurs="1"> - xs:annotation - xs:documentationRequired positioning element for the menuItem extension.</xs:documentation> - </xs:annotation> - </xs:element> - <xs:element - ref="perspective:inventoriedResourceActivatorSet" - minOccurs="0" - maxOccurs="unbounded"> - xs:annotation - xs:documentationActivate the extension only if there is at least one Resource in inventory that - satisfies the specified conditions. Conditions include the Resource's type or facet, the current - user's permissions for the Resource, or a Resource trait with a certain value. - </xs:documentation> - </xs:annotation> - </xs:element> - <xs:element - ref="perspective:globalPermissionActivatorSet" - minOccurs="0" - maxOccurs="unbounded"> - xs:annotation - xs:documentationActivate the extension only if the current user has the specified; global permissions. - </xs:documentation> - </xs:annotation> - </xs:element> - </xs:sequence> - <xs:attribute - name="action" - type="perspective:ActionType" - use="optional" - default="add"> - xs:annotation - xs:documentationAdd, Replace or Remove the menuItem extension. For removal all but the name attribute are - ignored. Default is add.</xs:documentation> - </xs:annotation> - </xs:attribute> - <xs:attribute - name="name" - type="perspective:NameType" - use="required"> - xs:annotation - xs:documentationInternal name for the menuItem extension. Unique within extension names defined by the - perspective.</xs:documentation> - </xs:annotation> - </xs:attribute> - <xs:attribute - name="displayName" - type="perspective:DisplayNameType" - use="optional"> - xs:annotation - xs:documentationThe display name for the menuItem extension. If omitted an icon is required. - </xs:documentation> - </xs:annotation> - </xs:attribute> - <xs:attribute - name="feature" - type="perspective:MenuItemFeatureType" - use="optional"> - xs:annotation - xs:documentationCertain menuItem extensions utilize special built-in rendering features. - </xs:documentation> - </xs:annotation> - </xs:attribute> - <xs:attribute - name="newWindow" - type="xs:boolean" - use="optional" - default="false"> - xs:annotation - xs:documentationIf true the url should be directed to a new window. Otherwise the content should be - presented in the current page body.</xs:documentation> - </xs:annotation> - </xs:attribute> - <xs:attribute - name="isDebug" - type="xs:boolean" - use="optional" - default="false"> - xs:annotation - xs:documentationIf true render this menuItem in debug mode only.</xs:documentation> - </xs:annotation> - </xs:attribute> - <xs:attribute - name="application" - type="xs:string" - use="optional"> - xs:annotation - xs:documentationThe application servicing the urls for this extension. Default is root (rhq-portal.war). - </xs:documentation> - </xs:annotation> - </xs:attribute> - <xs:attribute - name="url" - type="xs:anyURI" - use="optional"> - xs:annotation - xs:documentationThe request URL for the menuItem extension. If omitted it is assumed the menuItem exists - as a navigation element to child menuItems.</xs:documentation> - </xs:annotation> - </xs:attribute> - <xs:attribute - name="iconUrl" - type="xs:anyURI" - use="optional"> - xs:annotation - xs:documentationThe request URL for the icon displayed for this menuItem extension. If omitted no image is - displayed. Required if displayName if omitted.</xs:documentation> - </xs:annotation> - </xs:attribute> - <xs:attribute - name="iconWidth" - type="xs:int" - use="optional"> - </xs:attribute> - <xs:attribute - name="iconHeight" - type="xs:int" - use="optional"> - </xs:attribute> + xs:complexContent + <xs:extension base="perspective:ExtensionType"> + xs:sequence + <xs:element + ref="perspective:inventoriedResourceActivatorSet" + minOccurs="0" + maxOccurs="unbounded"> + xs:annotation + xs:documentationActivate the extension only if there is at least one Resource in inventory that + satisfies the specified conditions. Conditions include the Resource's type or facet, the current + user's permissions for the Resource, or a Resource trait with a certain value. + </xs:documentation> + </xs:annotation> + </xs:element> + <xs:element + ref="perspective:position" + minOccurs="1" + maxOccurs="1"> + xs:annotation + xs:documentationRequired positioning element for the menuItem extension.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + + <xs:attribute + name="url" + type="xs:anyURI" + use="optional"> + xs:annotation + xs:documentationThe request URL for this menu item. Typically kicks off a wizard or similar workflow. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute + name="action" + type="perspective:ActionType" + use="optional" + default="add"> + xs:annotation + xs:documentationAdd, Replace or Remove the menuItem extension. For removal all but the name attribute are + ignored. Default is add.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute + name="feature" + type="perspective:MenuItemFeatureType" + use="optional"> + xs:annotation + xs:documentationCertain menuItem extensions utilize special built-in rendering features. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute + name="newWindow" + type="xs:boolean" + use="optional" + default="false"> + xs:annotation + xs:documentationIf true the url should be directed to a new window. Otherwise the content should be + presented in the current page body.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute + name="isDebug" + type="xs:boolean" + use="optional" + default="false"> + xs:annotation + xs:documentationIf true render this menuItem in debug mode only.</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:extension> + </xs:complexContent> </xs:complexType>
<xs:element @@ -408,91 +393,42 @@
<xs:complexType name="TabType"> - xs:sequence - <xs:element - ref="perspective:position" - minOccurs="1" - maxOccurs="1"> - xs:annotation - xs:documentationRequired positioning element for the Tab or SubTab extension.</xs:documentation> - </xs:annotation> - </xs:element> - <xs:element - ref="perspective:currentResourceOrGroupActivatorSet" - minOccurs="0" - maxOccurs="unbounded"/> - <xs:element - ref="perspective:globalPermissionActivatorSet" - minOccurs="0" - maxOccurs="unbounded"> - xs:annotation - xs:documentationActivate tab only if the user has the required global permissions.</xs:documentation> - </xs:annotation> - </xs:element> - </xs:sequence> - <xs:attribute - name="action" - type="perspective:ActionType" - use="optional" - default="add"> - xs:annotation - xs:documentationAdd, Replace or Remove the tab extension. For removal all but the name attribute are - ignored. Default is add.</xs:documentation> - </xs:annotation> - </xs:attribute> - <xs:attribute - name="name" - type="perspective:NameType" - use="required"> - xs:annotation - xs:documentationInternal name for the tab extension. Unique within extension names defined by the - perspective.</xs:documentation> - </xs:annotation> - </xs:attribute> - <xs:attribute - name="displayName" - type="perspective:DisplayNameType" - use="required"> - xs:annotation - xs:documentationThe display name for the tab extension.</xs:documentation> - </xs:annotation> - </xs:attribute> - <xs:attribute - name="application" - type="xs:string" - use="optional"> - xs:annotation - xs:documentationThe application servicing the urls for this extension. Default is root (rhq-portal.war). - </xs:documentation> - </xs:annotation> - </xs:attribute> - <xs:attribute - name="url" - type="xs:anyURI" - use="required"> - xs:annotation - xs:documentationThe request URL for the tab extension.</xs:documentation> - </xs:annotation> - </xs:attribute> - <xs:attribute - name="iconUrl" - type="xs:anyURI" - use="optional"> - xs:annotation - xs:documentationThe request URL for the icon displayed for this tab extension. If omitted no image is - displayed.</xs:documentation> - </xs:annotation> - </xs:attribute> - <xs:attribute - name="iconWidth" - type="xs:int" - use="optional"> - </xs:attribute> - <xs:attribute - name="iconHeight" - type="xs:int" - use="optional"> - </xs:attribute> + xs:complexContent + <xs:extension base="perspective:ExtensionType"> + xs:sequence + <xs:element + ref="perspective:currentResourceOrGroupActivatorSet" + minOccurs="0" + maxOccurs="unbounded"/> + <xs:element + ref="perspective:position"> + xs:annotation + xs:documentationRequired positioning element for the tab.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + + <xs:attribute + name="url" + type="xs:anyURI" + use="optional"> + xs:annotation + xs:documentationThe request URL for this tab. Typically kicks off a wizard or similar workflow. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute + name="action" + type="perspective:ActionType" + use="optional" + default="add"> + xs:annotation + xs:documentationAdd, Replace or Remove the tab extension. For removal, all but the name attribute are + ignored. Default is add.</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:extension> + </xs:complexContent> </xs:complexType>
<xs:element @@ -815,6 +751,19 @@ </xs:annotation> </xs:element>
+ <xs:element + name="monitoringLicenseActivator" + type="perspective:MonitoringLicenseActivatorType"> + xs:annotation + xs:documentationThe user must have a license that includes monitoring in order + for the extension to be active.</xs:documentation> + xs:appinfo + <jaxb:class + name="MonitoringLicenseActivatorElement" /> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:complexType name="ResourceActivatorType"> xs:sequence @@ -835,23 +784,6 @@ maxOccurs="unbounded"> </xs:element> </xs:sequence> - <xs:attribute - name="plugin" - type="xs:string" - use="required"> - xs:annotation - xs:documentationPlugin for the specified resource type.</xs:documentation> - </xs:annotation> - </xs:attribute> - <xs:attribute - name="resourceType" - type="xs:string" - use="required"> - xs:annotation - xs:documentationResource Type that must be in inventory to activate the extension point. - </xs:documentation> - </xs:annotation> - </xs:attribute> </xs:complexType>
<xs:complexType @@ -875,6 +807,10 @@ </xs:attribute> </xs:complexType>
+ <xs:complexType + name="MonitoringLicenseActivatorType"> + </xs:complexType> + <xs:element name="position" type="perspective:PositionType"> @@ -953,22 +889,9 @@ </xs:simpleType>
<xs:simpleType - name="DescriptionType"> - <xs:restriction - base="xs:string"> - <xs:minLength - value="1" /> - <xs:maxLength - value="512" /> - </xs:restriction> - </xs:simpleType> - - <xs:simpleType name="DisplayNameType"> <xs:restriction base="xs:string"> - <xs:minLength - value="0" /> <xs:maxLength value="128" /> </xs:restriction> @@ -984,13 +907,11 @@ </xs:simpleType>
<xs:simpleType - name="HelpTextType"> + name="DescriptionType"> <xs:restriction base="xs:string"> - <xs:minLength - value="1" /> <xs:maxLength - value="1024" /> + value="2000" /> </xs:restriction> </xs:simpleType>
commit 5092e3a428de5752aebf76466533848a59e179e0 Merge: 16a8267... e4ed52a... Author: Jay Shaughnessy jshaughn@redhat.com Date: Tue Dec 8 16:19:37 2009 -0500
Merge branch 'linux-config' into linux-config-dev
commit 16a82671b3658cb99cb2ee5b81112936172be160 Author: Jay Shaughnessy jshaughn@redhat.com Date: Tue Dec 8 16:16:41 2009 -0500
Working towards url key mapping.
diff --git a/etc/samples/perspectives/sample-perspective/perspective/src/main/resources/META-INF/rhq-serverplugin.xml b/etc/samples/perspectives/sample-perspective/perspective/src/main/resources/META-INF/rhq-serverplugin.xml index b5499b2..1b32a74 100644 --- a/etc/samples/perspectives/sample-perspective/perspective/src/main/resources/META-INF/rhq-serverplugin.xml +++ b/etc/samples/perspectives/sample-perspective/perspective/src/main/resources/META-INF/rhq-serverplugin.xml @@ -67,7 +67,9 @@ </menuItem> <menuItem name="custom.child2" - displayName="Child-2"> + displayName="Child-2" + application="sample" + url="index.html"> <position extensionPoint="coreMenu" name="custom.child1" diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/perspectives/PerspectivesMenuUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/perspectives/PerspectivesMenuUIBean.java index e1ab2b5..ab125e5 100644 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/perspectives/PerspectivesMenuUIBean.java +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/perspectives/PerspectivesMenuUIBean.java @@ -53,4 +53,25 @@ public class PerspectivesMenuUIBean {
return result; } + + public String getUrlKey() { + String url = FacesContextUtility.getRequest().getParameter("url"); + int key = perspectiveManager.getUrlKey(url); + + return Integer.toString(key); + } + + public String getKeyViaUrl(String url) { + int key = perspectiveManager.getUrlKey(url); + + return Integer.toString(key); + } + + public String getUrlViaKey() { + String key = FacesContextUtility.getRequest().getParameter("key"); + String url = (null == key) ? null : perspectiveManager.getUrlViaKey(Integer.valueOf(key)); + + return url; + } + } diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/common/perspective-main.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/common/perspective-main.xhtml new file mode 100644 index 0000000..3db1171 --- /dev/null +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/common/perspective-main.xhtml @@ -0,0 +1,42 @@ +<?xml version="1.0"?> + +<!DOCTYPE html + PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<html + xmlns="http://www.w3.org/1999/xhtml" + xmlns:h="http://java.sun.com/jsf/html" + xmlns:f="http://java.sun.com/jsf/core" + xmlns:ui="http://java.sun.com/jsf/facelets" + xmlns:c="http://java.sun.com/jstl/core" + xmlns:onc="http://jboss.org/on/component" + xmlns:rich="http://richfaces.ajax4jsf.org/rich%22%3E + +<ui:composition template="/rhq/layout/main.xhtml"> + + <ui:param + name="pageTitle" + value="PERSPECTIVE PAGE" /> + + <ui:define name="breadcrumbs"> + <h:outputLink value="/">Custom</h:outputLink> + </ui:define> + + <ui:define name="body"> + + <iframe + id="perspective-main" + src="#{param.targetUrl}" + scrolling="no" + marginwidth="0" + marginheight="0" + frameborder="0" + style="overflow: visible; width: 100%; height: 100%;"> ERROR: Perspective-defined page could not be + embedded. Please make sure you're using IE6+ or FF2+. </iframe> + + </ui:define> + +</ui:composition> + +</html> diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveManagerLocal.java index 1a25bd8..9bdd5e9 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveManagerLocal.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveManagerLocal.java @@ -47,4 +47,9 @@ public interface PerspectiveManagerLocal { * @return the list of tabs that should be displayed for the specified user for the specified Resource */ List<Tab> getResourceTabs(Subject subject, Resource resource); + + public int getUrlKey(String url); + + public String getUrlViaKey(int key); + } \ No newline at end of file diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/perspective/metadata/PerspectivePluginMetadataManager.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/perspective/metadata/PerspectivePluginMetadataManager.java index d657ef6..c7a7adb 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/perspective/metadata/PerspectivePluginMetadataManager.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/perspective/metadata/PerspectivePluginMetadataManager.java @@ -131,7 +131,7 @@ public class PerspectivePluginMetadataManager { List<ApplicationType> applications = perspective.getApplication();
for (MenuItemType rawMenuItem : perspective.getMenuItem()) { - resolveUrls(applications, rawMenuItem); + resolveUrls(applications, rawMenuItem, "/rhq/common/perspective-main.xhtml?targetUrl="); ActionType action = rawMenuItem.getAction(); ExtensionPointType extensionPoint = rawMenuItem.getPosition().getExtensionPoint(); if (ExtensionPointType.CORE_MENU == extensionPoint) { @@ -155,14 +155,14 @@ public class PerspectivePluginMetadataManager { * @param applications * @param rawMenuItem */ - private void resolveUrls(List<ApplicationType> applications, MenuItemType rawMenuItem) { + private void resolveUrls(List<ApplicationType> applications, MenuItemType rawMenuItem, String targetUrl) { ApplicationType applicationType = getApplicationByName(applications, rawMenuItem.getApplication());
- rawMenuItem.setUrl(resolveUrl(applicationType, rawMenuItem.getUrl())); - rawMenuItem.setIconUrl(resolveUrl(applicationType, rawMenuItem.getIconUrl())); + rawMenuItem.setUrl(resolveUrl(applicationType, rawMenuItem.getUrl(), targetUrl)); + rawMenuItem.setIconUrl(resolveUrl(applicationType, rawMenuItem.getIconUrl(), targetUrl)); }
- private String resolveUrl(ApplicationType applicationType, String url) { + private String resolveUrl(ApplicationType applicationType, String url, String targetUrl) { String result = url;
if (null != url) { @@ -179,7 +179,7 @@ public class PerspectivePluginMetadataManager { baseUrl = baseUrl + "/"; applicationType.setBaseUrl(baseUrl); } - result = baseUrl + url; + result = targetUrl + baseUrl + url; } }
@@ -327,18 +327,15 @@ public class PerspectivePluginMetadataManager { return coreMenu; }
- public List<TaskType> getGlobalTasks() - { + public List<TaskType> getGlobalTasks() { return globalTasks; }
- public List<TaskType> getResourceTasks() - { + public List<TaskType> getResourceTasks() { return resourceTasks; }
- public List<TabType> getTabs() - { + public List<TabType> getTabs() { return tabs; } }
commit 889a0047cd7a3de2cced5ba99efaa0da74a3cf9c Author: Jay Shaughnessy jshaughn@redhat.com Date: Tue Dec 8 16:14:09 2009 -0500
removing obsolete dependency
diff --git a/modules/enterprise/server/container/pom.xml b/modules/enterprise/server/container/pom.xml index a4c6d40..4ee342f 100644 --- a/modules/enterprise/server/container/pom.xml +++ b/modules/enterprise/server/container/pom.xml @@ -44,12 +44,6 @@ <artifactId>rhq-container-lib</artifactId> <version>${project.version}</version> </dependency> - - <dependency> - <groupId>org.rhq</groupId> - <artifactId>rhq-sample-perspective</artifactId> - <version>${project.version}</version> - </dependency>
<!-- 3rd Party Deps -->
commit d08297b29466f3bcb31859946229a2c328bd9c3a Author: Adam Young ayoung@redhat.com Date: Tue Dec 8 15:09:00 2009 -0500
Created a unit test for ConfigRenderer and primed the pump with mock objects. This time added the test itself
diff --git a/.classpath b/.classpath index feaae55..55ab9f4 100644 --- a/.classpath +++ b/.classpath @@ -14,6 +14,7 @@ <classpathentry kind="src" path="modules/plugins/jboss-cache/src/main/java"/> <classpathentry kind="src" path="modules/plugins/jboss-cache-v3/src/main/java"/> <classpathentry excluding="org/rhq/plugins/antlrconfig/" kind="src" path="modules/plugins/antlr-config/src/main/java"/> + <classpathentry kind="src" path="modules/core/gui/src/test/java"/> <classpathentry kind="var" path="M2_REPO/org/jboss/integration/jboss-profileservice-spi/5.1.0.SP1/jboss-profileservice-spi-5.1.0.SP1.jar"/> <classpathentry kind="var" path="M2_REPO/org/jboss/man/jboss-managed/2.1.1.GA/jboss-managed-2.1.1.GA.jar"/> <classpathentry kind="var" path="M2_REPO/org/jboss/man/jboss-metatype/2.1.1.GA/jboss-metatype-2.1.1.GA.jar"/> @@ -97,7 +98,7 @@ <classpathentry kind="src" path="modules/plugins/apt/src/test/java"/> <classpathentry kind="src" path="modules/plugins/hosts/src/main/java"/> <classpathentry kind="src" path="modules/plugins/hosts/src/test/java"/> - <classpathentry kind="src" path="modules/plugins/virt/src/main/java"/> + <classpathentry kind="src" path="modules/plugins/virt/src/main/java"/> <classpathentry kind="src" path="modules/plugins/aliases/src/main/java"/> <classpathentry kind="src" path="modules/plugins/aliases/src/test/java"/> <classpathentry kind="src" path="modules/plugins/snmptrapd/src/main/java"/> diff --git a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/ConfigRendererTest.java b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/ConfigRendererTest.java index f4a5d27..68afd21 100644 --- a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/ConfigRendererTest.java +++ b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/ConfigRendererTest.java @@ -8,7 +8,6 @@ import javax.faces.FactoryFinder; import javax.faces.application.ApplicationFactory; import javax.faces.context.ExternalContext; import javax.faces.context.FacesContext; -import javax.faces.context.ResponseWriter; import javax.faces.lifecycle.Lifecycle; import javax.faces.render.RenderKitFactory;
@@ -25,16 +24,12 @@ import org.rhq.core.gui.util.FacesContextUtility; public class ConfigRendererTest {
RenderKitFactory rkf; - ConfigUIComponent configUIComponent; ConfigRenderer configRenderer; - FacesContext facesContext; ExternalContext externalContext; - AjaxContext ajaxContext; - ResponseWriter mockResponseWriter; - + MockResponseWriter mockResponseWriter; Lifecycle lifecycle;
@BeforeMethod @@ -57,29 +52,20 @@ public class ConfigRendererTest { FactoryFinder.setFactory(FactoryFinder.RENDER_KIT_FACTORY, MockRenderKitFactory.class.getName()); FactoryFinder.setFactory(FactoryFinder.APPLICATION_FACTORY, MockApplicationFactory.class.getName());
- } - - @Test - public void testDecodeReadWrite() { - HashMap<Object, Object> map = new HashMap(); - facesContext.getExternalContext().getRequestMap().put("com.sun.faces.util.RequestStateManager", map); - FacesContextImpl impl = new FacesContextImpl(externalContext, lifecycle); - map.put("com.sun.faces.FacesContextImpl", impl); - - configUIComponent.setReadOnly(false); - ValueExpression binding = new MockValueExpression(); binding.setValue(FacesContextUtility.getFacesContext().getELContext(), new Configuration()); - configUIComponent.setValueExpression("configuration", binding);
- Configuration configuration = configUIComponent.getConfiguration(); - Assert.assertNotNull(configuration); + }
+ @Test + public void testDecode() { + configUIComponent.setReadOnly(false); + Assert.assertNotNull(configUIComponent.getConfiguration()); configRenderer.decode(facesContext, configUIComponent); }
@@ -88,13 +74,7 @@ public class ConfigRendererTest { configRenderer.encodeBegin(this.facesContext, configUIComponent); configRenderer.encodeChildren(facesContext, configUIComponent); configRenderer.encodeEnd(facesContext, configUIComponent); - //System.out.println(mockResponseWriter.stringWriter.getBuffer().toString()); + System.out.println(mockResponseWriter.stringWriter.getBuffer().toString()); }
- public static void main(String[] args) throws Exception { - ConfigRendererTest test = new ConfigRendererTest(); - test.setUp(); - test.testDecodeReadWrite(); - - } } diff --git a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockResponseWriter.java b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockResponseWriter.java index 85f49b9..378ca41 100644 --- a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockResponseWriter.java +++ b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockResponseWriter.java @@ -9,7 +9,7 @@ import javax.faces.context.ResponseWriter;
public class MockResponseWriter extends ResponseWriter {
- StringWriter stringWriter = new StringWriter(); + public StringWriter stringWriter = new StringWriter();
@Override public ResponseWriter cloneWithWriter(Writer writer) {
commit 9e40e29cee09b589a2ecb24a163595c800ffeb31 Author: Adam Young ayoung@redhat.com Date: Tue Dec 8 15:08:29 2009 -0500
Created a unit test for ConfigRenderer and primed the pump with mock objects
diff --git a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/ConfigRendererTest.java b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/ConfigRendererTest.java new file mode 100644 index 0000000..f4a5d27 --- /dev/null +++ b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/ConfigRendererTest.java @@ -0,0 +1,100 @@ +package org.rhq.core.gui.configuration; + +import java.io.IOException; +import java.util.HashMap; + +import javax.el.ValueExpression; +import javax.faces.FactoryFinder; +import javax.faces.application.ApplicationFactory; +import javax.faces.context.ExternalContext; +import javax.faces.context.FacesContext; +import javax.faces.context.ResponseWriter; +import javax.faces.lifecycle.Lifecycle; +import javax.faces.render.RenderKitFactory; + +import com.sun.faces.context.FacesContextImpl; + +import org.ajax4jsf.context.AjaxContext; +import org.testng.Assert; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import org.rhq.core.domain.configuration.Configuration; +import org.rhq.core.gui.util.FacesContextUtility; + +public class ConfigRendererTest { + + RenderKitFactory rkf; + + ConfigUIComponent configUIComponent; + ConfigRenderer configRenderer; + + FacesContext facesContext; + ExternalContext externalContext; + + AjaxContext ajaxContext; + ResponseWriter mockResponseWriter; + + Lifecycle lifecycle; + + @BeforeMethod + protected void setUp() throws Exception { + configUIComponent = new ConfigUIComponent(); + configRenderer = new ConfigRenderer(); + + externalContext = new MockExternalContext(); + mockResponseWriter = new MockResponseWriter(); + facesContext = new MockFacesContext(externalContext, mockResponseWriter); + FacesContext.getCurrentInstance(); + + configUIComponent.setId("ID"); + + ajaxContext = AjaxContext.getCurrentInstance(facesContext); + lifecycle = new MockLifecycle(); + + ApplicationFactory af = new MockApplicationFactory(); + + FactoryFinder.setFactory(FactoryFinder.RENDER_KIT_FACTORY, MockRenderKitFactory.class.getName()); + FactoryFinder.setFactory(FactoryFinder.APPLICATION_FACTORY, MockApplicationFactory.class.getName()); + + } + + @Test + public void testDecodeReadWrite() { + + HashMap<Object, Object> map = new HashMap(); + + facesContext.getExternalContext().getRequestMap().put("com.sun.faces.util.RequestStateManager", map); + + FacesContextImpl impl = new FacesContextImpl(externalContext, lifecycle); + + map.put("com.sun.faces.FacesContextImpl", impl); + + configUIComponent.setReadOnly(false); + + ValueExpression binding = new MockValueExpression(); + binding.setValue(FacesContextUtility.getFacesContext().getELContext(), new Configuration()); + + configUIComponent.setValueExpression("configuration", binding); + + Configuration configuration = configUIComponent.getConfiguration(); + Assert.assertNotNull(configuration); + + configRenderer.decode(facesContext, configUIComponent); + } + + @Test + public void testEncode() throws IOException { + configRenderer.encodeBegin(this.facesContext, configUIComponent); + configRenderer.encodeChildren(facesContext, configUIComponent); + configRenderer.encodeEnd(facesContext, configUIComponent); + //System.out.println(mockResponseWriter.stringWriter.getBuffer().toString()); + } + + public static void main(String[] args) throws Exception { + ConfigRendererTest test = new ConfigRendererTest(); + test.setUp(); + test.testDecodeReadWrite(); + + } +} diff --git a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockApplication.java b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockApplication.java new file mode 100644 index 0000000..335eb88 --- /dev/null +++ b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockApplication.java @@ -0,0 +1,236 @@ +package org.rhq.core.gui.configuration; + +import java.util.Collection; +import java.util.Iterator; +import java.util.Locale; + +import javax.faces.FacesException; +import javax.faces.application.Application; +import javax.faces.application.NavigationHandler; +import javax.faces.application.StateManager; +import javax.faces.application.ViewHandler; +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; +import javax.faces.convert.Converter; +import javax.faces.el.MethodBinding; +import javax.faces.el.PropertyResolver; +import javax.faces.el.ReferenceSyntaxException; +import javax.faces.el.ValueBinding; +import javax.faces.el.VariableResolver; +import javax.faces.event.ActionListener; +import javax.faces.validator.Validator; + +public class MockApplication extends Application { + + @Override + public void addComponent(String componentType, String componentClass) { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public void addConverter(String converterId, String converterClass) { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public void addConverter(Class targetClass, String converterClass) { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public void addValidator(String validatorId, String validatorClass) { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public UIComponent createComponent(String componentType) throws FacesException { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public UIComponent createComponent(ValueBinding componentBinding, FacesContext context, String componentType) + throws FacesException { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public Converter createConverter(String converterId) { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public Converter createConverter(Class targetClass) { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public MethodBinding createMethodBinding(String ref, Class[] params) throws ReferenceSyntaxException { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public Validator createValidator(String validatorId) throws FacesException { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public ValueBinding createValueBinding(String ref) throws ReferenceSyntaxException { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public ActionListener getActionListener() { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public Iterator<String> getComponentTypes() { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public Iterator<String> getConverterIds() { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public Iterator<Class> getConverterTypes() { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public Locale getDefaultLocale() { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public String getDefaultRenderKitId() { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public String getMessageBundle() { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public NavigationHandler getNavigationHandler() { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public PropertyResolver getPropertyResolver() { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public StateManager getStateManager() { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public Iterator<Locale> getSupportedLocales() { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public Iterator<String> getValidatorIds() { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public VariableResolver getVariableResolver() { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public ViewHandler getViewHandler() { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public void setActionListener(ActionListener listener) { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public void setDefaultLocale(Locale locale) { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public void setDefaultRenderKitId(String renderKitId) { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public void setMessageBundle(String bundle) { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public void setNavigationHandler(NavigationHandler handler) { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public void setPropertyResolver(PropertyResolver resolver) { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public void setStateManager(StateManager manager) { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public void setSupportedLocales(Collection<Locale> locales) { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public void setVariableResolver(VariableResolver resolver) { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public void setViewHandler(ViewHandler handler) { + throw new RuntimeException("Function not implemented"); + + } + +} diff --git a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockApplicationFactory.java b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockApplicationFactory.java new file mode 100644 index 0000000..ba180a3 --- /dev/null +++ b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockApplicationFactory.java @@ -0,0 +1,20 @@ +package org.rhq.core.gui.configuration; + +import javax.faces.application.Application; +import javax.faces.application.ApplicationFactory; + +public class MockApplicationFactory extends ApplicationFactory { + + Application application = new MockApplication(); + + @Override + public Application getApplication() { + return application; + } + + @Override + public void setApplication(Application application) { + this.application = application; + } + +} diff --git a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockExternalContext.java b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockExternalContext.java new file mode 100644 index 0000000..8fb6172 --- /dev/null +++ b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockExternalContext.java @@ -0,0 +1,233 @@ +package org.rhq.core.gui.configuration; + +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; +import java.security.Principal; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Locale; +import java.util.Map; +import java.util.Set; + +import javax.faces.context.ExternalContext; + +import com.sun.faces.application.ApplicationImpl; + +public class MockExternalContext extends ExternalContext { + + @Override + public void dispatch(String path) throws IOException { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public String encodeActionURL(String url) { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public String encodeNamespace(String name) { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public String encodeResourceURL(String url) { + throw new RuntimeException("Function not implemented"); + + } + + public Map<String, Object> applicationMap; + + @Override + public Map<String, Object> getApplicationMap() { + if (null == applicationMap) { + applicationMap = new HashMap<String, Object>(); + applicationMap.put("com.sun.faces.ApplicationImpl", new ApplicationImpl()); + } + + return applicationMap; + } + + @Override + public String getAuthType() { + throw new RuntimeException("Function not implemented"); + + } + + MockServletContext servletContext = new MockServletContext(); + + @Override + public Object getContext() { + return servletContext; + } + + @Override + public String getInitParameter(String name) { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public Map getInitParameterMap() { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public String getRemoteUser() { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public Object getRequest() { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public String getRequestContextPath() { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public Map<String, Object> getRequestCookieMap() { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public Map<String, String> getRequestHeaderMap() { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public Map<String, String[]> getRequestHeaderValuesMap() { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public Locale getRequestLocale() { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public Iterator<Locale> getRequestLocales() { + throw new RuntimeException("Function not implemented"); + + } + + Map<String, Object> requestMap = new HashMap<String, Object>(); + + @Override + public Map<String, Object> getRequestMap() { + return requestMap; + } + + Map<String, String> requestParameterMap = new HashMap<String, String>(); + + @Override + public Map<String, String> getRequestParameterMap() { + return requestParameterMap; + } + + @Override + public Iterator<String> getRequestParameterNames() { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public Map<String, String[]> getRequestParameterValuesMap() { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public String getRequestPathInfo() { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public String getRequestServletPath() { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public URL getResource(String path) throws MalformedURLException { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public InputStream getResourceAsStream(String path) { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public Set<String> getResourcePaths(String path) { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public Object getResponse() { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public Object getSession(boolean create) { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public Map<String, Object> getSessionMap() { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public Principal getUserPrincipal() { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public boolean isUserInRole(String role) { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public void log(String message) { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public void log(String message, Throwable exception) { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public void redirect(String url) throws IOException { + throw new RuntimeException("Function not implemented"); + + } + +} diff --git a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockFacesContext.java b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockFacesContext.java new file mode 100644 index 0000000..49b007e --- /dev/null +++ b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockFacesContext.java @@ -0,0 +1,142 @@ +package org.rhq.core.gui.configuration; + +import java.util.Iterator; + +import javax.faces.application.Application; +import javax.faces.application.FacesMessage; +import javax.faces.application.FacesMessage.Severity; +import javax.faces.component.UIViewRoot; +import javax.faces.context.ExternalContext; +import javax.faces.context.FacesContext; +import javax.faces.context.ResponseStream; +import javax.faces.context.ResponseWriter; +import javax.faces.render.RenderKit; + +public class MockFacesContext extends FacesContext { + + private ExternalContext externalContext; + private Object responseCompleteWriter; + private MockResponseWriter mockResponseWriter; + + public MockFacesContext(ExternalContext externalContext, ResponseWriter responseWriter) { + this.externalContext = externalContext; + this.responseCompleteWriter = responseWriter; + } + + @Override + public void addMessage(String clientId, FacesMessage message) { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public Application getApplication() { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public Iterator<String> getClientIdsWithMessages() { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public ExternalContext getExternalContext() { + return externalContext; + + } + + @Override + public Severity getMaximumSeverity() { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public Iterator<FacesMessage> getMessages() { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public Iterator<FacesMessage> getMessages(String clientId) { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public RenderKit getRenderKit() { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public boolean getRenderResponse() { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public boolean getResponseComplete() { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public ResponseStream getResponseStream() { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public ResponseWriter getResponseWriter() { + if (null == mockResponseWriter) { + mockResponseWriter = new MockResponseWriter(); + } + return mockResponseWriter; + } + + @Override + public UIViewRoot getViewRoot() { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public void release() { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public void renderResponse() { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public void responseComplete() { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public void setResponseStream(ResponseStream responseStream) { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public void setResponseWriter(ResponseWriter responseWriter) { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public void setViewRoot(UIViewRoot root) { + throw new RuntimeException("Function not implemented"); + + } + +} diff --git a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockLifecycle.java b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockLifecycle.java new file mode 100644 index 0000000..c48708d --- /dev/null +++ b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockLifecycle.java @@ -0,0 +1,40 @@ +package org.rhq.core.gui.configuration; + +import javax.faces.FacesException; +import javax.faces.context.FacesContext; +import javax.faces.event.PhaseListener; +import javax.faces.lifecycle.Lifecycle; + +public class MockLifecycle extends Lifecycle { + + @Override + public void addPhaseListener(PhaseListener listener) { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public void execute(FacesContext context) throws FacesException { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public PhaseListener[] getPhaseListeners() { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public void removePhaseListener(PhaseListener listener) { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public void render(FacesContext context) throws FacesException { + throw new RuntimeException("Function not implemented"); + + } + +} diff --git a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockRenderKitFactory.java b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockRenderKitFactory.java new file mode 100644 index 0000000..760e703 --- /dev/null +++ b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockRenderKitFactory.java @@ -0,0 +1,31 @@ +package org.rhq.core.gui.configuration; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import javax.faces.context.FacesContext; +import javax.faces.render.RenderKit; +import javax.faces.render.RenderKitFactory; + +public class MockRenderKitFactory extends RenderKitFactory { + + Map<String, RenderKit> kits = new HashMap<String, RenderKit>(); + + @Override + public void addRenderKit(String renderKitId, RenderKit renderKit) { + kits.put(renderKitId, renderKit); + } + + @Override + public RenderKit getRenderKit(FacesContext context, String renderKitId) { + return kits.get(renderKitId); + + } + + @Override + public Iterator<String> getRenderKitIds() { + return kits.keySet().iterator(); + } + +} diff --git a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockResponseWriter.java b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockResponseWriter.java new file mode 100644 index 0000000..85f49b9 --- /dev/null +++ b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockResponseWriter.java @@ -0,0 +1,99 @@ +package org.rhq.core.gui.configuration; + +import java.io.IOException; +import java.io.StringWriter; +import java.io.Writer; + +import javax.faces.component.UIComponent; +import javax.faces.context.ResponseWriter; + +public class MockResponseWriter extends ResponseWriter { + + StringWriter stringWriter = new StringWriter(); + + @Override + public ResponseWriter cloneWithWriter(Writer writer) { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public void endDocument() throws IOException { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public void endElement(String name) throws IOException { + stringWriter.write("end element:" + name); + + } + + @Override + public void flush() throws IOException { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public String getCharacterEncoding() { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public String getContentType() { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public void startDocument() throws IOException { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public void startElement(String name, UIComponent component) throws IOException { + stringWriter.write("startElement: " + name + ": componenet:" + component.getId()); + } + + @Override + public void writeAttribute(String name, Object value, String property) throws IOException { + stringWriter.write("attribute:" + name + "value = " + value.toString() + "property = " + property); + + } + + @Override + public void writeComment(Object comment) throws IOException { + stringWriter.write("comment:" + comment); + + } + + @Override + public void writeText(Object text, String property) throws IOException { + write(text + ":" + property); + } + + @Override + public void writeText(char[] text, int off, int len) throws IOException { + write(text, off, len); + } + + @Override + public void writeURIAttribute(String name, Object value, String property) throws IOException { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public void close() throws IOException { + stringWriter.close(); + } + + @Override + public void write(char[] cbuf, int off, int len) throws IOException { + stringWriter.write(cbuf, off, len); + } + +} diff --git a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockServletContext.java b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockServletContext.java new file mode 100644 index 0000000..8740aca --- /dev/null +++ b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockServletContext.java @@ -0,0 +1,167 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2009 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.core.gui.configuration; + +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; +import java.util.Set; + +import javax.servlet.RequestDispatcher; +import javax.servlet.Servlet; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; + +import com.sun.faces.config.WebConfiguration; + +final class MockServletContext implements ServletContext { + public void setAttribute(String arg0, Object arg1) { + this.attributeMap.put(arg0, arg1); + + } + + public void removeAttribute(String arg0) { + attributeMap.remove(arg0); + + } + + public void log(String arg0, Throwable arg1) { + throw new RuntimeException("Function not implemented"); + + } + + public void log(Exception arg0, String arg1) { + throw new RuntimeException("Function not implemented"); + + } + + public void log(String arg0) { + throw new RuntimeException("Function not implemented"); + + } + + public Enumeration getServlets() { + throw new RuntimeException("Function not implemented"); + + } + + public Enumeration getServletNames() { + throw new RuntimeException("Function not implemented"); + + } + + public String getServletContextName() { + return MockServletContext.class.getSimpleName(); + + } + + public Servlet getServlet(String arg0) throws ServletException { + throw new RuntimeException("Function not implemented"); + + } + + public String getServerInfo() { + throw new RuntimeException("Function not implemented"); + + } + + public Set getResourcePaths(String arg0) { + throw new RuntimeException("Function not implemented"); + + } + + public InputStream getResourceAsStream(String arg0) { + throw new RuntimeException("Function not implemented"); + + } + + public URL getResource(String arg0) throws MalformedURLException { + throw new RuntimeException("Function not implemented"); + + } + + public RequestDispatcher getRequestDispatcher(String arg0) { + throw new RuntimeException("Function not implemented"); + + } + + public String getRealPath(String arg0) { + throw new RuntimeException("Function not implemented"); + + } + + public RequestDispatcher getNamedDispatcher(String arg0) { + throw new RuntimeException("Function not implemented"); + + } + + public int getMinorVersion() { + return 4; + } + + public String getMimeType(String arg0) { + throw new RuntimeException("Function not implemented"); + + } + + public int getMajorVersion() { + return 2; + + } + + Properties initParams = new Properties(); + + public Enumeration getInitParameterNames() { + return initParams.elements(); + + } + + public String getInitParameter(String key) { + return initParams.getProperty(key); + + } + + public ServletContext getContext(String arg0) { + throw new RuntimeException("Function not implemented"); + + } + + public Enumeration getAttributeNames() { + throw new RuntimeException("Function not implemented"); + + } + + Map<String, Object> attributeMap; + + public Object getAttribute(String key) { + if (null == attributeMap) { + attributeMap = new HashMap<String, Object>(); + WebConfiguration wc = WebConfiguration.getInstance(this); + + attributeMap.put("com.sun.faces.config.WebConfiguration", wc); + } + + return attributeMap.get(key); + } +} \ No newline at end of file diff --git a/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockValueExpression.java b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockValueExpression.java new file mode 100644 index 0000000..49bd739 --- /dev/null +++ b/modules/core/gui/src/test/java/org/rhq/core/gui/configuration/MockValueExpression.java @@ -0,0 +1,62 @@ +package org.rhq.core.gui.configuration; + +import javax.el.ELContext; +import javax.el.ValueExpression; + +public class MockValueExpression extends ValueExpression { + + @Override + public Class<?> getExpectedType() { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public Class<?> getType(ELContext arg0) { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public Object getValue(ELContext arg0) { + return value; + } + + @Override + public boolean isReadOnly(ELContext arg0) { + throw new RuntimeException("Function not implemented"); + + } + + public Object value; + public boolean literalText = false; + + @Override + public void setValue(ELContext arg0, Object arg1) { + this.value = arg1; + } + + @Override + public boolean equals(Object arg0) { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public String getExpressionString() { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public int hashCode() { + throw new RuntimeException("Function not implemented"); + + } + + @Override + public boolean isLiteralText() { + return literalText; + } + +} diff --git a/temp-testng-customsuite.xml b/temp-testng-customsuite.xml new file mode 100644 index 0000000..b4645bb --- /dev/null +++ b/temp-testng-customsuite.xml @@ -0,0 +1,8 @@ +<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd"> +<suite name="rhq" parallel=""> + <test verbose="2" name="org.rhq.core.gui.configuration.ConfigRendererTest" annotations="JDK"> + <classes> + <class name="org.rhq.core.gui.configuration.ConfigRendererTest"/> + </classes> + </test> +</suite>
commit 36636817b8004083d5f01216aa580b426e96c9f5 Author: John Sanda john@localhost.localdomain Date: Tue Dec 8 14:55:30 2009 -0500
[US 1025] Fixing raw config plugin redeployment error
When redeploying a plugin with raw config, I was getting a NPE in ConfigurationDefinition while ConfigurationMetadataManagerBean is applying the update. The NPE happens because of a couple of the fields in ConfigurationDefinition which are Maps are lazily initialized. Initializing them at the time of instantiation (of the ConfigurationDefinition object) to empty maps resolves the issue.
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/definition/ConfigurationDefinition.java b/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/definition/ConfigurationDefinition.java index 7249174..5c28844 100644 --- a/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/definition/ConfigurationDefinition.java +++ b/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/definition/ConfigurationDefinition.java @@ -94,12 +94,12 @@ public class ConfigurationDefinition implements Serializable { @MapKey(name = "name") @OneToMany(mappedBy = "configurationDefinition", cascade = CascadeType.ALL, fetch = FetchType.EAGER) @OrderBy - private Map<String, PropertyDefinition> propertyDefinitions; + private Map<String, PropertyDefinition> propertyDefinitions = new LinkedHashMap<String, PropertyDefinition>();
@MapKey(name = "name") @OneToMany(mappedBy = "configurationDefinition", cascade = CascadeType.ALL, fetch = FetchType.LAZY) @OrderBy - private Map<String, ConfigurationTemplate> templates; + private Map<String, ConfigurationTemplate> templates = new LinkedHashMap<String, ConfigurationTemplate>();
@Column(name = "config_format") @Enumerated(EnumType.STRING)
commit f43773789e7d9ec2826b951004c48d30afcfa571 Author: John Sanda john@localhost.localdomain Date: Tue Dec 8 13:45:14 2009 -0500
[BZ 545175] Updating resouce config rollback to support structured and raw.
Resource configuration rollback previously did not support configurations that support both structured and raw. Rollback for those configs is implemented as an update from raw.
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java index 2aa8f18..fb82e6e 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java @@ -1072,7 +1072,12 @@ public class ConfigurationManagerBean implements ConfigurationManagerLocal, Conf + configHistoryId + "'"); }
- updateResourceConfiguration(subject, resourceId, configuration); + if (isStructuredAndRawSupported(resourceId)) { + updateStructuredOrRawConfiguration(subject, resourceId, configuration, false); + } + else { + updateResourceConfiguration(subject, resourceId, configuration); + } }
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
commit 865f04011d5278cb4918685c99de4a3394d7cb01 Author: John Sanda jsanda@redhat.com Date: Tue Dec 8 12:54:39 2009 -0500
Porting a fix for a serialization bug introduced in the raw-config branch
In the externalization helper methods in Configuration.java, the parent properties of the Property and RawConfiguration objects was not getting set. This bug made its way into master when I cherry-picked another fix for a pre-existing bug and was not aware of the serialization bug at that time.
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/Configuration.java b/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/Configuration.java index 62bd8ce..5547f7c 100644 --- a/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/Configuration.java +++ b/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/Configuration.java @@ -654,7 +654,9 @@ public class Configuration implements Externalizable, Cloneable, AbstractPropert private Map<String, Property> createDeepCopyOfMap() { Map<String, Property> copy = new HashMap<String, Property>(); for (Map.Entry<String, Property> entry : this.properties.entrySet()) { - copy.put(entry.getKey(), entry.getValue().deepCopy(true)); + Property copiedProperty = entry.getValue().deepCopy(true); + copiedProperty.setConfiguration(this); + copy.put(entry.getKey(), copiedProperty); } return copy; } @@ -662,7 +664,9 @@ public class Configuration implements Externalizable, Cloneable, AbstractPropert private Set<RawConfiguration> createDeepCopyOfRawConfigs() { Set<RawConfiguration> copy = new HashSet<RawConfiguration>(); for (RawConfiguration rawConfig : this.rawConfigurations) { - copy.add(rawConfig.deepCopy(true)); + RawConfiguration copiedRawConfig = rawConfig.deepCopy(true); + copiedRawConfig.setConfiguration(this); + copy.add(copiedRawConfig); } return copy; }
commit d08fdf8856caa1d7445de420d27503b1dbeb05b9 Author: John Sanda john@localhost.localdomain Date: Wed Nov 25 22:24:44 2009 -0500
[BZ 541486] Fixing serialization bug for configuration update objects
The fix involved nothing more than making AbstractConfigurationUpdate implement Serializable. I have also added unit tests for all implementing classes to verify correct serialization behavior.
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/AbstractConfigurationUpdate.java b/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/AbstractConfigurationUpdate.java index 8fd3150..0231f78 100644 --- a/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/AbstractConfigurationUpdate.java +++ b/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/AbstractConfigurationUpdate.java @@ -24,6 +24,7 @@ package org.rhq.core.domain.configuration;
import java.io.ByteArrayOutputStream; import java.io.PrintStream; +import java.io.Serializable;
import javax.persistence.CascadeType; import javax.persistence.Column; @@ -44,7 +45,10 @@ import javax.xml.bind.annotation.XmlTransient; * Base class for resource configuration and plugin configuration updates (i.e. history items). */ @XmlAccessorType(XmlAccessType.FIELD) -public abstract class AbstractConfigurationUpdate { +public abstract class AbstractConfigurationUpdate implements Serializable { + + private static final long serialVersionUID = 1L; + @JoinColumn(name = "CONFIGURATION_ID", referencedColumnName = "ID", nullable = false) @OneToOne(cascade = { CascadeType.ALL }, fetch = FetchType.EAGER) @XmlTransient diff --git a/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/AbstractConfigurationUpdateTest.java b/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/AbstractConfigurationUpdateTest.java new file mode 100644 index 0000000..7195cde --- /dev/null +++ b/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/AbstractConfigurationUpdateTest.java @@ -0,0 +1,114 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2008 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, version 2, as + * published by the Free Software Foundation, and/or the GNU Lesser + * General Public License, version 2.1, also as published by the Free + * Software Foundation. + * + * 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 and the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * and the GNU Lesser 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.core.domain.configuration; + +import org.testng.annotations.Test; + +public abstract class AbstractConfigurationUpdateTest { + + + @Test + public void serializationShouldCopyConfiguration() throws Exception { + Configuration config = new Configuration(); + config.put(new PropertySimple("x", "1")); + + ResourceConfigurationUpdate update = new ResourceConfigurationUpdate(); + update.setConfiguration(config); + + ResourceConfigurationUpdate serializedUpdate = TestUtil.serializeAndDeserialize(update); + + org.testng.Assert.assertEquals( + serializedUpdate.getConfiguration(), + update.getConfiguration(), + "Failed to properly serialize the 'configuration' property" + ); + } + + @Test + public void serializationShouldCopyErrorMessage() throws Exception { + ResourceConfigurationUpdate update = new ResourceConfigurationUpdate(); + update.setErrorMessage("update error"); + + ResourceConfigurationUpdate serializedUpdate = TestUtil.serializeAndDeserialize(update); + + org.testng.Assert.assertEquals( + serializedUpdate.getErrorMessage(), + update.getErrorMessage(), + "Failed to properly serialize the 'errorMessage' property" + ); + } + + @Test + public void serializationShouldCopyStatus() throws Exception { + ResourceConfigurationUpdate update = new ResourceConfigurationUpdate(); + update.setStatus(ConfigurationUpdateStatus.SUCCESS); + + ResourceConfigurationUpdate serializedUpdate = TestUtil.serializeAndDeserialize(update); + + org.testng.Assert.assertEquals( + serializedUpdate.getStatus(), + update.getStatus(), + "Failed to properly serialize the 'status' property" + ); + } + + @Test + public void serializationShouldCopySubjectName() throws Exception { + ResourceConfigurationUpdate update = new ResourceConfigurationUpdate(null, new Configuration(), "rhqadmin"); + + ResourceConfigurationUpdate serializedUpdate = TestUtil.serializeAndDeserialize(update); + + org.testng.Assert.assertEquals( + serializedUpdate.getSubjectName(), + update.getSubjectName(), + "Failed to properly serialize the 'subjectName' property" + ); + } + + @Test + public void serializationShouldCopyCreatedTime() throws Exception { + ResourceConfigurationUpdate update = new ResourceConfigurationUpdate(); + + ResourceConfigurationUpdate serializedUpdate = TestUtil.serializeAndDeserialize(update); + + org.testng.Assert.assertEquals( + serializedUpdate.getCreatedTime(), + update.getCreatedTime(), + "Failed to properly serialize the 'createdTime' property" + ); + } + + @Test + public void serializationShouldCopyModifiedTime() throws Exception { + ResourceConfigurationUpdate update = new ResourceConfigurationUpdate(); + + ResourceConfigurationUpdate serializedUpdate = TestUtil.serializeAndDeserialize(update); + + org.testng.Assert.assertEquals( + serializedUpdate.getModifiedTime(), + update.getModifiedTime(), + "Failed to properly serialize the 'modifiedTime' property" + ); + } +} diff --git a/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/PluginConfigurationUpdateTest.java b/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/PluginConfigurationUpdateTest.java new file mode 100644 index 0000000..ee63afd --- /dev/null +++ b/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/PluginConfigurationUpdateTest.java @@ -0,0 +1,67 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2008 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, version 2, as + * published by the Free Software Foundation, and/or the GNU Lesser + * General Public License, version 2.1, also as published by the Free + * Software Foundation. + * + * 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 and the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * and the GNU Lesser 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.core.domain.configuration; + +import org.testng.annotations.Test; +import static org.testng.Assert.assertEquals; +import org.rhq.core.domain.resource.Resource; +import org.rhq.core.domain.resource.group.ResourceGroup; +import org.rhq.core.domain.configuration.group.GroupResourceConfigurationUpdate; +import org.rhq.core.domain.configuration.group.GroupPluginConfigurationUpdate; + +public class PluginConfigurationUpdateTest extends AbstractConfigurationUpdateTest { + + @Test + public void serializationShouldCopyResource() throws Exception { + Resource resource = new Resource(); + resource.setUuid("1234"); + + PluginConfigurationUpdate update = new PluginConfigurationUpdate(); + update.setResource(resource); + + PluginConfigurationUpdate serializedUpdate = TestUtil.serializeAndDeserialize(update); + + assertEquals( + serializedUpdate.getResource(), + update.getResource(), + "Failed to properly serialize the 'resource' property" + ); + } + + @Test + public void serializationShouldCopyGroupConfigurationUpdate() throws Exception { + PluginConfigurationUpdate update = new PluginConfigurationUpdate(); + update.setGroupConfigurationUpdate(new GroupPluginConfigurationUpdate(new ResourceGroup("resourceGroup"), + "rhqadmin")); + + PluginConfigurationUpdate serializedUpdate = TestUtil.serializeAndDeserialize(update); + + assertEquals( + serializedUpdate.getGroupConfigurationUpdate(), + update.getGroupConfigurationUpdate(), + "Failed to properly serialize the 'groupConfigurationUpdate' property" + ); + } + +} diff --git a/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/ResourceConfigurationUpdateTest.java b/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/ResourceConfigurationUpdateTest.java new file mode 100644 index 0000000..8a967a6 --- /dev/null +++ b/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/ResourceConfigurationUpdateTest.java @@ -0,0 +1,67 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2008 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, version 2, as + * published by the Free Software Foundation, and/or the GNU Lesser + * General Public License, version 2.1, also as published by the Free + * Software Foundation. + * + * 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 and the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * and the GNU Lesser 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.core.domain.configuration; + +import static org.testng.Assert.*; + +import org.testng.annotations.Test; +import org.rhq.core.domain.resource.Resource; +import org.rhq.core.domain.resource.group.ResourceGroup; +import org.rhq.core.domain.configuration.group.GroupResourceConfigurationUpdate; + +public class ResourceConfigurationUpdateTest extends AbstractConfigurationUpdateTest { + + @Test + public void serializationShouldCopyResource() throws Exception { + Resource resource = new Resource(); + resource.setUuid("1234"); + + ResourceConfigurationUpdate update = new ResourceConfigurationUpdate(); + update.setResource(resource); + + ResourceConfigurationUpdate serializedUpdate = TestUtil.serializeAndDeserialize(update); + + assertEquals( + serializedUpdate.getResource(), + update.getResource(), + "Failed to properly serialize the 'resource' property" + ); + } + + @Test + public void serializationShouldCopyGroupConfigurationUpdate() throws Exception { + ResourceConfigurationUpdate update = new ResourceConfigurationUpdate(); + update.setGroupConfigurationUpdate(new GroupResourceConfigurationUpdate(new ResourceGroup("resourceGroup"), + "rhqadmin")); + + ResourceConfigurationUpdate serializedUpdate = TestUtil.serializeAndDeserialize(update); + + assertEquals( + serializedUpdate.getGroupConfigurationUpdate(), + update.getGroupConfigurationUpdate(), + "Failed to properly serialize the 'groupConfigurationUpdate' property" + ); + } + +} diff --git a/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/TestUtil.java b/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/TestUtil.java new file mode 100644 index 0000000..c1fac86 --- /dev/null +++ b/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/TestUtil.java @@ -0,0 +1,45 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2008 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, version 2, as + * published by the Free Software Foundation, and/or the GNU Lesser + * General Public License, version 2.1, also as published by the Free + * Software Foundation. + * + * 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 and the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * and the GNU Lesser 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.core.domain.configuration; + +import java.io.ByteArrayOutputStream; +import java.io.ObjectOutputStream; +import java.io.ByteArrayInputStream; +import java.io.ObjectInputStream; + +public class TestUtil { + + public static <T> T serializeAndDeserialize(T object) throws Exception { + ByteArrayOutputStream byteOutputStream = new ByteArrayOutputStream(); + ObjectOutputStream ostream = new ObjectOutputStream(byteOutputStream); + + ostream.writeObject(object); + + ByteArrayInputStream byteInputStream = new ByteArrayInputStream(byteOutputStream.toByteArray()); + ObjectInputStream istream = new ObjectInputStream(byteInputStream); + + return (T) istream.readObject(); + } + +} diff --git a/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/group/GroupPluginConfigurationUpdateTest.java b/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/group/GroupPluginConfigurationUpdateTest.java new file mode 100644 index 0000000..0be4172 --- /dev/null +++ b/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/group/GroupPluginConfigurationUpdateTest.java @@ -0,0 +1,51 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2008 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, version 2, as + * published by the Free Software Foundation, and/or the GNU Lesser + * General Public License, version 2.1, also as published by the Free + * Software Foundation. + * + * 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 and the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * and the GNU Lesser 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.core.domain.configuration.group; + +import org.rhq.core.domain.configuration.AbstractConfigurationUpdateTest; +import org.rhq.core.domain.configuration.ResourceConfigurationUpdate; +import org.rhq.core.domain.configuration.Configuration; +import org.rhq.core.domain.configuration.TestUtil; +import org.rhq.core.domain.configuration.PluginConfigurationUpdate; +import org.rhq.core.domain.resource.Resource; +import org.testng.annotations.Test; +import static org.testng.Assert.assertEquals; + +public class GroupPluginConfigurationUpdateTest extends AbstractConfigurationUpdateTest { + + @Test + public void serializationShouldCopyConfigurationUpdates() throws Exception { + GroupPluginConfigurationUpdate update = new GroupPluginConfigurationUpdate(); + update.getConfigurationUpdates().add(new PluginConfigurationUpdate(new Resource(), new Configuration(), + "rhqadmin")); + + GroupPluginConfigurationUpdate serializedUpdate = TestUtil.serializeAndDeserialize(update); + + assertEquals( + serializedUpdate.getConfigurationUpdates(), + update.getConfigurationUpdates(), + "Failed to properly serialize the 'configurationUpdate' property" + ); + } +} diff --git a/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/group/GroupResourceConfigurationUpdateTest.java b/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/group/GroupResourceConfigurationUpdateTest.java new file mode 100644 index 0000000..ebb9008 --- /dev/null +++ b/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/group/GroupResourceConfigurationUpdateTest.java @@ -0,0 +1,51 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2008 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, version 2, as + * published by the Free Software Foundation, and/or the GNU Lesser + * General Public License, version 2.1, also as published by the Free + * Software Foundation. + * + * 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 and the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * and the GNU Lesser 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.core.domain.configuration.group; + +import static org.testng.Assert.*; + +import org.rhq.core.domain.configuration.AbstractConfigurationUpdateTest; +import org.rhq.core.domain.configuration.ResourceConfigurationUpdate; +import org.rhq.core.domain.configuration.Configuration; +import org.rhq.core.domain.configuration.TestUtil; +import org.rhq.core.domain.resource.Resource; +import org.testng.annotations.Test; + +public class GroupResourceConfigurationUpdateTest extends AbstractConfigurationUpdateTest { + + @Test + public void serializationShouldCopyConfigurationUpdates() throws Exception { + GroupResourceConfigurationUpdate update = new GroupResourceConfigurationUpdate(); + update.addConfigurationUpdate(new ResourceConfigurationUpdate(new Resource(), new Configuration(), "rhqadmin")); + + GroupResourceConfigurationUpdate serializedUpdate = TestUtil.serializeAndDeserialize(update); + + assertEquals( + serializedUpdate.getConfigurationUpdates(), + update.getConfigurationUpdates(), + "Failed to properly serialize the 'configurationUpdate' property" + ); + } + +}
commit ba3220112431c34649cf826e147c6ada7b26a46b Author: John Sanda john@localhost.localdomain Date: Tue Dec 8 11:34:35 2009 -0500
Adding functions to translate from structured to raw and vice versa
diff --git a/modules/enterprise/remoting/scripts/src/main/script/configuration/update_structured.js b/modules/enterprise/remoting/scripts/src/main/script/configuration/update_structured.js index 79dd0bf..54c39a9 100644 --- a/modules/enterprise/remoting/scripts/src/main/script/configuration/update_structured.js +++ b/modules/enterprise/remoting/scripts/src/main/script/configuration/update_structured.js @@ -79,6 +79,40 @@ function ConfigUtil(resourceName) { } }
+ this.translateToRaw = function(update) { + doTranslation(update, true); + } + + this.translateToStructured = function(update) { + doTranslation(update, false); + } + + function doTranslation(update, doStructured) { + println("Loading latest configuration for " + util.resource.name); + var configuration = util.getLatestConfiguration(); + + printConfiguration(configuration) + println(''); + + if (doStructured) { + doStructuredUpdate(util.resource, configuration, update); + } + else { + doRawUpdate(util.resource, configuration, update); + } + + println("Modified configuration..."); + printConfiguration(configuration) + println(''); + + var translatedConfig = ConfigurationManager.translateResourceConfiguration(util.resource.id, configuration, + doStructured); + + println("Translated configuration..."); + printConfiguration(translatedConfig); + println(''); + } + this.updateConfiguration = function(update, doStructured) { println("Loading latest configuration for " + this.resource.name); var configuration = this.getLatestConfiguration(); @@ -159,7 +193,11 @@ function ConfigUtil(resourceName) {
function applyStructuredUpdate(resource, configuration, update) { println("Applying resource configuration update..."); + doStructuredUpdate(resource, configuration, update); + ConfigurationManager.updateStructuredOrRawConfiguration(resource.id, configuration, structured); + }
+ function doStructuredUpdate(resource, configuration, update) { for (key in update) { var property = configuration.getSimple(key.toString()); if (property == null) { @@ -167,11 +205,15 @@ function ConfigUtil(resourceName) { } property.stringValue = update[key]; } - - ConfigurationManager.updateStructuredOrRawConfiguration(resource.id, configuration, structured); }
function applyRawUpdate(resource, configuration, update) { + println("Applying resource configuration update..."); + doRawUpdate(resource, configuration, update); + ConfigurationManager.updateStructuredOrRawConfiguration(resource.id, configuration, raw); + } + + function doRawUpdate(resourcec, configuration) { var updates = 0; var rawConfigs = java.util.ArrayList(configuration.rawConfigurations); for (path in update) { @@ -191,9 +233,6 @@ function ConfigUtil(resourceName) { if (updates == 0) { throw "\nNo matching paths were found. Update will abort."; } - - println("Applying resource configuration update..."); - ConfigurationManager.updateStructuredOrRawConfiguration(resource.id, configuration, raw); }
function findRawConfig(path, rawConfigs) {
commit f9515bc6cd7ee88de95321dcd5b457eead77e147 Author: John Sanda john@localhost.localdomain Date: Tue Dec 8 10:44:05 2009 -0500
Rewrite of script to make it more modular and to support for scenarios.
The update function now supports modifying multiple properties for a structured update. It supports updating multiple raws for a raw update, and it now also supports updating a config that suppoprts both structured and raw.
diff --git a/modules/enterprise/remoting/scripts/src/main/script/configuration/update_structured.js b/modules/enterprise/remoting/scripts/src/main/script/configuration/update_structured.js index 65e56a2..79dd0bf 100644 --- a/modules/enterprise/remoting/scripts/src/main/script/configuration/update_structured.js +++ b/modules/enterprise/remoting/scripts/src/main/script/configuration/update_structured.js @@ -21,179 +21,228 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
-var serverName = ''; var waitInterval = 100; -var STRUCTURED_SERVER = 'Structured Server'; -var STRUCTURED_ANR_RAW_SERVER = 'Structured and Raw Server' -var RAW_SERVER = 'Raw Server'; +var structured = true; +var raw = false;
-if (cmdLineArgsValid()) { - updateConfiguration(); -} +loadResourceTypes();
-function cmdLineArgsValid() { - var isValid = true; - -// if (!scriptUtil.isDefined('server')) { -// println("'server' is a required argument"); -// isValid = false; -// } -// -// serverName = server; -// if (!(serverName == 'structured' || serverName == 'structuredandraw' || 'raw')) { -// println("Invalid value for server argument. Must be one of <structured | raw | structuredandraw>"); -// isValid = false; -// } -// -// if (server) -// -// if (!scriptUtil.isDefined('propertyName')) { -// println("'propertyName' is a required argument"); -// isValid = false; -// } -// -// if (!scriptUtil.isDefined('propertyValue')) { -// println("'propertyValue' is a required argument\n"); -// isValid = false; -// } - - return isValid; -} +function loadResourceTypes() { + var resourceTypes = context.getAttribute('resourceTypes'); + if (resourceTypes != null && !resourceTypes.isEmpty()) { + return; + }
-function updateConfiguration() { - setServerName(); + var criteria = ResourceTypeCriteria(); + criteria.fetchResourceConfigurationDefinition(true);
- println("\nPreapring to update configuration for " + serverName); - - var resource = findServer(); - var configuration = getLatestConfiguration(resource); + resourceTypes = ResourceTypeManager.findResourceTypesByCriteria(criteria); + context.setAttribute('resourceTypes', resourceTypes, javax.script.ScriptContext.ENGINE_SCOPE); +}
- if (isStructuredUpdate()) { - printConfiguration(resource, configuration); - verifyPropertyToUpdateExists(configuration) - applyStructuredUpdate(resource, configuration); - } - else { - printRawConfiguration(resource, configuration); - verifyRawContentExists(); - applyRawUpdate(resource, configuration); - } +function ConfigUtil(resourceName) { + var util = this; + + this.resource = findServer(resourceName);
- waitForResourceConfigurationUpdateToComplete(resource.id); + this.getLatestConfiguration = function () { + var latestUpdate = ConfigurationManager.getLatestResourceConfigurationUpdate(this.resource.id);
- println("Configuration update has completed."); - configuration = getLatestConfiguration(resource); + Assert.assertNotNull( + latestUpdate, + "Failed to load the latest resource configuration update for " + this.resource.name + ); + Assert.assertNotNull( + latestUpdate.configuration, + "No configuration is attached to the latest config update object." + );
- if (isStructuredUpdate()) { - printConfiguration(resource, configuration); + return latestUpdate.configuration; } - else { - printRawConfiguration(resource, configuration); + + this.printLatestConfiguration = function() { + var configuration = this.getLatestConfiguration(); + printConfiguration(configuration); } -}
-function setServerName() { - if (server == 'structured') { - serverName = STRUCTURED_SERVER; + function printConfiguration(configuration) { + pretty.print(configuration); + + if (util.isRawSupported() || util.isStructuredAndRawSupported()) { + println("\nRaw configuration files:"); + var rawConfigs = java.util.ArrayList(configuration.rawConfigurations); + for (i = 0; i < rawConfigs.size(); i++) { + var rawConfig = rawConfigs.get(i); + println("\n[" + rawConfig.path + "]"); + println(java.lang.String(rawConfig.contents) + "\n\n---------------------"); + } + } } - else if (server == 'raw') { - serverName = RAW_SERVER; + + this.updateConfiguration = function(update, doStructured) { + println("Loading latest configuration for " + this.resource.name); + var configuration = this.getLatestConfiguration(); + + printConfiguration(configuration); + println(''); + + if (this.isStructuredSupported()) { + applyStructuredUpdate(this.resource, configuration, update); + } + else if (this.isRawSupported()) { + applyRawUpdate(this.resource, configuration, update); + } + else if (this.isStructuredAndRawSupported()) { + if (doStructured == null) { + throw "\nMust specify structured or raw when updating a configuration that supports both " + + "structured and raw. Update will abort."; + } + + if (doStructured) { + applyStructuredUpdate(this.resource, configuration, update); + } + else { + applyRawUpdate(this.resource, configuration, update); + } + } + + this.waitForResourceConfigurationUpdateToComplete(); + println("Configuration update has completed."); + + println("Loading latest, updated configuration"); + this.printLatestConfiguration(); } - else if (server == 'structuredandraw') { - serverName = STRUCTURED_ANR_RAW_SERVER; + + this.waitForResourceConfigurationUpdateToComplete = function() { + print("Waiting for configuration update to complete...") + while (ConfigurationManager.isResourceConfigurationUpdateInProgress(this.resource.id)) { + print("."); + java.lang.Thread.sleep(waitInterval); + } + println(''); } - else { - throw "\nInvalid value for server argument. Must be one of <structured | raw | structuredandraw>"; + + this.isRawSupported = function() { + var configFormat = this.resource.resourceType.resourceConfigurationDefinition.configurationFormat; + return ConfigurationFormat.RAW == configFormat; } -}
-function findServer() { - var criteria = ResourceCriteria(); - criteria.strict = true; - criteria.addFilterName(serverName); + this.isStructuredSupported = function() { + var configFormat = this.resource.resourceType.resourceConfigurationDefinition.configurationFormat; + return ConfigurationFormat.STRUCTURED == configFormat; + }
- var resources = ResourceManager.findResourcesByCriteria(criteria); + this.isStructuredAndRawSupported = function() { + var configFormat = this.resource.resourceType.resourceConfigurationDefinition.configurationFormat; + return ConfigurationFormat.STRUCTURED_AND_RAW == configFormat; + }
- Assert.assertTrue(resources.size() == 1, "Expected to get back one resource but got back " + resources.size()); + function verifyPropertyToUpdateExists(configuration) { + if (!isDefined('propertyName')) { + throw "\nThe 'propertyName' variable must be defined. Update will abort."; + }
- return resources.get(0); -} + if (!isDefined('propertyValue')) { + throw "\nThe 'propertyValue' variable must be defined. Update will abort."; + }
-function getLatestConfiguration(resource) { - var latestUpdate = ConfigurationManager.getLatestResourceConfigurationUpdate(resource.id); - - Assert.assertNotNull(latestUpdate, "Failed to load the latest resource configuration update for " + resource.name); - Assert.assertNotNull(latestUpdate.configuration, "No configuration is attached to the latest config update object."); - - return latestUpdate.configuration; -} + if(configuration.getSimple(propertyName) == null) { + throw "\nThe property '" + propertyName + "' is undefined. Update will abort."; + } + }
-function printConfiguration(resource, configuration) { - println("Fetching the latest resource configuration for " + resource.name); - pretty.print(configuration); - println(''); -} + function verifyRawContentExists() { + if (!isDefined('contents')) { + throw "\n'contents' argument is required when updating " + serverName; + } + }
-function printRawConfiguration(resource, configuration) { - var rawConfig = getRawConfig(configuration, 0); + function applyStructuredUpdate(resource, configuration, update) { + println("Applying resource configuration update...");
- println("Fetching the latest resource configuration for " + resource.name); - pretty.print(configuration); - println("The contents of " + rawConfig.path + ":\n"); - println(java.lang.String(rawConfig.contents) + "\n--------------------------------------\n"); -} + for (key in update) { + var property = configuration.getSimple(key.toString()); + if (property == null) { + throw "\nThe property '" + key + "' does not exist in the configuration. Update will abort."; + } + property.stringValue = update[key]; + }
-function isStructuredUpdate() { - return serverName == STRUCTURED_ANR_RAW_SERVER || serverName == STRUCTURED_SERVER; -} + ConfigurationManager.updateStructuredOrRawConfiguration(resource.id, configuration, structured); + }
-function verifyPropertyToUpdateExists(configuration) { - if(configuration.getSimple(propertyName) == null) { - throw "\nThe property '" + propertyName + "' is undefined. Update will abort." + function applyRawUpdate(resource, configuration, update) { + var updates = 0; + var rawConfigs = java.util.ArrayList(configuration.rawConfigurations); + for (path in update) { + var rawConfig = findRawConfig(path, rawConfigs); + if (rawConfig == null) { + println("Failed to find raw config with path ending with " + path); + } + else { + configuration.rawConfigurations.remove(rawConfig); + var contents = java.lang.String(update[path]); + rawConfig.contents = contents.bytes; + configuration.rawConfigurations.add(rawConfig); + updates++; + } + } + + if (updates == 0) { + throw "\nNo matching paths were found. Update will abort."; + } + + println("Applying resource configuration update..."); + ConfigurationManager.updateStructuredOrRawConfiguration(resource.id, configuration, raw); } -}
-function verifyRawContentExists() { - if (!isDefined('contents')) { - throw "\n'contents' argument is required when updating " + serverName; + function findRawConfig(path, rawConfigs) { + for (i = 0; i < rawConfigs.size(); i++) { + var rawConfig = rawConfigs.get(i); + if (rawConfig.path.endsWith(path.toString())) { + return rawConfig; + } + } + return null; } -}
-function applyStructuredUpdate(resource, configuration) { - var property = configuration.getSimple(propertyName); - property.stringValue = propertyValue; +}
- println("Apply resource configuration update..."); +function findServer(name) { + var criteria = ResourceCriteria(); + criteria.strict = true; + criteria.addFilterName(name); + criteria.fetchResourceType(true);
- ConfigurationManager.updateStructuredOrRawConfiguration(resource.id, configuration, true); -} + var resources = ResourceManager.findResourcesByCriteria(criteria);
-function applyRawUpdate(resource, configuration) { - var rawConfig = getRawConfig(configuration, 0); + Assert.assertTrue(resources.size() == 1, "Expected to get back one resource but got back " + resources.size());
- configuration.rawConfigurations.remove(rawConfig); + var resource = resources.get(0); + var resourceType = findResourceType(resource);
- var contentsString = java.lang.String(eval(contents)); - rawConfig.contents = contentsString.bytes; - configuration.rawConfigurations.add(rawConfig); + if (resourceType == null) { + resourceType = loadResourceType(resource);
- println("Apply resource configuration update..."); + if (resourceType == null) { + throw "Failed to initialize resource type for " + resource.name; + } + } + resource.resourceType = resourceType;
- ConfigurationManager.updateStructuredOrRawConfiguration(resource.id, configuration, false); + return resource; }
-function getRawConfig(configuration, index) { - var rawConfigs = java.util.LinkedList(configuration.rawConfigurations); - var rawConfig = rawConfigs.get(index); - - return rawConfig; +function loadResourceType(resource) { + return ResourceTypeManager.getResourceTypeById(resource.resourceType.id); }
-function waitForResourceConfigurationUpdateToComplete(resourceId) { - print("Waiting for configuration update to complete...") - while (ConfigurationManager.isResourceConfigurationUpdateInProgress(resourceId)) { - print("."); - java.lang.Thread.sleep(waitInterval); +function findResourceType(resource) { + for (i = 0; i < resourceTypes.size(); i++) { + var resourceType = resourceTypes.get(i); + if (resourceType.id == resource.resourceType.id) { + return resourceType; + } } - println(''); -} \ No newline at end of file + return null; +}
commit dcdc92a7c10c3d8a0884e2dbfed5d426a36a03e4 Author: Heiko W. Rupp pilhuhn@fedorapeople.org Date: Tue Dec 8 13:26:55 2009 +0100
Improve the plugin so that it kind of works. There is still an issue with the engine "forgetting" the script after some time.
diff --git a/modules/plugins/script2/pom.xml b/modules/plugins/script2/pom.xml index 839f0c3..ccb3ef0 100644 --- a/modules/plugins/script2/pom.xml +++ b/modules/plugins/script2/pom.xml @@ -34,8 +34,8 @@ <plugin> <artifactId>maven-compiler-plugin</artifactId> <configuration> - <source>1.5</source> - <target>1.5</target> + <source>1.6</source> + <target>1.6</target> </configuration> </plugin>
@@ -51,7 +51,11 @@ </goals> <configuration> <artifactItems> - + <artifactItem> + <groupId>org.jruby</groupId> + <artifactId>jruby-complete</artifactId> + <version>1.4.0</version> + </artifactItem> <!-- TODO include needed external jars that should go into your jar file
@@ -180,30 +184,12 @@
<dependencies> <dependency> - <groupId>commons-logging</groupId> - <artifactId>commons-logging</artifactId> - <version>1.1</version> - </dependency> - <dependency> - <groupId>org.rhq</groupId> - <artifactId>rhq-core-domain</artifactId> - <version>${rhq.version}</version> - <scope>provided</scope> - </dependency> - <dependency> - <groupId>org.rhq</groupId> - <artifactId>rhq-core-plugin-api</artifactId> - <version>${rhq.version}</version> - <scope>provided</scope> - </dependency> - <dependency> - <groupId>org.rhq</groupId> - <artifactId>rhq-core-native-system</artifactId> - <version>${rhq.version}</version> - <scope>provided</scope> + <groupId>org.jruby</groupId> + <artifactId>jruby-complete</artifactId> + <version>1.4.0</version> </dependency>
<!-- TODO add your dependencies here -->
</dependencies> -</project> \ No newline at end of file +</project> diff --git a/modules/plugins/script2/src/main/java/org/rhq/modules/plugins/script2/ScriptComponent.java b/modules/plugins/script2/src/main/java/org/rhq/modules/plugins/script2/ScriptComponent.java index 9204919..e388595 100644 --- a/modules/plugins/script2/src/main/java/org/rhq/modules/plugins/script2/ScriptComponent.java +++ b/modules/plugins/script2/src/main/java/org/rhq/modules/plugins/script2/ScriptComponent.java @@ -1,13 +1,25 @@
-package org.rhq.modules.plugins.Script2; +package org.rhq.modules.plugins.script2;
+import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.Reader; import java.util.HashSet; import java.util.Set;
+import javax.script.Invocable; +import javax.script.ScriptEngine; +import javax.script.ScriptEngineManager; +import javax.script.ScriptException; + import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory;
import org.rhq.core.domain.configuration.Configuration; +import org.rhq.core.domain.measurement.DataType; +import org.rhq.core.domain.measurement.MeasurementData; +import org.rhq.core.domain.measurement.MeasurementDataTrait; import org.rhq.core.pluginapi.inventory.InvalidPluginConfigurationException; import org.rhq.core.domain.measurement.AvailabilityType; import org.rhq.core.domain.measurement.MeasurementDataNumeric; @@ -21,14 +33,16 @@ import org.rhq.core.pluginapi.operation.OperationFacet; import org.rhq.core.pluginapi.operation.OperationResult;
-public class ScriptComponent implements ResourceComponent -, MeasurementFacet -, OperationFacet +public class ScriptComponent implements ResourceComponent, MeasurementFacet, OperationFacet { private final Log log = LogFactory.getLog(this.getClass());
private static final int CHANGEME = 1; // TODO remove or change this
+ private String scriptName; + ScriptEngine engine; + Object scriptObject; +
@@ -37,8 +51,23 @@ public class ScriptComponent implements ResourceComponent * @see org.rhq.core.pluginapi.inventory.ResourceComponent#getAvailability() */ public AvailabilityType getAvailability() { - // TODO supply real implementation - return AvailabilityType.UP; + + Object ret = null; + + try { + Invocable inv = (Invocable) engine; + ret = inv.invokeFunction("avail"); + if (ret instanceof Number) { + int tmp = ((Number)ret).intValue(); + if (tmp>0) + return AvailabilityType.UP; + } + } catch (ScriptException e) { + e.printStackTrace(); // TODO: Customise this generated block + } catch (NoSuchMethodException e) { + e.printStackTrace(); // TODO: Customise this generated block + } + return AvailabilityType.DOWN; }
@@ -51,6 +80,30 @@ public class ScriptComponent implements ResourceComponent Configuration conf = context.getPluginConfiguration(); // TODO add code to start the resource / connection to it
+ String engineName = conf.getSimpleValue("language",null); + if (engineName==null) + throw new InvalidPluginConfigurationException("No (valid) language given "); + + ScriptEngineManager seMgr = new ScriptEngineManager(); + engine = seMgr.getEngineByName(engineName); + + scriptName = conf.getSimpleValue("scriptName",null); + if (scriptName==null) + throw new InvalidPluginConfigurationException("No (valid) script name given"); + + File dataDir = context.getDataDirectory(); + File scriptFile = new File(dataDir.getAbsolutePath() + "/"+ scriptName); // TODO find a better directory for this. + if (!scriptFile.exists()) + throw new InvalidPluginConfigurationException("Script does not exist at " + scriptFile.getAbsolutePath()); + + try { + Reader reader = new BufferedReader(new FileReader(scriptFile)); + engine.eval(reader); +// scriptObject = engine.get("new MyClass"); + } + catch (ScriptException se) { + throw new InvalidPluginConfigurationException(se.getMessage()); + }
}
@@ -73,11 +126,42 @@ public class ScriptComponent implements ResourceComponent public void getValues(MeasurementReport report, Set<MeasurementScheduleRequest> metrics) throws Exception {
for (MeasurementScheduleRequest req : metrics) { - if (req.getName().equals("dummyMetric")) { - MeasurementDataNumeric res = new MeasurementDataNumeric(req, Double.valueOf(CHANGEME)); - report.addData(res); - } - // TODO add more metrics here + + Invocable inv = (Invocable) engine; + if (req.getDataType()== DataType.MEASUREMENT) { + MeasurementDataNumeric res; + try { + Object ret = inv.invokeFunction("metric",req.getName()); + if (ret instanceof Number) { + Double num = ((Number)ret).doubleValue(); + res = new MeasurementDataNumeric(req,num); + report.addData(res); + } + else { + log.debug("Returned value " + ret.toString() + " is no number for metric " + req.getName()); + } + } + catch (Exception e) { + log.debug(e.getMessage()); + } + } + else if (req.getDataType()==DataType.TRAIT) { + MeasurementDataTrait res; + try { + Object ret = inv.invokeFunction("trait",req.getName()); + if (ret instanceof String) { + String val = ((String)ret); + res = new MeasurementDataTrait(req,val); + report.addData(res); + } + else { + log.debug("Returned value " + ret.toString() + " is no string for metric " + req.getName()); + } + } + catch (Exception e) { + log.debug(e.getMessage()); + } + } } }
diff --git a/modules/plugins/script2/src/main/java/org/rhq/modules/plugins/script2/ScriptDiscovery.java b/modules/plugins/script2/src/main/java/org/rhq/modules/plugins/script2/ScriptDiscovery.java index 05a0ffd..25411ee 100644 --- a/modules/plugins/script2/src/main/java/org/rhq/modules/plugins/script2/ScriptDiscovery.java +++ b/modules/plugins/script2/src/main/java/org/rhq/modules/plugins/script2/ScriptDiscovery.java @@ -1,4 +1,4 @@ -package org.rhq.modules.plugins.Script2; +package org.rhq.modules.plugins.script2;
import java.util.Collections; import java.util.HashSet; @@ -20,8 +20,7 @@ import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext; /** * Discovery class */ -public class ScriptDiscovery implements ResourceDiscoveryComponent -,ManualAddFacet +public class ScriptDiscovery implements ResourceDiscoveryComponent,ManualAddFacet {
private final Log log = LogFactory.getLog(this.getClass()); @@ -41,11 +40,20 @@ public class ScriptDiscovery implements ResourceDiscoveryComponent */ public DiscoveredResourceDetails discoverResource(Configuration pluginConfiguration, ResourceDiscoveryContext context) throws InvalidPluginConfigurationException {
- // TODO implement this - DiscoveredResourceDetails detail = null; // new DiscoveredResourceDetails( -// context.getResourceType(), // ResourceType -// ); - - return detail; + String lang = pluginConfiguration.getSimpleValue("language", null); + String script = pluginConfiguration.getSimpleValue("scriptName",null); + String key = "script2Engine::" + lang + "::" + script; + + DiscoveredResourceDetails detail = new DiscoveredResourceDetails( + context.getResourceType(), // ResourceType + key, // resource key + "Script " + lang + "::" + script, // resource name TODO get via configuration + null, // version + lang + "Script " + script, // Description + pluginConfiguration, // Configuration + null // Process scans + ); + + return detail; } } \ No newline at end of file diff --git a/modules/plugins/script2/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/script2/src/main/resources/META-INF/rhq-plugin.xml index be73e2c..3608fe8 100644 --- a/modules/plugins/script2/src/main/resources/META-INF/rhq-plugin.xml +++ b/modules/plugins/script2/src/main/resources/META-INF/rhq-plugin.xml @@ -15,22 +15,28 @@
> <plugin-configuration> - <c:simple-property name="language" default="Ruby"> + <c:simple-property name="language" default="jruby"> <c:property-options> - <c:option value="Ruby"/> - <c:option value="Python"/> + <c:option value="jruby" name="Ruby"/> +<!-- <c:option value="jython" name="Python"/> --> + <c:option value="JavaScript" name="JavaScript"/> </c:property-options> </c:simple-property> - <c:simple-property name="availabilityScript" displayName="Name of availability script"/> - <c:simple-property name="monitorScript" /> + <c:simple-property name="scriptName" displayName="Name of the script" type="directory" required="true"/> </plugin-configuration>
+<!-- <operation name="dummyOperation"> - <!-- TODO supply parameters and return values --> + TODO supply parameters and return values </operation> +--> + <metric property="metric1" /> + <metric property="metric2" /> + <metric property="metric3" /> + <metric property="metric4" />
- <metric property="dummyMetric" displayName="Dummy display name"/> + <metric property="trait1" dataType="trait" />
commit fe68273f1fcf5c1448929312a4265f96a92dcfd8 Author: Heiko W. Rupp pilhuhn@fedorapeople.org Date: Tue Dec 8 08:35:48 2009 +0100
Script2 plugin is not yet ready
diff --git a/modules/plugins/pom.xml b/modules/plugins/pom.xml index df4a58f..de81bb2 100644 --- a/modules/plugins/pom.xml +++ b/modules/plugins/pom.xml @@ -122,7 +122,6 @@ <module>sshd</module> <module>twitter</module> <!--<module>virt</module>--> - <module>script2</module>
<!-- make this the last - it will validate all the plugins --> <module>validate-all-plugins</module>
commit 102f47947bc80d353775ba762b6c7d9ef4a312fe Merge: 7121c20... 81c5278... Author: Heiko W. Rupp pilhuhn@fedorapeople.org Date: Tue Dec 8 08:22:30 2009 +0100
Merge branch 'master' of ssh://git.fedorahosted.org/git/rhq/rhq into plugins
commit 81c5278a1c8e5574ced22c915b69d8d50f4ffafd Author: Ian Springer ian.springer@redhat.com Date: Mon Dec 7 16:46:21 2009 -0500
fix Wagon settings to get publishing of snapshots working again
diff --git a/etc/m2/settings.xml b/etc/m2/settings.xml index 4d0c77f..93664e7 100644 --- a/etc/m2/settings.xml +++ b/etc/m2/settings.xml @@ -250,7 +250,8 @@ <pluginGroup>org.rhq</pluginGroup> </pluginGroups>
- <!-- See: http://maven.apache.org/settings.html#Servers --> + <!-- See: http://maven.apache.org/settings.html#Servers + and: http://maven.apache.org/guides/mini/guide-wagon-providers.html --> <servers> <server> <id>jboss-snapshots</id> @@ -258,6 +259,18 @@ used by the release plugin to publish via WebDAV to the JBoss Snapshots repo. --> <username>YOUR_USERNAME</username> <password>YOUR_PASSWORD</password> + <configuration> + <httpConfiguration> + <put> + <params> + <param> + <name>http.authentication.preemptive</name> + <value>%b,true</value> + </param> + </params> + </put> + </httpConfiguration> + </configuration> </server> </servers>
diff --git a/pom.xml b/pom.xml index 67bd171..ec5bd8a 100644 --- a/pom.xml +++ b/pom.xml @@ -632,24 +632,30 @@
</plugins>
+ <!-- To allow deploying release artifacts to SVN and snapshot artifacts to HTTP/Dav. --> <extensions> - - <!-- Add support for scm URLs in the distributionManagement section. --> <extension> <groupId>org.apache.maven.wagon</groupId> <artifactId>wagon-scm</artifactId> <version>1.0-beta-6</version> </extension> - - <!-- Add support for dav URLs in the distributionManagement section. --> <extension> - <groupId>org.apache.maven.wagon</groupId> - <artifactId>wagon-webdav-jackrabbit</artifactId> - <version>1.0-beta-6</version> + <groupId>org.apache.maven.scm</groupId> + <artifactId>maven-scm-manager-plexus</artifactId> + <version>1.0</version> </extension> - - </extensions> - + <extension> + <groupId>org.apache.maven.scm</groupId> + <artifactId>maven-scm-provider-svnexe</artifactId> + <version>1.0</version> + </extension> + <extension> + <groupId>org.apache.maven.wagon</groupId> + <artifactId>wagon-webdav</artifactId> + <version>1.0-beta-2</version> + </extension> + </extensions> + </build>
<repositories>
commit 3f5871140391868156a4a71a1ff5dc126539fbdc Author: Ian Springer ian.springer@redhat.com Date: Mon Dec 7 16:43:48 2009 -0500
upgrade JBossAS deps from 5.2.0-SNAPSHOT to 6.0.0.M1
diff --git a/modules/plugins/jboss-as-5/pom.xml b/modules/plugins/jboss-as-5/pom.xml index 5530b39..1fba8eb 100644 --- a/modules/plugins/jboss-as-5/pom.xml +++ b/modules/plugins/jboss-as-5/pom.xml @@ -29,7 +29,7 @@ <properties> <scm.module.path>modules/plugins/jboss-as-5/</scm.module.path>
- <jbossas.version>5.2.0-SNAPSHOT</jbossas.version> + <jbossas.version>6.0.0.M1</jbossas.version> </properties>
<dependencyManagement> diff --git a/modules/plugins/jboss-cache-v3/pom.xml b/modules/plugins/jboss-cache-v3/pom.xml index cb75b29..bb934b5 100644 --- a/modules/plugins/jboss-cache-v3/pom.xml +++ b/modules/plugins/jboss-cache-v3/pom.xml @@ -22,7 +22,7 @@
<properties> <scm.module.path>modules/plugins/jboss-cache-v3/</scm.module.path> - <jbossas.version>5.2.0-SNAPSHOT</jbossas.version> + <jbossas.version>6.0.0.M1</jbossas.version> <rhq.groupId>org.rhq</rhq.groupId> </properties>
commit e4ed52ad2ad82d538a60c2b51508ce523512529a Author: Partha Aji paji@redhat.com Date: Mon Dec 7 16:17:47 2009 -0500
Revert "More samba fixes"
This reverts commit 151a0c7dbf99f33c8ebfaa3be113b97826bc22de. Wrong diagnosis caused the wrong fix to be inserted into the testConfigUpdate Operation of the samba test..
diff --git a/modules/plugins/samba/src/test/java/org/rhq/plugins/samba/SambaComponentTest.java b/modules/plugins/samba/src/test/java/org/rhq/plugins/samba/SambaComponentTest.java index 335b582..82b527b 100644 --- a/modules/plugins/samba/src/test/java/org/rhq/plugins/samba/SambaComponentTest.java +++ b/modules/plugins/samba/src/test/java/org/rhq/plugins/samba/SambaComponentTest.java @@ -68,14 +68,7 @@ public class SambaComponentTest extends AbstractAugeasConfigurationComponentTest config.put(new PropertySimple("load printers", "DUMBCHANGE")); config.put(new PropertySimple("cups options", "DUMBCHANGE")); config.put(new PropertySimple("enableRecycleBin", true)); - config.put(new PropertySimple("idmap uid", null)); - config.put(new PropertySimple("idmap gid", null)); - config.put(new PropertySimple("winbind use default domain", null)); - config.put(new PropertySimple("winbind offline logon", null)); - config.put(new PropertySimple("winbind offline logon", null)); - config.put(new PropertySimple("winbind enum users", null)); - config.put(new PropertySimple("winbind enum groups", null)); - config.put(new PropertySimple("winbind separator", null)); + return config; } }
commit 7121c2056f27839b8d87372b5067843b048a124b Merge: 407ac0f... 62d82ea... Author: Heiko W. Rupp pilhuhn@fedorapeople.org Date: Mon Dec 7 20:45:29 2009 +0100
Merge branch 'master' of ssh://git.fedorahosted.org/git/rhq/rhq into plugins
commit c83453892b2e7e337df0c52284203b2aa880f5d0 Author: John Sanda john@localhost.localdomain Date: Mon Dec 7 14:29:07 2009 -0500
Adding support for raw update
diff --git a/modules/enterprise/remoting/scripts/src/main/script/configuration/update_structured.js b/modules/enterprise/remoting/scripts/src/main/script/configuration/update_structured.js index ccfafd2..65e56a2 100644 --- a/modules/enterprise/remoting/scripts/src/main/script/configuration/update_structured.js +++ b/modules/enterprise/remoting/scripts/src/main/script/configuration/update_structured.js @@ -25,6 +25,7 @@ var serverName = ''; var waitInterval = 100; var STRUCTURED_SERVER = 'Structured Server'; var STRUCTURED_ANR_RAW_SERVER = 'Structured and Raw Server' +var RAW_SERVER = 'Raw Server';
if (cmdLineArgsValid()) { updateConfiguration(); @@ -33,26 +34,28 @@ if (cmdLineArgsValid()) { function cmdLineArgsValid() { var isValid = true;
- if (!scriptUtil.isDefined('server')) { - println("'server' is a required argument"); - isValid = false; - } - - serverName = server; - if (!(serverName == 'structured' || serverName == 'structuredandraw')) { - println("server argument must be 'structured' or 'structuredandraw'"); - isValid = false; - } - - if (!scriptUtil.isDefined('propertyName')) { - println("'propertyName' is a required argument"); - isValid = false; - } - - if (!scriptUtil.isDefined('propertyValue')) { - println("'propertyValue' is a required argument\n"); - isValid = false; - } +// if (!scriptUtil.isDefined('server')) { +// println("'server' is a required argument"); +// isValid = false; +// } +// +// serverName = server; +// if (!(serverName == 'structured' || serverName == 'structuredandraw' || 'raw')) { +// println("Invalid value for server argument. Must be one of <structured | raw | structuredandraw>"); +// isValid = false; +// } +// +// if (server) +// +// if (!scriptUtil.isDefined('propertyName')) { +// println("'propertyName' is a required argument"); +// isValid = false; +// } +// +// if (!scriptUtil.isDefined('propertyValue')) { +// println("'propertyValue' is a required argument\n"); +// isValid = false; +// }
return isValid; } @@ -65,28 +68,43 @@ function updateConfiguration() { var resource = findServer(); var configuration = getLatestConfiguration(resource);
- printConfiguration(resource, configuration); - - if (propertyToUpdateIsUndefined(configuration)) { - println("The property '" + propertyName + "' is undefined. Update will abort."); - return; + if (isStructuredUpdate()) { + printConfiguration(resource, configuration); + verifyPropertyToUpdateExists(configuration) + applyStructuredUpdate(resource, configuration); + } + else { + printRawConfiguration(resource, configuration); + verifyRawContentExists(); + applyRawUpdate(resource, configuration); }
- applyUpdate(resource, configuration); waitForResourceConfigurationUpdateToComplete(resource.id);
println("Configuration update has completed."); configuration = getLatestConfiguration(resource); - printConfiguration(resource, configuration); + + if (isStructuredUpdate()) { + printConfiguration(resource, configuration); + } + else { + printRawConfiguration(resource, configuration); + } }
function setServerName() { if (server == 'structured') { serverName = STRUCTURED_SERVER; } - else { + else if (server == 'raw') { + serverName = RAW_SERVER; + } + else if (server == 'structuredandraw') { serverName = STRUCTURED_ANR_RAW_SERVER; } + else { + throw "\nInvalid value for server argument. Must be one of <structured | raw | structuredandraw>"; + } }
function findServer() { @@ -116,11 +134,32 @@ function printConfiguration(resource, configuration) { println(''); }
-function propertyToUpdateIsUndefined(configuration) { - return configuration.getSimple(propertyName) == null; +function printRawConfiguration(resource, configuration) { + var rawConfig = getRawConfig(configuration, 0); + + println("Fetching the latest resource configuration for " + resource.name); + pretty.print(configuration); + println("The contents of " + rawConfig.path + ":\n"); + println(java.lang.String(rawConfig.contents) + "\n--------------------------------------\n"); +} + +function isStructuredUpdate() { + return serverName == STRUCTURED_ANR_RAW_SERVER || serverName == STRUCTURED_SERVER; +} + +function verifyPropertyToUpdateExists(configuration) { + if(configuration.getSimple(propertyName) == null) { + throw "\nThe property '" + propertyName + "' is undefined. Update will abort." + } }
-function applyUpdate(resource, configuration) { +function verifyRawContentExists() { + if (!isDefined('contents')) { + throw "\n'contents' argument is required when updating " + serverName; + } +} + +function applyStructuredUpdate(resource, configuration) { var property = configuration.getSimple(propertyName); property.stringValue = propertyValue;
@@ -129,6 +168,27 @@ function applyUpdate(resource, configuration) { ConfigurationManager.updateStructuredOrRawConfiguration(resource.id, configuration, true); }
+function applyRawUpdate(resource, configuration) { + var rawConfig = getRawConfig(configuration, 0); + + configuration.rawConfigurations.remove(rawConfig); + + var contentsString = java.lang.String(eval(contents)); + rawConfig.contents = contentsString.bytes; + configuration.rawConfigurations.add(rawConfig); + + println("Apply resource configuration update..."); + + ConfigurationManager.updateStructuredOrRawConfiguration(resource.id, configuration, false); +} + +function getRawConfig(configuration, index) { + var rawConfigs = java.util.LinkedList(configuration.rawConfigurations); + var rawConfig = rawConfigs.get(index); + + return rawConfig; +} + function waitForResourceConfigurationUpdateToComplete(resourceId) { print("Waiting for configuration update to complete...") while (ConfigurationManager.isResourceConfigurationUpdateInProgress(resourceId)) {
commit 41fc0866e3ebbb7ea0e28a408b66826bf6ac6d85 Author: John Mazzitelli mazz@redhat.com Date: Mon Dec 7 13:25:51 2009 -0500
rename the method/change log messages to make it clear this is starting the deployer that handles both agent AND server plugins
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/startup/StartupServlet.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/startup/StartupServlet.java index 5bb81d3..3407392 100644 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/startup/StartupServlet.java +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/startup/StartupServlet.java @@ -116,7 +116,7 @@ public class StartupServlet extends HttpServlet { // (that is, a scheduled job would more likely need to send a message; as opposed to an incoming message // causing a job to be scheduled), so that explains the ordering of the comm layer and the scheduler. startHibernateStatistics(); - startAgentPluginDeployer(); + startPluginDeployer(); startServerPluginContainer(); // before comm in case an agent wants to talk to it installJaasModules(); startServerCommunicationServices(); @@ -204,12 +204,12 @@ public class StartupServlet extends HttpServlet {
/** * Starts the plugin deployer which will effectively ask the plugin deployer to persist information about all - * detected agent plugins. + * detected agent and server plugins. * * @throws ServletException */ - private void startAgentPluginDeployer() throws ServletException { - log("Starting the agent-plugin deployer"); + private void startPluginDeployer() throws ServletException { + log("Starting the agent/server plugin deployer");
try { PluginDeploymentScannerMBean deployer_mbean; @@ -220,7 +220,7 @@ public class StartupServlet extends HttpServlet { iface, false); deployer_mbean.startDeployment(); } catch (Exception e) { - throw new ServletException("Cannot start the agent-plugin deployer", e); + throw new ServletException("Cannot start the agent/server plugin deployer", e); } }
commit 4830d2a6cc57d0feb6e4157a50d25556844eda08 Author: John Sanda john@localhost.localdomain Date: Mon Dec 7 13:20:20 2009 -0500
Adding a test script for applying structured updates
Also adding and exposing an isDefined() method to CLI srcipts.
diff --git a/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/utility/ScriptUtil.java b/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/utility/ScriptUtil.java index eef3f5a..327ba5e 100644 --- a/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/utility/ScriptUtil.java +++ b/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/utility/ScriptUtil.java @@ -30,9 +30,13 @@ import org.rhq.core.domain.resource.Resource; import org.rhq.core.domain.util.PageList; import org.rhq.core.domain.util.PageOrdering; import org.rhq.enterprise.client.ClientMain; +import org.rhq.enterprise.client.commands.ScriptCommand; import org.rhq.enterprise.server.operation.ResourceOperationSchedule; import org.rhq.enterprise.server.resource.ResourceManagerRemote;
+import javax.script.Bindings; +import javax.script.ScriptContext; +import javax.script.ScriptEngine; import java.io.File; import java.io.FileInputStream; import java.io.IOException; @@ -138,4 +142,14 @@ public class ScriptUtil {
return history; } + + public boolean isDefined(String identifier) { + ScriptCommand cmd = (ScriptCommand) client.getCommands().get("exec"); + ScriptEngine scriptEngine = cmd.getScriptEngine(); + + Bindings engineBindings = scriptEngine.getBindings(ScriptContext.ENGINE_SCOPE); + Bindings globalBindings = scriptEngine.getBindings(ScriptContext.GLOBAL_SCOPE); + + return engineBindings.containsKey(identifier) || globalBindings.containsKey(identifier); + } } diff --git a/modules/enterprise/remoting/scripts/src/main/script/configuration/update_structured.js b/modules/enterprise/remoting/scripts/src/main/script/configuration/update_structured.js new file mode 100644 index 0000000..ccfafd2 --- /dev/null +++ b/modules/enterprise/remoting/scripts/src/main/script/configuration/update_structured.js @@ -0,0 +1,139 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2008 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, version 2, as + * published by the Free Software Foundation, and/or the GNU Lesser + * General Public License, version 2.1, also as published by the Free + * Software Foundation. + * + * 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 and the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * and the GNU Lesser 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. + */ + +var serverName = ''; +var waitInterval = 100; +var STRUCTURED_SERVER = 'Structured Server'; +var STRUCTURED_ANR_RAW_SERVER = 'Structured and Raw Server' + +if (cmdLineArgsValid()) { + updateConfiguration(); +} + +function cmdLineArgsValid() { + var isValid = true; + + if (!scriptUtil.isDefined('server')) { + println("'server' is a required argument"); + isValid = false; + } + + serverName = server; + if (!(serverName == 'structured' || serverName == 'structuredandraw')) { + println("server argument must be 'structured' or 'structuredandraw'"); + isValid = false; + } + + if (!scriptUtil.isDefined('propertyName')) { + println("'propertyName' is a required argument"); + isValid = false; + } + + if (!scriptUtil.isDefined('propertyValue')) { + println("'propertyValue' is a required argument\n"); + isValid = false; + } + + return isValid; +} + +function updateConfiguration() { + setServerName(); + + println("\nPreapring to update configuration for " + serverName); + + var resource = findServer(); + var configuration = getLatestConfiguration(resource); + + printConfiguration(resource, configuration); + + if (propertyToUpdateIsUndefined(configuration)) { + println("The property '" + propertyName + "' is undefined. Update will abort."); + return; + } + + applyUpdate(resource, configuration); + waitForResourceConfigurationUpdateToComplete(resource.id); + + println("Configuration update has completed."); + configuration = getLatestConfiguration(resource); + printConfiguration(resource, configuration); +} + +function setServerName() { + if (server == 'structured') { + serverName = STRUCTURED_SERVER; + } + else { + serverName = STRUCTURED_ANR_RAW_SERVER; + } +} + +function findServer() { + var criteria = ResourceCriteria(); + criteria.strict = true; + criteria.addFilterName(serverName); + + var resources = ResourceManager.findResourcesByCriteria(criteria); + + Assert.assertTrue(resources.size() == 1, "Expected to get back one resource but got back " + resources.size()); + + return resources.get(0); +} + +function getLatestConfiguration(resource) { + var latestUpdate = ConfigurationManager.getLatestResourceConfigurationUpdate(resource.id); + + Assert.assertNotNull(latestUpdate, "Failed to load the latest resource configuration update for " + resource.name); + Assert.assertNotNull(latestUpdate.configuration, "No configuration is attached to the latest config update object."); + + return latestUpdate.configuration; +} + +function printConfiguration(resource, configuration) { + println("Fetching the latest resource configuration for " + resource.name); + pretty.print(configuration); + println(''); +} + +function propertyToUpdateIsUndefined(configuration) { + return configuration.getSimple(propertyName) == null; +} + +function applyUpdate(resource, configuration) { + var property = configuration.getSimple(propertyName); + property.stringValue = propertyValue; + + println("Apply resource configuration update..."); + + ConfigurationManager.updateStructuredOrRawConfiguration(resource.id, configuration, true); +} + +function waitForResourceConfigurationUpdateToComplete(resourceId) { + print("Waiting for configuration update to complete...") + while (ConfigurationManager.isResourceConfigurationUpdateInProgress(resourceId)) { + print("."); + java.lang.Thread.sleep(waitInterval); + } + println(''); +} \ No newline at end of file
commit 151a0c7dbf99f33c8ebfaa3be113b97826bc22de Author: Partha Aji paji@redhat.com Date: Mon Dec 7 13:02:07 2009 -0500
More samba fixes
diff --git a/modules/plugins/samba/src/test/java/org/rhq/plugins/samba/SambaComponentTest.java b/modules/plugins/samba/src/test/java/org/rhq/plugins/samba/SambaComponentTest.java index 82b527b..335b582 100644 --- a/modules/plugins/samba/src/test/java/org/rhq/plugins/samba/SambaComponentTest.java +++ b/modules/plugins/samba/src/test/java/org/rhq/plugins/samba/SambaComponentTest.java @@ -68,7 +68,14 @@ public class SambaComponentTest extends AbstractAugeasConfigurationComponentTest config.put(new PropertySimple("load printers", "DUMBCHANGE")); config.put(new PropertySimple("cups options", "DUMBCHANGE")); config.put(new PropertySimple("enableRecycleBin", true)); - + config.put(new PropertySimple("idmap uid", null)); + config.put(new PropertySimple("idmap gid", null)); + config.put(new PropertySimple("winbind use default domain", null)); + config.put(new PropertySimple("winbind offline logon", null)); + config.put(new PropertySimple("winbind offline logon", null)); + config.put(new PropertySimple("winbind enum users", null)); + config.put(new PropertySimple("winbind enum groups", null)); + config.put(new PropertySimple("winbind separator", null)); return config; } }
commit a39454fca038f3652ffa1090ea65f4fb55b5394e Merge: 613167d... 62d82ea... Author: Partha Aji paji@redhat.com Date: Mon Dec 7 11:51:38 2009 -0500
Fixed merge conflicts
diff --cc modules/enterprise/server/plugins/pom.xml index 69a1da3,7be2d7a..2c6472a --- a/modules/enterprise/server/plugins/pom.xml +++ b/modules/enterprise/server/plugins/pom.xml @@@ -1,48 -1,50 +1,53 @@@ -<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> +<project + xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd%22%3E
- <modelVersion>4.0.0</modelVersion> + <modelVersion>4.0.0</modelVersion>
- <parent> - <groupId>org.rhq</groupId> - <artifactId>rhq-parent</artifactId> - <version>1.4.0-SNAPSHOT</version> - </parent> - - <groupId>org.rhq</groupId> - <artifactId>rhq-enterprise-server-plugins-parent</artifactId> - <packaging>pom</packaging> - - <name>RHQ Enterprise Server Plugins</name> - <description>RHQ enterprise server plugins parent POM</description> - - <scm> - <connection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/modules/enterprise/server/plugins</connection> - <developerConnection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/modules/enterprise/server/plugins/</developerConnection> - </scm> - - <properties> - <scm.module.path>modules/enterprise/server/plugins/</scm.module.path> - </properties> - - <!-- all server-side plugins have access to some of the server-side APIs, therefore, we need this dependency --> - <dependencies> - <dependency> + <parent> <groupId>org.rhq</groupId> - <artifactId>rhq-enterprise-server</artifactId> - <version>${project.version}</version> - <type>ejb</type> - </dependency> - </dependencies> - + <artifactId>rhq-parent</artifactId> + <version>1.4.0-SNAPSHOT</version> + </parent> + + <groupId>org.rhq</groupId> + <artifactId>rhq-enterprise-server-plugins-parent</artifactId> + <packaging>pom</packaging> + + <name>RHQ Enterprise Server Plugins</name> + <description>RHQ enterprise server plugins parent POM</description> + + <scm> + <connection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/modules/enterprise/server/plugins</connection> + <developerConnection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/modules/enterprise/server/plugins/</developerConnection> + </scm> + + <properties> + <scm.module.path>modules/enterprise/server/plugins/</scm.module.path> + </properties> + + <!-- all server-side plugins have access to some of the server-side APIs, therefore, we need this dependency --> + <dependencies> + <dependency> + <groupId>org.rhq</groupId> + <artifactId>rhq-enterprise-server</artifactId> + <version>${project.version}</version> + <type>ejb</type> + </dependency> + </dependencies> - - <modules> - <module>disk</module> - <module>yum</module> - <module>url</module> - <module>rhnhosted</module> - <module>perspectives/core</module> - </modules> + <modules> + <module>disk</module> + <module>yum</module> + <module>url</module> + <module>rhnhosted</module> ++ <module>perspectives/core</module> + <module>alert-email</module> + <module>alert-mobicents</module> + <module>alert-microblog</module> + <module>alert-roles</module> + <module>alert-snmp</module> + <module>validate-all-serverplugins</module> + </modules>
</project>
commit 613167d78480196e70d9151ed7bca618f7e9820b Author: Partha Aji paji@redhat.com Date: Mon Dec 7 11:25:08 2009 -0500
Fixed samba unit tests
diff --git a/modules/plugins/samba/src/test/java/org/rhq/plugins/samba/SambaComponentTest.java b/modules/plugins/samba/src/test/java/org/rhq/plugins/samba/SambaComponentTest.java index 46f816c..82b527b 100644 --- a/modules/plugins/samba/src/test/java/org/rhq/plugins/samba/SambaComponentTest.java +++ b/modules/plugins/samba/src/test/java/org/rhq/plugins/samba/SambaComponentTest.java @@ -35,6 +35,15 @@ public class SambaComponentTest extends AbstractAugeasConfigurationComponentTest config.put(new PropertySimple("load printers", "yes")); config.put(new PropertySimple("cups options", "raw")); config.put(new PropertySimple("enableRecycleBin", false)); + + config.put(new PropertySimple("idmap uid", null)); + config.put(new PropertySimple("idmap gid", null)); + config.put(new PropertySimple("winbind use default domain", null)); + config.put(new PropertySimple("winbind offline logon", null)); + config.put(new PropertySimple("winbind offline logon", null)); + config.put(new PropertySimple("winbind enum users", null)); + config.put(new PropertySimple("winbind enum groups", null)); + config.put(new PropertySimple("winbind separator", null)); return config; }
commit 53fe766fd0f0a077745ab3ad9201a250df22e049 Author: Justin Harris jharris@redhat.com Date: Mon Dec 7 10:45:33 2009 -0500
Fixing typo in db-upgrade.
diff --git a/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml b/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml index b2532b7..a2182a7 100644 --- a/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml +++ b/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml @@ -2210,8 +2210,8 @@ REFERENCES RHQ_SUBJECT(ID) </statement> </schema-directSQL> - <schema-addColumn table="RHQ_ALERT_NOTIFICATION" column="ALERT_SENDER_NAME" type="VARCHAR2"/> - <schema-addColumn table="RHQ_ALERT_NOTIFICATION" column="ALERT_CONFIG_ID" type="INTEGER"/> + <schema-addColumn table="RHQ_ALERT_NOTIFICATION" column="ALERT_SENDER_NAME" columnType="VARCHAR2"/> + <schema-addColumn table="RHQ_ALERT_NOTIFICATION" column="ALERT_CONFIG_ID" columnType="INTEGER"/> <schema-directSQL> <statement> ALTER TABLE RHQ_ALERT_NOTIFICATION
commit 62d82ea0eba8824a1d22ccb8b875666d9a753814 Author: Bryan Kearney bkearney@localhost.localdomain Date: Mon Dec 7 10:42:27 2009 -0500
Typo in the db upgrade script
diff --git a/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml b/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml index b2532b7..a2182a7 100644 --- a/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml +++ b/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml @@ -2210,8 +2210,8 @@ REFERENCES RHQ_SUBJECT(ID) </statement> </schema-directSQL> - <schema-addColumn table="RHQ_ALERT_NOTIFICATION" column="ALERT_SENDER_NAME" type="VARCHAR2"/> - <schema-addColumn table="RHQ_ALERT_NOTIFICATION" column="ALERT_CONFIG_ID" type="INTEGER"/> + <schema-addColumn table="RHQ_ALERT_NOTIFICATION" column="ALERT_SENDER_NAME" columnType="VARCHAR2"/> + <schema-addColumn table="RHQ_ALERT_NOTIFICATION" column="ALERT_CONFIG_ID" columnType="INTEGER"/> <schema-directSQL> <statement> ALTER TABLE RHQ_ALERT_NOTIFICATION
commit ee6395b66eb25bffd1159d3d615d9afb80b98aa5 Author: Heiko W. Rupp pilhuhn@fedorapeople.org Date: Mon Dec 7 15:47:36 2009 +0100
Improve wording
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/resource/common/monitor/alerts/config/ViewDefinition.jsp b/modules/enterprise/gui/portal-war/src/main/webapp/resource/common/monitor/alerts/config/ViewDefinition.jsp index c445744..b8494f6 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/resource/common/monitor/alerts/config/ViewDefinition.jsp +++ b/modules/enterprise/gui/portal-war/src/main/webapp/resource/common/monitor/alerts/config/ViewDefinition.jsp @@ -26,6 +26,6 @@
<tiles:insert definition=".events.config.view.nav"/>
-<a href="/rhq/resource/alert/notif/listAlertSender.xhtml?id=${param.id}&ad=${param.ad}">Alert sender stuff</a> <!-- TODO fix and pass real id + ad--> +<a href="/rhq/resource/alert/notif/listAlertSender.xhtml?id=${param.id}&ad=${param.ad}">To Alert sender plugins</a>
<tiles:insert definition=".page.footer"/>
commit 8e63e6c026238c2905cf7d9396afba6efc99bfbc Author: Heiko W. Rupp pilhuhn@fedorapeople.org Date: Mon Dec 7 15:44:43 2009 +0100
Some more cleanup and little UI improvements.
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/ListNotificationsUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/ListNotificationsUIBean.java index 44cb584..f482acf 100644 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/ListNotificationsUIBean.java +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/ListNotificationsUIBean.java @@ -18,14 +18,14 @@ */ package org.rhq.enterprise.gui.alert;
+import java.io.Serializable; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map;
-import javax.faces.context.ExternalContext; -import javax.faces.context.FacesContext; +import javax.faces.application.FacesMessage;
import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -54,7 +54,7 @@ import org.rhq.enterprise.server.util.LookupUtil; */ @Scope(ScopeType.PAGE) @Name("ListNotificationsUIBean") -public class ListNotificationsUIBean { +public class ListNotificationsUIBean implements Serializable {
public static final String MANAGED_BEAN_NAME = "ListNotificationsUIBean"; private static final String OUTCOME_SUCCESS = "success"; @@ -146,6 +146,7 @@ public class ListNotificationsUIBean { AlertNotificationManagerLocal mgr = LookupUtil.getAlertNotificationManager(); Subject subject = EnterpriseFacesContextUtility.getSubject(); mgr.addAlertNotification(subject, alertDefinitionId,selectedSender,alertProperties); + // TODO leave message after checking success from backend return OUTCOME_SUCCESS; }
@@ -162,14 +163,16 @@ public class ListNotificationsUIBean { public String removeSelectedNotifications() { String[] stringItems = FacesContextUtility.getRequest().getParameterValues("selectedNotification"); if (stringItems == null || stringItems.length == 0) { - return OUTCOME_SUCCESS; // TODO leave message + FacesContextUtility.addMessage(FacesMessage.SEVERITY_WARN,"Nothing selected"); + return OUTCOME_SUCCESS; }
Integer[] notificationIds = StringUtility.getIntegerArray(stringItems);
AlertNotificationManagerLocal mgr = LookupUtil.getAlertNotificationManager(); Subject subject = EnterpriseFacesContextUtility.getSubject(); - mgr.removeNotifications(subject,alertDefinitionId,notificationIds); + int count = mgr.removeNotifications(subject,alertDefinitionId,notificationIds); + FacesContextUtility.addMessage(FacesMessage.SEVERITY_INFO,"Removed " + count + " items");
return OUTCOME_SUCCESS; } @@ -179,7 +182,7 @@ public class ListNotificationsUIBean { AlertNotificationManagerLocal mgr = LookupUtil.getAlertNotificationManager(); Subject subject = EnterpriseFacesContextUtility.getSubject();
- AlertSenderInfo info = mgr.getAlertInfoForSender(selectedSender); + AlertSenderInfo info = mgr.getAlertInfoForSender(selectedSender); if (info!=null && info.getUiSnippetUrl()!=null) return info.getUiSnippetUrl().toString(); else diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerBean.java index c72980a..e948aac 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerBean.java @@ -413,20 +413,6 @@ public class AlertNotificationManagerBean implements AlertNotificationManagerLoc return removed; }
- public void setSnmpNotification(Subject subject, Integer alertDefinitionId, SnmpNotification snmpNotification) { - AlertDefinition alertDefinition = getDetachedAlertDefinition(alertDefinitionId); - Set<AlertNotification> alertNotifications = alertDefinition.getAlertNotifications(); - for (AlertNotification alertNotification : alertNotifications) { - if (alertNotification instanceof SnmpNotification) { - alertNotifications.remove(alertNotification); - } - } - - alertNotifications.add(snmpNotification); - - postProcessAlertDefinition(alertDefinition); - } - public int purgeOrphanedAlertNotifications() { Query purgeQuery = entityManager.createNamedQuery(AlertNotification.QUERY_DELETE_ORPHANED); return purgeQuery.executeUpdate(); diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerLocal.java index 8093b7f..f67927f 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerLocal.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerLocal.java @@ -47,8 +47,6 @@ public interface AlertNotificationManagerLocal {
int addSubjectNotifications(Subject subject, Integer alertDefinitionId, Integer[] subjectId);
- void setSnmpNotification(Subject subject, Integer alertDefinitionId, SnmpNotification snmpNotification); - PageList<EmailNotification> getEmailNotifications(Integer alertDefinitionId, PageControl pageControl);
PageList<RoleNotification> getRoleNotifications(Integer alertDefinitionId, PageControl pageControl); @@ -67,6 +65,13 @@ public interface AlertNotificationManagerLocal {
PageList<SubjectNotification> getSubjectNotificationsBySubjects(Integer[] subjectId, PageControl pageControl);
+ /** + * Remove the passed notifications from the passed alert definition (all identified by their id) + * @param subject Caller + * @param alertDefinitionId alert definition to modify + * @param notificationIds Notifications to remove + * @return number of notifications removed + */ int removeNotifications(Subject subject, Integer alertDefinitionId, Integer[] notificationIds);
int purgeOrphanedAlertNotifications();
commit 628820eb8a6bd20119830d7940413f1be4266cd5 Author: Heiko W. Rupp pilhuhn@fedorapeople.org Date: Mon Dec 7 14:40:45 2009 +0100
Always log the result to info level for now.
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerBean.java index 17faabf..20fa9c8 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerBean.java @@ -672,6 +672,7 @@ public class AlertManagerBean implements AlertManagerLocal, AlertManagerRemote { emailAddresses.addAll(result.getEmails()); } // TODO log result + log.info(result); } catch (Throwable t) { log.error("Sender failed: " + t.getMessage());
commit 034c6a716f8c566496c9d6a0deb2179d1da28434 Author: Heiko W. Rupp pilhuhn@fedorapeople.org Date: Mon Dec 7 10:19:49 2009 +0100
Get rid of the old SNMP gui stuff, as this is now contained in the alert-snmp server plugin.
diff --git a/modules/enterprise/gui/portal-war/pom.xml b/modules/enterprise/gui/portal-war/pom.xml index 01a49cf..7de6682 100644 --- a/modules/enterprise/gui/portal-war/pom.xml +++ b/modules/enterprise/gui/portal-war/pom.xml @@ -329,12 +329,6 @@ </dependency>
<dependency> - <groupId>org.snmp4j</groupId> - <artifactId>snmp4j</artifactId> - <version>1.7.1</version> - </dependency> - - <dependency> <groupId>struts</groupId> <artifactId>struts</artifactId> <version>1.2.9</version> @@ -548,7 +542,7 @@ </build> </profile>
- <!-- + <!-- <profile> <id>dist</id>
@@ -586,4 +580,4 @@ </repository> </repositories>
-</project> \ No newline at end of file +</project> diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/config/SystemConfigForm.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/config/SystemConfigForm.java index fb2418c..c636aa2 100644 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/config/SystemConfigForm.java +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/config/SystemConfigForm.java @@ -64,20 +64,6 @@ public class SystemConfigForm extends BaseValidatorForm { private String ldapPassword = ""; private Boolean ldapEnabled = null; private boolean reindex = false; - private String snmpAuthProtocol = ""; - private String snmpAuthPassphrase = ""; - private String snmpPrivacyPassphrase = ""; - private String snmpCommunity = ""; - private String snmpEngineID = ""; - private String snmpContextName = ""; - private String snmpSecurityName = ""; - private String snmpTrapOID = ""; - private String snmpEnterpriseOID = ""; - private String snmpGenericID = ""; - private String snmpSpecificID = ""; - private String snmpAgentAddress = ""; - private String snmpVersion = ""; - private String snmpPrivacyProtocol = "";
@Override public String toString() { @@ -97,20 +83,6 @@ public class SystemConfigForm extends BaseValidatorForm { buf.append(" ldapSearchFilter=").append(ldapSearchFilter); buf.append(" ldapUsername=").append(ldapUsername); buf.append(" ldapPassword=").append(ldapPassword); - buf.append(" snmpAuthProtocol =").append(snmpAuthProtocol); - buf.append(" snmpAuthPassphrase =").append(snmpAuthPassphrase); - buf.append(" snmpPrivacyPassphrase =").append(snmpPrivacyPassphrase); - buf.append(" snmpCommunity =").append(snmpCommunity); - buf.append(" snmpEngineID =").append(snmpEngineID); - buf.append(" snmpContextName =").append(snmpContextName); - buf.append(" snmpSecurityName =").append(snmpSecurityName); - buf.append(" snmpTrapOID =").append(snmpTrapOID); - buf.append(" snmpEnterpriseOID =").append(snmpEnterpriseOID); - buf.append(" snmpGenericID =").append(snmpGenericID); - buf.append(" snmpSpecificID =").append(snmpSpecificID); - buf.append(" snmpAgentAddress =").append(snmpAgentAddress); - buf.append(" snmpVersion =").append(snmpVersion); - buf.append(" snmpPrivacyProtocol =").append(snmpPrivacyProtocol);
return buf.toString(); } @@ -153,20 +125,6 @@ public class SystemConfigForm extends BaseValidatorForm { ldapSearchFilter = ""; ldapUsername = ""; ldapPassword = ""; - snmpAuthProtocol = ""; - snmpAuthPassphrase = ""; - snmpPrivacyPassphrase = ""; - snmpCommunity = ""; - snmpEngineID = ""; - snmpContextName = ""; - snmpSecurityName = ""; - snmpTrapOID = ""; - snmpEnterpriseOID = ""; - snmpGenericID = ""; - snmpSpecificID = ""; - snmpAgentAddress = ""; - snmpVersion = ""; - snmpPrivacyProtocol = "";
super.reset(mapping, request); } @@ -264,20 +222,6 @@ public class SystemConfigForm extends BaseValidatorForm { String jaasProvider = prop.getProperty(RHQConstants.JAASProvider); ldapEnabled = RHQConstants.LDAPJAASProvider.equals(jaasProvider) ? Boolean.TRUE : null;
- snmpAuthProtocol = prop.getProperty(RHQConstants.SNMPAuthProtocol); - snmpAuthPassphrase = prop.getProperty(RHQConstants.SNMPAuthPassphrase); - snmpPrivacyPassphrase = prop.getProperty(RHQConstants.SNMPPrivacyPassphrase); - snmpCommunity = prop.getProperty(RHQConstants.SNMPCommunity); - snmpEngineID = prop.getProperty(RHQConstants.SNMPEngineID); - snmpContextName = prop.getProperty(RHQConstants.SNMPContextName); - snmpSecurityName = prop.getProperty(RHQConstants.SNMPSecurityName); - snmpTrapOID = prop.getProperty(RHQConstants.SNMPTrapOID); - snmpEnterpriseOID = prop.getProperty(RHQConstants.SNMPEnterpriseOID); - snmpGenericID = prop.getProperty(RHQConstants.SNMPGenericID); - snmpSpecificID = prop.getProperty(RHQConstants.SNMPSpecificID); - snmpAgentAddress = prop.getProperty(RHQConstants.SNMPAgentAddress); - snmpVersion = prop.getProperty(RHQConstants.SNMPVersion); - snmpPrivacyProtocol = prop.getProperty(RHQConstants.SNMPPrivacyProtocol); }
/** @@ -378,31 +322,6 @@ public class SystemConfigForm extends BaseValidatorForm { prop.setProperty(RHQConstants.JAASProvider, RHQConstants.JDBCJAASProvider); }
- prop.setProperty(RHQConstants.SNMPVersion, snmpVersion); - - if (snmpVersion.length() > 0) { - prop.setProperty(RHQConstants.SNMPTrapOID, snmpTrapOID); - - if ("3".equals(snmpVersion)) { - prop.setProperty(RHQConstants.SNMPAuthProtocol, snmpAuthProtocol); - prop.setProperty(RHQConstants.SNMPAuthPassphrase, snmpAuthPassphrase); - prop.setProperty(RHQConstants.SNMPPrivacyPassphrase, snmpPrivacyPassphrase); - prop.setProperty(RHQConstants.SNMPPrivacyProtocol, snmpPrivacyProtocol); - prop.setProperty(RHQConstants.SNMPContextName, snmpContextName); - prop.setProperty(RHQConstants.SNMPSecurityName, snmpSecurityName); - } else { - prop.setProperty(RHQConstants.SNMPCommunity, snmpCommunity); - - if ("1".equals(snmpVersion)) { - prop.setProperty(RHQConstants.SNMPEngineID, snmpEngineID); - prop.setProperty(RHQConstants.SNMPEnterpriseOID, snmpEnterpriseOID); - prop.setProperty(RHQConstants.SNMPGenericID, snmpGenericID); - prop.setProperty(RHQConstants.SNMPSpecificID, snmpSpecificID); - prop.setProperty(RHQConstants.SNMPAgentAddress, snmpAgentAddress); - } - } - } - return prop; }
@@ -664,117 +583,6 @@ public class SystemConfigForm extends BaseValidatorForm { this.reindex = reindex; }
- public String getSnmpAgentAddress() { - return snmpAgentAddress; - } - - public void setSnmpAgentAddress(String snmpAgentAddress) { - this.snmpAgentAddress = snmpAgentAddress; - } - - public String getSnmpAuthPassphrase() { - return snmpAuthPassphrase; - } - - public void setSnmpAuthPassphrase(String snmpAuthPassphrase) { - this.snmpAuthPassphrase = snmpAuthPassphrase; - } - - public String getSnmpAuthProtocol() { - return snmpAuthProtocol; - } - - public void setSnmpAuthProtocol(String snmpAuthProtocol) { - this.snmpAuthProtocol = snmpAuthProtocol; - } - - public String getSnmpCommunity() { - return snmpCommunity; - } - - public void setSnmpCommunity(String snmpCommunity) { - this.snmpCommunity = snmpCommunity; - } - - public String getSnmpContextName() { - return snmpContextName; - } - - public void setSnmpContextName(String snmpContextName) { - this.snmpContextName = snmpContextName; - } - - public String getSnmpEngineID() { - return snmpEngineID; - } - - public void setSnmpEngineID(String snmpEngineID) { - this.snmpEngineID = snmpEngineID; - } - - public String getSnmpEnterpriseOID() { - return snmpEnterpriseOID; - } - - public void setSnmpEnterpriseOID(String snmpEnterpriseOID) { - this.snmpEnterpriseOID = snmpEnterpriseOID; - } - - public String getSnmpGenericID() { - return snmpGenericID; - } - - public void setSnmpGenericID(String snmpGenericID) { - this.snmpGenericID = snmpGenericID; - } - - public String getSnmpPrivacyPassphrase() { - return snmpPrivacyPassphrase; - } - - public void setSnmpPrivacyPassphrase(String snmpPrivacyPassphrase) { - this.snmpPrivacyPassphrase = snmpPrivacyPassphrase; - } - - public String getSnmpPrivacyProtocol() { - return snmpPrivacyProtocol; - } - - public void setSnmpPrivacyProtocol(String snmpPrivacyProtocol) { - this.snmpPrivacyProtocol = snmpPrivacyProtocol; - } - - public String getSnmpSecurityName() { - return snmpSecurityName; - } - - public void setSnmpSecurityName(String snmpSecurityName) { - this.snmpSecurityName = snmpSecurityName; - } - - public String getSnmpSpecificID() { - return snmpSpecificID; - } - - public void setSnmpSpecificID(String snmpSpecificID) { - this.snmpSpecificID = snmpSpecificID; - } - - public String getSnmpTrapOID() { - return snmpTrapOID; - } - - public void setSnmpTrapOID(String snmpTrapOID) { - this.snmpTrapOID = snmpTrapOID; - } - - public String getSnmpVersion() { - return snmpVersion; - } - - public void setSnmpVersion(String snmpVersion) { - this.snmpVersion = snmpVersion; - }
/* (non-Javadoc) * @see org.apache.struts.action.ActionForm#validate(org.apache.struts.action.ActionMapping, @@ -788,17 +596,6 @@ public class SystemConfigForm extends BaseValidatorForm { errors = new ActionErrors(); }
- if (!empty(snmpVersion) && "3".equals(snmpVersion) && !empty(snmpAuthProtocol) && empty(snmpAuthPassphrase)) { - ActionMessage errorMessage = new ActionMessage("admin.settings.SNMPAuthPassphrase"); - errors.add("snmpAuthPassphrase", errorMessage); - } - - if (!empty(snmpVersion) && "3".equals(snmpVersion) && !empty(snmpPrivacyProtocol) - && empty(snmpPrivacyPassphrase)) { - ActionMessage errorMessage = new ActionMessage("admin.settings.SNMPPrivPassphrase"); - errors.add("snmpPrivacyPassphrase", errorMessage); - } - if (!empty(baselineDataSetVal)) { try { long freq = Long.parseLong(baselineDataSetVal); @@ -856,4 +653,4 @@ public class SystemConfigForm extends BaseValidatorForm { private boolean empty(String s) { return (s == null) || (s.length() == 0); } -} \ No newline at end of file +} diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/action/resource/common/monitor/alerts/config/PortalAction.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/action/resource/common/monitor/alerts/config/PortalAction.java index fdd3846..df7a3c8 100644 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/action/resource/common/monitor/alerts/config/PortalAction.java +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/action/resource/common/monitor/alerts/config/PortalAction.java @@ -72,7 +72,6 @@ public class PortalAction extends ResourceController { keyMethodMap.setProperty("viewOthers", "viewDefinitionOthers"); keyMethodMap.setProperty("viewRoles", "viewDefinitionRoles"); keyMethodMap.setProperty("viewUsers", "viewDefinitionUsers"); - keyMethodMap.setProperty("viewSnmp", "viewDefinitionSNMP");
keyMethodMap.setProperty("addOthers", "addOthersDefinitions"); keyMethodMap.setProperty("addRoles", "addRolesDefinitions"); @@ -128,16 +127,6 @@ public class PortalAction extends ResourceController { } }
- private void setSNMPEnabled(HttpServletRequest request) throws RemoteException { - Properties props = LookupUtil.getSystemManager().getSystemConfiguration(); - - // See if the property exists - if (props.containsKey(RHQConstants.SNMPVersion)) { - String ver = props.getProperty(RHQConstants.SNMPVersion); - request.setAttribute("snmpEnabled", ver.length() > 0); - } - } - public ActionForward newDefinition(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { setResource(request); @@ -208,7 +197,6 @@ public class PortalAction extends ResourceController { // JW - this shouldn't be a dialog ... portal.setDialog(true); request.setAttribute(Constants.PORTAL_KEY, portal);
- setSNMPEnabled(request); return null; }
@@ -222,7 +210,6 @@ public class PortalAction extends ResourceController { // JW - this shouldn't be a dialog ... portal.setDialog(true); request.setAttribute(Constants.PORTAL_KEY, portal);
- setSNMPEnabled(request); return null; }
@@ -236,21 +223,9 @@ public class PortalAction extends ResourceController { // JW - this shouldn't be a dialog ... portal.setDialog(true); request.setAttribute(Constants.PORTAL_KEY, portal);
- setSNMPEnabled(request); return null; }
- public ActionForward viewDefinitionSNMP(ActionMapping mapping, ActionForm form, HttpServletRequest request, - HttpServletResponse response) throws Exception { - setResource(request); - Portal portal = Portal.createPortal(); - setTitle(request, portal, "alert.config.platform.props.ViewDef.users.Title"); - portal.addPortlet(new Portlet(".events.config.view.snmp"), 1); - request.setAttribute(Constants.PORTAL_KEY, portal); - - setSNMPEnabled(request); - return null; - }
public ActionForward monitorConfigureAlerts(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { @@ -366,4 +341,4 @@ public class PortalAction extends ResourceController { String returnPath = ActionUtils.findReturnPath(mapping, parms); SessionUtils.setReturnPath(request.getSession(), returnPath); } -} \ No newline at end of file +} diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/action/resource/common/monitor/alerts/config/SnmpTrapForm.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/action/resource/common/monitor/alerts/config/SnmpTrapForm.java deleted file mode 100755 index 61b4859..0000000 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/action/resource/common/monitor/alerts/config/SnmpTrapForm.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2008 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.gui.legacy.action.resource.common.monitor.alerts.config; - -import javax.servlet.http.HttpServletRequest; -import org.apache.struts.action.ActionMapping; - -/** - * The Struts form for SnmpActionProps.jsp. - * - * @author Ian Springer - */ -public class SnmpTrapForm extends AddNotificationsForm { - private static final int DEFAULT_PORT = 161; - - private String host; - private Integer port = DEFAULT_PORT; - private String oid; - - public String getHost() { - return host; - } - - public void setHost(String host) { - this.host = host; - } - - public Integer getPort() { - return port; - } - - public void setPort(Integer port) { - this.port = port; - } - - public String getOid() { - return oid; - } - - public void setOid(String oid) { - this.oid = oid; - } - - @Override - public void reset(ActionMapping mapping, HttpServletRequest request) { - host = null; - port = DEFAULT_PORT; - oid = null; - super.reset(mapping, request); - } -} \ No newline at end of file diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/action/resource/common/monitor/alerts/config/SnmpTrapFormAction.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/action/resource/common/monitor/alerts/config/SnmpTrapFormAction.java deleted file mode 100755 index 31e3291..0000000 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/action/resource/common/monitor/alerts/config/SnmpTrapFormAction.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2008 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.gui.legacy.action.resource.common.monitor.alerts.config; - -import java.util.HashMap; -import java.util.Map; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.struts.action.ActionForm; -import org.apache.struts.action.ActionForward; -import org.apache.struts.action.ActionMapping; -import org.jetbrains.annotations.Nullable; - -import org.rhq.core.domain.alert.AlertDefinition; -import org.rhq.core.domain.alert.notification.SnmpNotification; -import org.rhq.core.domain.auth.Subject; -import org.rhq.core.domain.util.PageControl; -import org.rhq.core.domain.util.PageList; -import org.rhq.enterprise.gui.legacy.Constants; -import org.rhq.enterprise.gui.legacy.ParamConstants; -import org.rhq.enterprise.gui.legacy.action.BaseAction; -import org.rhq.enterprise.gui.legacy.action.resource.ResourceForm.FormContext; -import org.rhq.enterprise.gui.legacy.action.resource.common.monitor.alerts.AlertDefUtil; -import org.rhq.enterprise.gui.legacy.util.RequestUtils; -import org.rhq.enterprise.gui.util.WebUtility; -import org.rhq.enterprise.server.alert.AlertNotificationManagerLocal; -import org.rhq.enterprise.server.util.LookupUtil; - -/** - * Process a submitted {@link SnmpTrapForm} (SnmpActionProps.jsp). - * - * @author Ian Springer - */ -public class SnmpTrapFormAction extends BaseAction { - private Log log = LogFactory.getLog(SnmpTrapFormAction.class); - - @Override - public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, - HttpServletResponse response) throws Exception { - SnmpTrapForm snmpTrapForm = (SnmpTrapForm) form; - AlertDefinition alertDefinition = AlertDefUtil.getAlertDefinition(request); - PageControl pageControl = WebUtility.getPageControl(request); - Subject subject = RequestUtils.getSubject(request); - AlertNotificationManagerLocal alertNotificationManager = LookupUtil.getAlertNotificationManager(); - if (snmpTrapForm.isDeleteClicked()) { - SnmpNotification snmpNotification = getExistingSnmpNotification(alertDefinition, pageControl); - if (snmpNotification != null) { - alertNotificationManager.removeNotifications(subject, alertDefinition.getId(), - new Integer[] { snmpNotification.getId() }); - } - } else // SET button clicked - { - SnmpNotification snmpNotification = new SnmpNotification(alertDefinition, snmpTrapForm.getHost(), - snmpTrapForm.getPort(), snmpTrapForm.getOid()); - - // NOTE: We currently only support associating a single SNMP notification with an alert definition, - // so the below manager method will delete any existing SNMP notifs and then add the new one. - alertNotificationManager.setSnmpNotification(subject, alertDefinition.getId(), snmpNotification); - } - - Map<String, Integer> requestParams = createRequestParamsMap(snmpTrapForm); - return returnSuccess(request, mapping, requestParams); - } - - @Nullable - private SnmpNotification getExistingSnmpNotification(AlertDefinition alertDefinition, PageControl pageControl) { - SnmpNotification snmpNotification; - AlertNotificationManagerLocal alertNotificationManager = LookupUtil.getAlertNotificationManager(); - PageList<SnmpNotification> snmpNotifications = alertNotificationManager.getSnmpNotifications(alertDefinition - .getId(), pageControl); - if (!snmpNotifications.isEmpty()) { - if (snmpNotifications.size() > 1) { - log.error("More than one SNMP notification found for alert definition " + alertDefinition - + ", but the GUI currently only supports up to one SNMP notification per alert definition."); - } - - snmpNotification = snmpNotifications.get(0); - } else { - snmpNotification = null; - } - - return snmpNotification; - } - - private Map<String, Integer> createRequestParamsMap(SnmpTrapForm snmpTrapForm) { - Map<String, Integer> params = new HashMap<String, Integer>(); - params.put(Constants.ALERT_DEFINITION_PARAM, snmpTrapForm.getAd()); - - FormContext context = snmpTrapForm.getContext(); - if (context == FormContext.Type) { - params.put(ParamConstants.RESOURCE_TYPE_ID_PARAM, snmpTrapForm.getType()); - } else if (context == FormContext.Resource) { - params.put(ParamConstants.RESOURCE_ID_PARAM, snmpTrapForm.getId()); - } else if (context == FormContext.Group) { - params.put(ParamConstants.GROUP_ID_PARAM, snmpTrapForm.getGroupId()); - } else { - throw new IllegalArgumentException("Unsupported context: " + context); - } - return params; - } -} \ No newline at end of file diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/action/resource/common/monitor/alerts/config/SnmpTrapFormPrepareAction.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/action/resource/common/monitor/alerts/config/SnmpTrapFormPrepareAction.java deleted file mode 100755 index 847dac7..0000000 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/action/resource/common/monitor/alerts/config/SnmpTrapFormPrepareAction.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2008 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.gui.legacy.action.resource.common.monitor.alerts.config; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.struts.action.ActionForm; -import org.apache.struts.action.ActionForward; -import org.apache.struts.action.ActionMapping; -import org.jetbrains.annotations.Nullable; -import org.rhq.core.domain.alert.AlertDefinition; -import org.rhq.core.domain.alert.notification.SnmpNotification; -import org.rhq.core.domain.util.PageControl; -import org.rhq.core.domain.util.PageList; -import org.rhq.enterprise.gui.legacy.action.BaseAction; -import org.rhq.enterprise.gui.legacy.action.resource.common.monitor.alerts.AlertDefUtil; -import org.rhq.enterprise.gui.util.WebUtility; -import org.rhq.enterprise.server.alert.AlertNotificationManagerLocal; -import org.rhq.enterprise.server.util.LookupUtil; - -/** - * Prepare an {@link SnmpTrapForm} (SnmpActionProps.jsp). - * - * @author Ian Springer - */ -public class SnmpTrapFormPrepareAction extends BaseAction { - private Log log = LogFactory.getLog(SnmpTrapFormPrepareAction.class); - - public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, - HttpServletResponse response) throws Exception { - SnmpTrapForm snmpTrapForm = (SnmpTrapForm) form; - AlertDefinition alertDefinition = AlertDefUtil.getAlertDefinition(request); - PageControl pageControl = WebUtility.getPageControl(request); - SnmpNotification snmpNotification = getSnmpNotification(alertDefinition, pageControl); - if (snmpNotification != null) { - snmpTrapForm.setHost(snmpNotification.getHost()); - snmpTrapForm.setPort(snmpNotification.getPort()); - snmpTrapForm.setOid(snmpNotification.getOid()); - } - - return null; - } - - @Nullable - private SnmpNotification getSnmpNotification(AlertDefinition alertDefinition, PageControl pageControl) { - SnmpNotification snmpNotification; - AlertNotificationManagerLocal alertNotificationManager = LookupUtil.getAlertNotificationManager(); - PageList<SnmpNotification> snmpNotifications = alertNotificationManager.getSnmpNotifications(alertDefinition - .getId(), pageControl); - if (!snmpNotifications.isEmpty()) { - if (snmpNotifications.size() > 1) { - log.warn("More than one SNMP notification found for alert definition " + alertDefinition - + ", but the GUI currently only supports up to one SNMP notification per alert definition."); - } - - snmpNotification = snmpNotifications.get(0); - } else { - snmpNotification = null; - } - - return snmpNotification; - } -} \ No newline at end of file diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/struts-config.xml b/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/struts-config.xml index 3ee5e5d..f528afe 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/struts-config.xml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/struts-config.xml @@ -169,9 +169,6 @@ <form-bean name="RemoveNotificationsForm" type="org.rhq.enterprise.gui.legacy.action.resource.common.monitor.alerts.config.RemoveNotificationsForm"/>
- <form-bean name="SnmpTrapForm" - type="org.rhq.enterprise.gui.legacy.action.resource.common.monitor.alerts.config.SnmpTrapForm"/> - <form-bean name="NewAlertDefinitionForm" type="org.rhq.enterprise.gui.legacy.action.resource.common.monitor.alerts.config.DefinitionForm"/>
@@ -2595,14 +2592,6 @@ <set-property property="title" value="View+Alert+Detail"/> </action>
- <action path="/alerts/ViewNotificationsSnmp" - name="SnmpTrapForm" - scope="request" - validate="true" - type="org.rhq.enterprise.gui.legacy.action.resource.common.monitor.alerts.config.SnmpTrapFormPrepareAction"> - <set-property property="title" value="2.2.3.2"/> - </action> - <action path="/alerts/ViewNotificationsRoles" name="RemoveNotificationsForm" scope="request" @@ -2644,15 +2633,6 @@ <forward name="failure" path="/alerts/Config.do?mode=viewUsers" redirect="true"/> </action>
- <action path="/alerts/SetSnmpProps" - type="org.rhq.enterprise.gui.legacy.action.resource.common.monitor.alerts.config.SnmpTrapFormAction" - name="SnmpTrapForm" - scope="request" - input="/alerts/Config.do?mode=viewSnmp"> - <forward name="success" path="/alerts/Config.do?mode=viewSnmp" redirect="true"/> - <forward name="failure" path="/alerts/Config.do?mode=viewSnmp" redirect="true"/> - </action> - <!-- JBNADM-536 update for name and title property--> <action path="/software/ListSoftware" name="RemoveAlertsForm" diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/tiles/events-def.xml b/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/tiles/events-def.xml index 19b7e01..38238f5 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/tiles/events-def.xml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/tiles/events-def.xml @@ -55,44 +55,44 @@ <!-- list is different because of the resource owner stuff --> <definition name=".page.title.events.list.platform" extends=".page.title"> - <put name="linkUrl" + <put name="linkUrl" value="/resource/platform/inventory/PlatformLinks.jsp"/> <put name="titleBgStyle" value="PageTitlePlatformBg"/> <put name="titleImg" value="title_platform.gif"/> </definition> - + <definition name=".page.title.events.list.server" extends=".page.title"> - <put name="linkUrl" + <put name="linkUrl" value="/resource/server/inventory/ServerLinks.jsp"/> <put name="titleBgStyle" value="PageTitleServerBg"/> <put name="titleImg" value="title_server.gif"/> </definition> - + <definition name=".page.title.events.list.service" extends=".page.title"> - <put name="linkUrl" + <put name="linkUrl" value="/resource/service/inventory/ServiceLinks.jsp"/> <put name="titleBgStyle" value="PageTitleServiceBg"/> <put name="titleImg" value="title_service.gif"/> </definition> - + <definition name=".page.title.events.list.application" extends=".page.title"> - <put name="linkUrl" + <put name="linkUrl" value="/resource/application/inventory/ApplicationLinks.jsp"/> <put name="titleBgStyle" value="PageTitleApplicationBg"/> <put name="titleImg" value="title_application.gif"/> </definition> - + <definition name=".page.title.events.list.group" extends=".page.title"> - <put name="linkUrl" + <put name="linkUrl" value="/resource/group/inventory/GroupLinks.jsp"/> <put name="titleBgStyle" value="PageTitleGroupBg"/> <put name="titleImg" value="title_group.gif"/> </definition> - + <!-- view --> <definition name=".events.alert.view.nav" path="/resource/common/monitor/alerts/ViewAlertNavigation.jsp"/> @@ -118,10 +118,6 @@ path="/resource/common/monitor/alerts/ViewAlertNotificationsUsers.jsp" controllerUrl="/alerts/ViewNotificationsUsers.do"/>
- <definition name=".events.alert.view.notifications.snmp" - path="/resource/common/monitor/alerts/ViewAlertNotificationsOthers.jsp" - controllerUrl="/alerts/ViewNotificationsSnmp.do"/> - <definition name=".events.alert.view.controlaction" path="/resource/common/monitor/alerts/config/ViewDefinitionControlAction.jsp" controllerUrl="/alerts/ViewControlAction.do"/> @@ -182,7 +178,7 @@ <definition name=".events.config.conditions.condition.expression" path="/resource/common/monitor/alerts/config/DefinitionConditionExpression.jsp"/>
-<!-- +<!-- <definition name=".events.config.conditions.condition.deletelink" path="/resource/common/monitor/alerts/config/DefinitionConditionDeleteLink.jsp"/>
@@ -232,10 +228,6 @@ path="/resource/common/monitor/alerts/config/ListUsers.jsp" controllerUrl="/alerts/ViewNotificationsUsers.do"/>
- <definition name=".events.config.view.notifications.snmp" - path="/resource/common/monitor/alerts/config/SnmpActionProps.jsp" - controllerUrl="/alerts/ViewNotificationsSnmp.do"/> - <definition name=".events.config.view.controlactionbox" path="/resource/common/monitor/alerts/config/ViewDefinitionControlActionBox.jsp" controllerUrl="/alerts/ViewControlAction.do"/> @@ -257,12 +249,8 @@ <definition name=".events.config.view.roles" path="/resource/common/monitor/alerts/config/ViewDefinition.jsp" controllerUrl="/alerts/ViewDefinition.do"/> - - <definition name=".events.config.view.users" - path="/resource/common/monitor/alerts/config/ViewDefinition.jsp" - controllerUrl="/alerts/ViewDefinition.do"/>
- <definition name=".events.config.view.snmp" + <definition name=".events.config.view.users" path="/resource/common/monitor/alerts/config/ViewDefinition.jsp" controllerUrl="/alerts/ViewDefinition.do"/>
@@ -270,19 +258,19 @@ <definition name=".events.config.list" path="/resource/common/monitor/alerts/config/ListDefinitions.jsp" controllerUrl="/alerts/ListDefinitions.do"/> - + <definition name =".events.config.addusers" controllerUrl="/events/config/AddUsersFormPrepare.do" path="/resource/common/monitor/alerts/config/AddEventUsers.jsp"/> - + <definition name =".events.config.addroles" controllerUrl="/events/config/AddRolesFormPrepare.do" path="/resource/common/monitor/alerts/config/AddEventRoles.jsp"/> - + <definition name =".events.config.addothers" controllerUrl="/events/config/AddOthersFormPrepare.do" path="/resource/common/monitor/alerts/config/AddEventOthers.jsp"/> - + <definition name=".tabs.resource.events" extends=".tabs.resource"> <putList name="tabList"> @@ -318,7 +306,7 @@ <put name="subSectionName" value="Monitor"/> <put name="subSelectedIndex" value="3"/> </definition> - + <definition name=".tabs.resource.events.alerts" extends=".tabs.resource.events"> <put name="selectedIndex" value="0"/> @@ -339,7 +327,7 @@ <put name="subSectionName" value="Monitor"/> <put name="subSelectedIndex" value="2"/> </definition> - + <definition name=".tabs.resource.events.config.nocontrol" extends=".tabs.resource.nocontrol"> <put name="selectedIndex" value="0"/> @@ -360,7 +348,7 @@ <put name="subSectionName" value="Monitor"/> <put name="subSelectedIndex" value="3"/> </definition> - + <definition name=".tabs.resource.events.alerts.nocontrol" extends=".tabs.resource.nocontrol"> <put name="selectedIndex" value="0"/> diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/validation/validation.xml b/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/validation/validation.xml index 3377518..0974d94 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/validation/validation.xml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/validation/validation.xml @@ -212,74 +212,6 @@ <var-value>((*this* != null) or (ldapEnabled == null))</var-value> </var> </field> - - <field property="snmpTrapOID" depends="mask"> - <var> - <var-name>mask</var-name> - <var-value>${oid}</var-value> - </var> - <msg name="mask" - key="admin.settings.error.InvalidSNMPTrapOID"/> - </field> - - <!-- SNMP passhrase fields validated in the form class --> - - <field property="snmpEngineID" depends="mask"> - <var> - <var-name>mask</var-name> - <var-value>${numeric}</var-value> - </var> - <msg name="mask" - key="admin.settings.error.InvalidSNMPEngineID"/> - </field> - - <field property="snmpGenericID" depends="mask"> - <var> - <var-name>mask</var-name> - <var-value>${numeric}</var-value> - </var> - <msg name="mask" - key="admin.settings.error.InvalidSNMPGenericID"/> - </field> - - </form> - - <form name="SnmpTrapForm"> - - <field property="host" depends="required"> - <arg0 key="alert.config.edit.snmp.host"/> - <msg name="required" - key="errors.required"/> - </field> - - <field property="port" depends="intRange"> - <arg0 key="alert.config.edit.snmp.port"/> - <arg1 name="intRange" key="${var:min}" resource="false"/> - <arg2 name="intRange" key="${var:max}" resource="false"/> - <var> - <var-name>min</var-name> - <var-value>1</var-value> - </var> - <var> - <var-name>max</var-name> - <var-value>65535</var-value> - </var> - <msg name="intRange" - key="alert.config.edit.snmp.error.invalidPort"/> - </field> - - <field property="oid" depends="required,mask"> - <arg0 key="alert.config.edit.snmp.oid"/> - <var> - <var-name>mask</var-name> - <var-value>${oid}</var-value> - </var> - <msg name="required" - key="errors.required"/> - <msg name="mask" - key="common.error.invalid.oid"/> - </field> - </form>
<!-- for validating the general properties of an application: diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/admin/config/EditServerConfig.jsp b/modules/enterprise/gui/portal-war/src/main/webapp/admin/config/EditServerConfig.jsp index e2c5478..4ad7b5f 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/admin/config/EditServerConfig.jsp +++ b/modules/enterprise/gui/portal-war/src/main/webapp/admin/config/EditServerConfig.jsp @@ -49,9 +49,6 @@ <tiles:insert page="/admin/config/LDAPForm.jsp"/> <br> <br> -<tiles:insert page="/admin/config/SNMPForm.jsp"/> -<br> -<br> <tiles:insert page="/admin/config/ServerConfigForm.jsp"/>
<%--<tiles:insert page="/admin/config/MiscForm.jsp"/>--%> diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/admin/config/SNMPForm.jsp b/modules/enterprise/gui/portal-war/src/main/webapp/admin/config/SNMPForm.jsp deleted file mode 100644 index e6141c2..0000000 --- a/modules/enterprise/gui/portal-war/src/main/webapp/admin/config/SNMPForm.jsp +++ /dev/null @@ -1,171 +0,0 @@ -<%@ page language="java" %> -<%@ page errorPage="/common/Error.jsp" %> -<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-html-el" prefix="html" %> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-tiles" prefix="tiles" %> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-logic" prefix="logic" %> -<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> - -<!-- SNMP CONFIG PROPERTIES TITLE --> -<tiles:insert definition=".header.tab"> - <tiles:put name="tabKey" value="admin.settings.SNMPConfigPropTab"/> -</tiles:insert> -<!-- / --> - -<script> - function snmpVersionChange(e) { - showSnmpDiv(e.value); - } - - function showSnmpDiv(v) { - var allDiv = document.getElementById('snmpopts'); - var v1Div = document.getElementById('snmpv1opts'); - var v2Div = document.getElementById('snmpv1v2opts'); - var v3Div = document.getElementById('snmpv3opts'); - - if (v == '') { - v1Div.style.display = 'none'; - v2Div.style.display = 'none'; - v3Div.style.display = 'none'; - allDiv.style.display = 'none'; - return; - } - - allDiv.style.display = ''; - - if (v == '3') { - v2Div.style.display = 'none'; - v3Div.style.display = ''; - } - else { - v2Div.style.display = ''; - v3Div.style.display = 'none'; - } - - if (v == '1') { - v1Div.style.display = ''; - } - else { - v1Div.style.display = 'none'; - } - } - - function initSNMPForm() { - var form = document.forms['SystemConfigForm']; - snmpVersionChange(form.snmpVersion); - } -</script> - -<!-- SNMP CONFIG PROPERTIES CONTENTS --> -<table width="100%" cellpadding="0" cellspacing="0" border="0"> - <tr> - <td class="BlockCheckboxLabel" align="left" colspan="4"><fmt:message key="admin.settings.SNMPVersion"/> - <html:select property="snmpVersion" onchange="snmpVersionChange(this)"> - <html:option key="admin.settings.SNMPNone" value=""/> - <html:option value="3"/> - <html:option value="2c"/> - <html:option value="1"/> - </html:select> - </td> - </tr> -</table> - -<div id="snmpopts" style="position: relative;"> -<table width="100%" cellpadding="0" cellspacing="0" border="0"> - <tr> - <td colspan="4" class="BlockBottomLine"><div style="width: 1px; height: 1px;"/></td> - </tr> - <tr> - <td width="20%" class="BlockLabel"><fmt:message key="admin.settings.SNMPTrapOID"/></td> - <td width="30%" class="BlockContent"><html:text size="31" property="snmpTrapOID"/></td> - <td width="20%" class="BlockLabel"> </td> - <td width="30%" class="BlockContent"> </td> - </tr> -</table> -</div> - -<div id="snmpv3opts" style="position: relative;"> -<table width="100%" cellpadding="0" cellspacing="0" border="0"> - <tr> - <td width="20%" class="BlockLabel"><fmt:message key="admin.settings.SNMPAuthProtocol"/></td> - <td width="30%" class="BlockContent"> - <html:select property="snmpAuthProtocol"> - <html:option value="" key="common.label.None"/> - <html:option value="MD5"/> - <html:option value="SHA"/> - </html:select> - </td> - <td width="20%" class="BlockLabel"><fmt:message key="admin.settings.SNMPAuthPassphrase"/></td> - <td width="30%" class="BlockContent"><html:password size="31" property="snmpAuthPassphrase" redisplay="true"/></td> - </tr> - <tr> - <td width="20%" class="BlockLabel"><fmt:message key="admin.settings.SNMPPrivProtocol"/></td> - <td width="30%" class="BlockContent"> - <html:select property="snmpPrivacyProtocol"> - <html:option value="" key="common.label.None"/> - <html:option value="DES"/> - <html:option value="AES"/> - <html:option value="AES192"/> - <html:option value="AES256"/> - </html:select> - </td> - <td width="20%" class="BlockLabel"><fmt:message key="admin.settings.SNMPPrivPassphrase"/></td> - <td width="30%" class="BlockContent"><html:password size="31" property="snmpPrivacyPassphrase" redisplay="true"/></td> - </tr> - <tr> - <td width="20%" class="BlockLabel"><fmt:message key="admin.settings.SNMPContextName"/></td> - <td width="30%" class="BlockContent"><html:text size="31" property="snmpContextName"/></td> - <td width="20%" class="BlockLabel"><fmt:message key="admin.settings.SNMPSecurityName"/></td> - <td width="30%" class="BlockContent"><html:text size="31" property="snmpSecurityName"/></td> - </tr> -</table> -</div> - -<div id="snmpv1v2opts" style="position: relative;"> -<table width="100%" cellpadding="0" cellspacing="0" border="0"> - <tr> - <td width="20%" class="BlockLabel"><fmt:message key="admin.settings.SNMPCommunity"/></td> - <td width="30%" class="BlockContent"><html:text size="31" property="snmpCommunity"/></td> - <td width="20%" class="BlockLabel"> </td> - <td width="30%" class="BlockContent"> </td> - </tr> -</table> -</div> - -<div id="snmpv1opts" style="position: relative;"> -<table width="100%" cellpadding="0" cellspacing="0" border="0"> - <tr> - <td width="20%" class="BlockLabel"><fmt:message key="admin.settings.SNMPEngineID"/></td> - <td width="30%" class="BlockContent"><html:text size="31" property="snmpEngineID"/></td> - <td width="20%" class="BlockLabel"> </td> - <td width="30%" class="BlockContent"> </td> - </tr> - - <tr> - <td width="20%" class="BlockLabel"><fmt:message key="admin.settings.SNMPGenericID"/></td> - <td width="30%" class="BlockContent"><html:text size="31" property="snmpGenericID"/></td> - <td width="20%" class="BlockLabel"><fmt:message key="admin.settings.SNMPSpecificID"/></td> - <td width="30%" class="BlockContent"><html:text size="31" property="snmpSpecificID"/></td> - </tr> - - <tr> - <td width="20%" class="BlockLabel"><fmt:message key="admin.settings.SNMPEnterpriseOID"/></td> - <td width="30%" class="BlockContent"><html:text size="31" property="snmpEnterpriseOID"/></td> - <td width="20%" class="BlockLabel"><fmt:message key="admin.settings.SNMPAgentAddress"/></td> - <td width="30%" class="BlockContent"><html:text size="31" property="snmpAgentAddress"/></td> - </tr> -</table> -</div> - -<table width="100%" cellpadding="0" cellspacing="0" border="0"> - <tr> - <td class="BlockBottomLine"><div style="width: 1px; height: 1px;"/></td> - </tr> -</table> - -<script> -initSNMPForm(); -</script> - - -<!-- / --> diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/resource/common/monitor/alerts/config/SnmpActionProps.jsp b/modules/enterprise/gui/portal-war/src/main/webapp/resource/common/monitor/alerts/config/SnmpActionProps.jsp deleted file mode 100644 index f6c69ac..0000000 --- a/modules/enterprise/gui/portal-war/src/main/webapp/resource/common/monitor/alerts/config/SnmpActionProps.jsp +++ /dev/null @@ -1,34 +0,0 @@ -<%@ page language="java" %> -<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-html-el" prefix="html" %> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-logic" prefix="logic" %> - -<table width="100%" cellpadding="0" cellspacing="0" border="0"> - logic:messagesPresent - <tr> - <td colspan="6" align="left" class="ErrorField">html:errors/</td> - </tr> - </logic:messagesPresent> - <tr> - <td width="10%" class="BlockLabel" nowrap="true"><fmt:message key="alert.config.edit.snmp.host"/>:</td> - <td width="30%" class="BlockContent"><html:text size="40" maxlength="100" property="host"/></td> - <td width="10%" class="BlockLabel"><fmt:message key="alert.config.edit.snmp.port"/>:</td> - <td width="10%" class="BlockContent"><html:text size="30" maxlength="5" property="port"/></td> - <td width="10%" class="BlockLabel"><fmt:message key="alert.config.edit.snmp.oid"/>:</td> - <td width="30%" class="BlockContent"><html:text size="30" maxlength="250" property="oid"/></td> - </tr> - <tr> - <td colspan="6" class="BlockBottomLine"><div style="width: 1px; height: 1px;"/></td> - </tr> -</table> - -<table width="100%" cellpadding="5" cellspacing="0" border="0" class="ToolbarContent"> - <tr> - <td><html:image page="/images/tbb_set.gif" border="0" titleKey="FormButtons.ClickToOk" property="ok"/></td> - <td><html:image page="/images/tbb_remove.gif" border="0" titleKey="FormButtons.ClickToDelete" property="delete"/></td> - <td colspan="4" width="100%"> </td> - </tr> - <tr> - <td colspan="6" class="BlockBottomLine"><div style="width: 1px; height: 1px;"/></td> - </tr> -</table> diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/resource/common/monitor/alerts/config/ViewDefinitionNotifications.jsp b/modules/enterprise/gui/portal-war/src/main/webapp/resource/common/monitor/alerts/config/ViewDefinitionNotifications.jsp index 0f129f4..f38473f 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/resource/common/monitor/alerts/config/ViewDefinitionNotifications.jsp +++ b/modules/enterprise/gui/portal-war/src/main/webapp/resource/common/monitor/alerts/config/ViewDefinitionNotifications.jsp @@ -57,28 +57,10 @@ </c:url>
-<c:url var="viewSnmpUrl" value="/alerts/Config.do"> - <c:param name="mode" value="viewSnmp"/> - <c:choose> - <c:when test="${not empty Resource}"> - <c:param name="id" value="${Resource.id}"/> - </c:when> - <c:when test="${not empty ResourceGroup}"> - <c:param name="groupId" value="${ResourceGroup.id}"/> - </c:when> - <c:otherwise> - <c:param name="type" value="${ResourceType.id}"/> - </c:otherwise> - </c:choose> - <c:param name="ad" value="${alertDef.id}"/> -</c:url> - - <tiles:insert definition=".events.config.view.notifications.tabs"> <tiles:put name="viewRolesUrl" beanName="viewRolesUrl"/> <tiles:put name="viewUsersUrl" beanName="viewUsersUrl"/> <tiles:put name="viewOthersUrl" beanName="viewOthersUrl"/> - <tiles:put name="viewSnmpUrl" beanName="viewSnmpUrl"/> </tiles:insert>
<%-- @@ -109,12 +91,6 @@ <c:set var="addMode" value="addOthers"/> <c:set var="defaultSortColumn" value="0"/> </c:when> -<c:when test="${param.mode == 'viewSnmp'}"> -<% notificationsTile = ".events.config.view.notifications.snmp"; %> -<c:set var="formAction" value="/alerts/SetSnmpProps"/> -<c:set var="selfUrl" value="${viewSnmpUrl}"/> -<c:set var="defaultSortColumn" value="0"/> -</c:when> <c:otherwise> <%-- do nothing --%> </c:otherwise> diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/resource/common/monitor/alerts/config/ViewDefinitionNotificationsTabs.jsp b/modules/enterprise/gui/portal-war/src/main/webapp/resource/common/monitor/alerts/config/ViewDefinitionNotificationsTabs.jsp index 8e375db..9d3f301 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/resource/common/monitor/alerts/config/ViewDefinitionNotificationsTabs.jsp +++ b/modules/enterprise/gui/portal-war/src/main/webapp/resource/common/monitor/alerts/config/ViewDefinitionNotificationsTabs.jsp @@ -8,18 +8,17 @@ <tiles:importAttribute name="viewRolesUrl"/> <tiles:importAttribute name="viewUsersUrl"/> <tiles:importAttribute name="viewOthersUrl"/> -<tiles:importAttribute name="viewSnmpUrl"/>
<!-- MINI-TABS --> <table width="100%" border="0" cellspacing="0" cellpadding="0"> - <tr> + <tr> <td class="MiniTabEmpty"><html:img page="/images/spacer.gif" width="20" height="1" alt="" border="0"/> </td>
<td nowrap> <table width="100%" border="0" cellspacing="0" cellpadding="0"> - <tr> + <tr> <c:choose> <c:when test="${param.mode == 'viewRoles'}"> <td valign="top" width="15"><html:img page="/images/miniTabs_left_on.gif" width="11" height="19" alt="" border="0"/></td> @@ -35,10 +34,10 @@ </tr> </table> </td> - + <td nowrap> <table width="100%" border="0" cellspacing="0" cellpadding="0"> - <tr> + <tr> <c:choose> <c:when test="${param.mode == 'viewUsers'}"> <td valign="top" width="15"><html:img page="/images/miniTabs_left_on.gif" width="11" height="19" alt="" border="0"/></td> @@ -56,10 +55,10 @@ </tr> </table> </td> - + <td nowrap> <table width="100%" border="0" cellspacing="0" cellpadding="0"> - <tr> + <tr> <c:choose> <c:when test="${param.mode == 'viewOthers'}"> <td valign="top" width="15"><html:img page="/images/miniTabs_left_on.gif" width="11" height="19" alt="" border="0"/></td> @@ -79,37 +78,13 @@ </table> </td>
- <c:if test="${snmpEnabled}"> - <td nowrap> - <table width="100%" border="0" cellspacing="0" cellpadding="0"> - <tr> - <c:choose> - <c:when test="${param.mode == 'viewSnmp'}"> - <td valign="top" width="15"><html:img page="/images/miniTabs_left_on.gif" width="11" height="19" alt="" border="0"/></td> - <td class="MiniTabOn" nowrap><fmt:message key="monitoring.events.MiniTabs.SNMP"/></td> - <td valign="top" width="17"><html:img page="/images/miniTabs_right_on.gif" width="11" height="19" alt="" border="0"/></td> - </c:when> - <c:otherwise> - <td valign="top" width="15"><html:img page="/images/miniTabs_left_off.gif" width="11" height="19" alt="" border="0"/></td> - <td class="MiniTabOff" nowrap><html:link - href="${viewSnmpUrl}"><fmt:message - key="monitoring.events.MiniTabs.SNMP"/></html:link> - </td> - <td valign="top" width="17"><html:img page="/images/miniTabs_right_off.gif" width="11" height="19" alt="" border="0"/></td> - </c:otherwise> - </c:choose> - </tr> - </table> - </td> - </c:if> - <td width="100%" class="MiniTabEmpty"><html:img page="/images/spacer.gif" width="1" height="1" alt="" border="0"/> </td> </tr> - - <tr> + + <tr> <td colspan="6" width="100%" class="SubTabCell"><html:img page="/images/spacer.gif" width="1" height="3" alt="" border="0"/> diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/RHQConstants.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/RHQConstants.java index 49ed7ca..5411acc 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/RHQConstants.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/RHQConstants.java @@ -20,7 +20,7 @@ package org.rhq.enterprise.server;
/** * Global constants file to be used for config Properties, as well as any other constant used across subsystems - * + * * NOTE: The defaults for these properties can be found in sysconfig-data.xml in the dbutils module. */ public class RHQConstants { @@ -108,20 +108,4 @@ public class RHQConstants { // Syslog Actions enabled public static final String SyslogActionsEnabled = "CAM_SYSLOG_ACTIONS_ENABLED";
- // SNMP configurations - public static final String SNMPAuthProtocol = "SNMP_AUTH_PROTOCOL"; - public static final String SNMPAuthPassphrase = "SNMP_AUTH_PASSPHRASE"; - public static final String SNMPPrivacyPassphrase = "SNMP_PRIV_PASSPHRASE"; - public static final String SNMPCommunity = "SNMP_COMMUNITY"; - public static final String SNMPEngineID = "SNMP_ENGINE_ID"; - public static final String SNMPContextName = "SNMP_CONTEXT_NAME"; - public static final String SNMPSecurityName = "SNMP_SECURITY_NAME"; - public static final String SNMPTrapOID = "SNMP_TRAP_OID"; - public static final String SNMPEnterpriseOID = "SNMP_ENTERPRISE_OID"; - public static final String SNMPGenericID = "SNMP_GENERIC_ID"; - public static final String SNMPSpecificID = "SNMP_SPECIFIC_ID"; - public static final String SNMPAgentAddress = "SNMP_AGENT_ADDRESS"; - public static final String SNMPVersion = "SNMP_VERSION"; - public static final String SNMPPrivacyProtocol = "SNMP_PRIVACY_PROTOCOL"; - } \ No newline at end of file diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugins/alertSnmp/SnmpTrapSender.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugins/alertSnmp/SnmpTrapSender.java deleted file mode 100644 index 2a52279..0000000 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugins/alertSnmp/SnmpTrapSender.java +++ /dev/null @@ -1,794 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2008 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.plugins.alertSnmp; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; -import java.util.StringTokenizer; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.snmp4j.CommandResponderEvent; -import org.snmp4j.CommunityTarget; -import org.snmp4j.MessageException; -import org.snmp4j.PDU; -import org.snmp4j.PDUv1; -import org.snmp4j.ScopedPDU; -import org.snmp4j.Snmp; -import org.snmp4j.Target; -import org.snmp4j.UserTarget; -import org.snmp4j.event.ResponseEvent; -import org.snmp4j.mp.CounterSupport; -import org.snmp4j.mp.DefaultCounterListener; -import org.snmp4j.mp.MPv3; -import org.snmp4j.mp.SnmpConstants; -import org.snmp4j.mp.StateReference; -import org.snmp4j.mp.StatusInformation; -import org.snmp4j.security.AuthMD5; -import org.snmp4j.security.AuthSHA; -import org.snmp4j.security.PrivAES128; -import org.snmp4j.security.PrivAES192; -import org.snmp4j.security.PrivAES256; -import org.snmp4j.security.PrivDES; -import org.snmp4j.security.SecurityLevel; -import org.snmp4j.security.SecurityModels; -import org.snmp4j.security.SecurityProtocols; -import org.snmp4j.security.USM; -import org.snmp4j.security.UsmUser; -import org.snmp4j.smi.Address; -import org.snmp4j.smi.Integer32; -import org.snmp4j.smi.IpAddress; -import org.snmp4j.smi.Null; -import org.snmp4j.smi.OID; -import org.snmp4j.smi.OctetString; -import org.snmp4j.smi.TcpAddress; -import org.snmp4j.smi.TimeTicks; -import org.snmp4j.smi.UdpAddress; -import org.snmp4j.smi.UnsignedInteger32; -import org.snmp4j.smi.Variable; -import org.snmp4j.smi.VariableBinding; -import org.snmp4j.transport.AbstractTransportMapping; -import org.snmp4j.transport.DefaultTcpTransportMapping; -import org.snmp4j.transport.DefaultUdpTransportMapping; -import org.snmp4j.util.PDUFactory; - -import org.rhq.core.domain.alert.Alert; -import org.rhq.core.domain.configuration.Configuration; - -/** - * @author Ian Springer - */ -public class SnmpTrapSender implements PDUFactory { - public static final int DEFAULT = 0; - private static final String UDP_TRANSPORT = "udp"; - private static final String TCP_TRANSPORT = "tcp"; - - private Log log = LogFactory.getLog(SnmpTrapSender.class); - - private Target target; - - private OID authProtocol; - - private OID privProtocol; - - private OctetString privPassphrase; - - private OctetString authPassphrase; - - private OctetString community = new OctetString("public"); - - private OctetString contextEngineID; - - private OctetString contextName = new OctetString(); - - private OctetString securityName = new OctetString(); - - private TimeTicks sysUpTime = new TimeTicks(0); - - private OID trapOID = SnmpConstants.coldStart; - - private PDUv1 v1TrapPDU = new PDUv1(); - - private int version = SnmpConstants.version3; - - private int retries = 1; - - private int timeout = 1000; - - private int pduType = PDU.TRAP; - - private int maxRepetitions = 10; - - private int nonRepeaters = 0; - - private List<VariableBinding> vbs = new ArrayList<VariableBinding>(); - - private Address address; - - private int operation = DEFAULT; - - private boolean snmpEnabled; - - Configuration systemConfig; - - public SnmpTrapSender(Configuration preferences) { - this.systemConfig = preferences; - this.snmpEnabled = init(); - } - - private void checkTrapVariables(List<VariableBinding> vbs) { - - if ((pduType == PDU.INFORM) || (pduType == PDU.TRAP)) { - if ((vbs.size() == 0) || ((vbs.size() >= 1) && (!(vbs.get(0)).getOid().equals(SnmpConstants.sysUpTime)))) { - vbs.add(0, new VariableBinding(SnmpConstants.sysUpTime, sysUpTime)); - } - - if ((vbs.size() == 1) || ((vbs.size() >= 2) && (!(vbs.get(1)).getOid().equals(SnmpConstants.snmpTrapOID)))) { - vbs.add(1, new VariableBinding(SnmpConstants.snmpTrapOID, trapOID)); - } - } - } - - private void addUsmUser(Snmp snmp) { - snmp.getUSM().addUser(securityName, - new UsmUser(securityName, authProtocol, authPassphrase, privProtocol, privPassphrase)); - } - - private Snmp createSnmpSession() throws IOException { - AbstractTransportMapping transport; - if (address instanceof TcpAddress) { - transport = new DefaultTcpTransportMapping(); - } else { - transport = new DefaultUdpTransportMapping(); - } - - // Could save some CPU cycles: - // transport.setAsyncMsgProcessingSupported(false); - Snmp snmp = new Snmp(transport); - - if (version == SnmpConstants.version3) { - USM usm = new USM(SecurityProtocols.getInstance(), new OctetString(MPv3.createLocalEngineID()), 0); - SecurityModels.getInstance().addSecurityModel(usm); - addUsmUser(snmp); - } - - return snmp; - } - - private Target createTarget() { - if (version == SnmpConstants.version3) { - UserTarget target = new UserTarget(); - if (authPassphrase != null) { - if (privPassphrase != null) { - target.setSecurityLevel(SecurityLevel.AUTH_PRIV); - } else { - target.setSecurityLevel(SecurityLevel.AUTH_NOPRIV); - } - } else { - target.setSecurityLevel(SecurityLevel.NOAUTH_NOPRIV); - } - - target.setSecurityName(securityName); - return target; - } else { - CommunityTarget target = new CommunityTarget(); - target.setCommunity(community); - return target; - } - } - - public PDU send() throws IOException { - Snmp snmp = createSnmpSession(); - this.target = createTarget(); - target.setVersion(version); - target.setAddress(address); - target.setRetries(retries); - target.setTimeout(timeout); - snmp.listen(); - - PDU request = createPDU(target); - if (request.getType() == PDU.GETBULK) { - request.setMaxRepetitions(maxRepetitions); - request.setNonRepeaters(nonRepeaters); - } - - for (Object vb : vbs) { - request.add((VariableBinding) vb); - } - - PDU response = null; - ResponseEvent responseEvent; - long startTime = System.currentTimeMillis(); - responseEvent = snmp.send(request, target); - if (responseEvent != null) { - response = responseEvent.getResponse(); - if (log.isDebugEnabled()) - log.debug("Received response after " + (System.currentTimeMillis() - startTime) + " millis"); - } - - snmp.close(); - return response; - } - - private void getVariableBindings(String args) { - String oid = args; - char type = 'i'; - String value = null; - int equal = oid.indexOf("={"); - if (equal > 0) { - oid = args.substring(0, equal); - type = args.charAt(equal + 2); - value = args.substring(args.indexOf('}') + 1); - } else if (oid.indexOf('-') > 0) { - StringTokenizer st = new StringTokenizer(oid, "-"); - if (st.countTokens() != 2) { - throw new IllegalArgumentException("Illegal OID range specified: '" + oid); - } - - oid = st.nextToken(); - VariableBinding vbLower = new VariableBinding(new OID(oid)); - vbs.add(vbLower); - long last = Long.parseLong(st.nextToken()); - long first = vbLower.getOid().lastUnsigned(); - for (long k = first + 1; k <= last; k++) { - OID nextOID = new OID(vbLower.getOid().getValue(), 0, vbLower.getOid().size() - 1); - nextOID.appendUnsigned(k); - VariableBinding next = new VariableBinding(nextOID); - vbs.add(next); - } - - return; - } - - VariableBinding vb = new VariableBinding(new OID(oid)); - if (value != null) { - Variable variable; - switch (type) { - case 'i': { - variable = new Integer32(Integer.parseInt(value)); - break; - } - - case 'u': { - variable = new UnsignedInteger32(Long.parseLong(value)); - break; - } - - case 's': { - variable = new OctetString(value); - break; - } - - case 'x': { - variable = OctetString.fromString(value, ':', 16); - break; - } - - case 'd': { - variable = OctetString.fromString(value, '.', 10); - break; - } - - case 'b': { - variable = OctetString.fromString(value, ' ', 2); - break; - } - - case 'n': { - variable = new Null(); - break; - } - - case 'o': { - variable = new OID(value); - break; - } - - case 't': { - variable = new TimeTicks(Long.parseLong(value)); - break; - } - - case 'a': { - variable = new IpAddress(value); - break; - } - - default: { - throw new IllegalArgumentException("Variable type " + type + " not supported"); - } - } - - vb.setVariable(variable); - } - - vbs.add(vb); - } - - private static OctetString createOctetString(String s) { - OctetString octetString; - if (s.startsWith("0x")) { - octetString = OctetString.fromHexString(s.substring(2), ':'); - } else { - octetString = new OctetString(s); - } - - return octetString; - } - - private static Address createAddress(Configuration properties) { - // TODO: Make transport configurable (ips, 09/12/07). - - String host = properties.getSimpleValue("host",null); - String portS = properties.getSimpleValue("port","161"); - Integer port = Integer.valueOf(portS); - - final String transport = UDP_TRANSPORT; - String address = host + "/" + port; - if (transport.equalsIgnoreCase(UDP_TRANSPORT)) { - return new UdpAddress(address); - } else if (transport.equalsIgnoreCase(TCP_TRANSPORT)) { - return new TcpAddress(address); - } - - throw new IllegalArgumentException("Unknown transport: " + transport); - } - - protected String getVariableBindings(PDU response) { - StringBuffer strBuf = new StringBuffer(); - for (int i = 0; i < response.size(); i++) { - VariableBinding vb = response.get(i); - strBuf.append(vb.toString()); - } - - return strBuf.toString(); - } - - protected String getReport(PDU response) { - if (response.size() < 1) { - return "REPORT PDU does not contain a variable binding."; - } - - VariableBinding vb = response.get(0); - OID oid = vb.getOid(); - log.debug(" Current counter value is " + vb.getVariable() + "."); - - if (SnmpConstants.usmStatsUnsupportedSecLevels.equals(oid)) { - return "REPORT: Unsupported Security Level."; - } else if (SnmpConstants.usmStatsNotInTimeWindows.equals(oid)) { - return "REPORT: Message not within time window."; - } else if (SnmpConstants.usmStatsUnknownUserNames.equals(oid)) { - return "REPORT: Unknown user name."; - } else if (SnmpConstants.usmStatsUnknownEngineIDs.equals(oid)) { - return "REPORT: Unknown engine id."; - } else if (SnmpConstants.usmStatsWrongDigests.equals(oid)) { - return "REPORT: Wrong digest."; - } else if (SnmpConstants.usmStatsDecryptionErrors.equals(oid)) { - return "REPORT: Decryption error."; - } else if (SnmpConstants.snmpUnknownSecurityModels.equals(oid)) { - return "REPORT: Unknown security model."; - } else if (SnmpConstants.snmpInvalidMsgs.equals(oid)) { - return "REPORT: Invalid message."; - } else if (SnmpConstants.snmpUnknownPDUHandlers.equals(oid)) { - return "REPORT: Unknown PDU handler."; - } else if (SnmpConstants.snmpUnavailableContexts.equals(oid)) { - return "REPORT: Unavailable context."; - } else if (SnmpConstants.snmpUnknownContexts.equals(oid)) { - return "REPORT: Unknown context."; - } else { - return "REPORT contains unknown OID (" + oid.toString() + ")."; - } - } - - /** - * processPdu - * - * @param e CommandResponderEvent - */ - public synchronized void processPdu(CommandResponderEvent e) { - PDU command = e.getPDU(); - if (command != null) { - if (log.isDebugEnabled()) - log.debug(command.toString()); - if ((command.getType() != PDU.TRAP) && (command.getType() != PDU.V1TRAP) - && (command.getType() != PDU.REPORT) && (command.getType() != PDU.RESPONSE)) { - command.setErrorIndex(0); - command.setErrorStatus(0); - command.setType(PDU.RESPONSE); - StatusInformation statusInformation = new StatusInformation(); - StateReference ref = e.getStateReference(); - try { - e.getMessageDispatcher().returnResponsePdu(e.getMessageProcessingModel(), e.getSecurityModel(), - e.getSecurityName(), e.getSecurityLevel(), command, e.getMaxSizeResponsePDU(), ref, - statusInformation); - } catch (MessageException ex) { - log.error("Error while sending response: " + ex.getMessage()); - } - } - } - } - - public PDU createPDU(Target target) { - PDU request; - if (target.getVersion() == SnmpConstants.version3) { - request = new ScopedPDU(); - ScopedPDU scopedPDU = (ScopedPDU) request; - if (contextEngineID != null) { - scopedPDU.setContextEngineID(contextEngineID); - } - - if (contextName != null) { - scopedPDU.setContextName(contextName); - } - } else { - if (pduType == PDU.V1TRAP) { - v1TrapPDU.setTimestamp(sysUpTime.toLong()); - request = v1TrapPDU; - } else { - request = new PDU(); - } - } - - request.setType(pduType); - return request; - } - - /** - * This method sends the actual trap - * @param alert The alert to send - * @param alertParameters the notification data (target agent) - * @param platformName the name of the platform the alert is on - * @param conditions a string that shows the alert conditions - * @param bootTime TODO - * @param alertUrl TODO - * @return 'Error code' of the operation - */ - public String sendSnmpTrap(Alert alert, Configuration alertParameters, String platformName, String conditions, - Date bootTime, String alertUrl) { - if (!this.snmpEnabled) { - return "SNMP is not enabled."; - } - - String baseOid = alertParameters.getSimpleValue("OID",null); - - // TODO add a request id and a timestamp - - this.address = createAddress(alertParameters); - // bind the alert definitions name on the oid set in the alert - getVariableBindings(baseOid + ".1" + "={s}" + alert.getAlertDefinition().getName()); - // the resource the alert was defined on - getVariableBindings(baseOid + ".2" + "={s}" + alert.getAlertDefinition().getResource().getName()); - // the platform this resource is on - getVariableBindings(baseOid + ".3" + "={s}" + platformName); - // the conditions of this alert - getVariableBindings(baseOid + ".4" + "={s}" + conditions); - // severity of the alert - getVariableBindings(baseOid + ".5" + "={s}" + alert.getAlertDefinition().getPriority().toString().toLowerCase()); - // url of the alert detail - getVariableBindings(baseOid + ".6" + "={s}" + alertUrl); - - setSysUpTimeFromBootTime(bootTime); // needs to be called before checkTrapVariables(); - checkTrapVariables(this.vbs); - try { - PDU response = send(); - if ((getPduType() == PDU.TRAP) || (getPduType() == PDU.V1TRAP)) { - return (PDU.getTypeString(getPduType()) + " sent successfully"); - } else if (response == null) { - return ("Request timed out."); - } else if (response.getType() == PDU.REPORT) { - return getReport(response); - } else if (this.operation == DEFAULT) { - return "Response received with requestID=" + response.getRequestID() + ", errorIndex=" - + response.getErrorIndex() + ", " + "errorStatus=" + response.getErrorStatusText() + "(" - + response.getErrorStatus() + ")" + "\n" + getVariableBindings(response); - } else { - return "Received something strange: requestID=" + response.getRequestID() + ", errorIndex=" - + response.getErrorIndex() + ", " + "errorStatus=" + response.getErrorStatusText() + "(" - + response.getErrorStatus() + ")" + "\n" + getVariableBindings(response); - } - } catch (IOException ex) { - log.error(ex.getMessage()); - return "Error while trying to send request: " + ex.getMessage(); - } catch (IllegalArgumentException ex) { - log.error(ex.getMessage()); - return "SNMPAction configured incorrectly: " + ex.getMessage(); - } - } - - /** - * Calculate the time diff between system boot time and now and - * set the uptime variable from it. - * @param bootTime - */ - private void setSysUpTimeFromBootTime(Date bootTime) { - long now = System.currentTimeMillis(); - long delta; - if (bootTime != null) { - delta = now - bootTime.getTime(); - } else - delta = 0; - setSysUpTime(new TimeTicks(delta / 1000)); // TT is 100th of a second TODO : fix this !!! - - } - - private boolean init() { - - String snmpVersion = systemConfig.getSimpleValue("snmpVersion",null); - if ((snmpVersion != null) && (snmpVersion.length() > 0)) { - if (snmpVersion.equals("1")) { - this.version = SnmpConstants.version1; - this.pduType = PDU.V1TRAP; - } else if (snmpVersion.equals("2c")) { - this.version = SnmpConstants.version2c; - } else if (snmpVersion.equals("3")) { - this.version = SnmpConstants.version3; - } else { - throw new IllegalStateException("SNMP version " + snmpVersion + " is not supported."); - } - } else { - return false; - } - - if ((this.pduType == PDU.V1TRAP) && (this.version != SnmpConstants.version1)) { - throw new IllegalStateException("V1TRAP PDU type is only available for SNMP version 1"); - } - - String tmp = systemConfig.getSimpleValue("authProtocol","MD5"); - if ((tmp != null) && (tmp.length() > 0)) { - if (tmp.equals("MD5")) { - this.authProtocol = AuthMD5.ID; - } else if (tmp.equals("SHA")) { - this.authProtocol = AuthSHA.ID; - } else { - throw new IllegalStateException("SNMP authentication protocol unsupported: " + tmp); - } - } - - tmp = systemConfig.getSimpleValue("authPassphrase",null); - if ((tmp != null) && (tmp.length() > 0)) { - this.authPassphrase = createOctetString(tmp); - } - - tmp = systemConfig.getSimpleValue("privacyPassphrase",null); - if ((tmp != null) && (tmp.length() > 0)) { - this.privPassphrase = createOctetString(tmp); - } - - tmp = systemConfig.getSimpleValue("community",null); - if ((tmp != null) && (tmp.length() > 0)) { - this.community = createOctetString(tmp); - } - - tmp = systemConfig.getSimpleValue("engineId",null); - if ((tmp != null) && (tmp.length() > 0)) { - this.contextEngineID = createOctetString(tmp); - } - - tmp = systemConfig.getSimpleValue("targetContext",null); - if ((tmp != null) && (tmp.length() > 0)) { - this.contextName = createOctetString(tmp); - } - - tmp = systemConfig.getSimpleValue("securityName",null); - if ((tmp != null) && (tmp.length() > 0)) { - this.securityName = createOctetString(tmp); - } - - tmp = systemConfig.getSimpleValue("trapOid",null); - if ((tmp != null) && (tmp.length() > 0)) { - this.trapOID = new OID(tmp); - } - - tmp = systemConfig.getSimpleValue("enterpriseOid",null); - if ((tmp != null) && (tmp.length() > 0)) { - this.v1TrapPDU.setEnterprise(new OID(tmp)); - } - - tmp = systemConfig.getSimpleValue("genericId",null); - if ((tmp != null) && (tmp.length() > 0)) { - this.v1TrapPDU.setGenericTrap(Integer.parseInt(tmp)); - } - - tmp = systemConfig.getSimpleValue("specificId",null); - if ((tmp != null) && (tmp.length() > 0)) { - this.v1TrapPDU.setSpecificTrap(Integer.parseInt(tmp)); - } - - tmp = systemConfig.getSimpleValue("agentAddress",null); - if ((tmp != null) && (tmp.length() > 0)) { - this.v1TrapPDU.setAgentAddress(new IpAddress(tmp)); - } - - tmp = systemConfig.getSimpleValue("privacyProtocol","AES"); - if ((tmp != null) && (tmp.length() > 0)) { - if (tmp.equals("DES")) { - this.privProtocol = PrivDES.ID; - } else if ((tmp.equals("AES128")) || (tmp.equals("AES"))) { - this.privProtocol = PrivAES128.ID; - } else if (tmp.equals("AES192")) { - this.privProtocol = PrivAES192.ID; - } else if (tmp.equals("AES256")) { - this.privProtocol = PrivAES256.ID; - } else { - throw new IllegalArgumentException("Privacy protocol " + tmp + " not supported"); - } - } - - // Set the default counter listener to return proper USM and MP error counters. - CounterSupport.getInstance().addCounterListener(new DefaultCounterListener()); - - return true; - } - - /*=== Getters and Setters ==============================================*/ - - public OctetString getAuthPassphrase() { - return authPassphrase; - } - - public void setAuthPassphrase(OctetString authPassphrase) { - this.authPassphrase = authPassphrase; - } - - public OID getAuthProtocol() { - return authProtocol; - } - - public void setAuthProtocol(OID authProtocol) { - this.authProtocol = authProtocol; - } - - public OctetString getCommunity() { - return community; - } - - public void setCommunity(OctetString community) { - this.community = community; - } - - public OctetString getContextEngineID() { - return contextEngineID; - } - - public void setContextEngineID(OctetString contextEngineID) { - this.contextEngineID = contextEngineID; - } - - public void setContextName(OctetString contextName) { - this.contextName = contextName; - } - - public OctetString getContextName() { - return contextName; - } - - public int getMaxRepetitions() { - return maxRepetitions; - } - - public void setMaxRepetitions(int maxRepetitions) { - this.maxRepetitions = maxRepetitions; - } - - public int getNonRepeaters() { - return nonRepeaters; - } - - public void setNonRepeaters(int nonRepeaters) { - this.nonRepeaters = nonRepeaters; - } - - public int getOperation() { - return operation; - } - - public void setOperation(int operation) { - this.operation = operation; - } - - public OctetString getPrivPassphrase() { - return privPassphrase; - } - - public void setPrivPassphrase(OctetString privPassphrase) { - this.privPassphrase = privPassphrase; - } - - public OID getPrivProtocol() { - return privProtocol; - } - - public void setPrivProtocol(OID privProtocol) { - this.privProtocol = privProtocol; - } - - public int getRetries() { - return retries; - } - - public void setRetries(int retries) { - this.retries = retries; - } - - public OctetString getSecurityName() { - return securityName; - } - - public void setSecurityName(OctetString securityName) { - this.securityName = securityName; - } - - public TimeTicks getSysUpTime() { - return sysUpTime; - } - - public void setSysUpTime(TimeTicks sysUpTime) { - this.sysUpTime = sysUpTime; - } - - public Target getTarget() { - return target; - } - - public void setTarget(Target target) { - this.target = target; - } - - public int getTimeout() { - return timeout; - } - - public void setTimeout(int timeout) { - this.timeout = timeout; - } - - public OID getTrapOID() { - return trapOID; - } - - public void setTrapOID(OID trapOID) { - this.trapOID = trapOID; - } - - public List getVbs() { - return vbs; - } - - public void setVbs(ArrayList vbs) { - this.vbs = vbs; - } - - public int getVersion() { - return version; - } - - public void setVersion(int version) { - this.version = version; - } - - public int getPduType() { - return pduType; - } - - public void setPduType(int pduType) { - this.pduType = pduType; - } -} \ No newline at end of file diff --git a/modules/enterprise/server/plugins/alert-snmp/src/main/java/org/rhq/enterprise/server/plugins/alertSnmp/SnmpTrapSender.java b/modules/enterprise/server/plugins/alert-snmp/src/main/java/org/rhq/enterprise/server/plugins/alertSnmp/SnmpTrapSender.java new file mode 100644 index 0000000..2a52279 --- /dev/null +++ b/modules/enterprise/server/plugins/alert-snmp/src/main/java/org/rhq/enterprise/server/plugins/alertSnmp/SnmpTrapSender.java @@ -0,0 +1,794 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2008 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.plugins.alertSnmp; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.StringTokenizer; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.snmp4j.CommandResponderEvent; +import org.snmp4j.CommunityTarget; +import org.snmp4j.MessageException; +import org.snmp4j.PDU; +import org.snmp4j.PDUv1; +import org.snmp4j.ScopedPDU; +import org.snmp4j.Snmp; +import org.snmp4j.Target; +import org.snmp4j.UserTarget; +import org.snmp4j.event.ResponseEvent; +import org.snmp4j.mp.CounterSupport; +import org.snmp4j.mp.DefaultCounterListener; +import org.snmp4j.mp.MPv3; +import org.snmp4j.mp.SnmpConstants; +import org.snmp4j.mp.StateReference; +import org.snmp4j.mp.StatusInformation; +import org.snmp4j.security.AuthMD5; +import org.snmp4j.security.AuthSHA; +import org.snmp4j.security.PrivAES128; +import org.snmp4j.security.PrivAES192; +import org.snmp4j.security.PrivAES256; +import org.snmp4j.security.PrivDES; +import org.snmp4j.security.SecurityLevel; +import org.snmp4j.security.SecurityModels; +import org.snmp4j.security.SecurityProtocols; +import org.snmp4j.security.USM; +import org.snmp4j.security.UsmUser; +import org.snmp4j.smi.Address; +import org.snmp4j.smi.Integer32; +import org.snmp4j.smi.IpAddress; +import org.snmp4j.smi.Null; +import org.snmp4j.smi.OID; +import org.snmp4j.smi.OctetString; +import org.snmp4j.smi.TcpAddress; +import org.snmp4j.smi.TimeTicks; +import org.snmp4j.smi.UdpAddress; +import org.snmp4j.smi.UnsignedInteger32; +import org.snmp4j.smi.Variable; +import org.snmp4j.smi.VariableBinding; +import org.snmp4j.transport.AbstractTransportMapping; +import org.snmp4j.transport.DefaultTcpTransportMapping; +import org.snmp4j.transport.DefaultUdpTransportMapping; +import org.snmp4j.util.PDUFactory; + +import org.rhq.core.domain.alert.Alert; +import org.rhq.core.domain.configuration.Configuration; + +/** + * @author Ian Springer + */ +public class SnmpTrapSender implements PDUFactory { + public static final int DEFAULT = 0; + private static final String UDP_TRANSPORT = "udp"; + private static final String TCP_TRANSPORT = "tcp"; + + private Log log = LogFactory.getLog(SnmpTrapSender.class); + + private Target target; + + private OID authProtocol; + + private OID privProtocol; + + private OctetString privPassphrase; + + private OctetString authPassphrase; + + private OctetString community = new OctetString("public"); + + private OctetString contextEngineID; + + private OctetString contextName = new OctetString(); + + private OctetString securityName = new OctetString(); + + private TimeTicks sysUpTime = new TimeTicks(0); + + private OID trapOID = SnmpConstants.coldStart; + + private PDUv1 v1TrapPDU = new PDUv1(); + + private int version = SnmpConstants.version3; + + private int retries = 1; + + private int timeout = 1000; + + private int pduType = PDU.TRAP; + + private int maxRepetitions = 10; + + private int nonRepeaters = 0; + + private List<VariableBinding> vbs = new ArrayList<VariableBinding>(); + + private Address address; + + private int operation = DEFAULT; + + private boolean snmpEnabled; + + Configuration systemConfig; + + public SnmpTrapSender(Configuration preferences) { + this.systemConfig = preferences; + this.snmpEnabled = init(); + } + + private void checkTrapVariables(List<VariableBinding> vbs) { + + if ((pduType == PDU.INFORM) || (pduType == PDU.TRAP)) { + if ((vbs.size() == 0) || ((vbs.size() >= 1) && (!(vbs.get(0)).getOid().equals(SnmpConstants.sysUpTime)))) { + vbs.add(0, new VariableBinding(SnmpConstants.sysUpTime, sysUpTime)); + } + + if ((vbs.size() == 1) || ((vbs.size() >= 2) && (!(vbs.get(1)).getOid().equals(SnmpConstants.snmpTrapOID)))) { + vbs.add(1, new VariableBinding(SnmpConstants.snmpTrapOID, trapOID)); + } + } + } + + private void addUsmUser(Snmp snmp) { + snmp.getUSM().addUser(securityName, + new UsmUser(securityName, authProtocol, authPassphrase, privProtocol, privPassphrase)); + } + + private Snmp createSnmpSession() throws IOException { + AbstractTransportMapping transport; + if (address instanceof TcpAddress) { + transport = new DefaultTcpTransportMapping(); + } else { + transport = new DefaultUdpTransportMapping(); + } + + // Could save some CPU cycles: + // transport.setAsyncMsgProcessingSupported(false); + Snmp snmp = new Snmp(transport); + + if (version == SnmpConstants.version3) { + USM usm = new USM(SecurityProtocols.getInstance(), new OctetString(MPv3.createLocalEngineID()), 0); + SecurityModels.getInstance().addSecurityModel(usm); + addUsmUser(snmp); + } + + return snmp; + } + + private Target createTarget() { + if (version == SnmpConstants.version3) { + UserTarget target = new UserTarget(); + if (authPassphrase != null) { + if (privPassphrase != null) { + target.setSecurityLevel(SecurityLevel.AUTH_PRIV); + } else { + target.setSecurityLevel(SecurityLevel.AUTH_NOPRIV); + } + } else { + target.setSecurityLevel(SecurityLevel.NOAUTH_NOPRIV); + } + + target.setSecurityName(securityName); + return target; + } else { + CommunityTarget target = new CommunityTarget(); + target.setCommunity(community); + return target; + } + } + + public PDU send() throws IOException { + Snmp snmp = createSnmpSession(); + this.target = createTarget(); + target.setVersion(version); + target.setAddress(address); + target.setRetries(retries); + target.setTimeout(timeout); + snmp.listen(); + + PDU request = createPDU(target); + if (request.getType() == PDU.GETBULK) { + request.setMaxRepetitions(maxRepetitions); + request.setNonRepeaters(nonRepeaters); + } + + for (Object vb : vbs) { + request.add((VariableBinding) vb); + } + + PDU response = null; + ResponseEvent responseEvent; + long startTime = System.currentTimeMillis(); + responseEvent = snmp.send(request, target); + if (responseEvent != null) { + response = responseEvent.getResponse(); + if (log.isDebugEnabled()) + log.debug("Received response after " + (System.currentTimeMillis() - startTime) + " millis"); + } + + snmp.close(); + return response; + } + + private void getVariableBindings(String args) { + String oid = args; + char type = 'i'; + String value = null; + int equal = oid.indexOf("={"); + if (equal > 0) { + oid = args.substring(0, equal); + type = args.charAt(equal + 2); + value = args.substring(args.indexOf('}') + 1); + } else if (oid.indexOf('-') > 0) { + StringTokenizer st = new StringTokenizer(oid, "-"); + if (st.countTokens() != 2) { + throw new IllegalArgumentException("Illegal OID range specified: '" + oid); + } + + oid = st.nextToken(); + VariableBinding vbLower = new VariableBinding(new OID(oid)); + vbs.add(vbLower); + long last = Long.parseLong(st.nextToken()); + long first = vbLower.getOid().lastUnsigned(); + for (long k = first + 1; k <= last; k++) { + OID nextOID = new OID(vbLower.getOid().getValue(), 0, vbLower.getOid().size() - 1); + nextOID.appendUnsigned(k); + VariableBinding next = new VariableBinding(nextOID); + vbs.add(next); + } + + return; + } + + VariableBinding vb = new VariableBinding(new OID(oid)); + if (value != null) { + Variable variable; + switch (type) { + case 'i': { + variable = new Integer32(Integer.parseInt(value)); + break; + } + + case 'u': { + variable = new UnsignedInteger32(Long.parseLong(value)); + break; + } + + case 's': { + variable = new OctetString(value); + break; + } + + case 'x': { + variable = OctetString.fromString(value, ':', 16); + break; + } + + case 'd': { + variable = OctetString.fromString(value, '.', 10); + break; + } + + case 'b': { + variable = OctetString.fromString(value, ' ', 2); + break; + } + + case 'n': { + variable = new Null(); + break; + } + + case 'o': { + variable = new OID(value); + break; + } + + case 't': { + variable = new TimeTicks(Long.parseLong(value)); + break; + } + + case 'a': { + variable = new IpAddress(value); + break; + } + + default: { + throw new IllegalArgumentException("Variable type " + type + " not supported"); + } + } + + vb.setVariable(variable); + } + + vbs.add(vb); + } + + private static OctetString createOctetString(String s) { + OctetString octetString; + if (s.startsWith("0x")) { + octetString = OctetString.fromHexString(s.substring(2), ':'); + } else { + octetString = new OctetString(s); + } + + return octetString; + } + + private static Address createAddress(Configuration properties) { + // TODO: Make transport configurable (ips, 09/12/07). + + String host = properties.getSimpleValue("host",null); + String portS = properties.getSimpleValue("port","161"); + Integer port = Integer.valueOf(portS); + + final String transport = UDP_TRANSPORT; + String address = host + "/" + port; + if (transport.equalsIgnoreCase(UDP_TRANSPORT)) { + return new UdpAddress(address); + } else if (transport.equalsIgnoreCase(TCP_TRANSPORT)) { + return new TcpAddress(address); + } + + throw new IllegalArgumentException("Unknown transport: " + transport); + } + + protected String getVariableBindings(PDU response) { + StringBuffer strBuf = new StringBuffer(); + for (int i = 0; i < response.size(); i++) { + VariableBinding vb = response.get(i); + strBuf.append(vb.toString()); + } + + return strBuf.toString(); + } + + protected String getReport(PDU response) { + if (response.size() < 1) { + return "REPORT PDU does not contain a variable binding."; + } + + VariableBinding vb = response.get(0); + OID oid = vb.getOid(); + log.debug(" Current counter value is " + vb.getVariable() + "."); + + if (SnmpConstants.usmStatsUnsupportedSecLevels.equals(oid)) { + return "REPORT: Unsupported Security Level."; + } else if (SnmpConstants.usmStatsNotInTimeWindows.equals(oid)) { + return "REPORT: Message not within time window."; + } else if (SnmpConstants.usmStatsUnknownUserNames.equals(oid)) { + return "REPORT: Unknown user name."; + } else if (SnmpConstants.usmStatsUnknownEngineIDs.equals(oid)) { + return "REPORT: Unknown engine id."; + } else if (SnmpConstants.usmStatsWrongDigests.equals(oid)) { + return "REPORT: Wrong digest."; + } else if (SnmpConstants.usmStatsDecryptionErrors.equals(oid)) { + return "REPORT: Decryption error."; + } else if (SnmpConstants.snmpUnknownSecurityModels.equals(oid)) { + return "REPORT: Unknown security model."; + } else if (SnmpConstants.snmpInvalidMsgs.equals(oid)) { + return "REPORT: Invalid message."; + } else if (SnmpConstants.snmpUnknownPDUHandlers.equals(oid)) { + return "REPORT: Unknown PDU handler."; + } else if (SnmpConstants.snmpUnavailableContexts.equals(oid)) { + return "REPORT: Unavailable context."; + } else if (SnmpConstants.snmpUnknownContexts.equals(oid)) { + return "REPORT: Unknown context."; + } else { + return "REPORT contains unknown OID (" + oid.toString() + ")."; + } + } + + /** + * processPdu + * + * @param e CommandResponderEvent + */ + public synchronized void processPdu(CommandResponderEvent e) { + PDU command = e.getPDU(); + if (command != null) { + if (log.isDebugEnabled()) + log.debug(command.toString()); + if ((command.getType() != PDU.TRAP) && (command.getType() != PDU.V1TRAP) + && (command.getType() != PDU.REPORT) && (command.getType() != PDU.RESPONSE)) { + command.setErrorIndex(0); + command.setErrorStatus(0); + command.setType(PDU.RESPONSE); + StatusInformation statusInformation = new StatusInformation(); + StateReference ref = e.getStateReference(); + try { + e.getMessageDispatcher().returnResponsePdu(e.getMessageProcessingModel(), e.getSecurityModel(), + e.getSecurityName(), e.getSecurityLevel(), command, e.getMaxSizeResponsePDU(), ref, + statusInformation); + } catch (MessageException ex) { + log.error("Error while sending response: " + ex.getMessage()); + } + } + } + } + + public PDU createPDU(Target target) { + PDU request; + if (target.getVersion() == SnmpConstants.version3) { + request = new ScopedPDU(); + ScopedPDU scopedPDU = (ScopedPDU) request; + if (contextEngineID != null) { + scopedPDU.setContextEngineID(contextEngineID); + } + + if (contextName != null) { + scopedPDU.setContextName(contextName); + } + } else { + if (pduType == PDU.V1TRAP) { + v1TrapPDU.setTimestamp(sysUpTime.toLong()); + request = v1TrapPDU; + } else { + request = new PDU(); + } + } + + request.setType(pduType); + return request; + } + + /** + * This method sends the actual trap + * @param alert The alert to send + * @param alertParameters the notification data (target agent) + * @param platformName the name of the platform the alert is on + * @param conditions a string that shows the alert conditions + * @param bootTime TODO + * @param alertUrl TODO + * @return 'Error code' of the operation + */ + public String sendSnmpTrap(Alert alert, Configuration alertParameters, String platformName, String conditions, + Date bootTime, String alertUrl) { + if (!this.snmpEnabled) { + return "SNMP is not enabled."; + } + + String baseOid = alertParameters.getSimpleValue("OID",null); + + // TODO add a request id and a timestamp + + this.address = createAddress(alertParameters); + // bind the alert definitions name on the oid set in the alert + getVariableBindings(baseOid + ".1" + "={s}" + alert.getAlertDefinition().getName()); + // the resource the alert was defined on + getVariableBindings(baseOid + ".2" + "={s}" + alert.getAlertDefinition().getResource().getName()); + // the platform this resource is on + getVariableBindings(baseOid + ".3" + "={s}" + platformName); + // the conditions of this alert + getVariableBindings(baseOid + ".4" + "={s}" + conditions); + // severity of the alert + getVariableBindings(baseOid + ".5" + "={s}" + alert.getAlertDefinition().getPriority().toString().toLowerCase()); + // url of the alert detail + getVariableBindings(baseOid + ".6" + "={s}" + alertUrl); + + setSysUpTimeFromBootTime(bootTime); // needs to be called before checkTrapVariables(); + checkTrapVariables(this.vbs); + try { + PDU response = send(); + if ((getPduType() == PDU.TRAP) || (getPduType() == PDU.V1TRAP)) { + return (PDU.getTypeString(getPduType()) + " sent successfully"); + } else if (response == null) { + return ("Request timed out."); + } else if (response.getType() == PDU.REPORT) { + return getReport(response); + } else if (this.operation == DEFAULT) { + return "Response received with requestID=" + response.getRequestID() + ", errorIndex=" + + response.getErrorIndex() + ", " + "errorStatus=" + response.getErrorStatusText() + "(" + + response.getErrorStatus() + ")" + "\n" + getVariableBindings(response); + } else { + return "Received something strange: requestID=" + response.getRequestID() + ", errorIndex=" + + response.getErrorIndex() + ", " + "errorStatus=" + response.getErrorStatusText() + "(" + + response.getErrorStatus() + ")" + "\n" + getVariableBindings(response); + } + } catch (IOException ex) { + log.error(ex.getMessage()); + return "Error while trying to send request: " + ex.getMessage(); + } catch (IllegalArgumentException ex) { + log.error(ex.getMessage()); + return "SNMPAction configured incorrectly: " + ex.getMessage(); + } + } + + /** + * Calculate the time diff between system boot time and now and + * set the uptime variable from it. + * @param bootTime + */ + private void setSysUpTimeFromBootTime(Date bootTime) { + long now = System.currentTimeMillis(); + long delta; + if (bootTime != null) { + delta = now - bootTime.getTime(); + } else + delta = 0; + setSysUpTime(new TimeTicks(delta / 1000)); // TT is 100th of a second TODO : fix this !!! + + } + + private boolean init() { + + String snmpVersion = systemConfig.getSimpleValue("snmpVersion",null); + if ((snmpVersion != null) && (snmpVersion.length() > 0)) { + if (snmpVersion.equals("1")) { + this.version = SnmpConstants.version1; + this.pduType = PDU.V1TRAP; + } else if (snmpVersion.equals("2c")) { + this.version = SnmpConstants.version2c; + } else if (snmpVersion.equals("3")) { + this.version = SnmpConstants.version3; + } else { + throw new IllegalStateException("SNMP version " + snmpVersion + " is not supported."); + } + } else { + return false; + } + + if ((this.pduType == PDU.V1TRAP) && (this.version != SnmpConstants.version1)) { + throw new IllegalStateException("V1TRAP PDU type is only available for SNMP version 1"); + } + + String tmp = systemConfig.getSimpleValue("authProtocol","MD5"); + if ((tmp != null) && (tmp.length() > 0)) { + if (tmp.equals("MD5")) { + this.authProtocol = AuthMD5.ID; + } else if (tmp.equals("SHA")) { + this.authProtocol = AuthSHA.ID; + } else { + throw new IllegalStateException("SNMP authentication protocol unsupported: " + tmp); + } + } + + tmp = systemConfig.getSimpleValue("authPassphrase",null); + if ((tmp != null) && (tmp.length() > 0)) { + this.authPassphrase = createOctetString(tmp); + } + + tmp = systemConfig.getSimpleValue("privacyPassphrase",null); + if ((tmp != null) && (tmp.length() > 0)) { + this.privPassphrase = createOctetString(tmp); + } + + tmp = systemConfig.getSimpleValue("community",null); + if ((tmp != null) && (tmp.length() > 0)) { + this.community = createOctetString(tmp); + } + + tmp = systemConfig.getSimpleValue("engineId",null); + if ((tmp != null) && (tmp.length() > 0)) { + this.contextEngineID = createOctetString(tmp); + } + + tmp = systemConfig.getSimpleValue("targetContext",null); + if ((tmp != null) && (tmp.length() > 0)) { + this.contextName = createOctetString(tmp); + } + + tmp = systemConfig.getSimpleValue("securityName",null); + if ((tmp != null) && (tmp.length() > 0)) { + this.securityName = createOctetString(tmp); + } + + tmp = systemConfig.getSimpleValue("trapOid",null); + if ((tmp != null) && (tmp.length() > 0)) { + this.trapOID = new OID(tmp); + } + + tmp = systemConfig.getSimpleValue("enterpriseOid",null); + if ((tmp != null) && (tmp.length() > 0)) { + this.v1TrapPDU.setEnterprise(new OID(tmp)); + } + + tmp = systemConfig.getSimpleValue("genericId",null); + if ((tmp != null) && (tmp.length() > 0)) { + this.v1TrapPDU.setGenericTrap(Integer.parseInt(tmp)); + } + + tmp = systemConfig.getSimpleValue("specificId",null); + if ((tmp != null) && (tmp.length() > 0)) { + this.v1TrapPDU.setSpecificTrap(Integer.parseInt(tmp)); + } + + tmp = systemConfig.getSimpleValue("agentAddress",null); + if ((tmp != null) && (tmp.length() > 0)) { + this.v1TrapPDU.setAgentAddress(new IpAddress(tmp)); + } + + tmp = systemConfig.getSimpleValue("privacyProtocol","AES"); + if ((tmp != null) && (tmp.length() > 0)) { + if (tmp.equals("DES")) { + this.privProtocol = PrivDES.ID; + } else if ((tmp.equals("AES128")) || (tmp.equals("AES"))) { + this.privProtocol = PrivAES128.ID; + } else if (tmp.equals("AES192")) { + this.privProtocol = PrivAES192.ID; + } else if (tmp.equals("AES256")) { + this.privProtocol = PrivAES256.ID; + } else { + throw new IllegalArgumentException("Privacy protocol " + tmp + " not supported"); + } + } + + // Set the default counter listener to return proper USM and MP error counters. + CounterSupport.getInstance().addCounterListener(new DefaultCounterListener()); + + return true; + } + + /*=== Getters and Setters ==============================================*/ + + public OctetString getAuthPassphrase() { + return authPassphrase; + } + + public void setAuthPassphrase(OctetString authPassphrase) { + this.authPassphrase = authPassphrase; + } + + public OID getAuthProtocol() { + return authProtocol; + } + + public void setAuthProtocol(OID authProtocol) { + this.authProtocol = authProtocol; + } + + public OctetString getCommunity() { + return community; + } + + public void setCommunity(OctetString community) { + this.community = community; + } + + public OctetString getContextEngineID() { + return contextEngineID; + } + + public void setContextEngineID(OctetString contextEngineID) { + this.contextEngineID = contextEngineID; + } + + public void setContextName(OctetString contextName) { + this.contextName = contextName; + } + + public OctetString getContextName() { + return contextName; + } + + public int getMaxRepetitions() { + return maxRepetitions; + } + + public void setMaxRepetitions(int maxRepetitions) { + this.maxRepetitions = maxRepetitions; + } + + public int getNonRepeaters() { + return nonRepeaters; + } + + public void setNonRepeaters(int nonRepeaters) { + this.nonRepeaters = nonRepeaters; + } + + public int getOperation() { + return operation; + } + + public void setOperation(int operation) { + this.operation = operation; + } + + public OctetString getPrivPassphrase() { + return privPassphrase; + } + + public void setPrivPassphrase(OctetString privPassphrase) { + this.privPassphrase = privPassphrase; + } + + public OID getPrivProtocol() { + return privProtocol; + } + + public void setPrivProtocol(OID privProtocol) { + this.privProtocol = privProtocol; + } + + public int getRetries() { + return retries; + } + + public void setRetries(int retries) { + this.retries = retries; + } + + public OctetString getSecurityName() { + return securityName; + } + + public void setSecurityName(OctetString securityName) { + this.securityName = securityName; + } + + public TimeTicks getSysUpTime() { + return sysUpTime; + } + + public void setSysUpTime(TimeTicks sysUpTime) { + this.sysUpTime = sysUpTime; + } + + public Target getTarget() { + return target; + } + + public void setTarget(Target target) { + this.target = target; + } + + public int getTimeout() { + return timeout; + } + + public void setTimeout(int timeout) { + this.timeout = timeout; + } + + public OID getTrapOID() { + return trapOID; + } + + public void setTrapOID(OID trapOID) { + this.trapOID = trapOID; + } + + public List getVbs() { + return vbs; + } + + public void setVbs(ArrayList vbs) { + this.vbs = vbs; + } + + public int getVersion() { + return version; + } + + public void setVersion(int version) { + this.version = version; + } + + public int getPduType() { + return pduType; + } + + public void setPduType(int pduType) { + this.pduType = pduType; + } +} \ No newline at end of file
commit a20d85e6389e737985bef36e26861b8f21131d57 Merge: e97ad2b... 8a12038... Author: Heiko W. Rupp pilhuhn@fedorapeople.org Date: Mon Dec 7 08:32:52 2009 +0100
Merge branch 'master' into alertPlugin
diff --cc modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-details.xhtml index 0268277,4b98473..4836113 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-details.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-details.xhtml @@@ -13,9 -13,9 +13,9 @@@
<ui:define name="breadcrumbs"> <h:outputLink value="plugin-list.xhtml" > - <h:outputText value="Installed Plugins"/> + <h:outputText value="Installed #{plugin.deployment == 'SERVER' ? 'Server' : 'Agent'} Plugins"/> </h:outputLink> - > + > <h:outputLink value="#" > <h:outputText value="#{plugin.displayName}"/> </h:outputLink> diff --cc modules/enterprise/server/plugins/pom.xml index ad44fb0,89b7dac..7be2d7a --- a/modules/enterprise/server/plugins/pom.xml +++ b/modules/enterprise/server/plugins/pom.xml @@@ -39,11 -39,7 +39,12 @@@ <module>yum</module> <module>url</module> <module>rhnhosted</module> + <module>alert-email</module> + <module>alert-mobicents</module> + <module>alert-microblog</module> + <module>alert-roles</module> + <module>alert-snmp</module> + <module>validate-all-serverplugins</module> </modules>
</project>
commit 407ac0fc819c38b78b6640ca201b52b49fa04d2d Author: Heiko W. Rupp pilhuhn@fedorapeople.org Date: Sun Dec 6 22:44:59 2009 +0100
Plugin to run scripts in other languages like Ruby or Python
diff --git a/modules/plugins/pom.xml b/modules/plugins/pom.xml index 31c5bb9..df4a58f 100644 --- a/modules/plugins/pom.xml +++ b/modules/plugins/pom.xml @@ -107,7 +107,7 @@ <module>grub</module> <!-- not behaving <module>hardware</module> --> <module>hosts</module> - <module>sudoers</module> + <module>sudoers</module> <module>hudson</module> <!-- error in code generation (see RHQ-1225) <module>jira</module> --> <module>mysql</module> @@ -122,6 +122,7 @@ <module>sshd</module> <module>twitter</module> <!--<module>virt</module>--> + <module>script2</module>
<!-- make this the last - it will validate all the plugins --> <module>validate-all-plugins</module> diff --git a/modules/plugins/script2/pom.xml b/modules/plugins/script2/pom.xml new file mode 100644 index 0000000..839f0c3 --- /dev/null +++ b/modules/plugins/script2/pom.xml @@ -0,0 +1,209 @@ +<project + xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd" + > + + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.rhq</groupId> + <artifactId>rhq-plugins-parent</artifactId> + <version>1.4.0-SNAPSHOT</version> + </parent> + + <groupId>org.rhq</groupId> + <artifactId>rhq-script2-plugin</artifactId> + <packaging>jar</packaging> + + <name>RHQ Script2 Plugin</name> + <description>Plugin that allows monitoring via scripting languages (Ruby, Python)</description> + + <scm> + <connection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/modules/plugins/script2</connection> + <developerConnection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/modules/plugins/script2/</developerConnection> + </scm> + + + <properties> + <scm.module.path>modules/plugins/script2</scm.module.path> + </properties> + + <build> + <plugins> + <plugin> + <artifactId>maven-compiler-plugin</artifactId> + <configuration> + <source>1.5</source> + <target>1.5</target> + </configuration> + </plugin> + + <plugin> + <artifactId>maven-dependency-plugin</artifactId> + <version>2.0</version> + <executions> + <execution> + <id>copy-Script2-jar</id> + <phase>process-resources</phase> + <goals> + <goal>copy</goal> + </goals> + <configuration> + <artifactItems> + + <!-- TODO include needed external jars + that should go into your jar file + + The next one is an example: + --> + + </artifactItems> + <outputDirectory>${project.build.outputDirectory}/lib</outputDirectory> + </configuration> + </execution> + </executions> + </plugin> + + </plugins> + </build> + + <profiles> + <profile> + <id>dev</id> + + <properties> + <rhq.rootDir>../../..</rhq.rootDir> + <rhq.containerDir>${rhq.rootDir}/${rhq.defaultDevContainerPath}</rhq.containerDir> + <rhq.deploymentDir>${rhq.containerDir}/jbossas/server/default/deploy/${rhq.earName}/rhq-downloads/rhq-plugins</rhq.deploymentDir> + </properties> + + <build> + <plugins> + + <plugin> + <artifactId>maven-antrun-plugin</artifactId> + <version>1.1</version> + <executions> + + <execution> + <id>deploy</id> + <phase>compile</phase> + <configuration> + <tasks> + <mkdir dir="${rhq.deploymentDir}"/> + <property name="deployment.file" + location="${rhq.deploymentDir}/${project.build.finalName}.jar"/> + <echo>*** Updating ${deployment.file}...</echo> + <jar destfile="${deployment.file}" basedir="${project.build.outputDirectory}"/> + </tasks> + </configuration> + <goals> + <goal>run</goal> + </goals> + </execution> + + <execution> + <id>deploy-jar-meta-inf</id> + <phase>package</phase> + <configuration> + <tasks> + <property name="deployment.file" + location="${rhq.deploymentDir}/${project.build.finalName}.jar"/> + <echo>*** Updating META-INF dir in ${deployment.file}...</echo> + <unjar src="${project.build.directory}/${project.build.finalName}.jar" + dest="${project.build.outputDirectory}"> + <patternset> + <include name="META-INF/**"/> + </patternset> + </unjar> + <jar destfile="${deployment.file}" + manifest="${project.build.outputDirectory}/META-INF/MANIFEST.MF" + update="true"> + </jar> + </tasks> + </configuration> + <goals> + <goal>run</goal> + </goals> + </execution> + + <execution> + <id>undeploy</id> + <phase>clean</phase> + <configuration> + <tasks> + <property name="deployment.file" + location="${rhq.deploymentDir}/${project.build.finalName}.jar"/> + <echo>*** Deleting ${deployment.file}...</echo> + <delete file="${deployment.file}"/> + </tasks> + </configuration> + <goals> + <goal>run</goal> + </goals> + </execution> + + </executions> + </plugin> + + </plugins> + </build> + + </profile> + </profiles> + + + <repositories> + <repository> + <snapshots> + <enabled>false</enabled> + </snapshots> + <id>jboss</id> + <name>JBoss Repository</name> + <url>http://repository.jboss.org/maven2/</url> + </repository> + <!-- TODO add your own maven repositories here (if needed) --> + </repositories> + + <pluginRepositories> + <pluginRepository> + <snapshots> + <enabled>false</enabled> + </snapshots> + <id>jboss</id> + <name>JBoss Plugin Repository</name> + <url>http://repository.jboss.org/maven2/</url> + </pluginRepository> + </pluginRepositories> + + + <dependencies> + <dependency> + <groupId>commons-logging</groupId> + <artifactId>commons-logging</artifactId> + <version>1.1</version> + </dependency> + <dependency> + <groupId>org.rhq</groupId> + <artifactId>rhq-core-domain</artifactId> + <version>${rhq.version}</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.rhq</groupId> + <artifactId>rhq-core-plugin-api</artifactId> + <version>${rhq.version}</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.rhq</groupId> + <artifactId>rhq-core-native-system</artifactId> + <version>${rhq.version}</version> + <scope>provided</scope> + </dependency> + + <!-- TODO add your dependencies here --> + + </dependencies> +</project> \ No newline at end of file diff --git a/modules/plugins/script2/src/main/java/org/rhq/modules/plugins/script2/ScriptComponent.java b/modules/plugins/script2/src/main/java/org/rhq/modules/plugins/script2/ScriptComponent.java new file mode 100644 index 0000000..9204919 --- /dev/null +++ b/modules/plugins/script2/src/main/java/org/rhq/modules/plugins/script2/ScriptComponent.java @@ -0,0 +1,112 @@ + +package org.rhq.modules.plugins.Script2; + +import java.util.HashSet; +import java.util.Set; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.rhq.core.domain.configuration.Configuration; +import org.rhq.core.pluginapi.inventory.InvalidPluginConfigurationException; +import org.rhq.core.domain.measurement.AvailabilityType; +import org.rhq.core.domain.measurement.MeasurementDataNumeric; +import org.rhq.core.domain.measurement.MeasurementReport; +import org.rhq.core.domain.measurement.MeasurementScheduleRequest; +import org.rhq.core.pluginapi.inventory.ResourceComponent; +import org.rhq.core.pluginapi.inventory.ResourceContext; +import org.rhq.core.pluginapi.measurement.MeasurementFacet; +import org.rhq.core.pluginapi.operation.OperationContext; +import org.rhq.core.pluginapi.operation.OperationFacet; +import org.rhq.core.pluginapi.operation.OperationResult; + + +public class ScriptComponent implements ResourceComponent +, MeasurementFacet +, OperationFacet +{ + private final Log log = LogFactory.getLog(this.getClass()); + + private static final int CHANGEME = 1; // TODO remove or change this + + + + + /** + * Return availability of this resource + * @see org.rhq.core.pluginapi.inventory.ResourceComponent#getAvailability() + */ + public AvailabilityType getAvailability() { + // TODO supply real implementation + return AvailabilityType.UP; + } + + + /** + * Start the resource connection + * @see org.rhq.core.pluginapi.inventory.ResourceComponent#start(org.rhq.core.pluginapi.inventory.ResourceContext) + */ + public void start(ResourceContext context) throws InvalidPluginConfigurationException, Exception { + + Configuration conf = context.getPluginConfiguration(); + // TODO add code to start the resource / connection to it + + + } + + + /** + * Tear down the rescource connection + * @see org.rhq.core.pluginapi.inventory.ResourceComponent#stop() + */ + public void stop() { + + + } + + + + /** + * Gather measurement data + * @see org.rhq.core.pluginapi.measurement.MeasurementFacet#getValues(org.rhq.core.domain.measurement.MeasurementReport, java.util.Set) + */ + public void getValues(MeasurementReport report, Set<MeasurementScheduleRequest> metrics) throws Exception { + + for (MeasurementScheduleRequest req : metrics) { + if (req.getName().equals("dummyMetric")) { + MeasurementDataNumeric res = new MeasurementDataNumeric(req, Double.valueOf(CHANGEME)); + report.addData(res); + } + // TODO add more metrics here + } + } + + + + public void startOperationFacet(OperationContext context) { + + } + + + /** + * Invokes the passed operation on the managed resource + * @param name Name of the operation + * @param params The method parameters + * @return An operation result + * @see org.rhq.core.pluginapi.operation.OperationFacet + */ + public OperationResult invokeOperation(String name, Configuration params) throws Exception { + + OperationResult res = new OperationResult(); + if ("dummyOperation".equals(name)) { + // TODO implement me + + } + return res; + } + + + + + +} diff --git a/modules/plugins/script2/src/main/java/org/rhq/modules/plugins/script2/ScriptDiscovery.java b/modules/plugins/script2/src/main/java/org/rhq/modules/plugins/script2/ScriptDiscovery.java new file mode 100644 index 0000000..05a0ffd --- /dev/null +++ b/modules/plugins/script2/src/main/java/org/rhq/modules/plugins/script2/ScriptDiscovery.java @@ -0,0 +1,51 @@ +package org.rhq.modules.plugins.Script2; + +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.rhq.core.domain.configuration.Configuration; +import org.rhq.core.domain.configuration.Property; +import org.rhq.core.domain.configuration.PropertySimple; +import org.rhq.core.pluginapi.inventory.DiscoveredResourceDetails; +import org.rhq.core.pluginapi.inventory.InvalidPluginConfigurationException; +import org.rhq.core.pluginapi.inventory.ManualAddFacet; +import org.rhq.core.pluginapi.inventory.ProcessScanResult; +import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent; +import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext; + + +/** + * Discovery class + */ +public class ScriptDiscovery implements ResourceDiscoveryComponent +,ManualAddFacet +{ + + private final Log log = LogFactory.getLog(this.getClass()); + + /** + * This method is an empty dummy, as you have selected manual addition + * in the plugin generator. + * If you want to have auto discovery too, remove the "return emptySet" + * and implement the auto discovery logic. + */ + public Set<DiscoveredResourceDetails> discoverResources(ResourceDiscoveryContext discoveryContext) throws Exception { + return Collections.emptySet(); + } + + /** + * Do the manual add of this one resource + */ + public DiscoveredResourceDetails discoverResource(Configuration pluginConfiguration, ResourceDiscoveryContext context) throws InvalidPluginConfigurationException { + + // TODO implement this + DiscoveredResourceDetails detail = null; // new DiscoveredResourceDetails( +// context.getResourceType(), // ResourceType +// ); + + return detail; + } +} \ No newline at end of file diff --git a/modules/plugins/script2/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/script2/src/main/resources/META-INF/rhq-plugin.xml new file mode 100644 index 0000000..be73e2c --- /dev/null +++ b/modules/plugins/script2/src/main/resources/META-INF/rhq-plugin.xml @@ -0,0 +1,39 @@ +<?xml version="1.0"?> +<plugin name="script2" + displayName="script2Plugin" + description="Plugin that allows monitoring via scripting languages (Ruby, Python)" + package="org.rhq.modules.plugins.script2" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns="urn:xmlns:rhq-plugin" + xmlns:c="urn:xmlns:rhq-configuration"> + + + <server name="Script2" + discovery="ScriptDiscovery" + class="ScriptComponent" + supportsManualAdd="true" + + > + <plugin-configuration> + <c:simple-property name="language" default="Ruby"> + <c:property-options> + <c:option value="Ruby"/> + <c:option value="Python"/> + </c:property-options> + </c:simple-property> + <c:simple-property name="availabilityScript" displayName="Name of availability script"/> + <c:simple-property name="monitorScript" /> + </plugin-configuration> + + + <operation name="dummyOperation"> + <!-- TODO supply parameters and return values --> + </operation> + + <metric property="dummyMetric" displayName="Dummy display name"/> + + + + </server> + +</plugin> \ No newline at end of file
commit 43c99efe30a09265412818733d299608a4a75f86 Author: Heiko W. Rupp pilhuhn@fedorapeople.org Date: Sun Dec 6 22:27:05 2009 +0100
Make this plugin use manual add instead of autodiscovery.
diff --git a/modules/plugins/snmptrapd/src/main/java/org/rhq/plugins/snmptrapd/SnmpTrapdDiscovery.java b/modules/plugins/snmptrapd/src/main/java/org/rhq/plugins/snmptrapd/SnmpTrapdDiscovery.java index 60ec06c..ec741a4 100644 --- a/modules/plugins/snmptrapd/src/main/java/org/rhq/plugins/snmptrapd/SnmpTrapdDiscovery.java +++ b/modules/plugins/snmptrapd/src/main/java/org/rhq/plugins/snmptrapd/SnmpTrapdDiscovery.java @@ -26,36 +26,41 @@ import org.rhq.core.domain.configuration.Configuration; import org.rhq.core.domain.resource.ResourceType; import org.rhq.core.pluginapi.inventory.DiscoveredResourceDetails; import org.rhq.core.pluginapi.inventory.InvalidPluginConfigurationException; +import org.rhq.core.pluginapi.inventory.ManualAddFacet; import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent; import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
/** - * Discovery component for an SNMP trapd + * Discovery component for an SNMP trapd * @author Heiko W. Rupp * */ -public class SnmpTrapdDiscovery implements ResourceDiscoveryComponent<SnmpTrapdComponent> { +public class SnmpTrapdDiscovery implements ResourceDiscoveryComponent<SnmpTrapdComponent>, ManualAddFacet<SnmpTrapdComponent> {
- /* (non-Javadoc) - * @see org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent#discoverResources(org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext) + /* + * Autodiscovery is not supported. */ public Set<DiscoveredResourceDetails> discoverResources(ResourceDiscoveryContext context) throws InvalidPluginConfigurationException, Exception {
- Set<DiscoveredResourceDetails> results = new HashSet<DiscoveredResourceDetails>(); + return new HashSet<DiscoveredResourceDetails>();
- String pcName = context.getPluginContainerName(); + } + + /* + * Manual discovery + */ + public DiscoveredResourceDetails discoverResource(Configuration pluginConfiguration, + ResourceDiscoveryContext<SnmpTrapdComponent> ctx) throws InvalidPluginConfigurationException { + + String pcName = ctx.getPluginContainerName(); String key = "Trapd (" + pcName + ")"; String name = key; String description = "SNMP Trap receiver on " + pcName; - Configuration configuration = context.getDefaultPluginConfiguration(); - ResourceType resourceType = context.getResourceType(); - DiscoveredResourceDetails detail = new DiscoveredResourceDetails(resourceType, key, name, null, description, - configuration, null); - - results.add(detail); + ResourceType resourceType = ctx.getResourceType(); + DiscoveredResourceDetails details = new DiscoveredResourceDetails(resourceType, key, name, null, description, + pluginConfiguration, null);
- return results; + return details; } - } diff --git a/modules/plugins/snmptrapd/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/snmptrapd/src/main/resources/META-INF/rhq-plugin.xml index 0234c89..3b5f442 100644 --- a/modules/plugins/snmptrapd/src/main/resources/META-INF/rhq-plugin.xml +++ b/modules/plugins/snmptrapd/src/main/resources/META-INF/rhq-plugin.xml @@ -10,7 +10,8 @@
<server name="SnmpTrapd" discovery="SnmpTrapdDiscovery" - class="SnmpTrapdComponent"> + class="SnmpTrapdComponent" + supportsManualAdd="true">
<plugin-configuration> <c:simple-property name="port"
commit 8a1203861ab30be7d96812ca76ec952c1d2215ba Author: John Mazzitelli mazz@redhat.com Date: Sat Dec 5 02:32:59 2009 -0500
get better reports
diff --git a/etc/samples/simplereport-serverplugin/src/main/java/org/custom/SimpleReportsPluginComponent.java b/etc/samples/simplereport-serverplugin/src/main/java/org/custom/SimpleReportsPluginComponent.java index df44331..4cade37 100644 --- a/etc/samples/simplereport-serverplugin/src/main/java/org/custom/SimpleReportsPluginComponent.java +++ b/etc/samples/simplereport-serverplugin/src/main/java/org/custom/SimpleReportsPluginComponent.java @@ -126,17 +126,14 @@ public class SimpleReportsPluginComponent implements ServerPluginComponent { File file = new File(this.reportDir, "availabilities.txt"); PrintStream ps = new PrintStream(file); try { - ps.println("=== AVAILABILITY REPORT ==="); printHeader(ps); - ps.println("Date Generated: " + new Date()); + ps.println(" Report: AVAILABILITY"); + ps.println(" Date: " + new Date()); for (ResourceAvailability avail : avails) { - if (avail.getAvailabilityType() == null) { - ps.printf("%8s", "UNKNOWN"); - } else { - ps.printf("%8s", avail.getAvailabilityType().toString()); - } - ps.printf(" : %10d : ", avail.getResource().getId()); - ps.println(avail.getResource().getName()); + ps.printf("Resource: %6d | %4s | %s\n", // + avail.getResource().getId(), // + (avail.getAvailabilityType() == null) ? "???" : avail.getAvailabilityType().toString(), // + avail.getResource().getName()); } } finally { ps.close(); @@ -180,13 +177,13 @@ public class SimpleReportsPluginComponent implements ServerPluginComponent { File file = new File(this.reportDir, "platforms.txt"); PrintStream ps = new PrintStream(file); try { - ps.println("=== PLATFORM REPORT ==="); printHeader(ps); - ps.println("Date Generated: " + new Date()); - ps.println(" Committed: " + committed); - ps.println(" Ignored: " + ignored); - ps.println(" Deleted: " + deleted); - ps.println(" Uninventoried: " + uninventoried); + ps.println(" Report: PLATFORM"); + ps.println(" Date: " + new Date()); + ps.println(" Committed: " + committed); + ps.println(" Ignored: " + ignored); + ps.println(" Deleted: " + deleted); + ps.println("Uninventoried: " + uninventoried); } finally { ps.close(); } @@ -206,13 +203,13 @@ public class SimpleReportsPluginComponent implements ServerPluginComponent { File file = new File(this.reportDir, "servers.txt"); PrintStream ps = new PrintStream(file); try { - ps.println("=== SERVER REPORT ==="); printHeader(ps); - ps.println("Date Generated: " + new Date()); - ps.println(" Committed: " + committed); - ps.println(" Ignored: " + ignored); - ps.println(" Deleted: " + deleted); - ps.println(" Uninventoried: " + uninventoried); + ps.println(" Report: SERVER"); + ps.println(" Date: " + new Date()); + ps.println(" Committed: " + committed); + ps.println(" Ignored: " + ignored); + ps.println(" Deleted: " + deleted); + ps.println("Uninventoried: " + uninventoried); } finally { ps.close(); } @@ -232,13 +229,13 @@ public class SimpleReportsPluginComponent implements ServerPluginComponent { File file = new File(this.reportDir, "services.txt"); PrintStream ps = new PrintStream(file); try { - ps.println("=== SERVICE REPORT ==="); printHeader(ps); - ps.println(" Date Generated: " + new Date()); - ps.println(" Committed: " + committed); - ps.println(" Ignored: " + ignored); - ps.println(" Deleted: " + deleted); - ps.println(" Uninventoried: " + uninventoried); + ps.println(" Report: SERVICE"); + ps.println(" Date: " + new Date()); + ps.println(" Committed: " + committed); + ps.println(" Ignored: " + ignored); + ps.println(" Deleted: " + deleted); + ps.println("Uninventoried: " + uninventoried); } finally { ps.close(); } @@ -247,11 +244,7 @@ public class SimpleReportsPluginComponent implements ServerPluginComponent {
private void printHeader(PrintStream ps) { if (this.reportHeader != null) { - ps.println(); ps.println(this.reportHeader); - ps.println(); - } else { - ps.println(); } }
commit 14f056a25d6649a6de42cb1111c444d3cb2daa48 Author: John Mazzitelli mazz@redhat.com Date: Sat Dec 5 00:13:42 2009 -0500
add a new simple report that shows live availability this can be a way for someone to get live availability faster than the normal RHQ availability way perhaps you would do this for VIP resources that you must know their live avail every 10 seconds. you could then have an external process (or another server plugin job!) to alert when something goes down
diff --git a/etc/samples/simplereport-serverplugin/src/main/java/org/custom/SimpleReportPluginComponent.java b/etc/samples/simplereport-serverplugin/src/main/java/org/custom/SimpleReportPluginComponent.java deleted file mode 100644 index 042d3e3..0000000 --- a/etc/samples/simplereport-serverplugin/src/main/java/org/custom/SimpleReportPluginComponent.java +++ /dev/null @@ -1,169 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2009 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.custom; - -import java.io.File; -import java.io.PrintStream; -import java.util.Date; -import java.util.Properties; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.rhq.core.domain.configuration.PropertySimple; -import org.rhq.enterprise.server.plugin.pc.ScheduledJobInvocationContext; -import org.rhq.enterprise.server.plugin.pc.ServerPluginComponent; -import org.rhq.enterprise.server.plugin.pc.ServerPluginContext; - -/** - * A sample lifecycle listener for the sample generic plugin. This listener will be - * the main plugin component the server uses to start and stop the plugin. - */ -public class SimpleReportPluginComponent implements ServerPluginComponent { - private final Log log = LogFactory.getLog(SimpleReportPluginComponent.class); - - private static final String PROP_REPORT_DIRECTORY = "reportDirectory"; - private static final String PROP_REPORT_HEADER = "reportHeader"; - - private static final String JOBPROP_SHOW_PLATFORMS = "showPlatforms"; - private static final String JOBPROP_SHOW_SERVERS = "showServers"; - private static final String JOBPROP_SHOW_SERVICES = "showServices"; - - private ServerPluginContext context; - private File reportDir = null; - private String reportHeader = null; - - public void initialize(ServerPluginContext context) throws Exception { - PropertySimple reportDirProp = context.getPluginConfiguration().getSimple(PROP_REPORT_DIRECTORY); - if (reportDirProp == null || reportDirProp.getStringValue() == null) { - throw new Exception("Simple report server plugin is misconfigured - report directory property is not set"); - } - - this.reportDir = new File(reportDirProp.getStringValue()); - this.reportDir.mkdirs(); - if (!this.reportDir.isDirectory()) { - throw new Exception("Report directory does not exist and could not be created: " + this.reportDir); - } - - PropertySimple reportHeaderProp = context.getPluginConfiguration().getSimple(PROP_REPORT_HEADER); - if (reportHeaderProp != null) { - this.reportHeader = reportHeaderProp.getStringValue(); - } else { - this.reportHeader = null; - } - - this.context = context; - - log.info("The simple report server plugin has been initialized!!!"); - } - - public void start() { - log.info("The simple report server plugin has started!!!"); - } - - public void stop() { - log.info("The simple report server plugin has stopped!!!"); - } - - public void shutdown() { - log.info("The simple report server plugin has been shut down!!!"); - } - - public void generateSimpleReport(ScheduledJobInvocationContext invocation) throws Exception { - log.info("The simple report server plugin scheduled job [generateSimpleReport] has triggered!!!"); - - try { - Properties data = invocation.getJobDefinition().getCallbackData(); - boolean showPlatforms = Boolean.parseBoolean(data.getProperty(JOBPROP_SHOW_PLATFORMS, "true")); - boolean showServers = Boolean.parseBoolean(data.getProperty(JOBPROP_SHOW_SERVERS, "true")); - boolean showServices = Boolean.parseBoolean(data.getProperty(JOBPROP_SHOW_SERVICES, "true")); - if (showPlatforms) { - generatePlatformsReport(); - } - if (showServers) { - generateServersReport(); - } - if (showServices) { - generateServicesReport(); - } - } catch (Exception e) { - log.error("Failed to generate simple report", e); - } - return; - } - - private void generatePlatformsReport() throws Exception { - File file = new File(this.reportDir, "platforms.txt"); - PrintStream ps = new PrintStream(file); - try { - ps.println("=== PLATFORM REPORT ==="); - ps.println("Date Generated: " + new Date()); - printHeader(ps); - - // TODO: collect and print data - ps.println("...data here..."); - } finally { - ps.close(); - } - return; - } - - private void generateServersReport() throws Exception { - File file = new File(this.reportDir, "servers.txt"); - PrintStream ps = new PrintStream(file); - try { - ps.println("=== SERVER REPORT ==="); - ps.println("Date Generated: " + new Date()); - printHeader(ps); - - // TODO: collect and print data - ps.println("...data here..."); - } finally { - ps.close(); - } - return; - } - - private void generateServicesReport() throws Exception { - File file = new File(this.reportDir, "services.txt"); - PrintStream ps = new PrintStream(file); - try { - ps.println("=== SERVICE REPORT ==="); - ps.println("Date Generated: " + new Date()); - printHeader(ps); - - // TODO: collect and print data - ps.println("...data here..."); - } finally { - ps.close(); - } - return; - } - - private void printHeader(PrintStream ps) { - if (this.reportHeader != null) { - ps.println(); - ps.println(this.reportHeader); - ps.println(); - } else { - ps.println(); - } - } -} diff --git a/etc/samples/simplereport-serverplugin/src/main/java/org/custom/SimpleReportsPluginComponent.java b/etc/samples/simplereport-serverplugin/src/main/java/org/custom/SimpleReportsPluginComponent.java new file mode 100644 index 0000000..df44331 --- /dev/null +++ b/etc/samples/simplereport-serverplugin/src/main/java/org/custom/SimpleReportsPluginComponent.java @@ -0,0 +1,284 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2009 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.custom; + +import java.io.File; +import java.io.PrintStream; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Properties; + +import javax.naming.InitialContext; +import javax.naming.NamingException; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.rhq.core.domain.auth.Subject; +import org.rhq.core.domain.configuration.PropertySimple; +import org.rhq.core.domain.measurement.ResourceAvailability; +import org.rhq.core.domain.resource.InventoryStatus; +import org.rhq.core.domain.resource.ResourceCategory; +import org.rhq.enterprise.server.RHQConstants; +import org.rhq.enterprise.server.plugin.pc.ScheduledJobInvocationContext; +import org.rhq.enterprise.server.plugin.pc.ServerPluginComponent; +import org.rhq.enterprise.server.plugin.pc.ServerPluginContext; +import org.rhq.enterprise.server.resource.ResourceManagerLocal; +import org.rhq.enterprise.server.util.LookupUtil; + +/** + * A sample lifecycle listener for the sample generic plugin. This listener will be + * the main plugin component the server uses to start and stop the plugin. + */ +public class SimpleReportsPluginComponent implements ServerPluginComponent { + private final Log log = LogFactory.getLog(SimpleReportsPluginComponent.class); + + private static final String PROP_REPORT_DIRECTORY = "reportDirectory"; + private static final String PROP_REPORT_HEADER = "reportHeader"; + + private static final String JOBPROP_SHOW_PLATFORMS = "showPlatforms"; + private static final String JOBPROP_SHOW_SERVERS = "showServers"; + private static final String JOBPROP_SHOW_SERVICES = "showServices"; + + private static final String JOBPROP_RESOURCE_IDS = "resourceIds"; + + private ServerPluginContext context; + private File reportDir = null; + private String reportHeader = null; + + public void initialize(ServerPluginContext context) throws Exception { + PropertySimple reportDirProp = context.getPluginConfiguration().getSimple(PROP_REPORT_DIRECTORY); + if (reportDirProp == null || reportDirProp.getStringValue() == null) { + throw new Exception("Simple report server plugin is misconfigured - report directory property is not set"); + } + + this.reportDir = new File(reportDirProp.getStringValue()); + this.reportDir.mkdirs(); + if (!this.reportDir.isDirectory()) { + throw new Exception("Report directory does not exist and could not be created: " + this.reportDir); + } + + PropertySimple reportHeaderProp = context.getPluginConfiguration().getSimple(PROP_REPORT_HEADER); + if (reportHeaderProp != null) { + this.reportHeader = reportHeaderProp.getStringValue(); + } else { + this.reportHeader = null; + } + + this.context = context; + + log.info("The simple report server plugin has been initialized!!!"); + } + + public void start() { + log.info("The simple report server plugin has started!!!"); + } + + public void stop() { + log.info("The simple report server plugin has stopped!!!"); + } + + public void shutdown() { + log.info("The simple report server plugin has been shut down!!!"); + } + + public void generateResourceAvailabilityReport(ScheduledJobInvocationContext invocation) throws Exception { + log.info("The simple report server plugin scheduled job [generateResourceAvailabilityReport] has triggered!!!"); + + Properties data = invocation.getJobDefinition().getCallbackData(); + if (data == null) { + throw new Exception("No callback data - cannot generate resource availability report"); + } + + // determine what resources we need to ping + String resourceIdsStr = data.getProperty(JOBPROP_RESOURCE_IDS, ""); + String[] resourceIdsStrArray = resourceIdsStr.split(","); + List<Integer> resourceIds = new ArrayList<Integer>(resourceIdsStrArray.length); + for (String resourceIdStr : resourceIdsStrArray) { + resourceIds.add(new Integer(resourceIdStr)); // throws exception if not a valid number, which halts job (which is good) + } + + // ping the resources to get their availabilities + List<ResourceAvailability> avails = new ArrayList<ResourceAvailability>(resourceIds.size()); + for (Integer id : resourceIds) { + avails.add(pingResource(id.intValue())); + } + + // dump the availability data to the report file + File file = new File(this.reportDir, "availabilities.txt"); + PrintStream ps = new PrintStream(file); + try { + ps.println("=== AVAILABILITY REPORT ==="); + printHeader(ps); + ps.println("Date Generated: " + new Date()); + for (ResourceAvailability avail : avails) { + if (avail.getAvailabilityType() == null) { + ps.printf("%8s", "UNKNOWN"); + } else { + ps.printf("%8s", avail.getAvailabilityType().toString()); + } + ps.printf(" : %10d : ", avail.getResource().getId()); + ps.println(avail.getResource().getName()); + } + } finally { + ps.close(); + } + return; + } + + public void generateSimpleReports(ScheduledJobInvocationContext invocation) throws Exception { + log.info("The simple report server plugin scheduled job [generateSimpleReport] has triggered!!!"); + + try { + Properties data = invocation.getJobDefinition().getCallbackData(); + boolean showPlatforms = Boolean.parseBoolean(data.getProperty(JOBPROP_SHOW_PLATFORMS, "true")); + boolean showServers = Boolean.parseBoolean(data.getProperty(JOBPROP_SHOW_SERVERS, "true")); + boolean showServices = Boolean.parseBoolean(data.getProperty(JOBPROP_SHOW_SERVICES, "true")); + if (showPlatforms) { + generatePlatformsReport(); + } + if (showServers) { + generateServersReport(); + } + if (showServices) { + generateServicesReport(); + } + } catch (Exception e) { + log.error("Failed to generate simple report", e); + } + return; + } + + private void generatePlatformsReport() throws Exception { + Subject user = getOverlord(); + ResourceManagerLocal resourceManager = LookupUtil.getResourceManager(); + + ResourceCategory category = ResourceCategory.PLATFORM; + int committed = resourceManager.getResourceCountByCategory(user, category, InventoryStatus.COMMITTED); + int ignored = resourceManager.getResourceCountByCategory(user, category, InventoryStatus.IGNORED); + int deleted = resourceManager.getResourceCountByCategory(user, category, InventoryStatus.DELETED); + int uninventoried = resourceManager.getResourceCountByCategory(user, category, InventoryStatus.UNINVENTORIED); + + File file = new File(this.reportDir, "platforms.txt"); + PrintStream ps = new PrintStream(file); + try { + ps.println("=== PLATFORM REPORT ==="); + printHeader(ps); + ps.println("Date Generated: " + new Date()); + ps.println(" Committed: " + committed); + ps.println(" Ignored: " + ignored); + ps.println(" Deleted: " + deleted); + ps.println(" Uninventoried: " + uninventoried); + } finally { + ps.close(); + } + return; + } + + private void generateServersReport() throws Exception { + Subject user = getOverlord(); + ResourceManagerLocal resourceManager = LookupUtil.getResourceManager(); + + ResourceCategory category = ResourceCategory.SERVER; + int committed = resourceManager.getResourceCountByCategory(user, category, InventoryStatus.COMMITTED); + int ignored = resourceManager.getResourceCountByCategory(user, category, InventoryStatus.IGNORED); + int deleted = resourceManager.getResourceCountByCategory(user, category, InventoryStatus.DELETED); + int uninventoried = resourceManager.getResourceCountByCategory(user, category, InventoryStatus.UNINVENTORIED); + + File file = new File(this.reportDir, "servers.txt"); + PrintStream ps = new PrintStream(file); + try { + ps.println("=== SERVER REPORT ==="); + printHeader(ps); + ps.println("Date Generated: " + new Date()); + ps.println(" Committed: " + committed); + ps.println(" Ignored: " + ignored); + ps.println(" Deleted: " + deleted); + ps.println(" Uninventoried: " + uninventoried); + } finally { + ps.close(); + } + return; + } + + private void generateServicesReport() throws Exception { + Subject user = getOverlord(); + ResourceManagerLocal resourceManager = LookupUtil.getResourceManager(); + + ResourceCategory category = ResourceCategory.SERVICE; + int committed = resourceManager.getResourceCountByCategory(user, category, InventoryStatus.COMMITTED); + int ignored = resourceManager.getResourceCountByCategory(user, category, InventoryStatus.IGNORED); + int deleted = resourceManager.getResourceCountByCategory(user, category, InventoryStatus.DELETED); + int uninventoried = resourceManager.getResourceCountByCategory(user, category, InventoryStatus.UNINVENTORIED); + + File file = new File(this.reportDir, "services.txt"); + PrintStream ps = new PrintStream(file); + try { + ps.println("=== SERVICE REPORT ==="); + printHeader(ps); + ps.println(" Date Generated: " + new Date()); + ps.println(" Committed: " + committed); + ps.println(" Ignored: " + ignored); + ps.println(" Deleted: " + deleted); + ps.println(" Uninventoried: " + uninventoried); + } finally { + ps.close(); + } + return; + } + + private void printHeader(PrintStream ps) { + if (this.reportHeader != null) { + ps.println(); + ps.println(this.reportHeader); + ps.println(); + } else { + ps.println(); + } + } + + /** + * Returns the availability for the given resource (e.g. UP or DOWN). + * + * @param resourceId the ID of the resource whose availability is to be checked + * @return the resource availability + */ + private ResourceAvailability pingResource(int resourceId) { + Subject user = getOverlord(); + ResourceManagerLocal resourceManager = LookupUtil.getResourceManager(); + ResourceAvailability avail = resourceManager.getLiveResourceAvailability(user, resourceId); + return avail; + } + + private Subject getOverlord() { + Subject user = LookupUtil.getSubjectManager().getOverlord(); + return user; + } + + // currently not used, but this shows how you'd look up remote EJB SLSBs + private static <T> T lookupRemote(Class<? super T> type) { + try { + return (T) new InitialContext().lookup((RHQConstants.EAR_NAME + "/" + type.getSimpleName() + "/remote")); + } catch (NamingException e) { + throw new RuntimeException("Failed to lookup remote interface to EJB: " + type, e); + } + } +} diff --git a/etc/samples/simplereport-serverplugin/src/main/resources/META-INF/rhq-serverplugin.xml b/etc/samples/simplereport-serverplugin/src/main/resources/META-INF/rhq-serverplugin.xml index 098a734..180b711 100644 --- a/etc/samples/simplereport-serverplugin/src/main/resources/META-INF/rhq-serverplugin.xml +++ b/etc/samples/simplereport-serverplugin/src/main/resources/META-INF/rhq-serverplugin.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8" ?>
-<generic-plugin name="SimpleReportGenericPlugin" - displayName="Simple Report Plugin" +<generic-plugin name="SimpleReportsGenericPlugin" + displayName="Simple Reports Plugin" description="A generic plugin that periodically dumps simple reports. The reports contain RHQ data." package="org.custom" version="1.0" @@ -15,18 +15,18 @@ This is a sample server plugin that will periodically dump reports on RHQ data on the local filesystem. ]]></serverplugin:help>
- <serverplugin:plugin-component class="SimpleReportPluginComponent"/> + <serverplugin:plugin-component class="SimpleReportsPluginComponent"/>
serverplugin:scheduled-jobs <!-- notice that we use the map name as the methodName --> - <c:map-property name="generateSimpleReport"> + <c:map-property name="generateSimpleReports" description="Writes simple reports on the current inventory"> <c:simple-property name="enabled" type="boolean" required="true" default="true" summary="true" description="Whether or not the reports should be generated"/> <c:simple-property name="scheduleType" type="string" required="true" default="cron" summary="true" description="Indicates when the reports should be generated"> <c:property-options> <c:option value="periodic"/> - <c:option value="cron" default="true"/> + <c:option value="cron" default="true" /> </c:property-options> </c:simple-property> <c:simple-property name="scheduleTrigger" type="string" required="true" default="0 0/5 * * * ?" summary="true" @@ -43,6 +43,27 @@ <!-- not summary - user should not need to see these and must not change them --> <c:simple-property name="concurrent" type="boolean" required="true" readOnly="true" default="false"/> </c:map-property> + + <c:map-property name="generateResourceAvailabilityReport" description="Writes a report that indicates the live availability for a set of resources."> + <c:simple-property name="enabled" type="boolean" required="true" default="false" summary="true" + description="Whether or not the report should be generated"/> + <c:simple-property name="scheduleType" type="string" required="true" default="periodic" summary="true" + description="Indicates when the report should be generated"> + <c:property-options> + <c:option value="periodic" default="true" /> + <c:option value="cron" /> + </c:property-options> + </c:simple-property> + <c:simple-property name="scheduleTrigger" type="string" required="true" default="5000" summary="true" + description="Based on the schedule type, this is either the period, in milliseconds, or the cron expression to say when the report should be generated"/> + + <!-- custom properties specifically needed by the job class itself --> + <c:simple-property name="resourceIds" type="string" required="true" default="0" summary="true" + description="Comma-separated list of resource IDs. These will be the resources whose live status will be checked."/> + + <!-- not summary - user should not need to see these and must not change them --> + <c:simple-property name="concurrent" type="boolean" required="true" readOnly="true" default="false"/> + </c:map-property> </serverplugin:scheduled-jobs>
<!-- custom plugin config --> diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java index 450a38a..5b2716c 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java @@ -2004,6 +2004,36 @@ public class ResourceManagerBean implements ResourceManagerLocal, ResourceManage return getResourceById(subject, resourceId); }
+ public ResourceAvailability getLiveResourceAvailability(Subject subject, int resourceId) { + Resource res = getResourceById(subject, resourceId); + ResourceAvailability results = new ResourceAvailability(res, null); + + try { + Agent agent = res.getAgent(); + if (agent == null) { + throw new IllegalStateException("No agent is associated with the resource with id [" + resourceId + "]"); + } + + // first, quickly see if we can even ping the agent, if not, don't bother trying to get the resource avail + AgentClient client = agentManager.getAgentClient(agent); + boolean agentPing = client.ping(5000L); + if (agentPing) { + // we can't serialize the resource due to the hibernate proxies (agent can't deserialize hibernate objs) + // but we know we only need the basics for the agent to collect availability, so create a bare resource object + Resource bareResource = new Resource(res.getResourceKey(), res.getName(), res.getResourceType()); + bareResource.setId(res.getId()); + bareResource.setUuid(res.getUuid()); + Availability avail = client.getDiscoveryAgentService().getCurrentAvailability(bareResource); + if (avail != null) { + results.setAvailabilityType(avail.getAvailabilityType()); + } + } + } catch (Throwable ignore) { + } + + return results; + } + // lineage is a getXXX (not findXXX) because it logically returns a single object, but modeled as a list here public @XmlJavaTypeAdapter(value = ResourceListAdapter.class) List<Resource> findResourceLineage(Subject subject, int resourceId) { diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerLocal.java index c05372d..95445de 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerLocal.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerLocal.java @@ -28,6 +28,7 @@ import org.jetbrains.annotations.Nullable;
import org.rhq.core.domain.auth.Subject; import org.rhq.core.domain.criteria.ResourceCriteria; +import org.rhq.core.domain.measurement.ResourceAvailability; import org.rhq.core.domain.resource.Agent; import org.rhq.core.domain.resource.InventoryStatus; import org.rhq.core.domain.resource.Resource; @@ -407,6 +408,11 @@ public interface ResourceManagerLocal { // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
/** + * #see {@link ResourceManagerRemote#getLiveResourceAvailability(Subject, int) + */ + ResourceAvailability getLiveResourceAvailability(Subject subject, int resourceId); + + /** * #see {@link ResourceManagerRemote#getResource(Subject, int) */ Resource getResource(Subject subject, int resourceId); diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerRemote.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerRemote.java index 299ff4a..dd3fb3a 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerRemote.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerRemote.java @@ -29,6 +29,7 @@ import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import org.rhq.core.domain.auth.Subject; import org.rhq.core.domain.criteria.ResourceCriteria; +import org.rhq.core.domain.measurement.ResourceAvailability; import org.rhq.core.domain.resource.Resource; import org.rhq.core.domain.resource.ResourceCategory; import org.rhq.core.domain.resource.composite.ResourceComposite; @@ -49,6 +50,25 @@ import org.rhq.enterprise.server.system.ServerVersion; public interface ResourceManagerRemote {
/** + * Returns the availability of the resource with the specified id. + * This performs a live check - a resource will be considered UNKNOWN if the agent + * cannot be contacted for any reason. + * + * @param subject The logged in user's subject. + * @param resourceId the id of a {@link Resource} in inventory. + * + * @return the resource availability - note that if the encapsulated availability type is <code>null</code>, + * the resource availability is UNKNOWN. + * + * @throws FetchException if the resource represented by the resourceId parameter does not exist, or if the + * passed subject does not have permission to view this resource. + */ + @WebMethod + ResourceAvailability getLiveResourceAvailability( // + @WebParam(name = "subject") Subject subject, // + @WebParam(name = "resourceId") int resourceId); + + /** * Returns the Resource with the specified id. * * @param subject The logged in user's subject. diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/webservices/WebservicesManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/webservices/WebservicesManagerBean.java index 8587e51..5ee7ec5 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/webservices/WebservicesManagerBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/webservices/WebservicesManagerBean.java @@ -80,6 +80,7 @@ import org.rhq.core.domain.measurement.MeasurementData; import org.rhq.core.domain.measurement.MeasurementDataTrait; import org.rhq.core.domain.measurement.MeasurementDefinition; import org.rhq.core.domain.measurement.MeasurementSchedule; +import org.rhq.core.domain.measurement.ResourceAvailability; import org.rhq.core.domain.measurement.calltime.CallTimeDataComposite; import org.rhq.core.domain.measurement.composite.MeasurementDataNumericHighLowComposite; import org.rhq.core.domain.operation.GroupOperationHistory; @@ -684,6 +685,10 @@ public class WebservicesManagerBean implements WebservicesRemote { return resourceManager.getParentResource(subject, resourceId); }
+ public ResourceAvailability getLiveResourceAvailability(Subject subject, int resourceId) { + return resourceManager.getLiveResourceAvailability(subject, resourceId); + } + public Resource getResource(Subject subject, int resourceId) { return resourceManager.getResource(subject, resourceId); }
commit ef220f6a2cca96e27409c74d6e18d23e0e65aa91 Author: John Sanda john@localhost.localdomain Date: Fri Dec 4 21:43:55 2009 -0500
Adding error handling and unit tests for translation operation.
translationResourceConfiguration() now throws an exception if the configuration does not support both structured and raw.
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java index 7b7aec8..2aa8f18 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java @@ -1913,7 +1913,12 @@ public class ConfigurationManagerBean implements ConfigurationManagerLocal, Conf }
public Configuration translateResourceConfiguration(Subject subject, int resourceId, Configuration configuration, - boolean fromStructured) throws ResourceNotFoundException { + boolean fromStructured) { + + if (!isStructuredAndRawSupported(resourceId)) { + throw new TranslationNotSupportedException("The translation operation is only supported for " + + "configurations that support both structured and raw."); + }
Resource resource = entityManager.find(Resource.class, resourceId);
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerLocal.java index 69c5e96..f54254c 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerLocal.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerLocal.java @@ -487,6 +487,6 @@ public interface ConfigurationManagerLocal { RawConfiguration findRawConfigurationById(int rawConfigId);
Configuration translateResourceConfiguration(Subject subject, int resourceId, Configuration configuration, - boolean fromStructured) throws ResourceNotFoundException; + boolean fromStructured) throws ResourceNotFoundException, TranslationNotSupportedException;
} \ No newline at end of file diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/TranslationNotSupportedException.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/TranslationNotSupportedException.java index 4525aa0..38f245c 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/TranslationNotSupportedException.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/TranslationNotSupportedException.java @@ -23,7 +23,10 @@
package org.rhq.enterprise.server.configuration;
-public class TranslationNotSupportedException extends Exception { +import javax.ejb.ApplicationException; + +@ApplicationException(rollback = true) +public class TranslationNotSupportedException extends RuntimeException {
private static final long serialVersionUID = 1L;
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBeanUnitTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBeanUnitTest.java index e2d8e81..5ba68e1 100644 --- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBeanUnitTest.java +++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBeanUnitTest.java @@ -352,6 +352,92 @@ public class ConfigurationManagerBeanUnitTest extends JMockTest { assertPropertiesMatch(expectedUpdate, actualUpdate, "Expected to get back a failure update"); }
+ @Test + public void translatingFromStructuredToRawShouldReturnModifiedConfig() throws Exception { + final ConfigTranslationFixture fixture = newStructuredAndRawTranslationFixture(); + + final AgentClient agentClient = context.mock(AgentClient.class); + final ConfigurationAgentService configAgentService = context.mock(ConfigurationAgentService.class); + + final Configuration expectedConfig = new Configuration(); + + context.checking(new Expectations() {{ + allowing(entityMgr).find(Resource.class, fixture.resourceId); will(returnValue(fixture.resource)); + + oneOf(authorizationMgr).canViewResource(fixture.subject, fixture.resourceId); will(returnValue(true)); + + allowing(agentMgr).getAgentClient(fixture.resource.getAgent()); will(returnValue(agentClient)); + + allowing(agentClient).getConfigurationAgentService(); will(returnValue(configAgentService)); + + oneOf(configAgentService).merge(fixture.configuration, fixture.resourceId, FROM_STRUCTURED); + will(returnValue(expectedConfig)); + }}); + + Configuration translatedConfig = configurationMgr.translateResourceConfiguration(fixture.subject, + fixture.resourceId, fixture.configuration, FROM_STRUCTURED); + + assertSame( + translatedConfig, + expectedConfig, + "Expected to get back the configuration translated by the " + ConfigurationAgentService.class.getSimpleName()); + } + + @Test + public void translatingFromRawToStructuredShouldReturnModifiedConfig() throws Exception { + final ConfigTranslationFixture fixture = newStructuredAndRawTranslationFixture(); + + final AgentClient agentClient = context.mock(AgentClient.class); + final ConfigurationAgentService configAgentService = context.mock(ConfigurationAgentService.class); + + final Configuration expectedConfig = new Configuration(); + + context.checking(new Expectations() {{ + allowing(entityMgr).find(Resource.class, fixture.resourceId); will(returnValue(fixture.resource)); + + oneOf(authorizationMgr).canViewResource(fixture.subject, fixture.resourceId); will(returnValue(true)); + + allowing(agentMgr).getAgentClient(fixture.resource.getAgent()); will(returnValue(agentClient)); + + allowing(agentClient).getConfigurationAgentService(); will(returnValue(configAgentService)); + + oneOf(configAgentService).merge(fixture.configuration, fixture.resourceId, FROM_RAW); + will(returnValue(expectedConfig)); + }}); + + Configuration translatedConfig = configurationMgr.translateResourceConfiguration(fixture.subject, + fixture.resourceId, fixture.configuration, FROM_RAW); + + assertSame( + translatedConfig, + expectedConfig, + "Expected to get back the configuration translated by the " + ConfigurationAgentService.class.getSimpleName()); + } + + @Test(expectedExceptions = TranslationNotSupportedException.class) + public void exceptionShouldBeThrownWhenTryingToTranslateStructuredOnlyConfig() throws Exception { + final ConfigTranslationFixture fixture = newStructuredTranslationFixture(); + + context.checking(new Expectations() {{ + allowing(entityMgr).find(Resource.class, fixture.resourceId); will(returnValue(fixture.resource)); + }}); + + configurationMgr.translateResourceConfiguration(fixture.subject, fixture.resourceId, fixture.configuration, + FROM_STRUCTURED); + } + + @Test(expectedExceptions = TranslationNotSupportedException.class) + public void exceptionShouldBeThrownWhenTryingToTranslateRawOnlyConfig() throws Exception { + final ConfigTranslationFixture fixture = newRawTranslationFixture(); + + context.checking(new Expectations() {{ + allowing(entityMgr).find(Resource.class, fixture.resourceId); will(returnValue(fixture.resource)); + }}); + + configurationMgr.translateResourceConfiguration(fixture.subject, fixture.resourceId, fixture.configuration, + FROM_RAW); + } + public static Matcher<ConfigurationUpdateRequest> matchingUpdateRequest(ConfigurationUpdateRequest expected) { return new PropertyMatcher<ConfigurationUpdateRequest>(expected); } @@ -377,6 +463,27 @@ public class ConfigurationManagerBeanUnitTest extends JMockTest { return fixture; }
+ ConfigTranslationFixture newStructuredAndRawTranslationFixture() { + ConfigTranslationFixture fixture = new ConfigTranslationFixture(); + fixture.resource = createResourceWithStructuredAndRawConfig(fixture.resourceId); + + return fixture; + } + + ConfigTranslationFixture newStructuredTranslationFixture() { + ConfigTranslationFixture fixture = new ConfigTranslationFixture(); + fixture.resource = createResourceWithStructuredConfig(fixture.resourceId); + + return fixture; + } + + ConfigTranslationFixture newRawTranslationFixture() { + ConfigTranslationFixture fixture = new ConfigTranslationFixture(); + fixture.resource = createResourceWithRawConfig(fixture.resourceId); + + return fixture; + } + Resource createResource(int resourceId) { Resource resource = new Resource(resourceId); resource.setAgent(new Agent("test-agent", "localhost", 7080, null, null)); @@ -442,4 +549,11 @@ public class ConfigurationManagerBeanUnitTest extends JMockTest { Resource resource; }
+ static class ConfigTranslationFixture { + Subject subject = new Subject("rhqadmin", true, true); + int resourceId = -1; + Configuration configuration = new Configuration(); + Resource resource; + } + }
commit 96fea90d366cd5c5d0b32aa0ff2f61f4395fc643 Author: John Mazzitelli mazz@redhat.com Date: Fri Dec 4 17:44:45 2009 -0500
add another sample plugin that illustrates how you can dump reports periodically. need to use this to test redeploying plugins to make sure that works
diff --git a/.classpath b/.classpath index fdefd25..c62026e 100644 --- a/.classpath +++ b/.classpath @@ -111,6 +111,7 @@ <classpathentry kind="src" path="modules/plugins/augeas/src/test/java"/> <classpathentry kind="src" path="etc/samples/skeleton-plugin/src/main/java"/> <classpathentry kind="src" path="etc/samples/custom-serverplugin/src/main/java"/> + <classpathentry kind="src" path="etc/samples/simplereport-serverplugin/src/main/java"/> <classpathentry kind="src" path="etc/agentspawn/src/main/java"/> <classpathentry excluding="**" kind="src" path="modules/enterprise/comm/src/test/resources"/> <classpathentry excluding="**" kind="src" path="modules/enterprise/agent/src/main/resources"/> diff --git a/etc/samples/simplereport-serverplugin/pom.xml b/etc/samples/simplereport-serverplugin/pom.xml new file mode 100644 index 0000000..48c0f6c --- /dev/null +++ b/etc/samples/simplereport-serverplugin/pom.xml @@ -0,0 +1,158 @@ +<?xml version="1.0"?> + +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd%22%3E + + <modelVersion>4.0.0</modelVersion> + + <groupId>org.custom</groupId> + <artifactId>simplereport-serverplugin</artifactId> + <version>1.0-SNAPSHOT</version> + <packaging>jar</packaging> + + <name>RHQ Simple Report Server Plugin </name> + <description>A RHQ server plugin that periodically outputs a simple report containing some RHQ data</description> + + <properties> + <rhq.version>1.4.0-SNAPSHOT</rhq.version> + </properties> + + <dependencies> + + <!-- Below are the core modules that are required dependencies of all plugins --> + <dependency> + <groupId>org.rhq</groupId> + <artifactId>rhq-enterprise-server</artifactId> + <version>${rhq.version}</version> + <scope>provided</scope> <!-- provided by the server/plugin-container --> + </dependency> + + <!-- TODO: This is a fix for the Javac bug requiring annotations to be + available when compiling dependent classes. It is fixed in JDK 6. --> + <dependency> + <groupId>javax.persistence</groupId> + <artifactId>persistence-api</artifactId> + <version>1.0</version> + <scope>provided</scope> <!-- provided by the server/plugin-container --> + </dependency> + + <!-- TODO: This is a fix for the Javac bug requiring annotations to be + available when compiling dependent classes; it is fixed in JDK 6. --> + <dependency> + <groupId>jboss.jboss-embeddable-ejb3</groupId> + <artifactId>hibernate-all</artifactId> + <version>1.0.0.Alpha9</version> + <scope>provided</scope> <!-- provided by the server/plugin-container --> + </dependency> + + <!-- uncomment the one of the three logging systems your plugin uses: log4j, commons-logging or i18nlog --> + <!-- all three are provided to your plugin by the server/plugin-container --> + <!-- + <dependency> + <groupId>log4j</groupId> + <artifactId>log4j</artifactId> + <version>1.2.14</version> + <scope>provided</scope> + </dependency> + --> + + <!-- + <dependency> + <groupId>commons-logging</groupId> + <artifactId>commons-logging</artifactId> + <version>1.1</version> + <scope>provided</scope> + </dependency> + --> + + <!-- + <dependency> + <groupId>i18nlog</groupId> + <artifactId>i18nlog</artifactId> + <version>1.0.9</version> + </dependency> + --> + + <!-- Define any third-party dependencies your plugin has here. --> + <!-- + <dependency> + <groupId>group-id-of-dependency-goes-here</groupId> + <artifactId>artifact-id-of-dependency-goes-here</artifactId> + <version>version-of-dependency-goes-here</version> + </dependency> + --> + + </dependencies> + + <build> + <plugins> + + <plugin> + <artifactId>maven-compiler-plugin</artifactId> + <configuration> + <source>1.5</source> + <target>1.5</target> + </configuration> + </plugin> + + <!-- + If your plugin has third-party jar dependencies that are not already + available when deployed in the plugin container, you can package these + jars in your plugin. They go in your plugin jar's "lib" directory. + Uncomment the maven plugin definition below and define one or more jar + files (aka "artifactItem" elements) that you want to include in your + plugin jar. + --> + +<!-- + <plugin> + <artifactId>maven-dependency-plugin</artifactId> + <executions> + <execution> + <id>copy-dependencies</id> + <phase>process-resources</phase> + <goals> + <goal>copy</goal> + </goals> + <configuration> + <artifactItems> + <artifactItem> + <groupId>your-third-party-dep-group</groupId> + <artifactId>your-third-party-dep-artifact</artifactId> + <version>your-third-party-dep-version</version> + </artifactItem> + </artifactItems> + <outputDirectory>${project.build.outputDirectory}/lib</outputDirectory> + </configuration> + </execution> + </executions> + </plugin> +--> + + </plugins> + </build> + + <repositories> + <repository> + <id>jboss</id> + <name>JBoss Repository</name> + <url>http://repository.jboss.org/maven2/</url> + <snapshots> + <enabled>false</enabled> + </snapshots> + </repository> + </repositories> + + <pluginRepositories> + <pluginRepository> + <id>jboss</id> + <name>JBoss Plugin Repository</name> + <url>http://repository.jboss.org/maven2/</url> + <snapshots> + <enabled>false</enabled> + </snapshots> + </pluginRepository> + </pluginRepositories> + +</project> diff --git a/etc/samples/simplereport-serverplugin/src/main/java/org/custom/SimpleReportPluginComponent.java b/etc/samples/simplereport-serverplugin/src/main/java/org/custom/SimpleReportPluginComponent.java new file mode 100644 index 0000000..042d3e3 --- /dev/null +++ b/etc/samples/simplereport-serverplugin/src/main/java/org/custom/SimpleReportPluginComponent.java @@ -0,0 +1,169 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2009 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.custom; + +import java.io.File; +import java.io.PrintStream; +import java.util.Date; +import java.util.Properties; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.rhq.core.domain.configuration.PropertySimple; +import org.rhq.enterprise.server.plugin.pc.ScheduledJobInvocationContext; +import org.rhq.enterprise.server.plugin.pc.ServerPluginComponent; +import org.rhq.enterprise.server.plugin.pc.ServerPluginContext; + +/** + * A sample lifecycle listener for the sample generic plugin. This listener will be + * the main plugin component the server uses to start and stop the plugin. + */ +public class SimpleReportPluginComponent implements ServerPluginComponent { + private final Log log = LogFactory.getLog(SimpleReportPluginComponent.class); + + private static final String PROP_REPORT_DIRECTORY = "reportDirectory"; + private static final String PROP_REPORT_HEADER = "reportHeader"; + + private static final String JOBPROP_SHOW_PLATFORMS = "showPlatforms"; + private static final String JOBPROP_SHOW_SERVERS = "showServers"; + private static final String JOBPROP_SHOW_SERVICES = "showServices"; + + private ServerPluginContext context; + private File reportDir = null; + private String reportHeader = null; + + public void initialize(ServerPluginContext context) throws Exception { + PropertySimple reportDirProp = context.getPluginConfiguration().getSimple(PROP_REPORT_DIRECTORY); + if (reportDirProp == null || reportDirProp.getStringValue() == null) { + throw new Exception("Simple report server plugin is misconfigured - report directory property is not set"); + } + + this.reportDir = new File(reportDirProp.getStringValue()); + this.reportDir.mkdirs(); + if (!this.reportDir.isDirectory()) { + throw new Exception("Report directory does not exist and could not be created: " + this.reportDir); + } + + PropertySimple reportHeaderProp = context.getPluginConfiguration().getSimple(PROP_REPORT_HEADER); + if (reportHeaderProp != null) { + this.reportHeader = reportHeaderProp.getStringValue(); + } else { + this.reportHeader = null; + } + + this.context = context; + + log.info("The simple report server plugin has been initialized!!!"); + } + + public void start() { + log.info("The simple report server plugin has started!!!"); + } + + public void stop() { + log.info("The simple report server plugin has stopped!!!"); + } + + public void shutdown() { + log.info("The simple report server plugin has been shut down!!!"); + } + + public void generateSimpleReport(ScheduledJobInvocationContext invocation) throws Exception { + log.info("The simple report server plugin scheduled job [generateSimpleReport] has triggered!!!"); + + try { + Properties data = invocation.getJobDefinition().getCallbackData(); + boolean showPlatforms = Boolean.parseBoolean(data.getProperty(JOBPROP_SHOW_PLATFORMS, "true")); + boolean showServers = Boolean.parseBoolean(data.getProperty(JOBPROP_SHOW_SERVERS, "true")); + boolean showServices = Boolean.parseBoolean(data.getProperty(JOBPROP_SHOW_SERVICES, "true")); + if (showPlatforms) { + generatePlatformsReport(); + } + if (showServers) { + generateServersReport(); + } + if (showServices) { + generateServicesReport(); + } + } catch (Exception e) { + log.error("Failed to generate simple report", e); + } + return; + } + + private void generatePlatformsReport() throws Exception { + File file = new File(this.reportDir, "platforms.txt"); + PrintStream ps = new PrintStream(file); + try { + ps.println("=== PLATFORM REPORT ==="); + ps.println("Date Generated: " + new Date()); + printHeader(ps); + + // TODO: collect and print data + ps.println("...data here..."); + } finally { + ps.close(); + } + return; + } + + private void generateServersReport() throws Exception { + File file = new File(this.reportDir, "servers.txt"); + PrintStream ps = new PrintStream(file); + try { + ps.println("=== SERVER REPORT ==="); + ps.println("Date Generated: " + new Date()); + printHeader(ps); + + // TODO: collect and print data + ps.println("...data here..."); + } finally { + ps.close(); + } + return; + } + + private void generateServicesReport() throws Exception { + File file = new File(this.reportDir, "services.txt"); + PrintStream ps = new PrintStream(file); + try { + ps.println("=== SERVICE REPORT ==="); + ps.println("Date Generated: " + new Date()); + printHeader(ps); + + // TODO: collect and print data + ps.println("...data here..."); + } finally { + ps.close(); + } + return; + } + + private void printHeader(PrintStream ps) { + if (this.reportHeader != null) { + ps.println(); + ps.println(this.reportHeader); + ps.println(); + } else { + ps.println(); + } + } +} diff --git a/etc/samples/simplereport-serverplugin/src/main/resources/META-INF/rhq-serverplugin.xml b/etc/samples/simplereport-serverplugin/src/main/resources/META-INF/rhq-serverplugin.xml new file mode 100644 index 0000000..098a734 --- /dev/null +++ b/etc/samples/simplereport-serverplugin/src/main/resources/META-INF/rhq-serverplugin.xml @@ -0,0 +1,60 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<generic-plugin name="SimpleReportGenericPlugin" + displayName="Simple Report Plugin" + description="A generic plugin that periodically dumps simple reports. The reports contain RHQ data." + package="org.custom" + version="1.0" + apiVersion="2.0" + disabledOnDiscovery="true" + xmlns="urn:xmlns:rhq-serverplugin.generic" + xmlns:serverplugin="urn:xmlns:rhq-serverplugin" + xmlns:c="urn:xmlns:rhq-configuration"> + + serverplugin:help<![CDATA[ + This is a sample server plugin that will periodically dump reports on RHQ data on the local filesystem. + ]]></serverplugin:help> + + <serverplugin:plugin-component class="SimpleReportPluginComponent"/> + + serverplugin:scheduled-jobs + <!-- notice that we use the map name as the methodName --> + <c:map-property name="generateSimpleReport"> + <c:simple-property name="enabled" type="boolean" required="true" default="true" summary="true" + description="Whether or not the reports should be generated"/> + <c:simple-property name="scheduleType" type="string" required="true" default="cron" summary="true" + description="Indicates when the reports should be generated"> + <c:property-options> + <c:option value="periodic"/> + <c:option value="cron" default="true"/> + </c:property-options> + </c:simple-property> + <c:simple-property name="scheduleTrigger" type="string" required="true" default="0 0/5 * * * ?" summary="true" + description="Based on the schedule type, this is either the period, in milliseconds, or the cron expression to say when the reports should be generated"/> + + <!-- custom properties specifically needed by the job class itself --> + <c:simple-property name="showPlatforms" type="boolean" required="true" default="true" summary="true" + description="Whether or not the reports contain platform data"/> + <c:simple-property name="showServers" type="boolean" required="true" default="true" summary="true" + description="Whether or not the reports contain server data"/> + <c:simple-property name="showServices" type="boolean" required="true" default="true" summary="true" + description="Whether or not the reports contain service data"/> + + <!-- not summary - user should not need to see these and must not change them --> + <c:simple-property name="concurrent" type="boolean" required="true" readOnly="true" default="false"/> + </c:map-property> + </serverplugin:scheduled-jobs> + + <!-- custom plugin config --> + serverplugin:plugin-configuration + <!-- + Where should we put the reports? Note this is required but there is no default; this is why + disabledOnDiscovery="true" because we need the user to configure this plugin before it can be enabled. + --> + <c:simple-property name="reportDirectory" type="file" required="true" + description="The absolute pathname of the directory where the reports are stored." /> + <c:simple-property name="reportHeader" type="string" required="false" + description="If specified, this string will appear at the top of the report." /> + </serverplugin:plugin-configuration> + +</generic-plugin>
commit 72d1d85be547e49ab0918a11e714dacfaec4b854 Merge: 377529e... 9bdffbe... Author: Jay Shaughnessy jshaughn@redhat.com Date: Fri Dec 4 17:12:11 2009 -0500
merge work
commit 377529e9be2212df5c2fcd767c851a35c0ccc2b9 Author: Jay Shaughnessy jshaughn@redhat.com Date: Fri Dec 4 17:10:26 2009 -0500
git is intent on making me commit this file, so I will.
diff --git a/etc/eclipse-tools/templates/schema.xmlcatalog b/etc/eclipse-tools/templates/schema.xmlcatalog index d4054bb..207620e 100644 --- a/etc/eclipse-tools/templates/schema.xmlcatalog +++ b/etc/eclipse-tools/templates/schema.xmlcatalog @@ -1,11 +1,11 @@ -<?xml version="1.0" encoding="UTF-8"?> -<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog"> -<uri name="urn:xmlns:rhq-configuration" uri="platform:/resource/rhq/modules/core/client-api/src/main/resources/rhq-configuration.xsd"/> -<uri name="urn:xmlns:rhq-plugin" uri="platform:/resource/rhq/modules/core/client-api/src/main/resources/rhq-plugin.xsd"/> -<uri name="urn:xmlns:rhq-contentsource-packagedetails" uri="platform:/resource/rhq/modules/enterprise/server/xml-schemas/src/main/resources/rhq-contentsource-packagedetails.xsd"/> -<uri name="urn:xmlns:rhq-serverplugin" uri="platform:/resource/rhq/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin.xsd"/> -<uri name="urn:xmlns:rhq-serverplugin.generic" uri="platform:/resource/rhq/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-generic.xsd"/> -<uri name="urn:xmlns:rhq-serverplugin.alert" uri="platform:/resource/rhq/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-alert.xsd"/> -<uri name="urn:xmlns:rhq-serverplugin.content" uri="platform:/resource/rhq/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-content.xsd"/> -<uri name="urn:xmlns:rhq-serverplugin.perspective" uri="platform:/resource/rhq/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-perspective.xsd"/> -</catalog> +<?xml version="1.0" encoding="UTF-8"?> +<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog"> +<uri name="urn:xmlns:rhq-configuration" uri="platform:/resource/rhq/modules/core/client-api/src/main/resources/rhq-configuration.xsd"/> +<uri name="urn:xmlns:rhq-plugin" uri="platform:/resource/rhq/modules/core/client-api/src/main/resources/rhq-plugin.xsd"/> +<uri name="urn:xmlns:rhq-contentsource-packagedetails" uri="platform:/resource/rhq/modules/enterprise/server/xml-schemas/src/main/resources/rhq-contentsource-packagedetails.xsd"/> +<uri name="urn:xmlns:rhq-serverplugin" uri="platform:/resource/rhq/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin.xsd"/> +<uri name="urn:xmlns:rhq-serverplugin.generic" uri="platform:/resource/rhq/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-generic.xsd"/> +<uri name="urn:xmlns:rhq-serverplugin.alert" uri="platform:/resource/rhq/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-alert.xsd"/> +<uri name="urn:xmlns:rhq-serverplugin.content" uri="platform:/resource/rhq/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-content.xsd"/> +<uri name="urn:xmlns:rhq-serverplugin.perspective" uri="platform:/resource/rhq/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-perspective.xsd"/> +</catalog>
commit 9bdffbea34864d3414c30d546926ee49f5523c59 Author: Jay Shaughnessy jshaughn@redhat.com Date: Fri Dec 4 17:07:15 2009 -0500
Fix some imports given new generated schema types
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveManagerBean.java index e99071f..3d4f220 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveManagerBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveManagerBean.java @@ -36,11 +36,14 @@ import org.jetbrains.annotations.NotNull; import org.rhq.core.domain.auth.Subject; import org.rhq.core.domain.authz.Permission; import org.rhq.core.domain.resource.Resource; -import org.rhq.enterprise.gui.legacy.util.Tab; import org.rhq.enterprise.server.RHQConstants; import org.rhq.enterprise.server.auth.SubjectManagerLocal; import org.rhq.enterprise.server.authz.AuthorizationManagerLocal; +import org.rhq.enterprise.server.xmlschema.generated.serverplugin.perspective.GlobalPermissionActivatorSetType; +import org.rhq.enterprise.server.xmlschema.generated.serverplugin.perspective.GlobalPermissionActivatorType; +import org.rhq.enterprise.server.xmlschema.generated.serverplugin.perspective.GlobalPermissionType; import org.rhq.enterprise.server.xmlschema.generated.serverplugin.perspective.MenuItemType; +import org.rhq.enterprise.server.xmlschema.generated.serverplugin.perspective.ResourceActivatorSetType;
@Stateless // @WebService(endpointInterface = "org.rhq.enterprise.server.perspective.PerspectiveManagerRemote")
commit 6255174dd106d00f658397e864efbb48498c3501 Author: Jay Shaughnessy jshaughn@redhat.com Date: Fri Dec 4 17:06:39 2009 -0500
Update sample perspective descriptor with latest schema changes
diff --git a/etc/samples/perspectives/sample-perspective/perspective/src/main/resources/META-INF/rhq-serverplugin.xml b/etc/samples/perspectives/sample-perspective/perspective/src/main/resources/META-INF/rhq-serverplugin.xml index de12e05..b5499b2 100644 --- a/etc/samples/perspectives/sample-perspective/perspective/src/main/resources/META-INF/rhq-serverplugin.xml +++ b/etc/samples/perspectives/sample-perspective/perspective/src/main/resources/META-INF/rhq-serverplugin.xml @@ -83,10 +83,10 @@ extensionPoint="coreMenu" name="custom.child1" placement="start" /> - <permissionActivatorSet> - <permissionActivator + <globalPermissionActivatorSet> + <globalPermissionActivator permission="MANAGE_INVENTORY" /> - </permissionActivatorSet> + </globalPermissionActivatorSet> </menuItem> <menuItem name="custom.child1.newGroupDefinition" @@ -98,9 +98,9 @@ extensionPoint="coreMenu" name="custom.child1.newGroup" placement="after" /> - <permissionActivatorSet> - <permissionActivator + <globalPermissionActivatorSet> + <globalPermissionActivator permission="MANAGE_INVENTORY" /> - </permissionActivatorSet> + </globalPermissionActivatorSet> </menuItem> </perspectivePlugin> \ No newline at end of file
commit e12ab413ab3e123e9a134aecc02c6501252af898 Author: John Sanda john@localhost.localdomain Date: Fri Dec 4 17:00:10 2009 -0500
Adding a script to the dbutils build for "resetting" the database
If you set the system property 'dbreset' when you run the dbutils build as follows,
$ mvn install -Ddbreset
that will trigger a script to run which will drop and recreate the database. The script also sets the 'dbsetup' property so that the database will be reinitialized.
diff --git a/etc/m2/settings-rawconfig.xml b/etc/m2/settings-rawconfig.xml index 373a72b..f871d66 100644 --- a/etc/m2/settings-rawconfig.xml +++ b/etc/m2/settings-rawconfig.xml @@ -28,6 +28,7 @@ <!-- Profile to use to point test runs at a different db --> <id>test.rawconfig</id> <properties> + <rhq.test.ds.db-name>rhqrawconfig</rhq.test.ds.db-name> <rhq.test.ds.connection-url>jdbc:postgresql://127.0.0.1:5432/rhqrawconfig</rhq.test.ds.connection-url> <DatabaseTest.nofail>true</DatabaseTest.nofail>
diff --git a/modules/core/dbutils/pom.xml b/modules/core/dbutils/pom.xml index 83fa2a2..708f7d0 100644 --- a/modules/core/dbutils/pom.xml +++ b/modules/core/dbutils/pom.xml @@ -67,6 +67,50 @@
<build> <plugins> + <plugin> + <groupId>org.codehaus.groovy.maven</groupId> + <artifactId>gmaven-plugin</artifactId> + <version>1.0</version> + <dependencies> + <dependency> + <groupId>postgresql</groupId> + <artifactId>postgresql</artifactId> + <version>${postgresql.version}</version> + </dependency> + </dependencies> + <executions> + <execution> + <phase>test</phase> + <goals> + <goal>execute</goal> + </goals> + <configuration> + <source> + import org.postgresql.Driver + import groovy.sql.Sql + + if (!project.properties.dbreset) { + return + } + + database = project.properties['rhq.test.ds.db-name'] + project.properties.dbsetup = 'true' + + sql = Sql.newInstance( + "jdbc:postgresql://127.0.0.1:5432/postgres", + "postgres", + "postgres", + "org.postgresql.Driver") + + sql.execute("drop database if exists ${Sql.expand(database)};") + log.info("dropped database $database") + sql.execute("create database ${Sql.expand(database)} with owner rhqadmin;") + log.info("created database $database") + </source> + </configuration> + </execution> + </executions> + </plugin>
<plugin> <artifactId>maven-antrun-plugin</artifactId>
commit 6bfea798e97749db28830283ef345ab99c9d33cc Merge: 7409a2f... 70ba70e... Author: Jay Shaughnessy jshaughn@redhat.com Date: Fri Dec 4 16:13:00 2009 -0500
Merge branch 'linux-config' into linux-config-dev
Conflicts: etc/eclipse-tools/templates/schema.xmlcatalog modules/enterprise/gui/portal-war/src/main/webapp/admin/test/control.jsp
diff --cc etc/eclipse-tools/templates/schema.xmlcatalog index b316ba2,d4054bb..64b4f53 --- a/etc/eclipse-tools/templates/schema.xmlcatalog +++ b/etc/eclipse-tools/templates/schema.xmlcatalog @@@ -1,7 -1,11 +1,12 @@@ -<?xml version="1.0" encoding="UTF-8"?> -<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog"> -<uri name="urn:xmlns:rhq-configuration" uri="platform:/resource/rhq/modules/core/client-api/src/main/resources/rhq-configuration.xsd"/> -<uri name="urn:xmlns:rhq-plugin" uri="platform:/resource/rhq/modules/core/client-api/src/main/resources/rhq-plugin.xsd"/> -<uri name="urn:xmlns:rhq-contentsource-packagedetails" uri="platform:/resource/rhq/modules/enterprise/server/xml-schemas/src/main/resources/rhq-contentsource-packagedetails.xsd"/> -<uri name="urn:xmlns:rhq-serverplugin" uri="platform:/resource/rhq/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin.xsd"/> -<uri name="urn:xmlns:rhq-serverplugin.generic" uri="platform:/resource/rhq/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-generic.xsd"/> -<uri name="urn:xmlns:rhq-serverplugin.alert" uri="platform:/resource/rhq/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-alert.xsd"/> -<uri name="urn:xmlns:rhq-serverplugin.content" uri="platform:/resource/rhq/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-content.xsd"/> -<uri name="urn:xmlns:rhq-serverplugin.perspective" uri="platform:/resource/rhq/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-perspective.xsd"/> -</catalog> +<?xml version="1.0" encoding="UTF-8"?> +<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog"> +<uri name="urn:xmlns:rhq-configuration" uri="platform:/resource/rhq/modules/core/client-api/src/main/resources/rhq-configuration.xsd"/> +<uri name="urn:xmlns:rhq-plugin" uri="platform:/resource/rhq/modules/core/client-api/src/main/resources/rhq-plugin.xsd"/> - <uri name="urn:xmlns:rhq-serverplugin.content" uri="platform:/resource/rhq/modules/core/client-api/src/main/resources/rhq-serverplugin-content.xsd"/> - <uri name="urn:xmlns:rhq-perspective" uri="platform:/resource/rhq/modules/core/client-api/src/main/resources/rhq-perspective.xsd"/> ++<uri name="urn:xmlns:rhq-contentsource-packagedetails" uri="platform:/resource/rhq/modules/enterprise/server/xml-schemas/src/main/resources/rhq-contentsource-packagedetails.xsd"/> ++<uri name="urn:xmlns:rhq-serverplugin" uri="platform:/resource/rhq/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin.xsd"/> ++<uri name="urn:xmlns:rhq-serverplugin.generic" uri="platform:/resource/rhq/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-generic.xsd"/> ++<uri name="urn:xmlns:rhq-serverplugin.alert" uri="platform:/resource/rhq/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-alert.xsd"/> ++<uri name="urn:xmlns:rhq-serverplugin.content" uri="platform:/resource/rhq/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-content.xsd"/> ++<uri name="urn:xmlns:rhq-serverplugin.perspective" uri="platform:/resource/rhq/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-perspective.xsd"/> +</catalog> ++ diff --cc modules/enterprise/gui/portal-war/src/main/webapp/admin/test/control.jsp index 35ad895,25f3e25..9ba6f5b --- a/modules/enterprise/gui/portal-war/src/main/webapp/admin/test/control.jsp +++ b/modules/enterprise/gui/portal-war/src/main/webapp/admin/test/control.jsp @@@ -24,6 -24,9 +24,9 @@@ <%@ page import="org.rhq.enterprise.server.system.SystemManagerLocal" %> <%@ page import="org.rhq.enterprise.server.auth.SubjectManagerLocal" %> <%@ page import="org.rhq.enterprise.server.support.SupportManagerLocal" %> -<%@page import="org.rhq.enterprise.server.plugin.ServerPluginsLocal"%> -<%@page import="org.rhq.core.domain.plugin.PluginKey"%> -<%@page import="org.rhq.core.domain.plugin.PluginDeploymentType"%><html> ++<%@ page import="org.rhq.enterprise.server.plugin.ServerPluginsLocal"%> ++<%@ page import="org.rhq.core.domain.plugin.PluginKey"%> ++<%@ page import="org.rhq.core.domain.plugin.PluginDeploymentType"%><html> <%@ page import="org.rhq.enterprise.server.util.LookupUtil" %> <%@ page import="org.rhq.enterprise.server.scheduler.jobs.DataPurgeJob"%>
commit 7409a2ff73dfc834210171a7f757fed6042e3c16 Author: Jay Shaughnessy jshaughn@redhat.com Date: Fri Dec 4 16:05:32 2009 -0500
Files git is forcing me to commit, I think due to line termination issue.
diff --git a/etc/eclipse-tools/templates/schema.xmlcatalog b/etc/eclipse-tools/templates/schema.xmlcatalog index 3107878..b316ba2 100644 --- a/etc/eclipse-tools/templates/schema.xmlcatalog +++ b/etc/eclipse-tools/templates/schema.xmlcatalog @@ -1,7 +1,7 @@ -<?xml version="1.0" encoding="UTF-8"?> -<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog"> -<uri name="urn:xmlns:rhq-configuration" uri="platform:/resource/rhq/modules/core/client-api/src/main/resources/rhq-configuration.xsd"/> -<uri name="urn:xmlns:rhq-plugin" uri="platform:/resource/rhq/modules/core/client-api/src/main/resources/rhq-plugin.xsd"/> -<uri name="urn:xmlns:rhq-serverplugin.content" uri="platform:/resource/rhq/modules/core/client-api/src/main/resources/rhq-serverplugin-content.xsd"/> -<uri name="urn:xmlns:rhq-perspective" uri="platform:/resource/rhq/modules/core/client-api/src/main/resources/rhq-perspective.xsd"/> -</catalog> +<?xml version="1.0" encoding="UTF-8"?> +<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog"> +<uri name="urn:xmlns:rhq-configuration" uri="platform:/resource/rhq/modules/core/client-api/src/main/resources/rhq-configuration.xsd"/> +<uri name="urn:xmlns:rhq-plugin" uri="platform:/resource/rhq/modules/core/client-api/src/main/resources/rhq-plugin.xsd"/> +<uri name="urn:xmlns:rhq-serverplugin.content" uri="platform:/resource/rhq/modules/core/client-api/src/main/resources/rhq-serverplugin-content.xsd"/> +<uri name="urn:xmlns:rhq-perspective" uri="platform:/resource/rhq/modules/core/client-api/src/main/resources/rhq-perspective.xsd"/> +</catalog> diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/admin/test/control.jsp b/modules/enterprise/gui/portal-war/src/main/webapp/admin/test/control.jsp index f3f0a35..35ad895 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/admin/test/control.jsp +++ b/modules/enterprise/gui/portal-war/src/main/webapp/admin/test/control.jsp @@ -1,378 +1,378 @@ -<%@ page import="java.io.ByteArrayOutputStream" %> -<%@ page import="java.io.PrintStream" %> - -<%@ page import="org.rhq.core.domain.auth.Subject" %> -<%@ page import="org.rhq.core.domain.util.PersistenceUtility" %> - -<%@ page import="org.rhq.enterprise.gui.legacy.util.SessionUtils"%> -<%@ page import="org.rhq.enterprise.gui.util.WebUtility"%> - -<%@ page import="org.rhq.enterprise.server.measurement.MeasurementPreferences" %> -<%@ page import="org.rhq.enterprise.server.measurement.MeasurementPreferences.MetricRangePreferences" %> - -<%@ page import="org.rhq.enterprise.server.test.CoreTestLocal" %> -<%@ page import="org.rhq.enterprise.server.test.DiscoveryTestLocal" %> -<%@ page import="org.rhq.enterprise.server.test.MeasurementTestLocal" %> -<%@ page import="org.rhq.enterprise.server.test.ResourceGroupTestBeanLocal" %> -<%@ page import="org.rhq.enterprise.server.test.SubjectRoleTestBeanLocal" %> -<%@ page import="org.rhq.enterprise.server.test.AlertTemplateTestLocal" %> -<%@ page import="org.rhq.enterprise.server.cloud.instance.ServerManagerLocal" %> -<%@ page import="org.rhq.enterprise.server.test.ResourceGroupTestBeanLocal" %> -<%@ page import="org.rhq.enterprise.server.measurement.MeasurementBaselineManagerLocal" %> -<%@ page import="org.rhq.enterprise.server.measurement.MeasurementScheduleManagerLocal" %> -<%@ page import="org.rhq.enterprise.server.core.AgentManagerLocal" %> -<%@ page import="org.rhq.enterprise.server.system.SystemManagerLocal" %> -<%@ page import="org.rhq.enterprise.server.auth.SubjectManagerLocal" %> -<%@ page import="org.rhq.enterprise.server.support.SupportManagerLocal" %> -<%@ page import="org.rhq.enterprise.server.util.LookupUtil" %> -<%@ page import="org.rhq.enterprise.server.scheduler.jobs.DataPurgeJob"%> - -<%@ page import="org.rhq.enterprise.server.resource.ResourceTypeManagerRemote"%> -<%@ page import="org.rhq.core.domain.criteria.ResourceTypeCriteria"%> -<%@ page import="org.rhq.core.domain.resource.ResourceType"%> - -<%@ page import="javax.naming.NamingException" %> - -<%@ page contentType="text/html;charset=UTF-8" language="java" %> -<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %> -<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> - -<html> -<head><title>RHQ Test Control Page</title></head> -<body> - -<jsp:include page="/admin/include/adminTestLinks.html" flush="true" /> - -<% - CoreTestLocal coreTestBean; - DiscoveryTestLocal discoveryTestBean; - MeasurementTestLocal measurementTestBean; - ResourceGroupTestBeanLocal resourceGroupTestBean; - SubjectRoleTestBeanLocal subjectRoleTestBean; - ServerManagerLocal serverManager; - AlertTemplateTestLocal alertTemplateTestBean; - MeasurementBaselineManagerLocal measurementBaselineManager; - MeasurementScheduleManagerLocal measurementScheduleManager; - AgentManagerLocal agentManager; - SystemManagerLocal systemManager; - SubjectManagerLocal subjectManager; - SupportManagerLocal supportManager; - ResourceTypeManagerRemote typeManager; - - coreTestBean = LookupUtil.getCoreTest(); - discoveryTestBean = LookupUtil.getDiscoveryTest(); - measurementTestBean = LookupUtil.getMeasurementTest(); - resourceGroupTestBean = LookupUtil.getResourceGroupTestBean(); - subjectRoleTestBean = LookupUtil.getSubjectRoleTestBean(); - serverManager = LookupUtil.getServerManager(); - alertTemplateTestBean = LookupUtil.getAlertTemplateTestBean(); - measurementBaselineManager = LookupUtil.getMeasurementBaselineManager(); - measurementScheduleManager = LookupUtil.getMeasurementScheduleManager(); - agentManager = LookupUtil.getAgentManager(); - systemManager = LookupUtil.getSystemManager(); - subjectManager = LookupUtil.getSubjectManager(); - supportManager = LookupUtil.getSupportManager(); - typeManager = LookupUtil.getResourceTypeManagerRemote(); - - String result = null; - String mode = pageContext.getRequest().getParameter("mode"); - String failure = null; - try - { - if ("registerTestAgent".equals(mode)) - { - coreTestBean.registerTestAgent(); - } - else if ("registerTestPluginAndTypeInfo".equals(mode)) - { - discoveryTestBean.registerTestPluginAndTypeInfo(); - } - else if ("removeTestPluginAndTypeInfo".equals(mode)) - { - discoveryTestBean.removeTestPluginAndTypeInfo(); - } - else if ("sendTestFullInventoryReport".equals(mode)) - { - discoveryTestBean.sendTestFullInventoryReport(); - } - else if ("sendTestRuntimeInventoryReport".equals(mode)) - { - discoveryTestBean.sendTestRuntimeInventoryReport(); - } - else if ("sendTestMeasurementReport".equals(mode)) - { - measurementTestBean.sendTestMeasurementReport(); - } - else if ("sendNewPlatform".equals(mode)) - { - String address = request.getParameter("address"); - int servers = Integer.parseInt(request.getParameter("servers")); - int servicesPerServer = Integer.parseInt(request.getParameter("servicesPerServer")); - discoveryTestBean.sendNewPlatform(address, servers, servicesPerServer); - } - else if ("setupCompatibleGroups".equals(mode)) - { - resourceGroupTestBean.setupCompatibleGroups(); - } - else if ("setupUberMixedGroup".equals(mode)) - { - resourceGroupTestBean.setupUberMixedGroup(); - } - else if ("startStats".equals(mode)) - { - coreTestBean.enableHibernateStatistics(); - } - else if ("addProblemResource".equals(mode)) - { - measurementTestBean.addProblemResource(); - } - else if ("setAgentCurrentlyScheduledMetrics".equals(mode)) - { - String value = pageContext.getRequest().getParameter("v"); - measurementTestBean.setAgentCurrentlyScheduledMetrics(Double.valueOf(value)); - } - else if ("addSubjectsAndRoles".equals(mode)) - { - String roleCount = pageContext.getRequest().getParameter("roleCount"); - String usersInRoleCount = pageContext.getRequest().getParameter("usersInRoleCount"); - subjectRoleTestBean.createRolesAndUsers(Integer.parseInt(roleCount), Integer.parseInt(usersInRoleCount)); - } - else if ("clusterGetIdentity".equals(mode)) - { - String serverName = serverManager.getIdentity(); - pageContext.setAttribute("serverName", "(serverName = " + serverName + ")"); - } - else if ("cloneAlertTemplate".equals(mode)) - { - String alertTemplateId = pageContext.getRequest().getParameter("alertTemplateId"); - String numberOfClones = pageContext.getRequest().getParameter("numberOfClones"); - alertTemplateTestBean.cloneAlertTemplate(Integer.parseInt(alertTemplateId), Integer.parseInt(numberOfClones)); - } - else if ("calculateAutoBaselines".equals(mode)) - { - // for now, baselines aren't calculated until we hit our day limit, we force it here - java.util.Properties props = systemManager.getSystemConfiguration(); - props.put("CAM_BASELINE_LASTTIME", "0"); - systemManager.setSystemConfiguration(subjectManager.getOverlord(), props,true); - - measurementBaselineManager.calculateAutoBaselines(); - } - else if ("calculateOOBs".equals(mode)) - { - DataPurgeJob dpj = new DataPurgeJob(); - dpj.calculateOOBs(); - } - else if ("checkForSuspectAgents".equals(mode)) - { - agentManager.checkForSuspectAgents(); - } - else if ("dataPurgeJob".equals(mode)) - { - DataPurgeJob.purgeNow(); - } - else if ("dbMaintenance".equals(mode)) - { - systemManager.vacuum(subjectManager.getOverlord()); - systemManager.reindex(subjectManager.getOverlord()); - systemManager.analyze(subjectManager.getOverlord()); - } - else if ("metricDisplayRange".equals(mode)) - { - int lastHours = Integer.parseInt(pageContext.getRequest().getParameter("lastHours")); - Subject subject = WebUtility.getSubject(request); - MeasurementPreferences prefs = new MeasurementPreferences(subject); - MetricRangePreferences rangePrefs = prefs.getMetricRangePreferences(); - rangePrefs.lastN = lastHours; - prefs.setMetricRangePreferences(rangePrefs); - } - else if ("errorCorrectSchedules".equals("mode")) - { - measurementScheduleManager.errorCorrectSchedules(); - } - else if ("generateSnapshotReport".equals(mode)) - { - int resourceId = Integer.parseInt(request.getParameter("resourceId")); - String name = request.getParameter("name"); - String description = request.getParameter("description"); - java.net.URL url = supportManager.getSnapshotReport(subjectManager.getOverlord(), resourceId, name, description); - result = "Snapshot Report is located here: " + url.toString(); - } - else if ("typeManagerRemote".equals(mode)) - { - int typeId = Integer.parseInt(request.getParameter("typeId")); - ResourceTypeCriteria criteria = new ResourceTypeCriteria(); - criteria.addFilterId(typeId); - criteria.fetchMetricDefinitions(true); - java.util.List<ResourceType> types = typeManager.findResourceTypesByCriteria(subjectManager.getOverlord(), criteria); - result = ""; - for (ResourceType type : types) { - result += type.getName() + " has " + (type.getMetricDefinitions() != null ? type.getMetricDefinitions().size() : "empty") + " metric definitions"; - } - } - } - catch (Exception e) - { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - e.printStackTrace(new PrintStream(baos)); - failure = baos.toString(); - } - - pageContext.setAttribute("executed", mode); - pageContext.setAttribute("result", result); - pageContext.setAttribute("failure", failure); - pageContext.setAttribute("testAgentReported", Boolean.valueOf(coreTestBean.isTestAgentReported())); - -%> - -<c:if test="${executed != null}"> - <b>Executed <c:out value="${executed}"/>: </b> <c:out value="${result}"/><br> - <c:if test="${failure != null}"> - <pre style="background-color: yellow;"><c:out value="${failure}"/></pre> - </c:if> -</c:if> - -<h2>Administration</h2> - -<c:url var="url" value="/admin/test/control.jsp?mode=addSubjectsAndRoles"/> -Add Lots of Users and Roles -<form action="<c:out value="${url}"/>" method="get"> - <input type="hidden" name="mode" value="addSubjectsAndRoles"/> - Number of Roles: <input type="text" name="roleCount" size="5"/><br/> - Number of Users in each Role: <input type="text" name="usersInRoleCount" size="5"/><br/> - <input type="submit" value="Send" name="Send"/> -</form> - - -<ul> - <li><c:url var="url" value="/admin/test/control.jsp?mode=addSubjectsAndRoles"/> - <a href="<c:out value="${url}"/>">Report Test Agent</a> (done = <c:out value="${testAgentReported}"/>)</li> - <li><c:url var="url" value="/admin/test/control.jsp?mode=registerTestPluginAndTypeInfo"/> - <a href="<c:out value="${url}"/>">Register test plugin metadata</a></li> - <li><c:url var="url" value="/admin/test/control.jsp?mode=removeTestPluginAndTypeInfo"/> - <a href="<c:out value="${url}"/>">Remove test plugin metadata</a></li> -</ul> - -<h2>Core</h2> - -<ul> - <li><c:url var="url" value="/admin/test/control.jsp?mode=registerTestAgent"/> - <a href="<c:out value="${url}"/>">Report Test Agent</a> (done = <c:out value="${testAgentReported}"/>)</li> - <li><c:url var="url" value="/admin/test/control.jsp?mode=registerTestPluginAndTypeInfo"/> - <a href="<c:out value="${url}"/>">Register test plugin metadata</a></li> - <li><c:url var="url" value="/admin/test/control.jsp?mode=removeTestPluginAndTypeInfo"/> - <a href="<c:out value="${url}"/>">Remove test plugin metadata</a></li> - <li><c:url var="url" value="/admin/test/control.jsp?mode=dbMaintenance"/> - <a href="<c:out value="${url}"/>">Perform All Database Maintenance Now</a></li> -</ul> - -<h2>Cluster</h2> - -<ul> - <li><c:url var="url" value="/admin/test/control.jsp?mode=clusterGetIdentity"/> - <a href="<c:out value="${url}"/>">Get Identity</a> <c:out value="${serverName}"/></li> -</ul> - -<h2>Inventory</h2> - -<ul> - <li><c:url var="url" value="/admin/test/control.jsp?mode=sendTestFullInventoryReport"/> - <a href="<c:out value="${url}"/>">Send Full Inventory Report</a></li> - <li><c:url var="url" value="/admin/test/control.jsp?mode=sendTestRuntimeInventoryReport"/> - <a href="<c:out value="${url}"/>">Send Runtime Inventory Report</a></li> - <li><c:url var="url" value="/admin/test/control.jsp?mode=setupCompatibleGroups"/> - <a href="<c:out value="${url}"/>">Setup Compatible Groups</a></li> - <li><c:url var="url" value="/admin/test/control.jsp?mode=setupUberMixedGroup"/> - <a href="<c:out value="${url}"/>">Setup Uber Mixed Group</a></li> -</ul> - -<c:url var="url" value="/admin/test/control.jsp?mode=sendNewPlatform"/> -Send New Platform Inventory Report -<form action="<c:out value="${url}"/>" method="get"> - <input type="hidden" name="mode" value="sendNewPlatform"/> - Address: <input type="text" name="address" size="30"/><br/> - Servers: <input type="text" name="servers" size="5"/><br/> - Services Per Server: <input type="text" name="servicesPerServer" size="5"/><br/> - <input type="submit" value="Send" name="Send"/> -</form> - - -<h2>Measurement</h2> - -<ul> - <li><c:url var="url" value="/admin/test/control.jsp?mode=calculateAutoBaselines"/> - <a href="<c:out value="${url}"/>">Calculate Auto Baselines</a></li> - <li><c:url var="url" value="/admin/test/control.jsp?mode=sendTestMeasurementReport"/> - <a href="<c:out value="${url}"/>">Send Measurement Report</a></li> - <li><c:url var="url" value="/admin/test/control.jsp?mode=addProblemResource"/> - <a href="<c:out value="${url}"/>">Add problem Resource</a></li> - <li><c:url var="url" value="/admin/test/control.jsp?mode=setAgentCurrentlyScheduledMetrics&v=100"/> - <a href="<c:out value="${url}"/>">Set RHQ Agent 'CurrentlyScheduleMetrics' to 100</a></li> - <li><c:url var="url" value="/admin/test/control.jsp?mode=setAgentCurrentlyScheduledMetrics&v=50"/> - <a href="<c:out value="${url}"/>">Set RHQ Agent 'CurrentlyScheduleMetrics' to 50</a></li> - <li><c:url var="url" value="/admin/test/control.jsp?mode=checkForSuspectAgents"/> - <a href="<c:out value="${url}"/>">Check For Suspect Agents</a></li> - <li><c:url var="url" value="/admin/test/control.jsp?mode=dataPurgeJob"/> - <a href="<c:out value="${url}"/>">Force Data Purge Now</a></li> - <li><c:url var="url" value="/admin/test/control.jsp?mode=calculateOOBs"/> - <a href="<c:out value="${url}"/>">Force calculation of OOBs</a></li> - <li><c:url var="url" value="/admin/test/control.jsp?mode=errorCorrectSchedules"/> - <a href="<c:out value="${url}"/>">Error-Correct Measurement Schedules</a></li> -</ul> - -<h2>Alerts</h2> - -<c:url var="url" value="/admin/test/control.jsp?mode=cloneAlertTemplate"/> -Template Cloning -<form action="<c:out value="${url}"/>" method="get"> - <input type="hidden" name="mode" value="cloneAlertTemplate"/> - Alert Template ID: <input type="text" name="alertTemplateId" size="5"/><br/> - Number of Clones: <input type="text" name="numberOfClones" size="5"/><br/> - <input type="submit" value="Send" name="Send"/> -</form> - -<h2>Utilities</h2> -<ul> - <li><c:url var="url" value="/admin/test/control.jsp?mode=startStats"/> - <a href="<c:out value="${url}"/>">Start Hibernate Statistics Collection</a></li> -</ul> - - -<h2>User Preferences</h2> -<% - Subject subject = WebUtility.getSubject(request); - MeasurementPreferences prefs = new MeasurementPreferences(subject); - MetricRangePreferences rangePrefs = prefs.getMetricRangePreferences(); - pageContext.setAttribute("lastHours", String.valueOf(rangePrefs.lastN)); -%> -<form action="<c:out value="${url}"/>" method="get"> - <input type="hidden" name="mode" value="metricDisplayRange"/> - Last X hours: <input type="text" name="lastHours" size="5" value="<c:out value="${lastHours}"/>"/><br/> - <input type="submit" value="Send" name="Send"/> -</form> - -<h2>Snapshot Report</h2> - -<c:url var="url" value="/admin/test/control.jsp?mode=generateSnapshotReport"/> -Generate Snapshot Report -<form action="<c:out value="${url}"/>" method="get"> - <input type="hidden" name="mode" value="generateSnapshotReport"/> - Resource ID: <input type="text" name="resourceId" size="10"/><br/> - Name: <input type="text" name="name" size="30"/><br/> - Description: <input type="text" name="description" size="100"/><br/> - <input type="submit" value="Generate Snapshot" name="Generate Snapshot"/> -</form> - -<h2>Resource Type Criteria</h2> - -<c:url var="url" value="/admin/test/control.jsp?mode=typeManagerRemote"/> -Query ResourceTypes by Criteria -<form action="<c:out value="${url}"/>" method="get"> - <input type="hidden" name="mode" value="typeManagerRemote"/> - ResourceType ID: <input type="text" name="typeId" size="10"/><br/> - <input type="submit" value="Query by Criteria" name="Query by Criteria"/> -</form> - - - -</body> -</html> +<%@ page import="java.io.ByteArrayOutputStream" %> +<%@ page import="java.io.PrintStream" %> + +<%@ page import="org.rhq.core.domain.auth.Subject" %> +<%@ page import="org.rhq.core.domain.util.PersistenceUtility" %> + +<%@ page import="org.rhq.enterprise.gui.legacy.util.SessionUtils"%> +<%@ page import="org.rhq.enterprise.gui.util.WebUtility"%> + +<%@ page import="org.rhq.enterprise.server.measurement.MeasurementPreferences" %> +<%@ page import="org.rhq.enterprise.server.measurement.MeasurementPreferences.MetricRangePreferences" %> + +<%@ page import="org.rhq.enterprise.server.test.CoreTestLocal" %> +<%@ page import="org.rhq.enterprise.server.test.DiscoveryTestLocal" %> +<%@ page import="org.rhq.enterprise.server.test.MeasurementTestLocal" %> +<%@ page import="org.rhq.enterprise.server.test.ResourceGroupTestBeanLocal" %> +<%@ page import="org.rhq.enterprise.server.test.SubjectRoleTestBeanLocal" %> +<%@ page import="org.rhq.enterprise.server.test.AlertTemplateTestLocal" %> +<%@ page import="org.rhq.enterprise.server.cloud.instance.ServerManagerLocal" %> +<%@ page import="org.rhq.enterprise.server.test.ResourceGroupTestBeanLocal" %> +<%@ page import="org.rhq.enterprise.server.measurement.MeasurementBaselineManagerLocal" %> +<%@ page import="org.rhq.enterprise.server.measurement.MeasurementScheduleManagerLocal" %> +<%@ page import="org.rhq.enterprise.server.core.AgentManagerLocal" %> +<%@ page import="org.rhq.enterprise.server.system.SystemManagerLocal" %> +<%@ page import="org.rhq.enterprise.server.auth.SubjectManagerLocal" %> +<%@ page import="org.rhq.enterprise.server.support.SupportManagerLocal" %> +<%@ page import="org.rhq.enterprise.server.util.LookupUtil" %> +<%@ page import="org.rhq.enterprise.server.scheduler.jobs.DataPurgeJob"%> + +<%@ page import="org.rhq.enterprise.server.resource.ResourceTypeManagerRemote"%> +<%@ page import="org.rhq.core.domain.criteria.ResourceTypeCriteria"%> +<%@ page import="org.rhq.core.domain.resource.ResourceType"%> + +<%@ page import="javax.naming.NamingException" %> + +<%@ page contentType="text/html;charset=UTF-8" language="java" %> +<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %> +<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> + +<html> +<head><title>RHQ Test Control Page</title></head> +<body> + +<jsp:include page="/admin/include/adminTestLinks.html" flush="true" /> + +<% + CoreTestLocal coreTestBean; + DiscoveryTestLocal discoveryTestBean; + MeasurementTestLocal measurementTestBean; + ResourceGroupTestBeanLocal resourceGroupTestBean; + SubjectRoleTestBeanLocal subjectRoleTestBean; + ServerManagerLocal serverManager; + AlertTemplateTestLocal alertTemplateTestBean; + MeasurementBaselineManagerLocal measurementBaselineManager; + MeasurementScheduleManagerLocal measurementScheduleManager; + AgentManagerLocal agentManager; + SystemManagerLocal systemManager; + SubjectManagerLocal subjectManager; + SupportManagerLocal supportManager; + ResourceTypeManagerRemote typeManager; + + coreTestBean = LookupUtil.getCoreTest(); + discoveryTestBean = LookupUtil.getDiscoveryTest(); + measurementTestBean = LookupUtil.getMeasurementTest(); + resourceGroupTestBean = LookupUtil.getResourceGroupTestBean(); + subjectRoleTestBean = LookupUtil.getSubjectRoleTestBean(); + serverManager = LookupUtil.getServerManager(); + alertTemplateTestBean = LookupUtil.getAlertTemplateTestBean(); + measurementBaselineManager = LookupUtil.getMeasurementBaselineManager(); + measurementScheduleManager = LookupUtil.getMeasurementScheduleManager(); + agentManager = LookupUtil.getAgentManager(); + systemManager = LookupUtil.getSystemManager(); + subjectManager = LookupUtil.getSubjectManager(); + supportManager = LookupUtil.getSupportManager(); + typeManager = LookupUtil.getResourceTypeManagerRemote(); + + String result = null; + String mode = pageContext.getRequest().getParameter("mode"); + String failure = null; + try + { + if ("registerTestAgent".equals(mode)) + { + coreTestBean.registerTestAgent(); + } + else if ("registerTestPluginAndTypeInfo".equals(mode)) + { + discoveryTestBean.registerTestPluginAndTypeInfo(); + } + else if ("removeTestPluginAndTypeInfo".equals(mode)) + { + discoveryTestBean.removeTestPluginAndTypeInfo(); + } + else if ("sendTestFullInventoryReport".equals(mode)) + { + discoveryTestBean.sendTestFullInventoryReport(); + } + else if ("sendTestRuntimeInventoryReport".equals(mode)) + { + discoveryTestBean.sendTestRuntimeInventoryReport(); + } + else if ("sendTestMeasurementReport".equals(mode)) + { + measurementTestBean.sendTestMeasurementReport(); + } + else if ("sendNewPlatform".equals(mode)) + { + String address = request.getParameter("address"); + int servers = Integer.parseInt(request.getParameter("servers")); + int servicesPerServer = Integer.parseInt(request.getParameter("servicesPerServer")); + discoveryTestBean.sendNewPlatform(address, servers, servicesPerServer); + } + else if ("setupCompatibleGroups".equals(mode)) + { + resourceGroupTestBean.setupCompatibleGroups(); + } + else if ("setupUberMixedGroup".equals(mode)) + { + resourceGroupTestBean.setupUberMixedGroup(); + } + else if ("startStats".equals(mode)) + { + coreTestBean.enableHibernateStatistics(); + } + else if ("addProblemResource".equals(mode)) + { + measurementTestBean.addProblemResource(); + } + else if ("setAgentCurrentlyScheduledMetrics".equals(mode)) + { + String value = pageContext.getRequest().getParameter("v"); + measurementTestBean.setAgentCurrentlyScheduledMetrics(Double.valueOf(value)); + } + else if ("addSubjectsAndRoles".equals(mode)) + { + String roleCount = pageContext.getRequest().getParameter("roleCount"); + String usersInRoleCount = pageContext.getRequest().getParameter("usersInRoleCount"); + subjectRoleTestBean.createRolesAndUsers(Integer.parseInt(roleCount), Integer.parseInt(usersInRoleCount)); + } + else if ("clusterGetIdentity".equals(mode)) + { + String serverName = serverManager.getIdentity(); + pageContext.setAttribute("serverName", "(serverName = " + serverName + ")"); + } + else if ("cloneAlertTemplate".equals(mode)) + { + String alertTemplateId = pageContext.getRequest().getParameter("alertTemplateId"); + String numberOfClones = pageContext.getRequest().getParameter("numberOfClones"); + alertTemplateTestBean.cloneAlertTemplate(Integer.parseInt(alertTemplateId), Integer.parseInt(numberOfClones)); + } + else if ("calculateAutoBaselines".equals(mode)) + { + // for now, baselines aren't calculated until we hit our day limit, we force it here + java.util.Properties props = systemManager.getSystemConfiguration(); + props.put("CAM_BASELINE_LASTTIME", "0"); + systemManager.setSystemConfiguration(subjectManager.getOverlord(), props,true); + + measurementBaselineManager.calculateAutoBaselines(); + } + else if ("calculateOOBs".equals(mode)) + { + DataPurgeJob dpj = new DataPurgeJob(); + dpj.calculateOOBs(); + } + else if ("checkForSuspectAgents".equals(mode)) + { + agentManager.checkForSuspectAgents(); + } + else if ("dataPurgeJob".equals(mode)) + { + DataPurgeJob.purgeNow(); + } + else if ("dbMaintenance".equals(mode)) + { + systemManager.vacuum(subjectManager.getOverlord()); + systemManager.reindex(subjectManager.getOverlord()); + systemManager.analyze(subjectManager.getOverlord()); + } + else if ("metricDisplayRange".equals(mode)) + { + int lastHours = Integer.parseInt(pageContext.getRequest().getParameter("lastHours")); + Subject subject = WebUtility.getSubject(request); + MeasurementPreferences prefs = new MeasurementPreferences(subject); + MetricRangePreferences rangePrefs = prefs.getMetricRangePreferences(); + rangePrefs.lastN = lastHours; + prefs.setMetricRangePreferences(rangePrefs); + } + else if ("errorCorrectSchedules".equals("mode")) + { + measurementScheduleManager.errorCorrectSchedules(); + } + else if ("generateSnapshotReport".equals(mode)) + { + int resourceId = Integer.parseInt(request.getParameter("resourceId")); + String name = request.getParameter("name"); + String description = request.getParameter("description"); + java.net.URL url = supportManager.getSnapshotReport(subjectManager.getOverlord(), resourceId, name, description); + result = "Snapshot Report is located here: " + url.toString(); + } + else if ("typeManagerRemote".equals(mode)) + { + int typeId = Integer.parseInt(request.getParameter("typeId")); + ResourceTypeCriteria criteria = new ResourceTypeCriteria(); + criteria.addFilterId(typeId); + criteria.fetchMetricDefinitions(true); + java.util.List<ResourceType> types = typeManager.findResourceTypesByCriteria(subjectManager.getOverlord(), criteria); + result = ""; + for (ResourceType type : types) { + result += type.getName() + " has " + (type.getMetricDefinitions() != null ? type.getMetricDefinitions().size() : "empty") + " metric definitions"; + } + } + } + catch (Exception e) + { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + e.printStackTrace(new PrintStream(baos)); + failure = baos.toString(); + } + + pageContext.setAttribute("executed", mode); + pageContext.setAttribute("result", result); + pageContext.setAttribute("failure", failure); + pageContext.setAttribute("testAgentReported", Boolean.valueOf(coreTestBean.isTestAgentReported())); + +%> + +<c:if test="${executed != null}"> + <b>Executed <c:out value="${executed}"/>: </b> <c:out value="${result}"/><br> + <c:if test="${failure != null}"> + <pre style="background-color: yellow;"><c:out value="${failure}"/></pre> + </c:if> +</c:if> + +<h2>Administration</h2> + +<c:url var="url" value="/admin/test/control.jsp?mode=addSubjectsAndRoles"/> +Add Lots of Users and Roles +<form action="<c:out value="${url}"/>" method="get"> + <input type="hidden" name="mode" value="addSubjectsAndRoles"/> + Number of Roles: <input type="text" name="roleCount" size="5"/><br/> + Number of Users in each Role: <input type="text" name="usersInRoleCount" size="5"/><br/> + <input type="submit" value="Send" name="Send"/> +</form> + + +<ul> + <li><c:url var="url" value="/admin/test/control.jsp?mode=addSubjectsAndRoles"/> + <a href="<c:out value="${url}"/>">Report Test Agent</a> (done = <c:out value="${testAgentReported}"/>)</li> + <li><c:url var="url" value="/admin/test/control.jsp?mode=registerTestPluginAndTypeInfo"/> + <a href="<c:out value="${url}"/>">Register test plugin metadata</a></li> + <li><c:url var="url" value="/admin/test/control.jsp?mode=removeTestPluginAndTypeInfo"/> + <a href="<c:out value="${url}"/>">Remove test plugin metadata</a></li> +</ul> + +<h2>Core</h2> + +<ul> + <li><c:url var="url" value="/admin/test/control.jsp?mode=registerTestAgent"/> + <a href="<c:out value="${url}"/>">Report Test Agent</a> (done = <c:out value="${testAgentReported}"/>)</li> + <li><c:url var="url" value="/admin/test/control.jsp?mode=registerTestPluginAndTypeInfo"/> + <a href="<c:out value="${url}"/>">Register test plugin metadata</a></li> + <li><c:url var="url" value="/admin/test/control.jsp?mode=removeTestPluginAndTypeInfo"/> + <a href="<c:out value="${url}"/>">Remove test plugin metadata</a></li> + <li><c:url var="url" value="/admin/test/control.jsp?mode=dbMaintenance"/> + <a href="<c:out value="${url}"/>">Perform All Database Maintenance Now</a></li> +</ul> + +<h2>Cluster</h2> + +<ul> + <li><c:url var="url" value="/admin/test/control.jsp?mode=clusterGetIdentity"/> + <a href="<c:out value="${url}"/>">Get Identity</a> <c:out value="${serverName}"/></li> +</ul> + +<h2>Inventory</h2> + +<ul> + <li><c:url var="url" value="/admin/test/control.jsp?mode=sendTestFullInventoryReport"/> + <a href="<c:out value="${url}"/>">Send Full Inventory Report</a></li> + <li><c:url var="url" value="/admin/test/control.jsp?mode=sendTestRuntimeInventoryReport"/> + <a href="<c:out value="${url}"/>">Send Runtime Inventory Report</a></li> + <li><c:url var="url" value="/admin/test/control.jsp?mode=setupCompatibleGroups"/> + <a href="<c:out value="${url}"/>">Setup Compatible Groups</a></li> + <li><c:url var="url" value="/admin/test/control.jsp?mode=setupUberMixedGroup"/> + <a href="<c:out value="${url}"/>">Setup Uber Mixed Group</a></li> +</ul> + +<c:url var="url" value="/admin/test/control.jsp?mode=sendNewPlatform"/> +Send New Platform Inventory Report +<form action="<c:out value="${url}"/>" method="get"> + <input type="hidden" name="mode" value="sendNewPlatform"/> + Address: <input type="text" name="address" size="30"/><br/> + Servers: <input type="text" name="servers" size="5"/><br/> + Services Per Server: <input type="text" name="servicesPerServer" size="5"/><br/> + <input type="submit" value="Send" name="Send"/> +</form> + + +<h2>Measurement</h2> + +<ul> + <li><c:url var="url" value="/admin/test/control.jsp?mode=calculateAutoBaselines"/> + <a href="<c:out value="${url}"/>">Calculate Auto Baselines</a></li> + <li><c:url var="url" value="/admin/test/control.jsp?mode=sendTestMeasurementReport"/> + <a href="<c:out value="${url}"/>">Send Measurement Report</a></li> + <li><c:url var="url" value="/admin/test/control.jsp?mode=addProblemResource"/> + <a href="<c:out value="${url}"/>">Add problem Resource</a></li> + <li><c:url var="url" value="/admin/test/control.jsp?mode=setAgentCurrentlyScheduledMetrics&v=100"/> + <a href="<c:out value="${url}"/>">Set RHQ Agent 'CurrentlyScheduleMetrics' to 100</a></li> + <li><c:url var="url" value="/admin/test/control.jsp?mode=setAgentCurrentlyScheduledMetrics&v=50"/> + <a href="<c:out value="${url}"/>">Set RHQ Agent 'CurrentlyScheduleMetrics' to 50</a></li> + <li><c:url var="url" value="/admin/test/control.jsp?mode=checkForSuspectAgents"/> + <a href="<c:out value="${url}"/>">Check For Suspect Agents</a></li> + <li><c:url var="url" value="/admin/test/control.jsp?mode=dataPurgeJob"/> + <a href="<c:out value="${url}"/>">Force Data Purge Now</a></li> + <li><c:url var="url" value="/admin/test/control.jsp?mode=calculateOOBs"/> + <a href="<c:out value="${url}"/>">Force calculation of OOBs</a></li> + <li><c:url var="url" value="/admin/test/control.jsp?mode=errorCorrectSchedules"/> + <a href="<c:out value="${url}"/>">Error-Correct Measurement Schedules</a></li> +</ul> + +<h2>Alerts</h2> + +<c:url var="url" value="/admin/test/control.jsp?mode=cloneAlertTemplate"/> +Template Cloning +<form action="<c:out value="${url}"/>" method="get"> + <input type="hidden" name="mode" value="cloneAlertTemplate"/> + Alert Template ID: <input type="text" name="alertTemplateId" size="5"/><br/> + Number of Clones: <input type="text" name="numberOfClones" size="5"/><br/> + <input type="submit" value="Send" name="Send"/> +</form> + +<h2>Utilities</h2> +<ul> + <li><c:url var="url" value="/admin/test/control.jsp?mode=startStats"/> + <a href="<c:out value="${url}"/>">Start Hibernate Statistics Collection</a></li> +</ul> + + +<h2>User Preferences</h2> +<% + Subject subject = WebUtility.getSubject(request); + MeasurementPreferences prefs = new MeasurementPreferences(subject); + MetricRangePreferences rangePrefs = prefs.getMetricRangePreferences(); + pageContext.setAttribute("lastHours", String.valueOf(rangePrefs.lastN)); +%> +<form action="<c:out value="${url}"/>" method="get"> + <input type="hidden" name="mode" value="metricDisplayRange"/> + Last X hours: <input type="text" name="lastHours" size="5" value="<c:out value="${lastHours}"/>"/><br/> + <input type="submit" value="Send" name="Send"/> +</form> + +<h2>Snapshot Report</h2> + +<c:url var="url" value="/admin/test/control.jsp?mode=generateSnapshotReport"/> +Generate Snapshot Report +<form action="<c:out value="${url}"/>" method="get"> + <input type="hidden" name="mode" value="generateSnapshotReport"/> + Resource ID: <input type="text" name="resourceId" size="10"/><br/> + Name: <input type="text" name="name" size="30"/><br/> + Description: <input type="text" name="description" size="100"/><br/> + <input type="submit" value="Generate Snapshot" name="Generate Snapshot"/> +</form> + +<h2>Resource Type Criteria</h2> + +<c:url var="url" value="/admin/test/control.jsp?mode=typeManagerRemote"/> +Query ResourceTypes by Criteria +<form action="<c:out value="${url}"/>" method="get"> + <input type="hidden" name="mode" value="typeManagerRemote"/> + ResourceType ID: <input type="text" name="typeId" size="10"/><br/> + <input type="submit" value="Query by Criteria" name="Query by Criteria"/> +</form> + + + +</body> +</html>
commit 70ba70e6da9f5f778f1a99eeec56d512c1a7ee16 Merge: 2adb693... 06fa43b... Author: Jay Shaughnessy jshaughn@redhat.com Date: Fri Dec 4 16:03:55 2009 -0500
Merge branch 'linux-config-dev' into linux-config
Conflicts: modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveManagerBean.java
diff --cc modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveManagerBean.java index ac31b33,39a3bda..e99071f --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveManagerBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveManagerBean.java @@@ -31,19 -30,17 +31,16 @@@ import javax.persistence.PersistenceCon
import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; - +import org.jetbrains.annotations.NotNull; + import org.rhq.core.domain.auth.Subject; import org.rhq.core.domain.authz.Permission; +import org.rhq.core.domain.resource.Resource; ++import org.rhq.enterprise.gui.legacy.util.Tab; import org.rhq.enterprise.server.RHQConstants; import org.rhq.enterprise.server.auth.SubjectManagerLocal; import org.rhq.enterprise.server.authz.AuthorizationManagerLocal; - import org.rhq.enterprise.server.xmlschema.generated.serverplugin.perspective.GlobalPermissionActivatorSetType; - import org.rhq.enterprise.server.xmlschema.generated.serverplugin.perspective.GlobalPermissionActivatorType; - import org.rhq.enterprise.server.xmlschema.generated.serverplugin.perspective.GlobalPermissionType; -import org.rhq.enterprise.server.xmlschema.generated.serverplugin.perspective.InventoryActivatorSetType; import org.rhq.enterprise.server.xmlschema.generated.serverplugin.perspective.MenuItemType; - import org.rhq.enterprise.server.xmlschema.generated.serverplugin.perspective.ResourceActivatorSetType; -import org.rhq.enterprise.server.xmlschema.generated.serverplugin.perspective.PermissionActivatorSetType; -import org.rhq.enterprise.server.xmlschema.generated.serverplugin.perspective.PermissionActivatorType; -import org.rhq.enterprise.server.xmlschema.generated.serverplugin.perspective.PermissionType;
@Stateless // @WebService(endpointInterface = "org.rhq.enterprise.server.perspective.PerspectiveManagerRemote") @@@ -68,7 -67,8 +67,7 @@@ public class PerspectiveManagerBean imp
/* (non-Javadoc) * @see org.rhq.enterprise.server.perspective.PerspectiveManagerLocal#getCoreMenu(org.rhq.core.domain.auth.Subject) - */ + */ - @Override public synchronized List<MenuItem> getCoreMenu(Subject subject) throws PerspectiveException { Integer sessionId = subject.getSessionId(); CacheEntry cacheEntry = cache.get(sessionId); @@@ -103,13 -102,39 +101,45 @@@ return coreMenu; }
+ @NotNull - public List<Tab> getResourceTabs(Subject subject, Resource resource) - { ++ public List<Tab> getResourceTabs(Subject subject, Resource resource) { + // TODO: implement + return Collections.emptyList(); + } + + /** + * Return a unique key for the url. + * @param url + * @return + */ + public synchronized int getUrlKey(String url) { + int key = url.hashCode(); + + // in the very unlikely case that we have multiple urls with the same hashcode, protect + // ourselves. This will mess up user bookmarking of the url but saves us from internal confusion. + String mapEntry = urlMap.get(key); + while (!((null == mapEntry) || mapEntry.equals(url))) { + key *= 13; + mapEntry = urlMap.get(key); + } + + if (null == mapEntry) { + urlMap.put(key, url); + } + + return key; + } + + /** + * Return the url for the given key. + */ + public String getUrlViaKey(int key) { + return urlMap.get(key); + } + + // TODO: Is there any sort of listener approach we could use to clear an individual cache entry + // for various events like: change to role defs, change to inventory? Perhaps even a manual or + // automated refresh for the session? private void cleanCache() { Subject subject;
@@@ -141,11 -166,11 +171,12 @@@
for (MenuItem menuItem : menu) { MenuItemType item = menuItem.getItem(); - List<InventoryActivatorSetType> inventoryActivatorSets = item.getInventoryActivatorSet(); - List<PermissionActivatorSetType> permissionActivatorSets = item.getPermissionActivatorSet(); + List<ResourceActivatorSetType> inventoriedResourceActivatorSet = item.getInventoriedResourceActivatorSet(); - List<GlobalPermissionActivatorSetType> globalPermissionActivatorSet = item.getGlobalPermissionActivatorSet(); ++ List<GlobalPermissionActivatorSetType> globalPermissionActivatorSet = item ++ .getGlobalPermissionActivatorSet();
// Make sure activators are satisfied before copying - if (checkActivators(subject, inventoryActivatorSets, permissionActivatorSets)) { + if (checkActivators(subject, inventoriedResourceActivatorSet, globalPermissionActivatorSet)) { MenuItem copy = new MenuItem(menuItem.getItem());
result.add(copy); @@@ -167,7 -192,7 +198,8 @@@ boolean anyPassed = false; boolean anyFailed = false;
- for (GlobalPermissionActivatorType permissionActivator : permissionActivatorSet.getGlobalPermissionActivator()) { - for (PermissionActivatorType permissionActivator : permissionActivatorSet.getPermissionActivator()) { ++ for (GlobalPermissionActivatorType permissionActivator : permissionActivatorSet ++ .getGlobalPermissionActivator()) { boolean hasPermission = hasGlobalPermission(subject, permissionActivator.getPermission()); anyPassed = hasPermission; anyFailed = !hasPermission;
commit 06fa43b36c6bbe3faae5c72939713fec7b82d77c Author: Jay Shaughnessy jshaughn@redhat.com Date: Fri Dec 4 15:49:11 2009 -0500
Added mapping of extension urls to numeric key for cleaner param passing to template xhtml to support page within a page.
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveManagerBean.java index 27fd2bb..39a3bda 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveManagerBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveManagerBean.java @@ -54,6 +54,8 @@ public class PerspectiveManagerBean implements PerspectiveManagerLocal, Perspect // The cache is cleaned anytime there is a new entry. static private Map<Integer, CacheEntry> cache = new HashMap<Integer, CacheEntry>();
+ static private Map<Integer, String> urlMap = new HashMap<Integer, String>(); + @PersistenceContext(unitName = RHQConstants.PERSISTENCE_UNIT_NAME) private EntityManager entityManager;
@@ -87,11 +89,10 @@ public class PerspectiveManagerBean implements PerspectiveManagerLocal, Perspect
// We have to be careful not to mess with the core menu as it is returned from // the perspective manager. The core menu for each subject/sessionid could - // differ based on activation checks. So, get a new mnu structure when applying + // differ based on activation checks. So, get a new menu structure when applying // activation filters. coreMenu = getActivatedMenu(subject, coreMenu);
- // TODO : make safe copy cacheEntry.setCoreMenu(coreMenu); } catch (Exception e) { throw new PerspectiveException("Failed to get Core Menu.", e); @@ -101,6 +102,39 @@ public class PerspectiveManagerBean implements PerspectiveManagerLocal, Perspect return coreMenu; }
+ /** + * Return a unique key for the url. + * @param url + * @return + */ + public synchronized int getUrlKey(String url) { + int key = url.hashCode(); + + // in the very unlikely case that we have multiple urls with the same hashcode, protect + // ourselves. This will mess up user bookmarking of the url but saves us from internal confusion. + String mapEntry = urlMap.get(key); + while (!((null == mapEntry) || mapEntry.equals(url))) { + key *= 13; + mapEntry = urlMap.get(key); + } + + if (null == mapEntry) { + urlMap.put(key, url); + } + + return key; + } + + /** + * Return the url for the given key. + */ + public String getUrlViaKey(int key) { + return urlMap.get(key); + } + + // TODO: Is there any sort of listener approach we could use to clear an individual cache entry + // for various events like: change to role defs, change to inventory? Perhaps even a manual or + // automated refresh for the session? private void cleanCache() { Subject subject;
commit 2ee10c7ad87be8e5002a0a10ebf3a967c9cf295f Author: John Mazzitelli mazz@redhat.com Date: Fri Dec 4 15:48:28 2009 -0500
add build utility that validates server side plugins
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginManager.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginManager.java index 769db26..f8cdd5b 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginManager.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginManager.java @@ -37,7 +37,6 @@ import org.rhq.enterprise.server.util.LookupUtil; import org.rhq.enterprise.server.xmlschema.ScheduledJobDefinition; import org.rhq.enterprise.server.xmlschema.ServerPluginDescriptorMetadataParser; import org.rhq.enterprise.server.xmlschema.ServerPluginDescriptorUtil; -import org.rhq.enterprise.server.xmlschema.generated.serverplugin.ServerPluginComponentType; import org.rhq.enterprise.server.xmlschema.generated.serverplugin.ServerPluginDescriptorType;
/** @@ -450,9 +449,10 @@ public class ServerPluginManager { String pluginName = environment.getPluginKey().getPluginName(); ServerPluginComponent instance = null;
- ServerPluginComponentType componentXml = environment.getPluginDescriptor().getPluginComponent(); - if (componentXml != null) { - String className = componentXml.getClazz(); + ServerPluginDescriptorType descriptor = environment.getPluginDescriptor(); + String className = ServerPluginDescriptorMetadataParser.getPluginComponentClassName(descriptor); + + if (className != null) { log.debug("Creating plugin component [" + className + "] for plugin [" + pluginName + "]"); instance = (ServerPluginComponent) instantiatePluginClass(environment, className); log.debug("Plugin component created [" + instance.getClass() + "] for plugin [" + pluginName + "]"); @@ -474,11 +474,6 @@ public class ServerPluginManager {
ClassLoader loader = environment.getPluginClassLoader();
- String pkg = environment.getPluginDescriptor().getPackage(); - if ((className.indexOf('.') == -1) && (pkg != null)) { - className = pkg + '.' + className; - } - log.debug("Loading server plugin class [" + className + "]...");
try { diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginValidator.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginValidator.java new file mode 100644 index 0000000..9f8747e --- /dev/null +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginValidator.java @@ -0,0 +1,59 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2009 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.plugin.pc; + +/** + * Validates that a given plugin descriptor is correct. + * + * This is usually used during a build of a server plugin, but can be used at runtime + * to confirm a descriptor is valid. This does more than just validating the XML + * descriptor parses (in fact, that is confirmed before this validator object is ever + * called). Instead, it detects if things such as classnames and configurations match + * was is to be expected. + * + * Implementors of this class must have a no-arg constructor so it can be + * found and created by {@link ServerPluginValidatorUtil}. The names of the + * implementor classes (if they are to be used by that utility) must match the + * name of the plugin type followed by "Validator" (e.g. "GenericPluginValidator" + * or "AlertPluginValidator"). They must be in a subpackage under the + * package where this interface is, where that subpackage is named + * for that plugin type (minus the word "Plugin" and all lowercase) such as + * ".generic" or ".alert". + * + * Note that when this validator is invoked, the plugin descriptor has already had + * its basics validated (that is, it is assured the descriptor XML is well-formed + * and validates against the XML schema, the plugin has been given a version, its + * plugin component class is valid and can be instantiated (if one was specified) + * among other things). Implementors of this validator class need only validate + * specific things that are unique to the specific plugin type for which this + * validator is used. + * + * @author John Mazzitelli + */ +public interface ServerPluginValidator { + + /** + * Given a server plugin environment, this method should validate the descriptor + * to ensure it is logically correct. + * + * @param env the environment of the plugin to test + * @return <code>true</code> if the plugin descriptor is valid, <code>false</code> otherwise + */ + boolean validate(ServerPluginEnvironment env); +} diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginValidatorUtil.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginValidatorUtil.java new file mode 100644 index 0000000..1e16715 --- /dev/null +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginValidatorUtil.java @@ -0,0 +1,310 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2008 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, version 2, as + * published by the Free Software Foundation, and/or the GNU Lesser + * General Public License, version 2.1, also as published by the Free + * Software Foundation. + * + * 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 and the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * and the GNU Lesser 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.enterprise.server.plugin.pc; + +import java.io.File; +import java.net.JarURLConnection; +import java.net.URL; +import java.net.URLConnection; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.maven.artifact.versioning.ComparableVersion; + +import org.rhq.core.domain.plugin.PluginKey; +import org.rhq.enterprise.server.xmlschema.ServerPluginDescriptorMetadataParser; +import org.rhq.enterprise.server.xmlschema.ServerPluginDescriptorUtil; +import org.rhq.enterprise.server.xmlschema.generated.serverplugin.ServerPluginDescriptorType; + +/** + * A utility to test that a set of server plugins are valid. + * This has a main() in which you can pass a list of serverplugin jar filenames + * as arguments. If you do not pass arguments, you can set a system + * property {@link #SYSPROP_VALIDATE_SERVERPLUGINS} whose value is a comma-separated + * list of server plugin jar filenames. If you do not set that system property + * and you do not pass arguments, this will look for any and all plugin descriptors + * it can find in jar files found in the class's classloader and validate all + * of those plugin jars. + * + * @author John Mazzitelli + */ +public class ServerPluginValidatorUtil { + // this is a system property that can contain comma-separated list of plugin jar filenames + private static final String SYSPROP_VALIDATE_SERVERPLUGINS = "rhq.test.serverplugins"; + + private static final Log LOG = LogFactory.getLog(ServerPluginValidatorUtil.class); + private static final String PLUGIN_DESCRIPTOR_PATH = "META-INF/rhq-serverplugin.xml"; + + /** + * See {@link #validatePlugins(String[])} for information on what plugins get validated. + * + * The last line this will output will be "!OK!" and exit with an exit code of 0 if everything is OK. + * The last line this will output will be "!FAILURE!" and exit with an exit code of 1 if one or more plugins failed validation. + * + * @param args 0 or more plugin jar file paths + */ + public static void main(String[] args) { + try { + if (new ServerPluginValidatorUtil().validatePlugins(args)) { + System.out.println("!OK!"); + System.exit(0); + } else { + System.out.println("!FAILED!"); + System.exit(1); + } + } catch (Exception e) { + System.out.println("!FAILED!"); + System.out.println("Could not complete server plugin validation due to the following exception:"); + e.printStackTrace(System.out); + System.exit(1); + } + } + + /** + * If one or more argument strings are provided, they will be assumed to be paths to the plugin jars to validate. + * If no arguments are passed, but the system property {@link #SYSPROP_VALIDATE_SERVERPLUGINS} is set, its value + * is assumed to be a comma-separated list of plugin filenames. + * If no args are passed in, this class's classloader will be used to find the plugins to validate. + * + * @param pluginFileNames 0 or more plugin jar file paths + * + * @return 0 if all plugins validated successfully, 1 on error. + * + * @throws Exception on some error that caused the validation to abort + */ + public boolean validatePlugins(String[] pluginFileNames) throws Exception { + List<URL> jars; + + try { + if (pluginFileNames != null && pluginFileNames.length > 0) { + jars = new ArrayList<URL>(pluginFileNames.length); + for (String arg : pluginFileNames) { + URL jarUrl = new File(arg).toURI().toURL(); + jars.add(jarUrl); + LOG.info("Plugin jar: " + jarUrl); + } + } else { + String sysprop = System.getProperty(SYSPROP_VALIDATE_SERVERPLUGINS); + if (sysprop != null && !sysprop.startsWith("$")) { + String[] serverplugins = sysprop.split(","); + jars = new ArrayList<URL>(serverplugins.length); + for (String serverplugin : serverplugins) { + URL jarUrl = new File(serverplugin).toURI().toURL(); + jars.add(jarUrl); + LOG.info("Plugin jar: " + jarUrl); + } + } else { + jars = findPluginJars(); + } + } + } catch (Exception e) { + throw new RuntimeException(e); + } + + boolean status = validatePlugins(jars); + return status; + } + + public boolean validatePlugins(List<URL> jars) throws Exception { + + boolean success = true; // assume all goes well; we'll set this to false if we hit any error + ClassLoaderManager classloaderManager = null; + + try { + Map<URL, ServerPluginDescriptorType> descriptors = new HashMap<URL, ServerPluginDescriptorType>(); + for (URL jar : jars) { + try { + LOG.info("Parsing server plugin [" + jar + "]"); + ServerPluginDescriptorType descriptor = ServerPluginDescriptorUtil.loadPluginDescriptorFromUrl(jar); + descriptors.put(jar, descriptor); + } catch (Exception e) { + LOG.error("Failed to parse descriptor from plugin [" + jar + "]", e); + } + } + // make sure we successfully processed all the plugins that are in our finder + boolean sizesMatch = (descriptors.size() == jars.size()); + if (!sizesMatch) { + success = false; + LOG.error("Only [" + descriptors.size() + "] out of [" + jars.size() + + "] plugin descriptors are valid."); + } else { + LOG.info("All [" + jars.size() + "] plugin descriptors are valid."); + } + + classloaderManager = new ClassLoaderManager(descriptors, getClass().getClassLoader(), null); + + // examine all the resource types defined in all plugins and validate some things about them + for (Map.Entry<URL, ServerPluginDescriptorType> entry : descriptors.entrySet()) { + URL pluginUrl = entry.getKey(); + ServerPluginDescriptorType descriptor = entry.getValue(); + + String pluginName = descriptor.getName(); + if (pluginName == null) { + LOG.error("No plugin name in [" + pluginUrl + "]"); + success = false; + continue; + } else { + LOG.info("Validating plugin [" + pluginName + "] from [" + pluginUrl + "]"); + } + + ServerPluginType pluginType = new ServerPluginType(descriptor); + PluginKey pluginKey = PluginKey.createServerPluginKey(pluginType.stringify(), pluginName); + ClassLoader classloader = classloaderManager.obtainServerPluginClassLoader(pluginKey); + ServerPluginEnvironment env = new ServerPluginEnvironment(pluginUrl, classloader, descriptor); + + success = success && validatePluginComponentClass(env); + success = success && validatePluginVersion(env); + success = success && validatePluginConfiguration(env); + success = success && validateScheduledJobs(env); + + // now see if there is specific validation to be done based on the type of plugin + ServerPluginValidator validator = getValidator(pluginType); + if (validator != null) { + boolean validatorStatus = validator.validate(env); + if (!validatorStatus) { + LOG.error(pluginType.toString() + " validator detected a problem in plugin [" + + env.getPluginUrl() + "]"); + } + success = success && validatorStatus; + } + } + } finally { + // do any cleanup here + if (classloaderManager != null) { + classloaderManager.shutdown(); + } + } + + return success; + } + + private boolean validateScheduledJobs(ServerPluginEnvironment env) { + boolean success = true; + try { + ServerPluginDescriptorMetadataParser.getScheduledJobs(env.getPluginDescriptor()); + } catch (Exception e) { + LOG.error("Invalid scheduled jobs for plugin [" + env.getPluginUrl() + "]", e); + success = false; + } + return success; + } + + private boolean validatePluginConfiguration(ServerPluginEnvironment env) { + boolean success = true; + try { + ServerPluginDescriptorMetadataParser.getPluginConfigurationDefinition(env.getPluginDescriptor()); + } catch (Exception e) { + LOG.error("Invalid plugin configuration for plugin [" + env.getPluginUrl() + "]", e); + success = false; + } + return success; + } + + private boolean validatePluginVersion(ServerPluginEnvironment env) { + boolean success = true; + + try { + File pluginFile = new File(env.getPluginUrl().toURI()); + ComparableVersion version; + version = ServerPluginDescriptorUtil.getPluginVersion(pluginFile, env.getPluginDescriptor()); + if (version == null) { + throw new NullPointerException("version is null"); + } + } catch (Exception e) { + LOG.error("Invalid version for plugin [" + env.getPluginUrl() + "]", e); + success = false; + } + return success; + } + + private boolean validatePluginComponentClass(ServerPluginEnvironment env) { + + boolean success = true; + + String clazz = ServerPluginDescriptorMetadataParser.getPluginComponentClassName(env.getPluginDescriptor()); + + // the plugin component is optional - null is allowed + if (clazz != null) { + try { + Class<?> componentClazz = Class.forName(clazz, false, env.getPluginClassLoader()); + if (!ServerPluginComponent.class.isAssignableFrom(componentClazz)) { + success = false; + LOG.error("Component class [" + clazz + "] from plugin [" + env.getPluginUrl() + + "] does not implement " + ServerPluginComponent.class); + } + } catch (Exception e) { + success = false; + LOG.error("Component class [" + clazz + "] from plugin [" + env.getPluginUrl() + + "] could not be loaded", e); + } + } + return success; + } + + private List<URL> findPluginJars() throws Exception { + List<URL> retUrls = new ArrayList<URL>(); + + ClassLoader classloader = Thread.currentThread().getContextClassLoader(); + Enumeration<URL> descriptorUrls = classloader.getResources(PLUGIN_DESCRIPTOR_PATH); + while (descriptorUrls.hasMoreElements()) { + URL descriptorUrl = descriptorUrls.nextElement(); + URLConnection connection = descriptorUrl.openConnection(); + if (connection instanceof JarURLConnection) { + URL jarUrl = ((JarURLConnection) connection).getJarFileURL(); + retUrls.add(jarUrl); + LOG.info("Found plugin jar: " + jarUrl); + } else { + LOG.warn("Found a plugin descriptor outside of a jar, skipping: " + descriptorUrl); + } + } + + return retUrls; + } + + private ServerPluginValidator getValidator(ServerPluginType pluginType) throws Exception { + + String pkg = ServerPluginValidator.class.getPackage().getName(); + String simpleName = pluginType.getDescriptorType().getSimpleName().replaceAll("DescriptorType$", ""); + String subpkg = simpleName.replaceAll("Plugin$", "").toLowerCase(); + String className = pkg + '.' + subpkg + '.' + simpleName + "Validator"; + + ServerPluginValidator validator = null; + Class<?> clazz = null; + + try { + clazz = Class.forName(className); + } catch (Exception ignore) { + } + + if (clazz != null && ServerPluginValidator.class.isAssignableFrom(clazz)) { + validator = (ServerPluginValidator) clazz.newInstance(); + } + + return validator; + } +} \ No newline at end of file diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertPluginValidator.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertPluginValidator.java new file mode 100644 index 0000000..9117447 --- /dev/null +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertPluginValidator.java @@ -0,0 +1,30 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2009 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.plugin.pc.alert; + +import org.rhq.enterprise.server.plugin.pc.ServerPluginEnvironment; +import org.rhq.enterprise.server.plugin.pc.ServerPluginValidator; + +public class AlertPluginValidator implements ServerPluginValidator { + public boolean validate(ServerPluginEnvironment env) { + // TODO test validate env.getPluginDescriptor() + return true; + } +} diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/content/ContentPluginValidator.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/content/ContentPluginValidator.java new file mode 100644 index 0000000..0564f1b --- /dev/null +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/content/ContentPluginValidator.java @@ -0,0 +1,30 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2009 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.plugin.pc.content; + +import org.rhq.enterprise.server.plugin.pc.ServerPluginEnvironment; +import org.rhq.enterprise.server.plugin.pc.ServerPluginValidator; + +public class ContentPluginValidator implements ServerPluginValidator { + public boolean validate(ServerPluginEnvironment env) { + // TODO test validate env.getPluginDescriptor() + return true; + } +} diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/generic/GenericPluginValidator.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/generic/GenericPluginValidator.java new file mode 100644 index 0000000..2b3233e --- /dev/null +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/generic/GenericPluginValidator.java @@ -0,0 +1,30 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2009 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.plugin.pc.generic; + +import org.rhq.enterprise.server.plugin.pc.ServerPluginEnvironment; +import org.rhq.enterprise.server.plugin.pc.ServerPluginValidator; + +public class GenericPluginValidator implements ServerPluginValidator { + public boolean validate(ServerPluginEnvironment env) { + // currently, there is nothing extra we need to validate other than what the main validator did + return true; + } +} diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/perspective/PerspectivePluginValidator.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/perspective/PerspectivePluginValidator.java new file mode 100644 index 0000000..f08cd78 --- /dev/null +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/perspective/PerspectivePluginValidator.java @@ -0,0 +1,30 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2009 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.plugin.pc.perspective; + +import org.rhq.enterprise.server.plugin.pc.ServerPluginEnvironment; +import org.rhq.enterprise.server.plugin.pc.ServerPluginValidator; + +public class PerspectivePluginValidator implements ServerPluginValidator { + public boolean validate(ServerPluginEnvironment env) { + // TODO test validate env.getPluginDescriptor() + return true; + } +} diff --git a/modules/enterprise/server/plugins/pom.xml b/modules/enterprise/server/plugins/pom.xml index 960616b..89b7dac 100644 --- a/modules/enterprise/server/plugins/pom.xml +++ b/modules/enterprise/server/plugins/pom.xml @@ -39,6 +39,7 @@ <module>yum</module> <module>url</module> <module>rhnhosted</module> + <module>validate-all-serverplugins</module> </modules>
</project> diff --git a/modules/enterprise/server/plugins/validate-all-serverplugins/pom.xml b/modules/enterprise/server/plugins/validate-all-serverplugins/pom.xml new file mode 100644 index 0000000..6576a1a --- /dev/null +++ b/modules/enterprise/server/plugins/validate-all-serverplugins/pom.xml @@ -0,0 +1,64 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.rhq</groupId> + <artifactId>rhq-enterprise-server-plugins-parent</artifactId> + <version>1.4.0-SNAPSHOT</version> + </parent> + + <groupId>org.rhq</groupId> + <artifactId>validate-all-serverplugins</artifactId> + <packaging>pom</packaging> + + <name>RHQ Validate All Server Plugins</name> + <description>Test POM that will validate all RHQ server plugins</description> + + <scm> + <connection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/modules/enterprise/server/plugins/validate-all-serverplugins</connection> + <developerConnection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/modules/enterprise/server/plugins/validate-all-serverplugins</developerConnection> + </scm> + + <properties> + <scm.module.path>modules/enterprise/server/plugins/validate-all-serverplugins/</scm.module.path> + </properties> + + <build> + <plugins> + <plugin> + <artifactId>maven-antrun-plugin</artifactId> + <executions> + <execution> + <phase>integration-test</phase> + <configuration> + <tasks> + <property name="test.classpath" refid="maven.test.classpath" /> + <echo>Validating plugins...</echo> + <java classname="org.rhq.enterprise.server.plugin.pc.ServerPluginValidatorUtil" failonerror="true" fork="true"> + <classpath> + <pathelement path="${test.classpath}" /> + <pathelement location="../disk/target/rhq-serverplugin-disk-${project.version}.jar" /> + <pathelement location="../jboss-software/target/rhq-serverplugin-jboss-software-${project.version}.jar" /> + <pathelement location="../rhnhosted/target/rhq-serverplugin-rhnhosted-${project.version}.jar" /> + <pathelement location="../url/target/rhq-serverplugin-url-${project.version}.jar" /> + <pathelement location="../yum/target/rhq-serverplugin-yum-${project.version}.jar" /> + </classpath> + <sysproperty key="org.apache.commons.logging.Log" value="org.apache.commons.logging.impl.SimpleLog" /> + <sysproperty key="rhq.test.serverplugins" value="${rhq.test.serverplugins}" /> + <!-- + <jvmarg line="-Xdebug -Xrunjdwp:transport=dt_socket,address=8797,server=y,suspend=y" /> + --> + </java> + </tasks> + </configuration> + <goals> + <goal>run</goal> + </goals> + </execution> + </executions> + </plugin> + </plugins> + </build> + +</project> diff --git a/modules/enterprise/server/xml-schemas/src/main/java/org/rhq/enterprise/server/xmlschema/ServerPluginDescriptorMetadataParser.java b/modules/enterprise/server/xml-schemas/src/main/java/org/rhq/enterprise/server/xmlschema/ServerPluginDescriptorMetadataParser.java index 49f89a2..4c16fee 100644 --- a/modules/enterprise/server/xml-schemas/src/main/java/org/rhq/enterprise/server/xmlschema/ServerPluginDescriptorMetadataParser.java +++ b/modules/enterprise/server/xml-schemas/src/main/java/org/rhq/enterprise/server/xmlschema/ServerPluginDescriptorMetadataParser.java @@ -35,8 +35,10 @@ import org.rhq.core.domain.configuration.PropertySimple; import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; import org.rhq.core.domain.configuration.definition.ConfigurationTemplate; import org.rhq.core.domain.configuration.definition.PropertyDefinition; +import org.rhq.core.domain.configuration.definition.PropertyDefinitionList; import org.rhq.core.domain.configuration.definition.PropertyDefinitionMap; import org.rhq.core.domain.configuration.definition.PropertyDefinitionSimple; +import org.rhq.enterprise.server.xmlschema.generated.serverplugin.ServerPluginComponentType; import org.rhq.enterprise.server.xmlschema.generated.serverplugin.ServerPluginDescriptorType;
/** @@ -55,6 +57,34 @@ public class ServerPluginDescriptorMetadataParser { private static final String SCHEDULED_JOB_PROP_NAME_SCHEDULE_TRIGGER = "scheduleTrigger";
/** + * Returns the fully qualified class name of the plugin component. + * If the descriptor did not define a plugin component, this will return <code>null</code>. + * @param descriptor + * + * @return the name of the plugin component class, or <code>null</code> if not specified + */ + public static String getPluginComponentClassName(ServerPluginDescriptorType descriptor) { + + ServerPluginComponentType componentXml = descriptor.getPluginComponent(); + if (componentXml == null) { + return null; + } + + String className = componentXml.getClazz(); + if (className == null) { + // this should never happen, the xml schema validation should have caught this earlier + throw new IllegalArgumentException("Missing plugin component classname for plugin " + descriptor.getName()); + } + + String pkg = descriptor.getPackage(); + if ((className.indexOf('.') == -1) && (pkg != null)) { + className = pkg + '.' + className; + } + + return className; + } + + /** * Returns the global configuration definition for the plugin. This does not include any scheduled * job information - see {@link #getScheduledJobs(ServerPluginDescriptorType)} for that. * @@ -170,6 +200,9 @@ public class ServerPluginDescriptorMetadataParser { }
job = new ScheduledJobDefinition(jobId, enabled, className, methodName, scheduleType, callbackData); + } else if (!(mapDef instanceof PropertyDefinitionList)) { + // mapDef isn't even a list (which would have indicated its a valid list-of-maps of jobs) - so assume its invalid + throw new Exception("Invalid scheduled job definition [" + mapDef.getName() + "]"); }
return job;
commit 8ad387af1bfd52073627a96bec54288683ac1b10 Author: John Mazzitelli mazz@redhat.com Date: Fri Dec 4 13:44:14 2009 -0500
add eclipse tool to build the xml-schemas module
diff --git a/etc/eclipse-tools/maven/RHQ Maven Build - Dev Profile Server XML Schemas.launch b/etc/eclipse-tools/maven/RHQ Maven Build - Dev Profile Server XML Schemas.launch new file mode 100644 index 0000000..a21c63a --- /dev/null +++ b/etc/eclipse-tools/maven/RHQ Maven Build - Dev Profile Server XML Schemas.launch @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<launchConfiguration type="org.eclipse.ui.externaltools.ProgramLaunchConfigurationType"> +<stringAttribute key="bad_container_name" value="\rhq\etc\eclipse-tools\maven"/> +<booleanAttribute key="org.eclipse.debug.core.appendEnvironmentVariables" value="true"/> +<listAttribute key="org.eclipse.debug.ui.favoriteGroups"> +<listEntry value="org.eclipse.ui.externaltools.launchGroup"/> +</listAttribute> +<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="${env_var:M2_HOME}/bin/${MAVEN_EXE}"/> +<stringAttribute key="org.eclipse.ui.externaltools.ATTR_TOOL_ARGUMENTS" value="-o -Dmaven.test.skip=true -Pdev install"/> +<stringAttribute key="org.eclipse.ui.externaltools.ATTR_WORKING_DIRECTORY" value="${workspace_loc:/rhq/modules/enterprise/server/xml-schemas}"/> +</launchConfiguration>
commit 92d497d9a033c26f5a4800b2868e04d37d7c3391 Author: Jay Shaughnessy jshaughn@redhat.com Date: Fri Dec 4 15:47:43 2009 -0500
Added url key support for mapping extension urls to numeric keys for cleaner param passing to template xhtml.
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/perspective/metadata/PerspectivePluginMetadataManager.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/perspective/metadata/PerspectivePluginMetadataManager.java index 099e9fe..5afd065 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/perspective/metadata/PerspectivePluginMetadataManager.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/perspective/metadata/PerspectivePluginMetadataManager.java @@ -26,8 +26,10 @@ import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory;
-import org.rhq.enterprise.server.perspective.ExtensionPoint; import org.rhq.enterprise.server.perspective.MenuItem; +import org.rhq.enterprise.server.xmlschema.generated.serverplugin.perspective.ActionType; +import org.rhq.enterprise.server.xmlschema.generated.serverplugin.perspective.ApplicationType; +import org.rhq.enterprise.server.xmlschema.generated.serverplugin.perspective.ExtensionPointType; import org.rhq.enterprise.server.xmlschema.generated.serverplugin.perspective.MenuItemType; import org.rhq.enterprise.server.xmlschema.generated.serverplugin.perspective.PerspectivePluginDescriptorType; import org.rhq.enterprise.server.xmlschema.generated.serverplugin.perspective.PlacementType; @@ -85,6 +87,7 @@ public class PerspectivePluginMetadataManager {
// always process the core perspective first as other perspectives may reference its definitions processCorePerspective(); + processNonCorePerspectives();
isStarted = true; } @@ -104,13 +107,17 @@ public class PerspectivePluginMetadataManager { if (null == this.coreMenu) { this.coreMenu = new ArrayList<MenuItem>(); } - for (MenuItemType menuItemDef : cp.getMenuItem()) { - PositionType position = menuItemDef.getPosition(); - if (ExtensionPoint.coreMenu == ExtensionPoint.valueOf(position.getExtensionPoint())) { - addToMenu(this.coreMenu, menuItemDef); - } else { - throw new IllegalArgumentException("Unknown Extension Point defined in menuItem [" - + menuItemDef.getName() + "] : " + position.getExtensionPoint()); + + processPerspective(cp); + + // TODO: remove this debug code + //printMenu(this.coreMenu, ""); + } + + private void processNonCorePerspectives() { + for (String key : loadedPlugins.keySet()) { + if (!CORE_PERSPECTIVE_NAME.equals(key)) { + processPerspective(loadedPlugins.get(key)); } }
@@ -118,6 +125,84 @@ public class PerspectivePluginMetadataManager { //printMenu(this.coreMenu, ""); }
+ private void processPerspective(PerspectivePluginDescriptorType perspective) { + List<ApplicationType> applications = perspective.getApplication(); + + for (MenuItemType rawMenuItem : perspective.getMenuItem()) { + resolveUrls(applications, rawMenuItem); + ActionType action = rawMenuItem.getAction(); + ExtensionPointType extensionPoint = rawMenuItem.getPosition().getExtensionPoint(); + if (ExtensionPointType.CORE_MENU == extensionPoint) { + if (ActionType.ADD == action) { + menuAdd(this.coreMenu, rawMenuItem); + } else if (ActionType.REMOVE == action) { + menuRemove(this.coreMenu, rawMenuItem); + } else if (ActionType.REPLACE == action) { + menuReplace(this.coreMenu, rawMenuItem); + } + } else { + throw new IllegalArgumentException("Unknown Extension Point defined in menuItem [" + + rawMenuItem.getName() + "] : " + extensionPoint); + } + } + } + + /** + * Update the url and iconUrl as needed by applying delclard application information. + * + * @param applications + * @param rawMenuItem + */ + private void resolveUrls(List<ApplicationType> applications, MenuItemType rawMenuItem) { + ApplicationType applicationType = getApplicationByName(applications, rawMenuItem.getApplication()); + + rawMenuItem.setUrl(resolveUrl(applicationType, rawMenuItem.getUrl())); + rawMenuItem.setIconUrl(resolveUrl(applicationType, rawMenuItem.getIconUrl())); + } + + private String resolveUrl(ApplicationType applicationType, String url) { + String result = url; + + if (null != url) { + if (isRelativeUrl(url)) { + if (null == applicationType) { + throw new IllegalArgumentException( + "Relative URL found without application. Add application attribute to fully resolve url '" + + url + "'"); + } + + String baseUrl = applicationType.getBaseUrl(); + // fix the baseUrl if it lacks the separator + if (!baseUrl.endsWith("/")) { + baseUrl = baseUrl + "/"; + applicationType.setBaseUrl(baseUrl); + } + result = baseUrl + url; + } + } + + return result; + } + + private boolean isRelativeUrl(String url) { + return (!(url.startsWith("/") || url.startsWith("http"))); + } + + private ApplicationType getApplicationByName(List<ApplicationType> applications, String name) { + ApplicationType result = null; + + if (null != applications && null != name) { + for (ApplicationType application : applications) { + if (application.getName().equals(name)) { + result = application; + break; + } + } + } + + return result; + } + // TODO: remove this debug code @SuppressWarnings("unused") private void printMenu(List<MenuItem> menu, String indent) { @@ -130,11 +215,11 @@ public class PerspectivePluginMetadataManager { } }
- private void addToMenu(List<MenuItem> menu, MenuItemType menuItemDef) { + private void menuAdd(List<MenuItem> menu, MenuItemType rawMenuItem) {
- PositionType position = menuItemDef.getPosition(); - List<MenuItem> containingMenu = getContainingMenu(menu, menuItemDef); - MenuItem menuItem = new MenuItem(menuItemDef); + PositionType position = rawMenuItem.getPosition(); + List<MenuItem> containingMenu = getContainingMenu(menu, rawMenuItem); + MenuItem menuItem = new MenuItem(rawMenuItem);
if (PlacementType.START == position.getPlacement()) { containingMenu.add(0, menuItem); @@ -143,7 +228,7 @@ public class PerspectivePluginMetadataManager { } else { int index = getMenuItemIndex(containingMenu, position.getName()); if (-1 == index) { - throw new IllegalArgumentException("Invalid position defined for menuItem [" + menuItemDef.getName() + throw new IllegalArgumentException("Invalid position defined for menuItem [" + rawMenuItem.getName() + "]. Referenced menuItem not found : " + position.getName() + ". Make sure supporting menus are defined for the menuItem."); } @@ -152,15 +237,61 @@ public class PerspectivePluginMetadataManager { } }
- private List<MenuItem> getContainingMenu(List<MenuItem> menu, MenuItemType menuItemDef) { - String name = menuItemDef.getName(); + private void menuRemove(List<MenuItem> menu, MenuItemType rawMenuItem) { + + PositionType position = rawMenuItem.getPosition(); + List<MenuItem> containingMenu; + try { + containingMenu = getContainingMenu(menu, rawMenuItem); + int index = getMenuItemIndex(containingMenu, rawMenuItem.getName()); + if (-1 == index) { + throw new IllegalArgumentException("Invalid position defined for menuItem [" + rawMenuItem.getName() + + "]. Referenced menuItem not found : " + position.getName() + + ". Make sure supporting menus are defined for the menuItem."); + } + + containingMenu.remove(index); + + } catch (IllegalArgumentException e) { + if (log.isDebugEnabled()) { + log.debug("Menu item not found. Ignoring removal of " + rawMenuItem.getName(), e); + } + } + } + + private void menuReplace(List<MenuItem> menu, MenuItemType rawMenuItem) { + + PositionType position = rawMenuItem.getPosition(); + List<MenuItem> containingMenu; + try { + containingMenu = getContainingMenu(menu, rawMenuItem); + int index = getMenuItemIndex(containingMenu, rawMenuItem.getName()); + if (-1 == index) { + throw new IllegalArgumentException("Invalid position defined for menuItem [" + rawMenuItem.getName() + + "]. Referenced menuItem not found : " + position.getName() + + ". Make sure supporting menus are defined for the menuItem."); + } + + containingMenu.set(index, new MenuItem(rawMenuItem)); + + } catch (IllegalArgumentException e) { + if (log.isDebugEnabled()) { + log.debug("Menu item not found. Ignoring replacement and attempting add for " + rawMenuItem.getName(), + e); + } + menuAdd(menu, rawMenuItem); + } + } + + private List<MenuItem> getContainingMenu(List<MenuItem> menu, MenuItemType rawMenuItem) { + String name = rawMenuItem.getName(); String[] nameTokens = (null != name) ? name.split("\.") : new String[0]; List<MenuItem> result = menu;
for (int i = 0; (i + 1 < nameTokens.length); ++i) { int index = this.getMenuItemIndex(result, nameTokens[i]); if (-1 == index) { - throw new IllegalArgumentException("Invalid position defined for menuItem [" + menuItemDef.getName() + throw new IllegalArgumentException("Invalid position defined for menuItem [" + rawMenuItem.getName() + "]. No containing menu found for : " + name + ". Make sure supporting menus are defined for the menuItem."); }
commit 6f55f5113f3397f6127ee2db35ed396bf04089cb Author: Jay Shaughnessy jshaughn@redhat.com Date: Fri Dec 4 15:46:20 2009 -0500
Fixed iconUrl.
diff --git a/modules/enterprise/server/plugins/perspectives/core/perspective/src/main/resources/META-INF/rhq-serverplugin.xml b/modules/enterprise/server/plugins/perspectives/core/perspective/src/main/resources/META-INF/rhq-serverplugin.xml index b3bad4f..b589710 100644 --- a/modules/enterprise/server/plugins/perspectives/core/perspective/src/main/resources/META-INF/rhq-serverplugin.xml +++ b/modules/enterprise/server/plugins/perspectives/core/perspective/src/main/resources/META-INF/rhq-serverplugin.xml @@ -170,7 +170,7 @@ <menuItem name="groups.compatibleGroups" displayName="Compatible Groups" - iconUrl="images/icons/Cluster_up_16.png" + iconUrl="/images/icons/Cluster_up_16.png" url="/GroupHub.do?groupCategory=COMPATIBLE"> <position extensionPoint="coreMenu"
commit f41f9bf9e9d36db97b2ae2637e5915a9bbbed276 Author: Jay Shaughnessy jshaughn@redhat.com Date: Fri Dec 4 15:45:51 2009 -0500
Added ApplicationType for application declaration and attributes. And added ExtensionPointType for explicit XSD checking of valid EPs.
diff --git a/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-perspective.xsd b/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-perspective.xsd index 0dfb1a9..5f0de23 100644 --- a/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-perspective.xsd +++ b/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-perspective.xsd @@ -51,6 +51,11 @@ base="serverplugin:ServerPluginDescriptorType"> xs:sequence <xs:element + ref="perspective:application" + minOccurs="0" + maxOccurs="unbounded"> + </xs:element> + <xs:element ref="perspective:globalTask" minOccurs="0" maxOccurs="unbounded"> @@ -81,6 +86,46 @@ </xs:complexType>
<xs:element + name="application" + type="perspective:ApplicationType"> + xs:annotation + xs:documentationDeclares a web application referenced by an extension in the perspective. It is assumed that + the application will be deployed by the perspective or will be externally available. Extension urls can be + absolute or relative. Urls starting with "http" are external and processed as is. Urls starting with "/" are + relative to the root application (rhq-portal.war). Any other urls are assumed relative and will prepend the + baseUrl of the declared application (required in this case). specify an application will resolve url's + relatively to the root application (It is assumed that the root application (rhq-portal.war) + </xs:documentation> + xs:appinfo + <jaxb:class + name="PerspectiveApplicationElement" /> + </xs:appinfo> + </xs:annotation> + </xs:element> + + <xs:complexType + name="ApplicationType"> + <xs:attribute + name="name" + type="perspective:NameType" + use="required"> + xs:annotation + xs:documentationInternal name for referencing the application by the extensions. By convention, the + context root.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute + name="baseUrl" + type="xs:string" + use="required"> + xs:annotation + xs:documentationThe base url prepended to all extension urls declaring this application. + </xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:complexType> + + <xs:element name="globalTask" type="perspective:TaskType"> xs:annotation @@ -174,6 +219,15 @@ </xs:annotation> </xs:attribute> <xs:attribute + name="application" + type="xs:string" + use="optional"> + xs:annotation + xs:documentationThe application servicing the urls for this extension. Default is root (rhq-portal.war). + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="url" type="xs:anyURI" use="required"> @@ -195,7 +249,7 @@
<xs:element name="extensionPoint" - type="perspective:ExtensionPointNameType"> + type="perspective:ExtensionPointType"> </xs:element>
<xs:element @@ -304,6 +358,15 @@ </xs:annotation> </xs:attribute> <xs:attribute + name="application" + type="xs:string" + use="optional"> + xs:annotation + xs:documentationThe application servicing the urls for this extension. Default is root (rhq-portal.war). + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="url" type="xs:anyURI" use="optional"> @@ -419,6 +482,15 @@ </xs:annotation> </xs:attribute> <xs:attribute + name="application" + type="xs:string" + use="optional"> + xs:annotation + xs:documentationThe application servicing the urls for this extension. Default is root (rhq-portal.war). + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="url" type="xs:anyURI" use="required"> @@ -682,7 +754,7 @@ name="PositionType"> <xs:attribute name="extensionPoint" - type="perspective:ExtensionPointNameType" + type="perspective:ExtensionPointType" use="required"> xs:annotation xs:documentationThe extension point for which the extension is being positioned.</xs:documentation> @@ -765,13 +837,11 @@ </xs:simpleType>
<xs:simpleType - name="ExtensionPointNameType"> + name="ExtensionPointType"> <xs:restriction base="xs:string"> - <xs:minLength - value="1" /> - <xs:maxLength - value="128" /> + <xs:enumeration + value="coreMenu"></xs:enumeration> </xs:restriction> </xs:simpleType>
commit 522ddf2c5a080ad5e5849b2d695eba158678c206 Author: Jay Shaughnessy jshaughn@redhat.com Date: Fri Dec 4 15:43:57 2009 -0500
made this a generated type via the XSD: ExtensionPointType
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/perspective/ExtensionPoint.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/perspective/ExtensionPoint.java deleted file mode 100644 index 8f7bc47..0000000 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/perspective/ExtensionPoint.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.rhq.enterprise.server.perspective; - - -/** - * Immutable class representing a single perspective extension point. - * - * @author jshaughnessy - * - */ -public enum ExtensionPoint { - coreMenu, taskPane; -}
commit 44329a0b5312a4a31bc0bdd35e420dfb7f96a6eb Author: Jay Shaughnessy jshaughn@redhat.com Date: Fri Dec 4 15:41:19 2009 -0500
Remove the sample perspective from default deployment. (If you have it deployed you may need to delete it from rhq.ear/rhq-serverplugins and the entry from the db in rhq_plugins. The db entry may not exist depending on how up to date your env is. Also, make sure both the core and sample perspectives get installed in the dev-container when build -Pdev.
diff --git a/etc/samples/perspectives/sample-perspective/perspective/pom.xml b/etc/samples/perspectives/sample-perspective/perspective/pom.xml index 9674697..2345bc2 100644 --- a/etc/samples/perspectives/sample-perspective/perspective/pom.xml +++ b/etc/samples/perspectives/sample-perspective/perspective/pom.xml @@ -69,8 +69,6 @@ </dependencies>
<build> - <finalName>${project.artifactId}</finalName> - <plugins>
<plugin> @@ -88,7 +86,7 @@ location="${rhq.deploymentDir}/WEB-INF/classes" /> <jar update="yes" - destfile="${basedir}/target/${project.build.finalName}.jar" + destfile="${basedir}/target/${project.artifactId}-${project.version}.jar" basedir="${basedir}/../app/target" includes="*.war" /> </tasks> @@ -101,5 +99,61 @@ </plugin> </plugins> </build> + + <profiles> + <profile> + <id>dev</id> + + <properties> + <rhq.rootDir>../../../../..</rhq.rootDir> + <rhq.containerDir>${rhq.rootDir}/${rhq.defaultDevContainerPath}</rhq.containerDir> + <rhq.deploymentDir>${rhq.containerDir}/jbossas/server/default/deploy/${rhq.earName}/rhq-serverplugins</rhq.deploymentDir> + </properties> + + <build> + <plugins> + + <plugin> + <artifactId>maven-antrun-plugin</artifactId> + <version>1.1</version> + <executions> + + <execution> + <id>deploy</id> + <phase>install</phase> + <configuration> + <tasks> + <property name="deployment.file" location="${rhq.deploymentDir}/${project.build.finalName}.jar" /> + <echo>*** Updating ${deployment.file}...</echo> + <copy file="${basedir}/target/${project.build.finalName}.jar" toDir="${rhq.deploymentDir}" /> + </tasks> + </configuration> + <goals> + <goal>run</goal> + </goals> + </execution> + + <execution> + <id>undeploy</id> + <phase>clean</phase> + <configuration> + <tasks> + <property name="deployment.file" location="${rhq.deploymentDir}/${project.build.finalName}.jar" /> + <echo>*** Deleting ${deployment.file}...</echo> + <delete file="${deployment.file}" /> + </tasks> + </configuration> + <goals> + <goal>run</goal> + </goals> + </execution> + + </executions> + </plugin> + + </plugins> + </build> + </profile> + </profiles>
</project> diff --git a/modules/enterprise/server/ear/pom.xml b/modules/enterprise/server/ear/pom.xml index 02e4f91..a622266 100644 --- a/modules/enterprise/server/ear/pom.xml +++ b/modules/enterprise/server/ear/pom.xml @@ -1,520 +1,520 @@ -<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> +<project + xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd%22%3E
- <modelVersion>4.0.0</modelVersion> + <modelVersion>4.0.0</modelVersion>
- <parent> - <groupId>org.rhq</groupId> - <artifactId>rhq-parent</artifactId> - <version>1.4.0-SNAPSHOT</version> - </parent> + <parent> + <groupId>org.rhq</groupId> + <artifactId>rhq-parent</artifactId> + <version>1.4.0-SNAPSHOT</version> + </parent>
- <groupId>org.rhq</groupId> - <artifactId>rhq-enterprise-server-ear</artifactId> - <packaging>ear</packaging> + <groupId>org.rhq</groupId> + <artifactId>rhq-enterprise-server-ear</artifactId> + <packaging>ear</packaging>
- <name>RHQ Enterprise Server EAR</name> - <description>RHQ enterprise server EAR</description> + <name>RHQ Enterprise Server EAR</name> + <description>RHQ enterprise server EAR</description>
- <scm> - <connection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/modules/enterprise/server/ear/</connection> - <developerConnection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/modules/enterprise/server/ear/</developerConnection> - </scm> + <scm> + <connection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/modules/enterprise/server/ear/</connection> + <developerConnection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/modules/enterprise/server/ear/</developerConnection> + </scm>
- <properties> - <scm.module.path>modules/enterprise/server/ear/</scm.module.path> - <earDirectory>${project.build.directory}/${project.build.finalName}</earDirectory> + <properties> + <scm.module.path>modules/enterprise/server/ear/</scm.module.path> + <earDirectory>${project.build.directory}/${project.build.finalName}</earDirectory>
- <!-- dependency versions --> - <seam.version>1.2.1.GA</seam.version> - </properties> + <!-- dependency versions --> + <seam.version>1.2.1.GA</seam.version> + </properties>
- <dependencies> + <dependencies>
- <!-- Internal Deps --> + <!-- Internal Deps -->
- <!-- ** EJB-JARs --> + <!-- ** EJB-JARs -->
- <dependency> - <groupId>org.rhq</groupId> - <artifactId>rhq-enterprise-server</artifactId> - <version>${project.version}</version> - <type>ejb</type> - </dependency> + <dependency> + <groupId>org.rhq</groupId> + <artifactId>rhq-enterprise-server</artifactId> + <version>${project.version}</version> + <type>ejb</type> + </dependency>
- <dependency> - <groupId>org.rhq</groupId> - <artifactId>rhq-core-domain</artifactId> - <version>${project.version}</version> - <type>ejb</type> - </dependency> + <dependency> + <groupId>org.rhq</groupId> + <artifactId>rhq-core-domain</artifactId> + <version>${project.version}</version> + <type>ejb</type> + </dependency>
- <!-- ** WARs --> + <!-- ** WARs -->
- <dependency> - <groupId>org.rhq</groupId> - <artifactId>rhq-portal</artifactId> - <version>${project.version}</version> - <type>war</type> - </dependency> + <dependency> + <groupId>org.rhq</groupId> + <artifactId>rhq-portal</artifactId> + <version>${project.version}</version> + <type>war</type> + </dependency>
- <dependency> - <groupId>org.rhq</groupId> - <artifactId>rhq-webdav</artifactId> - <version>${project.version}</version> - <type>war</type> - </dependency> - - <!-- ** SARs --> -<!-- - <dependency> - <groupId>org.rhq</groupId> - <artifactId>rhq-enterprise-server-agent-sar</artifactId> - <version>${project.version}</version> - <type>sar</type> - </dependency> ---> + <dependency> + <groupId>org.rhq</groupId> + <artifactId>rhq-webdav</artifactId> + <version>${project.version}</version> + <type>war</type> + </dependency>
- <!-- 3rd Party Deps --> + <!-- ** SARs --> + <!-- + <dependency> <groupId>org.rhq</groupId> <artifactId>rhq-enterprise-server-agent-sar</artifactId> + <version>${project.version}</version> <type>sar</type> </dependency> + -->
- <!-- ** WARs --> + <!-- 3rd Party Deps -->
- <dependency> - <groupId>jboss</groupId> - <artifactId>jboss-remoting-servlet-invoker</artifactId> - <version>2x.r3040.jon</version> - <type>war</type> - </dependency> + <!-- ** WARs -->
- <!-- ** JARs --> + <dependency> + <groupId>jboss</groupId> + <artifactId>jboss-remoting-servlet-invoker</artifactId> + <version>2x.r3040.jon</version> + <type>war</type> + </dependency>
-<!-- - <dependency> - <groupId>jboss</groupId> - <artifactId>jboss-seam</artifactId> - <version>${seam.version}</version> - </dependency> ---> + <!-- ** JARs -->
- </dependencies> + <!-- + <dependency> <groupId>jboss</groupId> <artifactId>jboss-seam</artifactId> <version>${seam.version}</version> + </dependency> + -->
- <build> + </dependencies>
- <finalName>rhq</finalName> + <build>
- <resources> + <finalName>rhq</finalName>
- <resource> - <directory>src/main/resources</directory> - <filtering>true</filtering> - </resource> + <resources>
- </resources> + <resource> + <directory>src/main/resources</directory> + <filtering>true</filtering> + </resource>
- <plugins> + </resources>
- <plugin> - <artifactId>maven-antrun-plugin</artifactId> - <version>1.1</version> - <executions> - <execution> - <phase>generate-sources</phase> - <configuration> - <tasks> - <mkdir dir="${earDirectory}/license" /> - </tasks> - </configuration> - <goals> - <goal>run</goal> - </goals> - </execution> - </executions> - </plugin> - - <plugin> - <artifactId>maven-ear-plugin</artifactId> - <version>2.3.1</version> - <configuration> - <archive> - <manifest> - <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries> - <addDefaultImplementationEntries>true</addDefaultImplementationEntries> - </manifest> - <manifestEntries> - <Build-Number>${buildNumber}</Build-Number> - </manifestEntries> - </archive> - <displayName>RHQ</displayName> - <version>1.4</version> <!-- J2EE version --> - <workDirectory>${earDirectory}</workDirectory> - <resourcesDir>${basedir}/target/classes</resourcesDir> - <defaultJavaBundleDir>lib</defaultJavaBundleDir> - <unpackTypes>war,ejb,sar</unpackTypes> - <modules> - - <!-- ** WARs --> - - <webModule> - <groupId>${project.groupId}</groupId> - <artifactId>rhq-portal</artifactId> - <bundleFileName>rhq-portal.war</bundleFileName> - <contextRoot>/</contextRoot> - </webModule> - - <!-- included unless exclude.webdav property is set to true. --> - <webModule> - <groupId>${project.groupId}</groupId> - <artifactId>rhq-webdav</artifactId> - <excluded>${exclude-webdav}</excluded> - <bundleFileName>rhq-webdav.war</bundleFileName> - <contextRoot>/webdav</contextRoot> - </webModule> - - <!-- ** EJB-JARs --> - - <ejbModule> - <groupId>${project.groupId}</groupId> - <artifactId>rhq-enterprise-server</artifactId> - <bundleFileName>rhq-enterprise-server-ejb3.jar</bundleFileName> - </ejbModule> - - <ejbModule> - <groupId>${project.groupId}</groupId> - <artifactId>rhq-core-domain</artifactId> - <bundleFileName>rhq-core-domain-ejb3.jar</bundleFileName> - </ejbModule> - - <!-- ** SARs --> -<!-- - <sarModule> - <groupId>${project.groupId}</groupId> - <artifactId>rhq-enterprise-server-agent-sar</artifactId> - <bundleFileName>rhq-agent.sar</bundleFileName> - </sarModule> ---> - - <!-- ** JARs --> - -<!-- - <jarModule> - <groupId>jboss</groupId> - <artifactId>jboss-seam</artifactId> - <bundleDir>lib</bundleDir> - <includeInApplicationXml>true</includeInApplicationXml> - </jarModule> ---> - - </modules> - </configuration> - </plugin> - - <plugin> - <artifactId>maven-dependency-plugin</artifactId> - <version>2.0</version> - <executions> - - <execution> - <id>copy-rhq-plugins</id> - <phase>process-resources</phase> - <goals> - <goal>copy</goal> - </goals> - <configuration> - <artifactItems> - - <artifactItem> - <groupId>org.rhq</groupId> - <artifactId>rhq-agent-plugin</artifactId> - <version>${project.version}</version> - </artifactItem> - - <artifactItem> - <groupId>org.rhq</groupId> - <artifactId>rhq-aliases-plugin</artifactId> - <version>${project.version}</version> - </artifactItem> - - <artifactItem> - <groupId>org.rhq</groupId> - <artifactId>rhq-apache-plugin</artifactId> - <version>${project.version}</version> - </artifactItem> - - <artifactItem> - <groupId>org.rhq</groupId> - <artifactId>rhq-apt-plugin</artifactId> - <version>${project.version}</version> - </artifactItem> - - <artifactItem> - <groupId>org.rhq</groupId> - <artifactId>rhq-augeas-plugin</artifactId> - <version>${project.version}</version> - </artifactItem> - - <artifactItem> - <groupId>org.rhq</groupId> - <artifactId>rhq-cron-plugin</artifactId> - <version>${project.version}</version> - </artifactItem> - - <artifactItem> - <groupId>org.rhq</groupId> - <artifactId>rhq-database-plugin</artifactId> - <version>${project.version}</version> - </artifactItem> - - <artifactItem> - <groupId>org.rhq</groupId> - <artifactId>rhq-grub-plugin</artifactId> - <version>${project.version}</version> - </artifactItem> - - <artifactItem> - <groupId>org.rhq</groupId> - <artifactId>rhq-hosts-plugin</artifactId> - <version>${project.version}</version> - </artifactItem> - - <artifactItem> - <groupId>org.rhq</groupId> - <artifactId>rhq-hudson-plugin</artifactId> - <version>${project.version}</version> - </artifactItem> - - <artifactItem> - <groupId>org.rhq</groupId> - <artifactId>rhq-iis-plugin</artifactId> - <version>${project.version}</version> - </artifactItem> - -<!-- TODO: Uncomment once errors from RHQ-1226 are fixed. - <artifactItem> - <groupId>org.rhq</groupId> - <artifactId>rhq-jira-plugin</artifactId> - <version>${project.version}</version> - </artifactItem> - --> - <artifactItem> - <groupId>org.rhq</groupId> - <artifactId>rhq-jmx-plugin</artifactId> - <version>${project.version}</version> - </artifactItem> - - <artifactItem> - <groupId>org.rhq</groupId> - <artifactId>rhq-mysql-plugin</artifactId> - <version>${project.version}</version> - </artifactItem> - - <artifactItem> - <groupId>org.rhq</groupId> - <artifactId>rhq-netservices-plugin</artifactId> - <version>${project.version}</version> - </artifactItem> - - <artifactItem> - <groupId>org.rhq</groupId> - <artifactId>rhq-oracle-plugin</artifactId> - <version>${project.version}</version> - </artifactItem> - - <artifactItem> - <groupId>org.rhq</groupId> - <artifactId>rhq-perftest-plugin</artifactId> - <version>${project.version}</version> - </artifactItem> - - <artifactItem> - <groupId>org.rhq</groupId> - <artifactId>rhq-platform-plugin</artifactId> - <version>${project.version}</version> - </artifactItem> - - <artifactItem> - <groupId>org.rhq</groupId> - <artifactId>rhq-postfix-plugin</artifactId> - <version>${project.version}</version> - </artifactItem> - - <artifactItem> - <groupId>org.rhq</groupId> - <artifactId>rhq-postgres-plugin</artifactId> - <version>${project.version}</version> - </artifactItem> - - <artifactItem> - <groupId>org.rhq</groupId> - <artifactId>rhq-samba-plugin</artifactId> - <version>${project.version}</version> - </artifactItem> - - <artifactItem> - <groupId>org.rhq</groupId> - <artifactId>rhq-script-plugin</artifactId> - <version>${project.version}</version> - </artifactItem> - - <artifactItem> - <groupId>org.rhq</groupId> - <artifactId>rhq-snmptrapd-plugin</artifactId> - <version>${project.version}</version> - </artifactItem> - - <artifactItem> - <groupId>org.rhq</groupId> - <artifactId>rhq-sshd-plugin</artifactId> - <version>${project.version}</version> - </artifactItem> - - <artifactItem> - <groupId>org.rhq</groupId> - <artifactId>rhq-sudoers-plugin</artifactId> - <version>${project.version}</version> - </artifactItem> - -<!-- TODO: Uncomment once errors in virt plugin have been fixed. - <artifactItem> - <groupId>org.rhq</groupId> - <artifactId>rhq-virt-plugin</artifactId> - <version>${project.version}</version> - </artifactItem> ---> - </artifactItems> - <outputDirectory>${earDirectory}/rhq-downloads/rhq-plugins</outputDirectory> - </configuration> - </execution> - - <execution> - <id>copy-rhq-serverplugins</id> - <phase>process-resources</phase> - <goals> - <goal>copy</goal> - </goals> - <configuration> - <artifactItems> - - <artifactItem> - <groupId>org.rhq</groupId> - <artifactId>rhq-serverplugin-disk</artifactId> - <version>${project.version}</version> - </artifactItem> - - <artifactItem> - <groupId>org.rhq</groupId> - <artifactId>rhq-serverplugin-url</artifactId> - <version>${project.version}</version> - </artifactItem> - - <artifactItem> - <groupId>org.rhq</groupId> - <artifactId>rhq-serverplugin-yum</artifactId> - <version>${project.version}</version> - </artifactItem> - - <artifactItem> - <groupId>org.rhq</groupId> - <artifactId>rhq-core-perspective</artifactId> - <version>${project.version}</version> - </artifactItem> - - <!-- Temporary Sample Perspective --> - <artifactItem> - <groupId>org.rhq</groupId> - <artifactId>rhq-sample-perspective</artifactId> - <version>${project.version}</version> - </artifactItem> - - </artifactItems> - <outputDirectory>${earDirectory}/rhq-serverplugins</outputDirectory> - </configuration> - </execution> + <plugins>
- </executions> - </plugin> - </plugins> - </build> - - <profiles> - - <profile> - <id>dev</id> - - <properties> - <rhq.rootDir>../../../..</rhq.rootDir> - <rhq.containerDir>${rhq.rootDir}/${rhq.defaultDevContainerPath}</rhq.containerDir> - <rhq.deploymentName>${project.build.finalName}.ear</rhq.deploymentName> - <rhq.deploymentDir>${rhq.containerDir}/jbossas/server/default/deploy/${rhq.deploymentName}</rhq.deploymentDir> - </properties> - - <build> - <plugins> - - <plugin> + <plugin> <artifactId>maven-antrun-plugin</artifactId> <version>1.1</version> <executions> + <execution> + <phase>generate-sources</phase> + <configuration> + <tasks> + <mkdir + dir="${earDirectory}/license" /> + </tasks> + </configuration> + <goals> + <goal>run</goal> + </goals> + </execution> + </executions> + </plugin>
- <execution> - <id>deploy</id> - <phase>package</phase> - <configuration> - <tasks> - <mkdir dir="${earDirectory}/license" /> - <copy todir="${earDirectory}/license" file="${basedir}/src/main/license/license.xml"/> - <property name="deployment.dir" location="${rhq.deploymentDir}" /> - <echo>*** Copying updated files from target${file.separator}${project.build.finalName}${file.separator} to ${deployment.dir}${file.separator}...</echo> - <copy todir="${deployment.dir}" verbose="${rhq.verbose}"> - <fileset dir="${basedir}/target/${project.build.finalName}" /> - </copy> - <property name="deployment.descriptor.file" location="${deployment.dir}/META-INF/application.xml" /> - <echo>*** Touching ${deployment.descriptor.file} to force redeployment of ${rhq.deploymentName}...</echo> - <touch file="${deployment.descriptor.file}" /> - </tasks> - </configuration> - <goals> - <goal>run</goal> - </goals> - </execution> - - <execution> - <id>deploy-ear-meta-inf</id> - <phase>package</phase> - <configuration> - <tasks> - <unjar src="${project.build.directory}/${project.build.finalName}.ear" dest="${rhq.deploymentDir}"> - <patternset> - <include name="META-INF/**" /> - </patternset> - </unjar> - </tasks> - </configuration> - <goals> - <goal>run</goal> - </goals> - </execution> - - <execution> - <id>undeploy</id> - <phase>clean</phase> - <configuration> - <tasks> - <property name="deployment.dir" location="${rhq.deploymentDir}" /> - <echo>*** Deleting ${deployment.dir}${file.separator}...</echo> - <delete dir="${deployment.dir}" /> - </tasks> - </configuration> - <goals> - <goal>run</goal> - </goals> - </execution> + <plugin> + <artifactId>maven-ear-plugin</artifactId> + <version>2.3.1</version> + <configuration> + <archive> + <manifest> + <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries> + <addDefaultImplementationEntries>true</addDefaultImplementationEntries> + </manifest> + <manifestEntries> + <Build-Number>${buildNumber}</Build-Number> + </manifestEntries> + </archive> + <displayName>RHQ</displayName> + <version>1.4</version> <!-- J2EE version --> + <workDirectory>${earDirectory}</workDirectory> + <resourcesDir>${basedir}/target/classes</resourcesDir> + <defaultJavaBundleDir>lib</defaultJavaBundleDir> + <unpackTypes>war,ejb,sar</unpackTypes> + <modules> + + <!-- ** WARs --> + + <webModule> + <groupId>${project.groupId}</groupId> + <artifactId>rhq-portal</artifactId> + <bundleFileName>rhq-portal.war</bundleFileName> + <contextRoot>/</contextRoot> + </webModule> + + <!-- included unless exclude.webdav property is set to true. --> + <webModule> + <groupId>${project.groupId}</groupId> + <artifactId>rhq-webdav</artifactId> + <excluded>${exclude-webdav}</excluded> + <bundleFileName>rhq-webdav.war</bundleFileName> + <contextRoot>/webdav</contextRoot> + </webModule> + + <!-- ** EJB-JARs --> + + <ejbModule> + <groupId>${project.groupId}</groupId> + <artifactId>rhq-enterprise-server</artifactId> + <bundleFileName>rhq-enterprise-server-ejb3.jar</bundleFileName> + </ejbModule> + + <ejbModule> + <groupId>${project.groupId}</groupId> + <artifactId>rhq-core-domain</artifactId> + <bundleFileName>rhq-core-domain-ejb3.jar</bundleFileName> + </ejbModule> + + <!-- ** SARs --> + <!-- + <sarModule> <groupId>${project.groupId}</groupId> + <artifactId>rhq-enterprise-server-agent-sar</artifactId> + <bundleFileName>rhq-agent.sar</bundleFileName> </sarModule> + --> + + <!-- ** JARs --> + + <!-- + <jarModule> <groupId>jboss</groupId> <artifactId>jboss-seam</artifactId> <bundleDir>lib</bundleDir> + <includeInApplicationXml>true</includeInApplicationXml> </jarModule> + --> + + </modules> + </configuration> + </plugin>
- </executions> - </plugin> + <plugin> + <artifactId>maven-dependency-plugin</artifactId> + <version>2.0</version> + <executions>
- </plugins> - </build> - </profile> + <execution> + <id>copy-rhq-plugins</id> + <phase>process-resources</phase> + <goals> + <goal>copy</goal> + </goals> + <configuration> + <artifactItems> + + <artifactItem> + <groupId>org.rhq</groupId> + <artifactId>rhq-agent-plugin</artifactId> + <version>${project.version}</version> + </artifactItem> + + <artifactItem> + <groupId>org.rhq</groupId> + <artifactId>rhq-aliases-plugin</artifactId> + <version>${project.version}</version> + </artifactItem> + + <artifactItem> + <groupId>org.rhq</groupId> + <artifactId>rhq-apache-plugin</artifactId> + <version>${project.version}</version> + </artifactItem> + + <artifactItem> + <groupId>org.rhq</groupId> + <artifactId>rhq-apt-plugin</artifactId> + <version>${project.version}</version> + </artifactItem> + + <artifactItem> + <groupId>org.rhq</groupId> + <artifactId>rhq-augeas-plugin</artifactId> + <version>${project.version}</version> + </artifactItem> + + <artifactItem> + <groupId>org.rhq</groupId> + <artifactId>rhq-cron-plugin</artifactId> + <version>${project.version}</version> + </artifactItem> + + <artifactItem> + <groupId>org.rhq</groupId> + <artifactId>rhq-database-plugin</artifactId> + <version>${project.version}</version> + </artifactItem> + + <artifactItem> + <groupId>org.rhq</groupId> + <artifactId>rhq-grub-plugin</artifactId> + <version>${project.version}</version> + </artifactItem> + + <artifactItem> + <groupId>org.rhq</groupId> + <artifactId>rhq-hosts-plugin</artifactId> + <version>${project.version}</version> + </artifactItem> + + <artifactItem> + <groupId>org.rhq</groupId> + <artifactId>rhq-hudson-plugin</artifactId> + <version>${project.version}</version> + </artifactItem> + + <artifactItem> + <groupId>org.rhq</groupId> + <artifactId>rhq-iis-plugin</artifactId> + <version>${project.version}</version> + </artifactItem> + + <!-- + TODO: Uncomment once errors from RHQ-1226 are fixed. <artifactItem> + <groupId>org.rhq</groupId> <artifactId>rhq-jira-plugin</artifactId> + <version>${project.version}</version> </artifactItem> + --> + <artifactItem> + <groupId>org.rhq</groupId> + <artifactId>rhq-jmx-plugin</artifactId> + <version>${project.version}</version> + </artifactItem> + + <artifactItem> + <groupId>org.rhq</groupId> + <artifactId>rhq-mysql-plugin</artifactId> + <version>${project.version}</version> + </artifactItem> + + <artifactItem> + <groupId>org.rhq</groupId> + <artifactId>rhq-netservices-plugin</artifactId> + <version>${project.version}</version> + </artifactItem> + + <artifactItem> + <groupId>org.rhq</groupId> + <artifactId>rhq-oracle-plugin</artifactId> + <version>${project.version}</version> + </artifactItem> + + <artifactItem> + <groupId>org.rhq</groupId> + <artifactId>rhq-perftest-plugin</artifactId> + <version>${project.version}</version> + </artifactItem> + + <artifactItem> + <groupId>org.rhq</groupId> + <artifactId>rhq-platform-plugin</artifactId> + <version>${project.version}</version> + </artifactItem> + + <artifactItem> + <groupId>org.rhq</groupId> + <artifactId>rhq-postfix-plugin</artifactId> + <version>${project.version}</version> + </artifactItem> + + <artifactItem> + <groupId>org.rhq</groupId> + <artifactId>rhq-postgres-plugin</artifactId> + <version>${project.version}</version> + </artifactItem> + + <artifactItem> + <groupId>org.rhq</groupId> + <artifactId>rhq-samba-plugin</artifactId> + <version>${project.version}</version> + </artifactItem> + + <artifactItem> + <groupId>org.rhq</groupId> + <artifactId>rhq-script-plugin</artifactId> + <version>${project.version}</version> + </artifactItem> + + <artifactItem> + <groupId>org.rhq</groupId> + <artifactId>rhq-snmptrapd-plugin</artifactId> + <version>${project.version}</version> + </artifactItem> + + <artifactItem> + <groupId>org.rhq</groupId> + <artifactId>rhq-sshd-plugin</artifactId> + <version>${project.version}</version> + </artifactItem> + + <artifactItem> + <groupId>org.rhq</groupId> + <artifactId>rhq-sudoers-plugin</artifactId> + <version>${project.version}</version> + </artifactItem> + + <!-- + TODO: Uncomment once errors in virt plugin have been fixed. <artifactItem> + <groupId>org.rhq</groupId> <artifactId>rhq-virt-plugin</artifactId> + <version>${project.version}</version> </artifactItem> + --> + </artifactItems> + <outputDirectory>${earDirectory}/rhq-downloads/rhq-plugins</outputDirectory> + </configuration> + </execution> + + <execution> + <id>copy-rhq-serverplugins</id> + <phase>process-resources</phase> + <goals> + <goal>copy</goal> + </goals> + <configuration> + <artifactItems> + + <artifactItem> + <groupId>org.rhq</groupId> + <artifactId>rhq-serverplugin-disk</artifactId> + <version>${project.version}</version> + </artifactItem> + + <artifactItem> + <groupId>org.rhq</groupId> + <artifactId>rhq-serverplugin-url</artifactId> + <version>${project.version}</version> + </artifactItem> + + <artifactItem> + <groupId>org.rhq</groupId> + <artifactId>rhq-serverplugin-yum</artifactId> + <version>${project.version}</version> + </artifactItem> + + <artifactItem> + <groupId>org.rhq</groupId> + <artifactId>rhq-core-perspective</artifactId> + <version>${project.version}</version> + </artifactItem> + + </artifactItems> + <outputDirectory>${earDirectory}/rhq-serverplugins</outputDirectory> + </configuration> + </execution>
- </profiles> + </executions> + </plugin> + </plugins> + </build> + + <profiles> + + <profile> + <id>dev</id> + + <properties> + <rhq.rootDir>../../../..</rhq.rootDir> + <rhq.containerDir>${rhq.rootDir}/${rhq.defaultDevContainerPath}</rhq.containerDir> + <rhq.deploymentName>${project.build.finalName}.ear</rhq.deploymentName> + <rhq.deploymentDir>${rhq.containerDir}/jbossas/server/default/deploy/${rhq.deploymentName}</rhq.deploymentDir> + </properties> + + <build> + <plugins> + + <plugin> + <artifactId>maven-antrun-plugin</artifactId> + <version>1.1</version> + <executions> + + <execution> + <id>deploy</id> + <phase>package</phase> + <configuration> + <tasks> + <mkdir + dir="${earDirectory}/license" /> + <copy + todir="${earDirectory}/license" + file="${basedir}/src/main/license/license.xml" /> + <property + name="deployment.dir" + location="${rhq.deploymentDir}" /> + <echo>*** Copying updated files from + target${file.separator}${project.build.finalName}${file.separator} to + ${deployment.dir}${file.separator}...</echo> + <copy + todir="${deployment.dir}" + verbose="${rhq.verbose}"> + <fileset + dir="${basedir}/target/${project.build.finalName}" /> + </copy> + <property + name="deployment.descriptor.file" + location="${deployment.dir}/META-INF/application.xml" /> + <echo>*** Touching ${deployment.descriptor.file} to force redeployment of + ${rhq.deploymentName}...</echo> + <touch + file="${deployment.descriptor.file}" /> + </tasks> + </configuration> + <goals> + <goal>run</goal> + </goals> + </execution> + + <execution> + <id>deploy-ear-meta-inf</id> + <phase>package</phase> + <configuration> + <tasks> + <unjar + src="${project.build.directory}/${project.build.finalName}.ear" + dest="${rhq.deploymentDir}"> + <patternset> + <include + name="META-INF/**" /> + </patternset> + </unjar> + </tasks> + </configuration> + <goals> + <goal>run</goal> + </goals> + </execution> + + <execution> + <id>undeploy</id> + <phase>clean</phase> + <configuration> + <tasks> + <property + name="deployment.dir" + location="${rhq.deploymentDir}" /> + <echo>*** Deleting ${deployment.dir}${file.separator}...</echo> + <delete + dir="${deployment.dir}" /> + </tasks> + </configuration> + <goals> + <goal>run</goal> + </goals> + </execution> + + </executions> + </plugin> + + </plugins> + </build> + </profile> + + </profiles>
</project> diff --git a/modules/enterprise/server/plugins/perspectives/core/perspective/pom.xml b/modules/enterprise/server/plugins/perspectives/core/perspective/pom.xml index e8dfec7..ca5eda3 100644 --- a/modules/enterprise/server/plugins/perspectives/core/perspective/pom.xml +++ b/modules/enterprise/server/plugins/perspectives/core/perspective/pom.xml @@ -58,5 +58,64 @@ -->
</dependencies> + + <profiles> + + <profile> + <id>dev</id> + + <properties> + <rhq.rootDir>../../../../../../..</rhq.rootDir> + <rhq.containerDir>${rhq.rootDir}/${rhq.defaultDevContainerPath}</rhq.containerDir> + <rhq.deploymentDir>${rhq.containerDir}/jbossas/server/default/deploy/${rhq.earName}/rhq-serverplugins</rhq.deploymentDir> + </properties> + + <build> + <plugins> + + <plugin> + <artifactId>maven-antrun-plugin</artifactId> + <version>1.1</version> + <executions> + + <execution> + <id>deploy</id> + <phase>compile</phase> + <configuration> + <tasks> + <mkdir dir="${rhq.deploymentDir}" /> + <property name="deployment.file" location="${rhq.deploymentDir}/${project.build.finalName}.jar" /> + <echo>*** Updating ${deployment.file}...</echo> + <jar destfile="${deployment.file}" basedir="${project.build.outputDirectory}" /> + </tasks> + </configuration> + <goals> + <goal>run</goal> + </goals> + </execution> + + <execution> + <id>undeploy</id> + <phase>clean</phase> + <configuration> + <tasks> + <property name="deployment.file" location="${rhq.deploymentDir}/${project.build.finalName}.jar" /> + <echo>*** Deleting ${deployment.file}...</echo> + <delete file="${deployment.file}" /> + </tasks> + </configuration> + <goals> + <goal>run</goal> + </goals> + </execution> + + </executions> + </plugin> + + </plugins> + </build> + </profile> + + </profiles>
</project> diff --git a/modules/enterprise/server/plugins/pom.xml b/modules/enterprise/server/plugins/pom.xml index dc2c402..69a1da3 100644 --- a/modules/enterprise/server/plugins/pom.xml +++ b/modules/enterprise/server/plugins/pom.xml @@ -1,47 +1,48 @@ -<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> +<project + xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd%22%3E
- <modelVersion>4.0.0</modelVersion> + <modelVersion>4.0.0</modelVersion>
- <parent> - <groupId>org.rhq</groupId> - <artifactId>rhq-parent</artifactId> - <version>1.4.0-SNAPSHOT</version> - </parent> - - <groupId>org.rhq</groupId> - <artifactId>rhq-enterprise-server-plugins-parent</artifactId> - <packaging>pom</packaging> - - <name>RHQ Enterprise Server Plugins</name> - <description>RHQ enterprise server plugins parent POM</description> - - <scm> - <connection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/modules/enterprise/server/plugins</connection> - <developerConnection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/modules/enterprise/server/plugins/</developerConnection> - </scm> - - <properties> - <scm.module.path>modules/enterprise/server/plugins/</scm.module.path> - </properties> - - <!-- all server-side plugins have access to some of the server-side APIs, therefore, we need this dependency --> - <dependencies> - <dependency> + <parent> <groupId>org.rhq</groupId> - <artifactId>rhq-enterprise-server</artifactId> - <version>${project.version}</version> - <type>ejb</type> - </dependency> - </dependencies> - - <modules> - <module>disk</module> - <module>yum</module> - <module>url</module> - <module>rhnhosted</module> - <module>perspectives/core</module> - <!-- temporary sample perspective plugin --> - <module>../../../../etc/samples/perspectives/sample-perspective</module> - </modules> + <artifactId>rhq-parent</artifactId> + <version>1.4.0-SNAPSHOT</version> + </parent> + + <groupId>org.rhq</groupId> + <artifactId>rhq-enterprise-server-plugins-parent</artifactId> + <packaging>pom</packaging> + + <name>RHQ Enterprise Server Plugins</name> + <description>RHQ enterprise server plugins parent POM</description> + + <scm> + <connection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/modules/enterprise/server/plugins</connection> + <developerConnection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/modules/enterprise/server/plugins/</developerConnection> + </scm> + + <properties> + <scm.module.path>modules/enterprise/server/plugins/</scm.module.path> + </properties> + + <!-- all server-side plugins have access to some of the server-side APIs, therefore, we need this dependency --> + <dependencies> + <dependency> + <groupId>org.rhq</groupId> + <artifactId>rhq-enterprise-server</artifactId> + <version>${project.version}</version> + <type>ejb</type> + </dependency> + </dependencies> + + <modules> + <module>disk</module> + <module>yum</module> + <module>url</module> + <module>rhnhosted</module> + <module>perspectives/core</module> + </modules>
</project>
commit 8c042f481cba89b3d37d90e56cf4491c25f88f7f Author: Jay Shaughnessy jshaughn@redhat.com Date: Fri Dec 4 15:38:24 2009 -0500
Sample perspective additions. Custom images, application declaration.
diff --git a/etc/samples/perspectives/sample-perspective/app/src/main/webapp/images/create.png b/etc/samples/perspectives/sample-perspective/app/src/main/webapp/images/create.png new file mode 100644 index 0000000..5403358 Binary files /dev/null and b/etc/samples/perspectives/sample-perspective/app/src/main/webapp/images/create.png differ diff --git a/etc/samples/perspectives/sample-perspective/app/src/main/webapp/images/jboss.png b/etc/samples/perspectives/sample-perspective/app/src/main/webapp/images/jboss.png new file mode 100644 index 0000000..d0e1ef5 Binary files /dev/null and b/etc/samples/perspectives/sample-perspective/app/src/main/webapp/images/jboss.png differ diff --git a/etc/samples/perspectives/sample-perspective/perspective/src/main/resources/META-INF/rhq-serverplugin.xml b/etc/samples/perspectives/sample-perspective/perspective/src/main/resources/META-INF/rhq-serverplugin.xml index 1fefde4..de12e05 100644 --- a/etc/samples/perspectives/sample-perspective/perspective/src/main/resources/META-INF/rhq-serverplugin.xml +++ b/etc/samples/perspectives/sample-perspective/perspective/src/main/resources/META-INF/rhq-serverplugin.xml @@ -11,6 +11,43 @@ xmlns:serverplugin="urn:xmlns:rhq-serverplugin" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance%22%3E
+ + <!-- Declare supporting applications for this perspective --> + <application + name="sample" + baseUrl="/rhq-sample-perspective/" /> + + <!-- replace the coreMenu log with a new one --> + <menuItem + action="replace" + name="logo" + displayName="" + application="sample" + url="/" + iconUrl="images/jboss.png"> + <position + extensionPoint="coreMenu" + placement="start" /> + </menuItem> + + <!-- remove the 'new' menu items from the group menuGroup and move them to the custom menuGroup --> + <menuItem + action="remove" + name="groups.newGroup"> + <position + extensionPoint="coreMenu" + name="groups.groupDefinitions" + placement="after" /> + </menuItem> + <menuItem + action="remove" + name="groups.newGroupDefinition"> + <position + extensionPoint="coreMenu" + name="groups.newGroup" + placement="after" /> + </menuItem> + <!-- Add Custom menuItem to Core Menu --> <menuItem name="custom" @@ -20,16 +57,14 @@ name="help" placement="after" /> </menuItem> - <menuItem name="custom.child1" - displayName="Child1"> + displayName="Child-1"> <position extensionPoint="coreMenu" name="custom" placement="start" /> </menuItem> - <menuItem name="custom.child2" displayName="Child-2"> @@ -38,16 +73,34 @@ name="custom.child1" placement="after" /> </menuItem> - <menuItem - name="custom.grandchild1" - displayName="GrandChild 1" - feature="aboutBox" - iconUrl="http://127.0.0.1:7080/images/icons/availability_grey_16.png%22%3E + name="custom.child1.newGroup" + displayName="New Group" + application="sample" + url="/resource/group/Inventory.do?mode=new" + iconUrl="images/create.png"> <position extensionPoint="coreMenu" name="custom.child1" placement="start" /> + <permissionActivatorSet> + <permissionActivator + permission="MANAGE_INVENTORY" /> + </permissionActivatorSet> + </menuItem> + <menuItem + name="custom.child1.newGroupDefinition" + displayName="New Group Definition" + application="sample" + url="/rhq/definition/group/new.xhtml" + iconUrl="images/create.png"> + <position + extensionPoint="coreMenu" + name="custom.child1.newGroup" + placement="after" /> + <permissionActivatorSet> + <permissionActivator + permission="MANAGE_INVENTORY" /> + </permissionActivatorSet> </menuItem> - </perspectivePlugin> \ No newline at end of file
commit 96cf72f32bb4470f842dabcc0b54f0f6c6aeda0c Author: Justin Harris jharris@redhat.com Date: Fri Dec 4 15:26:48 2009 -0500
Moving tab selection into session bean.
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/InstalledPluginsSessionUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/InstalledPluginsSessionUIBean.java index ec66bb5..096671c 100644 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/InstalledPluginsSessionUIBean.java +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/InstalledPluginsSessionUIBean.java @@ -20,6 +20,7 @@ package org.rhq.enterprise.gui.admin.plugin;
public class InstalledPluginsSessionUIBean { private boolean showAllServerPlugins = false; + private String selectedTab;
public InstalledPluginsSessionUIBean() { } @@ -39,4 +40,12 @@ public class InstalledPluginsSessionUIBean { public void hideUndeployedServerPlugins() { setShowAllServerPlugins(false); } + + public String getSelectedTab() { + return selectedTab; + } + + public void setSelectedTab(String selectedTab) { + this.selectedTab = selectedTab; + } } \ No newline at end of file diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/InstalledPluginsUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/InstalledPluginsUIBean.java index 7f32e48..52fecb0 100644 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/InstalledPluginsUIBean.java +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/InstalledPluginsUIBean.java @@ -61,23 +61,9 @@ public class InstalledPluginsUIBean { private ResourceMetadataManagerLocal resourceMetadataManagerBean = LookupUtil.getResourceMetadataManager(); private ServerPluginsLocal serverPluginsBean = LookupUtil.getServerPlugins();
- private String selectedTab; - public InstalledPluginsUIBean() { }
- public String getSelectedTab() { - if (selectedTab == null) { - selectedTab = FacesContextUtility.getOptionalRequestParameter("tab"); - } - - return selectedTab; - } - - public void setSelectedTab(String selectedTab) { - this.selectedTab = selectedTab; - } - public void restartMasterPluginContainer() {
hasPermission(); diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-details.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-details.xhtml index abb046d..4b98473 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-details.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-details.xhtml @@ -13,7 +13,6 @@
<ui:define name="breadcrumbs"> <h:outputLink value="plugin-list.xhtml" > - <f:param name="tab" value="#{plugin.deployment}"/> <h:outputText value="Installed #{plugin.deployment == 'SERVER' ? 'Server' : 'Agent'} Plugins"/> </h:outputLink> > diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-list.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-list.xhtml index bcb0ee7..d96db32 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-list.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-list.xhtml @@ -39,7 +39,7 @@ </f:facet>
<h:panelGrid columns="1" width="100%"> - <rich:tabPanel switchType="ajax" selectedTab="#{InstalledPluginsUIBean.selectedTab}"> + <rich:tabPanel switchType="ajax" selectedTab="#{InstalledPluginsSessionUIBean.selectedTab}">
<!-- ========== AGENT PLUGINS TAB ========== -->
commit e97ad2b514a62435215ab1d17a5454e076815f43 Author: Heiko W. Rupp pilhuhn@fedorapeople.org Date: Fri Dec 4 21:21:24 2009 +0100
Prevent a NPE if a Sender (illegally) returns null in its send() method.
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerBean.java index ec99907..17faabf 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerBean.java @@ -665,7 +665,9 @@ public class AlertManagerBean implements AlertManagerLocal, AlertManagerRemote { if (sender!=null) { try { SenderResult result = sender.send(alert); - if (result.getState() == ResultState.SUCCESS) { + if (result == null) { + log.warn("- !! -- sender " + alertNotification.getSenderName() + " did not return a SenderResult. Please fix this -- !! - "); + } else if (result.getState() == ResultState.SUCCESS) { if (result.getEmails()!=null && !result.getEmails().isEmpty()) emailAddresses.addAll(result.getEmails()); }
commit 8b4e561be5ca5e060ccebe8fad5222c7e58ee0b2 Author: Heiko W. Rupp pilhuhn@fedorapeople.org Date: Fri Dec 4 21:18:07 2009 +0100
Fix return values
diff --git a/modules/enterprise/server/plugins/alert-snmp/src/main/java/org/rhq/enterprise/server/plugins/alertSnmp/SnmpSender.java b/modules/enterprise/server/plugins/alert-snmp/src/main/java/org/rhq/enterprise/server/plugins/alertSnmp/SnmpSender.java index e715965..5c9a609 100644 --- a/modules/enterprise/server/plugins/alert-snmp/src/main/java/org/rhq/enterprise/server/plugins/alertSnmp/SnmpSender.java +++ b/modules/enterprise/server/plugins/alert-snmp/src/main/java/org/rhq/enterprise/server/plugins/alertSnmp/SnmpSender.java @@ -70,17 +70,19 @@ public class SnmpSender extends AlertSender { String platformName = lineage.get(0).getName(); String conditions = alertManager.prettyPrintAlertConditions(alert); String alertUrl = alertManager.prettyPrintAlertURL(alert); + + SenderResult res ; try { bootTime = new Date(); // TODO = LookupUtil.getCoreServer().getBootTime(); result = snmpTrapSender.sendSnmpTrap(alert, alertParameters, platformName, conditions, bootTime, alertUrl); + res = new SenderResult(ResultState.SUCCESS,result); } catch (Throwable t) { result = "failed - cause: " + t; + res = new SenderResult(ResultState.FAILURE,result); }
log.debug("Result of sending SNMP trap: " + result); - // TODO: Log the action result to the DB (i.e. as an AlertNotificationLog). - // (see http://jira.jboss.com/jira/browse/JBNADM-1820)
- return null; // TODO: Customise this generated block + return res; } }
commit bac6b961387933faeb229067506131f65e45962e Author: Heiko W. Rupp pilhuhn@fedorapeople.org Date: Fri Dec 4 21:15:51 2009 +0100
Oops, fix constructor call.
diff --git a/modules/enterprise/server/plugins/alert-snmp/src/main/java/org/rhq/enterprise/server/plugins/alertSnmp/SnmpSender.java b/modules/enterprise/server/plugins/alert-snmp/src/main/java/org/rhq/enterprise/server/plugins/alertSnmp/SnmpSender.java index 8130459..e715965 100644 --- a/modules/enterprise/server/plugins/alert-snmp/src/main/java/org/rhq/enterprise/server/plugins/alertSnmp/SnmpSender.java +++ b/modules/enterprise/server/plugins/alert-snmp/src/main/java/org/rhq/enterprise/server/plugins/alertSnmp/SnmpSender.java @@ -62,7 +62,7 @@ public class SnmpSender extends AlertSender { AlertManagerLocal alertManager = LookupUtil.getAlertManager(); ResourceManagerLocal resourceManager = LookupUtil.getResourceManager();
- SnmpTrapSender snmpTrapSender = new SnmpTrapSender(); + SnmpTrapSender snmpTrapSender = new SnmpTrapSender(preferences); log.debug("Sending SNMP trap with OID " + oid + " to SNMP engine " + host + ":" + port + "..."); String result;
commit d4208f6a1ed51b450465137070130b40fb9d09b6 Author: Heiko W. Rupp pilhuhn@fedorapeople.org Date: Fri Dec 4 21:00:37 2009 +0100
Change over to the new plugin preferences and add the remaining config parameters.
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugins/alertSnmp/SnmpTrapSender.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugins/alertSnmp/SnmpTrapSender.java index af66bce..2a52279 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugins/alertSnmp/SnmpTrapSender.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugins/alertSnmp/SnmpTrapSender.java @@ -22,7 +22,6 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Date; import java.util.List; -import java.util.Properties; import java.util.StringTokenizer;
import org.apache.commons.logging.Log; @@ -72,12 +71,7 @@ import org.snmp4j.transport.DefaultUdpTransportMapping; import org.snmp4j.util.PDUFactory;
import org.rhq.core.domain.alert.Alert; -import org.rhq.core.domain.alert.notification.SnmpNotification; import org.rhq.core.domain.configuration.Configuration; -import org.rhq.enterprise.server.RHQConstants; -import org.rhq.enterprise.server.plugin.pc.alert.ResultState; -import org.rhq.enterprise.server.plugin.pc.alert.SenderResult; -import org.rhq.enterprise.server.util.LookupUtil;
/** * @author Ian Springer @@ -133,7 +127,10 @@ public class SnmpTrapSender implements PDUFactory {
private boolean snmpEnabled;
- public SnmpTrapSender() { + Configuration systemConfig; + + public SnmpTrapSender(Configuration preferences) { + this.systemConfig = preferences; this.snmpEnabled = init(); }
@@ -457,7 +454,7 @@ public class SnmpTrapSender implements PDUFactory { /** * This method sends the actual trap * @param alert The alert to send - * @param snmpNotification the notification data (target agent) + * @param alertParameters the notification data (target agent) * @param platformName the name of the platform the alert is on * @param conditions a string that shows the alert conditions * @param bootTime TODO @@ -533,9 +530,8 @@ public class SnmpTrapSender implements PDUFactory { }
private boolean init() { - Properties systemConfig = LookupUtil.getSystemManager().getSystemConfiguration();
- String snmpVersion = systemConfig.getProperty(RHQConstants.SNMPVersion); + String snmpVersion = systemConfig.getSimpleValue("snmpVersion",null); if ((snmpVersion != null) && (snmpVersion.length() > 0)) { if (snmpVersion.equals("1")) { this.version = SnmpConstants.version1; @@ -555,84 +551,84 @@ public class SnmpTrapSender implements PDUFactory { throw new IllegalStateException("V1TRAP PDU type is only available for SNMP version 1"); }
- String snmpAuthProtocol = systemConfig.getProperty(RHQConstants.SNMPAuthProtocol); - if ((snmpAuthProtocol != null) && (snmpAuthProtocol.length() > 0)) { - if (snmpAuthProtocol.equals("MD5")) { + String tmp = systemConfig.getSimpleValue("authProtocol","MD5"); + if ((tmp != null) && (tmp.length() > 0)) { + if (tmp.equals("MD5")) { this.authProtocol = AuthMD5.ID; - } else if (snmpAuthProtocol.equals("SHA")) { + } else if (tmp.equals("SHA")) { this.authProtocol = AuthSHA.ID; } else { - throw new IllegalStateException("SNMP authentication protocol unsupported: " + snmpAuthProtocol); + throw new IllegalStateException("SNMP authentication protocol unsupported: " + tmp); } }
- snmpAuthProtocol = systemConfig.getProperty(RHQConstants.SNMPAuthPassphrase); - if ((snmpAuthProtocol != null) && (snmpAuthProtocol.length() > 0)) { - this.authPassphrase = createOctetString(snmpAuthProtocol); + tmp = systemConfig.getSimpleValue("authPassphrase",null); + if ((tmp != null) && (tmp.length() > 0)) { + this.authPassphrase = createOctetString(tmp); }
- snmpAuthProtocol = systemConfig.getProperty(RHQConstants.SNMPPrivacyPassphrase); - if ((snmpAuthProtocol != null) && (snmpAuthProtocol.length() > 0)) { - this.privPassphrase = createOctetString(snmpAuthProtocol); + tmp = systemConfig.getSimpleValue("privacyPassphrase",null); + if ((tmp != null) && (tmp.length() > 0)) { + this.privPassphrase = createOctetString(tmp); }
- snmpAuthProtocol = systemConfig.getProperty(RHQConstants.SNMPCommunity); - if ((snmpAuthProtocol != null) && (snmpAuthProtocol.length() > 0)) { - this.community = createOctetString(snmpAuthProtocol); + tmp = systemConfig.getSimpleValue("community",null); + if ((tmp != null) && (tmp.length() > 0)) { + this.community = createOctetString(tmp); }
- snmpAuthProtocol = systemConfig.getProperty(RHQConstants.SNMPEngineID); - if ((snmpAuthProtocol != null) && (snmpAuthProtocol.length() > 0)) { - this.contextEngineID = createOctetString(snmpAuthProtocol); + tmp = systemConfig.getSimpleValue("engineId",null); + if ((tmp != null) && (tmp.length() > 0)) { + this.contextEngineID = createOctetString(tmp); }
- snmpAuthProtocol = systemConfig.getProperty(RHQConstants.SNMPContextName); - if ((snmpAuthProtocol != null) && (snmpAuthProtocol.length() > 0)) { - this.contextName = createOctetString(snmpAuthProtocol); + tmp = systemConfig.getSimpleValue("targetContext",null); + if ((tmp != null) && (tmp.length() > 0)) { + this.contextName = createOctetString(tmp); }
- snmpAuthProtocol = systemConfig.getProperty(RHQConstants.SNMPSecurityName); - if ((snmpAuthProtocol != null) && (snmpAuthProtocol.length() > 0)) { - this.securityName = createOctetString(snmpAuthProtocol); + tmp = systemConfig.getSimpleValue("securityName",null); + if ((tmp != null) && (tmp.length() > 0)) { + this.securityName = createOctetString(tmp); }
- snmpAuthProtocol = systemConfig.getProperty(RHQConstants.SNMPTrapOID); - if ((snmpAuthProtocol != null) && (snmpAuthProtocol.length() > 0)) { - this.trapOID = new OID(snmpAuthProtocol); + tmp = systemConfig.getSimpleValue("trapOid",null); + if ((tmp != null) && (tmp.length() > 0)) { + this.trapOID = new OID(tmp); }
- snmpAuthProtocol = systemConfig.getProperty(RHQConstants.SNMPEnterpriseOID); - if ((snmpAuthProtocol != null) && (snmpAuthProtocol.length() > 0)) { - this.v1TrapPDU.setEnterprise(new OID(snmpAuthProtocol)); + tmp = systemConfig.getSimpleValue("enterpriseOid",null); + if ((tmp != null) && (tmp.length() > 0)) { + this.v1TrapPDU.setEnterprise(new OID(tmp)); }
- snmpAuthProtocol = systemConfig.getProperty(RHQConstants.SNMPGenericID); - if ((snmpAuthProtocol != null) && (snmpAuthProtocol.length() > 0)) { - this.v1TrapPDU.setGenericTrap(Integer.parseInt(snmpAuthProtocol)); + tmp = systemConfig.getSimpleValue("genericId",null); + if ((tmp != null) && (tmp.length() > 0)) { + this.v1TrapPDU.setGenericTrap(Integer.parseInt(tmp)); }
- snmpAuthProtocol = systemConfig.getProperty(RHQConstants.SNMPSpecificID); - if ((snmpAuthProtocol != null) && (snmpAuthProtocol.length() > 0)) { - this.v1TrapPDU.setSpecificTrap(Integer.parseInt(snmpAuthProtocol)); + tmp = systemConfig.getSimpleValue("specificId",null); + if ((tmp != null) && (tmp.length() > 0)) { + this.v1TrapPDU.setSpecificTrap(Integer.parseInt(tmp)); }
- snmpAuthProtocol = systemConfig.getProperty(RHQConstants.SNMPAgentAddress); - if ((snmpAuthProtocol != null) && (snmpAuthProtocol.length() > 0)) { - this.v1TrapPDU.setAgentAddress(new IpAddress(snmpAuthProtocol)); + tmp = systemConfig.getSimpleValue("agentAddress",null); + if ((tmp != null) && (tmp.length() > 0)) { + this.v1TrapPDU.setAgentAddress(new IpAddress(tmp)); }
- snmpAuthProtocol = systemConfig.getProperty(RHQConstants.SNMPPrivacyProtocol); - if ((snmpAuthProtocol != null) && (snmpAuthProtocol.length() > 0)) { - if (snmpAuthProtocol.equals("DES")) { + tmp = systemConfig.getSimpleValue("privacyProtocol","AES"); + if ((tmp != null) && (tmp.length() > 0)) { + if (tmp.equals("DES")) { this.privProtocol = PrivDES.ID; - } else if ((snmpAuthProtocol.equals("AES128")) || (snmpAuthProtocol.equals("AES"))) { + } else if ((tmp.equals("AES128")) || (tmp.equals("AES"))) { this.privProtocol = PrivAES128.ID; - } else if (snmpAuthProtocol.equals("AES192")) { + } else if (tmp.equals("AES192")) { this.privProtocol = PrivAES192.ID; - } else if (snmpAuthProtocol.equals("AES256")) { + } else if (tmp.equals("AES256")) { this.privProtocol = PrivAES256.ID; } else { - throw new IllegalArgumentException("Privacy protocol " + snmpAuthProtocol + " not supported"); + throw new IllegalArgumentException("Privacy protocol " + tmp + " not supported"); } }
diff --git a/modules/enterprise/server/plugins/alert-snmp/src/main/java/org/rhq/enterprise/server/plugins/alertSnmp/SnmpSender.java b/modules/enterprise/server/plugins/alert-snmp/src/main/java/org/rhq/enterprise/server/plugins/alertSnmp/SnmpSender.java index cf34731..8130459 100644 --- a/modules/enterprise/server/plugins/alert-snmp/src/main/java/org/rhq/enterprise/server/plugins/alertSnmp/SnmpSender.java +++ b/modules/enterprise/server/plugins/alert-snmp/src/main/java/org/rhq/enterprise/server/plugins/alertSnmp/SnmpSender.java @@ -35,7 +35,7 @@ import org.rhq.enterprise.server.resource.ResourceManagerLocal; import org.rhq.enterprise.server.util.LookupUtil;
/** - * // TODO: Document this + * AlertSender that sends alerts via SNMP Traps * @author Heiko W. Rupp */ public class SnmpSender extends AlertSender { diff --git a/modules/enterprise/server/plugins/alert-snmp/src/main/resources/META-INF/rhq-serverplugin.xml b/modules/enterprise/server/plugins/alert-snmp/src/main/resources/META-INF/rhq-serverplugin.xml index 3f37a96..e50abbe 100644 --- a/modules/enterprise/server/plugins/alert-snmp/src/main/resources/META-INF/rhq-serverplugin.xml +++ b/modules/enterprise/server/plugins/alert-snmp/src/main/resources/META-INF/rhq-serverplugin.xml @@ -22,7 +22,7 @@
<!-- Global preferences for all mircoblog alerts --> serverplugin:plugin-configuration - <c:simple-property name="snmpVersion" displayName="Snmp protcol version" type="string"> + <c:simple-property name="snmpVersion" displayName="Snmp protcol version" type="string" required="false" default="1"> <c:property-options> <c:option value="1"/> <c:option value="2c"/> @@ -30,18 +30,21 @@ </c:property-options> </c:simple-property>
- <c:simple-property name="trapOid" displayName="Trap OID" description="OID for the trap sent" type="string"/> - <c:group name="1" displayName="Snmp version 1 properties" hiddenByDefault="true"> - <c:simple-property name="v1Community" type="string" default="public"/> - <c:simple-property name="engineId" /> - <c:simple-property name="genericId" /> - <c:simple-property name="enterpriseOid"/> - <c:simple-property name="specificId" /> - <c:simple-property name="agentAddress" description="Address of our SNMP agent"/> + <c:simple-property name="trapOid" displayName="Trap OID" description="OID for the trap sent" type="string" /> + <c:simple-property name="community" type="string" default="public" description="Community - v1 and v2c only" required="false"/> + + <c:group name="1" displayName="Snmp version 1 properties" hiddenByDefault="true" > + <c:simple-property name="engineId" required="false"/> + <c:simple-property name="genericId" required="false"/> + <c:simple-property name="enterpriseOid" required="false"/> + <c:simple-property name="specificId" required="false"/> + <c:simple-property name="agentAddress" description="Address of our SNMP agent" required="false"/> </c:group> + <!-- <c:group name="2c" displayName="Snmp version 2c properties" hiddenByDefault="true"> - <c:simple-property name="v2Community" type="string"/> + Nothing special </c:group> + --> <c:group name="3" displayName="Snmp version 3 properties" hiddenByDefault="true"> <c:simple-property name="authProtocol" type="string" default="MD5"> <c:property-options> @@ -52,14 +55,16 @@ </c:simple-property> <c:simple-property name="privacyProtocol" default="AES"> <c:property-options> - <c:option value="None"/> <c:option value="DES"/> <c:option value="AES"/> <c:option value="AES192"/> <c:option value="AES256"/> </c:property-options> </c:simple-property> - + <c:simple-property name="targetContext" displayName="Target Context Name" type="string" required="false"/> + <c:simple-property name="authPassphrase" description="Auto Passphrase is required with autorization enabled" type="password" required="false"/> + <c:simple-property name="privacyPassphrase" description="Privacy Passphrase is required with privacy enabled" type="password" required="false"/> + <c:simple-property name="securityName" type="string" required="false"/>
</c:group> </serverplugin:plugin-configuration>
commit 638d81a5085d395221f3c7a47d83fe1fc1dd7b7c Author: John Sanda jsanda@redhat.com Date: Fri Dec 4 14:49:07 2009 -0500
Updating unit tests and adding logic to throw an exception when wrong update method is called.
If updateResourceConfigurationUpdate() is called with a configuration that supports both structured and raw an exception is thrown because there is not sufficient information to determine whether the structured or raw was modified. And assuming one or the other could result in unintended changes to the configuration.
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java index e900d24..7b7aec8 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java @@ -1012,6 +1012,14 @@ public class ConfigurationManagerBean implements ConfigurationManagerLocal, Conf public ResourceConfigurationUpdate updateResourceConfiguration(Subject subject, int resourceId, @XmlJavaTypeAdapter(ConfigurationAdapter.class) Configuration newConfiguration) throws ResourceNotFoundException { + + if (isStructuredAndRawSupported(resourceId)) { + throw new ConfigurationUpdateNotSupportedException("Cannot update a resource configuration that " + + "supports both structured and raw configuration using this method because there is insufficient " + + "information. You should instead call updateStructuredOrRawConfiguration() which requires you " + + "whether the structured or raw was updated."); + } + // must do this in a separate transaction so it is committed prior to sending the agent request // (consider synchronizing to avoid the condition where someone calls this method twice quickly // in two different txs which would put two updates in INPROGRESS and cause havoc) diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationUpdateNotSupportedException.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationUpdateNotSupportedException.java new file mode 100644 index 0000000..dc9564a --- /dev/null +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationUpdateNotSupportedException.java @@ -0,0 +1,42 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2008 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.configuration; + +import javax.ejb.ApplicationException; + +@ApplicationException(rollback = true) +public class ConfigurationUpdateNotSupportedException extends RuntimeException { + + public ConfigurationUpdateNotSupportedException() { + super(); + } + + public ConfigurationUpdateNotSupportedException(String message) { + super(message); + } + + public ConfigurationUpdateNotSupportedException(String message, Throwable cause) { + super(message, cause); + } + + public ConfigurationUpdateNotSupportedException(Throwable cause) { + super(cause); + } +} diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBeanUnitTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBeanUnitTest.java index 7958411..e2d8e81 100644 --- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBeanUnitTest.java +++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBeanUnitTest.java @@ -109,18 +109,45 @@ public class ConfigurationManagerBeanUnitTest extends JMockTest { }
@Test - public void updateResourceConfigShouldAddUpdateToAuditTrailAndSendUpdateToAgent() throws Exception { - final Subject subject = new Subject("rhqadmin", true, true); - final int resourceId = -1; - final Configuration newConfig = new Configuration(); - final boolean isPartOfGroupUpdate = false; + public void updateStructuredResourceConfigShouldUpdateAuditTrailAndSendUpdateToAgent() throws Exception { + final ResourceConfigUpdateFixture fixture = newStructuredResourceConfigUpdateFixture();
- Resource resource = new Resource(resourceId); - resource.setAgent(new Agent("test-agent", "localhost", 7080, null, null)); + final ResourceConfigurationUpdate expectedUpdate = new ResourceConfigurationUpdate(fixture.resource, + fixture.configuration, fixture.subject.getName());
- final ResourceConfigurationUpdate expectedUpdate = new ResourceConfigurationUpdate(resource, newConfig, - subject.getName()); - expectedUpdate.setId(-1); + final AgentClient agentClient = context.mock(AgentClient.class); + final ConfigurationAgentService configAgentService = context.mock(ConfigurationAgentService.class); + + final ConfigurationUpdateRequest expectedUpdateRequest = new ConfigurationUpdateRequest(expectedUpdate.getId(), + expectedUpdate.getConfiguration(), expectedUpdate.getResource().getId()); + + context.checking(new Expectations() {{ + allowing(entityMgr).find(Resource.class, fixture.resourceId); will(returnValue(fixture.resource)); + + oneOf(configurationMgrLocal).persistNewResourceConfigurationUpdateHistory(fixture.subject, + fixture.resourceId, fixture.configuration, INPROGRESS, fixture.subject.getName(), + fixture.isPartOfGroupUpdate); + will(returnValue(expectedUpdate)); + + allowing(agentMgr).getAgentClient(expectedUpdate.getResource().getAgent()); will(returnValue(agentClient)); + + allowing(agentClient).getConfigurationAgentService(); will(returnValue(configAgentService)); + + oneOf(configAgentService).updateResourceConfiguration(with(matchingUpdateRequest(expectedUpdateRequest))); + }}); + + ResourceConfigurationUpdate actualUpdate = configurationMgr.updateResourceConfiguration(fixture.subject, + fixture.resourceId, fixture.configuration); + + assertSame(actualUpdate, expectedUpdate, "Expected to get back the persisted configuration update"); + } + + @Test + public void updateRawResourceConfigShouldUpdateAuditTrailAndSendUpdateToAgent() throws Exception { + final ResourceConfigUpdateFixture fixture = newRawResourceConfigUpdateFixture(); + + final ResourceConfigurationUpdate expectedUpdate = new ResourceConfigurationUpdate(fixture.resource, + fixture.configuration, fixture.subject.getName());
final AgentClient agentClient = context.mock(AgentClient.class); final ConfigurationAgentService configAgentService = context.mock(ConfigurationAgentService.class); @@ -129,8 +156,11 @@ public class ConfigurationManagerBeanUnitTest extends JMockTest { expectedUpdate.getConfiguration(), expectedUpdate.getResource().getId());
context.checking(new Expectations() {{ - oneOf(configurationMgrLocal).persistNewResourceConfigurationUpdateHistory(subject, resourceId, newConfig, - INPROGRESS, subject.getName(), isPartOfGroupUpdate); + allowing(entityMgr).find(Resource.class, fixture.resourceId); will(returnValue(fixture.resource)); + + oneOf(configurationMgrLocal).persistNewResourceConfigurationUpdateHistory(fixture.subject, + fixture.resourceId, fixture.configuration, INPROGRESS, fixture.subject.getName(), + fixture.isPartOfGroupUpdate); will(returnValue(expectedUpdate));
allowing(agentMgr).getAgentClient(expectedUpdate.getResource().getAgent()); will(returnValue(agentClient)); @@ -140,28 +170,32 @@ public class ConfigurationManagerBeanUnitTest extends JMockTest { oneOf(configAgentService).updateResourceConfiguration(with(matchingUpdateRequest(expectedUpdateRequest))); }});
- ResourceConfigurationUpdate actualUpdate = configurationMgr.updateResourceConfiguration(subject, resourceId, - newConfig); + ResourceConfigurationUpdate actualUpdate = configurationMgr.updateResourceConfiguration(fixture.subject, + fixture.resourceId, fixture.configuration);
assertSame(actualUpdate, expectedUpdate, "Expected to get back the persisted configuration update"); }
+ @Test(expectedExceptions = ConfigurationUpdateNotSupportedException.class) + public void exceptionShouldBeThrownWhenCallingWrongMethodForConfigThatSupportsStructuredAndRaw() throws Exception { + final ResourceConfigUpdateFixture fixture = newStructuredAndRawResourceConfigUpdateFixture(); + + context.checking(new Expectations() {{ + allowing(entityMgr).find(Resource.class, fixture.resourceId); will(returnValue(fixture.resource)); + }}); + + configurationMgr.updateResourceConfiguration(fixture.subject, fixture.resourceId, fixture.configuration); + } + @Test public void updateResourceConfigShouldTranslateStructuredWhenStructredConfigHasEdits() throws Exception { - final Subject subject = new Subject("rhqadmin", true, true); - final int resourceId = -1; - final Configuration newConfig = new Configuration(); - final boolean isPartOfGroupUpdate = false; + final ResourceConfigUpdateFixture fixture = newStructuredAndRawResourceConfigUpdateFixture();
- final Configuration translatedConfig = newConfig.deepCopy(); + final Configuration translatedConfig = fixture.configuration.deepCopy(); translatedConfig.addRawConfiguration(new RawConfiguration());
- final Resource resource = new Resource(resourceId); - resource.setResourceType(createStructuredAndRaw()); - resource.setAgent(new Agent("test-agent", "localhost", 7080, null, null)); - - final ResourceConfigurationUpdate expectedUpdate = new ResourceConfigurationUpdate(resource, translatedConfig, - subject.getName()); + final ResourceConfigurationUpdate expectedUpdate = new ResourceConfigurationUpdate(fixture.resource, + translatedConfig, fixture.subject.getName()); expectedUpdate.setId(-1);
final AgentClient agentClient = context.mock(AgentClient.class); @@ -173,15 +207,16 @@ public class ConfigurationManagerBeanUnitTest extends JMockTest { final Sequence configUdpate = context.sequence("structured-config-update");
context.checking(new Expectations() {{ - allowing(entityMgr).find(Resource.class, resourceId); will(returnValue(resource)); + allowing(entityMgr).find(Resource.class, fixture.resourceId); will(returnValue(fixture.resource));
- allowing(authorizationMgr).canViewResource(subject, resourceId); will(returnValue(true)); + allowing(authorizationMgr).canViewResource(fixture.subject, fixture.resourceId); will(returnValue(true));
- oneOf(configAgentService).merge(newConfig, resourceId, FROM_STRUCTURED); + oneOf(configAgentService).merge(fixture.configuration, fixture.resourceId, FROM_STRUCTURED); will(returnValue(translatedConfig)); inSequence(configUdpate);
- oneOf(configurationMgrLocal).persistNewResourceConfigurationUpdateHistory(subject, resourceId, - translatedConfig, INPROGRESS, subject.getName(), isPartOfGroupUpdate); + oneOf(configurationMgrLocal).persistNewResourceConfigurationUpdateHistory(fixture.subject, + fixture.resourceId, translatedConfig, INPROGRESS, fixture.subject.getName(), + fixture.isPartOfGroupUpdate); will(returnValue(expectedUpdate)); inSequence(configUdpate);
@@ -193,25 +228,18 @@ public class ConfigurationManagerBeanUnitTest extends JMockTest { inSequence(configUdpate); }});
- ResourceConfigurationUpdate actualUpdate = configurationMgr.updateStructuredOrRawConfiguration(subject, resourceId, - newConfig, FROM_STRUCTURED); + ResourceConfigurationUpdate actualUpdate = configurationMgr.updateStructuredOrRawConfiguration(fixture.subject, + fixture.resourceId, fixture.configuration, FROM_STRUCTURED);
assertSame(actualUpdate, expectedUpdate, "Expected to get back the persisted configuration update"); }
@Test public void updateResourceConfigShouldNotTranslateStructuredWhenRawNotSupported() throws Exception { - final Subject subject = new Subject("rhqadmin", true, true); - final int resourceId = -1; - final Configuration newConfig = new Configuration(); - final boolean isPartOfGroupUpdate = false; - - final Resource resource = new Resource(resourceId); - resource.setAgent(new Agent("test-agent", "localhost", 7080, null, null)); - resource.setResourceType(createStructurerdOnly()); + final ResourceConfigUpdateFixture fixture = newStructuredResourceConfigUpdateFixture();
- final ResourceConfigurationUpdate expectedUpdate = new ResourceConfigurationUpdate(resource, newConfig, - subject.getName()); + final ResourceConfigurationUpdate expectedUpdate = new ResourceConfigurationUpdate(fixture.resource, + fixture.configuration, fixture.subject.getName()); expectedUpdate.setId(-1);
final AgentClient agentClient = context.mock(AgentClient.class); @@ -223,10 +251,11 @@ public class ConfigurationManagerBeanUnitTest extends JMockTest { final Sequence configUdpate = context.sequence("structured-config-update");
context.checking(new Expectations() {{ - allowing(entityMgr).find(Resource.class, resourceId); will(returnValue(resource)); + allowing(entityMgr).find(Resource.class, fixture.resourceId); will(returnValue(fixture.resource));
- oneOf(configurationMgrLocal).persistNewResourceConfigurationUpdateHistory(subject, resourceId, newConfig, - INPROGRESS, subject.getName(), isPartOfGroupUpdate); + oneOf(configurationMgrLocal).persistNewResourceConfigurationUpdateHistory(fixture.subject, + fixture.resourceId, fixture.configuration, INPROGRESS, fixture.subject.getName(), + fixture.isPartOfGroupUpdate); will(returnValue(expectedUpdate)); inSequence(configUdpate);
@@ -238,29 +267,22 @@ public class ConfigurationManagerBeanUnitTest extends JMockTest { inSequence(configUdpate); }});
- ResourceConfigurationUpdate actualUpdate = configurationMgr.updateStructuredOrRawConfiguration(subject, resourceId, - newConfig, FROM_STRUCTURED); + ResourceConfigurationUpdate actualUpdate = configurationMgr.updateStructuredOrRawConfiguration(fixture.subject, + fixture.resourceId, fixture.configuration, FROM_STRUCTURED);
assertSame(actualUpdate, expectedUpdate, "Expected to get back the persisted configuration update"); }
@Test public void updateResourceConfigShouldTranslateRawWhenRawConfigHasEdits() throws Exception { - final Subject subject = new Subject("rhqadmin", true, true); - final int resourceId = -1; - final Configuration newConfig = new Configuration(); - newConfig.addRawConfiguration(new RawConfiguration()); - final boolean isPartOfGroupUpdate = false; + final ResourceConfigUpdateFixture fixture = newStructuredAndRawResourceConfigUpdateFixture(); + fixture.configuration.addRawConfiguration(new RawConfiguration());
- final Configuration translatedConfig = newConfig.deepCopy(); + final Configuration translatedConfig = fixture.configuration.deepCopy(); translatedConfig.put(new PropertySimple("x", "y"));
- final Resource resource = new Resource(resourceId); - resource.setResourceType(createStructuredAndRaw()); - resource.setAgent(new Agent("test-agent", "localhost", 7080, null, null)); - - final ResourceConfigurationUpdate expectedUpdate = new ResourceConfigurationUpdate(resource, translatedConfig, - subject.getName()); + final ResourceConfigurationUpdate expectedUpdate = new ResourceConfigurationUpdate(fixture.resource, translatedConfig, + fixture.subject.getName()); expectedUpdate.setId(-1);
final AgentClient agentClient = context.mock(AgentClient.class); @@ -272,15 +294,16 @@ public class ConfigurationManagerBeanUnitTest extends JMockTest { final Sequence configUdpate = context.sequence("raw-config-update");
context.checking(new Expectations() {{ - allowing(entityMgr).find(Resource.class, resourceId); will(returnValue(resource)); + allowing(entityMgr).find(Resource.class, fixture.resourceId); will(returnValue(fixture.resource));
- allowing(authorizationMgr).canViewResource(subject, resourceId); will(returnValue(true)); + allowing(authorizationMgr).canViewResource(fixture.subject, fixture.resourceId); will(returnValue(true));
- oneOf(configAgentService).merge(newConfig, resourceId, FROM_RAW); + oneOf(configAgentService).merge(fixture.configuration, fixture.resourceId, FROM_RAW); will(returnValue(translatedConfig)); inSequence(configUdpate);
- oneOf(configurationMgrLocal).persistNewResourceConfigurationUpdateHistory(subject, resourceId, - translatedConfig, INPROGRESS, subject.getName(), isPartOfGroupUpdate); + oneOf(configurationMgrLocal).persistNewResourceConfigurationUpdateHistory(fixture.subject, + fixture.resourceId, translatedConfig, INPROGRESS, fixture.subject.getName(), + fixture.isPartOfGroupUpdate); will(returnValue(expectedUpdate)); inSequence(configUdpate);
@@ -292,33 +315,29 @@ public class ConfigurationManagerBeanUnitTest extends JMockTest { inSequence(configUdpate); }});
- ResourceConfigurationUpdate actualUpdate = configurationMgr.updateStructuredOrRawConfiguration(subject, resourceId, - newConfig, FROM_RAW); + ResourceConfigurationUpdate actualUpdate = configurationMgr.updateStructuredOrRawConfiguration(fixture.subject, + fixture.resourceId, fixture.configuration, FROM_RAW);
assertSame(actualUpdate, expectedUpdate, "Expected to get back the persisted configuration update"); }
@Test public void updateResourceConfigShouldMarkUpdateAsFailureWhenExceptionOccurs() throws Exception { - final Subject subject = new Subject("rhqadmin", true, true); - final int resourceId = -1; - final Configuration newConfig = new Configuration(); - final boolean isPartOfGroupUpdate = false; - - Resource resource = new Resource(resourceId); - resource.setAgent(new Agent("test-agent", "localhost", 7080, null, null)); + final ResourceConfigUpdateFixture fixture = newStructuredResourceConfigUpdateFixture();
final RuntimeException exception = new RuntimeException();
- final ResourceConfigurationUpdate expectedUpdate = new ResourceConfigurationUpdate(resource, newConfig, - subject.getName()); + final ResourceConfigurationUpdate expectedUpdate = new ResourceConfigurationUpdate(fixture.resource, + fixture.configuration, fixture.subject.getName()); expectedUpdate.setId(-1); expectedUpdate.setStatus(FAILURE); expectedUpdate.setErrorMessageFromThrowable(exception);
context.checking(new Expectations() {{ - oneOf(configurationMgrLocal).persistNewResourceConfigurationUpdateHistory(subject, resourceId, newConfig, - INPROGRESS, subject.getName(), isPartOfGroupUpdate); + allowing(entityMgr).find(Resource.class, fixture.resourceId); will(returnValue(fixture.resource)); + + oneOf(configurationMgrLocal).persistNewResourceConfigurationUpdateHistory(fixture.subject, fixture.resourceId, + fixture.configuration, INPROGRESS, fixture.subject.getName(), fixture.isPartOfGroupUpdate); will(returnValue(expectedUpdate));
oneOf(configurationMgrLocal).mergeConfigurationUpdate(expectedUpdate); @@ -327,8 +346,8 @@ public class ConfigurationManagerBeanUnitTest extends JMockTest { will(throwException(exception)); }});
- ResourceConfigurationUpdate actualUpdate = configurationMgr.updateResourceConfiguration(subject, resourceId, - newConfig); + ResourceConfigurationUpdate actualUpdate = configurationMgr.updateResourceConfiguration(fixture.subject, + fixture.resourceId, fixture.configuration);
assertPropertiesMatch(expectedUpdate, actualUpdate, "Expected to get back a failure update"); } @@ -337,7 +356,55 @@ public class ConfigurationManagerBeanUnitTest extends JMockTest { return new PropertyMatcher<ConfigurationUpdateRequest>(expected); }
- ResourceType createStructuredAndRaw() { + ResourceConfigUpdateFixture newStructuredResourceConfigUpdateFixture() { + ResourceConfigUpdateFixture fixture = new ResourceConfigUpdateFixture(); + fixture.resource = createResourceWithStructuredConfig(fixture.resourceId); + + return fixture; + } + + ResourceConfigUpdateFixture newRawResourceConfigUpdateFixture() { + ResourceConfigUpdateFixture fixture = new ResourceConfigUpdateFixture(); + fixture.resource = createResourceWithRawConfig(fixture.resourceId); + + return fixture; + } + + ResourceConfigUpdateFixture newStructuredAndRawResourceConfigUpdateFixture() { + ResourceConfigUpdateFixture fixture = new ResourceConfigUpdateFixture(); + fixture.resource = createResourceWithStructuredAndRawConfig(fixture.resourceId); + + return fixture; + } + + Resource createResource(int resourceId) { + Resource resource = new Resource(resourceId); + resource.setAgent(new Agent("test-agent", "localhost", 7080, null, null)); + return resource; + } + + Resource createResourceWithStructuredConfig(int resourceId) { + Resource resource = createResource(resourceId); + resource.setResourceType(createStructurerdOnlyResourceType()); + + return resource; + } + + Resource createResourceWithStructuredAndRawConfig(int resourceId) { + Resource resource = createResource(resourceId); + resource.setResourceType(createStructuredAndRawResourceType()); + + return resource; + } + + Resource createResourceWithRawConfig(int resourceId) { + Resource resource = createResource(resourceId); + resource.setResourceType(createRawResourceType()); + + return resource; + } + + ResourceType createStructuredAndRawResourceType() { ConfigurationDefinition configDef = new ConfigurationDefinition("structured-and-raw", "structured and raw"); configDef.setConfigurationFormat(ConfigurationFormat.STRUCTURED_AND_RAW);
@@ -347,7 +414,7 @@ public class ConfigurationManagerBeanUnitTest extends JMockTest { return resourceType; }
- ResourceType createStructurerdOnly() { + ResourceType createStructurerdOnlyResourceType() { ConfigurationDefinition configDef = new ConfigurationDefinition("structred-config-def", "structured config def"); configDef.setConfigurationFormat(ConfigurationFormat.STRUCTURED);
@@ -357,4 +424,22 @@ public class ConfigurationManagerBeanUnitTest extends JMockTest { return resourceType; }
+ ResourceType createRawResourceType() { + ConfigurationDefinition configDef = new ConfigurationDefinition("raw-config-def", "raw config def"); + configDef.setConfigurationFormat(ConfigurationFormat.RAW); + + ResourceType resourceType = new ResourceType(); + resourceType.setResourceConfigurationDefinition(configDef); + + return resourceType; + } + + static class ResourceConfigUpdateFixture { + Subject subject = new Subject("rhqadmin", true, true); + int resourceId = -1; + Configuration configuration = new Configuration(); + boolean isPartOfGroupUpdate = false; + Resource resource; + } + }
commit 2adb6937cd83f788d30a5b2b309a635a967f6a96 Author: Partha Aji paji@redhat.com Date: Fri Dec 4 14:38:10 2009 -0500
Added code to setup recycle bin for Samba
diff --git a/modules/plugins/samba/src/main/java/org/rhq/plugins/samba/SambaServerComponent.java b/modules/plugins/samba/src/main/java/org/rhq/plugins/samba/SambaServerComponent.java index d26aceb..db9767a 100644 --- a/modules/plugins/samba/src/main/java/org/rhq/plugins/samba/SambaServerComponent.java +++ b/modules/plugins/samba/src/main/java/org/rhq/plugins/samba/SambaServerComponent.java @@ -18,18 +18,24 @@ */ package org.rhq.plugins.samba;
+import net.augeas.Augeas; + import org.rhq.core.domain.configuration.Configuration; +import org.rhq.core.domain.configuration.PropertySimple; +import org.rhq.core.domain.configuration.definition.PropertyDefinitionSimple; import org.rhq.core.domain.measurement.AvailabilityType; import org.rhq.core.domain.resource.ResourceType; import org.rhq.core.pluginapi.configuration.ConfigurationUpdateReport; import org.rhq.core.pluginapi.inventory.CreateResourceReport; import org.rhq.core.pluginapi.inventory.ResourceContext; import org.rhq.plugins.augeas.AugeasConfigurationComponent; +import org.rhq.plugins.augeas.helper.AugeasNode;
/** * TODO */ public class SambaServerComponent extends AugeasConfigurationComponent { + static final String ENABLE_RECYCLING = "enableRecycleBin";
public void start(ResourceContext resourceContext) throws Exception { super.start(resourceContext); @@ -64,7 +70,8 @@ public class SambaServerComponent extends AugeasConfigurationComponent { @Override protected String getChildResourceConfigurationRootPath(ResourceType resourceType, Configuration resourceConfig) { if (resourceType.getName().equals(SambaShareComponent.RESOURCE_TYPE_NAME)) { - String targetName = resourceConfig.getSimple(SambaShareComponent.NAME_RESOURCE_CONFIG_PROP).getStringValue(); + String targetName = resourceConfig.getSimple(SambaShareComponent.NAME_RESOURCE_CONFIG_PROP) + .getStringValue(); return "/files/etc/samba/smb.conf/target[.='" + targetName + "']"; } else { throw new IllegalArgumentException("Unsupported child Resource type: " + resourceType); @@ -79,4 +86,33 @@ public class SambaServerComponent extends AugeasConfigurationComponent { throw new IllegalArgumentException("Unsupported child Resource type: " + resourceType); } } + + @Override + protected void setNodeFromPropertySimple(Augeas augeas, AugeasNode node, PropertyDefinitionSimple propDefSimple, + PropertySimple propSimple) { + if (ENABLE_RECYCLING.equals(propDefSimple.getName())) { + if (propSimple.getBooleanValue()) { + String path = node.getParent().getPath(); + augeas.set(path + "/vfs\ objects", "recycle"); + augeas.set(path + "/recycle:repository", ".recycle"); + augeas.set(path + "/recycle:keeptree", "yes"); + augeas.set(path + "/recycle:versions", "yes"); + } else { + String path = node.getParent().getPath(); + augeas.remove(path + "/vfs\ objects"); + augeas.remove(path + "/recycle:repository"); + augeas.remove(path + "/recycle:keeptree"); + augeas.remove(path + "/recycle:versions"); + } + } else { + super.setNodeFromPropertySimple(augeas, node, propDefSimple, propSimple); + } + } + + protected Object toPropertyValue(PropertyDefinitionSimple propDefSimple, Augeas augeas, AugeasNode node) { + if (ENABLE_RECYCLING.equals(propDefSimple.getName())) { + return "recycle".equals(augeas.get(node.getParent().getPath() + "/vfs\ objects")); + } + return super.toPropertyValue(propDefSimple, augeas, node); + } } diff --git a/modules/plugins/samba/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/samba/src/main/resources/META-INF/rhq-plugin.xml index 958c44b..a9505ce 100644 --- a/modules/plugins/samba/src/main/resources/META-INF/rhq-plugin.xml +++ b/modules/plugins/samba/src/main/resources/META-INF/rhq-plugin.xml @@ -42,7 +42,7 @@
<c:simple-property name="workgroup" description="The workgroup your server will appear to be in when queried by clients" required="false"/> <c:simple-property name="server string" description="Value that will display in the printer comment box in print manager" required="false"/> - + <c:simple-property name="enableRecycleBin" type="boolean" description="Enable recycle bin for all the shares. Deleted files or directories will be copied to a .recycle under the tree."/> </c:group>
<c:group name="Security"> diff --git a/modules/plugins/samba/src/test/java/org/rhq/plugins/samba/SambaComponentTest.java b/modules/plugins/samba/src/test/java/org/rhq/plugins/samba/SambaComponentTest.java index afae482..46f816c 100644 --- a/modules/plugins/samba/src/test/java/org/rhq/plugins/samba/SambaComponentTest.java +++ b/modules/plugins/samba/src/test/java/org/rhq/plugins/samba/SambaComponentTest.java @@ -34,7 +34,7 @@ public class SambaComponentTest extends AbstractAugeasConfigurationComponentTest config.put(new PropertySimple("encrypt passwords", "yes")); config.put(new PropertySimple("load printers", "yes")); config.put(new PropertySimple("cups options", "raw")); - + config.put(new PropertySimple("enableRecycleBin", false)); return config; }
@@ -48,7 +48,6 @@ public class SambaComponentTest extends AbstractAugeasConfigurationComponentTest return "Samba Server"; }
- @Override protected Configuration getUpdatedResourceConfig() { Configuration config = new Configuration(); @@ -59,6 +58,7 @@ public class SambaComponentTest extends AbstractAugeasConfigurationComponentTest config.put(new PropertySimple("encrypt passwords", "DUMBCHANGE")); config.put(new PropertySimple("load printers", "DUMBCHANGE")); config.put(new PropertySimple("cups options", "DUMBCHANGE")); + config.put(new PropertySimple("enableRecycleBin", true));
return config; }
commit cc4b14ed21a33cb8b9ce1ace6cd6f93eef0c1a06 Author: Justin Harris jharris@redhat.com Date: Fri Dec 4 14:36:52 2009 -0500
* Changing plugin list to optionally show 'Server Plugins' tab initially. * Modifying plugin details page breadcrumbs to point back to the appropriate tab on the plugin list page.
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/InstalledPluginsUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/InstalledPluginsUIBean.java index 52fecb0..7f32e48 100644 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/InstalledPluginsUIBean.java +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/InstalledPluginsUIBean.java @@ -61,9 +61,23 @@ public class InstalledPluginsUIBean { private ResourceMetadataManagerLocal resourceMetadataManagerBean = LookupUtil.getResourceMetadataManager(); private ServerPluginsLocal serverPluginsBean = LookupUtil.getServerPlugins();
+ private String selectedTab; + public InstalledPluginsUIBean() { }
+ public String getSelectedTab() { + if (selectedTab == null) { + selectedTab = FacesContextUtility.getOptionalRequestParameter("tab"); + } + + return selectedTab; + } + + public void setSelectedTab(String selectedTab) { + this.selectedTab = selectedTab; + } + public void restartMasterPluginContainer() {
hasPermission(); diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-details.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-details.xhtml index 5bb4b2a..abb046d 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-details.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-details.xhtml @@ -13,7 +13,8 @@
<ui:define name="breadcrumbs"> <h:outputLink value="plugin-list.xhtml" > - <h:outputText value="Installed Plugins"/> + <f:param name="tab" value="#{plugin.deployment}"/> + <h:outputText value="Installed #{plugin.deployment == 'SERVER' ? 'Server' : 'Agent'} Plugins"/> </h:outputLink> > <h:outputLink value="#" > diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-list.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-list.xhtml index f9addf1..bcb0ee7 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-list.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-list.xhtml @@ -39,11 +39,11 @@ </f:facet>
<h:panelGrid columns="1" width="100%"> - rich:tabPanel + <rich:tabPanel switchType="ajax" selectedTab="#{InstalledPluginsUIBean.selectedTab}">
<!-- ========== AGENT PLUGINS TAB ========== -->
- <rich:tab label="Agent Plugins"> + <rich:tab name="AGENT" label="Agent Plugins">
<rich:dataTable id="agentPluginsDataTable" value="#{InstalledPluginsUIBean.installedAgentPlugins}" @@ -131,7 +131,7 @@
<!-- ========== SERVER PLUGINS TAB ========== -->
- <rich:tab label="Server Plugins"> + <rich:tab name="SERVER" label="Server Plugins">
<rich:dataTable id="serverPluginsDataTable" value="#{InstalledPluginsUIBean.installedServerPlugins}"
commit 8b84420e8c04f7be1611042e8e466e6a2de80c5b Author: Shannon Hughes shughes@scooby.rdu.redhat.com Date: Fri Dec 4 13:53:35 2009 -0500
plugin and resource config vars for Active Server Integration
diff --git a/modules/plugins/samba/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/samba/src/main/resources/META-INF/rhq-plugin.xml index a98da65..958c44b 100644 --- a/modules/plugins/samba/src/main/resources/META-INF/rhq-plugin.xml +++ b/modules/plugins/samba/src/main/resources/META-INF/rhq-plugin.xml @@ -16,6 +16,15 @@ class="SambaServerComponent">
<plugin-configuration> + <c:group name="Active Server Directory"> + <c:simple-property name="krealm" displayName="Kerberos Realm" required="false"/> + <c:simple-property name="kdc" displayName="KDC" required="false"/> + <c:simple-property name="kadmin" displayName="Admin Server" required="false"/> + <c:simple-property name="realm" displayName="ADS Realm" required="false"/> + <c:simple-property name="domain" displayName="Domain" required="false"/> + </c:group> + + <c:group name="Augeas"> <c:simple-property name="augeasModuleName" displayName="Augeas Module Name" default="Samba" required="true" readOnly="true" description="the name of the Augeas module/lens to use for loading and updating this resource's configuration"/>
@@ -25,6 +34,7 @@
<c:simple-property name="resourceConfigurationRootNode" required="true" readOnly="true" default="/files/etc/samba/smb.conf/target[.='global']"/> + </c:group> </plugin-configuration>
<resource-configuration> @@ -54,6 +64,16 @@ <c:simple-property name="cups options" required="false" description="Free form string of options passed to cups library"/>
</c:group> + + <c:group name="Active Server Directory"> + <c:simple-property name="idmap uid" required="false" displayName="Idmap UID" description="Specifies range of users ids that are allocated for use in mapping Linux users to NT user SIDs"/> + <c:simple-property name="idmap gid" required="false" displayName="Idmap GID" description="Specifies range of group ids that are allocated for use in mapping Linux groups to NT group SIDs"/> + <c:simple-property name="winbind use default domain" required="false" displayName="Use default domain" type="boolean" description="Operate on users without domain component in usernames"/> + <c:simple-property name="winbind offline logon" required="false" displayName="Offline logon" type="boolean" description="Use pam_winbind module with Cached Credentials"/> + <c:simple-property name="winbind enum users" required="false" displayName="User enumeration" type="boolean" description="Allow enumeration of user info"/> + <c:simple-property name="winbind enum groups" required="false" displayName="User enumeration" type="boolean" description="Allow enumeration of group info"/> + <c:simple-property name="winbind separator" required="false" displayName="Winbind separator" description="Character used when listing a username in the DOMAIN\user format"/> + </c:group> </resource-configuration>
<service name="Samba Share" description="a Samba share"
commit 1985394679171bb1974e968060c32c3ffbf8b83a Merge: ebc80a1... e1daafc... Author: Adam Young ayoung@redhat.com Date: Fri Dec 4 13:29:22 2009 -0500
Merge branch 'raw-config' of ssh://git.fedorahosted.org/git/rhq/rhq into raw-config
commit ebc80a11d8bc573298bd1a34d1dbd15c05094d75 Author: Adam Young ayoung@redhat.com Date: Fri Dec 4 13:28:33 2009 -0500
Cleaned up navigation, made it so view-raw tracks the link clicked
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/RawConfiguration.java b/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/RawConfiguration.java index 1bb27c9..069ca34 100644 --- a/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/RawConfiguration.java +++ b/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/RawConfiguration.java @@ -23,7 +23,7 @@
package org.rhq.core.domain.configuration;
-import org.rhq.core.util.MessageDigestGenerator; +import java.io.Serializable;
import javax.persistence.Column; import javax.persistence.Entity; @@ -36,7 +36,8 @@ import javax.persistence.PrePersist; import javax.persistence.PreUpdate; import javax.persistence.SequenceGenerator; import javax.persistence.Table; -import java.io.Serializable; + +import org.rhq.core.util.MessageDigestGenerator;
/** * Resources support structured configuration as well as raw configuration which is represented by this class. A raw @@ -122,6 +123,14 @@ public class RawConfiguration implements Serializable, DeepCopyable<RawConfigura updateSha256(); }
+ public String getContentString() { + return new String(getContents()); + } + + public void setContentString(String newValue) { + setContents(newValue.getBytes()); + } + private byte[] copy(byte[] original) { byte[] copy = new byte[original.length]; for (int i = 0; i < original.length; ++i) { @@ -206,7 +215,7 @@ public class RawConfiguration implements Serializable, DeepCopyable<RawConfigura if (this.path == null && that.path == null) { return true; } - if ((this.path !=null && that.path != null) && this.path.equals(that.path)) { + if ((this.path != null && that.path != null) && this.path.equals(that.path)) { return true; } } @@ -230,14 +239,9 @@ public class RawConfiguration implements Serializable, DeepCopyable<RawConfigura
@Override public String toString() { - return new StringBuilder() - .append(getClass().getSimpleName()) - .append("[id=").append(id) - .append(", path=").append(path) - .append(", sha256=").append(sha256) - .append(", configuration=").append(configuration) - .append("]") - .toString(); + return new StringBuilder().append(getClass().getSimpleName()).append("[id=").append(id).append(", path=") + .append(path).append(", sha256=").append(sha256).append(", configuration=").append(configuration).append( + "]").toString(); }
public RawConfiguration deepCopy(boolean keepId) { @@ -247,7 +251,7 @@ public class RawConfiguration implements Serializable, DeepCopyable<RawConfigura }
copy.path = this.path; - + if (this.contents != null) { copy.setContents(this.getContents()); } @@ -256,4 +260,3 @@ public class RawConfiguration implements Serializable, DeepCopyable<RawConfigura }
} - diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ExistingResourceConfigurationUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ExistingResourceConfigurationUIBean.java index bb93d81..b7a781d 100644 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ExistingResourceConfigurationUIBean.java +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ExistingResourceConfigurationUIBean.java @@ -51,16 +51,23 @@ import org.rhq.enterprise.server.util.LookupUtil; /** * @author Ian Springer */ -//@ Name(value = "ExistingResourceConfigurationUIBean") -//@ Scope(ScopeType.PAGE) public class ExistingResourceConfigurationUIBean extends AbstractConfigurationUIBean { public static final String MANAGED_BEAN_NAME = "ExistingResourceConfigurationUIBean";
+ /** + * + */ + private String selectedPath; + private TreeMap<String, RawConfiguration> raws; + private TreeMap<String, RawConfiguration> modified = new TreeMap<String, RawConfiguration>(); + private RawConfiguration current = null; + // =========== actions ===========
public ExistingResourceConfigurationUIBean() { removeSessionScopedBeanIfInView("/rhq/resource/configuration/view.xhtml", ExistingResourceConfigurationUIBean.class); + }
public String editConfiguration() { @@ -81,6 +88,9 @@ public class ExistingResourceConfigurationUIBean extends AbstractConfigurationUI }
public String updateConfiguration() { + + modified = null; + return updateConfiguration(true);
} @@ -94,9 +104,9 @@ public class ExistingResourceConfigurationUIBean extends AbstractConfigurationUI ConfigurationMaskingUtility.unmaskConfiguration(getConfiguration(), getConfigurationDefinition()); int resourceId = EnterpriseFacesContextUtility.getResource().getId();
- AbstractResourceConfigurationUpdate updateRequest = - this.configurationManager.updateStructuredOrRawConfiguration(EnterpriseFacesContextUtility.getSubject(), - resourceId, getMergedConfiguration(), fromStructured); + AbstractResourceConfigurationUpdate updateRequest = this.configurationManager + .updateStructuredOrRawConfiguration(EnterpriseFacesContextUtility.getSubject(), resourceId, + getMergedConfiguration(), fromStructured); if (updateRequest != null) { switch (updateRequest.getStatus()) { case SUCCESS: @@ -224,27 +234,6 @@ public class ExistingResourceConfigurationUIBean extends AbstractConfigurationUI return getConfiguration().getId(); }
- /* - public Configuration getConfiguration() { - if (null == configuration) { - - Subject subject = EnterpriseFacesContextUtility.getSubject(); - int resourceId = EnterpriseFacesContextUtility.getResource().getId(); - AbstractResourceConfigurationUpdate configurationUpdate = LookupUtil.getConfigurationManager() - .getLatestResourceConfigurationUpdate(subject, resourceId); - Configuration configuration = (configurationUpdate != null) ? configurationUpdate.getConfiguration() : null; - if (configuration != null) { - //ConfigurationMaskingUtility.maskConfiguration(configuration, getConfigurationDefinition()); - } - - return configuration; - - } - return configuration; - - } - */ - private ConfigurationFormat getConfigurationFormat() { return getConfigurationDefinition().getConfigurationFormat(); } @@ -333,10 +322,10 @@ public class ExistingResourceConfigurationUIBean extends AbstractConfigurationUI
public void setCurrentContents(String updated) {
- String original = new String(getCurrent().getContents()); + String original = getCurrent().getContentString(); if (!updated.equals(original)) { current = current.deepCopy(false); - current.setContents(updated.getBytes()); + current.setContentString(updated); //TODO update other values like MD5 getModified().put(current.getPath(), current); } @@ -358,14 +347,6 @@ public class ExistingResourceConfigurationUIBean extends AbstractConfigurationUI
/** * This is a no-op, since the upload work was done by upload file - * But is kept as a target for the "save" icon from the full screen page - */ - public String update() { - return "/rhq/resource/configuration/edit-raw.xhtml?currentResourceId=" + getResourceId(); - } - - /** - * This is a no-op, since the upload work was done by upload file * But is kept as a target for the "action" value */ public String upload() { @@ -442,12 +423,4 @@ public class ExistingResourceConfigurationUIBean extends AbstractConfigurationUI return raws; }
- /** - * - */ - String selectedPath; - private TreeMap<String, RawConfiguration> raws; - TreeMap<String, RawConfiguration> modified = new TreeMap<String, RawConfiguration>(); - RawConfiguration current = null; - } \ No newline at end of file diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-navigation/configuration-navigation.xml b/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-navigation/configuration-navigation.xml index 4443b36..764f6fb 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-navigation/configuration-navigation.xml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-navigation/configuration-navigation.xml @@ -6,7 +6,6 @@
<navigation-rule>
- <navigation-case> <from-action>#{ExistingResourceConfigurationUIBean.editConfiguration}</from-action> <to-view-id>/rhq/resource/configuration/edit.xhtml?id=#{param.id}</to-view-id> @@ -26,13 +25,6 @@
</navigation-rule>
- <navigation-rule> - <from-view-id>/rhq/resource/configuration/edit-raw-full.xhtml</from-view-id> - <navigation-case> - <from-action> #{RawConfigCollection.update}</from-action> - <to-view-id>/rhq/resource/configuration/edit-raw.xhtml?id=#{param.id}</to-view-id> - </navigation-case> - </navigation-rule>
<navigation-rule>
@@ -44,8 +36,7 @@ <to-view-id>/rhq/resource/configuration/history.xhtml?id=#{param.id}</to-view-id> <redirect/> </navigation-case> - - + </navigation-rule>
commit 562e9a95e7a1926c79bfbba89f4985a4a2909cb8 Author: Heiko W. Rupp pilhuhn@fedorapeople.org Date: Fri Dec 4 18:58:52 2009 +0100
First cut at an snmp alert sender plugin and removal of the old sender method
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerBean.java index 940262a..ec99907 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerBean.java @@ -25,7 +25,6 @@ import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.Date; import java.util.HashMap; -import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; @@ -58,13 +57,9 @@ import org.rhq.core.domain.alert.notification.AlertNotification; import org.rhq.core.domain.alert.notification.AlertNotificationLog; import org.rhq.core.domain.alert.notification.EmailNotification; import org.rhq.core.domain.alert.notification.RoleNotification; -import org.rhq.core.domain.alert.notification.SnmpNotification; import org.rhq.core.domain.alert.notification.SubjectNotification; import org.rhq.core.domain.auth.Subject; import org.rhq.core.domain.authz.Permission; -import org.rhq.core.domain.configuration.Configuration; -import org.rhq.core.domain.configuration.Property; -import org.rhq.core.domain.configuration.PropertySimple; import org.rhq.core.domain.criteria.AlertCriteria; import org.rhq.core.domain.measurement.MeasurementSchedule; import org.rhq.core.domain.measurement.MeasurementUnits; @@ -659,10 +654,6 @@ public class AlertManagerBean implements AlertManagerLocal, AlertManagerRemote { String emailAddress = emailNotification.getEmailAddress();
processEmailAddress(alert, emailAddress, emailAddresses); - } else if (alertNotification instanceof SnmpNotification) { - SnmpNotification snmpNotification = (SnmpNotification) alertNotification; - - sendAlertSnmpTrap(alert, snmpNotification); }
@@ -882,44 +873,23 @@ public class AlertManagerBean implements AlertManagerLocal, AlertManagerRemote { return builder.toString(); }
- private String prettyPrintAlertURL(Alert alert) { + public String prettyPrintAlertURL(Alert alert) { StringBuilder builder = new StringBuilder();
String baseUrl = systemManager.getSystemConfiguration().getProperty(RHQConstants.BaseURL); builder.append(baseUrl); - if (baseUrl.endsWith("/") == false) { + if (!baseUrl.endsWith("/")) { builder.append("/"); }
builder.append("alerts/Alerts.do?mode=viewAlert");
- builder.append("&id=" + alert.getAlertDefinition().getResource().getId()); - builder.append("&a=" + alert.getId()); + builder.append("&id=").append(alert.getAlertDefinition().getResource().getId()); + builder.append("&a=").append(alert.getId());
return builder.toString(); }
- private void sendAlertSnmpTrap(Alert alert, SnmpNotification snmpNotification) { - SnmpTrapSender snmpTrapSender = new SnmpTrapSender(); - log.debug("Sending SNMP trap with OID " + snmpNotification.getOid() + " to SNMP engine " - + snmpNotification.getHost() + ":" + snmpNotification.getPort() + "..."); - String result; - List<Resource> lineage = resourceManager.getResourceLineage(alert.getAlertDefinition().getResource().getId()); - String platformName = lineage.get(0).getName(); - String conditions = prettyPrintAlertConditions(alert.getConditionLogs()); - String alertUrl = prettyPrintAlertURL(alert); - try { - if (bootTime == null) - bootTime = LookupUtil.getCoreServer().getBootTime(); - result = snmpTrapSender.sendSnmpTrap(alert, snmpNotification, platformName, conditions, bootTime, alertUrl); - } catch (Throwable t) { - result = "failed - cause: " + t; - } - - log.debug("Result of sending SNMP trap: " + result); - // TODO: Log the action result to the DB (i.e. as an AlertNotificationLog). - // (see http://jira.jboss.com/jira/browse/JBNADM-1820) - }
private void processRecovery(AlertDefinition firedDefinition) { Subject overlord = subjectManager.getOverlord(); diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerLocal.java index a3d8ee5..efdf723 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerLocal.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerLocal.java @@ -115,4 +115,5 @@ public interface AlertManagerLocal {
PageList<Alert> findAlertsByCriteria(Subject subject, AlertCriteria criteria);
+ String prettyPrintAlertURL(Alert alert); } \ No newline at end of file diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/SnmpTrapSender.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/SnmpTrapSender.java deleted file mode 100644 index 000f8e5..0000000 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/SnmpTrapSender.java +++ /dev/null @@ -1,789 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2008 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.alert; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; -import java.util.Properties; -import java.util.StringTokenizer; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.snmp4j.CommandResponderEvent; -import org.snmp4j.CommunityTarget; -import org.snmp4j.MessageException; -import org.snmp4j.PDU; -import org.snmp4j.PDUv1; -import org.snmp4j.ScopedPDU; -import org.snmp4j.Snmp; -import org.snmp4j.Target; -import org.snmp4j.UserTarget; -import org.snmp4j.event.ResponseEvent; -import org.snmp4j.mp.CounterSupport; -import org.snmp4j.mp.DefaultCounterListener; -import org.snmp4j.mp.MPv3; -import org.snmp4j.mp.SnmpConstants; -import org.snmp4j.mp.StateReference; -import org.snmp4j.mp.StatusInformation; -import org.snmp4j.security.AuthMD5; -import org.snmp4j.security.AuthSHA; -import org.snmp4j.security.PrivAES128; -import org.snmp4j.security.PrivAES192; -import org.snmp4j.security.PrivAES256; -import org.snmp4j.security.PrivDES; -import org.snmp4j.security.SecurityLevel; -import org.snmp4j.security.SecurityModels; -import org.snmp4j.security.SecurityProtocols; -import org.snmp4j.security.USM; -import org.snmp4j.security.UsmUser; -import org.snmp4j.smi.Address; -import org.snmp4j.smi.Integer32; -import org.snmp4j.smi.IpAddress; -import org.snmp4j.smi.Null; -import org.snmp4j.smi.OID; -import org.snmp4j.smi.OctetString; -import org.snmp4j.smi.TcpAddress; -import org.snmp4j.smi.TimeTicks; -import org.snmp4j.smi.UdpAddress; -import org.snmp4j.smi.UnsignedInteger32; -import org.snmp4j.smi.Variable; -import org.snmp4j.smi.VariableBinding; -import org.snmp4j.transport.AbstractTransportMapping; -import org.snmp4j.transport.DefaultTcpTransportMapping; -import org.snmp4j.transport.DefaultUdpTransportMapping; -import org.snmp4j.util.PDUFactory; - -import org.rhq.core.domain.alert.Alert; -import org.rhq.core.domain.alert.notification.SnmpNotification; -import org.rhq.enterprise.server.RHQConstants; -import org.rhq.enterprise.server.util.LookupUtil; - -/** - * @author Ian Springer - */ -public class SnmpTrapSender implements PDUFactory { - public static final int DEFAULT = 0; - private static final String UDP_TRANSPORT = "udp"; - private static final String TCP_TRANSPORT = "tcp"; - - private Log log = LogFactory.getLog(SnmpTrapSender.class); - - private Target target; - - private OID authProtocol; - - private OID privProtocol; - - private OctetString privPassphrase; - - private OctetString authPassphrase; - - private OctetString community = new OctetString("public"); - - private OctetString contextEngineID; - - private OctetString contextName = new OctetString(); - - private OctetString securityName = new OctetString(); - - private TimeTicks sysUpTime = new TimeTicks(0); - - private OID trapOID = SnmpConstants.coldStart; - - private PDUv1 v1TrapPDU = new PDUv1(); - - private int version = SnmpConstants.version3; - - private int retries = 1; - - private int timeout = 1000; - - private int pduType = PDU.TRAP; - - private int maxRepetitions = 10; - - private int nonRepeaters = 0; - - private List<VariableBinding> vbs = new ArrayList<VariableBinding>(); - - private Address address; - - private int operation = DEFAULT; - - private boolean snmpEnabled; - - public SnmpTrapSender() { - this.snmpEnabled = init(); - } - - private void checkTrapVariables(List<VariableBinding> vbs) { - - if ((pduType == PDU.INFORM) || (pduType == PDU.TRAP)) { - if ((vbs.size() == 0) || ((vbs.size() >= 1) && (!(vbs.get(0)).getOid().equals(SnmpConstants.sysUpTime)))) { - vbs.add(0, new VariableBinding(SnmpConstants.sysUpTime, sysUpTime)); - } - - if ((vbs.size() == 1) || ((vbs.size() >= 2) && (!(vbs.get(1)).getOid().equals(SnmpConstants.snmpTrapOID)))) { - vbs.add(1, new VariableBinding(SnmpConstants.snmpTrapOID, trapOID)); - } - } - } - - private void addUsmUser(Snmp snmp) { - snmp.getUSM().addUser(securityName, - new UsmUser(securityName, authProtocol, authPassphrase, privProtocol, privPassphrase)); - } - - private Snmp createSnmpSession() throws IOException { - AbstractTransportMapping transport; - if (address instanceof TcpAddress) { - transport = new DefaultTcpTransportMapping(); - } else { - transport = new DefaultUdpTransportMapping(); - } - - // Could save some CPU cycles: - // transport.setAsyncMsgProcessingSupported(false); - Snmp snmp = new Snmp(transport); - - if (version == SnmpConstants.version3) { - USM usm = new USM(SecurityProtocols.getInstance(), new OctetString(MPv3.createLocalEngineID()), 0); - SecurityModels.getInstance().addSecurityModel(usm); - addUsmUser(snmp); - } - - return snmp; - } - - private Target createTarget() { - if (version == SnmpConstants.version3) { - UserTarget target = new UserTarget(); - if (authPassphrase != null) { - if (privPassphrase != null) { - target.setSecurityLevel(SecurityLevel.AUTH_PRIV); - } else { - target.setSecurityLevel(SecurityLevel.AUTH_NOPRIV); - } - } else { - target.setSecurityLevel(SecurityLevel.NOAUTH_NOPRIV); - } - - target.setSecurityName(securityName); - return target; - } else { - CommunityTarget target = new CommunityTarget(); - target.setCommunity(community); - return target; - } - } - - public PDU send() throws IOException { - Snmp snmp = createSnmpSession(); - this.target = createTarget(); - target.setVersion(version); - target.setAddress(address); - target.setRetries(retries); - target.setTimeout(timeout); - snmp.listen(); - - PDU request = createPDU(target); - if (request.getType() == PDU.GETBULK) { - request.setMaxRepetitions(maxRepetitions); - request.setNonRepeaters(nonRepeaters); - } - - for (Object vb : vbs) { - request.add((VariableBinding) vb); - } - - PDU response = null; - ResponseEvent responseEvent; - long startTime = System.currentTimeMillis(); - responseEvent = snmp.send(request, target); - if (responseEvent != null) { - response = responseEvent.getResponse(); - if (log.isDebugEnabled()) - log.debug("Received response after " + (System.currentTimeMillis() - startTime) + " millis"); - } - - snmp.close(); - return response; - } - - private void getVariableBindings(String args) { - String oid = args; - char type = 'i'; - String value = null; - int equal = oid.indexOf("={"); - if (equal > 0) { - oid = args.substring(0, equal); - type = args.charAt(equal + 2); - value = args.substring(args.indexOf('}') + 1); - } else if (oid.indexOf('-') > 0) { - StringTokenizer st = new StringTokenizer(oid, "-"); - if (st.countTokens() != 2) { - throw new IllegalArgumentException("Illegal OID range specified: '" + oid); - } - - oid = st.nextToken(); - VariableBinding vbLower = new VariableBinding(new OID(oid)); - vbs.add(vbLower); - long last = Long.parseLong(st.nextToken()); - long first = vbLower.getOid().lastUnsigned(); - for (long k = first + 1; k <= last; k++) { - OID nextOID = new OID(vbLower.getOid().getValue(), 0, vbLower.getOid().size() - 1); - nextOID.appendUnsigned(k); - VariableBinding next = new VariableBinding(nextOID); - vbs.add(next); - } - - return; - } - - VariableBinding vb = new VariableBinding(new OID(oid)); - if (value != null) { - Variable variable; - switch (type) { - case 'i': { - variable = new Integer32(Integer.parseInt(value)); - break; - } - - case 'u': { - variable = new UnsignedInteger32(Long.parseLong(value)); - break; - } - - case 's': { - variable = new OctetString(value); - break; - } - - case 'x': { - variable = OctetString.fromString(value, ':', 16); - break; - } - - case 'd': { - variable = OctetString.fromString(value, '.', 10); - break; - } - - case 'b': { - variable = OctetString.fromString(value, ' ', 2); - break; - } - - case 'n': { - variable = new Null(); - break; - } - - case 'o': { - variable = new OID(value); - break; - } - - case 't': { - variable = new TimeTicks(Long.parseLong(value)); - break; - } - - case 'a': { - variable = new IpAddress(value); - break; - } - - default: { - throw new IllegalArgumentException("Variable type " + type + " not supported"); - } - } - - vb.setVariable(variable); - } - - vbs.add(vb); - } - - private static OctetString createOctetString(String s) { - OctetString octetString; - if (s.startsWith("0x")) { - octetString = OctetString.fromHexString(s.substring(2), ':'); - } else { - octetString = new OctetString(s); - } - - return octetString; - } - - private static Address createAddress(SnmpNotification snmpNotification) { - // TODO: Make transport configurable (ips, 09/12/07). - final String transport = UDP_TRANSPORT; - String address = snmpNotification.getHost() + "/" + snmpNotification.getPort(); - if (transport.equalsIgnoreCase(UDP_TRANSPORT)) { - return new UdpAddress(address); - } else if (transport.equalsIgnoreCase(TCP_TRANSPORT)) { - return new TcpAddress(address); - } - - throw new IllegalArgumentException("Unknown transport: " + transport); - } - - protected String getVariableBindings(PDU response) { - StringBuffer strBuf = new StringBuffer(); - for (int i = 0; i < response.size(); i++) { - VariableBinding vb = response.get(i); - strBuf.append(vb.toString()); - } - - return strBuf.toString(); - } - - protected String getReport(PDU response) { - if (response.size() < 1) { - return "REPORT PDU does not contain a variable binding."; - } - - VariableBinding vb = response.get(0); - OID oid = vb.getOid(); - log.debug(" Current counter value is " + vb.getVariable() + "."); - - if (SnmpConstants.usmStatsUnsupportedSecLevels.equals(oid)) { - return "REPORT: Unsupported Security Level."; - } else if (SnmpConstants.usmStatsNotInTimeWindows.equals(oid)) { - return "REPORT: Message not within time window."; - } else if (SnmpConstants.usmStatsUnknownUserNames.equals(oid)) { - return "REPORT: Unknown user name."; - } else if (SnmpConstants.usmStatsUnknownEngineIDs.equals(oid)) { - return "REPORT: Unknown engine id."; - } else if (SnmpConstants.usmStatsWrongDigests.equals(oid)) { - return "REPORT: Wrong digest."; - } else if (SnmpConstants.usmStatsDecryptionErrors.equals(oid)) { - return "REPORT: Decryption error."; - } else if (SnmpConstants.snmpUnknownSecurityModels.equals(oid)) { - return "REPORT: Unknown security model."; - } else if (SnmpConstants.snmpInvalidMsgs.equals(oid)) { - return "REPORT: Invalid message."; - } else if (SnmpConstants.snmpUnknownPDUHandlers.equals(oid)) { - return "REPORT: Unknown PDU handler."; - } else if (SnmpConstants.snmpUnavailableContexts.equals(oid)) { - return "REPORT: Unavailable context."; - } else if (SnmpConstants.snmpUnknownContexts.equals(oid)) { - return "REPORT: Unknown context."; - } else { - return "REPORT contains unknown OID (" + oid.toString() + ")."; - } - } - - /** - * processPdu - * - * @param e CommandResponderEvent - */ - public synchronized void processPdu(CommandResponderEvent e) { - PDU command = e.getPDU(); - if (command != null) { - if (log.isDebugEnabled()) - log.debug(command.toString()); - if ((command.getType() != PDU.TRAP) && (command.getType() != PDU.V1TRAP) - && (command.getType() != PDU.REPORT) && (command.getType() != PDU.RESPONSE)) { - command.setErrorIndex(0); - command.setErrorStatus(0); - command.setType(PDU.RESPONSE); - StatusInformation statusInformation = new StatusInformation(); - StateReference ref = e.getStateReference(); - try { - e.getMessageDispatcher().returnResponsePdu(e.getMessageProcessingModel(), e.getSecurityModel(), - e.getSecurityName(), e.getSecurityLevel(), command, e.getMaxSizeResponsePDU(), ref, - statusInformation); - } catch (MessageException ex) { - log.error("Error while sending response: " + ex.getMessage()); - } - } - } - } - - public PDU createPDU(Target target) { - PDU request; - if (target.getVersion() == SnmpConstants.version3) { - request = new ScopedPDU(); - ScopedPDU scopedPDU = (ScopedPDU) request; - if (contextEngineID != null) { - scopedPDU.setContextEngineID(contextEngineID); - } - - if (contextName != null) { - scopedPDU.setContextName(contextName); - } - } else { - if (pduType == PDU.V1TRAP) { - v1TrapPDU.setTimestamp(sysUpTime.toLong()); - request = v1TrapPDU; - } else { - request = new PDU(); - } - } - - request.setType(pduType); - return request; - } - - /** - * This method sends the actual trap - * @param alert The alert to send - * @param snmpNotification the notification data (target agent) - * @param platformName the name of the platform the alert is on - * @param conditions a string that shows the alert conditions - * @param bootTime TODO - * @param alertUrl TODO - * @return 'Error code' of the operation - */ - public String sendSnmpTrap(Alert alert, SnmpNotification snmpNotification, String platformName, String conditions, - Date bootTime, String alertUrl) { - if (!this.snmpEnabled) { - return "SNMP is not enabled."; - } - - // TODO add a request id and a timestamp - - this.address = createAddress(snmpNotification); - String baseOid = snmpNotification.getOid(); - // bind the alert definitions name on the oid set in the alert - getVariableBindings(baseOid + ".1" + "={s}" + alert.getAlertDefinition().getName()); - // the resource the alert was defined on - getVariableBindings(baseOid + ".2" + "={s}" + alert.getAlertDefinition().getResource().getName()); - // the platform this resource is on - getVariableBindings(baseOid + ".3" + "={s}" + platformName); - // the conditions of this alert - getVariableBindings(baseOid + ".4" + "={s}" + conditions); - // severity of the alert - getVariableBindings(baseOid + ".5" + "={s}" + alert.getAlertDefinition().getPriority().toString().toLowerCase()); - // url of the alert detail - getVariableBindings(baseOid + ".6" + "={s}" + alertUrl); - - setSysUpTimeFromBootTime(bootTime); // needs to be called before checkTrapVariables(); - checkTrapVariables(this.vbs); - try { - PDU response = send(); - if ((getPduType() == PDU.TRAP) || (getPduType() == PDU.V1TRAP)) { - return (PDU.getTypeString(getPduType()) + " sent successfully"); - } else if (response == null) { - return ("Request timed out."); - } else if (response.getType() == PDU.REPORT) { - return getReport(response); - } else if (this.operation == DEFAULT) { - return "Response received with requestID=" + response.getRequestID() + ", errorIndex=" - + response.getErrorIndex() + ", " + "errorStatus=" + response.getErrorStatusText() + "(" - + response.getErrorStatus() + ")" + "\n" + getVariableBindings(response); - } else { - return "Received something strange: requestID=" + response.getRequestID() + ", errorIndex=" - + response.getErrorIndex() + ", " + "errorStatus=" + response.getErrorStatusText() + "(" - + response.getErrorStatus() + ")" + "\n" + getVariableBindings(response); - } - } catch (IOException ex) { - log.error(ex.getMessage()); - return "Error while trying to send request: " + ex.getMessage(); - } catch (IllegalArgumentException ex) { - log.error(ex.getMessage()); - return "SNMPAction configured incorrectly: " + ex.getMessage(); - } - } - - /** - * Calculate the time diff between system boot time and now and - * set the uptime variable from it. - * @param bootTime - */ - private void setSysUpTimeFromBootTime(Date bootTime) { - long now = System.currentTimeMillis(); - long delta; - if (bootTime != null) { - delta = now - bootTime.getTime(); - } else - delta = 0; - setSysUpTime(new TimeTicks(delta / 1000)); // TT is 100th of a second TODO : fix this !!! - - } - - private boolean init() { - Properties systemConfig = LookupUtil.getSystemManager().getSystemConfiguration(); - - String snmpVersion = systemConfig.getProperty(RHQConstants.SNMPVersion); - if ((snmpVersion != null) && (snmpVersion.length() > 0)) { - if (snmpVersion.equals("1")) { - this.version = SnmpConstants.version1; - this.pduType = PDU.V1TRAP; - } else if (snmpVersion.equals("2c")) { - this.version = SnmpConstants.version2c; - } else if (snmpVersion.equals("3")) { - this.version = SnmpConstants.version3; - } else { - throw new IllegalStateException("SNMP version " + snmpVersion + " is not supported."); - } - } else { - return false; - } - - if ((this.pduType == PDU.V1TRAP) && (this.version != SnmpConstants.version1)) { - throw new IllegalStateException("V1TRAP PDU type is only available for SNMP version 1"); - } - - String snmpAuthProtocol = systemConfig.getProperty(RHQConstants.SNMPAuthProtocol); - if ((snmpAuthProtocol != null) && (snmpAuthProtocol.length() > 0)) { - if (snmpAuthProtocol.equals("MD5")) { - this.authProtocol = AuthMD5.ID; - } else if (snmpAuthProtocol.equals("SHA")) { - this.authProtocol = AuthSHA.ID; - } else { - throw new IllegalStateException("SNMP authentication protocol unsupported: " + snmpAuthProtocol); - } - } - - snmpAuthProtocol = systemConfig.getProperty(RHQConstants.SNMPAuthPassphrase); - if ((snmpAuthProtocol != null) && (snmpAuthProtocol.length() > 0)) { - this.authPassphrase = createOctetString(snmpAuthProtocol); - } - - snmpAuthProtocol = systemConfig.getProperty(RHQConstants.SNMPPrivacyPassphrase); - if ((snmpAuthProtocol != null) && (snmpAuthProtocol.length() > 0)) { - this.privPassphrase = createOctetString(snmpAuthProtocol); - } - - snmpAuthProtocol = systemConfig.getProperty(RHQConstants.SNMPCommunity); - if ((snmpAuthProtocol != null) && (snmpAuthProtocol.length() > 0)) { - this.community = createOctetString(snmpAuthProtocol); - } - - snmpAuthProtocol = systemConfig.getProperty(RHQConstants.SNMPEngineID); - if ((snmpAuthProtocol != null) && (snmpAuthProtocol.length() > 0)) { - this.contextEngineID = createOctetString(snmpAuthProtocol); - } - - snmpAuthProtocol = systemConfig.getProperty(RHQConstants.SNMPContextName); - if ((snmpAuthProtocol != null) && (snmpAuthProtocol.length() > 0)) { - this.contextName = createOctetString(snmpAuthProtocol); - } - - snmpAuthProtocol = systemConfig.getProperty(RHQConstants.SNMPSecurityName); - if ((snmpAuthProtocol != null) && (snmpAuthProtocol.length() > 0)) { - this.securityName = createOctetString(snmpAuthProtocol); - } - - snmpAuthProtocol = systemConfig.getProperty(RHQConstants.SNMPTrapOID); - if ((snmpAuthProtocol != null) && (snmpAuthProtocol.length() > 0)) { - this.trapOID = new OID(snmpAuthProtocol); - } - - snmpAuthProtocol = systemConfig.getProperty(RHQConstants.SNMPEnterpriseOID); - if ((snmpAuthProtocol != null) && (snmpAuthProtocol.length() > 0)) { - this.v1TrapPDU.setEnterprise(new OID(snmpAuthProtocol)); - } - - snmpAuthProtocol = systemConfig.getProperty(RHQConstants.SNMPGenericID); - if ((snmpAuthProtocol != null) && (snmpAuthProtocol.length() > 0)) { - this.v1TrapPDU.setGenericTrap(Integer.parseInt(snmpAuthProtocol)); - } - - snmpAuthProtocol = systemConfig.getProperty(RHQConstants.SNMPSpecificID); - if ((snmpAuthProtocol != null) && (snmpAuthProtocol.length() > 0)) { - this.v1TrapPDU.setSpecificTrap(Integer.parseInt(snmpAuthProtocol)); - } - - snmpAuthProtocol = systemConfig.getProperty(RHQConstants.SNMPAgentAddress); - if ((snmpAuthProtocol != null) && (snmpAuthProtocol.length() > 0)) { - this.v1TrapPDU.setAgentAddress(new IpAddress(snmpAuthProtocol)); - } - - snmpAuthProtocol = systemConfig.getProperty(RHQConstants.SNMPPrivacyProtocol); - if ((snmpAuthProtocol != null) && (snmpAuthProtocol.length() > 0)) { - if (snmpAuthProtocol.equals("DES")) { - this.privProtocol = PrivDES.ID; - } else if ((snmpAuthProtocol.equals("AES128")) || (snmpAuthProtocol.equals("AES"))) { - this.privProtocol = PrivAES128.ID; - } else if (snmpAuthProtocol.equals("AES192")) { - this.privProtocol = PrivAES192.ID; - } else if (snmpAuthProtocol.equals("AES256")) { - this.privProtocol = PrivAES256.ID; - } else { - throw new IllegalArgumentException("Privacy protocol " + snmpAuthProtocol + " not supported"); - } - } - - // Set the default counter listener to return proper USM and MP error counters. - CounterSupport.getInstance().addCounterListener(new DefaultCounterListener()); - - return true; - } - - /*=== Getters and Setters ==============================================*/ - - public OctetString getAuthPassphrase() { - return authPassphrase; - } - - public void setAuthPassphrase(OctetString authPassphrase) { - this.authPassphrase = authPassphrase; - } - - public OID getAuthProtocol() { - return authProtocol; - } - - public void setAuthProtocol(OID authProtocol) { - this.authProtocol = authProtocol; - } - - public OctetString getCommunity() { - return community; - } - - public void setCommunity(OctetString community) { - this.community = community; - } - - public OctetString getContextEngineID() { - return contextEngineID; - } - - public void setContextEngineID(OctetString contextEngineID) { - this.contextEngineID = contextEngineID; - } - - public void setContextName(OctetString contextName) { - this.contextName = contextName; - } - - public OctetString getContextName() { - return contextName; - } - - public int getMaxRepetitions() { - return maxRepetitions; - } - - public void setMaxRepetitions(int maxRepetitions) { - this.maxRepetitions = maxRepetitions; - } - - public int getNonRepeaters() { - return nonRepeaters; - } - - public void setNonRepeaters(int nonRepeaters) { - this.nonRepeaters = nonRepeaters; - } - - public int getOperation() { - return operation; - } - - public void setOperation(int operation) { - this.operation = operation; - } - - public OctetString getPrivPassphrase() { - return privPassphrase; - } - - public void setPrivPassphrase(OctetString privPassphrase) { - this.privPassphrase = privPassphrase; - } - - public OID getPrivProtocol() { - return privProtocol; - } - - public void setPrivProtocol(OID privProtocol) { - this.privProtocol = privProtocol; - } - - public int getRetries() { - return retries; - } - - public void setRetries(int retries) { - this.retries = retries; - } - - public OctetString getSecurityName() { - return securityName; - } - - public void setSecurityName(OctetString securityName) { - this.securityName = securityName; - } - - public TimeTicks getSysUpTime() { - return sysUpTime; - } - - public void setSysUpTime(TimeTicks sysUpTime) { - this.sysUpTime = sysUpTime; - } - - public Target getTarget() { - return target; - } - - public void setTarget(Target target) { - this.target = target; - } - - public int getTimeout() { - return timeout; - } - - public void setTimeout(int timeout) { - this.timeout = timeout; - } - - public OID getTrapOID() { - return trapOID; - } - - public void setTrapOID(OID trapOID) { - this.trapOID = trapOID; - } - - public List getVbs() { - return vbs; - } - - public void setVbs(ArrayList vbs) { - this.vbs = vbs; - } - - public int getVersion() { - return version; - } - - public void setVersion(int version) { - this.version = version; - } - - public int getPduType() { - return pduType; - } - - public void setPduType(int pduType) { - this.pduType = pduType; - } -} \ No newline at end of file diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugins/alertSnmp/SnmpTrapSender.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugins/alertSnmp/SnmpTrapSender.java new file mode 100644 index 0000000..af66bce --- /dev/null +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugins/alertSnmp/SnmpTrapSender.java @@ -0,0 +1,798 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2008 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.plugins.alertSnmp; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Properties; +import java.util.StringTokenizer; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.snmp4j.CommandResponderEvent; +import org.snmp4j.CommunityTarget; +import org.snmp4j.MessageException; +import org.snmp4j.PDU; +import org.snmp4j.PDUv1; +import org.snmp4j.ScopedPDU; +import org.snmp4j.Snmp; +import org.snmp4j.Target; +import org.snmp4j.UserTarget; +import org.snmp4j.event.ResponseEvent; +import org.snmp4j.mp.CounterSupport; +import org.snmp4j.mp.DefaultCounterListener; +import org.snmp4j.mp.MPv3; +import org.snmp4j.mp.SnmpConstants; +import org.snmp4j.mp.StateReference; +import org.snmp4j.mp.StatusInformation; +import org.snmp4j.security.AuthMD5; +import org.snmp4j.security.AuthSHA; +import org.snmp4j.security.PrivAES128; +import org.snmp4j.security.PrivAES192; +import org.snmp4j.security.PrivAES256; +import org.snmp4j.security.PrivDES; +import org.snmp4j.security.SecurityLevel; +import org.snmp4j.security.SecurityModels; +import org.snmp4j.security.SecurityProtocols; +import org.snmp4j.security.USM; +import org.snmp4j.security.UsmUser; +import org.snmp4j.smi.Address; +import org.snmp4j.smi.Integer32; +import org.snmp4j.smi.IpAddress; +import org.snmp4j.smi.Null; +import org.snmp4j.smi.OID; +import org.snmp4j.smi.OctetString; +import org.snmp4j.smi.TcpAddress; +import org.snmp4j.smi.TimeTicks; +import org.snmp4j.smi.UdpAddress; +import org.snmp4j.smi.UnsignedInteger32; +import org.snmp4j.smi.Variable; +import org.snmp4j.smi.VariableBinding; +import org.snmp4j.transport.AbstractTransportMapping; +import org.snmp4j.transport.DefaultTcpTransportMapping; +import org.snmp4j.transport.DefaultUdpTransportMapping; +import org.snmp4j.util.PDUFactory; + +import org.rhq.core.domain.alert.Alert; +import org.rhq.core.domain.alert.notification.SnmpNotification; +import org.rhq.core.domain.configuration.Configuration; +import org.rhq.enterprise.server.RHQConstants; +import org.rhq.enterprise.server.plugin.pc.alert.ResultState; +import org.rhq.enterprise.server.plugin.pc.alert.SenderResult; +import org.rhq.enterprise.server.util.LookupUtil; + +/** + * @author Ian Springer + */ +public class SnmpTrapSender implements PDUFactory { + public static final int DEFAULT = 0; + private static final String UDP_TRANSPORT = "udp"; + private static final String TCP_TRANSPORT = "tcp"; + + private Log log = LogFactory.getLog(SnmpTrapSender.class); + + private Target target; + + private OID authProtocol; + + private OID privProtocol; + + private OctetString privPassphrase; + + private OctetString authPassphrase; + + private OctetString community = new OctetString("public"); + + private OctetString contextEngineID; + + private OctetString contextName = new OctetString(); + + private OctetString securityName = new OctetString(); + + private TimeTicks sysUpTime = new TimeTicks(0); + + private OID trapOID = SnmpConstants.coldStart; + + private PDUv1 v1TrapPDU = new PDUv1(); + + private int version = SnmpConstants.version3; + + private int retries = 1; + + private int timeout = 1000; + + private int pduType = PDU.TRAP; + + private int maxRepetitions = 10; + + private int nonRepeaters = 0; + + private List<VariableBinding> vbs = new ArrayList<VariableBinding>(); + + private Address address; + + private int operation = DEFAULT; + + private boolean snmpEnabled; + + public SnmpTrapSender() { + this.snmpEnabled = init(); + } + + private void checkTrapVariables(List<VariableBinding> vbs) { + + if ((pduType == PDU.INFORM) || (pduType == PDU.TRAP)) { + if ((vbs.size() == 0) || ((vbs.size() >= 1) && (!(vbs.get(0)).getOid().equals(SnmpConstants.sysUpTime)))) { + vbs.add(0, new VariableBinding(SnmpConstants.sysUpTime, sysUpTime)); + } + + if ((vbs.size() == 1) || ((vbs.size() >= 2) && (!(vbs.get(1)).getOid().equals(SnmpConstants.snmpTrapOID)))) { + vbs.add(1, new VariableBinding(SnmpConstants.snmpTrapOID, trapOID)); + } + } + } + + private void addUsmUser(Snmp snmp) { + snmp.getUSM().addUser(securityName, + new UsmUser(securityName, authProtocol, authPassphrase, privProtocol, privPassphrase)); + } + + private Snmp createSnmpSession() throws IOException { + AbstractTransportMapping transport; + if (address instanceof TcpAddress) { + transport = new DefaultTcpTransportMapping(); + } else { + transport = new DefaultUdpTransportMapping(); + } + + // Could save some CPU cycles: + // transport.setAsyncMsgProcessingSupported(false); + Snmp snmp = new Snmp(transport); + + if (version == SnmpConstants.version3) { + USM usm = new USM(SecurityProtocols.getInstance(), new OctetString(MPv3.createLocalEngineID()), 0); + SecurityModels.getInstance().addSecurityModel(usm); + addUsmUser(snmp); + } + + return snmp; + } + + private Target createTarget() { + if (version == SnmpConstants.version3) { + UserTarget target = new UserTarget(); + if (authPassphrase != null) { + if (privPassphrase != null) { + target.setSecurityLevel(SecurityLevel.AUTH_PRIV); + } else { + target.setSecurityLevel(SecurityLevel.AUTH_NOPRIV); + } + } else { + target.setSecurityLevel(SecurityLevel.NOAUTH_NOPRIV); + } + + target.setSecurityName(securityName); + return target; + } else { + CommunityTarget target = new CommunityTarget(); + target.setCommunity(community); + return target; + } + } + + public PDU send() throws IOException { + Snmp snmp = createSnmpSession(); + this.target = createTarget(); + target.setVersion(version); + target.setAddress(address); + target.setRetries(retries); + target.setTimeout(timeout); + snmp.listen(); + + PDU request = createPDU(target); + if (request.getType() == PDU.GETBULK) { + request.setMaxRepetitions(maxRepetitions); + request.setNonRepeaters(nonRepeaters); + } + + for (Object vb : vbs) { + request.add((VariableBinding) vb); + } + + PDU response = null; + ResponseEvent responseEvent; + long startTime = System.currentTimeMillis(); + responseEvent = snmp.send(request, target); + if (responseEvent != null) { + response = responseEvent.getResponse(); + if (log.isDebugEnabled()) + log.debug("Received response after " + (System.currentTimeMillis() - startTime) + " millis"); + } + + snmp.close(); + return response; + } + + private void getVariableBindings(String args) { + String oid = args; + char type = 'i'; + String value = null; + int equal = oid.indexOf("={"); + if (equal > 0) { + oid = args.substring(0, equal); + type = args.charAt(equal + 2); + value = args.substring(args.indexOf('}') + 1); + } else if (oid.indexOf('-') > 0) { + StringTokenizer st = new StringTokenizer(oid, "-"); + if (st.countTokens() != 2) { + throw new IllegalArgumentException("Illegal OID range specified: '" + oid); + } + + oid = st.nextToken(); + VariableBinding vbLower = new VariableBinding(new OID(oid)); + vbs.add(vbLower); + long last = Long.parseLong(st.nextToken()); + long first = vbLower.getOid().lastUnsigned(); + for (long k = first + 1; k <= last; k++) { + OID nextOID = new OID(vbLower.getOid().getValue(), 0, vbLower.getOid().size() - 1); + nextOID.appendUnsigned(k); + VariableBinding next = new VariableBinding(nextOID); + vbs.add(next); + } + + return; + } + + VariableBinding vb = new VariableBinding(new OID(oid)); + if (value != null) { + Variable variable; + switch (type) { + case 'i': { + variable = new Integer32(Integer.parseInt(value)); + break; + } + + case 'u': { + variable = new UnsignedInteger32(Long.parseLong(value)); + break; + } + + case 's': { + variable = new OctetString(value); + break; + } + + case 'x': { + variable = OctetString.fromString(value, ':', 16); + break; + } + + case 'd': { + variable = OctetString.fromString(value, '.', 10); + break; + } + + case 'b': { + variable = OctetString.fromString(value, ' ', 2); + break; + } + + case 'n': { + variable = new Null(); + break; + } + + case 'o': { + variable = new OID(value); + break; + } + + case 't': { + variable = new TimeTicks(Long.parseLong(value)); + break; + } + + case 'a': { + variable = new IpAddress(value); + break; + } + + default: { + throw new IllegalArgumentException("Variable type " + type + " not supported"); + } + } + + vb.setVariable(variable); + } + + vbs.add(vb); + } + + private static OctetString createOctetString(String s) { + OctetString octetString; + if (s.startsWith("0x")) { + octetString = OctetString.fromHexString(s.substring(2), ':'); + } else { + octetString = new OctetString(s); + } + + return octetString; + } + + private static Address createAddress(Configuration properties) { + // TODO: Make transport configurable (ips, 09/12/07). + + String host = properties.getSimpleValue("host",null); + String portS = properties.getSimpleValue("port","161"); + Integer port = Integer.valueOf(portS); + + final String transport = UDP_TRANSPORT; + String address = host + "/" + port; + if (transport.equalsIgnoreCase(UDP_TRANSPORT)) { + return new UdpAddress(address); + } else if (transport.equalsIgnoreCase(TCP_TRANSPORT)) { + return new TcpAddress(address); + } + + throw new IllegalArgumentException("Unknown transport: " + transport); + } + + protected String getVariableBindings(PDU response) { + StringBuffer strBuf = new StringBuffer(); + for (int i = 0; i < response.size(); i++) { + VariableBinding vb = response.get(i); + strBuf.append(vb.toString()); + } + + return strBuf.toString(); + } + + protected String getReport(PDU response) { + if (response.size() < 1) { + return "REPORT PDU does not contain a variable binding."; + } + + VariableBinding vb = response.get(0); + OID oid = vb.getOid(); + log.debug(" Current counter value is " + vb.getVariable() + "."); + + if (SnmpConstants.usmStatsUnsupportedSecLevels.equals(oid)) { + return "REPORT: Unsupported Security Level."; + } else if (SnmpConstants.usmStatsNotInTimeWindows.equals(oid)) { + return "REPORT: Message not within time window."; + } else if (SnmpConstants.usmStatsUnknownUserNames.equals(oid)) { + return "REPORT: Unknown user name."; + } else if (SnmpConstants.usmStatsUnknownEngineIDs.equals(oid)) { + return "REPORT: Unknown engine id."; + } else if (SnmpConstants.usmStatsWrongDigests.equals(oid)) { + return "REPORT: Wrong digest."; + } else if (SnmpConstants.usmStatsDecryptionErrors.equals(oid)) { + return "REPORT: Decryption error."; + } else if (SnmpConstants.snmpUnknownSecurityModels.equals(oid)) { + return "REPORT: Unknown security model."; + } else if (SnmpConstants.snmpInvalidMsgs.equals(oid)) { + return "REPORT: Invalid message."; + } else if (SnmpConstants.snmpUnknownPDUHandlers.equals(oid)) { + return "REPORT: Unknown PDU handler."; + } else if (SnmpConstants.snmpUnavailableContexts.equals(oid)) { + return "REPORT: Unavailable context."; + } else if (SnmpConstants.snmpUnknownContexts.equals(oid)) { + return "REPORT: Unknown context."; + } else { + return "REPORT contains unknown OID (" + oid.toString() + ")."; + } + } + + /** + * processPdu + * + * @param e CommandResponderEvent + */ + public synchronized void processPdu(CommandResponderEvent e) { + PDU command = e.getPDU(); + if (command != null) { + if (log.isDebugEnabled()) + log.debug(command.toString()); + if ((command.getType() != PDU.TRAP) && (command.getType() != PDU.V1TRAP) + && (command.getType() != PDU.REPORT) && (command.getType() != PDU.RESPONSE)) { + command.setErrorIndex(0); + command.setErrorStatus(0); + command.setType(PDU.RESPONSE); + StatusInformation statusInformation = new StatusInformation(); + StateReference ref = e.getStateReference(); + try { + e.getMessageDispatcher().returnResponsePdu(e.getMessageProcessingModel(), e.getSecurityModel(), + e.getSecurityName(), e.getSecurityLevel(), command, e.getMaxSizeResponsePDU(), ref, + statusInformation); + } catch (MessageException ex) { + log.error("Error while sending response: " + ex.getMessage()); + } + } + } + } + + public PDU createPDU(Target target) { + PDU request; + if (target.getVersion() == SnmpConstants.version3) { + request = new ScopedPDU(); + ScopedPDU scopedPDU = (ScopedPDU) request; + if (contextEngineID != null) { + scopedPDU.setContextEngineID(contextEngineID); + } + + if (contextName != null) { + scopedPDU.setContextName(contextName); + } + } else { + if (pduType == PDU.V1TRAP) { + v1TrapPDU.setTimestamp(sysUpTime.toLong()); + request = v1TrapPDU; + } else { + request = new PDU(); + } + } + + request.setType(pduType); + return request; + } + + /** + * This method sends the actual trap + * @param alert The alert to send + * @param snmpNotification the notification data (target agent) + * @param platformName the name of the platform the alert is on + * @param conditions a string that shows the alert conditions + * @param bootTime TODO + * @param alertUrl TODO + * @return 'Error code' of the operation + */ + public String sendSnmpTrap(Alert alert, Configuration alertParameters, String platformName, String conditions, + Date bootTime, String alertUrl) { + if (!this.snmpEnabled) { + return "SNMP is not enabled."; + } + + String baseOid = alertParameters.getSimpleValue("OID",null); + + // TODO add a request id and a timestamp + + this.address = createAddress(alertParameters); + // bind the alert definitions name on the oid set in the alert + getVariableBindings(baseOid + ".1" + "={s}" + alert.getAlertDefinition().getName()); + // the resource the alert was defined on + getVariableBindings(baseOid + ".2" + "={s}" + alert.getAlertDefinition().getResource().getName()); + // the platform this resource is on + getVariableBindings(baseOid + ".3" + "={s}" + platformName); + // the conditions of this alert + getVariableBindings(baseOid + ".4" + "={s}" + conditions); + // severity of the alert + getVariableBindings(baseOid + ".5" + "={s}" + alert.getAlertDefinition().getPriority().toString().toLowerCase()); + // url of the alert detail + getVariableBindings(baseOid + ".6" + "={s}" + alertUrl); + + setSysUpTimeFromBootTime(bootTime); // needs to be called before checkTrapVariables(); + checkTrapVariables(this.vbs); + try { + PDU response = send(); + if ((getPduType() == PDU.TRAP) || (getPduType() == PDU.V1TRAP)) { + return (PDU.getTypeString(getPduType()) + " sent successfully"); + } else if (response == null) { + return ("Request timed out."); + } else if (response.getType() == PDU.REPORT) { + return getReport(response); + } else if (this.operation == DEFAULT) { + return "Response received with requestID=" + response.getRequestID() + ", errorIndex=" + + response.getErrorIndex() + ", " + "errorStatus=" + response.getErrorStatusText() + "(" + + response.getErrorStatus() + ")" + "\n" + getVariableBindings(response); + } else { + return "Received something strange: requestID=" + response.getRequestID() + ", errorIndex=" + + response.getErrorIndex() + ", " + "errorStatus=" + response.getErrorStatusText() + "(" + + response.getErrorStatus() + ")" + "\n" + getVariableBindings(response); + } + } catch (IOException ex) { + log.error(ex.getMessage()); + return "Error while trying to send request: " + ex.getMessage(); + } catch (IllegalArgumentException ex) { + log.error(ex.getMessage()); + return "SNMPAction configured incorrectly: " + ex.getMessage(); + } + } + + /** + * Calculate the time diff between system boot time and now and + * set the uptime variable from it. + * @param bootTime + */ + private void setSysUpTimeFromBootTime(Date bootTime) { + long now = System.currentTimeMillis(); + long delta; + if (bootTime != null) { + delta = now - bootTime.getTime(); + } else + delta = 0; + setSysUpTime(new TimeTicks(delta / 1000)); // TT is 100th of a second TODO : fix this !!! + + } + + private boolean init() { + Properties systemConfig = LookupUtil.getSystemManager().getSystemConfiguration(); + + String snmpVersion = systemConfig.getProperty(RHQConstants.SNMPVersion); + if ((snmpVersion != null) && (snmpVersion.length() > 0)) { + if (snmpVersion.equals("1")) { + this.version = SnmpConstants.version1; + this.pduType = PDU.V1TRAP; + } else if (snmpVersion.equals("2c")) { + this.version = SnmpConstants.version2c; + } else if (snmpVersion.equals("3")) { + this.version = SnmpConstants.version3; + } else { + throw new IllegalStateException("SNMP version " + snmpVersion + " is not supported."); + } + } else { + return false; + } + + if ((this.pduType == PDU.V1TRAP) && (this.version != SnmpConstants.version1)) { + throw new IllegalStateException("V1TRAP PDU type is only available for SNMP version 1"); + } + + String snmpAuthProtocol = systemConfig.getProperty(RHQConstants.SNMPAuthProtocol); + if ((snmpAuthProtocol != null) && (snmpAuthProtocol.length() > 0)) { + if (snmpAuthProtocol.equals("MD5")) { + this.authProtocol = AuthMD5.ID; + } else if (snmpAuthProtocol.equals("SHA")) { + this.authProtocol = AuthSHA.ID; + } else { + throw new IllegalStateException("SNMP authentication protocol unsupported: " + snmpAuthProtocol); + } + } + + snmpAuthProtocol = systemConfig.getProperty(RHQConstants.SNMPAuthPassphrase); + if ((snmpAuthProtocol != null) && (snmpAuthProtocol.length() > 0)) { + this.authPassphrase = createOctetString(snmpAuthProtocol); + } + + snmpAuthProtocol = systemConfig.getProperty(RHQConstants.SNMPPrivacyPassphrase); + if ((snmpAuthProtocol != null) && (snmpAuthProtocol.length() > 0)) { + this.privPassphrase = createOctetString(snmpAuthProtocol); + } + + snmpAuthProtocol = systemConfig.getProperty(RHQConstants.SNMPCommunity); + if ((snmpAuthProtocol != null) && (snmpAuthProtocol.length() > 0)) { + this.community = createOctetString(snmpAuthProtocol); + } + + snmpAuthProtocol = systemConfig.getProperty(RHQConstants.SNMPEngineID); + if ((snmpAuthProtocol != null) && (snmpAuthProtocol.length() > 0)) { + this.contextEngineID = createOctetString(snmpAuthProtocol); + } + + snmpAuthProtocol = systemConfig.getProperty(RHQConstants.SNMPContextName); + if ((snmpAuthProtocol != null) && (snmpAuthProtocol.length() > 0)) { + this.contextName = createOctetString(snmpAuthProtocol); + } + + snmpAuthProtocol = systemConfig.getProperty(RHQConstants.SNMPSecurityName); + if ((snmpAuthProtocol != null) && (snmpAuthProtocol.length() > 0)) { + this.securityName = createOctetString(snmpAuthProtocol); + } + + snmpAuthProtocol = systemConfig.getProperty(RHQConstants.SNMPTrapOID); + if ((snmpAuthProtocol != null) && (snmpAuthProtocol.length() > 0)) { + this.trapOID = new OID(snmpAuthProtocol); + } + + snmpAuthProtocol = systemConfig.getProperty(RHQConstants.SNMPEnterpriseOID); + if ((snmpAuthProtocol != null) && (snmpAuthProtocol.length() > 0)) { + this.v1TrapPDU.setEnterprise(new OID(snmpAuthProtocol)); + } + + snmpAuthProtocol = systemConfig.getProperty(RHQConstants.SNMPGenericID); + if ((snmpAuthProtocol != null) && (snmpAuthProtocol.length() > 0)) { + this.v1TrapPDU.setGenericTrap(Integer.parseInt(snmpAuthProtocol)); + } + + snmpAuthProtocol = systemConfig.getProperty(RHQConstants.SNMPSpecificID); + if ((snmpAuthProtocol != null) && (snmpAuthProtocol.length() > 0)) { + this.v1TrapPDU.setSpecificTrap(Integer.parseInt(snmpAuthProtocol)); + } + + snmpAuthProtocol = systemConfig.getProperty(RHQConstants.SNMPAgentAddress); + if ((snmpAuthProtocol != null) && (snmpAuthProtocol.length() > 0)) { + this.v1TrapPDU.setAgentAddress(new IpAddress(snmpAuthProtocol)); + } + + snmpAuthProtocol = systemConfig.getProperty(RHQConstants.SNMPPrivacyProtocol); + if ((snmpAuthProtocol != null) && (snmpAuthProtocol.length() > 0)) { + if (snmpAuthProtocol.equals("DES")) { + this.privProtocol = PrivDES.ID; + } else if ((snmpAuthProtocol.equals("AES128")) || (snmpAuthProtocol.equals("AES"))) { + this.privProtocol = PrivAES128.ID; + } else if (snmpAuthProtocol.equals("AES192")) { + this.privProtocol = PrivAES192.ID; + } else if (snmpAuthProtocol.equals("AES256")) { + this.privProtocol = PrivAES256.ID; + } else { + throw new IllegalArgumentException("Privacy protocol " + snmpAuthProtocol + " not supported"); + } + } + + // Set the default counter listener to return proper USM and MP error counters. + CounterSupport.getInstance().addCounterListener(new DefaultCounterListener()); + + return true; + } + + /*=== Getters and Setters ==============================================*/ + + public OctetString getAuthPassphrase() { + return authPassphrase; + } + + public void setAuthPassphrase(OctetString authPassphrase) { + this.authPassphrase = authPassphrase; + } + + public OID getAuthProtocol() { + return authProtocol; + } + + public void setAuthProtocol(OID authProtocol) { + this.authProtocol = authProtocol; + } + + public OctetString getCommunity() { + return community; + } + + public void setCommunity(OctetString community) { + this.community = community; + } + + public OctetString getContextEngineID() { + return contextEngineID; + } + + public void setContextEngineID(OctetString contextEngineID) { + this.contextEngineID = contextEngineID; + } + + public void setContextName(OctetString contextName) { + this.contextName = contextName; + } + + public OctetString getContextName() { + return contextName; + } + + public int getMaxRepetitions() { + return maxRepetitions; + } + + public void setMaxRepetitions(int maxRepetitions) { + this.maxRepetitions = maxRepetitions; + } + + public int getNonRepeaters() { + return nonRepeaters; + } + + public void setNonRepeaters(int nonRepeaters) { + this.nonRepeaters = nonRepeaters; + } + + public int getOperation() { + return operation; + } + + public void setOperation(int operation) { + this.operation = operation; + } + + public OctetString getPrivPassphrase() { + return privPassphrase; + } + + public void setPrivPassphrase(OctetString privPassphrase) { + this.privPassphrase = privPassphrase; + } + + public OID getPrivProtocol() { + return privProtocol; + } + + public void setPrivProtocol(OID privProtocol) { + this.privProtocol = privProtocol; + } + + public int getRetries() { + return retries; + } + + public void setRetries(int retries) { + this.retries = retries; + } + + public OctetString getSecurityName() { + return securityName; + } + + public void setSecurityName(OctetString securityName) { + this.securityName = securityName; + } + + public TimeTicks getSysUpTime() { + return sysUpTime; + } + + public void setSysUpTime(TimeTicks sysUpTime) { + this.sysUpTime = sysUpTime; + } + + public Target getTarget() { + return target; + } + + public void setTarget(Target target) { + this.target = target; + } + + public int getTimeout() { + return timeout; + } + + public void setTimeout(int timeout) { + this.timeout = timeout; + } + + public OID getTrapOID() { + return trapOID; + } + + public void setTrapOID(OID trapOID) { + this.trapOID = trapOID; + } + + public List getVbs() { + return vbs; + } + + public void setVbs(ArrayList vbs) { + this.vbs = vbs; + } + + public int getVersion() { + return version; + } + + public void setVersion(int version) { + this.version = version; + } + + public int getPduType() { + return pduType; + } + + public void setPduType(int pduType) { + this.pduType = pduType; + } +} \ No newline at end of file diff --git a/modules/enterprise/server/plugins/alert-snmp/pom.xml b/modules/enterprise/server/plugins/alert-snmp/pom.xml new file mode 100644 index 0000000..62ec039 --- /dev/null +++ b/modules/enterprise/server/plugins/alert-snmp/pom.xml @@ -0,0 +1,162 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd%22%3E + <parent> + <artifactId>rhq-enterprise-server-plugins-parent</artifactId> + <groupId>org.rhq</groupId> + <version>1.4.0-SNAPSHOT</version> + </parent> + <modelVersion>4.0.0</modelVersion> + + <groupId>org.rhq</groupId> + <artifactId>alert-snmp</artifactId> + <version>1.4.0-SNAPSHOT</version> + + <name>RHQ Enterprise Server SNMP Alert Plugin</name> + + <scm> + <connection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/modules/enterprise/server/plugins/alert-snmp/</connection> + <developerConnection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/modules/enterprise/server/plugins/alert-snmp/</developerConnection> + </scm> + + <properties> + <scm.module.path>modules/enterprise/server/plugins/alert-snmp/</scm.module.path> + </properties> + + <dependencies> + + <dependency> + <groupId>org.rhq</groupId> + <artifactId>rhq-enterprise-server</artifactId> + <version>1.4.0-SNAPSHOT</version> + <scope>provided</scope> <!-- by JBossAS --> + </dependency> + + <!-- TODO: This is a fix for the Javac bug requiring annotations to be + available when compiling dependent classes. It is fixed in JDK 6 --> + <dependency> + <groupId>javax.persistence</groupId> + <artifactId>persistence-api</artifactId> + <version>1.0</version> + <scope>provided</scope> + </dependency> + + <dependency> + <groupId>jboss.jboss-embeddable-ejb3</groupId> + <artifactId>hibernate-all</artifactId> + <version>1.0.0.Alpha9</version> + <scope>provided</scope> + <!-- needed for referenced domain entities that use Hibernate annotations --> + </dependency> + + <dependency> + <groupId>org.snmp4j</groupId> + <artifactId>snmp4j</artifactId> + <version>1.8.2</version> + </dependency> + + + </dependencies> + + <build> + <plugins> + + <plugin> + <artifactId>maven-surefire-plugin</artifactId> + <configuration> + <excludedGroups>${rhq.testng.excludedGroups}</excludedGroups> + <!-- + <argLine>-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=y</argLine> + --> + </configuration> + </plugin> + + </plugins> + </build> + + <profiles> + + <profile> + <id>dev</id> + + <properties> + <rhq.rootDir>../../../../..</rhq.rootDir> + <rhq.containerDir>${rhq.rootDir}/${rhq.defaultDevContainerPath}</rhq.containerDir> + <rhq.deploymentDir>${rhq.containerDir}/jbossas/server/default/deploy/${rhq.earName}/rhq-serverplugins</rhq.deploymentDir> + </properties> + + <build> + <plugins> + + <plugin> + <artifactId>maven-antrun-plugin</artifactId> + <version>1.1</version> + <executions> + + <execution> + <id>deploy</id> + <phase>compile</phase> + <configuration> + <tasks> + <mkdir dir="${rhq.deploymentDir}" /> + <property name="deployment.file" location="${rhq.deploymentDir}/${project.build.finalName}.jar" /> + <echo>*** Updating ${deployment.file}...</echo> + <jar destfile="${deployment.file}" basedir="${project.build.outputDirectory}" /> + </tasks> + </configuration> + <goals> + <goal>run</goal> + </goals> + </execution> + + <execution> + <id>undeploy</id> + <phase>clean</phase> + <configuration> + <tasks> + <property name="deployment.file" location="${rhq.deploymentDir}/${project.build.finalName}.jar" /> + <echo>*** Deleting ${deployment.file}...</echo> + <delete file="${deployment.file}" /> + </tasks> + </configuration> + <goals> + <goal>run</goal> + </goals> + </execution> + + </executions> + </plugin> + + <plugin> + <artifactId>maven-dependency-plugin</artifactId> + <version>2.0</version> + <executions> + <execution> + <id>copy-snmp4j-jar</id> + <phase>process-resources</phase> + <goals> + <goal>copy</goal> + </goals> + <configuration> + <artifactItems> + <artifactItem> + <groupId>org.snmp4j</groupId> + <artifactId>snmp4j</artifactId> + <version>1.8.2</version> + </artifactItem> + </artifactItems> + <outputDirectory>${project.build.outputDirectory}/lib</outputDirectory> + </configuration> + </execution> + </executions> + </plugin> + + + </plugins> + </build> + </profile> + + </profiles> + +</project> diff --git a/modules/enterprise/server/plugins/alert-snmp/src/main/java/org/rhq/enterprise/server/plugins/alertSnmp/SnmpSender.java b/modules/enterprise/server/plugins/alert-snmp/src/main/java/org/rhq/enterprise/server/plugins/alertSnmp/SnmpSender.java new file mode 100644 index 0000000..cf34731 --- /dev/null +++ b/modules/enterprise/server/plugins/alert-snmp/src/main/java/org/rhq/enterprise/server/plugins/alertSnmp/SnmpSender.java @@ -0,0 +1,86 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2009 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.plugins.alertSnmp; + +import java.util.Date; +import java.util.List; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.rhq.core.domain.alert.Alert; +import org.rhq.core.domain.resource.Resource; +import org.rhq.enterprise.server.alert.AlertManagerLocal; +import org.rhq.enterprise.server.plugin.pc.alert.ResultState; +import org.rhq.enterprise.server.plugins.alertSnmp.SnmpTrapSender; +import org.rhq.enterprise.server.plugin.pc.alert.AlertSender; +import org.rhq.enterprise.server.plugin.pc.alert.SenderResult; +import org.rhq.enterprise.server.resource.ResourceManagerLocal; +import org.rhq.enterprise.server.util.LookupUtil; + +/** + * // TODO: Document this + * @author Heiko W. Rupp + */ +public class SnmpSender extends AlertSender { + + private final Log log = LogFactory.getLog(SnmpSender.class); + + @Override + public SenderResult send(Alert alert) { + + Date bootTime = null; + + + String oid = alertParameters.getSimpleValue("OID",null); + if (oid==null) { + return new SenderResult(ResultState.FAILURE,"no OID given"); + } + String host = alertParameters.getSimpleValue("host",null); + if (host==null) { + return new SenderResult(ResultState.FAILURE,"no host given"); + } + String portS = alertParameters.getSimpleValue("port","161"); + Integer port = Integer.valueOf(portS); + + AlertManagerLocal alertManager = LookupUtil.getAlertManager(); + ResourceManagerLocal resourceManager = LookupUtil.getResourceManager(); + + SnmpTrapSender snmpTrapSender = new SnmpTrapSender(); + log.debug("Sending SNMP trap with OID " + oid + " to SNMP engine " + + host + ":" + port + "..."); + String result; + List<Resource> lineage = resourceManager.getResourceLineage(alert.getAlertDefinition().getResource().getId()); + String platformName = lineage.get(0).getName(); + String conditions = alertManager.prettyPrintAlertConditions(alert); + String alertUrl = alertManager.prettyPrintAlertURL(alert); + try { + bootTime = new Date(); // TODO = LookupUtil.getCoreServer().getBootTime(); + result = snmpTrapSender.sendSnmpTrap(alert, alertParameters, platformName, conditions, bootTime, alertUrl); + } catch (Throwable t) { + result = "failed - cause: " + t; + } + + log.debug("Result of sending SNMP trap: " + result); + // TODO: Log the action result to the DB (i.e. as an AlertNotificationLog). + // (see http://jira.jboss.com/jira/browse/JBNADM-1820) + + return null; // TODO: Customise this generated block + } +} diff --git a/modules/enterprise/server/plugins/alert-snmp/src/main/resources/META-INF/rhq-serverplugin.xml b/modules/enterprise/server/plugins/alert-snmp/src/main/resources/META-INF/rhq-serverplugin.xml new file mode 100644 index 0000000..3f37a96 --- /dev/null +++ b/modules/enterprise/server/plugins/alert-snmp/src/main/resources/META-INF/rhq-serverplugin.xml @@ -0,0 +1,79 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<alert-plugin + name="alert-snmp" + displayName="Alert:SNMP" + xmlns="urn:xmlns:rhq-serverplugin.alert" + xmlns:c="urn:xmlns:rhq-configuration" + xmlns:serverplugin="urn:xmlns:rhq-serverplugin" + package="org.rhq.enterprise.server.plugins.alertSnmp" + description="Alert sender plugin that sends alert notifications via SNMP traps" + version="1.0" + > + + serverplugin:help + This alert sender plugin is used to send notifications via SNMP traps + </serverplugin:help> + + <!-- startup & tear down listener, + scheduled jobs + <serverplugin:plugin-component class="Foo" /> + --> + + + <!-- Global preferences for all mircoblog alerts --> + serverplugin:plugin-configuration + <c:simple-property name="snmpVersion" displayName="Snmp protcol version" type="string"> + <c:property-options> + <c:option value="1"/> + <c:option value="2c"/> + <c:option value="3"/> + </c:property-options> + </c:simple-property> + + <c:simple-property name="trapOid" displayName="Trap OID" description="OID for the trap sent" type="string"/> + <c:group name="1" displayName="Snmp version 1 properties" hiddenByDefault="true"> + <c:simple-property name="v1Community" type="string" default="public"/> + <c:simple-property name="engineId" /> + <c:simple-property name="genericId" /> + <c:simple-property name="enterpriseOid"/> + <c:simple-property name="specificId" /> + <c:simple-property name="agentAddress" description="Address of our SNMP agent"/> + </c:group> + <c:group name="2c" displayName="Snmp version 2c properties" hiddenByDefault="true"> + <c:simple-property name="v2Community" type="string"/> + </c:group> + <c:group name="3" displayName="Snmp version 3 properties" hiddenByDefault="true"> + <c:simple-property name="authProtocol" type="string" default="MD5"> + <c:property-options> + <c:option value="none"/> + <c:option value="MD5"/> + <c:option value="SHA"/> + </c:property-options> + </c:simple-property> + <c:simple-property name="privacyProtocol" default="AES"> + <c:property-options> + <c:option value="None"/> + <c:option value="DES"/> + <c:option value="AES"/> + <c:option value="AES192"/> + <c:option value="AES256"/> + </c:property-options> + </c:simple-property> + + + </c:group> + </serverplugin:plugin-configuration> + + <!-- How does this sender show up in drop downs etc --> + <short-name>SNMP</short-name> + + <!-- Class that does the actual sending --> + <plugin-class>SnmpSender</plugin-class> + + <alert-configuration> + <c:simple-property name="host" type="string" required="true" description="Trap target host"/> + <c:simple-property name="port" type="integer" required="false" default="161" description="Trap target port"/> + <c:simple-property name="OID" type="string" required="true" description="OID of the trap sent"/> + + </alert-configuration> +</alert-plugin> diff --git a/modules/enterprise/server/plugins/pom.xml b/modules/enterprise/server/plugins/pom.xml index e201de1..ad44fb0 100644 --- a/modules/enterprise/server/plugins/pom.xml +++ b/modules/enterprise/server/plugins/pom.xml @@ -43,6 +43,7 @@ <module>alert-mobicents</module> <module>alert-microblog</module> <module>alert-roles</module> + <module>alert-snmp</module> </modules>
</project>
commit 705d9808f7fd0d68d5987f487053b34ba7b42fd1 Author: Ian Springer ian.springer@redhat.com Date: Fri Dec 4 12:48:57 2009 -0500
change how activators are defined a bit; split out perm type into global perm type and resource perm type; remove subTab type (tab type will be used for both top-level tabs and sub-tabs; start on code for loading Resource tabs
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveManagerBean.java index 27fd2bb..ac31b33 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveManagerBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveManagerBean.java @@ -19,6 +19,7 @@ package org.rhq.enterprise.server.perspective;
import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -31,16 +32,18 @@ import javax.persistence.PersistenceContext; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory;
+import org.jetbrains.annotations.NotNull; import org.rhq.core.domain.auth.Subject; import org.rhq.core.domain.authz.Permission; +import org.rhq.core.domain.resource.Resource; import org.rhq.enterprise.server.RHQConstants; import org.rhq.enterprise.server.auth.SubjectManagerLocal; import org.rhq.enterprise.server.authz.AuthorizationManagerLocal; -import org.rhq.enterprise.server.xmlschema.generated.serverplugin.perspective.InventoryActivatorSetType; +import org.rhq.enterprise.server.xmlschema.generated.serverplugin.perspective.GlobalPermissionActivatorSetType; +import org.rhq.enterprise.server.xmlschema.generated.serverplugin.perspective.GlobalPermissionActivatorType; +import org.rhq.enterprise.server.xmlschema.generated.serverplugin.perspective.GlobalPermissionType; import org.rhq.enterprise.server.xmlschema.generated.serverplugin.perspective.MenuItemType; -import org.rhq.enterprise.server.xmlschema.generated.serverplugin.perspective.PermissionActivatorSetType; -import org.rhq.enterprise.server.xmlschema.generated.serverplugin.perspective.PermissionActivatorType; -import org.rhq.enterprise.server.xmlschema.generated.serverplugin.perspective.PermissionType; +import org.rhq.enterprise.server.xmlschema.generated.serverplugin.perspective.ResourceActivatorSetType;
@Stateless // @WebService(endpointInterface = "org.rhq.enterprise.server.perspective.PerspectiveManagerRemote") @@ -65,8 +68,7 @@ public class PerspectiveManagerBean implements PerspectiveManagerLocal, Perspect
/* (non-Javadoc) * @see org.rhq.enterprise.server.perspective.PerspectiveManagerLocal#getCoreMenu(org.rhq.core.domain.auth.Subject) - */ - @Override + */ public synchronized List<MenuItem> getCoreMenu(Subject subject) throws PerspectiveException { Integer sessionId = subject.getSessionId(); CacheEntry cacheEntry = cache.get(sessionId); @@ -101,6 +103,13 @@ public class PerspectiveManagerBean implements PerspectiveManagerLocal, Perspect return coreMenu; }
+ @NotNull + public List<Tab> getResourceTabs(Subject subject, Resource resource) + { + // TODO: implement + return Collections.emptyList(); + } + private void cleanCache() { Subject subject;
@@ -132,11 +141,11 @@ public class PerspectiveManagerBean implements PerspectiveManagerLocal, Perspect
for (MenuItem menuItem : menu) { MenuItemType item = menuItem.getItem(); - List<InventoryActivatorSetType> inventoryActivatorSets = item.getInventoryActivatorSet(); - List<PermissionActivatorSetType> permissionActivatorSets = item.getPermissionActivatorSet(); + List<ResourceActivatorSetType> inventoriedResourceActivatorSet = item.getInventoriedResourceActivatorSet(); + List<GlobalPermissionActivatorSetType> globalPermissionActivatorSet = item.getGlobalPermissionActivatorSet();
// Make sure activators are satisfied before copying - if (checkActivators(subject, inventoryActivatorSets, permissionActivatorSets)) { + if (checkActivators(subject, inventoriedResourceActivatorSet, globalPermissionActivatorSet)) { MenuItem copy = new MenuItem(menuItem.getItem());
result.add(copy); @@ -149,16 +158,16 @@ public class PerspectiveManagerBean implements PerspectiveManagerLocal, Perspect return result; }
- private boolean checkActivators(Subject subject, List<InventoryActivatorSetType> inventoryActivatorSets, - List<PermissionActivatorSetType> permissionActivatorSets) { + private boolean checkActivators(Subject subject, List<ResourceActivatorSetType> resourceActivatorSets, + List<GlobalPermissionActivatorSetType> permissionActivatorSets) {
// global perm checking is relatively fast, make sure these pass before checking inventory activators - for (PermissionActivatorSetType permissionActivatorSet : permissionActivatorSets) { + for (GlobalPermissionActivatorSetType permissionActivatorSet : permissionActivatorSets) { boolean any = permissionActivatorSet.isAny(); boolean anyPassed = false; boolean anyFailed = false;
- for (PermissionActivatorType permissionActivator : permissionActivatorSet.getPermissionActivator()) { + for (GlobalPermissionActivatorType permissionActivator : permissionActivatorSet.getGlobalPermissionActivator()) { boolean hasPermission = hasGlobalPermission(subject, permissionActivator.getPermission()); anyPassed = hasPermission; anyFailed = !hasPermission; @@ -176,15 +185,15 @@ public class PerspectiveManagerBean implements PerspectiveManagerLocal, Perspect } }
- for (InventoryActivatorSetType inventoryActivatorSet : inventoryActivatorSets) { + for (ResourceActivatorSetType resourceActivatorSet : resourceActivatorSets) { //TODO: impl }
return true; }
- private boolean hasGlobalPermission(Subject subject, PermissionType permissionType) { - if (permissionType == PermissionType.SUPERUSER) { + private boolean hasGlobalPermission(Subject subject, GlobalPermissionType permissionType) { + if (permissionType == GlobalPermissionType.SUPERUSER) { return authorizationManager.isSystemSuperuser(subject); }
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveManagerLocal.java index 18d46b4..1a25bd8 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveManagerLocal.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveManagerLocal.java @@ -23,10 +23,10 @@ import java.util.List; import javax.ejb.Local;
import org.rhq.core.domain.auth.Subject; +import org.rhq.core.domain.resource.Resource;
@Local public interface PerspectiveManagerLocal { - /** * Return the core menu for the specified subject. Depending on their inventory and roles the * core menu for one subject1 could differ from that of subject2. @@ -38,4 +38,13 @@ public interface PerspectiveManagerLocal { * @return */ List<MenuItem> getCoreMenu(Subject subject) throws PerspectiveException; + + /** + * Returns the list of tabs that should be displayed for the specified user for the specified Resource. + * + * @param subject a user + * @param resource an inventoried Resource + * @return the list of tabs that should be displayed for the specified user for the specified Resource + */ + List<Tab> getResourceTabs(Subject subject, Resource resource); } \ No newline at end of file diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/perspective/Tab.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/perspective/Tab.java new file mode 100644 index 0000000..5090824 --- /dev/null +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/perspective/Tab.java @@ -0,0 +1,75 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2008 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.perspective; + +import java.util.List; + +import org.rhq.enterprise.server.xmlschema.generated.serverplugin.perspective.TabType; + +/** + * A tab in the Resource or Group view. + * + * @author Ian Springer + */ +public class Tab +{ + private List<Tab> children; + private String name; + private String displayName; + private String url; + private String iconUrl; + + public Tab(TabType tab) + { + this.name = tab.getName(); + this.displayName = tab.getDisplayName(); + this.url = tab.getUrl(); + this.iconUrl = tab.getIconUrl(); + } + + public List<Tab> getChildren() + { + return children; + } + + public void setChildren(List<Tab> children) + { + this.children = children; + } + + public String getName() + { + return name; + } + + public String getDisplayName() + { + return displayName; + } + + public String getUrl() + { + return url; + } + + public String getIconUrl() + { + return iconUrl; + } +} diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/perspective/metadata/PerspectivePluginMetadataManager.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/perspective/metadata/PerspectivePluginMetadataManager.java index 099e9fe..b3b9eda 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/perspective/metadata/PerspectivePluginMetadataManager.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/perspective/metadata/PerspectivePluginMetadataManager.java @@ -32,12 +32,13 @@ import org.rhq.enterprise.server.xmlschema.generated.serverplugin.perspective.Me import org.rhq.enterprise.server.xmlschema.generated.serverplugin.perspective.PerspectivePluginDescriptorType; import org.rhq.enterprise.server.xmlschema.generated.serverplugin.perspective.PlacementType; import org.rhq.enterprise.server.xmlschema.generated.serverplugin.perspective.PositionType; +import org.rhq.enterprise.server.xmlschema.generated.serverplugin.perspective.TabType; import org.rhq.enterprise.server.xmlschema.generated.serverplugin.perspective.TaskType;
/** * This loads in all deployed perspective server plugins and maintains the complete set of * {@link #getMetadataManager() metadata} found in all plugin descriptors. Individual plugin - * metadata is irrelevant and not retrievable. The union of the perpective definitions is + * metadata is irrelevant and not retrievable. The union of the perspective definitions is * maintained and made available. Conflict resolution rules are applied as needed for * clashing perspective definitions. * @@ -46,7 +47,6 @@ import org.rhq.enterprise.server.xmlschema.generated.serverplugin.perspective.Ta * * @author Jay Shaughnessy */ - public class PerspectivePluginMetadataManager { private final String CORE_PERSPECTIVE_NAME = "CorePerspective";
@@ -59,6 +59,7 @@ public class PerspectivePluginMetadataManager { private boolean isStarted = false; private List<TaskType> globalTasks = null; private List<TaskType> resourceTasks = null; + private List<TabType> tabs; private List<MenuItem> coreMenu = null;
public PerspectivePluginMetadataManager() { @@ -97,8 +98,9 @@ public class PerspectivePluginMetadataManager { + CORE_PERSPECTIVE_NAME); }
- globalTasks = cp.getGlobalTask(); - resourceTasks = cp.getResourceTask(); + this.globalTasks = cp.getGlobalTask(); + this.resourceTasks = cp.getResourceTask(); + this.tabs = cp.getTab(); // TODO
// Setup core menus if (null == this.coreMenu) { @@ -194,4 +196,18 @@ public class PerspectivePluginMetadataManager { return coreMenu; }
+ public List<TaskType> getGlobalTasks() + { + return globalTasks; + } + + public List<TaskType> getResourceTasks() + { + return resourceTasks; + } + + public List<TabType> getTabs() + { + return tabs; + } } diff --git a/modules/enterprise/server/plugins/perspectives/core/perspective/src/main/resources/META-INF/rhq-serverplugin.xml b/modules/enterprise/server/plugins/perspectives/core/perspective/src/main/resources/META-INF/rhq-serverplugin.xml index b3bad4f..1cc754c 100644 --- a/modules/enterprise/server/plugins/perspectives/core/perspective/src/main/resources/META-INF/rhq-serverplugin.xml +++ b/modules/enterprise/server/plugins/perspectives/core/perspective/src/main/resources/META-INF/rhq-serverplugin.xml @@ -61,10 +61,10 @@ extensionPoint="coreMenu" name="administration" placement="after" /> - <permissionActivatorSet> - <permissionActivator + <globalPermissionActivatorSet> + <globalPermissionActivator permission="SUPERUSER" /> - </permissionActivatorSet> + </globalPermissionActivatorSet> </menuItem> <menuItem name="help" @@ -206,10 +206,10 @@ name="groups.groupDefinitions" placement="after" addBreak="true" /> - <permissionActivatorSet> - <permissionActivator + <globalPermissionActivatorSet> + <globalPermissionActivator permission="MANAGE_INVENTORY" /> - </permissionActivatorSet> + </globalPermissionActivatorSet> </menuItem> <menuItem name="groups.newGroupDefinition" @@ -219,10 +219,10 @@ extensionPoint="coreMenu" name="groups.newGroup" placement="after" /> - <permissionActivatorSet> - <permissionActivator + <globalPermissionActivatorSet> + <globalPermissionActivator permission="MANAGE_INVENTORY" /> - </permissionActivatorSet> + </globalPermissionActivatorSet> </menuItem> <menuItem name="groups.favoriteGroups" @@ -273,13 +273,13 @@ extensionPoint="coreMenu" name="administration.security" placement="after" /> - <permissionActivatorSet + <globalPermissionActivatorSet any="true"> - <permissionActivator + <globalPermissionActivator permission="MANAGE_INVENTORY" /> - <permissionActivator + <globalPermissionActivator permission="MANAGE_SETTINGS" /> - </permissionActivatorSet> + </globalPermissionActivatorSet> </menuItem> <menuItem name="administration.content" @@ -288,10 +288,10 @@ extensionPoint="coreMenu" name="administration.systemConfiguration" placement="after" /> - <permissionActivatorSet> - <permissionActivator + <globalPermissionActivatorSet> + <globalPermissionActivator permission="MANAGE_INVENTORY" /> - </permissionActivatorSet> + </globalPermissionActivatorSet> </menuItem> <menuItem name="administration.highAvailability" @@ -300,10 +300,10 @@ extensionPoint="coreMenu" name="administration.content" placement="after" /> - <permissionActivatorSet> - <permissionActivator + <globalPermissionActivatorSet> + <globalPermissionActivator permission="MANAGE_INVENTORY" /> - </permissionActivatorSet> + </globalPermissionActivatorSet> </menuItem> <menuItem name="administration.reports" @@ -331,10 +331,10 @@ extensionPoint="coreMenu" name="administration.download" placement="after" /> - <permissionActivatorSet> - <permissionActivator + <globalPermissionActivatorSet> + <globalPermissionActivator permission="MANAGE_SETTINGS" /> - </permissionActivatorSet> + </globalPermissionActivatorSet> </menuItem>
<!-- Core Menu: Debug --> @@ -513,10 +513,10 @@ extensionPoint="coreMenu" name="administration.systemConfiguration" placement="start" /> - <permissionActivatorSet> - <permissionActivator + <globalPermissionActivatorSet> + <globalPermissionActivator permission="MANAGE_SETTINGS" /> - </permissionActivatorSet> + </globalPermissionActivatorSet> </menuItem> <menuItem name="administration.systemConfiguration.plugins" @@ -526,10 +526,10 @@ extensionPoint="coreMenu" name="administration.systemConfiguration.settings" placement="after" /> - <permissionActivatorSet> - <permissionActivator + <globalPermissionActivatorSet> + <globalPermissionActivator permission="MANAGE_SETTINGS" /> - </permissionActivatorSet> + </globalPermissionActivatorSet> </menuItem> <menuItem name="administration.systemConfiguration.templates" @@ -539,10 +539,10 @@ extensionPoint="coreMenu" name="administration.systemConfiguration.plugins" placement="after" /> - <permissionActivatorSet> - <permissionActivator + <globalPermissionActivatorSet> + <globalPermissionActivator permission="MANAGE_INVENTORY" /> - </permissionActivatorSet> + </globalPermissionActivatorSet> </menuItem>
<!-- Core Menu: administration.content --> diff --git a/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-perspective.xsd b/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-perspective.xsd index 0dfb1a9..05fcb8b 100644 --- a/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-perspective.xsd +++ b/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-perspective.xsd @@ -66,12 +66,7 @@ maxOccurs="unbounded"> </xs:element> <xs:element - ref="perspective:resourceTab" - minOccurs="0" - maxOccurs="unbounded"> - </xs:element> - <xs:element - ref="perspective:resourceSubTab" + ref="perspective:tab" minOccurs="0" maxOccurs="unbounded"> </xs:element> @@ -117,7 +112,7 @@ </xs:annotation> </xs:element> <xs:element - ref="perspective:inventoryActivatorSet" + ref="perspective:inventoriedResourceActivatorSet" minOccurs="0" maxOccurs="unbounded"> xs:annotation @@ -128,7 +123,7 @@ </xs:annotation> </xs:element> <xs:element - ref="perspective:permissionActivatorSet" + ref="perspective:globalPermissionActivatorSet" minOccurs="0" maxOccurs="unbounded"> xs:annotation @@ -228,21 +223,22 @@ </xs:annotation> </xs:element> <xs:element - ref="perspective:inventoryActivatorSet" + ref="perspective:inventoriedResourceActivatorSet" minOccurs="0" maxOccurs="unbounded"> xs:annotation - xs:documentationActivate the extension only if the user has resources of the specified type in - inventory. Activated only if the user has the required permissions. Activated for resources only if - specified trait conditions are also met.</xs:documentation> + xs:documentationActivate the extension only if there is at least one Resource in inventory that + satisfies the specified conditions. Conditions include the Resource's type or facet, the current + user's permissions for the Resource, or a Resource trait with a certain value. + </xs:documentation> </xs:annotation> </xs:element> <xs:element - ref="perspective:permissionActivatorSet" + ref="perspective:globalPermissionActivatorSet" minOccurs="0" maxOccurs="unbounded"> xs:annotation - xs:documentationActivate the extension only if the user has the required global permissions. + xs:documentationActivate the extension only if the current user has the specified; global permissions. </xs:documentation> </xs:annotation> </xs:element> @@ -334,7 +330,7 @@ </xs:complexType>
<xs:element - name="resourceTab" + name="tab" type="perspective:TabType"> xs:annotation xs:documentation @@ -342,21 +338,7 @@ </xs:documentation> xs:appinfo <jaxb:class - name="PerspectiveResourceTabElement" /> - </xs:appinfo> - </xs:annotation> - </xs:element> - - <xs:element - name="resourceSubTab" - type="perspective:TabType"> - xs:annotation - xs:documentation - Add, Replace or Remove a resourceSubTab extension for a ResourceTab extension point. - </xs:documentation> - xs:appinfo - <jaxb:class - name="PerspectiveResourceSubTabElement" /> + name="TabElement" /> </xs:appinfo> </xs:annotation> </xs:element> @@ -373,21 +355,15 @@ </xs:annotation> </xs:element> <xs:element - ref="perspective:inventoryActivatorSet" + ref="perspective:currentResourceOrGroupActivatorSet" minOccurs="0" - maxOccurs="unbounded"> - xs:annotation - xs:documentationActivate the extension only if the user has resources of the specified type in - inventory. Activated only if the user has the required permissions. Activated for resources only if - specified trait conditions are also met.</xs:documentation> - </xs:annotation> - </xs:element> + maxOccurs="unbounded"/> <xs:element - ref="perspective:permissionActivatorSet" + ref="perspective:globalPermissionActivatorSet" minOccurs="0" maxOccurs="unbounded"> xs:annotation - xs:documentationActivate task only if the user has the required global permissions.</xs:documentation> + xs:documentationActivate tab only if the user has the required global permissions.</xs:documentation> </xs:annotation> </xs:element> </xs:sequence> @@ -448,18 +424,31 @@ </xs:complexType>
<xs:element - name="permissionActivatorSet" - type="perspective:PermissionActivatorSetType"> + name="globalPermissionActivatorSet" + type="perspective:GlobalPermissionActivatorSetType"> xs:annotation - xs:documentationOne or more permission conditions that must be satisfied in order for the extension to be + xs:documentationOne or more global permission conditions that must be satisfied in order for the extension to be active.</xs:documentation> xs:appinfo <jaxb:class - name="PermissionActivatorSetElement" /> + name="GlobalPermissionActivatorSetElement" /> </xs:appinfo> </xs:annotation> </xs:element>
+ <xs:element + name="resourcePermissionActivatorSet" + type="perspective:ResourcePermissionActivatorSetType"> + xs:annotation + xs:documentationOne or more Resource permission conditions that must be satisfied in order for the extension to be + active.</xs:documentation> + xs:appinfo + <jaxb:class + name="ResourcePermissionActivatorSetElement" /> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="traitActivatorSet" type="perspective:TraitActivatorSetType"> @@ -474,44 +463,69 @@ </xs:element>
<xs:element - name="inventoryActivatorSet" - type="perspective:InventoryActivatorSetType"> + name="inventoriedResourceActivatorSet" + type="perspective:ResourceActivatorSetType"> xs:annotation xs:documentationOne or more inventory conditions that must be satisfied in order for the extension to be active.</xs:documentation> xs:appinfo <jaxb:class - name="InventoryActivatorSetElement" /> + name="InventoriedResourceActivatorSetElement" /> + </xs:appinfo> + </xs:annotation> + </xs:element> + + <xs:element + name="currentResourceOrGroupActivatorSet" + type="perspective:ResourceActivatorSetType"> + xs:annotation + xs:documentationOne or more inventory conditions that must be satisfied in order for the extension to be + active.</xs:documentation> + xs:appinfo + <jaxb:class + name="CurrentResourceOrGroupActivatorSetElement" /> + </xs:appinfo> + </xs:annotation> + </xs:element> + + <xs:element + name="facetActivatorSet" + type="perspective:FacetActivatorSetType"> + xs:annotation + xs:documentationOne or more ResourceType facets that the current Resource or Compatible Group must implement + in order for the extension to be active.</xs:documentation> + xs:appinfo + <jaxb:class + name="FacetActivatorSetElement" /> </xs:appinfo> </xs:annotation> </xs:element>
<xs:complexType - name="PermissionActivatorSetType"> - xs:sequence - <xs:element - ref="perspective:permissionActivator" - minOccurs="0" - maxOccurs="unbounded"> - </xs:element> - </xs:sequence> - <xs:attribute - name="any" - type="xs:boolean" - use="optional" - default="false"> - xs:annotation - xs:documentationIf true extension activation passes if any individual activator is satisfied. If false all - activators must be satisfied. Default is false.</xs:documentation> - </xs:annotation> - </xs:attribute> + name="FacetActivatorSetType"> + xs:sequence + <xs:element + ref="perspective:facetActivator" + minOccurs="0" + maxOccurs="unbounded"/> + </xs:sequence> + <xs:attribute + name="any" + type="xs:boolean" + use="optional" + default="false"> + xs:annotation + xs:documentationIf true extension activation passes if any individual activator is satisfied. If false all + activators must be satisfied. Default is false.</xs:documentation> + </xs:annotation> + </xs:attribute> </xs:complexType>
<xs:complexType - name="TraitActivatorSetType"> + name="GlobalPermissionActivatorSetType"> xs:sequence <xs:element - ref="perspective:traitActivator" + ref="perspective:globalPermissionActivator" minOccurs="0" maxOccurs="unbounded"> </xs:element> @@ -528,11 +542,32 @@ </xs:attribute> </xs:complexType>
+ <xs:complexType + name="ResourcePermissionActivatorSetType"> + xs:sequence + <xs:element + ref="perspective:resourcePermissionActivator" + minOccurs="0" + maxOccurs="unbounded"> + </xs:element> + </xs:sequence> + <xs:attribute + name="any" + type="xs:boolean" + use="optional" + default="false"> + xs:annotation + xs:documentationIf true extension activation passes if any individual activator is satisfied. If false all + activators must be satisfied. Default is false.</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:complexType> + <xs:complexType - name="InventoryActivatorSetType"> + name="TraitActivatorSetType"> xs:sequence <xs:element - ref="perspective:inventoryActivator" + ref="perspective:traitActivator" minOccurs="0" maxOccurs="unbounded"> </xs:element> @@ -549,23 +584,86 @@ </xs:attribute> </xs:complexType>
+ <xs:complexType + name="ResourceActivatorSetType"> + xs:sequence + <xs:element + ref="perspective:resourceActivator" + minOccurs="0" + maxOccurs="unbounded"> + </xs:element> + </xs:sequence> + <xs:attribute + name="any" + type="xs:boolean" + use="optional" + default="false"> + xs:annotation + xs:documentationIf true extension activation passes if any individual activator is satisfied. If false all + activators must be satisfied. Default is false.</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:complexType> + <xs:element - name="permissionActivator" - type="perspective:PermissionActivatorType"> + name="globalPermissionActivator" + type="perspective:GlobalPermissionActivatorType"> xs:annotation - xs:documentationAn activator specifying a permission condition that must be satisfied in order for the + xs:documentationAn activator specifying a global permission condition that must be satisfied in order for the extension to be active.</xs:documentation> </xs:annotation> </xs:element>
+ <xs:element + name="resourcePermissionActivator" + type="perspective:ResourcePermissionActivatorType"> + xs:annotation + xs:documentationAn activator specifying a resource permission condition that must be satisfied in order for + the extension to be active.</xs:documentation> + </xs:annotation> + </xs:element> + + <xs:element + name="facetActivator" + type="perspective:FacetActivatorType"> + xs:annotation + xs:documentationAn activator specifying a facet that must be implemented by the current Resource or + Compatible Group in order for the extension to be active.</xs:documentation> + </xs:annotation> + </xs:element> + + <xs:complexType + name="FacetActivatorType"> + <xs:attribute + name="facet" + type="perspective:FacetType" + use="required"> + xs:annotation + xs:documentationThe required facet.</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:complexType> + + <xs:complexType + name="GlobalPermissionActivatorType"> + <xs:attribute + name="permission" + type="perspective:GlobalPermissionType" + use="required"> + xs:annotation + xs:documentationThe required Global permission.</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:complexType> + <xs:complexType - name="PermissionActivatorType"> + name="ResourcePermissionActivatorType"> <xs:attribute name="permission" - type="perspective:PermissionType" + type="perspective:ResourcePermissionType" use="required"> xs:annotation - xs:documentationThe required permission.</xs:documentation> + xs:documentationThe required Resource permission.</xs:documentation> </xs:annotation> </xs:attribute> </xs:complexType> @@ -620,23 +718,42 @@ </xs:complexType>
<xs:element - name="inventoryActivator" - type="perspective:InventoryActivatorType"> + name="resourceActivator" + type="perspective:ResourceActivatorType"> xs:annotation - xs:documentationAn activator specifying inventory conditions that must be satisfied in order for the + xs:documentationA Resource with this ResourceType must be in inventory in order for the extension to be active.</xs:documentation> xs:appinfo <jaxb:class - name="InventoryActivatorElement" /> + name="ResourceActivatorElement" /> </xs:appinfo> </xs:annotation> </xs:element>
+ <xs:element + name="resourceTypeActivator" + type="perspective:ResourceTypeActivatorType"> + xs:annotation + xs:documentationThe Resource or Compatible Group must be of this ResourceType + in order for the extension to be active.</xs:documentation> + xs:appinfo + <jaxb:class + name="ResourceTypeActivatorElement" /> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:complexType - name="InventoryActivatorType"> + name="ResourceActivatorType"> xs:sequence + xs:choice + <xs:element ref="perspective:resourceTypeActivator"> + </xs:element> + <xs:element ref="perspective:facetActivatorSet"> + </xs:element> + </xs:choice> <xs:element - ref="perspective:permissionActivatorSet" + ref="perspective:resourcePermissionActivatorSet" minOccurs="0" maxOccurs="unbounded"> </xs:element> @@ -665,6 +782,27 @@ </xs:attribute> </xs:complexType>
+ <xs:complexType + name="ResourceTypeActivatorType"> + <xs:attribute + name="plugin" + type="xs:string" + use="required"> + xs:annotation + xs:documentationPlugin for the specified resource type.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute + name="resourceType" + type="xs:string" + use="required"> + xs:annotation + xs:documentationResource Type that must be in inventory to activate the extension point. + </xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:complexType> + <xs:element name="position" type="perspective:PositionType"> @@ -839,7 +977,7 @@ </xs:simpleType>
<xs:simpleType - name="PermissionType"> + name="GlobalPermissionType"> <xs:restriction base="xs:string"> <xs:enumeration @@ -851,28 +989,76 @@ value="MANAGE_SECURITY"></xs:enumeration> <xs:enumeration value="MANAGE_SETTINGS"></xs:enumeration> - - <xs:enumeration - value="CONFIGURE"></xs:enumeration> - <xs:enumeration - value="CONTROL"></xs:enumeration> - <xs:enumeration - value="CREATE_CHILD_RESOURCE"></xs:enumeration> - <xs:enumeration - value="DELETE_RESOURCE"></xs:enumeration> - <xs:enumeration - value="MANAGE_ALERTS"></xs:enumeration> - <xs:enumeration - value="MANAGE_CONTENT"></xs:enumeration> - <xs:enumeration - value="MANAGE_MEASUREMENTS"></xs:enumeration> - <xs:enumeration - value="MODIFY_RESOURCE"></xs:enumeration> - <xs:enumeration - value="VIEW_RESOURCE"></xs:enumeration> </xs:restriction> </xs:simpleType>
+ <xs:simpleType + name="ResourcePermissionType"> + <xs:restriction + base="xs:string"> + <xs:enumeration + value="CONFIGURE"></xs:enumeration> + <xs:enumeration + value="CONTROL"></xs:enumeration> + <xs:enumeration + value="CREATE_CHILD_RESOURCE"></xs:enumeration> + <xs:enumeration + value="DELETE_RESOURCE"></xs:enumeration> + <xs:enumeration + value="MANAGE_ALERTS"></xs:enumeration> + <xs:enumeration + value="MANAGE_CONTENT"></xs:enumeration> + <xs:enumeration + value="MANAGE_MEASUREMENTS"></xs:enumeration> + <xs:enumeration + value="MODIFY_RESOURCE"></xs:enumeration> + <xs:enumeration + value="VIEW_RESOURCE"></xs:enumeration> + </xs:restriction> + </xs:simpleType> + + <xs:simpleType + name="FacetType"> + <xs:restriction + base="xs:string"> + <xs:enumeration value="measurement" > + xs:annotation + xs:documentationThe Resource type defines one or more metrics.</xs:documentation> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="event" > + xs:annotation + xs:documentationThe Resource type defines one or more events.</xs:documentation> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="pluginConfiguration" > + xs:annotation + xs:documentationThe Resource type defines one or more plugin configuration (aka connection) properties.</xs:documentation> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="configuration" > + xs:annotation + xs:documentationThe Resource type defines one or more resource configuration properties.</xs:documentation> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="operation" > + xs:annotation + xs:documentationThe Resource type defines one or more operations.</xs:documentation> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="content" > + xs:annotation + xs:documentationThe Resource type defines one or more packages.</xs:documentation> + </xs:annotation> + </xs:enumeration> + <xs:enumeration value="callTime" > + xs:annotation + xs:documentationThe Resource type defines one or more call-time metrics.</xs:documentation> + </xs:annotation> + </xs:enumeration> + </xs:restriction> + </xs:simpleType> + <xs:simpleType name="PlacementType"> xs:annotation
commit e1daafc42fd35e06ec493779dab01b7b95142097 Author: John Sanda jsanda@redhat.com Date: Fri Dec 4 12:21:55 2009 -0500
Adding unit tests for LegacyConfigManagemnt
In addition to adding tests, changing method name in ConfigManagement from execute() to executeLoad() to be consistent.
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigManagement.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigManagement.java index 3ad0df8..0c2d9fd 100644 --- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigManagement.java +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigManagement.java @@ -40,7 +40,7 @@ public interface ConfigManagement {
void setConfigurationUtilityService(ConfigurationUtilityService configUtilityService);
- Configuration execute(int resourceId) throws PluginContainerException; + Configuration executeLoad(int resourceId) throws PluginContainerException;
void executeUpdate(int resourceId, Configuration configuration) throws PluginContainerException; diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManager.java index 2bda0c3..b360858 100644 --- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManager.java +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManager.java @@ -245,7 +245,7 @@ public class ConfigurationManager extends AgentService implements ContainerServi Configuration configuration = null;
try { - configuration = loadConfig.execute(resourceId); + configuration = loadConfig.executeLoad(resourceId); } catch (Throwable t) { throw new PluginContainerException(createErrorMsg(resourceId, "An exception was thrown."), t); } diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LegacyConfigManagement.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LegacyConfigManagement.java index 9630eb9..d11c0aa 100644 --- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LegacyConfigManagement.java +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LegacyConfigManagement.java @@ -43,20 +43,23 @@ public class LegacyConfigManagement extends ConfigManagementSupport {
private static final Log log = LogFactory.getLog(LegacyConfigManagement.class);
- public Configuration execute(int resourceId) throws PluginContainerException { + public Configuration executeLoad(int resourceId) throws PluginContainerException { Configuration configuration = loadConfigFromFacet(resourceId, READ); + + if (configuration == null) { + return null; + } + ResourceType resourceType = componentService.getResourceType(resourceId);
- // If the plugin didn't already set the notes field, set it to something useful. if (configuration.getNotes() == null) { configuration.setNotes("Resource config for " + resourceType.getName() + " Resource w/ id " + resourceId); }
ConfigurationDefinition configurationDefinition = resourceType.getResourceConfigurationDefinition();
- // Normalize and validate the config. - ConfigurationUtility.normalizeConfiguration(configuration, configurationDefinition); - List<String> errorMessages = ConfigurationUtility.validateConfiguration(configuration, + configUtilityService.normalizeConfiguration(configuration, configurationDefinition); + List<String> errorMessages = configUtilityService.validateConfiguration(configuration, configurationDefinition); for (String errorMessage : errorMessages) { log.warn("Plugin Error: Invalid " + resourceType.getName() + " Resource configuration returned by " diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/RawConfigManagement.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/RawConfigManagement.java index 4f1ab96..5514784 100644 --- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/RawConfigManagement.java +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/RawConfigManagement.java @@ -39,7 +39,7 @@ public class RawConfigManagement extends ConfigManagementSupport {
private final Log log = LogFactory.getLog(RawConfigManagement.class);
- public Configuration execute(int resourceId) throws PluginContainerException { + public Configuration executeLoad(int resourceId) throws PluginContainerException { ResourceConfigurationFacet facet = loadResouceConfiguratonFacet(resourceId);
Set<RawConfiguration> rawConfigs = facet.loadRawConfigurations(); diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/StructuredAndRawConfigManagement.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/StructuredAndRawConfigManagement.java index 30dcc2e..3f976c7 100644 --- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/StructuredAndRawConfigManagement.java +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/StructuredAndRawConfigManagement.java @@ -40,7 +40,7 @@ public class StructuredAndRawConfigManagement extends ConfigManagementSupport {
private final Log log = LogFactory.getLog(StructuredAndRawConfigManagement.class);
- public Configuration execute(int resourceId) throws PluginContainerException { + public Configuration executeLoad(int resourceId) throws PluginContainerException { ResourceConfigurationFacet facet = loadResouceConfiguratonFacet(resourceId);
Configuration configuration = facet.loadStructuredConfiguration(); diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/StructuredConfigManagement.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/StructuredConfigManagement.java index 7a04d04..f807e72 100644 --- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/StructuredConfigManagement.java +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/StructuredConfigManagement.java @@ -36,7 +36,7 @@ public class StructuredConfigManagement extends ConfigManagementSupport {
private final Log log = LogFactory.getLog(StructuredConfigManagement.class);
- public Configuration execute(int resourceId) throws PluginContainerException { + public Configuration executeLoad(int resourceId) throws PluginContainerException { ResourceConfigurationFacet facet = loadResouceConfiguratonFacet(resourceId);
Configuration configuration = facet.loadStructuredConfiguration(); diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigManagementFactoryImplTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigManagementFactoryImplTest.java index 4e58e9c..4864fe2 100644 --- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigManagementFactoryImplTest.java +++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigManagementFactoryImplTest.java @@ -34,22 +34,18 @@ import org.rhq.core.domain.configuration.definition.ConfigurationFormat; import org.rhq.test.JMockTest; import org.jmock.Expectations;
-public class ConfigManagementFactoryImplTest extends JMockTest { +public class ConfigManagementFactoryImplTest extends ConfigManagementTest {
static final String LEGACY_AMPS_VERSION = "2.0";
static final String NON_LEGACY_AMPS_VERSION = "2.1";
- ComponentService componentService; - int resourceId = -1;
ConfigManagementFactoryImpl factory;
@BeforeMethod public void setup() { - componentService = context.mock(ComponentService.class); - factory = new ConfigManagementFactoryImpl(); factory.setComponentService(componentService); } diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigManagementTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigManagementTest.java index 57e5183..1ad81f6 100644 --- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigManagementTest.java +++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigManagementTest.java @@ -30,10 +30,12 @@ import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; import org.rhq.core.domain.resource.ResourceType; import org.rhq.core.clientapi.server.configuration.ConfigurationUpdateResponse; import org.rhq.core.pluginapi.configuration.ConfigurationUpdateReport; +import org.rhq.core.pc.util.ComponentService; import org.rhq.test.JMockTest;
import static org.rhq.test.AssertUtils.*; import static org.testng.Assert.assertEquals; +import org.testng.annotations.BeforeMethod;
import java.util.HashSet; import java.util.Random; @@ -47,6 +49,14 @@ public class ConfigManagementTest extends JMockTest { int resourceId = -1; boolean daemonThread = true; boolean onlyIfStarted = true; + ComponentService componentService; + ConfigurationUtilityService configUtilityService; + + @BeforeMethod + public void initMocks() { + componentService = context.mock(ComponentService.class); + configUtilityService = context.mock(ConfigurationUtilityService.class); + }
Configuration createStructuredConfig() { Configuration config = new Configuration(); diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigurationManagerTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigurationManagerTest.java index 9b0b910..6418922 100644 --- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigurationManagerTest.java +++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigurationManagerTest.java @@ -28,13 +28,11 @@ import static org.testng.Assert.*; import org.jmock.Expectations; import org.rhq.core.clientapi.agent.PluginContainerException; import org.rhq.core.clientapi.agent.configuration.ConfigurationUpdateRequest; -import org.rhq.core.clientapi.server.configuration.ConfigurationUpdateResponse; import org.rhq.core.clientapi.server.configuration.ConfigurationServerService; import org.rhq.core.domain.configuration.Configuration; import org.rhq.core.domain.configuration.RawConfiguration; import org.rhq.core.domain.configuration.PropertySimple; import org.rhq.core.domain.resource.ResourceType; -import org.rhq.core.pc.util.ComponentService; import org.rhq.core.pc.util.FacetLockType; import org.rhq.core.pc.PluginContainerConfiguration; import org.rhq.core.pc.ServerServices; @@ -46,7 +44,6 @@ import org.hamcrest.Matcher;
import java.util.Set; import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.Callable;
public class ConfigurationManagerTest extends ConfigManagementTest {
@@ -60,16 +57,12 @@ public class ConfigurationManagerTest extends ConfigManagementTest {
ConfigManagementFactory configMgmtFactory;
- ComponentService componentService; - ConfigurationManager configurationMgr;
@BeforeMethod public void setup() { configMgmtFactory = context.mock(ConfigManagementFactory.class);
- componentService = context.mock(ComponentService.class); - configurationMgr = new ConfigurationManager(); configurationMgr.setConfigManagementFactory(configMgmtFactory); configurationMgr.setComponentService(componentService); @@ -84,7 +77,7 @@ public class ConfigurationManagerTest extends ConfigManagementTest { context.checking(new Expectations() {{ atLeast(1).of(configMgmtFactory).getStrategy(resourceId); will(returnValue(loadConfig));
- atLeast(1).of(loadConfig).execute(resourceId); will(returnValue(expectedConfig)); + atLeast(1).of(loadConfig).executeLoad(resourceId); will(returnValue(expectedConfig)); }});
Configuration actualConfig = configurationMgr.loadResourceConfiguration(resourceId); @@ -99,7 +92,7 @@ public class ConfigurationManagerTest extends ConfigManagementTest { context.checking(new Expectations() {{ atLeast(1).of(configMgmtFactory).getStrategy(resourceId); will(returnValue(loadConfig));
- atLeast(1).of(loadConfig).execute(resourceId); will(returnValue(null)); + atLeast(1).of(loadConfig).executeLoad(resourceId); will(returnValue(null));
allowing(componentService).getResourceType(resourceId); will(returnValue(new ResourceType())); }}); @@ -116,7 +109,7 @@ public class ConfigurationManagerTest extends ConfigManagementTest {
atLeast(1).of(configMgmtFactory).getStrategy(resourceId); will(returnValue(loadConfig));
- atLeast(1).of(loadConfig).execute(resourceId); will(throwException(new RuntimeException())); + atLeast(1).of(loadConfig).executeLoad(resourceId); will(throwException(new RuntimeException())); }});
configurationMgr.loadResourceConfiguration(resourceId); diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LegacyConfigManagementTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LegacyConfigManagementTest.java new file mode 100644 index 0000000..094d304 --- /dev/null +++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LegacyConfigManagementTest.java @@ -0,0 +1,212 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2008 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.core.pc.configuration; + +import org.testng.annotations.Test; +import org.testng.annotations.BeforeMethod; +import static org.testng.Assert.assertNull; +import org.rhq.core.pluginapi.configuration.ConfigurationFacet; +import org.rhq.core.pluginapi.configuration.ConfigurationUpdateReport; +import org.rhq.core.domain.configuration.Configuration; +import org.rhq.core.domain.configuration.PropertySimple; +import org.rhq.core.domain.configuration.ConfigurationUpdateStatus; +import static org.rhq.core.domain.configuration.ConfigurationUpdateStatus.*; +import org.rhq.core.pc.util.FacetLockType; +import org.rhq.test.jmock.PropertyMatcher; +import org.jmock.Expectations; +import org.jmock.api.Action; +import org.jmock.api.Invocation; +import org.hamcrest.Matcher; +import org.hamcrest.Description; + +public class LegacyConfigManagementTest extends ConfigManagementTest { + + ConfigurationFacet facet; + + LegacyConfigManagement configMgmt; + + @BeforeMethod + public void setup() { + facet = context.mock(ConfigurationFacet.class); + + configMgmt = new LegacyConfigManagement(); + configMgmt.setComponentService(componentService); + configMgmt.setConfigurationUtilityService(configUtilityService); + } + + @Test + public void structuredConfigShouldGetLoaded() throws Exception { + final Configuration config = new Configuration(); + config.put(new PropertySimple("x", "1")); + config.put(new PropertySimple("y", "2")); + + addDefaultExpectationsForLoad(config); + + Configuration loadedConfig = configMgmt.executeLoad(resourceId); + + assertStructuredLoaded(config, loadedConfig); + } + + @Test + public void theConfigNotesShouldGetSet() throws Exception { + final Configuration config = new Configuration(); + config.setNotes(null); + + addDefaultExpectationsForLoad(config); + + Configuration loadedConfig = configMgmt.executeLoad(resourceId); + + assertNotesSetToDefault(loadedConfig); + } + + @Test + public void nullShouldBeReturnedWhenStructuredIsNull() throws Exception { + final Configuration config = null; + + context.checking(new Expectations() {{ + atLeast(1).of(componentService).getComponent(resourceId, + ConfigurationFacet.class, + FacetLockType.READ, + ConfigManagement.FACET_METHOD_TIMEOUT, + daemonThread, + onlyIfStarted); + will(returnValue(facet)); + + allowing(componentService).getResourceType(resourceId); will(returnValue(resourceType)); + + atLeast(1).of(facet).loadResourceConfiguration(); will(returnValue(null)); + }}); + + Configuration loadedConfig = configMgmt.executeLoad(resourceId); + + assertNull(loadedConfig, "Expected null to be returned when facet returns null for structured."); + } + + private void addDefaultExpectationsForLoad(final Configuration config) throws Exception { + context.checking(new Expectations() {{ + atLeast(1).of(componentService).getComponent(resourceId, + ConfigurationFacet.class, + FacetLockType.READ, + ConfigManagement.FACET_METHOD_TIMEOUT, + daemonThread, + onlyIfStarted); + will(returnValue(facet)); + + allowing(componentService).getResourceType(resourceId); will(returnValue(resourceType)); + + atLeast(1).of(facet).loadResourceConfiguration(); will(returnValue(config)); + + atLeast(1).of(configUtilityService).normalizeConfiguration(config, getResourceConfigDefinition()); + + atLeast(1).of(configUtilityService).validateConfiguration(config, getResourceConfigDefinition()); + }}); + } + + @Test + public void facetShouldBeCalledToUpdateStructured() throws Exception { + final Configuration config = new Configuration(); + + final ConfigurationUpdateReport updateReport = new ConfigurationUpdateReport(config); + + final boolean isDaemonThread = false; + + context.checking(new Expectations() {{ + atLeast(1).of(componentService).getComponent(resourceId, + ConfigurationFacet.class, + FacetLockType.WRITE, + ConfigManagement.FACET_METHOD_TIMEOUT, + isDaemonThread, + onlyIfStarted); + will(returnValue(facet)); + + oneOf(facet).updateResourceConfiguration(with(matchingUpdateReport(updateReport))); + will(updateReportTo(SUCCESS)); + }}); + + configMgmt.executeUpdate(resourceId, config); + } + + @Test(expectedExceptions = UpdateInProgressException.class) + public void exceptionShouldBeThrownWhenUpdateDoesNotComplete() throws Exception { + final Configuration config = new Configuration(); + + final ConfigurationUpdateReport updateReport = new ConfigurationUpdateReport(config); + + final boolean isDaemonThread = false; + + context.checking(new Expectations() {{ + atLeast(1).of(componentService).getComponent(resourceId, + ConfigurationFacet.class, + FacetLockType.WRITE, + ConfigManagement.FACET_METHOD_TIMEOUT, + isDaemonThread, + onlyIfStarted); + will(returnValue(facet)); + + oneOf(facet).updateResourceConfiguration(with(matchingUpdateReport(updateReport))); + will(updateReportTo(INPROGRESS)); + }}); + + configMgmt.executeUpdate(resourceId, config); + } + + @Test(expectedExceptions = ConfigurationUpdateException.class) + public void exceptionShouldBeThrownWhenUpdateFails() throws Exception { + final Configuration config = new Configuration(); + + final ConfigurationUpdateReport updateReport = new ConfigurationUpdateReport(config); + + final boolean isDaemonThread = false; + + context.checking(new Expectations() {{ + atLeast(1).of(componentService).getComponent(resourceId, + ConfigurationFacet.class, + FacetLockType.WRITE, + ConfigManagement.FACET_METHOD_TIMEOUT, + isDaemonThread, + onlyIfStarted); + will(returnValue(facet)); + + oneOf(facet).updateResourceConfiguration(with(matchingUpdateReport(updateReport))); + will(updateReportTo(FAILURE)); + }}); + + configMgmt.executeUpdate(resourceId, config); + } + + public static Matcher<ConfigurationUpdateReport> matchingUpdateReport(ConfigurationUpdateReport expected) { + return new PropertyMatcher<ConfigurationUpdateReport>(expected); + } + + public static Action updateReportTo(final ConfigurationUpdateStatus status) { + return new Action() { + public void describeTo(Description description) { + description.appendText("Updates " + ConfigurationUpdateReport.class.getSimpleName() + " to " + status); + } + + public Object invoke(Invocation invocation) throws Throwable { + ConfigurationUpdateReport report = (ConfigurationUpdateReport) invocation.getParameter(0); + report.setStatus(status); + return null; + } + }; + } + +} diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/RawConfigManagementTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/RawConfigManagementTest.java index 2d6975c..8d1ec7a 100644 --- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/RawConfigManagementTest.java +++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/RawConfigManagementTest.java @@ -23,16 +23,13 @@
package org.rhq.core.pc.configuration;
-import static org.rhq.core.domain.configuration.ConfigurationUpdateStatus.SUCCESS; import static java.util.Collections.EMPTY_SET;
import org.jmock.Expectations; import org.rhq.core.domain.configuration.Configuration; import org.rhq.core.domain.configuration.RawConfiguration; -import org.rhq.core.pc.util.ComponentService; import org.rhq.core.pc.util.FacetLockType; import org.rhq.core.pluginapi.configuration.ResourceConfigurationFacet; -import org.rhq.core.pluginapi.configuration.ConfigurationUpdateReport; import static org.testng.Assert.assertNull; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; @@ -41,19 +38,12 @@ import java.util.Set;
public class RawConfigManagementTest extends ConfigManagementTest {
- ComponentService componentService; - - ConfigurationUtilityService configUtilityService; - ResourceConfigurationFacet configFacet;
RawConfigManagement rawConfigMgmt;
@BeforeMethod public void setup() { - componentService = context.mock(ComponentService.class); - configUtilityService = context.mock(ConfigurationUtilityService.class); - configFacet = context.mock(ResourceConfigurationFacet.class);
rawConfigMgmt = new RawConfigManagement(); @@ -70,7 +60,7 @@ public class RawConfigManagementTest extends ConfigManagementTest {
addDefaultExpectationsForLoad(rawConfigs);
- Configuration loadedConfig = rawConfigMgmt.execute(resourceId); + Configuration loadedConfig = rawConfigMgmt.executeLoad(resourceId);
assertRawsLoaded(rawConfigs, loadedConfig); } @@ -82,7 +72,7 @@ public class RawConfigManagementTest extends ConfigManagementTest {
addDefaultExpectationsForLoad(EMPTY_SET);
- Configuration loadedConfig = rawConfigMgmt.execute(resourceId); + Configuration loadedConfig = rawConfigMgmt.executeLoad(resourceId);
assertNotesSetToDefault(loadedConfig); } @@ -93,7 +83,7 @@ public class RawConfigManagementTest extends ConfigManagementTest {
addDefaultExpectationsForLoad(rawConfigs);
- Configuration loadedConfig = rawConfigMgmt.execute(resourceId); + Configuration loadedConfig = rawConfigMgmt.executeLoad(resourceId);
assertNull(loadedConfig, "Expected null to be returned when facet returns null for raw."); } diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/StructuredAndRawConfigManagementTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/StructuredAndRawConfigManagementTest.java index 4ee7cc2..b3b5882 100644 --- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/StructuredAndRawConfigManagementTest.java +++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/StructuredAndRawConfigManagementTest.java @@ -26,7 +26,6 @@ package org.rhq.core.pc.configuration; import static org.testng.Assert.*; import static java.util.Collections.*;
-import org.rhq.core.pc.util.ComponentService; import org.rhq.core.pc.util.FacetLockType; import org.rhq.core.pluginapi.configuration.ResourceConfigurationFacet; import org.rhq.core.domain.configuration.Configuration; @@ -42,10 +41,6 @@ import java.util.Set;
public class StructuredAndRawConfigManagementTest extends ConfigManagementTest {
- ComponentService componentService; - - ConfigurationUtilityService configUtilityService; - ResourceConfigurationFacet configFacet;
StructuredAndRawConfigManagement structuredAndRawConfigManagement; @@ -55,9 +50,6 @@ public class StructuredAndRawConfigManagementTest extends ConfigManagementTest { resourceType = new ResourceType(); resourceType.setResourceConfigurationDefinition(new ConfigurationDefinition("", ""));
- componentService = context.mock(ComponentService.class); - configUtilityService = context.mock(ConfigurationUtilityService.class); - configFacet = context.mock(ResourceConfigurationFacet.class);
structuredAndRawConfigManagement = new StructuredAndRawConfigManagement(); @@ -77,7 +69,7 @@ public class StructuredAndRawConfigManagementTest extends ConfigManagementTest {
addDefaultExpectationsForLoad(config, rawConfigs);
- Configuration loadedConfig = structuredAndRawConfigManagement.execute(resourceId); + Configuration loadedConfig = structuredAndRawConfigManagement.executeLoad(resourceId);
assertRawsLoaded(rawConfigs, loadedConfig); } @@ -90,7 +82,7 @@ public class StructuredAndRawConfigManagementTest extends ConfigManagementTest {
addDefaultExpectationsForLoad(config, EMPTY_SET);
- Configuration loadedConfig = structuredAndRawConfigManagement.execute(resourceId); + Configuration loadedConfig = structuredAndRawConfigManagement.executeLoad(resourceId);
assertStructuredLoaded(config, loadedConfig); } @@ -102,7 +94,7 @@ public class StructuredAndRawConfigManagementTest extends ConfigManagementTest {
addDefaultExpectationsForLoad(config, EMPTY_SET);
- Configuration loadedConfig = structuredAndRawConfigManagement.execute(resourceId); + Configuration loadedConfig = structuredAndRawConfigManagement.executeLoad(resourceId);
assertNotesSetToDefault(loadedConfig); } @@ -115,7 +107,7 @@ public class StructuredAndRawConfigManagementTest extends ConfigManagementTest {
addDefaultExpectationsForLoad(config, rawConfigs);
- Configuration loadedConfig = structuredAndRawConfigManagement.execute(resourceId); + Configuration loadedConfig = structuredAndRawConfigManagement.executeLoad(resourceId);
Configuration emptyStructured = new Configuration();
@@ -133,7 +125,7 @@ public class StructuredAndRawConfigManagementTest extends ConfigManagementTest {
addDefaultExpectationsForLoad(config, rawConfigs);
- Configuration loadedConfig = structuredAndRawConfigManagement.execute(resourceId); + Configuration loadedConfig = structuredAndRawConfigManagement.executeLoad(resourceId);
assertRawsLoaded(EMPTY_SET, loadedConfig); assertStructuredLoaded(config, loadedConfig); @@ -157,7 +149,7 @@ public class StructuredAndRawConfigManagementTest extends ConfigManagementTest { oneOf(configFacet).loadRawConfigurations(); will(returnValue(null)); }});
- Configuration loadedConfig = structuredAndRawConfigManagement.execute(resourceId); + Configuration loadedConfig = structuredAndRawConfigManagement.executeLoad(resourceId);
assertNull(loadedConfig, "Expected null to be returned when facet returns null for both structured and raw."); } diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/StructuredConfigManagementTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/StructuredConfigManagementTest.java index 855aab4..9b24df7 100644 --- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/StructuredConfigManagementTest.java +++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/StructuredConfigManagementTest.java @@ -26,7 +26,6 @@ package org.rhq.core.pc.configuration; import org.jmock.Expectations; import org.rhq.core.domain.configuration.Configuration; import org.rhq.core.domain.configuration.PropertySimple; -import org.rhq.core.pc.util.ComponentService; import org.rhq.core.pc.util.FacetLockType; import org.rhq.core.pluginapi.configuration.ResourceConfigurationFacet; import static org.testng.Assert.assertNull; @@ -35,19 +34,12 @@ import org.testng.annotations.Test;
public class StructuredConfigManagementTest extends ConfigManagementTest {
- ComponentService componentService; - - ConfigurationUtilityService configUtilityService; - ResourceConfigurationFacet configFacet;
StructuredConfigManagement structuredMgmt;
@BeforeMethod public void setup() { - componentService = context.mock(ComponentService.class); - configUtilityService = context.mock(ConfigurationUtilityService.class); - configFacet = context.mock(ResourceConfigurationFacet.class);
structuredMgmt = new StructuredConfigManagement(); @@ -63,7 +55,7 @@ public class StructuredConfigManagementTest extends ConfigManagementTest {
addDefaultExpectationsForLoad(config);
- Configuration loadedConfig = structuredMgmt.execute(resourceId); + Configuration loadedConfig = structuredMgmt.executeLoad(resourceId);
assertStructuredLoaded(config, loadedConfig); } @@ -75,7 +67,7 @@ public class StructuredConfigManagementTest extends ConfigManagementTest {
addDefaultExpectationsForLoad(config);
- Configuration loadedConfig = structuredMgmt.execute(resourceId); + Configuration loadedConfig = structuredMgmt.executeLoad(resourceId);
assertNotesSetToDefault(loadedConfig); } @@ -98,7 +90,7 @@ public class StructuredConfigManagementTest extends ConfigManagementTest { atLeast(1).of(configFacet).loadStructuredConfiguration(); will(returnValue(null)); }});
- Configuration loadedConfig = structuredMgmt.execute(resourceId); + Configuration loadedConfig = structuredMgmt.executeLoad(resourceId);
assertNull(loadedConfig, "Expected null to be returned when facet returns null for structured."); } diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/UpdateResourceConfigurationRunnerTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/UpdateResourceConfigurationRunnerTest.java index 0877668..7dd18b0 100644 --- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/UpdateResourceConfigurationRunnerTest.java +++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/UpdateResourceConfigurationRunnerTest.java @@ -34,14 +34,8 @@ import org.rhq.core.clientapi.server.configuration.ConfigurationUpdateResponse; import org.rhq.core.domain.configuration.Configuration; import org.rhq.core.domain.configuration.ConfigurationUpdateStatus; import static org.rhq.core.domain.configuration.ConfigurationUpdateStatus.FAILURE; -import static org.rhq.core.domain.configuration.ConfigurationUpdateStatus.INPROGRESS; import static org.rhq.core.domain.configuration.ConfigurationUpdateStatus.SUCCESS; -import org.rhq.core.pc.util.ComponentService; -import static org.rhq.core.pc.configuration.ConfigManagement.FACET_METHOD_TIMEOUT; -import static org.rhq.core.pc.util.FacetLockType.WRITE; -import org.rhq.core.pluginapi.configuration.ConfigurationFacet; import org.rhq.core.pluginapi.configuration.ConfigurationUpdateReport; -import static org.rhq.test.AssertUtils.assertPropertiesMatch; import org.rhq.test.jmock.PropertyMatcher; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; @@ -52,13 +46,10 @@ public class UpdateResourceConfigurationRunnerTest extends ConfigManagementTest
ConfigurationServerService configServerService;
- ConfigurationUtilityService configUtilService; - @BeforeMethod public void setup() throws Exception { configMgmt = context.mock(ConfigManagement.class); configServerService = context.mock(ConfigurationServerService.class); - configUtilService = context.mock(ConfigurationUtilityService.class); }
@Test @@ -71,7 +62,7 @@ public class UpdateResourceConfigurationRunnerTest extends ConfigManagementTest
UpdateResourceConfigurationRunner updateRunner = new UpdateResourceConfigurationRunner(configServerService, resourceType, configMgmt, updateRequest); - updateRunner.setConfigUtilService(configUtilService); + updateRunner.setConfigUtilService(configUtilityService);
final ConfigurationUpdateResponse successResponse = new ConfigurationUpdateResponse(configUpdateId, null, SUCCESS, null); @@ -79,8 +70,8 @@ public class UpdateResourceConfigurationRunnerTest extends ConfigManagementTest context.checking(new Expectations() {{ oneOf(configMgmt).executeUpdate(resourceId, config);
- oneOf(configUtilService).normalizeConfiguration(config, resourceType.getResourceConfigurationDefinition()); - oneOf(configUtilService).validateConfiguration(config, resourceType.getResourceConfigurationDefinition()); + oneOf(configUtilityService).normalizeConfiguration(config, resourceType.getResourceConfigurationDefinition()); + oneOf(configUtilityService).validateConfiguration(config, resourceType.getResourceConfigurationDefinition());
oneOf(configServerService).completeConfigurationUpdate(with(matchingResponse(successResponse))); }}); @@ -100,7 +91,7 @@ public class UpdateResourceConfigurationRunnerTest extends ConfigManagementTest
UpdateResourceConfigurationRunner updateRunner = new UpdateResourceConfigurationRunner(null, resourceType, configMgmt, updateRequest); - updateRunner.setConfigUtilService(configUtilService); + updateRunner.setConfigUtilService(configUtilityService);
final ConfigurationUpdateResponse successResponse = new ConfigurationUpdateResponse(configUpdateId, null, SUCCESS, null); @@ -108,8 +99,8 @@ public class UpdateResourceConfigurationRunnerTest extends ConfigManagementTest context.checking(new Expectations() {{ oneOf(configMgmt).executeUpdate(resourceId, config);
- oneOf(configUtilService).normalizeConfiguration(config, resourceType.getResourceConfigurationDefinition()); - oneOf(configUtilService).validateConfiguration(config, resourceType.getResourceConfigurationDefinition()); + oneOf(configUtilityService).normalizeConfiguration(config, resourceType.getResourceConfigurationDefinition()); + oneOf(configUtilityService).validateConfiguration(config, resourceType.getResourceConfigurationDefinition());
}});
@@ -128,7 +119,7 @@ public class UpdateResourceConfigurationRunnerTest extends ConfigManagementTest
UpdateResourceConfigurationRunner updateRunner = new UpdateResourceConfigurationRunner(configServerService, resourceType, configMgmt, updateRequest); - updateRunner.setConfigUtilService(configUtilService); + updateRunner.setConfigUtilService(configUtilityService);
String errorMsg = "Configuration facet did not indicate success or failure - assuming failure.";
@@ -138,8 +129,8 @@ public class UpdateResourceConfigurationRunnerTest extends ConfigManagementTest context.checking(new Expectations() {{ oneOf(configMgmt).executeUpdate(resourceId, config); will(throwException(new UpdateInProgressException()));
- oneOf(configUtilService).normalizeConfiguration(config, resourceType.getResourceConfigurationDefinition()); - oneOf(configUtilService).validateConfiguration(config, resourceType.getResourceConfigurationDefinition()); + oneOf(configUtilityService).normalizeConfiguration(config, resourceType.getResourceConfigurationDefinition()); + oneOf(configUtilityService).validateConfiguration(config, resourceType.getResourceConfigurationDefinition());
oneOf(configServerService).completeConfigurationUpdate(with(matchingResponse(failureResponse))); }}); @@ -159,7 +150,7 @@ public class UpdateResourceConfigurationRunnerTest extends ConfigManagementTest
UpdateResourceConfigurationRunner updateRunner = new UpdateResourceConfigurationRunner(configServerService, resourceType, configMgmt, updateRequest); - updateRunner.setConfigUtilService(configUtilService); + updateRunner.setConfigUtilService(configUtilityService);
String errorMsg = "Configuration update failed.";
@@ -171,8 +162,8 @@ public class UpdateResourceConfigurationRunnerTest extends ConfigManagementTest context.checking(new Expectations() {{ oneOf(configMgmt).executeUpdate(resourceId, config); will(throwExceptionFromFacet(exception));
- oneOf(configUtilService).normalizeConfiguration(config, resourceType.getResourceConfigurationDefinition()); - oneOf(configUtilService).validateConfiguration(config, resourceType.getResourceConfigurationDefinition()); + oneOf(configUtilityService).normalizeConfiguration(config, resourceType.getResourceConfigurationDefinition()); + oneOf(configUtilityService).validateConfiguration(config, resourceType.getResourceConfigurationDefinition());
oneOf(configServerService).completeConfigurationUpdate(with(matchingResponse(failureResponse))); }}); @@ -192,7 +183,7 @@ public class UpdateResourceConfigurationRunnerTest extends ConfigManagementTest
UpdateResourceConfigurationRunner updateRunner = new UpdateResourceConfigurationRunner(null, resourceType, configMgmt, updateRequest); - updateRunner.setConfigUtilService(configUtilService); + updateRunner.setConfigUtilService(configUtilityService);
String errorMsg = "Configuration update failed.";
@@ -204,8 +195,8 @@ public class UpdateResourceConfigurationRunnerTest extends ConfigManagementTest context.checking(new Expectations() {{ oneOf(configMgmt).executeUpdate(resourceId, config); will(throwExceptionFromFacet(exception));
- oneOf(configUtilService).normalizeConfiguration(config, resourceType.getResourceConfigurationDefinition()); - oneOf(configUtilService).validateConfiguration(config, resourceType.getResourceConfigurationDefinition()); + oneOf(configUtilityService).normalizeConfiguration(config, resourceType.getResourceConfigurationDefinition()); + oneOf(configUtilityService).validateConfiguration(config, resourceType.getResourceConfigurationDefinition()); }});
ConfigurationUpdateResponse actualResponse = updateRunner.call();
commit ad9d172b73baa53de2260c9a8ac7bf9ab2cfe791 Author: Justin Harris jharris@redhat.com Date: Fri Dec 4 11:12:29 2009 -0500
Adding a 'no config' message if a server plugin has no configurations defined.
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-config.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-config.xhtml index fa30a67..f0cca1b 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-config.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-config.xhtml @@ -20,6 +20,7 @@
.col2 { width: 80%; + vertical-align: top; } </style> </ui:define> @@ -93,6 +94,22 @@ readOnly="true" /> </rich:panel>
+ <rich:panel id="noConfigMessage" + rendered="#{not pluginConfigUIBean.editable and pluginConfigUIBean.plugin != null}" + style="background: #EEEEEE;"> + <h:outputText escape="true" value="#{pluginConfigUIBean.plugin.displayName} has no configuration. " /> + <br /> + <br /> + <h:outputText value="See the " /> + <h:outputLink value="/rhq/admin/plugin/plugin-details.xhtml"> + <f:param name="plugin" value="#{pluginConfigUIBean.plugin.name}"/> + <f:param name="deployment" value="#{pluginConfigUIBean.plugin.deployment}"/> + <f:param name="pluginType" value="#{pluginConfigUIBean.plugin.type}"/> + <h:outputText value="#{pluginConfigUIBean.plugin.displayName} details page"/> + </h:outputLink> + <h:outputText value=" for more plugin information." /> + </rich:panel> + <h:panelGroup id="pluginButtons" rendered="#{pluginConfigUIBean.editable}"> <h:outputLink value="/rhq/admin/plugin/plugin-edit.xhtml" styleClass="buttonmed"> <f:param name="plugin" value="#{pluginConfigUIBean.plugin.name}"/>
commit 245da064d9d3e261940656c3a5ac630cd9d12e5c Merge: 58f1a6b... 3325442... Author: Heiko W. Rupp pilhuhn@fedorapeople.org Date: Fri Dec 4 15:34:00 2009 +0100
Merge branch 'master' into alertPlugin
diff --cc modules/core/domain/src/main/java/org/rhq/core/domain/plugin/ServerPlugin.java index a01a40a,0243c49..d65f7e9 --- a/modules/core/domain/src/main/java/org/rhq/core/domain/plugin/ServerPlugin.java +++ b/modules/core/domain/src/main/java/org/rhq/core/domain/plugin/ServerPlugin.java @@@ -129,11 -154,35 +154,35 @@@ import org.rhq.core.domain.configuratio + " p.type, " // + " p.ctime, " // + " p.mtime) " // - + " FROM ServerPlugin AS p " // - + " LEFT JOIN p.pluginConfiguration " // - + " LEFT JOIN p.scheduledJobsConfiguration " // + + " FROM ServerPlugin AS p " // + + " LEFT JOIN p.pluginConfiguration " // + + " LEFT JOIN p.scheduledJobsConfiguration " // + " WHERE p.name=:name "), //
+ // finds all installed AND deleted + // this query does not load the content blob, but loads everything else + @NamedQuery(name = ServerPlugin.QUERY_FIND_ALL, query = "" // + + " SELECT new org.rhq.core.domain.plugin.ServerPlugin( " // + + " p.id, " // + + " p.name, " // + + " p.path, " // + + " p.displayName, " // + + " p.enabled, " // + + " p.status, " // + + " p.description, " // + + " p.help, " // + + " p.md5, " // + + " p.version, " // + + " p.ampsVersion, " // + + " p.pluginConfiguration, " // + + " p.scheduledJobsConfiguration, " // + + " p.type, " // + + " p.ctime, " // + + " p.mtime) " // + + " FROM ServerPlugin AS p " // + + " LEFT JOIN p.pluginConfiguration " // + + " LEFT JOIN p.scheduledJobsConfiguration "), + // finds all installed - ignores those plugins marked as deleted // this query does not load the content blob, but loads everything else @NamedQuery(name = ServerPlugin.QUERY_FIND_ALL_INSTALLED, query = "" // diff --cc modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/PluginFactory.java index 0000000,3e1c4dd..8ea565e mode 000000,100644..100644 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/PluginFactory.java +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/PluginFactory.java @@@ -1,0 -1,62 +1,63 @@@ + /* + * RHQ Management Platform + * Copyright (C) 2005-2009 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.gui.admin.plugin; + ++import org.jboss.seam.ScopeType; + import org.jboss.seam.annotations.Factory; + import org.jboss.seam.annotations.Name; + import org.jboss.seam.annotations.web.RequestParameter; + + import org.rhq.core.domain.plugin.AbstractPlugin; + import org.rhq.core.domain.plugin.Plugin; + import org.rhq.core.domain.plugin.PluginDeploymentType; + import org.rhq.core.domain.plugin.PluginKey; + import org.rhq.core.domain.plugin.ServerPlugin; + import org.rhq.enterprise.server.plugin.ServerPluginsLocal; + import org.rhq.enterprise.server.util.LookupUtil; + + /** + * Component responsible for providing a {@link Plugin} via request + * parameters. + * + * @author jharris + */ + @Name("pluginFactory") + public class PluginFactory { + + @RequestParameter("plugin") + private String name; + @RequestParameter("deployment") + private PluginDeploymentType deployment; + @RequestParameter("pluginType") + private String pluginType; + + @Factory(value = "plugin", autoCreate = true) + public AbstractPlugin lookupPlugin() { + if (this.deployment == PluginDeploymentType.AGENT) { + return LookupUtil.getResourceMetadataManager().getPlugin(this.name); + } else if (this.deployment == PluginDeploymentType.SERVER) { + PluginKey pluginKey = new PluginKey(this.deployment, this.pluginType, this.name); + ServerPluginsLocal serverPluginsBean = LookupUtil.getServerPlugins(); + ServerPlugin plugin = serverPluginsBean.getServerPlugin(pluginKey); + return serverPluginsBean.getServerPluginRelationships(plugin); + } + + return null; + } + } diff --cc modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-navigation/admin-navigation.xml index 377523c,9a597b9..e6700ee --- a/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-navigation/admin-navigation.xml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-navigation/admin-navigation.xml @@@ -41,6 -30,63 +41,63 @@@ </navigation-rule>
<navigation-rule> + <from-view-id>/rhq/admin/plugin/plugin-config.xhtml</from-view-id> + + <navigation-case> + <from-action>#{ConfigHelperUIBean.accessMap}</from-action> + <to-view-id>/rhq/admin/plugin/plugin-edit-view-map.xhtml?plugin=#{pluginConfigUIBean.plugin.name}&deployment=#{pluginConfigUIBean.plugin.deployment}&pluginType=#{pluginConfigUIBean.plugin.type}&listName=#{param.listName}&listIndex=#{param.listIndex}</to-view-id> + + <redirect /> + </navigation-case> + </navigation-rule> + + <navigation-rule> + <from-view-id>/rhq/admin/plugin/plugin-edit.xhtml</from-view-id> + + <navigation-case> + <from-action>#{ConfigHelperUIBean.addNewMap}</from-action> + <to-view-id>/rhq/admin/plugin/plugin-edit-add-map.xhtml</to-view-id> + </navigation-case> + + <navigation-case> + <from-action>#{ConfigHelperUIBean.accessMap}</from-action> + <to-view-id>/rhq/admin/plugin/plugin-edit-update-map.xhtml</to-view-id> + </navigation-case> + + <navigation-case> + <from-action>#{editPluginConfigurationUIBean.updatePlugin}</from-action> + <from-outcome>success</from-outcome> + <to-view-id>/rhq/admin/plugin/plugin-config.xhtml?pluginName=#{editPluginConfigurationUIBean.plugin.name}</to-view-id> + + <redirect /> + </navigation-case> + </navigation-rule> + + <navigation-rule> + <from-view-id>/rhq/admin/plugin/plugin-edit-add-map.xhtml</from-view-id> + + <navigation-case> + <from-outcome>success</from-outcome> + <to-view-id>/rhq/admin/plugin/plugin-edit.xhtml?plugin=#{pluginConfigUIBean.plugin.name}&deployment=#{pluginConfigUIBean.plugin.deployment}&pluginType=#{pluginConfigUIBean.plugin.type}</to-view-id> + + <redirect/> + </navigation-case> + + </navigation-rule> + + <navigation-rule> + <from-view-id>/rhq/admin/plugin/plugin-edit-update-map.xhtml</from-view-id> + + <navigation-case> + <from-outcome>success</from-outcome> + <to-view-id>/rhq/admin/plugin/plugin-edit.xhtml?plugin=#{pluginConfigUIBean.plugin.name}&deployment=#{pluginConfigUIBean.plugin.deployment}&pluginType=#{pluginConfigUIBean.plugin.type}</to-view-id> + + <redirect/> + </navigation-case> + + </navigation-rule> - ++ + <navigation-rule> <navigation-case> <from-outcome>sessionExpired</from-outcome> <to-view-id>/Login.do</to-view-id> diff --cc modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsLocal.java index 522dfa1,09323ac..f4bbb7b --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsLocal.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsLocal.java @@@ -16,19 -16,40 +16,40 @@@ import org.rhq.enterprise.server.xmlsch
/** * Interface to the methods that interact with the serve-side plugin infrastructure. + * Most of these methods will only return information on {@link PluginStatusType#INSTALLED} + * plugins; only when explicitly stated will a method return data on + * {@link PluginStatusType#DELETED} plugins, too. - * + * * @author John Mazzitelli */ @Local public interface ServerPluginsLocal { /** - * Returns a list of all the server plugins in the database. + * Recycles the master plugin container, essentially shutting down all server plugins + * and then restarting them. - * - * @param subject the user asking to restart the master plugin container + * - * @return all plugins found in the DB ++ * @param subject the user asking to restart the master plugin container + */ + void restartMasterPluginContainer(Subject subject); + + /** + * Returns a list of all the installed server plugins in the database - * ++ * + * @return all installed server plugins found in the DB */ List<ServerPlugin> getServerPlugins();
/** + * Returns a list of all the installed and deleted server plugins in the database. + * When a plugin is "undeployed", it still exists in the database, but is flagged + * as "deleted". This method returns those deleted plugins in addition to those plugins + * that are still installed. - * ++ * + * @return all installed and deleted server plugins found in the DB + */ + List<ServerPlugin> getAllServerPlugins(); + + /** * Returns a plugin with the given key. * @param key identifies the plugin to find * @return the named plugin @@@ -58,8 -79,16 +79,16 @@@ List<ServerPlugin> getServerPluginsById(List<Integer> pluginIds);
/** + * Get a list of both installed and deleted plugins from their IDs. - * ++ * + * @param pluginIds the IDs of the plugins to load. + * @return plugins matching the given IDs + */ + List<ServerPlugin> getAllServerPluginsById(List<Integer> pluginIds); + + /** * Given a plugin key, returns the descriptor for that plugin. - * + * * @param pluginKey * @return descriptor parsed from the file in the plugin jar * @throws Exception if the descriptor could not be retrieved or parsed for the given plugin
commit 33254426aff3b82e4cca41337041c97a90f92e13 Merge: 02d4ac9... 07eab37... Author: John Mazzitelli mazz@redhat.com Date: Fri Dec 4 08:29:21 2009 -0500
Merge branch 'master' into pc
commit 58f1a6be5e2e119d05360df4df1efefea64a253e Merge: 8b3d2f3... 07eab37... Author: Heiko W. Rupp pilhuhn@fedorapeople.org Date: Fri Dec 4 12:51:34 2009 +0100
Merge branch 'master' into alertPlugin
commit 8b3d2f3018cee2157c202f56d92027b71e61932b Author: Heiko W. Rupp pilhuhn@fedorapeople.org Date: Fri Dec 4 12:50:24 2009 +0100
Start implementing a sender that uses a custom-ui
diff --git a/modules/enterprise/server/plugins/alert-roles/pom.xml b/modules/enterprise/server/plugins/alert-roles/pom.xml new file mode 100644 index 0000000..dc4e8b4 --- /dev/null +++ b/modules/enterprise/server/plugins/alert-roles/pom.xml @@ -0,0 +1,151 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd%22%3E + <parent> + <artifactId>rhq-enterprise-server-plugins-parent</artifactId> + <groupId>org.rhq</groupId> + <version>1.4.0-SNAPSHOT</version> + </parent> + <modelVersion>4.0.0</modelVersion> + + <groupId>org.rhq</groupId> + <artifactId>alert-roles</artifactId> + <version>1.4.0-SNAPSHOT</version> + + <name>RHQ Enterprise Server Roles Alert Plugin</name> + + <scm> + <connection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/modules/enterprise/server/plugins/alert-roles/</connection> + <developerConnection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/modules/enterprise/server/plugins/alert-roles/</developerConnection> + </scm> + + <properties> + <scm.module.path>modules/enterprise/server/plugins/alert-roles/</scm.module.path> + <seam.version>2.1.0.SP1</seam.version> + </properties> + + <dependencies> + <dependency> + <groupId>javax.mail</groupId> + <artifactId>mail</artifactId> + <version>1.3.1</version> + <scope>provided</scope> <!-- by JBossAS --> + </dependency> + + <dependency> + <groupId>org.rhq</groupId> + <artifactId>rhq-enterprise-server</artifactId> + <version>1.4.0-SNAPSHOT</version> + <scope>provided</scope> <!-- by JBossAS --> + </dependency> + + <dependency> + <groupId>org.jboss.seam</groupId> + <artifactId>jboss-seam</artifactId> + <version>${seam.version}</version> + <exclusions> + <exclusion> + <groupId>xml-apis</groupId> + <artifactId>xml-apis</artifactId> + </exclusion> + </exclusions> + </dependency> + + <!-- TODO: This is a fix for the Javac bug requiring annotations to be + available when compiling dependent classes. It is fixed in JDK 6 --> + <dependency> + <groupId>javax.persistence</groupId> + <artifactId>persistence-api</artifactId> + <version>1.0</version> + <scope>provided</scope> + </dependency> + + <dependency> + <groupId>jboss.jboss-embeddable-ejb3</groupId> + <artifactId>hibernate-all</artifactId> + <version>1.0.0.Alpha9</version> + <scope>provided</scope> + <!-- needed for referenced domain entities that use Hibernate annotations --> + </dependency> + + </dependencies> + + <build> + <plugins> + + <plugin> + <artifactId>maven-surefire-plugin</artifactId> + <configuration> + <excludedGroups>${rhq.testng.excludedGroups}</excludedGroups> + <!-- + <argLine>-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=y</argLine> + --> + </configuration> + </plugin> + + </plugins> + </build> + + <profiles> + + <profile> + <id>dev</id> + + <properties> + <rhq.rootDir>../../../../..</rhq.rootDir> + <rhq.containerDir>${rhq.rootDir}/${rhq.defaultDevContainerPath}</rhq.containerDir> + <rhq.deploymentDir>${rhq.containerDir}/jbossas/server/default/deploy/${rhq.earName}/rhq-serverplugins</rhq.deploymentDir> + </properties> + + <build> + <plugins> + + <plugin> + <artifactId>maven-antrun-plugin</artifactId> + <version>1.1</version> + <executions> + + <execution> + <id>deploy</id> + <phase>compile</phase> + <configuration> + <tasks> + <mkdir dir="${rhq.deploymentDir}" /> + <property name="deployment.file" location="${rhq.deploymentDir}/${project.build.finalName}.jar" /> + <echo>*** Updating ${deployment.file}...</echo> + <jar destfile="${deployment.file}" basedir="${project.build.outputDirectory}" /> + </tasks> + </configuration> + <goals> + <goal>run</goal> + </goals> + </execution> + + <execution> + <id>undeploy</id> + <phase>clean</phase> + <configuration> + <tasks> + <property name="deployment.file" location="${rhq.deploymentDir}/${project.build.finalName}.jar" /> + <echo>*** Deleting ${deployment.file}...</echo> + <delete file="${deployment.file}" /> + </tasks> + </configuration> + <goals> + <goal>run</goal> + </goals> + </execution> + + </executions> + </plugin> + + </plugins> + </build> + </profile> + + </profiles> + + + +</project> \ No newline at end of file diff --git a/modules/enterprise/server/plugins/alert-roles/src/main/java/org/rhq/enterprise/server/plugins/alertRoles/RolesBackingBean.java b/modules/enterprise/server/plugins/alert-roles/src/main/java/org/rhq/enterprise/server/plugins/alertRoles/RolesBackingBean.java new file mode 100644 index 0000000..a83c9cf --- /dev/null +++ b/modules/enterprise/server/plugins/alert-roles/src/main/java/org/rhq/enterprise/server/plugins/alertRoles/RolesBackingBean.java @@ -0,0 +1,38 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2009 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.plugins.alertRoles; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.jboss.seam.annotations.Name; + +/** + * // TODO: Document this + * @author Heiko W. Rupp + */ +@Name("RolesBackingBean") +public class RolesBackingBean { + + private final Log log = LogFactory.getLog(RolesBackingBean.class); + + public String getMessage() { + return "Hello BackingBean"; + } +} diff --git a/modules/enterprise/server/plugins/alert-roles/src/main/java/org/rhq/enterprise/server/plugins/alertRoles/RolesSender.java b/modules/enterprise/server/plugins/alert-roles/src/main/java/org/rhq/enterprise/server/plugins/alertRoles/RolesSender.java new file mode 100644 index 0000000..cd59115 --- /dev/null +++ b/modules/enterprise/server/plugins/alert-roles/src/main/java/org/rhq/enterprise/server/plugins/alertRoles/RolesSender.java @@ -0,0 +1,44 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2009 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.plugins.alertRoles; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.rhq.core.domain.alert.Alert; +import org.rhq.enterprise.server.plugin.pc.alert.AlertSender; +import org.rhq.enterprise.server.plugin.pc.alert.ResultState; +import org.rhq.enterprise.server.plugin.pc.alert.SenderResult; + +/** + * AlertSender that notifies RHQ roles by gathering the email addresses of the + * members of the given roles and putting them into the SenderResult object for + * later delivery by the system. + * + * @author Heiko W. Rupp + */ +public class RolesSender extends AlertSender { + + private final Log log = LogFactory.getLog(RolesSender.class); + + @Override + public SenderResult send(Alert alert) { + return new SenderResult(ResultState.FAILURE,"Not yet implemented"); + } +} diff --git a/modules/enterprise/server/plugins/alert-roles/src/main/resources/META-INF/rhq-serverplugin.xml b/modules/enterprise/server/plugins/alert-roles/src/main/resources/META-INF/rhq-serverplugin.xml new file mode 100644 index 0000000..5719da8 --- /dev/null +++ b/modules/enterprise/server/plugins/alert-roles/src/main/resources/META-INF/rhq-serverplugin.xml @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<alert-plugin + name="alert-roles" + displayName="Alert:Roles" + xmlns="urn:xmlns:rhq-serverplugin.alert" + xmlns:c="urn:xmlns:rhq-configuration" + xmlns:serverplugin="urn:xmlns:rhq-serverplugin" + package="org.rhq.enterprise.server.plugins.alertRoles" + description="Alert sender plugin that sends alert notifications to RHQ roles" + version="1.0" + > + + serverplugin:help + This alert sender plugin is used to send notifications to RHQ roles + </serverplugin:help> + + <!-- startup & tear down listener, + scheduled jobs + <serverplugin:plugin-component class="Foo" /> + --> + + + + <!-- How does this sender show up in drop downs etc --> + <short-name>Roles</short-name> + + <!-- Class that does the actual sending --> + <plugin-class>RolesSender</plugin-class> + + <custom-ui> + <ui-snippet-name>roles.xhtml</ui-snippet-name> + <backing-bean-name>RolesBackingBean</backing-bean-name> + </custom-ui> +</alert-plugin> \ No newline at end of file diff --git a/modules/enterprise/server/plugins/alert-roles/src/main/resources/roles.xhtml b/modules/enterprise/server/plugins/alert-roles/src/main/resources/roles.xhtml new file mode 100644 index 0000000..49dcf0b --- /dev/null +++ b/modules/enterprise/server/plugins/alert-roles/src/main/resources/roles.xhtml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<html xmlns="http://www.w3.org/1999/xhtml" + xmlns:h="http://java.sun.com/jsf/html" + xmlns:f="http://java.sun.com/jsf/core" + xmlns:ui="http://java.sun.com/jsf/facelets" + xmlns:c="http://java.sun.com/jstl/core" + xmlns:onc="http://jboss.org/on/component" + xmlns:a4j="https://richfaces.org/a4j" + xmlns:rich="http://richfaces.ajax4jsf.org/rich%22%3E + + <h:outputText value="Hello New Facelet roles world"/> + + <br/> + <h:outputText value="#{RolesBackingBean.message}"/> +</html> \ No newline at end of file diff --git a/modules/enterprise/server/plugins/pom.xml b/modules/enterprise/server/plugins/pom.xml index cf4e995..e201de1 100644 --- a/modules/enterprise/server/plugins/pom.xml +++ b/modules/enterprise/server/plugins/pom.xml @@ -41,7 +41,8 @@ <module>rhnhosted</module> <module>alert-email</module> <module>alert-mobicents</module> - <module>alert-microblog</module> + <module>alert-microblog</module> + <module>alert-roles</module> </modules>
</project>
commit e1ccf2a482f8312734fb034b8506b88986bbcaca Author: Heiko W. Rupp pilhuhn@fedorapeople.org Date: Fri Dec 4 12:49:48 2009 +0100
Cleanup and more support for custom-ui
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerBean.java index 7321832..c72980a 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerBean.java @@ -451,11 +451,6 @@ public class AlertNotificationManagerBean implements AlertNotificationManagerLoc } }
- public void handleAlertConfigurationDefinition(ConfigurationDefinition desc) { - - // TODO - } - public Configuration getAlertPropertiesConfiguration(AlertNotification notification) { Configuration config = notification.getConfiguration(); if (config!=null) @@ -465,12 +460,15 @@ public class AlertNotificationManagerBean implements AlertNotificationManagerLoc }
public ConfigurationDefinition getConfigurationDefinitionForSender(String shortName) { + AlertSenderPluginManager pluginmanager = alertManager.getAlertPluginManager(); - String pluginName = pluginmanager.getPluginNameForShortName(shortName); - PluginKey key = pluginmanager.getAlertSenderInfo(shortName).getPluginKey(); + + AlertSenderInfo senderInfo = pluginmanager.getAlertSenderInfo(shortName); + String pluginName = senderInfo.getPluginName(); + PluginKey key = senderInfo.getPluginKey(); + try { AlertPluginDescriptorType descriptor = (AlertPluginDescriptorType) serverPluginsBean.getServerPluginDescriptor(key); - // TODO get alert-propertis, not plugin-configuration //ConfigurationDefinition pluginConfigurationDefinition = ConfigurationMetadataParser.parse("pc:" + pluginName, descriptor.getPluginConfiguration()); ConfigurationDefinition pluginConfigurationDefinition = ConfigurationMetadataParser.parse("alerts:" + pluginName, descriptor.getAlertConfiguration());
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerLocal.java index f7f9aab..8093b7f 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerLocal.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerLocal.java @@ -71,8 +71,6 @@ public interface AlertNotificationManagerLocal {
int purgeOrphanedAlertNotifications();
- void handleAlertConfigurationDefinition(ConfigurationDefinition desc); - public Configuration getAlertPropertiesConfiguration(AlertNotification notification);
/** diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSenderPluginManager.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSenderPluginManager.java index d633d04..3a3b724 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSenderPluginManager.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSenderPluginManager.java @@ -28,10 +28,8 @@ import java.util.Map; import org.apache.commons.logging.Log; import org.w3c.dom.Element;
-import org.rhq.core.clientapi.descriptor.configuration.ConfigurationDescriptor; import org.rhq.core.domain.alert.notification.AlertNotification; import org.rhq.core.domain.configuration.Configuration; -import org.rhq.core.domain.plugin.Plugin; import org.rhq.core.domain.plugin.PluginKey; import org.rhq.core.domain.plugin.ServerPlugin; import org.rhq.enterprise.server.alert.AlertNotificationManagerLocal; @@ -52,7 +50,6 @@ import org.rhq.enterprise.server.xmlschema.generated.serverplugin.alert.CustomUi public class AlertSenderPluginManager extends ServerPluginManager {
private final Log log = getLog(); - private Map<String,String> pluginNameToType = new HashMap<String, String>(); private Map<String,String> pluginClassByName = new HashMap<String, String>(); private Map<String,ServerPluginEnvironment> pluginEnvByName = new HashMap<String, ServerPluginEnvironment>(); private Map<String,AlertSenderInfo> senderInfoByName = new HashMap<String, AlertSenderInfo>(); @@ -72,11 +69,12 @@ public class AlertSenderPluginManager extends ServerPluginManager { */ @Override public void loadPlugin(ServerPluginEnvironment env,boolean enable) throws Exception { + log.info("Start loading alert plugin " + env.getPluginKey().getPluginName()); super.loadPlugin(env,enable);
AlertPluginDescriptorType type = (AlertPluginDescriptorType) env.getPluginDescriptor();
- String className = ((Element)type.getPluginClass()).getTextContent(); + String className = type.getPluginClass(); if (!className.contains(".")) { className = type.getPackage() + "." + className; } @@ -84,7 +82,7 @@ public class AlertSenderPluginManager extends ServerPluginManager { Class.forName(className,false,env.getPluginClassLoader()); } catch (Exception e) { - log.error("Can't find pluginClass " + className + ". Plugin will be ignored"); + log.error("Can't find pluginClass " + className + ". Plugin " + env.getPluginKey().getPluginName() + " will be ignored"); try { unloadPlugin(env.getPluginKey().getPluginName()); } @@ -95,7 +93,7 @@ public class AlertSenderPluginManager extends ServerPluginManager { }
// The short name is basically the key into the plugin - String shortName = ((Element) type.getShortName()).getTextContent(); + String shortName = type.getShortName(); pluginClassByName.put(shortName,className);
// @@ -118,24 +116,48 @@ public class AlertSenderPluginManager extends ServerPluginManager { log.error("Plugin will be ignored"); return; } + + // Get the backing bean class + className = customUI.getBackingBeanName(); + if (!className.contains(".")) { + className = type.getPackage() + "." + className; + } + try { + Class.forName(className,true,env.getPluginClassLoader()); // TODO how make this available to Seam and the Web-CL ? + } + catch (Throwable t ) { + log.error("Backing bean " + className + " not found for plugin " + shortName); + } }
- AlertSenderInfo info = new AlertSenderInfo(shortName, "-TODO-", env.getPluginKey()); + AlertSenderInfo info = new AlertSenderInfo(shortName, type.getDescription(), env.getPluginKey()); info.setUiSnippetUrl(uiSnippetUrl); senderInfoByName.put(shortName, info);
pluginEnvByName.put(shortName,env);
- ConfigurationDescriptor desc = type.getAlertConfiguration(); + }
- AlertNotificationManagerLocal mgr = LookupUtil.getAlertNotificationManager(); - mgr.handleAlertConfigurationDefinition(null); // TODO remove ? + @Override + protected void unloadPlugin(String pluginName) throws Exception { + log.info("Unloading plugin " + pluginName ); + super.unloadPlugin(pluginName); + String shortName=null; + for (AlertSenderInfo info: senderInfoByName.values()) { + if (info.getPluginName().equals(pluginName)) { + shortName = info.getShortName(); + break; + } + } + pluginClassByName.remove(shortName); + senderInfoByName.remove(shortName); + pluginEnvByName.remove(shortName); }
/** * Instantiate an AlertSender for the passed shortName, which is the name you have provided * in the plugin descriptor in the <shortName> element - * @param notification + * @param notification The alert notification we need the sender for. Wanted sender is in notification.getSenderName() * @return a new AlertSender with preferences set * @see AlertSender */ @@ -163,10 +185,10 @@ public class AlertSenderPluginManager extends ServerPluginManager { return null; }
- // TODO We have no entityManager lying around here, which means + // We have no entityManager lying around here, which means // Configuration is an uninitialized Proxy and we'd get a LazyInit // Exception later. - // So lets get a session and attach the stuff... TODO + // So lets get it from the SessionBeans ServerPluginContext ctx = getServerPluginContext(env); AlertNotificationManagerLocal mgr = LookupUtil.getAlertNotificationManager();
@@ -196,11 +218,6 @@ public class AlertSenderPluginManager extends ServerPluginManager { return new ArrayList<String>(pluginClassByName.keySet()); }
- - public String getPluginNameForShortName(String shortName) { - return pluginNameToType.get(shortName); - } - public AlertSenderInfo getAlertSenderInfo(String shortName) { return senderInfoByName.get(shortName); } diff --git a/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-alert.xsd b/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-alert.xsd index e369a18..fbff21a 100644 --- a/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-alert.xsd +++ b/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-alert.xsd @@ -41,18 +41,19 @@ xs:complexContent <xs:extension base="serverplugin:ServerPluginDescriptorType"> xs:sequence - <xs:element name="short-name" minOccurs="1" maxOccurs="1"> + <xs:element name="short-name" minOccurs="1" maxOccurs="1" type="xs:string"> xs:annotation xs:documentation The short name of this plugin as it will be shown in Headers and drop down boxes </xs:documentation> </xs:annotation> </xs:element> - <xs:element name="plugin-class" minOccurs="1" maxOccurs="1"> + <xs:element name="plugin-class" minOccurs="1" maxOccurs="1" type="xs:string"> xs:annotation xs:documentation The name of the class implementing the plugin functionality. This class needs to - implement the org.rhq.enterprise.server.plugin.pc.alert.AlertSender base class + implement the org.rhq.enterprise.server.plugin.pc.alert.AlertSender base class. + If not fully qualified, the package given on the <alert-plugin> element will be taken. </xs:documentation> </xs:annotation> </xs:element> @@ -93,6 +94,14 @@ </xs:documentation> </xs:annotation> </xs:element> + <xs:element name="backing-bean-name" minOccurs="1" maxOccurs="1" type="xs:string"> + xs:annotation + xs:documentation + The class name of a backing bean used in this ui-snippet. + If not fully qualified, the package given on the <alert-plugin> element will be taken. + </xs:documentation> + </xs:annotation> + </xs:element> </xs:sequence> </xs:complexType> </xs:element>
commit 701fff884a27d7f1175462b5ad2e6398141f44ba Author: Heiko W. Rupp pilhuhn@fedorapeople.org Date: Fri Dec 4 09:18:33 2009 +0100
Start supporting custom user UIs for alert properties.
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/ListNotificationsUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/ListNotificationsUIBean.java index fcce6fd..44cb584 100644 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/ListNotificationsUIBean.java +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/ListNotificationsUIBean.java @@ -45,6 +45,7 @@ import org.rhq.core.gui.util.StringUtility; import org.rhq.enterprise.gui.util.EnterpriseFacesContextUtility; import org.rhq.enterprise.server.alert.AlertDefinitionManagerLocal; import org.rhq.enterprise.server.alert.AlertNotificationManagerLocal; +import org.rhq.enterprise.server.plugin.pc.alert.AlertSenderInfo; import org.rhq.enterprise.server.util.LookupUtil;
/** @@ -172,4 +173,16 @@ public class ListNotificationsUIBean {
return OUTCOME_SUCCESS; } + + + public String getCustomContentUrl() { + AlertNotificationManagerLocal mgr = LookupUtil.getAlertNotificationManager(); + Subject subject = EnterpriseFacesContextUtility.getSubject(); + + AlertSenderInfo info = mgr.getAlertInfoForSender(selectedSender); + if (info!=null && info.getUiSnippetUrl()!=null) + return info.getUiSnippetUrl().toString(); + else + return "/rhq/empty.xhtml"; + } } \ No newline at end of file diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/empty.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/empty.xhtml new file mode 100644 index 0000000..f32e91a --- /dev/null +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/empty.xhtml @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<html xmlns="http://www.w3.org/1999/xhtml" + xmlns:ui="http://java.sun.com/jsf/facelets%22%3E +ui:remove + THIS FILE IS INTENTIONALLY BLANK +</ui:remove> +</html> \ No newline at end of file diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/alert/notif/listAlertSender.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/alert/notif/listAlertSender.xhtml index 8fae094..667cadd 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/alert/notif/listAlertSender.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/alert/notif/listAlertSender.xhtml @@ -129,6 +129,10 @@ action="#{ListNotificationsUIBean.mySubmitForm}" /> </rich:panel> + + <!-- user supplied UI --> + <ui:include src="#{ListNotificationsUIBean.customContentUrl}"/> + </h:form>
<h:outputLink value="/rhq/resource/alert/listAlertDefinitions.xhtml"> @@ -137,4 +141,4 @@ </h:outputLink> </ui:define> </ui:composition> -</html> \ No newline at end of file +</html> diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerBean.java index 9a0399c..7321832 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerBean.java @@ -60,6 +60,7 @@ import org.rhq.enterprise.server.authz.RoleManagerLocal; import org.rhq.enterprise.server.configuration.ConfigurationManagerLocal; import org.rhq.enterprise.server.configuration.metadata.ConfigurationMetadataManagerLocal; import org.rhq.enterprise.server.plugin.ServerPluginsLocal; +import org.rhq.enterprise.server.plugin.pc.alert.AlertSenderInfo; import org.rhq.enterprise.server.plugin.pc.alert.AlertSenderPluginManager; import org.rhq.enterprise.server.xmlschema.generated.serverplugin.ServerPluginDescriptorType; import org.rhq.enterprise.server.xmlschema.generated.serverplugin.alert.AlertPluginDescriptorType; @@ -493,6 +494,13 @@ public class AlertNotificationManagerBean implements AlertNotificationManagerLoc return senders; }
+ public AlertSenderInfo getAlertInfoForSender(String shortName) { + AlertSenderPluginManager pluginmanager = alertManager.getAlertPluginManager(); + AlertSenderInfo info = pluginmanager.getAlertSenderInfo(shortName); + + return info; + } + /** * Add a new AlertNotification to the passed definition * @param user subject of the caller @@ -514,7 +522,7 @@ public class AlertNotificationManagerBean implements AlertNotificationManagerLoc notif.setConfiguration(configuration); entityManager.persist(notif); definition.getAlertNotifications().add(notif); - + }
/** diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerLocal.java index debec43..f7f9aab 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerLocal.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerLocal.java @@ -33,6 +33,7 @@ import org.rhq.core.domain.configuration.Configuration; import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; import org.rhq.core.domain.util.PageControl; import org.rhq.core.domain.util.PageList; +import org.rhq.enterprise.server.plugin.pc.alert.AlertSenderInfo;
/** * @author Joseph Marques @@ -103,4 +104,6 @@ public interface AlertNotificationManagerLocal { * */ List<AlertNotification> getNotificationsForAlertDefinition(Subject user, int alertDefinitionId); + + AlertSenderInfo getAlertInfoForSender(String shortName); } \ No newline at end of file diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSenderInfo.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSenderInfo.java index ac03577..c6570e5 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSenderInfo.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSenderInfo.java @@ -18,6 +18,8 @@ */ package org.rhq.enterprise.server.plugin.pc.alert;
+import java.net.URL; + import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory;
@@ -33,6 +35,7 @@ public class AlertSenderInfo { private String description; private String pluginName; private PluginKey pluginKey; + private URL uiSnippetUrl;
public AlertSenderInfo(String shortName, String description, PluginKey key) { this.shortName = shortName; @@ -64,4 +67,12 @@ public class AlertSenderInfo { public PluginKey getPluginKey() { return pluginKey; } + + public URL getUiSnippetUrl() { + return uiSnippetUrl; + } + + public void setUiSnippetUrl(URL uiSnippetUrl) { + this.uiSnippetUrl = uiSnippetUrl; + } } diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSenderPluginManager.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSenderPluginManager.java index 54cc203..d633d04 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSenderPluginManager.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSenderPluginManager.java @@ -18,6 +18,7 @@ */ package org.rhq.enterprise.server.plugin.pc.alert;
+import java.net.URL; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -41,6 +42,7 @@ import org.rhq.enterprise.server.plugin.pc.ServerPluginEnvironment; import org.rhq.enterprise.server.plugin.pc.ServerPluginManager; import org.rhq.enterprise.server.util.LookupUtil; import org.rhq.enterprise.server.xmlschema.generated.serverplugin.alert.AlertPluginDescriptorType; +import org.rhq.enterprise.server.xmlschema.generated.serverplugin.alert.CustomUi;
/** * Plugin manager that takes care of loading the plug-ins and instantiating @@ -82,7 +84,7 @@ public class AlertSenderPluginManager extends ServerPluginManager { Class.forName(className,false,env.getPluginClassLoader()); } catch (Exception e) { - log.warn("Can't find pluginClass " + className + ". Plugin will be ignored"); + log.error("Can't find pluginClass " + className + ". Plugin will be ignored"); try { unloadPlugin(env.getPluginKey().getPluginName()); } @@ -91,16 +93,43 @@ public class AlertSenderPluginManager extends ServerPluginManager { } return; } + + // The short name is basically the key into the plugin String shortName = ((Element) type.getShortName()).getTextContent(); pluginClassByName.put(shortName,className); - senderInfoByName.put(shortName,new AlertSenderInfo(shortName,"-TODO-",env.getPluginKey())); + + // + // Ok, we have a valid plugin class, so we can look for other things + // and store the info + // + + String uiSnippetPath; + URL uiSnippetUrl = null; + CustomUi customUI = type.getCustomUi(); + if (customUI!=null) { + uiSnippetPath = customUI.getUiSnippetName(); + + try { + uiSnippetUrl = env.getPluginClassLoader().getResource(uiSnippetPath); + log.info("UI snipped for " + shortName + " is at " + uiSnippetUrl); + } + catch (Exception e) { + log.error("No valid ui snippet provided, but <custom-ui> given for sender plugin " + shortName + "Error is "+ e.getMessage()); + log.error("Plugin will be ignored"); + return; + } + } + + AlertSenderInfo info = new AlertSenderInfo(shortName, "-TODO-", env.getPluginKey()); + info.setUiSnippetUrl(uiSnippetUrl); + senderInfoByName.put(shortName, info);
pluginEnvByName.put(shortName,env);
ConfigurationDescriptor desc = type.getAlertConfiguration();
AlertNotificationManagerLocal mgr = LookupUtil.getAlertNotificationManager(); - mgr.handleAlertConfigurationDefinition(null); // TODO + mgr.handleAlertConfigurationDefinition(null); // TODO remove ? }
/** diff --git a/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-alert.xsd b/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-alert.xsd index 404887f..e369a18 100644 --- a/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-alert.xsd +++ b/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-alert.xsd @@ -36,6 +36,7 @@ </xs:appinfo> </xs:annotation> </xs:element> + <xs:complexType name="AlertPluginDescriptorType"> xs:complexContent <xs:extension base="serverplugin:ServerPluginDescriptorType"> @@ -57,6 +58,7 @@ </xs:element> <!-- alert specific schema goes here. note, serverplugin xsd gives you global <plugin-configuration> already --> <xs:element ref="alert:alert-configuration" minOccurs="0" maxOccurs="1"/> + <xs:element ref="alert:custom-ui" minOccurs="0" maxOccurs="1"/> </xs:sequence> </xs:extension> </xs:complexContent> @@ -68,7 +70,32 @@ This section defines the configuration items that are used for individual alert templates. </xs:documentation> </xs:annotation> + </xs:element>
+ <xs:element name="custom-ui"> + xs:annotation + xs:documentation + This element provides information for custom configuration UIs. If it is used, + the configuration from <alert:alert-configuration/> is *not* used and the user + is responsible itself for filling in the alertProperties configuration that gets + injected into the alert sender. + </xs:documentation> + </xs:annotation> + xs:complexType + xs:sequence + <xs:element name="ui-snippet-name" minOccurs="1" maxOccurs="1" type="xs:string"> + xs:annotation + xs:documentation + The name of a file that provides Facelets or xhtml content, + which gets included via <ui:include/> into the configuration + page. Put the file into the src/resources/ folder in the maven build + which puts them into the root of the generated jar file. + </xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> </xs:element>
+ </xs:schema>
commit e03430fb4d3994535dc7b21db2771ca06a9643ea Merge: 321a857... 07eab37... Author: Partha Aji paji@redhat.com Date: Thu Dec 3 20:34:36 2009 -0500
Fixed a bunch of conflicts
diff --cc modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveManagerHelper.java index 94c2d19,0000000..1dc5206 mode 100644,000000..100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveManagerHelper.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveManagerHelper.java @@@ -1,42 -1,0 +1,42 @@@ +package org.rhq.enterprise.server.perspective; + +import org.rhq.enterprise.server.plugin.pc.MasterServerPluginContainer; +import org.rhq.enterprise.server.plugin.pc.ServerPluginServiceManagement; +import org.rhq.enterprise.server.plugin.pc.perspective.PerspectiveServerPluginContainer; +import org.rhq.enterprise.server.plugin.pc.perspective.PerspectiveServerPluginManager; +import org.rhq.enterprise.server.plugin.pc.perspective.metadata.PerspectivePluginMetadataManager; +import org.rhq.enterprise.server.util.LookupUtil; + +public class PerspectiveManagerHelper { + + public static PerspectiveServerPluginContainer getPluginContainer() throws Exception { + PerspectiveServerPluginContainer pc = null; + + try { + ServerPluginServiceManagement mbean = LookupUtil.getServerPluginService(); + if (!mbean.isMasterPluginContainerStarted()) { + throw new IllegalStateException("The master plugin container is not started!"); + } + + MasterServerPluginContainer master = mbean.getMasterPluginContainer(); - pc = master.getPluginContainer(PerspectiveServerPluginContainer.class); ++ pc = master.getPluginContainerByClass(PerspectiveServerPluginContainer.class); + } catch (IllegalStateException ise) { + throw ise; + } catch (Exception e) { + throw new Exception("Cannot obtain the Perspective plugin container", e); + } + + if (pc == null) { + throw new Exception("Perspective plugin container is null!"); + } + + return pc; + } + + public static PerspectivePluginMetadataManager getPluginMetadataManager() throws Exception { + PerspectiveServerPluginManager manager = (PerspectiveServerPluginManager) getPluginContainer() + .getPluginManager(); + return manager.getMetadataManager(); + } + +} diff --cc modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginManager.java index c747814,769db26..ef8a591 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginManager.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginManager.java @@@ -284,27 -380,20 +380,18 @@@ public class ServerPluginManager MasterServerPluginContainerConfiguration masterConfig = masterPC.getConfiguration(); File dataDir = new File(masterConfig.getDataDirectory(), pluginName); File tmpDir = masterConfig.getTemporaryDirectory(); - - Configuration plugnConfig; + Configuration pluginConfig = null; List<ScheduledJobDefinition> schedules; - try { - // TODO: today we have no way in the UI to customize the plugin config values - // for now, just use the defaults as defined in the descriptor - ConfigurationDefinition configDef = ServerPluginDescriptorMetadataParser - .getPluginConfigurationDefinition(pluginDescriptor); - // It is not required that a server plugin define plugin configuration - if (null != configDef) { - pluginConfig = configDef.getDefaultTemplate().createConfiguration(); - } - - // TODO: today we have no way in the UI to customize the schedules - // for now, just use the defaults as defined in the descriptor - schedules = ServerPluginDescriptorMetadataParser.getScheduledJobs(pluginDescriptor); + ServerPlugin plugin = getPlugin(env); - plugnConfig = plugin.getPluginConfiguration(); ++ pluginConfig = plugin.getPluginConfiguration(); + Configuration scheduledJobsConfig = plugin.getScheduledJobsConfiguration(); + schedules = ServerPluginDescriptorMetadataParser.getScheduledJobs(scheduledJobsConfig); } catch (Exception e) { - // TODO need proper exception handling - throw new RuntimeException(e); + throw new RuntimeException("Failed to get plugin config/schedules from the database", e); }
- context = new ServerPluginContext(env, dataDir, tmpDir, plugnConfig, schedules); + context = new ServerPluginContext(env, dataDir, tmpDir, pluginConfig, schedules); this.pluginContextCache.put(pluginName, context); return context; } diff --cc modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/perspective/PerspectiveServerPluginManager.java index ee0fef1,0000000..1554b08 mode 100644,000000..100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/perspective/PerspectiveServerPluginManager.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/perspective/PerspectiveServerPluginManager.java @@@ -1,219 -1,0 +1,220 @@@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2009 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.plugin.pc.perspective; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.util.Collections; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; + +import javax.management.MBeanServerConnection; +import javax.management.ObjectName; +import javax.naming.Context; +import javax.naming.InitialContext; + +import org.rhq.core.util.file.FileUtil; +import org.rhq.enterprise.server.plugin.pc.ServerPluginEnvironment; +import org.rhq.enterprise.server.plugin.pc.ServerPluginManager; +import org.rhq.enterprise.server.plugin.pc.perspective.metadata.PerspectivePluginMetadataManager; +import org.rhq.enterprise.server.xmlschema.generated.serverplugin.perspective.PerspectivePluginDescriptorType; + +/** + * This loads in all perspective server plugins that can be found. You can obtain a loaded plugin's + * {@link ServerPluginEnvironment environment}, including its classloader, from this object as well. + * + * @author Jay Shaughnessy + * @author John Mazzitelli + */ +public class PerspectiveServerPluginManager extends ServerPluginManager { + + private PerspectivePluginMetadataManager metadataManager; + + public PerspectiveServerPluginManager(PerspectiveServerPluginContainer pc) { + super(pc); + } + + @Override + public void initialize() throws Exception { + super.initialize(); + this.metadataManager = new PerspectivePluginMetadataManager(); + } + + @Override + public void shutdown() { + super.shutdown(); + this.metadataManager = null; + } + + /** + * An object that can be used to process and store all metadata from all perspective plugins. This object will contain all the + * metadata found in all loaded perspective plugins. + * + * @return object to retrieve plugin metadata from + */ + public PerspectivePluginMetadataManager getMetadataManager() { + return this.metadataManager; + } + + /* At load-time ensure that any WAR files packaged with the server plugin are deployed to the RHQ + * Server. Note, perspective apps are logically deployed along-side, not inside the rhq.ear (although physically + * under the default/work). They should have access to the same shared components. + * + * @see org.rhq.enterprise.server.plugin.pc.AbstractTypeServerPluginContainer#loadPlugin(org.rhq.enterprise.server.plugin.pc.ServerPluginEnvironment) + */ + @Override - public synchronized void loadPlugin(ServerPluginEnvironment env) throws Exception { - super.loadPlugin(env); ++ public synchronized void loadPlugin(ServerPluginEnvironment env, boolean enabled) throws Exception { ++ super.loadPlugin(env, enabled); + + // merge this perspective into any previously loaded perspective definitions + this.metadataManager.loadPlugin((PerspectivePluginDescriptorType) env.getPluginDescriptor()); + + String name = null; + try { + JarFile plugin = new JarFile(env.getPluginUrl().getFile()); + for (JarEntry entry : Collections.list(plugin.entries())) { + name = entry.getName(); + if (name.toLowerCase().endsWith(".war")) { + deployWar(env, entry.getName(), plugin.getInputStream(entry)); + } + } + } catch (Exception e) { - getLog().error("Failed to deploy " + env.getPluginName() + "#" + name, e); ++ getLog().error("Failed to deploy " + env.getPluginKey().getPluginName() + "#" + name, e); + } + } + + private void deployWar(ServerPluginEnvironment env, String name, InputStream iStream) { + try { + // Save the war file to the plugins data directory. This survives restarts and will + // act as our deploy directory. + File deployFile = writeWarToFile(getDeployFile(env, name), iStream); + + // get reference to MBean server + Context ic = new InitialContext(); + MBeanServerConnection server = (MBeanServerConnection) ic.lookup("jmx/invoker/RMIAdaptor"); + + // get reference to MainDeployer MBean + ObjectName mainDeployer = new ObjectName("jboss.system:service=MainDeployer"); + + server.invoke(mainDeployer, "deploy", new Object[] { deployFile.getAbsolutePath() }, + new String[] { String.class.getName() }); + + } catch (Exception e) { + e.printStackTrace(); + } + } + + private File getDeployFile(ServerPluginEnvironment env, String name) throws IOException { + File dataDir = getServerPluginContext(env).getDataDirectory(); + dataDir.mkdirs(); + return new File(dataDir, name); + } + + private File writeWarToFile(File destFile, InputStream iStream) throws Exception { + + // Delete any previous instance of the file + if (destFile.exists()) { + getLog().debug("Existing file found and will be deleted at: " + destFile); + destFile.delete(); + } + + FileUtil.writeFile(iStream, destFile); + + if (!destFile.exists()) { + String err = "Temporary file for application update not written to: " + destFile; + getLog().error(err); + throw new Exception(err); + } + + return destFile; + } + + /** + * All of the plugins have been loaded, so now let the metadata manager sort through the definitions. + * + * @see org.rhq.enterprise.server.plugin.pc.ServerPluginManager#startPlugins() + */ + @Override + public synchronized void startPlugins() { + super.startPlugins(); + + this.metadataManager.start(); + } + + /* (non-Javadoc) + * @see org.rhq.enterprise.server.plugin.pc.ServerPluginManager#stopPlugins() + */ + @Override + public synchronized void stopPlugins() { + // TODO Auto-generated method stub + super.stopPlugins(); + } + + /* At unload-time ensure that any WAR files packaged with the server plugin are un-deployed on + * the RHQ Server. + * + * @see org.rhq.enterprise.server.plugin.pc.AbstractTypeServerPluginContainer#unloadPlugin(org.rhq.enterprise.server.plugin.pc.ServerPluginEnvironment) + */ + @Override - public synchronized void unloadPlugin(ServerPluginEnvironment env) throws Exception { ++ public synchronized void unloadPlugin(String pluginName) throws Exception { ++ ServerPluginEnvironment env = getPluginEnvironment(pluginName); + String name = null; + try { + JarFile plugin = new JarFile(env.getPluginUrl().getFile()); + for (JarEntry entry : Collections.list(plugin.entries())) { + name = entry.getName(); + if (name.toLowerCase().endsWith(".war")) { + undeployWar(getDeployFile(env, entry.getName())); + } + } + + } catch (Exception e) { - getLog().error("Failed to deploy " + env.getPluginName() + "#" + name, e); ++ getLog().error("Failed to deploy " + env.getPluginKey().getPluginName() + "#" + name, e); + } + + this.metadataManager.unloadPlugin((PerspectivePluginDescriptorType) env.getPluginDescriptor()); + - super.unloadPlugin(env); ++ super.unloadPlugin(pluginName); + } + + private void undeployWar(File deployFile) { + try { + // get reference to MBean server + Context ic = new InitialContext(); + MBeanServerConnection server = (MBeanServerConnection) ic.lookup("jmx/invoker/RMIAdaptor"); + + // get reference to MainDeployer MBean + ObjectName mainDeployer = new ObjectName("jboss.system:service=MainDeployer"); + + URL fileUrl = deployFile.toURI().toURL(); + + Boolean isDeployed = (Boolean) server.invoke(mainDeployer, "isDeployed", new Object[] { fileUrl }, + new String[] { URL.class.getName() }); + + if (isDeployed) { + server.invoke(mainDeployer, "undeploy", new Object[] { fileUrl }, new String[] { URL.class.getName() }); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + +} diff --cc modules/plugins/jboss-cache-v3/pom.xml index df71edc,cb75b29..6ed68dc --- a/modules/plugins/jboss-cache-v3/pom.xml +++ b/modules/plugins/jboss-cache-v3/pom.xml @@@ -22,8 -22,8 +22,7 @@@
<properties> <scm.module.path>modules/plugins/jboss-cache-v3/</scm.module.path> - - <jbossas.version>5.2.0-SNAPSHOT</jbossas.version> - <rhq.groupId>org.rhq</rhq.groupId> + <jbossas.version>6.0.0.M1</jbossas.version> </properties>
<dependencyManagement> @@@ -588,3 -588,3 +587,4 @@@ </reporting>
</project> ++
commit 02d4ac93b97dd44dff2c890e22083d55c5798550 Author: John Mazzitelli mazz@redhat.com Date: Thu Dec 3 20:27:08 2009 -0500
provide a way to restart the master PC from the plugin UI
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/InstalledPluginsUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/InstalledPluginsUIBean.java index 9ba94c7..52fecb0 100644 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/InstalledPluginsUIBean.java +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/InstalledPluginsUIBean.java @@ -64,6 +64,19 @@ public class InstalledPluginsUIBean { public InstalledPluginsUIBean() { }
+ public void restartMasterPluginContainer() { + + hasPermission(); + try { + Subject subject = EnterpriseFacesContextUtility.getSubject(); + serverPluginsBean.restartMasterPluginContainer(subject); + FacesContextUtility.addMessage(FacesMessage.SEVERITY_INFO, "Master plugin container has been restarted."); + } catch (Exception e) { + processException("Failed to restart the master plugin container", e); + } + return; + } + public Collection<Plugin> getInstalledAgentPlugins() {
hasPermission(); diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-list.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-list.xhtml index 24d2bc9..f9addf1 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-list.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-list.xhtml @@ -216,17 +216,6 @@ <f:facet name="footer"> rich:columnGroup <rich:column colspan="#{InstalledPluginsSessionUIBean.showAllServerPlugins ? 6 : 5}" width="100%"> - <h:commandButton action="#{InstalledPluginsUIBean.scan}" - value="SCAN FOR UPDATES" styleClass="on-pager-button buttonsmall"> - </h:commandButton> - <h:commandButton action="#{InstalledPluginsSessionUIBean.showUndeployedServerPlugins}" - rendered="#{!InstalledPluginsSessionUIBean.showAllServerPlugins}" - value="SHOW UNDEPLOYED" styleClass="on-pager-button buttonsmall"> - </h:commandButton> - <h:commandButton action="#{InstalledPluginsSessionUIBean.hideUndeployedServerPlugins}" - rendered="#{InstalledPluginsSessionUIBean.showAllServerPlugins}" - value="HIDE UNDEPLOYED" styleClass="on-pager-button buttonsmall"> - </h:commandButton> <onc:selectCommandButton action="#{InstalledPluginsUIBean.enableServerPlugins}" value="ENABLE" target="selectedPlugin" styleClass="on-pager-button buttonsmall"> </onc:selectCommandButton> @@ -240,6 +229,22 @@ value="PURGE" target="selectedPlugin" styleClass="on-pager-button buttonsmall"> </onc:selectCommandButton> </rich:column> + <rich:column breakBefore="true" colspan="#{InstalledPluginsSessionUIBean.showAllServerPlugins ? 6 : 5}" width="100%"> + <h:commandButton action="#{InstalledPluginsUIBean.scan}" + value="SCAN FOR UPDATES" styleClass="on-pager-button buttonsmall"> + </h:commandButton> + <h:commandButton action="#{InstalledPluginsUIBean.restartMasterPluginContainer}" + value="RESTART MASTER PLUGIN CONTAINER" styleClass="on-pager-button buttonsmall"> + </h:commandButton> + <h:commandButton action="#{InstalledPluginsSessionUIBean.showUndeployedServerPlugins}" + rendered="#{!InstalledPluginsSessionUIBean.showAllServerPlugins}" + value="SHOW UNDEPLOYED" styleClass="on-pager-button buttonsmall"> + </h:commandButton> + <h:commandButton action="#{InstalledPluginsSessionUIBean.hideUndeployedServerPlugins}" + rendered="#{InstalledPluginsSessionUIBean.showAllServerPlugins}" + value="HIDE UNDEPLOYED" styleClass="on-pager-button buttonsmall"> + </h:commandButton> + </rich:column> </rich:columnGroup> </f:facet>
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsBean.java index 8a15d5c..d86e958 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsBean.java @@ -79,6 +79,11 @@ public class ServerPluginsBean implements ServerPluginsLocal { @EJB private ServerPluginsLocal serverPluginsBean; //self
+ @RequiredPermission(Permission.MANAGE_SETTINGS) + public void restartMasterPluginContainer(Subject subject) { + LookupUtil.getServerPluginService().restartMasterPluginContainer(); + } + @SuppressWarnings("unchecked") public List<ServerPlugin> getServerPlugins() { Query q = entityManager.createNamedQuery(ServerPlugin.QUERY_FIND_ALL_INSTALLED); diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsLocal.java index 191e8e7..09323ac 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsLocal.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsLocal.java @@ -25,6 +25,14 @@ import org.rhq.enterprise.server.xmlschema.generated.serverplugin.ServerPluginDe @Local public interface ServerPluginsLocal { /** + * Recycles the master plugin container, essentially shutting down all server plugins + * and then restarting them. + * + * @param subject the user asking to restart the master plugin container + */ + void restartMasterPluginContainer(Subject subject); + + /** * Returns a list of all the installed server plugins in the database * * @return all installed server plugins found in the DB
commit b27d35f3c786ffc8140d9cd23cb006b54625a307 Author: Justin Harris jharris@redhat.com Date: Thu Dec 3 18:36:29 2009 -0500
Making add/update lists work for both scheduled jobs and plugin configs.
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/EditPluginConfigurationUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/EditPluginConfigurationUIBean.java index cd63cb4..6dab242 100644 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/EditPluginConfigurationUIBean.java +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/EditPluginConfigurationUIBean.java @@ -26,8 +26,11 @@ import org.jboss.seam.annotations.In; import org.jboss.seam.annotations.Logger; import org.jboss.seam.annotations.Name; import org.jboss.seam.annotations.Scope; +import org.jboss.seam.annotations.web.RequestParameter; import org.jboss.seam.log.Log; import org.rhq.core.domain.auth.Subject; +import org.rhq.core.domain.configuration.Configuration; +import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; import org.rhq.core.domain.plugin.ServerPlugin; import org.rhq.core.gui.util.FacesContextUtility; import org.rhq.enterprise.gui.util.EnterpriseFacesContextUtility; @@ -41,6 +44,17 @@ public class EditPluginConfigurationUIBean extends AbstractPluginConfigurationUI @Logger private Log log;
+ private Configuration currentConfiguration; + private ConfigurationDefinition currentConfigurationDefinition; + + public Configuration getCurrentConfiguration() { + return currentConfiguration; + } + + public ConfigurationDefinition getCurrentConfigurationDefinition() { + return currentConfigurationDefinition; + } + @Create public void init() { checkPermission(); @@ -57,6 +71,29 @@ public class EditPluginConfigurationUIBean extends AbstractPluginConfigurationUI } }
+ @RequestParameter("listName") + public void setListName(String listName) { + ServerPlugin plugin = getPlugin(); + + if (listName != null && plugin != null) { + if (hasListName(plugin.getPluginConfiguration(), listName)) { + this.currentConfiguration = plugin.getPluginConfiguration(); + this.currentConfigurationDefinition = getPluginConfigurationDefinition(); + } else if (hasListName(plugin.getScheduledJobsConfiguration(), listName)) { + this.currentConfiguration = plugin.getScheduledJobsConfiguration(); + this.currentConfigurationDefinition = getScheduledJobsDefinition(); + } + } + } + + private boolean hasListName(Configuration config, String listName) { + if (config != null) { + return config.getList(listName) != null; + } + + return false; + } + public String finishMap() { FacesContextUtility.addMessage(FacesMessage.SEVERITY_INFO, "Map updated."); return "success"; diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-edit-add-map.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-edit-add-map.xhtml index 146e8c2..223074e 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-edit-add-map.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-edit-add-map.xhtml @@ -16,8 +16,8 @@ <ui:param name="editBreadCrumb" value="true" />
<ui:define name="mapConfig"> - <onc:config configurationDefinition="#{editPluginConfigurationUIBean.scheduledJobsDefinition}" - configuration="#{editPluginConfigurationUIBean.plugin.scheduledJobsConfiguration}" + <onc:config configurationDefinition="#{editPluginConfigurationUIBean.currentConfigurationDefinition}" + configuration="#{editPluginConfigurationUIBean.currentConfiguration}" listName="#{param.listName}" />
<h:panelGrid columns="2" styleClass="buttons-table" columnClasses="button-cell"> diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-edit-update-map.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-edit-update-map.xhtml index cd7611d..db99b33 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-edit-update-map.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-edit-update-map.xhtml @@ -16,8 +16,8 @@ <ui:param name="editBreadCrumb" value="true" />
<ui:define name="mapConfig"> - <onc:config configurationDefinition="#{editPluginConfigurationUIBean.scheduledJobsDefinition}" - configuration="#{editPluginConfigurationUIBean.plugin.scheduledJobsConfiguration}" + <onc:config configurationDefinition="#{editPluginConfigurationUIBean.currentConfigurationDefinition}" + configuration="#{editPluginConfigurationUIBean.currentConfiguration}" listName="#{param.listName}" listIndex="#{param.listIndex}" />
commit 4036c1c05fbcd5e68b671f6de0d871f92b8f93f7 Author: Justin Harris jharris@redhat.com Date: Thu Dec 3 15:58:47 2009 -0500
Adding in 'user defined jobs' functionality.
Note that this is hard-coded to configure scheduled jobs - if the plugin configuration can also define a list-o-maps, this will need to be modified.
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/EditPluginConfigurationUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/EditPluginConfigurationUIBean.java index d12f6c7..cd63cb4 100644 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/EditPluginConfigurationUIBean.java +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/EditPluginConfigurationUIBean.java @@ -34,7 +34,7 @@ import org.rhq.enterprise.gui.util.EnterpriseFacesContextUtility; import org.rhq.enterprise.server.plugin.ServerPluginsLocal; import org.rhq.enterprise.server.util.LookupUtil;
-@Scope(ScopeType.PAGE) +@Scope(ScopeType.SESSION) @Name("editPluginConfigurationUIBean") public class EditPluginConfigurationUIBean extends AbstractPluginConfigurationUIBean implements Serializable {
@@ -50,14 +50,19 @@ public class EditPluginConfigurationUIBean extends AbstractPluginConfigurationUI // The superclass holds the plugin instance variable, but in this // case we want it injected via the PluginFactory - so this serves as // the injection point - @In(value="plugin", required=false) + @In(value = "plugin", required = false) public void setCurrentPlugin(ServerPlugin currentPlugin) { if (currentPlugin != null) { setPlugin(currentPlugin); } }
- public void updatePlugin() { + public String finishMap() { + FacesContextUtility.addMessage(FacesMessage.SEVERITY_INFO, "Map updated."); + return "success"; + } + + public String updatePlugin() { try { ServerPluginsLocal serverPlugins = LookupUtil.getServerPlugins(); Subject subject = EnterpriseFacesContextUtility.getSubject(); @@ -67,6 +72,10 @@ public class EditPluginConfigurationUIBean extends AbstractPluginConfigurationUI log.error("Error updating the plugin configurations.", e); FacesContextUtility.addMessage(FacesMessage.SEVERITY_ERROR, "There was an error changing the configuration settings.", e); + + return null; } + + return "success"; } } diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/PluginFactory.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/PluginFactory.java index 8ea7838..3e1c4dd 100644 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/PluginFactory.java +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/PluginFactory.java @@ -31,8 +31,8 @@ import org.rhq.enterprise.server.plugin.ServerPluginsLocal; import org.rhq.enterprise.server.util.LookupUtil;
/** - * Component responsible for looking up a {@link Plugin}, obtaining - * the <code>name</code> and <code>type</code> from request parameters. + * Component responsible for providing a {@link Plugin} via request + * parameters. * * @author jharris */ diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-navigation/admin-navigation.xml b/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-navigation/admin-navigation.xml index 93932df..9a597b9 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-navigation/admin-navigation.xml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-navigation/admin-navigation.xml @@ -28,6 +28,63 @@ </navigation-case>
</navigation-rule> + + <navigation-rule> + <from-view-id>/rhq/admin/plugin/plugin-config.xhtml</from-view-id> + + <navigation-case> + <from-action>#{ConfigHelperUIBean.accessMap}</from-action> + <to-view-id>/rhq/admin/plugin/plugin-edit-view-map.xhtml?plugin=#{pluginConfigUIBean.plugin.name}&deployment=#{pluginConfigUIBean.plugin.deployment}&pluginType=#{pluginConfigUIBean.plugin.type}&listName=#{param.listName}&listIndex=#{param.listIndex}</to-view-id> + + <redirect /> + </navigation-case> + </navigation-rule> + + <navigation-rule> + <from-view-id>/rhq/admin/plugin/plugin-edit.xhtml</from-view-id> + + <navigation-case> + <from-action>#{ConfigHelperUIBean.addNewMap}</from-action> + <to-view-id>/rhq/admin/plugin/plugin-edit-add-map.xhtml</to-view-id> + </navigation-case> + + <navigation-case> + <from-action>#{ConfigHelperUIBean.accessMap}</from-action> + <to-view-id>/rhq/admin/plugin/plugin-edit-update-map.xhtml</to-view-id> + </navigation-case> + + <navigation-case> + <from-action>#{editPluginConfigurationUIBean.updatePlugin}</from-action> + <from-outcome>success</from-outcome> + <to-view-id>/rhq/admin/plugin/plugin-config.xhtml?pluginName=#{editPluginConfigurationUIBean.plugin.name}</to-view-id> + + <redirect /> + </navigation-case> + </navigation-rule> + + <navigation-rule> + <from-view-id>/rhq/admin/plugin/plugin-edit-add-map.xhtml</from-view-id> + + <navigation-case> + <from-outcome>success</from-outcome> + <to-view-id>/rhq/admin/plugin/plugin-edit.xhtml?plugin=#{pluginConfigUIBean.plugin.name}&deployment=#{pluginConfigUIBean.plugin.deployment}&pluginType=#{pluginConfigUIBean.plugin.type}</to-view-id> + + <redirect/> + </navigation-case> + + </navigation-rule> + + <navigation-rule> + <from-view-id>/rhq/admin/plugin/plugin-edit-update-map.xhtml</from-view-id> + + <navigation-case> + <from-outcome>success</from-outcome> + <to-view-id>/rhq/admin/plugin/plugin-edit.xhtml?plugin=#{pluginConfigUIBean.plugin.name}&deployment=#{pluginConfigUIBean.plugin.deployment}&pluginType=#{pluginConfigUIBean.plugin.type}</to-view-id> + + <redirect/> + </navigation-case> + + </navigation-rule>
<navigation-rule> <navigation-case> diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-edit-add-map.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-edit-add-map.xhtml new file mode 100644 index 0000000..146e8c2 --- /dev/null +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-edit-add-map.xhtml @@ -0,0 +1,32 @@ +<?xml version="1.0"?> + +<!DOCTYPE html + PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<html xmlns="http://www.w3.org/1999/xhtml" + xmlns:h="http://java.sun.com/jsf/html" + xmlns:f="http://java.sun.com/jsf/core" + xmlns:ui="http://java.sun.com/jsf/facelets" + xmlns:c="http://java.sun.com/jstl/core" + xmlns:onc="http://jboss.org/on/component%22%3E + +<ui:composition template="/rhq/admin/plugin/plugin-edit-map.xhtml"> + <ui:param name="actionVerb" value="Add to" /> + <ui:param name="editBreadCrumb" value="true" /> + + <ui:define name="mapConfig"> + <onc:config configurationDefinition="#{editPluginConfigurationUIBean.scheduledJobsDefinition}" + configuration="#{editPluginConfigurationUIBean.plugin.scheduledJobsConfiguration}" + listName="#{param.listName}" /> + + <h:panelGrid columns="2" styleClass="buttons-table" columnClasses="button-cell"> + <h:commandButton value="OK" type="submit" action="#{editPluginConfigurationUIBean.finishMap}" + alt="Click to Add Map" styleClass="buttonmed"/> + <h:commandButton value="RESET" type="reset" immediate="true" + alt="Click to Reset Fields" styleClass="buttonmed"/> + </h:panelGrid> + </ui:define> +</ui:composition> + +</html> diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-edit-map.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-edit-map.xhtml new file mode 100644 index 0000000..429880e --- /dev/null +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-edit-map.xhtml @@ -0,0 +1,57 @@ +<?xml version="1.0"?> + +<!DOCTYPE html + PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<html xmlns="http://www.w3.org/1999/xhtml" + xmlns:h="http://java.sun.com/jsf/html" + xmlns:f="http://java.sun.com/jsf/core" + xmlns:ui="http://java.sun.com/jsf/facelets" + xmlns:c="http://java.sun.com/jstl/core" + xmlns:onc="http://jboss.org/on/component%22%3E + +<ui:composition template="/rhq/layout/main.xhtml"> + <ui:param name="pageTitle" value="Edit #{editPluginConfigurationUIBean.plugin.displayName} - #{actionVerb} List '#{param.listName}'"/> + + <ui:define name="breadcrumbs"> + <h:outputLink value="/admin/config/Config.do?mode=edit"> + <h:outputText value="Server Settings"/> + </h:outputLink> + > + <h:outputLink value="plugin-config.xhtml?pluginName=#{editPluginConfigurationUIBean.plugin.name}"> + <h:outputText value="Server Plugins Configuration"/> + </h:outputLink> + <c:if test="#{editBreadCrumb}"> + > + <h:outputLink value="plugin-edit.xhtml?plugin=#{editPluginConfigurationUIBean.plugin.name}&pluginType=#{editPluginConfigurationUIBean.plugin.type}&deployment=#{editPluginConfigurationUIBean.plugin.deployment}"> + <h:outputText value="Edit #{editPluginConfigurationUIBean.plugin.displayName} Configuration"/> + </h:outputLink> + </c:if> + > + <h:outputLink value="#"> + <h:outputText value="Edit #{editPluginConfigurationUIBean.plugin.displayName} Configuration - #{actionVerb} List '#{param.listName}'"/> + </h:outputLink> + </ui:define> + + <ui:define name="body"> + + <h:messages showSummary="true" + showDetail="true" + infoClass="InfoBlock" + warnClass="WarnBlock" + errorClass="ErrorBlock" + fatalClass="FatalBlock" + globalOnly="true" + layout="table" + width="100%"/> + + <h:form id="editPluginConfigurationForm" onsubmit="prepareInputsForSubmission(this)"> + <ui:insert name="mapConfig" /> + </h:form> + + </ui:define> + +</ui:composition> + +</html> diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-edit-update-map.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-edit-update-map.xhtml new file mode 100644 index 0000000..cd7611d --- /dev/null +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-edit-update-map.xhtml @@ -0,0 +1,33 @@ +<?xml version="1.0"?> + +<!DOCTYPE html + PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<html xmlns="http://www.w3.org/1999/xhtml" + xmlns:h="http://java.sun.com/jsf/html" + xmlns:f="http://java.sun.com/jsf/core" + xmlns:ui="http://java.sun.com/jsf/facelets" + xmlns:c="http://java.sun.com/jstl/core" + xmlns:onc="http://jboss.org/on/component%22%3E + +<ui:composition template="/rhq/admin/plugin/plugin-edit-map.xhtml"> + <ui:param name="actionVerb" value="Update" /> + <ui:param name="editBreadCrumb" value="true" /> + + <ui:define name="mapConfig"> + <onc:config configurationDefinition="#{editPluginConfigurationUIBean.scheduledJobsDefinition}" + configuration="#{editPluginConfigurationUIBean.plugin.scheduledJobsConfiguration}" + listName="#{param.listName}" + listIndex="#{param.listIndex}" /> + + <h:panelGrid columns="2" styleClass="buttons-table" columnClasses="button-cell"> + <h:commandButton value="OK" type="submit" action="#{editPluginConfigurationUIBean.finishMap}" + alt="Click to Update Map" styleClass="buttonmed"/> + <h:commandButton value="RESET" type="reset" immediate="true" + alt="Click to Reset Fields" styleClass="buttonmed"/> + </h:panelGrid> + </ui:define> +</ui:composition> + +</html> diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-edit-view-map.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-edit-view-map.xhtml new file mode 100644 index 0000000..ae64beb --- /dev/null +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-edit-view-map.xhtml @@ -0,0 +1,26 @@ +<?xml version="1.0"?> + +<!DOCTYPE html + PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<html xmlns="http://www.w3.org/1999/xhtml" + xmlns:h="http://java.sun.com/jsf/html" + xmlns:f="http://java.sun.com/jsf/core" + xmlns:ui="http://java.sun.com/jsf/facelets" + xmlns:c="http://java.sun.com/jstl/core" + xmlns:onc="http://jboss.org/on/component%22%3E + +<ui:composition template="/rhq/admin/plugin/plugin-edit-map.xhtml"> + <ui:param name="actionVerb" value="View" /> + + <ui:define name="mapConfig"> + <onc:config configurationDefinition="#{editPluginConfigurationUIBean.scheduledJobsDefinition}" + configuration="#{editPluginConfigurationUIBean.plugin.scheduledJobsConfiguration}" + listName="#{param.listName}" + listIndex="#{param.listIndex}" + readOnly="true" /> + </ui:define> +</ui:composition> + +</html> diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-edit.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-edit.xhtml index 38e8c60..3269451 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-edit.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-edit.xhtml @@ -20,7 +20,7 @@ <h:outputText value="Server Plugins Configuration"/> </h:outputLink> > - <h:outputLink value="plugin-edit.xhtml?pluginName"> + <h:outputLink value="plugin-edit.xhtml?plugin=#{editPluginConfigurationUIBean.plugin.name}&pluginType=#{editPluginConfigurationUIBean.plugin.type}&deployment=#{editPluginConfigurationUIBean.plugin.deployment}"> <h:outputText value="Edit #{editPluginConfigurationUIBean.plugin.displayName} Configuration"/> </h:outputLink> </ui:define>
commit fb73e1f38922afd8263d20669c93ff6bb82e069b Author: John Sanda john@localhost.localdomain Date: Thu Dec 3 15:56:16 2009 -0500
Changing name of new udpate method to updateStructuredOrRawConfiguration.
This helps avoid the method overloading problem with SOAP and is consistent with the practice of not overloading EJB methods that are exposed in remote APIs.
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ExistingResourceConfigurationUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ExistingResourceConfigurationUIBean.java index 37dbf2e..bb93d81 100644 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ExistingResourceConfigurationUIBean.java +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ExistingResourceConfigurationUIBean.java @@ -94,8 +94,9 @@ public class ExistingResourceConfigurationUIBean extends AbstractConfigurationUI ConfigurationMaskingUtility.unmaskConfiguration(getConfiguration(), getConfigurationDefinition()); int resourceId = EnterpriseFacesContextUtility.getResource().getId();
- AbstractResourceConfigurationUpdate updateRequest = this.configurationManager.updateResourceConfiguration( - EnterpriseFacesContextUtility.getSubject(), resourceId, getMergedConfiguration(), fromStructured); + AbstractResourceConfigurationUpdate updateRequest = + this.configurationManager.updateStructuredOrRawConfiguration(EnterpriseFacesContextUtility.getSubject(), + resourceId, getMergedConfiguration(), fromStructured); if (updateRequest != null) { switch (updateRequest.getStatus()) { case SUCCESS: diff --git a/modules/enterprise/remoting/scripts/src/test/script/org/rhq/enterprise/remoting/cli/test_ConfigurationManager.js b/modules/enterprise/remoting/scripts/src/test/script/org/rhq/enterprise/remoting/cli/test_ConfigurationManager.js index 2581e38..3c797b5 100644 --- a/modules/enterprise/remoting/scripts/src/test/script/org/rhq/enterprise/remoting/cli/test_ConfigurationManager.js +++ b/modules/enterprise/remoting/scripts/src/test/script/org/rhq/enterprise/remoting/cli/test_ConfigurationManager.js @@ -67,7 +67,7 @@ function testGetAndUpdateRawConfiguration() {
rawConfig.contents = modifiedContents.getBytes();
- var configUdpate = ConfigurationManager.updateResourceConfiguration(rawServer.id, latestUpdate.configuration); + var configUdpate = ConfigurationManager.updateStructuredOrRawConfiguration(rawServer.id, latestUpdate.configuration);
waitForResourceConfigUpdateToComplete(rawServer.id);
@@ -93,7 +93,7 @@ function testGetAndUpdateStructuredConfiguration() {
modifiedConfig.put(PropertySimple("foo", java.util.Date()));
- var configUdpate = ConfigurationManager.updateResourceConfiguration(structuredServer.id, modifiedConfig); + var configUdpate = ConfigurationManager.updateStructuredOrRawConfiguration(structuredServer.id, modifiedConfig);
waitForResourceConfigUpdateToComplete(structuredServer.id);
@@ -119,7 +119,7 @@ function testGetAndUpdateStructuredandRawConfigurationOnRawEdit() {
rawConfig.contents = modifiedContents.bytes;
- var configUpdate = ConfigurationManager.updateResourceConfiguration(structuredAndRawServer.id, + var configUpdate = ConfigurationManager.updateStructuredOrRawConfiguration(structuredAndRawServer.id, latestUpdate.configuration, false);
waitForResourceConfigUpdateToComplete(structuredAndRawServer.id); @@ -146,7 +146,7 @@ function testGetAndUpdateStrucuturedOnStructuredEdit() {
modifiedConfig.put(PropertySimple("x", java.util.Date()));
- ConfigurationManager.updateResourceConfiguration(structuredAndRawServer.id, modifiedConfig, true); + ConfigurationManager.updateStructuredOrRawConfiguration(structuredAndRawServer.id, modifiedConfig, true);
waitForResourceConfigUpdateToComplete(structuredAndRawServer.id);
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java index 81fada8..e900d24 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java @@ -981,13 +981,7 @@ public class ConfigurationManagerBean implements ConfigurationManagerLocal, Conf return; }
- private void dumpProperties(Configuration configuration) { - for (String key : configuration.getAllProperties().keySet()) { - log.error("key = "); - } - } - - public ResourceConfigurationUpdate updateResourceConfiguration(Subject subject, int resourceId, + public ResourceConfigurationUpdate updateStructuredOrRawConfiguration(Subject subject, int resourceId, Configuration newConfiguration, boolean fromStructured) throws ResourceNotFoundException, ConfigurationUpdateStillInProgressException {
@@ -1022,7 +1016,6 @@ public class ConfigurationManagerBean implements ConfigurationManagerLocal, Conf // (consider synchronizing to avoid the condition where someone calls this method twice quickly // in two different txs which would put two updates in INPROGRESS and cause havoc) ResourceConfigurationUpdate newUpdate; - dumpProperties(newConfiguration); // here we call ourself, but we do so via the EJB interface so we pick up the REQUIRES_NEW semantics // this can return null if newConfiguration is not actually different. newUpdate = configurationManager.persistNewResourceConfigurationUpdateHistory(subject, resourceId, diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerLocal.java index 5ec3e95..69c5e96 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerLocal.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerLocal.java @@ -471,7 +471,7 @@ public interface ConfigurationManagerLocal { ResourceConfigurationUpdate updateResourceConfiguration(Subject subject, int resourceId, Configuration newConfiguration) throws ResourceNotFoundException, ConfigurationUpdateStillInProgressException;
- ResourceConfigurationUpdate updateResourceConfiguration(Subject subject, int resourceId, + ResourceConfigurationUpdate updateStructuredOrRawConfiguration(Subject subject, int resourceId, Configuration newConfiguration, boolean fromStructured) throws ResourceNotFoundException, ConfigurationUpdateStillInProgressException;
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerRemote.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerRemote.java index d7f64a6..40b401e 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerRemote.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerRemote.java @@ -180,8 +180,8 @@ public interface ConfigurationManagerRemote { @XmlJavaTypeAdapter(ConfigurationAdapter.class) Configuration newConfiguration) throws ResourceNotFoundException, ConfigurationUpdateStillInProgressException;
- @WebMethod(operationName = "updateStructuredOrRawResourceConfiguration") - ResourceConfigurationUpdate updateResourceConfiguration( + @WebMethod + ResourceConfigurationUpdate updateStructuredOrRawConfiguration( @WebParam Subject subject, @WebParam int resourceId, @WebParam diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/webservices/WebservicesManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/webservices/WebservicesManagerBean.java index 601644d..8916b19 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/webservices/WebservicesManagerBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/webservices/WebservicesManagerBean.java @@ -370,10 +370,11 @@ public class WebservicesManagerBean implements WebservicesRemote { return configurationManager.updateResourceConfiguration(subject, resourceId, newConfiguration); }
- public ResourceConfigurationUpdate updateResourceConfiguration(Subject subject, int resourceId, + public ResourceConfigurationUpdate updateStructuredOrRawConfiguration(Subject subject, int resourceId, Configuration newConfiguration, boolean fromStructured) throws ResourceNotFoundException, ConfigurationUpdateStillInProgressException { - return configurationManager.updateResourceConfiguration(subject, resourceId, newConfiguration, fromStructured); + return configurationManager.updateStructuredOrRawConfiguration(subject, resourceId, newConfiguration, + fromStructured); }
public ConfigurationDefinition getPackageTypeConfigurationDefinition(Subject subject, int packageTypeId) { diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBeanUnitTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBeanUnitTest.java index 5091edb..7958411 100644 --- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBeanUnitTest.java +++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBeanUnitTest.java @@ -193,7 +193,7 @@ public class ConfigurationManagerBeanUnitTest extends JMockTest { inSequence(configUdpate); }});
- ResourceConfigurationUpdate actualUpdate = configurationMgr.updateResourceConfiguration(subject, resourceId, + ResourceConfigurationUpdate actualUpdate = configurationMgr.updateStructuredOrRawConfiguration(subject, resourceId, newConfig, FROM_STRUCTURED);
assertSame(actualUpdate, expectedUpdate, "Expected to get back the persisted configuration update"); @@ -238,7 +238,7 @@ public class ConfigurationManagerBeanUnitTest extends JMockTest { inSequence(configUdpate); }});
- ResourceConfigurationUpdate actualUpdate = configurationMgr.updateResourceConfiguration(subject, resourceId, + ResourceConfigurationUpdate actualUpdate = configurationMgr.updateStructuredOrRawConfiguration(subject, resourceId, newConfig, FROM_STRUCTURED);
assertSame(actualUpdate, expectedUpdate, "Expected to get back the persisted configuration update"); @@ -292,7 +292,7 @@ public class ConfigurationManagerBeanUnitTest extends JMockTest { inSequence(configUdpate); }});
- ResourceConfigurationUpdate actualUpdate = configurationMgr.updateResourceConfiguration(subject, resourceId, + ResourceConfigurationUpdate actualUpdate = configurationMgr.updateStructuredOrRawConfiguration(subject, resourceId, newConfig, FROM_RAW);
assertSame(actualUpdate, expectedUpdate, "Expected to get back the persisted configuration update");
commit a28a1ae60d13c6335a5dd4d6b78395fb673f8b60 Author: John Sanda john@localhost.localdomain Date: Thu Dec 3 14:52:58 2009 -0500
Fixing test so that it retrieves the "live" config after applying the update instead of just retrieving it from the database. This way, we verify that the update has been applied on the reosurce.
diff --git a/modules/enterprise/remoting/scripts/src/test/script/org/rhq/enterprise/remoting/cli/test_ConfigurationManager.js b/modules/enterprise/remoting/scripts/src/test/script/org/rhq/enterprise/remoting/cli/test_ConfigurationManager.js index 5cd8c26..2581e38 100644 --- a/modules/enterprise/remoting/scripts/src/test/script/org/rhq/enterprise/remoting/cli/test_ConfigurationManager.js +++ b/modules/enterprise/remoting/scripts/src/test/script/org/rhq/enterprise/remoting/cli/test_ConfigurationManager.js @@ -48,7 +48,8 @@ function testUpdateResourceConfiguration() { java.lang.Thread.sleep(1000); }
- config = ConfigurationManager.getResourceConfiguration(resource.id); + var latestUpdate = ConfigurationManager.getLatestResourceConfigurationUpdate(resource.id); + var config = latestUpdate.configuration; var updatedProperty = config.getSimple(propertyName);
Assert.assertEquals(updatedProperty.stringValue, propertyValue, 'Failed to update resource configuration');
commit dd2b2259228c3b3e72f8c196d1f71d72f8d98641 Author: John Sanda john@localhost.localdomain Date: Thu Dec 3 14:49:08 2009 -0500
[US 6] Fixing logic of legacy update config
Update wasn't actually getting applied and exceptions now need to be thrown to indicate that the update was not successful.
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LegacyConfigManagement.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LegacyConfigManagement.java index 9d9bbbd..9630eb9 100644 --- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LegacyConfigManagement.java +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LegacyConfigManagement.java @@ -29,6 +29,7 @@ import org.rhq.core.pc.util.FacetLockType; import org.rhq.core.clientapi.agent.PluginContainerException; import org.rhq.core.clientapi.agent.configuration.ConfigurationUtility; import org.rhq.core.domain.configuration.Configuration; +import org.rhq.core.domain.configuration.ConfigurationUpdateStatus; import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; import org.rhq.core.domain.resource.ResourceType; import org.rhq.core.pluginapi.configuration.ConfigurationFacet; @@ -79,6 +80,20 @@ public class LegacyConfigManagement extends ConfigManagementSupport { throws PluginContainerException { ConfigurationFacet facet = loadConfigurationFacet(resourceId, WRITE); ConfigurationUpdateReport report = new ConfigurationUpdateReport(configuration); + + facet.updateResourceConfiguration(report); + + if (ConfigurationUpdateStatus.SUCCESS == report.getStatus()) { + return; + } + + if (ConfigurationUpdateStatus.INPROGRESS == report.getStatus()) { + throw new UpdateInProgressException(); + } + + if (ConfigurationUpdateStatus.FAILURE == report.getStatus()) { + throw new ConfigurationUpdateException(report.getErrorMessage()); + } }
}
commit afeeb911466d140366eceb1323dd46eb4842f3f3 Merge: 677fcf0... f8f2d0d... Author: Adam Young ayoung@redhat.com Date: Thu Dec 3 14:32:28 2009 -0500
Merge branch 'raw-config' of ssh://git.fedorahosted.org/git/rhq/rhq into raw-config
commit f8f2d0d22621901aa3423d90326c36688e58c5e1 Author: John Sanda jsanda@redhat.com Date: Thu Dec 3 13:38:50 2009 -0500
Fixing broken build...again. Updating test method to call correct version of generated API.
diff --git a/modules/enterprise/remoting/webservices/src/test/java/org/rhq/enterprise/server/ws/WsConfigurationManagerTest.java b/modules/enterprise/remoting/webservices/src/test/java/org/rhq/enterprise/server/ws/WsConfigurationManagerTest.java index 9423ed3..7c80417 100644 --- a/modules/enterprise/remoting/webservices/src/test/java/org/rhq/enterprise/server/ws/WsConfigurationManagerTest.java +++ b/modules/enterprise/remoting/webservices/src/test/java/org/rhq/enterprise/server/ws/WsConfigurationManagerTest.java @@ -189,7 +189,7 @@ public class WsConfigurationManagerTest extends AssertJUnit implements TestPrope config.getPropertySimpleContainer().add(property);
ResourceConfigurationUpdate configUpdate = WEBSERVICE_REMOTE.updateResourceConfiguration(subject, resource.id, - config, true); + config);
while (WEBSERVICE_REMOTE.isResourceConfigurationUpdateInProgress(subject, resource.id)) { java.lang.Thread.sleep(1000);
commit 677fcf061369a59cbc039ceff9e80c860c29a6c7 Merge: fc861ac... 8aa3c65... Author: Adam Young ayoung@redhat.com Date: Thu Dec 3 13:00:26 2009 -0500
Merge branch 'raw-config' of ssh://git.fedorahosted.org/git/rhq/rhq into raw-config
commit fc861ac962877b62eaf27f976bcb36f649583036 Author: Adam Young ayoung@redhat.com Date: Thu Dec 3 12:59:38 2009 -0500
Removed extra translation.
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ExistingResourceConfigurationUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ExistingResourceConfigurationUIBean.java index 4467e2a..37dbf2e 100644 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ExistingResourceConfigurationUIBean.java +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ExistingResourceConfigurationUIBean.java @@ -94,12 +94,8 @@ public class ExistingResourceConfigurationUIBean extends AbstractConfigurationUI ConfigurationMaskingUtility.unmaskConfiguration(getConfiguration(), getConfigurationDefinition()); int resourceId = EnterpriseFacesContextUtility.getResource().getId();
- //TODO this is two round trips to the agent. need to blend these into one. - Configuration configuration = LookupUtil.getConfigurationManager().translateResourceConfiguration( - EnterpriseFacesContextUtility.getSubject(), getResourceId(), getMergedConfiguration(), false); - AbstractResourceConfigurationUpdate updateRequest = this.configurationManager.updateResourceConfiguration( - EnterpriseFacesContextUtility.getSubject(), resourceId, configuration, fromStructured); + EnterpriseFacesContextUtility.getSubject(), resourceId, getMergedConfiguration(), fromStructured); if (updateRequest != null) { switch (updateRequest.getStatus()) { case SUCCESS:
commit 321a85793f44e10a507adca43f8e4ffd9d39c206 Author: Ian Springer ian.springer@redhat.com Date: Thu Dec 3 12:49:12 2009 -0500
custom settings.xml file for linux-config Hudson builds
diff --git a/etc/m2/settings-linux-config.xml b/etc/m2/settings-linux-config.xml new file mode 100644 index 0000000..ee22bd1 --- /dev/null +++ b/etc/m2/settings-linux-config.xml @@ -0,0 +1,54 @@ +<?xml version="1.0"?> + +<!--===== Maven 2 user settings file for building the linux-config branch =====--> + +<!-- See: http://maven.apache.org/settings.html --> + +<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 + http://maven.apache.org/xsd/settings-1.0.0.xsd%22%3E + + <!-- + **************************** PROFILES **************************** + --> + + <!-- + See: + http://maven.apache.org/guides/introduction/introduction-to-profiles.html + and: http://docs.codehaus.org/display/MAVENUSER/Profiles + --> + + <activeProfiles> + <activeProfile>test.linux-config</activeProfile> + </activeProfiles> + + <profiles> + <profile> + <!-- Profile to use to point test runs at a different db --> + <id>test.linux-config</id> + <properties> + <rhq.test.ds.connection-url>jdbc:postgresql://127.0.0.1:5432/rhqlconf</rhq.test.ds.connection-url> + <DatabaseTest.nofail>true</DatabaseTest.nofail> + + <!-- comm and agent config properties --> + <rhq.comm.test.connectorBindPort>11112</rhq.comm.test.connectorBindPort> + <rhq.comm.test.connector2BindPort>22223</rhq.comm.test.connector2BindPort> + <agent1.cfg.file>test-agent1-cfg-mvn.xml</agent1.cfg.file> + <agent2.cfg.file>test-agent2-cfg-mvn.xml</agent2.cfg.file> + <agent1.server.bind-port>55556</agent1.server.bind-port> + <agent2.server.bind-port>66667</agent2.server.bind-port> + <agent1.communications.connector.bind-port>33334</agent1.communications.connector.bind-port> + <agent2.communications.connector.bind-port>44445</agent2.communications.connector.bind-port> + </properties> + </profile> + </profiles> + + <pluginGroups> + <!-- + This will allow you to invoke "org.rhq" Maven goals using the + "rhq" prefix + --> + <pluginGroup>org.rhq</pluginGroup> + </pluginGroups> +</settings>
commit 0eef94a3263adaa36e0296239301b9fe174c3f2d Merge: 0b9c7a8... d618ccb... Author: John Mazzitelli mazz@redhat.com Date: Thu Dec 3 11:07:29 2009 -0500
Merge branch 'master' into pc
commit 1118be54e0fb3e2d43df1e24360dc82b99518fbd Merge: 2da740f... 28260b6... Author: Adam Young ayoung@redhat.com Date: Thu Dec 3 10:52:35 2009 -0500
Merge branch 'raw-config' of ssh://git.fedorahosted.org/git/rhq/rhq into raw-config
commit 2da740f0820b6f1ba5d98886feb79907332074f6 Author: Adam Young ayoung@redhat.com Date: Thu Dec 3 10:48:48 2009 -0500
Reduced the two round trips to one for updating configs.
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ExistingResourceConfigurationUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ExistingResourceConfigurationUIBean.java index e5fffd2..4467e2a 100644 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ExistingResourceConfigurationUIBean.java +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ExistingResourceConfigurationUIBean.java @@ -81,6 +81,16 @@ public class ExistingResourceConfigurationUIBean extends AbstractConfigurationUI }
public String updateConfiguration() { + return updateConfiguration(true); + + } + + public String updateRawConfiguration() { + return updateConfiguration(false); + } + + public String updateConfiguration(boolean fromStructured) { + ConfigurationMaskingUtility.unmaskConfiguration(getConfiguration(), getConfigurationDefinition()); int resourceId = EnterpriseFacesContextUtility.getResource().getId();
@@ -89,7 +99,7 @@ public class ExistingResourceConfigurationUIBean extends AbstractConfigurationUI EnterpriseFacesContextUtility.getSubject(), getResourceId(), getMergedConfiguration(), false);
AbstractResourceConfigurationUpdate updateRequest = this.configurationManager.updateResourceConfiguration( - EnterpriseFacesContextUtility.getSubject(), resourceId, configuration); + EnterpriseFacesContextUtility.getSubject(), resourceId, configuration, fromStructured); if (updateRequest != null) { switch (updateRequest.getStatus()) { case SUCCESS: diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-navigation/configuration-navigation.xml b/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-navigation/configuration-navigation.xml index 86af6c3..4443b36 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-navigation/configuration-navigation.xml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-navigation/configuration-navigation.xml @@ -39,7 +39,7 @@ <from-view-id>/rhq/resource/configuration/edit-raw.xhtml</from-view-id>
<navigation-case> - <from-action>#{ExistingResourceConfigurationUIBean.updateConfiguration}</from-action> + <from-action>#{ExistingResourceConfigurationUIBean.updateRawConfiguration}</from-action> <from-outcome>success</from-outcome> <to-view-id>/rhq/resource/configuration/history.xhtml?id=#{param.id}</to-view-id> <redirect/> diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit-raw.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit-raw.xhtml index 0775e16..c01694e 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit-raw.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit-raw.xhtml @@ -67,7 +67,7 @@ <div>* <h:outputText value="#{messages.uncommitted}" /></div> <h:panelGrid columns="2" styleClass="buttons-table" columnClasses="button-cell"> - <h:commandButton value="SAVE" action="#{ExistingResourceConfigurationUIBean.updateConfiguration}" + <h:commandButton value="SAVE" action="#{ExistingResourceConfigurationUIBean.updateRawConfiguration}" title="Click to Save Changes" styleClass="buttonmed" rendered="${ResourceUIBean.permissions.configure}" />
commit 8aa3c657ae4a19a199d1c8d4e35fc72251fbd2ea Merge: 2d9441e... 28260b6... Author: John Sanda john@localhost.localdomain Date: Thu Dec 3 10:45:44 2009 -0500
Merge branch 'raw-config' of ssh://git.fedorahosted.org/git/rhq/rhq into raw-config
commit 2d9441ecaf7eb2a7d18d1fa84c3e1ba9f4c2f125 Author: John Sanda john@localhost.localdomain Date: Thu Dec 3 10:42:22 2009 -0500
Fixing build failures in webservices module
We were getting compiler errors in some of the test classes in the webservices module after I added the new configuration update operation to ConfigurationManagerRemote. It caused a problem because the method is overloaded and SOAP does not support method overloading. I resolved the issue by overriding the default value of the generated SOAP operation name to be updateStructuredOrRawResourceConfiguration().
diff --git a/modules/enterprise/remoting/pom.xml b/modules/enterprise/remoting/pom.xml index 63ff0ef..9fc448a 100644 --- a/modules/enterprise/remoting/pom.xml +++ b/modules/enterprise/remoting/pom.xml @@ -15,7 +15,7 @@ <description>RHQ Enterprise Remoting Parent POM</description>
<modules> - <!--<module>webservices</module>--> + <module>webservices</module> </modules>
<profiles> @@ -27,7 +27,7 @@ </activation>
<modules> - <!--<module>webservices</module>--> + <module>webservices</module> <module>cli</module> <!-- Temporarily commenting out scripts module from build. The scripts tests require a running server and diff --git a/modules/enterprise/remoting/webservices/src/test/java/org/rhq/enterprise/server/ws/WsConfigurationManagerTest.java b/modules/enterprise/remoting/webservices/src/test/java/org/rhq/enterprise/server/ws/WsConfigurationManagerTest.java index 7c80417..9423ed3 100644 --- a/modules/enterprise/remoting/webservices/src/test/java/org/rhq/enterprise/server/ws/WsConfigurationManagerTest.java +++ b/modules/enterprise/remoting/webservices/src/test/java/org/rhq/enterprise/server/ws/WsConfigurationManagerTest.java @@ -189,7 +189,7 @@ public class WsConfigurationManagerTest extends AssertJUnit implements TestPrope config.getPropertySimpleContainer().add(property);
ResourceConfigurationUpdate configUpdate = WEBSERVICE_REMOTE.updateResourceConfiguration(subject, resource.id, - config); + config, true);
while (WEBSERVICE_REMOTE.isResourceConfigurationUpdateInProgress(subject, resource.id)) { java.lang.Thread.sleep(1000); diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerRemote.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerRemote.java index 4fcac24..d7f64a6 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerRemote.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerRemote.java @@ -180,8 +180,13 @@ public interface ConfigurationManagerRemote { @XmlJavaTypeAdapter(ConfigurationAdapter.class) Configuration newConfiguration) throws ResourceNotFoundException, ConfigurationUpdateStillInProgressException;
- ResourceConfigurationUpdate updateResourceConfiguration(Subject subject, int resourceId, - Configuration newConfiguration, boolean fromStructured) + @WebMethod(operationName = "updateStructuredOrRawResourceConfiguration") + ResourceConfigurationUpdate updateResourceConfiguration( + @WebParam Subject subject, + @WebParam int resourceId, + @WebParam + @XmlJavaTypeAdapter(ConfigurationAdapter.class) Configuration newConfiguration, + @WebParam boolean fromStructured) throws ResourceNotFoundException, ConfigurationUpdateStillInProgressException;
/**
commit 28260b63c7f2b078df30059896d42d3035fcd23a Author: John Sanda jsanda@redhat.com Date: Thu Dec 3 09:54:21 2009 -0500
Adding raw-config-test plugin to aggregrate build
diff --git a/modules/plugins/pom.xml b/modules/plugins/pom.xml index 31c5bb9..f102dcf 100644 --- a/modules/plugins/pom.xml +++ b/modules/plugins/pom.xml @@ -123,6 +123,9 @@ <module>twitter</module> <!--<module>virt</module>-->
+ <!-- this is just for testing raw config --> + <module>raw-config-test</module> + <!-- make this the last - it will validate all the plugins --> <module>validate-all-plugins</module> </modules>
commit 7801d9f35bb10ce188a8299df44d5906f8b10dfa Merge: feeef73... 05e637c... Author: John Sanda jsanda@redhat.com Date: Thu Dec 3 09:05:19 2009 -0500
Merge branch 'master' into raw-config
diff --cc modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-details.xhtml index 6867608,5bb4b2a..d3901bd --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-details.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-details.xhtml @@@ -45,28 -45,32 +45,35 @@@ <h:panelGrid styleClass="BlockContent" columns="4" width="100%">
<h:outputLabel styleClass="BlockLabel" value="Version:"/> - <h:outputText styleClass="BlockContent" value="#{InstalledPluginUIBean.plugin.version}"/> + <h:outputText styleClass="BlockContent" value="#{plugin.version}"/>
+ <h:outputLabel styleClass="BlockLabel" value="AMPS Version:"/> + <h:outputText styleClass="BlockContent" value="#{InstalledPluginUIBean.plugin.ampsVersion}"/> + <h:outputLabel styleClass="BlockLabel" value="Enabled:"/> - <h:outputText value="#{InstalledPluginUIBean.plugin.enabled}"/> + <h:outputText value="#{plugin.enabled}"/>
<h:outputLabel styleClass="BlockLabel" value="Type:"/> - <h:outputText value="#{InstalledPluginUIBean.plugin.deployment}"/> + <h:outputText value="#{plugin.deployment}"/>
<h:outputLabel styleClass="BlockLabel" value="MD5:"/> - <h:outputText value="#{InstalledPluginUIBean.plugin.md5}"/> + <h:outputText value="#{plugin.md5}"/>
<h:outputLabel styleClass="BlockLabel" value="Description:"/> - <h:outputText value="#{InstalledPluginUIBean.plugin.description}"/> + <h:outputText value="#{plugin.description}"/>
<h:outputLabel styleClass="BlockLabel" value="Path:"/> - <h:outputText value="#{InstalledPluginUIBean.plugin.path}"/> - + <h:outputText value="#{plugin.path}"/> </h:panelGrid>
+ <br /> + <h:outputLink value="/rhq/admin/plugin/plugin-config.xhtml" rendered="#{plugin.deployment eq 'SERVER'}"> + <f:param name="pluginName" value="#{plugin.name}"/> + <h:outputText value="Configure '#{plugin.displayName}'"/> + </h:outputLink> + <br /> + <br /> + rich:panel <f:facet name="header"> <h:outputText value="Plugin Help"/>
commit e684c4b09516066c85b5b8787a27e41d1a39b874 Merge: 8d962f6... 05e637c... Author: Heiko W. Rupp pilhuhn@fedorapeople.org Date: Thu Dec 3 10:55:54 2009 +0100
Merge remote branch 'master/master' into alertPlugin
commit feeef733963b7a92237611ceb946555294b75858 Merge: e56a3b5... 4b5f092... Author: John Sanda john@localhost.localdomain Date: Wed Dec 2 21:14:56 2009 -0500
Merge branch 'raw-config' of ssh://git.fedorahosted.org/git/rhq/rhq into raw-config
commit e56a3b5a850454c7aec97f3703da87f0385db994 Author: John Sanda john@localhost.localdomain Date: Wed Dec 2 21:09:20 2009 -0500
[US 910, 914] Exposing the configuration translation operation to the remote APIs
Adding a CLI script to test the resource configuration translation. Temporarily commenting out the webservices module in the build because for reasons of which I am not aware it is failing with compilation errors in several of its test classes.
diff --git a/modules/enterprise/remoting/pom.xml b/modules/enterprise/remoting/pom.xml index 9fc448a..63ff0ef 100644 --- a/modules/enterprise/remoting/pom.xml +++ b/modules/enterprise/remoting/pom.xml @@ -15,7 +15,7 @@ <description>RHQ Enterprise Remoting Parent POM</description>
<modules> - <module>webservices</module> + <!--<module>webservices</module>--> </modules>
<profiles> @@ -27,7 +27,7 @@ </activation>
<modules> - <module>webservices</module> + <!--<module>webservices</module>--> <module>cli</module> <!-- Temporarily commenting out scripts module from build. The scripts tests require a running server and diff --git a/modules/enterprise/remoting/scripts/src/test/script/org/rhq/enterprise/remoting/cli/test_ConfigurationManager.js b/modules/enterprise/remoting/scripts/src/test/script/org/rhq/enterprise/remoting/cli/test_ConfigurationManager.js index df8e8f7..5cd8c26 100644 --- a/modules/enterprise/remoting/scripts/src/test/script/org/rhq/enterprise/remoting/cli/test_ConfigurationManager.js +++ b/modules/enterprise/remoting/scripts/src/test/script/org/rhq/enterprise/remoting/cli/test_ConfigurationManager.js @@ -25,7 +25,8 @@ rhq.login('rhqadmin', 'rhqadmin');
skippedTests.push('testUpdateResourceGroupConfiguration');
-executeAllTests(); +//executeAllTests(); +executeTests(['testTranslateConfigFromStructuredToRaw'])
rhq.logout();
@@ -157,6 +158,46 @@ function testGetAndUpdateStrucuturedOnStructuredEdit() { ); }
+function testTranslateConfigFromStructuredToRaw() { + var resourceName = 'Structured and Raw Server'; + var server = findResourceByNameAndParentName(resourceName, 'localhost'); + + var latestUpdate = loadLatestStructuredAndRawConfigUpdate(resourceName, server.id); + var latestConfig = latestUpdate.configuration; + + var newValue = "merged - " + java.util.Date().toString(); + latestConfig.put(PropertySimple("y", newValue)); + + var mergedConfig = ConfigurationManager.translateResourceConfiguration(server.id, latestConfig, true); + + Assert.assertNotNull(mergedConfig, "Expected to get back a configuration object after translation"); + + var rawConfigs = java.util.ArrayList(mergedConfig.rawConfigurations); + + Assert.assertNumberEqualsJS(rawConfigs.size(), 3, "Expected there to be 3 raw config files"); + + var rawConfig = null; + for (i = 0; i < rawConfigs.size(); i++) { + if (rawConfigs.get(i).path.endsWith('structured-and-raw-test-1.txt')) { + rawConfig = rawConfigs.get(i); + break; + } + } + + Assert.assertNotNull(rawConfig, "Failed to find modified raw config"); + + var contents = java.lang.String(rawConfig.contents); + + Assert.assertTrue(contents.contains(newValue), "Failed to modifiy raw config"); + + var properties = java.util.ArrayList(mergedConfig.properties); + for (i = 0; i < properties.size(); i++) { + var property = properties.get(i); + Assert.assertNotNull(property.configuration); + Assert.assertNumberEqualsJS(property.configuration.id, latestConfig.id, "Property references the wrong configuration"); + } +} + function loadLatestRawConfigUpdate(resourceName, resourceId) { var latestUpdate = ConfigurationManager.getLatestResourceConfigurationUpdate(resourceId);
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerRemote.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerRemote.java index 85ad927..4fcac24 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerRemote.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerRemote.java @@ -261,4 +261,7 @@ public interface ConfigurationManagerRemote { @WebParam(name = "subject") Subject subject, // @WebParam(name = "packageTypeId") int packageTypeId);
+ Configuration translateResourceConfiguration(Subject subject, int resourceId, Configuration configuration, + boolean fromStructured) throws ResourceNotFoundException; + } \ No newline at end of file diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/webservices/WebservicesManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/webservices/WebservicesManagerBean.java index e8af8f9..601644d 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/webservices/WebservicesManagerBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/webservices/WebservicesManagerBean.java @@ -380,6 +380,11 @@ public class WebservicesManagerBean implements WebservicesRemote { return configurationManager.getPackageTypeConfigurationDefinition(subject, packageTypeId); }
+ public Configuration translateResourceConfiguration(Subject subject, int resourceId, Configuration configuration, + boolean fromStructured) throws ResourceNotFoundException { + return configurationManager.translateResourceConfiguration(subject, resourceId, configuration, fromStructured); + } + //CONFIGURATIONMANAGER: END ----------------------------------
//CONTENTMANAGER: BEGIN ----------------------------------
commit 4b5f09264765e21405cfe6dfb8944f867ec18250 Author: Adam Young ayoung@redhat.com Date: Wed Dec 2 19:47:24 2009 -0500
Fixed download for raw config
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ExistingResourceConfigurationUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ExistingResourceConfigurationUIBean.java index ef7d7df..e5fffd2 100644 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ExistingResourceConfigurationUIBean.java +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ExistingResourceConfigurationUIBean.java @@ -83,8 +83,13 @@ public class ExistingResourceConfigurationUIBean extends AbstractConfigurationUI public String updateConfiguration() { ConfigurationMaskingUtility.unmaskConfiguration(getConfiguration(), getConfigurationDefinition()); int resourceId = EnterpriseFacesContextUtility.getResource().getId(); + + //TODO this is two round trips to the agent. need to blend these into one. + Configuration configuration = LookupUtil.getConfigurationManager().translateResourceConfiguration( + EnterpriseFacesContextUtility.getSubject(), getResourceId(), getMergedConfiguration(), false); + AbstractResourceConfigurationUpdate updateRequest = this.configurationManager.updateResourceConfiguration( - EnterpriseFacesContextUtility.getSubject(), resourceId, getConfiguration()); + EnterpriseFacesContextUtility.getSubject(), resourceId, configuration); if (updateRequest != null) { switch (updateRequest.getStatus()) { case SUCCESS: diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-navigation/configuration-navigation.xml b/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-navigation/configuration-navigation.xml index 5668f17..86af6c3 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-navigation/configuration-navigation.xml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-navigation/configuration-navigation.xml @@ -37,10 +37,12 @@ <navigation-rule>
<from-view-id>/rhq/resource/configuration/edit-raw.xhtml</from-view-id> - <navigation-case> - <from-action> #{rawConfigCollection.choseRaw}</from-action> - <from-outcome>success</from-outcome> - <to-view-id>/rhq/resource/configuration/edit-raw.xhtml?id=#{param.id}</to-view-id> + + <navigation-case> + <from-action>#{ExistingResourceConfigurationUIBean.updateConfiguration}</from-action> + <from-outcome>success</from-outcome> + <to-view-id>/rhq/resource/configuration/history.xhtml?id=#{param.id}</to-view-id> + <redirect/> </navigation-case>
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/download.jsp b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/download.jsp index 947ef6c..d207584 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/download.jsp +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/download.jsp @@ -1,10 +1,11 @@ -<%@page import="org.rhq.enterprise.gui.configuration.resource.RawConfigCollection"%><% + +<%@page import="org.rhq.enterprise.gui.configuration.resource.ExistingResourceConfigurationUIBean"%><% response.setContentType("text/plain"); - Object o = request.getSession().getValue("RawConfigCollection"); + Object o = request.getSession().getValue("ExistingResourceConfigurationUIBean"); if ( o == null){ response.getWriter().append("Error message goes here."); }else{ - RawConfigCollection rawConfigCollection = (RawConfigCollection)o; - response.setHeader("Content-Disposition", "attachment;filename="+rawConfigCollection.getCurrentPath()); - response.getWriter().append(new String(rawConfigCollection.getCurrentContents())); + ExistingResourceConfigurationUIBean existingResourceConfigurationUIBean = (ExistingResourceConfigurationUIBean)o; + response.setHeader("Content-Disposition", "attachment;filename="+existingResourceConfigurationUIBean.getCurrentPath()); + response.getWriter().append(new String(existingResourceConfigurationUIBean.getCurrentContents())); }%> diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit-raw.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit-raw.xhtml index e1bc0d3..0775e16 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit-raw.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit-raw.xhtml @@ -65,10 +65,13 @@ </h:panelGroup> <div>______________________________________</div> <div>* <h:outputText value="#{messages.uncommitted}" /></div> - <h:panelGrid columns="2" styleClass="buttons-table" columnClasses="button-cell"> - <a4j:commandButton action="#{ExistingResourceConfigurationUIBean.commit}" - value="#{messages.commit}" reRender="changedFiles" styleClass="buttonmed"/> - <a4j:commandButton + <h:panelGrid columns="2" styleClass="buttons-table" columnClasses="button-cell"> + + <h:commandButton value="SAVE" action="#{ExistingResourceConfigurationUIBean.updateConfiguration}" + title="Click to Save Changes" styleClass="buttonmed" + rendered="${ResourceUIBean.permissions.configure}" /> + + <a4j:commandButton action="#{ExistingResourceConfigurationUIBean.discard}" value="#{messages.discard}" reRender="changedFiles" styleClass="buttonmed"/> </h:panelGrid> @@ -89,11 +92,11 @@ <h:outputText value=" #{messages.upload} " /> <f:param name="id" value="#{ResourceUIBean.id}" /> <f:param name="conversationId" value="#{conversation.id}" /> - </h:outputLink> <s:link action="#{ExistingResourceConfigurationUIBean.download}"> + </h:outputLink> <h:outputLink value="download.jsp"> <img src="/images/download.png" /> - <h:outputText value=" #{messages.download} " /> + <h:outputText value=" dammit #{messages.download} " /> <f:param name="id" value="#{ResourceUIBean.id}" /> - </s:link> + </h:outputLink> <div><h:inputTextarea cols="80" rows="40" value="#{ExistingResourceConfigurationUIBean.currentContents}" /></div>
commit 0b9c7a8f4f0772fa63df65ed0a245b3344194e43 Author: John Mazzitelli mazz@redhat.com Date: Wed Dec 2 16:50:01 2009 -0500
finish the new UI that lets you completely purge a server plugin. You are free to re-deploy/re-upload a new plugin to replace it.
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/plugin/ServerPlugin.java b/modules/core/domain/src/main/java/org/rhq/core/domain/plugin/ServerPlugin.java index 976b83b..0243c49 100644 --- a/modules/core/domain/src/main/java/org/rhq/core/domain/plugin/ServerPlugin.java +++ b/modules/core/domain/src/main/java/org/rhq/core/domain/plugin/ServerPlugin.java @@ -84,6 +84,31 @@ import org.rhq.core.domain.configuration.Configuration; + " WHERE p.id IN (:ids) " // + " AND p.status = 'INSTALLED' "), //
+ // gets plugins that are both installed and deleted + // this query does not load the content blob, but loads everything else + @NamedQuery(name = ServerPlugin.QUERY_FIND_ALL_BY_IDS, query = "" // + + " SELECT new org.rhq.core.domain.plugin.ServerPlugin( " // + + " p.id, " // + + " p.name, " // + + " p.path, " // + + " p.displayName, " // + + " p.enabled, " // + + " p.status, " // + + " p.description, " // + + " p.help, " // + + " p.md5, " // + + " p.version, " // + + " p.ampsVersion, " // + + " p.pluginConfiguration, " // + + " p.scheduledJobsConfiguration, " // + + " p.type, " // + + " p.ctime, " // + + " p.mtime) " // + + " FROM ServerPlugin AS p " // + + " LEFT JOIN p.pluginConfiguration " // + + " LEFT JOIN p.scheduledJobsConfiguration " // + + " WHERE p.id IN (:ids) "), // + // this query does not load the content blob, but loads everything else @NamedQuery(name = ServerPlugin.QUERY_FIND_BY_NAME, query = "" // + " SELECT new org.rhq.core.domain.plugin.ServerPlugin( " // @@ -218,6 +243,7 @@ public class ServerPlugin extends AbstractPlugin { public static final String QUERY_GET_STATUS_BY_NAME = "ServerPlugin.queryGetStatusByName"; public static final String QUERY_GET_KEYS_BY_ENABLED = "ServerPlugin.queryGetKeysByEnabled"; public static final String QUERY_FIND_BY_IDS = "ServerPlugin.findByIds"; + public static final String QUERY_FIND_ALL_BY_IDS = "ServerPlugin.findAllByIds"; public static final String QUERY_FIND_BY_NAME = "ServerPlugin.findByName"; public static final String QUERY_FIND_ANY_BY_NAME = "ServerPlugin.findAnyByName"; public static final String QUERY_FIND_ALL = "ServerPlugin.findAll"; diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/InstalledPluginsSessionUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/InstalledPluginsSessionUIBean.java new file mode 100644 index 0000000..ec66bb5 --- /dev/null +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/InstalledPluginsSessionUIBean.java @@ -0,0 +1,42 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2009 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.gui.admin.plugin; + +public class InstalledPluginsSessionUIBean { + private boolean showAllServerPlugins = false; + + public InstalledPluginsSessionUIBean() { + } + + public boolean isShowAllServerPlugins() { + return showAllServerPlugins; + } + + public void setShowAllServerPlugins(boolean showDeletedServerPlugins) { + this.showAllServerPlugins = showDeletedServerPlugins; + } + + public void showUndeployedServerPlugins() { + setShowAllServerPlugins(true); + } + + public void hideUndeployedServerPlugins() { + setShowAllServerPlugins(false); + } +} \ No newline at end of file diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/InstalledPluginsUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/InstalledPluginsUIBean.java index 476dd2f..9ba94c7 100644 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/InstalledPluginsUIBean.java +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/InstalledPluginsUIBean.java @@ -26,6 +26,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; +import java.util.TreeMap;
import javax.faces.application.FacesMessage;
@@ -37,6 +38,7 @@ import org.rhq.core.domain.auth.Subject; import org.rhq.core.domain.authz.Permission; import org.rhq.core.domain.plugin.AbstractPlugin; import org.rhq.core.domain.plugin.Plugin; +import org.rhq.core.domain.plugin.PluginStatusType; import org.rhq.core.domain.plugin.ServerPlugin; import org.rhq.core.gui.util.FacesContextUtility; import org.rhq.core.gui.util.StringUtility; @@ -65,13 +67,24 @@ public class InstalledPluginsUIBean { public Collection<Plugin> getInstalledAgentPlugins() {
hasPermission(); - return resourceMetadataManagerBean.getPlugins(); + List<Plugin> plugins = resourceMetadataManagerBean.getPlugins(); + plugins = sort(plugins); + return plugins; }
public Collection<ServerPlugin> getInstalledServerPlugins() {
hasPermission(); - return serverPluginsBean.getAllServerPlugins(); + List<ServerPlugin> plugins; + + InstalledPluginsSessionUIBean session = FacesContextUtility.getManagedBean(InstalledPluginsSessionUIBean.class); + if (session.isShowAllServerPlugins()) { + plugins = serverPluginsBean.getAllServerPlugins(); + } else { + plugins = serverPluginsBean.getServerPlugins(); + } + plugins = sort(plugins); + return plugins; }
public void scan() { @@ -126,15 +139,26 @@ public class InstalledPluginsUIBean { }
public void enableServerPlugins() { - List<ServerPlugin> selectedPlugins = getSelectedServerPlugins(); + List<ServerPlugin> allSelectedPlugins = getSelectedServerPlugins(); List<String> selectedPluginNames = new ArrayList<String>(); - for (ServerPlugin selectedPlugin : selectedPlugins) { - selectedPluginNames.add(selectedPlugin.getName()); + List<ServerPlugin> pluginsToEnable = new ArrayList<ServerPlugin>(); + + for (ServerPlugin selectedPlugin : allSelectedPlugins) { + if (!selectedPlugin.isEnabled() && selectedPlugin.getStatus() == PluginStatusType.INSTALLED) { + selectedPluginNames.add(selectedPlugin.getName()); + pluginsToEnable.add(selectedPlugin); + } + } + + if (selectedPluginNames.isEmpty()) { + FacesContextUtility.addMessage(FacesMessage.SEVERITY_INFO, + "No disabled plugins were selected. Nothing to enable"); + return; }
try { Subject subject = EnterpriseFacesContextUtility.getSubject(); - serverPluginsBean.enableServerPlugins(subject, getIds(selectedPlugins)); + serverPluginsBean.enableServerPlugins(subject, getIds(pluginsToEnable)); FacesContextUtility .addMessage(FacesMessage.SEVERITY_INFO, "Enabled server plugins: " + selectedPluginNames); } catch (Exception e) { @@ -144,15 +168,26 @@ public class InstalledPluginsUIBean { }
public void disableServerPlugins() { - List<ServerPlugin> selectedPlugins = getSelectedServerPlugins(); + List<ServerPlugin> allSelectedPlugins = getSelectedServerPlugins(); List<String> selectedPluginNames = new ArrayList<String>(); - for (ServerPlugin selectedPlugin : selectedPlugins) { - selectedPluginNames.add(selectedPlugin.getName()); + List<ServerPlugin> pluginsToDisable = new ArrayList<ServerPlugin>(); + + for (ServerPlugin selectedPlugin : allSelectedPlugins) { + if (selectedPlugin.isEnabled()) { + selectedPluginNames.add(selectedPlugin.getName()); + pluginsToDisable.add(selectedPlugin); + } + } + + if (selectedPluginNames.isEmpty()) { + FacesContextUtility.addMessage(FacesMessage.SEVERITY_INFO, + "No enabled plugins were selected. Nothing to disable"); + return; }
try { Subject subject = EnterpriseFacesContextUtility.getSubject(); - serverPluginsBean.disableServerPlugins(subject, getIds(selectedPlugins)); + serverPluginsBean.disableServerPlugins(subject, getIds(pluginsToDisable)); FacesContextUtility.addMessage(FacesMessage.SEVERITY_INFO, "Disabled server plugins: " + selectedPluginNames); } catch (Exception e) { @@ -162,15 +197,25 @@ public class InstalledPluginsUIBean { }
public void undeployServerPlugins() { - List<? extends AbstractPlugin> selectedPlugins = getSelectedServerPlugins(); + List<ServerPlugin> allSelectedPlugins = getSelectedServerPlugins(); List<String> selectedPluginNames = new ArrayList<String>(); - for (AbstractPlugin selectedPlugin : selectedPlugins) { - selectedPluginNames.add(selectedPlugin.getName()); + List<ServerPlugin> pluginsToUndeploy = new ArrayList<ServerPlugin>(); + for (ServerPlugin selectedPlugin : allSelectedPlugins) { + if (selectedPlugin.getStatus() == PluginStatusType.INSTALLED) { + selectedPluginNames.add(selectedPlugin.getName()); + pluginsToUndeploy.add(selectedPlugin); + } + } + + if (selectedPluginNames.isEmpty()) { + FacesContextUtility.addMessage(FacesMessage.SEVERITY_INFO, + "No deployed plugins were selected. Nothing to undeploy"); + return; }
try { Subject subject = EnterpriseFacesContextUtility.getSubject(); - serverPluginsBean.undeployServerPlugins(subject, getIds(selectedPlugins)); + serverPluginsBean.undeployServerPlugins(subject, getIds(pluginsToUndeploy)); FacesContextUtility.addMessage(FacesMessage.SEVERITY_INFO, "Undeployed server plugins: " + selectedPluginNames); } catch (Exception e) { @@ -179,6 +224,29 @@ public class InstalledPluginsUIBean { return; }
+ public void purgeServerPlugins() { + List<ServerPlugin> allSelectedPlugins = getSelectedServerPlugins(); + List<String> selectedPluginNames = new ArrayList<String>(); + + for (ServerPlugin selectedPlugin : allSelectedPlugins) { + selectedPluginNames.add(selectedPlugin.getName()); + } + + if (selectedPluginNames.isEmpty()) { + FacesContextUtility.addMessage(FacesMessage.SEVERITY_INFO, "No plugins were selected. Nothing to purge"); + return; + } + + try { + Subject subject = EnterpriseFacesContextUtility.getSubject(); + serverPluginsBean.purgeServerPlugins(subject, getIds(allSelectedPlugins)); + FacesContextUtility.addMessage(FacesMessage.SEVERITY_INFO, "Purged server plugins: " + selectedPluginNames); + } catch (Exception e) { + processException("Failed to undeploy server plugins", e); + } + return; + } + private List<Integer> getIds(List<? extends AbstractPlugin> plugins) { ArrayList<Integer> ids = new ArrayList<Integer>(plugins.size()); for (AbstractPlugin plugin : plugins) { @@ -190,7 +258,7 @@ public class InstalledPluginsUIBean { private List<ServerPlugin> getSelectedServerPlugins() { Integer[] integerItems = getSelectedPluginIds(); List<Integer> ids = Arrays.asList(integerItems); - List<ServerPlugin> plugins = serverPluginsBean.getServerPluginsById(ids); + List<ServerPlugin> plugins = serverPluginsBean.getAllServerPluginsById(ids); return plugins; }
@@ -218,4 +286,12 @@ public class InstalledPluginsUIBean { log.error(errMsg + ". Cause: " + ThrowableUtil.getAllMessages(e)); FacesContextUtility.addMessage(FacesMessage.SEVERITY_ERROR, errMsg, e); } + + private <T extends AbstractPlugin> List<T> sort(List<T> plugins) { + TreeMap<String, T> map = new TreeMap<String, T>(); + for (T plugin : plugins) { + map.put(plugin.getName(), plugin); + } + return new ArrayList<T>(map.values()); + } } \ No newline at end of file diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-managed-beans/admin-beans.xml b/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-managed-beans/admin-beans.xml index a80402b..ffce946 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-managed-beans/admin-beans.xml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-managed-beans/admin-beans.xml @@ -20,12 +20,19 @@ <managed-bean-class>org.rhq.enterprise.gui.admin.plugin.InstalledPluginsUIBean</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean> + <managed-bean> + <description>Maintains state of the tab views</description> + <display-name>Installed Plugins Session State</display-name> + <managed-bean-name>InstalledPluginsSessionUIBean</managed-bean-name> + <managed-bean-class>org.rhq.enterprise.gui.admin.plugin.InstalledPluginsSessionUIBean</managed-bean-class> + <managed-bean-scope>session</managed-bean-scope> + </managed-bean>
- <managed-bean> - <description>Access to downloads information</description> - <managed-bean-name>DownloadsUIBean</managed-bean-name> - <managed-bean-class>org.rhq.enterprise.gui.admin.DownloadsUIBean</managed-bean-class> - <managed-bean-scope>request</managed-bean-scope> - </managed-bean> + <managed-bean> + <description>Access to downloads information</description> + <managed-bean-name>DownloadsUIBean</managed-bean-name> + <managed-bean-class>org.rhq.enterprise.gui.admin.DownloadsUIBean</managed-bean-class> + <managed-bean-scope>request</managed-bean-scope> + </managed-bean>
</faces-config> \ No newline at end of file diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-list.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-list.xhtml index 0b020b3..24d2bc9 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-list.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-list.xhtml @@ -40,6 +40,9 @@
<h:panelGrid columns="1" width="100%"> rich:tabPanel + + <!-- ========== AGENT PLUGINS TAB ========== --> + <rich:tab label="Agent Plugins">
<rich:dataTable id="agentPluginsDataTable" @@ -75,7 +78,7 @@ <h:outputText styleClass="headerText" value="Name"/> </f:facet>
- <h:outputLink value="/rhq/admin/plugin/plugin-details-view.xhtml"> + <h:outputLink value="/rhq/admin/plugin/plugin-details.xhtml"> <f:param name="plugin" value="#{agentPlugin.name}"/> <f:param name="deployment" value="AGENT"/> <h:outputText value="#{agentPlugin.displayName}"/> @@ -108,7 +111,8 @@ <h:outputText styleClass="headerText" value="Enabled"/> </f:facet>
- <h:outputText value="#{agentPlugin.enabled}"/> + <h:graphicImage value="/images/icons/availability_green_16.png" rendered="#{agentPlugin.enabled}"/> + <h:graphicImage value="/images/icons/availability_red_16.png" rendered="#{!agentPlugin.enabled}"/> </rich:column>
<f:facet name="footer"> @@ -125,13 +129,15 @@
</rich:tab>
+ <!-- ========== SERVER PLUGINS TAB ========== --> + <rich:tab label="Server Plugins">
<rich:dataTable id="serverPluginsDataTable" value="#{InstalledPluginsUIBean.installedServerPlugins}" var="serverPlugin" width="100%" - columnsWidth="3%, 20%, 52%, 15%, 10%" + columnsWidth="#{InstalledPluginsSessionUIBean.showAllServerPlugins ? '3%, 20%, 52%, 15%, 5%, 5%' : '3%, 20%, 52%, 15%, 10%'}" headerClass="tableRowHeader" footerClass="on-pager-footer" onRowMouseOver="this.style.backgroundColor='#E7E7E7'" @@ -194,15 +200,33 @@ <h:outputText styleClass="headerText" value="Enabled"/> </f:facet>
- <h:outputText value="#{serverPlugin.enabled}"/> + <h:graphicImage value="/images/icons/availability_green_16.png" rendered="#{serverPlugin.enabled}"/> + <h:graphicImage value="/images/icons/availability_red_16.png" rendered="#{!serverPlugin.enabled}"/> + </rich:column> + + <rich:column rendered="#{InstalledPluginsSessionUIBean.showAllServerPlugins}"> + <f:facet name="header"> + <h:outputText styleClass="headerText" value="Deployed"/> + </f:facet> + + <h:graphicImage value="/images/icons/availability_green_16.png" rendered="#{serverPlugin.status eq 'INSTALLED' }"/> + <h:graphicImage value="/images/icons/availability_red_16.png" rendered="#{serverPlugin.status ne 'INSTALLED' }"/> </rich:column>
<f:facet name="footer"> rich:columnGroup - <rich:column colspan="5" width="100%"> + <rich:column colspan="#{InstalledPluginsSessionUIBean.showAllServerPlugins ? 6 : 5}" width="100%"> <h:commandButton action="#{InstalledPluginsUIBean.scan}" value="SCAN FOR UPDATES" styleClass="on-pager-button buttonsmall"> </h:commandButton> + <h:commandButton action="#{InstalledPluginsSessionUIBean.showUndeployedServerPlugins}" + rendered="#{!InstalledPluginsSessionUIBean.showAllServerPlugins}" + value="SHOW UNDEPLOYED" styleClass="on-pager-button buttonsmall"> + </h:commandButton> + <h:commandButton action="#{InstalledPluginsSessionUIBean.hideUndeployedServerPlugins}" + rendered="#{InstalledPluginsSessionUIBean.showAllServerPlugins}" + value="HIDE UNDEPLOYED" styleClass="on-pager-button buttonsmall"> + </h:commandButton> <onc:selectCommandButton action="#{InstalledPluginsUIBean.enableServerPlugins}" value="ENABLE" target="selectedPlugin" styleClass="on-pager-button buttonsmall"> </onc:selectCommandButton> @@ -212,6 +236,9 @@ <onc:selectCommandButton action="#{InstalledPluginsUIBean.undeployServerPlugins}" value="UNDEPLOY" target="selectedPlugin" styleClass="on-pager-button buttonsmall"> </onc:selectCommandButton> + <onc:selectCommandButton action="#{InstalledPluginsUIBean.purgeServerPlugins}" + value="PURGE" target="selectedPlugin" styleClass="on-pager-button buttonsmall"> + </onc:selectCommandButton> </rich:column> </rich:columnGroup> </f:facet> diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsBean.java index 37ae962..8a15d5c 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsBean.java @@ -127,6 +127,15 @@ public class ServerPluginsBean implements ServerPluginsLocal { return query.getResultList(); }
+ public List<ServerPlugin> getAllServerPluginsById(List<Integer> pluginIds) { + if (pluginIds == null || pluginIds.size() == 0) { + return new ArrayList<ServerPlugin>(); // nothing to do + } + Query query = entityManager.createNamedQuery(ServerPlugin.QUERY_FIND_ALL_BY_IDS); + query.setParameter("ids", pluginIds); + return query.getResultList(); + } + public ServerPluginDescriptorType getServerPluginDescriptor(PluginKey pluginKey) throws Exception { ServerPlugin plugin = getServerPlugin(pluginKey); File pluginsDir = LookupUtil.getServerPluginService().getServerPluginsDirectory(); @@ -296,6 +305,24 @@ public class ServerPluginsBean implements ServerPluginsLocal { }
@RequiredPermission(Permission.MANAGE_SETTINGS) + public List<PluginKey> purgeServerPlugins(Subject subject, List<Integer> pluginIds) throws Exception { + if (pluginIds == null || pluginIds.size() == 0) { + return new ArrayList<PluginKey>(); // nothing to do + } + + // first, ensure we undeploy them + List<PluginKey> purgePlugins = undeployServerPlugins(subject, pluginIds); + + // now remove them from the db + for (PluginKey pluginKey : purgePlugins) { + purgeServerPlugin(subject, pluginKey); // delete the row in the DB + } + + log.info("Server plugins " + purgePlugins + " have been undeployed"); + return purgePlugins; + } + + @RequiredPermission(Permission.MANAGE_SETTINGS) @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) public void setServerPluginEnabledFlag(Subject subject, List<Integer> pluginIds, boolean enabled) throws Exception { if (pluginIds == null || pluginIds.size() == 0) { diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsLocal.java index 4a0c3f7..191e8e7 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsLocal.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsLocal.java @@ -16,6 +16,9 @@ import org.rhq.enterprise.server.xmlschema.generated.serverplugin.ServerPluginDe
/** * Interface to the methods that interact with the serve-side plugin infrastructure. + * Most of these methods will only return information on {@link PluginStatusType#INSTALLED} + * plugins; only when explicitly stated will a method return data on + * {@link PluginStatusType#DELETED} plugins, too. * * @author John Mazzitelli */ @@ -68,6 +71,14 @@ public interface ServerPluginsLocal { List<ServerPlugin> getServerPluginsById(List<Integer> pluginIds);
/** + * Get a list of both installed and deleted plugins from their IDs. + * + * @param pluginIds the IDs of the plugins to load. + * @return plugins matching the given IDs + */ + List<ServerPlugin> getAllServerPluginsById(List<Integer> pluginIds); + + /** * Given a plugin key, returns the descriptor for that plugin. * * @param pluginKey @@ -117,6 +128,17 @@ public interface ServerPluginsLocal { List<PluginKey> undeployServerPlugins(Subject subject, List<Integer> pluginIds) throws Exception;
/** + * Purges the undeployed plugins from the system so there is no record of them to have + * ever existed. This deletes all remnants of the plugin from the database. + * + * @param subject user making the request + * @param pluginIds the plugins to be purged + * @return the list of keys of plugins that were purged + * @throws Exception if failed to purge a plugin + */ + List<PluginKey> purgeServerPlugins(Subject subject, List<Integer> pluginIds) throws Exception; + + /** * Turns on or off the enabled flag in the database but does NOT restart the server plugin container. * This has "requires new" semantics, so the results are committed immediately upon return. *
commit 9f013cacd320fa6d2fc0f2deb8d8ad407989081a Author: John Mazzitelli mazz@redhat.com Date: Wed Dec 2 12:46:03 2009 -0500
add API to get all server plugins, including deleted ones this also fixes some tests so they can run even if there are some other plugins found in the db
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/plugin/ServerPlugin.java b/modules/core/domain/src/main/java/org/rhq/core/domain/plugin/ServerPlugin.java index 714872e..976b83b 100644 --- a/modules/core/domain/src/main/java/org/rhq/core/domain/plugin/ServerPlugin.java +++ b/modules/core/domain/src/main/java/org/rhq/core/domain/plugin/ServerPlugin.java @@ -134,6 +134,30 @@ import org.rhq.core.domain.configuration.Configuration; + " LEFT JOIN p.scheduledJobsConfiguration " // + " WHERE p.name=:name "), //
+ // finds all installed AND deleted + // this query does not load the content blob, but loads everything else + @NamedQuery(name = ServerPlugin.QUERY_FIND_ALL, query = "" // + + " SELECT new org.rhq.core.domain.plugin.ServerPlugin( " // + + " p.id, " // + + " p.name, " // + + " p.path, " // + + " p.displayName, " // + + " p.enabled, " // + + " p.status, " // + + " p.description, " // + + " p.help, " // + + " p.md5, " // + + " p.version, " // + + " p.ampsVersion, " // + + " p.pluginConfiguration, " // + + " p.scheduledJobsConfiguration, " // + + " p.type, " // + + " p.ctime, " // + + " p.mtime) " // + + " FROM ServerPlugin AS p " // + + " LEFT JOIN p.pluginConfiguration " // + + " LEFT JOIN p.scheduledJobsConfiguration "), + // finds all installed - ignores those plugins marked as deleted // this query does not load the content blob, but loads everything else @NamedQuery(name = ServerPlugin.QUERY_FIND_ALL_INSTALLED, query = "" // @@ -196,6 +220,7 @@ public class ServerPlugin extends AbstractPlugin { public static final String QUERY_FIND_BY_IDS = "ServerPlugin.findByIds"; public static final String QUERY_FIND_BY_NAME = "ServerPlugin.findByName"; public static final String QUERY_FIND_ANY_BY_NAME = "ServerPlugin.findAnyByName"; + public static final String QUERY_FIND_ALL = "ServerPlugin.findAll"; public static final String QUERY_FIND_ALL_INSTALLED = "ServerPlugin.findAllInstalled"; public static final String QUERY_FIND_ALL_INSTALLED_KEYS = "ServerPlugin.findAllInstalledKeys"; public static final String QUERY_FIND_KEYS_BY_IDS = "ServerPlugin.findKeysByIds"; diff --git a/modules/core/domain/src/test/java/org/rhq/core/domain/resource/test/PluginTest.java b/modules/core/domain/src/test/java/org/rhq/core/domain/resource/test/PluginTest.java index c7afe81..c397780 100644 --- a/modules/core/domain/src/test/java/org/rhq/core/domain/resource/test/PluginTest.java +++ b/modules/core/domain/src/test/java/org/rhq/core/domain/resource/test/PluginTest.java @@ -244,6 +244,9 @@ public class PluginTest extends AbstractEJB3Test { getTransactionManager().begin(); EntityManager em = getEntityManager(); try { + Query query = em.createNamedQuery(Plugin.QUERY_FIND_ALL_INSTALLED); + int originalNumberOfPlugins = query.getResultList().size(); + String name = "PluginTest-testPersist"; String path = "/test/Persist"; String displayName = "Plugin Test - testPersist"; @@ -291,7 +294,7 @@ public class PluginTest extends AbstractEJB3Test { assert new String(plugin.getContent()).equals(new String(content));
// test our queries that purposefully do not load in the content blob - Query query = em.createNamedQuery(Plugin.QUERY_FIND_BY_NAME); + query = em.createNamedQuery(Plugin.QUERY_FIND_BY_NAME); query.setParameter("name", name); plugin = (Plugin) query.getSingleResult(); assert plugin != null; @@ -350,7 +353,7 @@ public class PluginTest extends AbstractEJB3Test {
// mark a plugin deleted - all of our queries should then never see it plugin.setStatus(PluginStatusType.DELETED); - em.merge(plugin); + plugin = em.merge(plugin);
query = em.createNamedQuery(Plugin.QUERY_FIND_BY_NAME); query.setParameter("name", name); @@ -364,7 +367,7 @@ public class PluginTest extends AbstractEJB3Test {
query = em.createNamedQuery(Plugin.QUERY_FIND_ALL_INSTALLED); results = query.getResultList(); - assert results.size() == 0; + assert results.size() == originalNumberOfPlugins;
} finally { getTransactionManager().rollback(); diff --git a/modules/core/domain/src/test/java/org/rhq/core/domain/resource/test/ServerPluginTest.java b/modules/core/domain/src/test/java/org/rhq/core/domain/resource/test/ServerPluginTest.java index 7186f52..1e52b62 100644 --- a/modules/core/domain/src/test/java/org/rhq/core/domain/resource/test/ServerPluginTest.java +++ b/modules/core/domain/src/test/java/org/rhq/core/domain/resource/test/ServerPluginTest.java @@ -274,6 +274,9 @@ public class ServerPluginTest extends AbstractEJB3Test { getTransactionManager().begin(); EntityManager em = getEntityManager(); try { + Query query = em.createNamedQuery(ServerPlugin.QUERY_FIND_ALL_INSTALLED); + int originalNumberOfPlugins = query.getResultList().size(); + String name = "ServerPluginTest-testPersist"; String path = "/test/Persist"; String displayName = "Server Plugin Test - testPersist"; @@ -328,7 +331,7 @@ public class ServerPluginTest extends AbstractEJB3Test { assert new String(plugin.getContent()).equals(new String(content));
// test our queries that purposefully do not load in the content blob - Query query = em.createNamedQuery(ServerPlugin.QUERY_FIND_BY_NAME); + query = em.createNamedQuery(ServerPlugin.QUERY_FIND_BY_NAME); query.setParameter("name", name); plugin = (ServerPlugin) query.getSingleResult(); assert plugin != null; @@ -396,7 +399,7 @@ public class ServerPluginTest extends AbstractEJB3Test {
query = em.createNamedQuery(ServerPlugin.QUERY_FIND_ALL_INSTALLED_KEYS); List<PluginKey> allKeys = query.getResultList(); - assert allKeys.size() == 1; + assert allKeys.size() == originalNumberOfPlugins + 1; assert allKeys.contains(new PluginKey(plugin));
query = em.createNamedQuery(ServerPlugin.QUERY_FIND_KEYS_BY_IDS); @@ -423,7 +426,11 @@ public class ServerPluginTest extends AbstractEJB3Test {
query = em.createNamedQuery(ServerPlugin.QUERY_FIND_ALL_INSTALLED); results = query.getResultList(); - assert results.size() == 0; + assert results.size() == originalNumberOfPlugins; + + query = em.createNamedQuery(ServerPlugin.QUERY_FIND_ALL); + results = query.getResultList(); + assert results.size() == originalNumberOfPlugins + 1;
} finally { getTransactionManager().rollback(); diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/InstalledPluginsUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/InstalledPluginsUIBean.java index 6fac7a3..476dd2f 100644 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/InstalledPluginsUIBean.java +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/InstalledPluginsUIBean.java @@ -71,7 +71,7 @@ public class InstalledPluginsUIBean { public Collection<ServerPlugin> getInstalledServerPlugins() {
hasPermission(); - return serverPluginsBean.getServerPlugins(); + return serverPluginsBean.getAllServerPlugins(); }
public void scan() { diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsBean.java index d80b5be..37ae962 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsBean.java @@ -85,6 +85,12 @@ public class ServerPluginsBean implements ServerPluginsLocal { return q.getResultList(); }
+ @SuppressWarnings("unchecked") + public List<ServerPlugin> getAllServerPlugins() { + Query q = entityManager.createNamedQuery(ServerPlugin.QUERY_FIND_ALL); + return q.getResultList(); + } + public ServerPlugin getServerPlugin(PluginKey key) { Query query = entityManager.createNamedQuery(ServerPlugin.QUERY_FIND_BY_NAME); query.setParameter("name", key.getPluginName()); diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsLocal.java index d21e36a..4a0c3f7 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsLocal.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsLocal.java @@ -22,13 +22,23 @@ import org.rhq.enterprise.server.xmlschema.generated.serverplugin.ServerPluginDe @Local public interface ServerPluginsLocal { /** - * Returns a list of all the server plugins in the database. + * Returns a list of all the installed server plugins in the database * - * @return all plugins found in the DB + * @return all installed server plugins found in the DB */ List<ServerPlugin> getServerPlugins();
/** + * Returns a list of all the installed and deleted server plugins in the database. + * When a plugin is "undeployed", it still exists in the database, but is flagged + * as "deleted". This method returns those deleted plugins in addition to those plugins + * that are still installed. + * + * @return all installed and deleted server plugins found in the DB + */ + List<ServerPlugin> getAllServerPlugins(); + + /** * Returns a plugin with the given key. * @param key identifies the plugin to find * @return the named plugin diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/plugin/ServerPluginsBeanTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/plugin/ServerPluginsBeanTest.java index 63f2e1d..e1738e5 100644 --- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/plugin/ServerPluginsBeanTest.java +++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/plugin/ServerPluginsBeanTest.java @@ -126,8 +126,14 @@ public class ServerPluginsBeanTest extends AbstractEJB3Test { List<ServerPlugin> plugins = this.serverPluginsBean.getServerPlugins(); assert plugins.contains(p1) : plugins; assert plugins.contains(p2) : plugins; - assetLazyInitializationException(plugins.get(0)); - assetLazyInitializationException(plugins.get(1)); + assetLazyInitializationException(plugins.get(plugins.indexOf(p1))); + assetLazyInitializationException(plugins.get(plugins.indexOf(p2))); + + plugins = this.serverPluginsBean.getAllServerPlugins(); + assert plugins.contains(p1) : plugins; + assert plugins.contains(p2) : plugins; + assetLazyInitializationException(plugins.get(plugins.indexOf(p1))); + assetLazyInitializationException(plugins.get(plugins.indexOf(p2)));
List<Integer> ids = new ArrayList<Integer>(2); ids.add(p1.getId()); @@ -136,8 +142,8 @@ public class ServerPluginsBeanTest extends AbstractEJB3Test { assert plugins.size() == 2 : plugins; assert plugins.contains(p1) : plugins; assert plugins.contains(p2) : plugins; - assetLazyInitializationException(plugins.get(0)); - assetLazyInitializationException(plugins.get(1)); + assetLazyInitializationException(plugins.get(plugins.indexOf(p1))); + assetLazyInitializationException(plugins.get(plugins.indexOf(p2))); }
public void testUpdatePlugins() throws Exception { @@ -205,6 +211,8 @@ public class ServerPluginsBeanTest extends AbstractEJB3Test {
public void testUndeployPlugins() throws Exception {
+ int originalSize = this.serverPluginsBean.getAllServerPlugins().size(); + PluginStatusType status;
PluginKey missingKey; @@ -227,6 +235,9 @@ public class ServerPluginsBeanTest extends AbstractEJB3Test { status = this.serverPluginsBean.getServerPluginStatus(p2key); assert status == PluginStatusType.INSTALLED;
+ assert this.serverPluginsBean.getServerPlugins().size() == originalSize + 2; + assert this.serverPluginsBean.getAllServerPlugins().size() == originalSize + 2; + List<Integer> ids = new ArrayList<Integer>(2); ids.add(p1.getId()); ids.add(p2.getId()); @@ -245,6 +256,9 @@ public class ServerPluginsBeanTest extends AbstractEJB3Test { pluginKeys = this.serverPluginsBean.getServerPluginKeysByEnabled(true); assert !pluginKeys.contains(p1.getName()) : pluginKeys; assert !pluginKeys.contains(p2.getName()) : pluginKeys; + + assert this.serverPluginsBean.getServerPlugins().size() == originalSize; + assert this.serverPluginsBean.getAllServerPlugins().size() == originalSize + 2; }
public void testReRegisterPlugins() throws Exception {
commit 6deb56bdd494670a38d5ef8f06a99ff8041f6dd5 Merge: 924d620... 9f6e1dc... Author: Adam Young ayoung@redhat.com Date: Wed Dec 2 16:44:11 2009 -0500
Merge branch 'raw-config' of ssh://git.fedorahosted.org/git/rhq/rhq into raw-config
commit c513655e9b3c278f878bb8eb564b17299a0d125b Author: Justin Harris jharris@redhat.com Date: Wed Dec 2 16:30:54 2009 -0500
* Modifying server plugin config page to be read-only * Adding additional edit page for server plugin configs. * Refactoring several UI beans to share common functionality.
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/AbstractPluginConfigurationUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/AbstractPluginConfigurationUIBean.java new file mode 100644 index 0000000..d8dc707 --- /dev/null +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/AbstractPluginConfigurationUIBean.java @@ -0,0 +1,97 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2009 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.gui.admin.plugin; + +import javax.faces.application.FacesMessage; +import org.jboss.seam.annotations.Logger; +import org.jboss.seam.log.Log; +import org.rhq.core.clientapi.agent.metadata.ConfigurationMetadataParser; +import org.rhq.core.domain.auth.Subject; +import org.rhq.core.domain.authz.Permission; +import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; +import org.rhq.core.domain.plugin.PluginDeploymentType; +import org.rhq.core.domain.plugin.PluginKey; +import org.rhq.core.domain.plugin.ServerPlugin; +import org.rhq.core.gui.util.FacesContextUtility; +import org.rhq.enterprise.gui.util.EnterpriseFacesContextUtility; +import org.rhq.enterprise.server.authz.PermissionException; +import org.rhq.enterprise.server.plugin.ServerPluginsLocal; +import org.rhq.enterprise.server.util.LookupUtil; +import org.rhq.enterprise.server.xmlschema.generated.serverplugin.ServerPluginDescriptorType; + +public abstract class AbstractPluginConfigurationUIBean { + + protected final ServerPluginsLocal serverPluginsBean = LookupUtil.getServerPlugins(); + @Logger + private Log log; + + private ServerPlugin plugin; + private ConfigurationDefinition pluginConfigurationDefinition; + private ConfigurationDefinition scheduledJobsDefinition; + + public ServerPlugin getPlugin() { + return plugin; + } + + public void setPlugin(ServerPlugin plugin) { + this.plugin = plugin; + } + + public ConfigurationDefinition getPluginConfigurationDefinition() { + return this.pluginConfigurationDefinition; + } + + public ConfigurationDefinition getScheduledJobsDefinition() { + return this.scheduledJobsDefinition; + } + + public boolean isEditable() { + return this.plugin != null && + (this.plugin.getPluginConfiguration() != null || + this.plugin.getScheduledJobsConfiguration() != null); + } + + // TODO: Find a more centralized way to do this - maybe via annotation + // on the class?? + /** + * Throws a permission exception if the user is not allowed to access this functionality. + */ + protected void checkPermission() { + Subject subject = EnterpriseFacesContextUtility.getSubject(); + if (!LookupUtil.getAuthorizationManager().hasGlobalPermission(subject, Permission.MANAGE_SETTINGS)) { + throw new PermissionException("User [" + subject.getName() + "] does not have the proper permissions to view or manage plugins"); + } + } + + protected void lookupConfigDefinitions() { + if (this.plugin.getDeployment() == PluginDeploymentType.SERVER) { + PluginKey pluginKey = new PluginKey(this.plugin); + + try { + ServerPluginDescriptorType descriptor = serverPluginsBean.getServerPluginDescriptor(pluginKey); + this.pluginConfigurationDefinition = ConfigurationMetadataParser.parse("pc:" + pluginKey.getPluginName(), descriptor.getPluginConfiguration()); + this.scheduledJobsDefinition = ConfigurationMetadataParser.parse("jobs:" + pluginKey.getPluginName(), descriptor.getScheduledJobs()); + } catch (Exception e) { + String err = "Cannot determine what the plugin configuration or scheduled jobs configuration looks like"; + log.error(err + " - Cause: " + e); + FacesContextUtility.addMessage(FacesMessage.SEVERITY_ERROR, err, e); + } + } + } +} diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/EditPluginConfigurationUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/EditPluginConfigurationUIBean.java new file mode 100644 index 0000000..d12f6c7 --- /dev/null +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/EditPluginConfigurationUIBean.java @@ -0,0 +1,72 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2009 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.gui.admin.plugin; + +import java.io.Serializable; +import javax.faces.application.FacesMessage; +import org.jboss.seam.ScopeType; +import org.jboss.seam.annotations.Create; +import org.jboss.seam.annotations.In; +import org.jboss.seam.annotations.Logger; +import org.jboss.seam.annotations.Name; +import org.jboss.seam.annotations.Scope; +import org.jboss.seam.log.Log; +import org.rhq.core.domain.auth.Subject; +import org.rhq.core.domain.plugin.ServerPlugin; +import org.rhq.core.gui.util.FacesContextUtility; +import org.rhq.enterprise.gui.util.EnterpriseFacesContextUtility; +import org.rhq.enterprise.server.plugin.ServerPluginsLocal; +import org.rhq.enterprise.server.util.LookupUtil; + +@Scope(ScopeType.PAGE) +@Name("editPluginConfigurationUIBean") +public class EditPluginConfigurationUIBean extends AbstractPluginConfigurationUIBean implements Serializable { + + @Logger + private Log log; + + @Create + public void init() { + checkPermission(); + lookupConfigDefinitions(); + } + + // The superclass holds the plugin instance variable, but in this + // case we want it injected via the PluginFactory - so this serves as + // the injection point + @In(value="plugin", required=false) + public void setCurrentPlugin(ServerPlugin currentPlugin) { + if (currentPlugin != null) { + setPlugin(currentPlugin); + } + } + + public void updatePlugin() { + try { + ServerPluginsLocal serverPlugins = LookupUtil.getServerPlugins(); + Subject subject = EnterpriseFacesContextUtility.getSubject(); + serverPlugins.updateServerPluginExceptContent(subject, getPlugin()); + FacesContextUtility.addMessage(FacesMessage.SEVERITY_INFO, "Configuration settings saved."); + } catch (Exception e) { + log.error("Error updating the plugin configurations.", e); + FacesContextUtility.addMessage(FacesMessage.SEVERITY_ERROR, + "There was an error changing the configuration settings.", e); + } + } +} diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/InstalledPluginComponent.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/InstalledPluginComponent.java deleted file mode 100644 index 43e9e41..0000000 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/InstalledPluginComponent.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2009 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.gui.admin.plugin; - -import org.jboss.seam.annotations.Factory; -import org.jboss.seam.annotations.Name; -import org.jboss.seam.annotations.web.RequestParameter; - -import org.rhq.core.domain.plugin.AbstractPlugin; -import org.rhq.core.domain.plugin.Plugin; -import org.rhq.core.domain.plugin.PluginDeploymentType; -import org.rhq.core.domain.plugin.PluginKey; -import org.rhq.core.domain.plugin.ServerPlugin; -import org.rhq.enterprise.server.plugin.ServerPluginsLocal; -import org.rhq.enterprise.server.util.LookupUtil; - -/** - * Component responsible for looking up a {@link Plugin}, obtaining - * the <code>name</code> and <code>type</code> from request parameters. - * - * @author jharris - */ -@Name("installedPlugin") -public class InstalledPluginComponent { - - @RequestParameter("plugin") - private String name; - @RequestParameter("deployment") - private PluginDeploymentType deployment; - @RequestParameter("pluginType") - private String pluginType; - - public String getName() { - return this.name; - } - - public void setName(String name) { - this.name = name; - } - - public PluginDeploymentType getDeployment() { - return this.deployment; - } - - public void setType(PluginDeploymentType deployment) { - this.deployment = deployment; - } - - public String getPluginType() { - return this.pluginType; - } - - public void setPluginType(String pluginType) { - this.pluginType = pluginType; - } - - @Factory(value = "plugin", autoCreate = true) - public AbstractPlugin lookupPlugin() { - if (this.deployment == PluginDeploymentType.AGENT) { - return LookupUtil.getResourceMetadataManager().getPlugin(this.name); - } else if (this.deployment == PluginDeploymentType.SERVER) { - PluginKey pluginKey = new PluginKey(this.deployment, this.pluginType, this.name); - ServerPluginsLocal serverPluginsBean = LookupUtil.getServerPlugins(); - ServerPlugin plugin = serverPluginsBean.getServerPlugin(pluginKey); - return serverPluginsBean.getServerPluginRelationships(plugin); - } - - return null; - } -} diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/PluginConfigurationUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/PluginConfigurationUIBean.java index 49634bd..c7c25f2 100644 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/PluginConfigurationUIBean.java +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/PluginConfigurationUIBean.java @@ -18,30 +18,17 @@ */ package org.rhq.enterprise.gui.admin.plugin;
+import java.io.Serializable; import java.util.List; import java.util.Map; -import javax.faces.application.FacesMessage; import org.jboss.seam.ScopeType; import org.jboss.seam.annotations.Create; -import org.jboss.seam.annotations.Logger; import org.jboss.seam.annotations.Name; import org.jboss.seam.annotations.Scope; import org.jboss.seam.annotations.web.RequestParameter; -import org.jboss.seam.log.Log; -import org.rhq.core.clientapi.agent.metadata.ConfigurationMetadataParser; -import org.rhq.core.domain.auth.Subject; -import org.rhq.core.domain.authz.Permission; -import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; -import org.rhq.core.domain.plugin.PluginDeploymentType; import org.rhq.core.domain.plugin.PluginKey; import org.rhq.core.domain.plugin.ServerPlugin; -import org.rhq.core.gui.util.FacesContextUtility; -import org.rhq.enterprise.gui.util.EnterpriseFacesContextUtility; -import org.rhq.enterprise.server.authz.PermissionException; -import org.rhq.enterprise.server.plugin.ServerPluginsLocal; import org.rhq.enterprise.server.plugin.pc.ServerPluginType; -import org.rhq.enterprise.server.util.LookupUtil; -import org.rhq.enterprise.server.xmlschema.generated.serverplugin.ServerPluginDescriptorType; import org.richfaces.component.UITree; import org.richfaces.component.html.HtmlTree; import org.richfaces.event.NodeSelectedEvent; @@ -50,44 +37,23 @@ import org.richfaces.model.TreeNodeImpl;
@Scope(ScopeType.PAGE) @Name("pluginConfigUIBean") -public class PluginConfigurationUIBean { +public class PluginConfigurationUIBean extends AbstractPluginConfigurationUIBean implements Serializable {
@RequestParameter private String pluginName; - @Logger - private Log log; - private final ServerPluginsLocal serverPluginsBean = LookupUtil.getServerPlugins(); private TreeNode root; - private ServerPlugin currentPlugin; - private ConfigurationDefinition pluginConfigurationDefinition; - private ConfigurationDefinition scheduledJobsDefinition;
public TreeNode getRoot() { return root; }
- public ServerPlugin getCurrentPlugin() { - return currentPlugin; - } - - public ConfigurationDefinition getPluginConfigurationDefinition() { - return this.pluginConfigurationDefinition; - } - - public ConfigurationDefinition getScheduledJobsDefinition() { - return this.scheduledJobsDefinition; - } - - public boolean isEditable() { - return this.currentPlugin != null && - (this.currentPlugin.getPluginConfiguration() != null || - this.currentPlugin.getScheduledJobsConfiguration() != null); - } - @Create - public void createTree() { - hasPermission(); + public void init() { + checkPermission(); + createTree(); + }
+ private void createTree() { this.root = new TreeNodeImpl(); Map<ServerPluginType, List<PluginKey>> types = serverPluginsBean.getInstalledServerPluginsGroupedByType();
@@ -144,15 +110,15 @@ public class PluginConfigurationUIBean { */ public boolean adviseSelected(UITree node) { if (isServerPluginSelected(node)) { - if (this.currentPlugin != null) { - return node.getRowData() == this.currentPlugin; + if (getPlugin() != null) { + return node.getRowData() == getPlugin(); } else { // there is no plugin currently selected ServerPlugin plugin = (ServerPlugin) node.getRowData();
// if this is the node that matches the request parameter, // go ahead and load the config and select this node if (plugin.getName().equals(this.pluginName)) { - this.currentPlugin = plugin; + setPlugin(plugin); lookupConfigDefinitions();
return true; @@ -165,59 +131,23 @@ public class PluginConfigurationUIBean { return false; }
+ /** + * Responds to node selection events in the plugin tree widget. + * + * @param event + */ public void processSelection(NodeSelectedEvent event) { HtmlTree node = (HtmlTree) event.getSource();
if (isServerPluginSelected(node)) { - this.currentPlugin = (ServerPlugin) node.getRowData(); + setPlugin((ServerPlugin) node.getRowData()); lookupConfigDefinitions();
node.setSelected(); } }
- public void updatePlugin() { - try { - ServerPluginsLocal serverPlugins = LookupUtil.getServerPlugins(); - Subject subject = EnterpriseFacesContextUtility.getSubject(); - serverPlugins.updateServerPluginExceptContent(subject, this.currentPlugin); - FacesContextUtility.addMessage(FacesMessage.SEVERITY_INFO, "Configuration settings saved."); - } catch (Exception e) { - log.error("Error updating the plugin configurations.", e); - FacesContextUtility.addMessage(FacesMessage.SEVERITY_ERROR, - "There was an error changing the configuration settings.", e); - } - } - private boolean isServerPluginSelected(UITree tree) { return tree.getRowData() instanceof ServerPlugin; } - - private void lookupConfigDefinitions() { - if (this.currentPlugin.getDeployment() == PluginDeploymentType.SERVER) { - PluginKey pluginKey = new PluginKey(this.currentPlugin); - - try { - ServerPluginDescriptorType descriptor = serverPluginsBean.getServerPluginDescriptor(pluginKey); - this.pluginConfigurationDefinition = ConfigurationMetadataParser.parse("pc:" + pluginKey.getPluginName(), descriptor.getPluginConfiguration()); - this.scheduledJobsDefinition = ConfigurationMetadataParser.parse("jobs:" + pluginKey.getPluginName(), descriptor.getScheduledJobs()); - } catch (Exception e) { - String err = "Cannot determine what the plugin configuration or scheduled jobs configuration looks like"; - log.error(err + " - Cause: " + e); - FacesContextUtility.addMessage(FacesMessage.SEVERITY_ERROR, err, e); - } - } - } - - // TODO: Find a more centralized way to do this - maybe via annotation - // on the class?? - /** - * Throws a permission exception if the user is not allowed to access this functionality. - */ - private void hasPermission() { - Subject subject = EnterpriseFacesContextUtility.getSubject(); - if (!LookupUtil.getAuthorizationManager().hasGlobalPermission(subject, Permission.MANAGE_SETTINGS)) { - throw new PermissionException("User [" + subject.getName() + "] does not have the proper permissions to view or manage plugins"); - } - } } diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/PluginFactory.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/PluginFactory.java new file mode 100644 index 0000000..8ea7838 --- /dev/null +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/PluginFactory.java @@ -0,0 +1,62 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2009 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.gui.admin.plugin; + +import org.jboss.seam.annotations.Factory; +import org.jboss.seam.annotations.Name; +import org.jboss.seam.annotations.web.RequestParameter; + +import org.rhq.core.domain.plugin.AbstractPlugin; +import org.rhq.core.domain.plugin.Plugin; +import org.rhq.core.domain.plugin.PluginDeploymentType; +import org.rhq.core.domain.plugin.PluginKey; +import org.rhq.core.domain.plugin.ServerPlugin; +import org.rhq.enterprise.server.plugin.ServerPluginsLocal; +import org.rhq.enterprise.server.util.LookupUtil; + +/** + * Component responsible for looking up a {@link Plugin}, obtaining + * the <code>name</code> and <code>type</code> from request parameters. + * + * @author jharris + */ +@Name("pluginFactory") +public class PluginFactory { + + @RequestParameter("plugin") + private String name; + @RequestParameter("deployment") + private PluginDeploymentType deployment; + @RequestParameter("pluginType") + private String pluginType; + + @Factory(value = "plugin", autoCreate = true) + public AbstractPlugin lookupPlugin() { + if (this.deployment == PluginDeploymentType.AGENT) { + return LookupUtil.getResourceMetadataManager().getPlugin(this.name); + } else if (this.deployment == PluginDeploymentType.SERVER) { + PluginKey pluginKey = new PluginKey(this.deployment, this.pluginType, this.name); + ServerPluginsLocal serverPluginsBean = LookupUtil.getServerPlugins(); + ServerPlugin plugin = serverPluginsBean.getServerPlugin(pluginKey); + return serverPluginsBean.getServerPluginRelationships(plugin); + } + + return null; + } +} diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-config.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-config.xhtml index e061589..fa30a67 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-config.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-config.xhtml @@ -75,27 +75,31 @@ </rich:panel>
<h:panelGroup id="pluginConfig"> - <rich:panel rendered="#{pluginConfigUIBean.currentPlugin.pluginConfiguration != null}"> + <rich:panel rendered="#{pluginConfigUIBean.plugin.pluginConfiguration != null}"> <f:facet name="header"> <h:outputText value="Plugin Configuration"/> </f:facet> <onc:config configurationDefinition="#{pluginConfigUIBean.pluginConfigurationDefinition}" - configuration="#{pluginConfigUIBean.currentPlugin.pluginConfiguration}" /> + configuration="#{pluginConfigUIBean.plugin.pluginConfiguration}" + readOnly="true" /> </rich:panel>
- <rich:panel rendered="#{pluginConfigUIBean.currentPlugin.scheduledJobsConfiguration != null}"> + <rich:panel rendered="#{pluginConfigUIBean.plugin.scheduledJobsConfiguration != null}"> <f:facet name="header"> <h:outputText value="Scheduled Jobs"/> </f:facet> <onc:config configurationDefinition="#{pluginConfigUIBean.scheduledJobsDefinition}" - configuration="#{pluginConfigUIBean.currentPlugin.scheduledJobsConfiguration}" /> + configuration="#{pluginConfigUIBean.plugin.scheduledJobsConfiguration}" + readOnly="true" /> </rich:panel>
<h:panelGroup id="pluginButtons" rendered="#{pluginConfigUIBean.editable}"> - <h:commandButton value="SAVE" type="submit" action="#{pluginConfigUIBean.updatePlugin}" - alt="Click to Save Changes" styleClass="buttonmed" /> - <h:commandButton value="RESET" type="reset" immediate="true" - title="Click to Reset Fields" styleClass="buttonmed"/> + <h:outputLink value="/rhq/admin/plugin/plugin-edit.xhtml" styleClass="buttonmed"> + <f:param name="plugin" value="#{pluginConfigUIBean.plugin.name}"/> + <f:param name="deployment" value="#{pluginConfigUIBean.plugin.deployment}"/> + <f:param name="pluginType" value="#{pluginConfigUIBean.plugin.type}"/> + <h:outputText value="EDIT"/> + </h:outputLink> </h:panelGroup> </h:panelGroup> </h:panelGrid> diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-edit.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-edit.xhtml new file mode 100644 index 0000000..38e8c60 --- /dev/null +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-edit.xhtml @@ -0,0 +1,68 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<html xmlns="http://www.w3.org/1999/xhtml" + xmlns:h="http://java.sun.com/jsf/html" + xmlns:f="http://java.sun.com/jsf/core" + xmlns:ui="http://java.sun.com/jsf/facelets" + xmlns:c="http://java.sun.com/jstl/core" + xmlns:onc="http://jboss.org/on/component" + xmlns:rich="http://richfaces.ajax4jsf.org/rich%22%3E + +<ui:composition template="/rhq/layout/main.xhtml"> + <ui:param name="pageTitle" value="Edit #{editPluginConfigurationUIBean.plugin.displayName} Configuration"/> + + <ui:define name="breadcrumbs"> + <h:outputLink value="/admin/config/Config.do?mode=edit"> + <h:outputText value="Server Settings"/> + </h:outputLink> + > + <h:outputLink value="plugin-config.xhtml?pluginName=#{editPluginConfigurationUIBean.plugin.name}"> + <h:outputText value="Server Plugins Configuration"/> + </h:outputLink> + > + <h:outputLink value="plugin-edit.xhtml?pluginName"> + <h:outputText value="Edit #{editPluginConfigurationUIBean.plugin.displayName} Configuration"/> + </h:outputLink> + </ui:define> + + <ui:define name="body"> + <br/> + <h:messages showSummary="true" + showDetail="true" + infoClass="InfoBlock" + warnClass="WarnBlock" + errorClass="ErrorBlock" + fatalClass="FatalBlock" + globalOnly="true" + layout="table" + width="100%"/> + + <h:form id="pluginConfigForm"> + <rich:panel rendered="#{editPluginConfigurationUIBean.plugin.pluginConfiguration != null}"> + <f:facet name="header"> + <h:outputText value="Plugin Configuration"/> + </f:facet> + <onc:config configurationDefinition="#{editPluginConfigurationUIBean.pluginConfigurationDefinition}" + configuration="#{editPluginConfigurationUIBean.plugin.pluginConfiguration}" /> + </rich:panel> + + <rich:panel rendered="#{editPluginConfigurationUIBean.plugin.scheduledJobsConfiguration != null}"> + <f:facet name="header"> + <h:outputText value="Scheduled Jobs"/> + </f:facet> + <onc:config configurationDefinition="#{editPluginConfigurationUIBean.scheduledJobsDefinition}" + configuration="#{editPluginConfigurationUIBean.plugin.scheduledJobsConfiguration}" /> + </rich:panel> + + <h:panelGroup id="pluginButtons"> + <h:commandButton value="SAVE" type="submit" action="#{editPluginConfigurationUIBean.updatePlugin}" + alt="Click to Save Changes" styleClass="buttonmed" /> + <h:commandButton value="RESET" type="reset" immediate="true" + title="Click to Reset Fields" styleClass="buttonmed"/> + </h:panelGroup> + </h:form> + </ui:define> + +</ui:composition> + +</html> \ No newline at end of file
commit 9f6e1dc7c556715481c79e9727c347aa5e6400d8 Author: John Sanda john@localhost.localdomain Date: Wed Dec 2 16:18:53 2009 -0500
Fixing serialization bug that I introduced during some previous refactoring.
The parent properties of a Configuration object's properties and raw configs were not getting set.
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/Configuration.java b/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/Configuration.java index c51a6ba..144f136 100644 --- a/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/Configuration.java +++ b/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/Configuration.java @@ -638,7 +638,9 @@ public class Configuration implements Externalizable, Cloneable, AbstractPropert private Map<String, Property> createDeepCopyOfMap() { Map<String, Property> copy = new HashMap<String, Property>(); for (Map.Entry<String, Property> entry : this.properties.entrySet()) { - copy.put(entry.getKey(), entry.getValue().deepCopy(true)); + Property copiedProperty = entry.getValue().deepCopy(true); + copiedProperty.setConfiguration(this); + copy.put(entry.getKey(), copiedProperty); } return copy; } @@ -646,7 +648,9 @@ public class Configuration implements Externalizable, Cloneable, AbstractPropert private Set<RawConfiguration> createDeepCopyOfRawConfigs() { Set<RawConfiguration> copy = new HashSet<RawConfiguration>(); for (RawConfiguration rawConfig : this.rawConfigurations) { - copy.add(rawConfig.deepCopy(true)); + RawConfiguration copiedRawConfig = rawConfig.deepCopy(true); + copiedRawConfig.setConfiguration(this); + copy.add(copiedRawConfig); } return copy; } diff --git a/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/ConfigurationTest.java b/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/ConfigurationTest.java index 3da4922..c1aba0c 100644 --- a/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/ConfigurationTest.java +++ b/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/ConfigurationTest.java @@ -498,6 +498,13 @@ public class ConfigurationTest { Configuration serializedConfig = TestUtil.serializeAndDeserialize(config);
assertEquals(serializedConfig.getMap(), config.getMap(), "Failed to property serialize the map property"); + for (Property property : serializedConfig.getProperties()) { + assertEquals( + property.getConfiguration(), + serializedConfig, + "Failed to update parent reference of property during serialization" + ); + } }
@Test @@ -667,6 +674,13 @@ public class ConfigurationTest { config.getRawConfigurations(), "Failed to properly serialize rawConfigurations property" ); + for (RawConfiguration rawConfig : serializedConfig.getRawConfigurations()) { + assertEquals( + rawConfig.getConfiguration(), + serializedConfig, + "Failed to update parent reference of raw config during serialization" + ); + } }
private void updateModifiedTime(Configuration config) {
commit f3e1bb8389ae4598751c4f9580fce10a94dc156e Merge: 6dba977... 6a11544... Author: Jay Shaughnessy jshaughn@redhat.com Date: Wed Dec 2 16:17:38 2009 -0500
Merge branch 'linux-config-dev' into linux-config
commit 6a11544f9d8a9e3e8b8b12e779643cdbb8c1e1d6 Author: Jay Shaughnessy jshaughn@redhat.com Date: Wed Dec 2 16:16:39 2009 -0500
Added global permission activation for core menu items
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveManagerBean.java index 67a08be..27fd2bb 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveManagerBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveManagerBean.java @@ -18,6 +18,7 @@ */ package org.rhq.enterprise.server.perspective;
+import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -31,8 +32,15 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory;
import org.rhq.core.domain.auth.Subject; +import org.rhq.core.domain.authz.Permission; import org.rhq.enterprise.server.RHQConstants; import org.rhq.enterprise.server.auth.SubjectManagerLocal; +import org.rhq.enterprise.server.authz.AuthorizationManagerLocal; +import org.rhq.enterprise.server.xmlschema.generated.serverplugin.perspective.InventoryActivatorSetType; +import org.rhq.enterprise.server.xmlschema.generated.serverplugin.perspective.MenuItemType; +import org.rhq.enterprise.server.xmlschema.generated.serverplugin.perspective.PermissionActivatorSetType; +import org.rhq.enterprise.server.xmlschema.generated.serverplugin.perspective.PermissionActivatorType; +import org.rhq.enterprise.server.xmlschema.generated.serverplugin.perspective.PermissionType;
@Stateless // @WebService(endpointInterface = "org.rhq.enterprise.server.perspective.PerspectiveManagerRemote") @@ -45,12 +53,14 @@ public class PerspectiveManagerBean implements PerspectiveManagerLocal, Perspect // based on username it's not quite appropriate. // The cache is cleaned anytime there is a new entry. static private Map<Integer, CacheEntry> cache = new HashMap<Integer, CacheEntry>(); - private List<MenuItem> coreMenu;
@PersistenceContext(unitName = RHQConstants.PERSISTENCE_UNIT_NAME) private EntityManager entityManager;
@EJB + private AuthorizationManagerLocal authorizationManager; + + @EJB private SubjectManagerLocal subjectManager;
/* (non-Javadoc) @@ -75,6 +85,12 @@ public class PerspectiveManagerBean implements PerspectiveManagerLocal, Perspect try { coreMenu = PerspectiveManagerHelper.getPluginMetadataManager().getCoreMenu();
+ // We have to be careful not to mess with the core menu as it is returned from + // the perspective manager. The core menu for each subject/sessionid could + // differ based on activation checks. So, get a new mnu structure when applying + // activation filters. + coreMenu = getActivatedMenu(subject, coreMenu); + // TODO : make safe copy cacheEntry.setCoreMenu(coreMenu); } catch (Exception e) { @@ -82,8 +98,6 @@ public class PerspectiveManagerBean implements PerspectiveManagerLocal, Perspect } }
- // TODO: Apply Activators here - return coreMenu; }
@@ -104,6 +118,79 @@ public class PerspectiveManagerBean implements PerspectiveManagerLocal, Perspect } }
+ /** + * Given a menu return a filtered copy such that inactive menu items are not present. Recursively + * handles children menus. + * + * @param subject + * @param coreMenu + * @return A filtered copy of the menu structure. This results in new Lists and new MenuItems + * that refer to the original MenuItemType objects. + */ + private List<MenuItem> getActivatedMenu(Subject subject, List<MenuItem> menu) { + List<MenuItem> result = new ArrayList<MenuItem>(menu.size()); + + for (MenuItem menuItem : menu) { + MenuItemType item = menuItem.getItem(); + List<InventoryActivatorSetType> inventoryActivatorSets = item.getInventoryActivatorSet(); + List<PermissionActivatorSetType> permissionActivatorSets = item.getPermissionActivatorSet(); + + // Make sure activators are satisfied before copying + if (checkActivators(subject, inventoryActivatorSets, permissionActivatorSets)) { + MenuItem copy = new MenuItem(menuItem.getItem()); + + result.add(copy); + if (menuItem.isMenuGroup()) { + copy.setChildren(getActivatedMenu(subject, menuItem.getChildren())); + } + } + } + + return result; + } + + private boolean checkActivators(Subject subject, List<InventoryActivatorSetType> inventoryActivatorSets, + List<PermissionActivatorSetType> permissionActivatorSets) { + + // global perm checking is relatively fast, make sure these pass before checking inventory activators + for (PermissionActivatorSetType permissionActivatorSet : permissionActivatorSets) { + boolean any = permissionActivatorSet.isAny(); + boolean anyPassed = false; + boolean anyFailed = false; + + for (PermissionActivatorType permissionActivator : permissionActivatorSet.getPermissionActivator()) { + boolean hasPermission = hasGlobalPermission(subject, permissionActivator.getPermission()); + anyPassed = hasPermission; + anyFailed = !hasPermission; + + if (any && anyPassed) { + break; + } + if (!any && anyFailed) { + break; + } + } + + if ((any && !anyPassed) || (!any && anyFailed)) { + return false; + } + } + + for (InventoryActivatorSetType inventoryActivatorSet : inventoryActivatorSets) { + //TODO: impl + } + + return true; + } + + private boolean hasGlobalPermission(Subject subject, PermissionType permissionType) { + if (permissionType == PermissionType.SUPERUSER) { + return authorizationManager.isSystemSuperuser(subject); + } + + return authorizationManager.hasGlobalPermission(subject, Permission.valueOf(permissionType.name())); + } + // TODO: remove this debug code @SuppressWarnings("unused") private void printMenu(List<MenuItem> menu, String indent) {
commit 6dba977fd4c08ff09e9fde32de6a47d72289b73a Author: Ian Springer ian.springer@redhat.com Date: Wed Dec 2 15:59:27 2009 -0500
upgrade version of JBossAS deps from 5.2.0-SNAPSHOT to 6.0.0.M1; fix parent of jboss-cache-v3 module
diff --git a/modules/plugins/jboss-as-5/pom.xml b/modules/plugins/jboss-as-5/pom.xml index 5530b39..1fba8eb 100644 --- a/modules/plugins/jboss-as-5/pom.xml +++ b/modules/plugins/jboss-as-5/pom.xml @@ -29,7 +29,7 @@ <properties> <scm.module.path>modules/plugins/jboss-as-5/</scm.module.path>
- <jbossas.version>5.2.0-SNAPSHOT</jbossas.version> + <jbossas.version>6.0.0.M1</jbossas.version> </properties>
<dependencyManagement> diff --git a/modules/plugins/jboss-cache-v3/pom.xml b/modules/plugins/jboss-cache-v3/pom.xml index dcfad62..df71edc 100644 --- a/modules/plugins/jboss-cache-v3/pom.xml +++ b/modules/plugins/jboss-cache-v3/pom.xml @@ -3,14 +3,13 @@ <modelVersion>4.0.0</modelVersion>
<parent> - <groupId>org.jboss.on</groupId> - <!-- Bypass the jon-plugins-parent which can not have children. It must build after the plugins in order to execute integration tests on them. --> - <artifactId>jopr-modules-parent</artifactId> - <version>2.4.0-SNAPSHOT</version> + <groupId>org.rhq</groupId> + <artifactId>rhq-plugins-parent</artifactId> + <version>1.4.0-SNAPSHOT</version> </parent>
<groupId>org.jboss.on</groupId> - <artifactId>jopr-jboss-cache-v3-plugin</artifactId> + <artifactId>jopr-jboss-cache-v3-plugin</artifactId> <packaging>jar</packaging>
<name>RHQ JBossCache 3.x Plugin</name> @@ -23,7 +22,8 @@
<properties> <scm.module.path>modules/plugins/jboss-cache-v3/</scm.module.path> - <jbossas.version>5.2.0-SNAPSHOT</jbossas.version> + + <jbossas.version>6.0.0.M1</jbossas.version> </properties>
<dependencyManagement> @@ -50,7 +50,7 @@ <dependency> <groupId>${rhq.groupId}</groupId> <artifactId>rhq-jmx-plugin</artifactId> - <version>${rhq.version}</version> + <version>${project.version}</version> <scope>provided</scope> </dependency>
commit c92dae896a7195b92aeb3d7061af0d88bbb3c5fb Author: Jay Shaughnessy jshaughn@redhat.com Date: Wed Dec 2 14:07:09 2009 -0500
Added first pass at activation schema elements and added permission activators to the core menu. Note, activators are not yet being processed.
diff --git a/modules/enterprise/server/plugins/perspectives/core/perspective/src/main/resources/META-INF/rhq-serverplugin.xml b/modules/enterprise/server/plugins/perspectives/core/perspective/src/main/resources/META-INF/rhq-serverplugin.xml index 8e0cf4d..b3bad4f 100644 --- a/modules/enterprise/server/plugins/perspectives/core/perspective/src/main/resources/META-INF/rhq-serverplugin.xml +++ b/modules/enterprise/server/plugins/perspectives/core/perspective/src/main/resources/META-INF/rhq-serverplugin.xml @@ -61,6 +61,10 @@ extensionPoint="coreMenu" name="administration" placement="after" /> + <permissionActivatorSet> + <permissionActivator + permission="SUPERUSER" /> + </permissionActivatorSet> </menuItem> <menuItem name="help" @@ -70,30 +74,7 @@ name="debug" placement="after" /> </menuItem> -<!-- - <menuItem - name="refresh" - displayName="" - iconUrl="/images/refreshStopped.gif" - feature="refreshMenu"> - <position - extensionPoint="coreMenu" - name="help" - placement="after" - location="right" /> - </menuItem> - <menuItem - name="loggedInAs" - displayName="Logged in as " - feature="loggedInAsMenu"> - <position - extensionPoint="coreMenu" - name="refresh" - placement="after" - location="right" /> - </menuItem> - --> - + <!-- Core Menu: Overview --> <menuItem name="overview.subsystemViews" @@ -225,6 +206,10 @@ name="groups.groupDefinitions" placement="after" addBreak="true" /> + <permissionActivatorSet> + <permissionActivator + permission="MANAGE_INVENTORY" /> + </permissionActivatorSet> </menuItem> <menuItem name="groups.newGroupDefinition" @@ -234,6 +219,10 @@ extensionPoint="coreMenu" name="groups.newGroup" placement="after" /> + <permissionActivatorSet> + <permissionActivator + permission="MANAGE_INVENTORY" /> + </permissionActivatorSet> </menuItem> <menuItem name="groups.favoriteGroups" @@ -284,6 +273,13 @@ extensionPoint="coreMenu" name="administration.security" placement="after" /> + <permissionActivatorSet + any="true"> + <permissionActivator + permission="MANAGE_INVENTORY" /> + <permissionActivator + permission="MANAGE_SETTINGS" /> + </permissionActivatorSet> </menuItem> <menuItem name="administration.content" @@ -292,6 +288,10 @@ extensionPoint="coreMenu" name="administration.systemConfiguration" placement="after" /> + <permissionActivatorSet> + <permissionActivator + permission="MANAGE_INVENTORY" /> + </permissionActivatorSet> </menuItem> <menuItem name="administration.highAvailability" @@ -300,6 +300,10 @@ extensionPoint="coreMenu" name="administration.content" placement="after" /> + <permissionActivatorSet> + <permissionActivator + permission="MANAGE_INVENTORY" /> + </permissionActivatorSet> </menuItem> <menuItem name="administration.reports" @@ -327,6 +331,10 @@ extensionPoint="coreMenu" name="administration.download" placement="after" /> + <permissionActivatorSet> + <permissionActivator + permission="MANAGE_SETTINGS" /> + </permissionActivatorSet> </menuItem>
<!-- Core Menu: Debug --> @@ -505,6 +513,10 @@ extensionPoint="coreMenu" name="administration.systemConfiguration" placement="start" /> + <permissionActivatorSet> + <permissionActivator + permission="MANAGE_SETTINGS" /> + </permissionActivatorSet> </menuItem> <menuItem name="administration.systemConfiguration.plugins" @@ -514,6 +526,10 @@ extensionPoint="coreMenu" name="administration.systemConfiguration.settings" placement="after" /> + <permissionActivatorSet> + <permissionActivator + permission="MANAGE_SETTINGS" /> + </permissionActivatorSet> </menuItem> <menuItem name="administration.systemConfiguration.templates" @@ -523,6 +539,10 @@ extensionPoint="coreMenu" name="administration.systemConfiguration.plugins" placement="after" /> + <permissionActivatorSet> + <permissionActivator + permission="MANAGE_INVENTORY" /> + </permissionActivatorSet> </menuItem>
<!-- Core Menu: administration.content --> diff --git a/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-perspective.xsd b/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-perspective.xsd index 4f0858e..0dfb1a9 100644 --- a/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-perspective.xsd +++ b/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-perspective.xsd @@ -117,7 +117,7 @@ </xs:annotation> </xs:element> <xs:element - ref="perspective:inventoryActivator" + ref="perspective:inventoryActivatorSet" minOccurs="0" maxOccurs="unbounded"> xs:annotation @@ -128,7 +128,7 @@ </xs:annotation> </xs:element> <xs:element - ref="perspective:permissionActivator" + ref="perspective:permissionActivatorSet" minOccurs="0" maxOccurs="unbounded"> xs:annotation @@ -228,7 +228,7 @@ </xs:annotation> </xs:element> <xs:element - ref="perspective:inventoryActivator" + ref="perspective:inventoryActivatorSet" minOccurs="0" maxOccurs="unbounded"> xs:annotation @@ -238,7 +238,7 @@ </xs:annotation> </xs:element> <xs:element - ref="perspective:permissionActivator" + ref="perspective:permissionActivatorSet" minOccurs="0" maxOccurs="unbounded"> xs:annotation @@ -373,7 +373,7 @@ </xs:annotation> </xs:element> <xs:element - ref="perspective:inventoryActivator" + ref="perspective:inventoryActivatorSet" minOccurs="0" maxOccurs="unbounded"> xs:annotation @@ -383,7 +383,7 @@ </xs:annotation> </xs:element> <xs:element - ref="perspective:permissionActivator" + ref="perspective:permissionActivatorSet" minOccurs="0" maxOccurs="unbounded"> xs:annotation @@ -448,58 +448,128 @@ </xs:complexType>
<xs:element - name="inventoryActivator"> + name="permissionActivatorSet" + type="perspective:PermissionActivatorSetType"> xs:annotation - xs:documentationAn activator specifying inventory conditions that must be satisfied in order for the - extension to be active.</xs:documentation> + xs:documentationOne or more permission conditions that must be satisfied in order for the extension to be + active.</xs:documentation> xs:appinfo <jaxb:class - name="InventoryActivatorElement" /> + name="PermissionActivatorSetElement" /> </xs:appinfo> </xs:annotation> + </xs:element>
- xs:complexType - xs:sequence - <xs:element - ref="perspective:permissionActivator" - minOccurs="0" - maxOccurs="unbounded"> - </xs:element> - <xs:element - ref="perspective:traitActivator" - minOccurs="0" - maxOccurs="unbounded"> - </xs:element> - </xs:sequence> - <xs:attribute - name="plugin" - type="xs:string" - use="required"> - xs:annotation - xs:documentationPlugin for the specified resource type.</xs:documentation> - </xs:annotation> - </xs:attribute> - <xs:attribute - name="resourceType" - type="xs:string" - use="required"> - xs:annotation - xs:documentationResource Type that must be in inventory to activate the extension point. - </xs:documentation> - </xs:annotation> - </xs:attribute> - </xs:complexType> + <xs:element + name="traitActivatorSet" + type="perspective:TraitActivatorSetType"> + xs:annotation + xs:documentationOne or more inventory conditions that must be satisfied in order for the extension to be + active.</xs:documentation> + xs:appinfo + <jaxb:class + name="TraitActivatorSetElement" /> + </xs:appinfo> + </xs:annotation> + </xs:element> + + <xs:element + name="inventoryActivatorSet" + type="perspective:InventoryActivatorSetType"> + xs:annotation + xs:documentationOne or more inventory conditions that must be satisfied in order for the extension to be + active.</xs:documentation> + xs:appinfo + <jaxb:class + name="InventoryActivatorSetElement" /> + </xs:appinfo> + </xs:annotation> </xs:element>
+ <xs:complexType + name="PermissionActivatorSetType"> + xs:sequence + <xs:element + ref="perspective:permissionActivator" + minOccurs="0" + maxOccurs="unbounded"> + </xs:element> + </xs:sequence> + <xs:attribute + name="any" + type="xs:boolean" + use="optional" + default="false"> + xs:annotation + xs:documentationIf true extension activation passes if any individual activator is satisfied. If false all + activators must be satisfied. Default is false.</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:complexType> + + <xs:complexType + name="TraitActivatorSetType"> + xs:sequence + <xs:element + ref="perspective:traitActivator" + minOccurs="0" + maxOccurs="unbounded"> + </xs:element> + </xs:sequence> + <xs:attribute + name="any" + type="xs:boolean" + use="optional" + default="false"> + xs:annotation + xs:documentationIf true extension activation passes if any individual activator is satisfied. If false all + activators must be satisfied. Default is false.</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:complexType> + + <xs:complexType + name="InventoryActivatorSetType"> + xs:sequence + <xs:element + ref="perspective:inventoryActivator" + minOccurs="0" + maxOccurs="unbounded"> + </xs:element> + </xs:sequence> + <xs:attribute + name="any" + type="xs:boolean" + use="optional" + default="false"> + xs:annotation + xs:documentationIf true extension activation passes if any individual activator is satisfied. If false all + activators must be satisfied. Default is false.</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:complexType> + <xs:element name="permissionActivator" - type="perspective:PermissionType"> + type="perspective:PermissionActivatorType"> xs:annotation xs:documentationAn activator specifying a permission condition that must be satisfied in order for the extension to be active.</xs:documentation> </xs:annotation> </xs:element>
+ <xs:complexType + name="PermissionActivatorType"> + <xs:attribute + name="permission" + type="perspective:PermissionType" + use="required"> + xs:annotation + xs:documentationThe required permission.</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:complexType> + <xs:element name="traitActivator" type="perspective:TraitActivatorType"> @@ -550,6 +620,52 @@ </xs:complexType>
<xs:element + name="inventoryActivator" + type="perspective:InventoryActivatorType"> + xs:annotation + xs:documentationAn activator specifying inventory conditions that must be satisfied in order for the + extension to be active.</xs:documentation> + xs:appinfo + <jaxb:class + name="InventoryActivatorElement" /> + </xs:appinfo> + </xs:annotation> + </xs:element> + + <xs:complexType + name="InventoryActivatorType"> + xs:sequence + <xs:element + ref="perspective:permissionActivatorSet" + minOccurs="0" + maxOccurs="unbounded"> + </xs:element> + <xs:element + ref="perspective:traitActivatorSet" + minOccurs="0" + maxOccurs="unbounded"> + </xs:element> + </xs:sequence> + <xs:attribute + name="plugin" + type="xs:string" + use="required"> + xs:annotation + xs:documentationPlugin for the specified resource type.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute + name="resourceType" + type="xs:string" + use="required"> + xs:annotation + xs:documentationResource Type that must be in inventory to activate the extension point. + </xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:complexType> + + <xs:element name="position" type="perspective:PositionType"> xs:annotation @@ -727,6 +843,9 @@ <xs:restriction base="xs:string"> <xs:enumeration + value="SUPERUSER"></xs:enumeration> + + <xs:enumeration value="MANAGE_INVENTORY"></xs:enumeration> <xs:enumeration value="MANAGE_SECURITY"></xs:enumeration>
commit 924d6208e06183833873ecaa29a18a6835269667 Merge: 010fa2e... 45b67f2... Author: Adam Young ayoung@redhat.com Date: Wed Dec 2 13:01:24 2009 -0500
Merge branch 'raw-config' of ssh://git.fedorahosted.org/git/rhq/rhq into raw-config
commit 010fa2e49623fe5d793da189aa001c1ee9801aa9 Author: Adam Young ayoung@redhat.com Date: Wed Dec 2 13:01:10 2009 -0500
Cleaned up a handful of places that still referred to the rawConfigCollection and related classes
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit-raw-full.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit-raw-full.xhtml index d5dea5f..7f0fc6c 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit-raw-full.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit-raw-full.xhtml @@ -20,13 +20,13 @@
<h:form id="editResourceConfigurationForm" > <input type="hidden" name="id" value="#{ResourceUIBean.id}" /> -<h:commandLink action="#{rawConfigCollection.update}" > +<h:commandLink action="#{ExistingResourceConfigurationUIBean.update}" > <img src="/images/save.png" alt="#{messages.save}" title="#{messages.save}"/> <f:param name="conversationId" value="#{conversation.id}"/> <f:param name="id" value="#{ResourceUIBean.id}"/> </h:commandLink> <div> -<h:inputTextarea cols="800" rows="600" value="#{rawConfigCollection.currentContents}" /> +<h:inputTextarea cols="800" rows="600" value="#{ExistingResourceConfigurationUIBean.currentContents}" /> </div> </h:form> </ui:define> diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit-raw.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit-raw.xhtml index 060dfc4..e1bc0d3 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit-raw.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit-raw.xhtml @@ -89,7 +89,7 @@ <h:outputText value=" #{messages.upload} " /> <f:param name="id" value="#{ResourceUIBean.id}" /> <f:param name="conversationId" value="#{conversation.id}" /> - </h:outputLink> <s:link action="#{rawConfigDownload.download}"> + </h:outputLink> <s:link action="#{ExistingResourceConfigurationUIBean.download}"> <img src="/images/download.png" /> <h:outputText value=" #{messages.download} " /> <f:param name="id" value="#{ResourceUIBean.id}" /> diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/upload.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/upload.xhtml index 1ebde85..a3736d9 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/upload.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/upload.xhtml @@ -27,7 +27,7 @@ <h:form id="uploadform" enctype="multipart/form-data"> <rich:fileUpload id="upload" - fileUploadListener="#{rawConfigCollection.fileUploadListener}" + fileUploadListener="#{ExistingResourceConfigurationUIBean.fileUploadListener}" maxFilesQuantity="1" noDuplicate="true" immediateUpload="true" @@ -35,13 +35,13 @@ allowFlash="false" maxRequestSize="100000" > - <a4j:support event="onuploadcomplete" action="#{rawConfigCollection.upload}" /> + <a4j:support event="onuploadcomplete" action="#{ExistingResourceConfigurationUIBean.upload}" /> </rich:fileUpload> </h:form> </h:panelGrid> <h:outputLink value="edit-raw.xhtml" action="toEditRaw" > <h:outputText value="#{messages.uploadcomplete}" /> - <f:param name="id" value="#{rawConfigCollection.resourceId}" /> + <f:param name="id" value="#{ExistingResourceConfigurationUIBean.resourceId}" /> </h:outputLink> </rich:panel>
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view-raw-full.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view-raw-full.xhtml index 3867b7b..e9e8c1a 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view-raw-full.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view-raw-full.xhtml @@ -26,7 +26,7 @@ <h:form id="editResourceConfigurationForm" > <input type="hidden" name="id" value="#{ResourceUIBean.id}" /> <div> -<pre><h:outputText value="#{RawConfigViewer.currentContents}" /></pre> +<pre><h:outputText value="#{ExistingResourceConfigurationUIBean.currentContents}" /></pre> </div> </h:form> </ui:define> diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view-raw.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view-raw.xhtml index b0b3002..4823f74 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view-raw.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view-raw.xhtml @@ -68,15 +68,15 @@ <h:panelGroup id="changedFiles" layout="vertical"> <h:form> <input type="hidden" name="id" value="#{ResourceUIBean.id}" /> - <ui:repeat value="#{RawConfigViewer.paths}" var="path"> + <ui:repeat value="#{ExistingResourceConfigurationViewUIBean.paths}" var="path"> <div> <h:commandLink - action="#{RawConfigViewer.select(path)}" + action="#{ExistingResourceConfigurationViewUIBean.select(path)}" value="#{path}" - rendered="#{path != RawConfigViewer.current.path}"> + rendered="#{path != ExistingResourceConfigurationViewUIBean.current.path}"> <f:param name="currentPath" value="#{path}" /> </h:commandLink> - <h:outputText value="#{path}" rendered="#{path == RawConfigViewer.current.path}" /> + <h:outputText value="#{path}" rendered="#{path == ExistingResourceConfigurationViewUIBean.current.path}" /> </div> </ui:repeat> </h:form> @@ -86,20 +86,20 @@ </td> <td> <div> - Current File: <h:outputText value="#{RawConfigViewer.current.path}" + Current File: <h:outputText value="#{ExistingResourceConfigurationViewUIBean.current.path}" styleClass="outhello" /> </div> <h:outputLink value="view-raw-full.xhtml" action="navigateToUpload" > <img src="/images/viewfullscreen.png" /> <h:outputText value=" Full Screen " /> <f:param name="id" value="#{ResourceUIBean.id}" /> - </h:outputLink><s:link action="#{rawConfigDownload.download}"> + </h:outputLink><s:link action="#{ExistingResourceConfigurationViewUIBean.download}"> <img src="/images/download.png" /> <h:outputText value=" Download " /> <f:param name="id" value="#{ResourceUIBean.id}" /> </s:link> <div> - <pre><h:outputText value="#{RawConfigViewer.currentContents}" /></pre> + <pre><h:outputText value="#{ExistingResourceConfigurationViewUIBean.currentContents}" /></pre> </div> </td> </tr> diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml index dd2eded..0d4899f 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml @@ -29,7 +29,7 @@ THIS TEXT WILL BE REMOVED. </h:panelGroup>
<h:outputText value="#{messages.youareviewingstructured}" /> - <h:panelGroup rendered="#{rawConfigCollection.rawSupported}" > + <h:panelGroup rendered="#{ExistingResourceConfigurationUIBean.rawSupported}" > <h:outputText value=" #{messages.switch2}" /> <h:outputLink value="view-raw.xhtml"> <f:param name="id" value="#{ResourceUIBean.id}" /> @@ -48,10 +48,10 @@ THIS TEXT WILL BE REMOVED.
<h:commandButton value="#{messages.editstructured}" action="#{ExistingResourceConfigurationUIBean.editConfiguration}" title="Edit this Configuration" styleClass="buttonmed" - rendered="${ResourceUIBean.permissions.configure and rawConfigCollection.structuredSupported and !ExistingResourceConfigurationUIBean.updateInProgress}" /> + rendered="${ResourceUIBean.permissions.configure and ExistingResourceConfigurationUIBean.structuredSupported and !ExistingResourceConfigurationUIBean.updateInProgress}" /> <h:commandButton value="#{messages.editraw}" action="#{ExistingResourceConfigurationUIBean.editRawConfiguration}" title="Advanced Mode Edit of Raw Configuration Files" styleClass="buttonmed" - rendered="${ResourceUIBean.permissions.configure and rawConfigCollection.rawSupported and !ExistingResourceConfigurationUIBean.updateInProgress}" /> + rendered="${ResourceUIBean.permissions.configure and ExistingResourceConfigurationUIBean.rawSupported and !ExistingResourceConfigurationUIBean.updateInProgress}" /> </h:panelGrid>
<onc:config configurationDefinition="#{ExistingResourceConfigurationUIBean.configurationDefinition}"
commit 45b67f2ee9603e5733624e89baafab163452642e Author: John Sanda john@localhost.localdomain Date: Wed Dec 2 12:08:41 2009 -0500
[US 6] Adding CLI script test to verify that updates for a config that supports structured and raw works
diff --git a/modules/enterprise/remoting/scripts/src/test/script/org/rhq/enterprise/remoting/cli/test_ConfigurationManager.js b/modules/enterprise/remoting/scripts/src/test/script/org/rhq/enterprise/remoting/cli/test_ConfigurationManager.js index 9e9961e..df8e8f7 100644 --- a/modules/enterprise/remoting/scripts/src/test/script/org/rhq/enterprise/remoting/cli/test_ConfigurationManager.js +++ b/modules/enterprise/remoting/scripts/src/test/script/org/rhq/enterprise/remoting/cli/test_ConfigurationManager.js @@ -104,13 +104,66 @@ function testGetAndUpdateStructuredConfiguration() { ); }
+function testGetAndUpdateStructuredandRawConfigurationOnRawEdit() { + var resourceName = 'Structured and Raw Server'; + var structuredAndRawServer = findResourceByNameAndParentName(resourceName, 'localhost'); + + var latestUpdate = loadLatestStructuredAndRawConfigUpdate(resourceName, structuredAndRawServer.id); + + var rawConfig = getRawConfig(resourceName, latestUpdate.configuration, 0); + + var contents = java.lang.String(rawConfig.contents); + var modifiedContents = java.lang.StringBuilder(contents).append("\nModified at ").append(getDate()).toString(); + + rawConfig.contents = modifiedContents.bytes; + + var configUpdate = ConfigurationManager.updateResourceConfiguration(structuredAndRawServer.id, + latestUpdate.configuration, false); + + waitForResourceConfigUpdateToComplete(structuredAndRawServer.id); + + latestpdate = loadLatestStructuredAndRawConfigUpdate(resourceName, structuredAndRawServer.id); + + rawConfigs = java.util.LinkedList(latestUpdate.configuration.rawConfigurations); + rawConfig = rawConfigs.get(0); + var updatedContents = rawConfig.contents; + + Assert.assertEquals( + java.lang.String(updatedContents), + java.lang.String(modifiedContents), + "Failed to update raw config for '" + resourceName + "'" + ); +} + +function testGetAndUpdateStrucuturedOnStructuredEdit() { + var resourceName = 'Structured and Raw Server'; + var structuredAndRawServer = findResourceByNameAndParentName(resourceName, 'localhost'); + + var latestUpdate = loadLatestStructuredAndRawConfigUpdate(resourceName, structuredAndRawServer.id); + var modifiedConfig = latestUpdate.configuration; + + modifiedConfig.put(PropertySimple("x", java.util.Date())); + + ConfigurationManager.updateResourceConfiguration(structuredAndRawServer.id, modifiedConfig, true); + + waitForResourceConfigUpdateToComplete(structuredAndRawServer.id); + + latestUpdate = loadLatestStructuredAndRawConfigUpdate(resourceName, structuredAndRawServer.id); + + Assert.assertEquals( + latestUpdate.configuration.properties, + modifiedConfig.properties, + "Failed to update structured config for '" + resourceName + "'" + ); +} + function loadLatestRawConfigUpdate(resourceName, resourceId) { var latestUpdate = ConfigurationManager.getLatestResourceConfigurationUpdate(resourceId);
Assert.assertNotNull(latestUpdate, "Failed to find latest resource configuration update for '" + resourceName + "'"); Assert.assertTrue( latestUpdate.configuration.rawConfigurations.size() > 0, - "Expected to find at least one raw config file for '" + "'" + "Expected to find at least one raw config file for '" + resourceName + "'" );
return latestUpdate; @@ -123,6 +176,18 @@ function loadLatestStructuredConfigUpdate(resourceName, resourceId) { return latestUpdate; }
+function loadLatestStructuredAndRawConfigUpdate(resourceName, resourceId) { + var latestUpdate = ConfigurationManager.getLatestResourceConfigurationUpdate(resourceId); + + Assert.assertNotNull(latestUpdate, "Failed to find latest resource configuration update for '" + resourceName + "'"); + Assert.assertTrue( + latestUpdate.configuration.rawConfigurations.size() > 0, + "Expected to find at least one raw config file for '" + resourceName + "'" + ) + + return latestUpdate; +} + function getRawConfig(resourceName, configuration, index) { var rawConfigs = java.util.LinkedList(configuration.rawConfigurations); var rawConfig = rawConfigs.get(index); diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerRemote.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerRemote.java index 5c8e49f..85ad927 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerRemote.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerRemote.java @@ -180,6 +180,10 @@ public interface ConfigurationManagerRemote { @XmlJavaTypeAdapter(ConfigurationAdapter.class) Configuration newConfiguration) throws ResourceNotFoundException, ConfigurationUpdateStillInProgressException;
+ ResourceConfigurationUpdate updateResourceConfiguration(Subject subject, int resourceId, + Configuration newConfiguration, boolean fromStructured) + throws ResourceNotFoundException, ConfigurationUpdateStillInProgressException; + /** * Get the currently live resource configuration for the {@link Resource} with the given id. This actually asks for * the up-to-date configuration directly from the agent. An exception will be thrown if communications with the diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/webservices/WebservicesManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/webservices/WebservicesManagerBean.java index 8587e51..e8af8f9 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/webservices/WebservicesManagerBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/webservices/WebservicesManagerBean.java @@ -370,6 +370,12 @@ public class WebservicesManagerBean implements WebservicesRemote { return configurationManager.updateResourceConfiguration(subject, resourceId, newConfiguration); }
+ public ResourceConfigurationUpdate updateResourceConfiguration(Subject subject, int resourceId, + Configuration newConfiguration, boolean fromStructured) + throws ResourceNotFoundException, ConfigurationUpdateStillInProgressException { + return configurationManager.updateResourceConfiguration(subject, resourceId, newConfiguration, fromStructured); + } + public ConfigurationDefinition getPackageTypeConfigurationDefinition(Subject subject, int packageTypeId) { return configurationManager.getPackageTypeConfigurationDefinition(subject, packageTypeId); }
commit 8d962f6e402b390c88aec6ef3d24043aa875c85d Author: Heiko W. Rupp pilhuhn@fedorapeople.org Date: Wed Dec 2 16:41:20 2009 +0100
Re-order, as they are not shared with the remote.
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerLocal.java index 17615ea..a3d8ee5 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerLocal.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerLocal.java @@ -80,14 +80,6 @@ public interface AlertManagerLocal {
Map<Integer, Integer> getAlertCountForSchedules(long begin, long end, List<Integer> scheduleIds);
- // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - // - // The following are shared with the Remote Interface - // - // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - - PageList<Alert> findAlertsByCriteria(Subject subject, AlertCriteria criteria); - /** * Mark the matching alert as acknowledged by the user * @param alertId Id of the alert to acknowledge @@ -114,4 +106,13 @@ public interface AlertManagerLocal { * @return true if the definition got disabled */ boolean willDefinitionBeDisabled(Alert alert); + + // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + // + // The following are shared with the Remote Interface + // + // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + + PageList<Alert> findAlertsByCriteria(Subject subject, AlertCriteria criteria); + } \ No newline at end of file
commit 23f332d3636cb3e37ad022acd832e7040ef6971d Author: John Sanda john@localhost.localdomain Date: Wed Dec 2 09:45:24 2009 -0500
Fixing copy/paste error
diff --git a/modules/enterprise/server/jar/pom.xml b/modules/enterprise/server/jar/pom.xml index 4914e77..e960104 100644 --- a/modules/enterprise/server/jar/pom.xml +++ b/modules/enterprise/server/jar/pom.xml @@ -356,12 +356,6 @@ </dependency>
<dependency> - <groupId>com.redhat.rhn</groupId> - <artifactId>rhn-common</artifactId> - <version>1.0-SNAPSHOT</version> - </dependency> - - <dependency> <groupId>${groupId}</groupId> <artifactId>test-utils</artifactId> <version>${version}</version>
commit af6cd35a3db12035c2873745fbb2f8a41454099d Author: Heiko W. Rupp pilhuhn@fedorapeople.org Date: Wed Dec 2 15:27:41 2009 +0100
Implement some "deferred emailing" - senders can create email addresses, that alert info gets sent to.
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerBean.java index 615b1f5..940262a 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerBean.java @@ -25,6 +25,7 @@ import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.Date; import java.util.HashMap; +import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; @@ -90,6 +91,7 @@ import org.rhq.enterprise.server.plugin.pc.MasterServerPluginContainer; import org.rhq.enterprise.server.plugin.pc.alert.AlertSender; import org.rhq.enterprise.server.plugin.pc.alert.AlertSenderPluginManager; import org.rhq.enterprise.server.plugin.pc.alert.AlertServerPluginContainer; +import org.rhq.enterprise.server.plugin.pc.alert.ResultState; import org.rhq.enterprise.server.plugin.pc.alert.SenderResult; import org.rhq.enterprise.server.resource.ResourceManagerLocal; import org.rhq.enterprise.server.system.SystemManagerLocal; @@ -672,6 +674,10 @@ public class AlertManagerBean implements AlertManagerLocal, AlertManagerRemote { if (sender!=null) { try { SenderResult result = sender.send(alert); + if (result.getState() == ResultState.SUCCESS) { + if (result.getEmails()!=null && !result.getEmails().isEmpty()) + emailAddresses.addAll(result.getEmails()); + } // TODO log result } catch (Throwable t) { diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSender.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSender.java index 4acf335..f43173a 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSender.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSender.java @@ -47,6 +47,11 @@ public abstract class AlertSender { /** * This method is called to actually send an alert notification. * This is where you implement all functionality. + * + * The return value is a SenderResult object, which encodes a log message, + * success or failure and can contain email addresses that got computed by + * your AlertSender and which will be sent by the system after *all* senders + * have been run. * @param alert the Alert to operate on * @return result of sending - a ResultState and a message for auditing */ diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/ResultState.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/ResultState.java index 8133ba9..8ce8c7d 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/ResultState.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/ResultState.java @@ -24,6 +24,8 @@ package org.rhq.enterprise.server.plugin.pc.alert; * @see SenderResult */ public enum ResultState { + /** Success */ SUCCESS, - FAILURE; + /** Failure */ + FAILURE } diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/SenderResult.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/SenderResult.java index b5a49a1..c42248d 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/SenderResult.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/SenderResult.java @@ -18,6 +18,9 @@ */ package org.rhq.enterprise.server.plugin.pc.alert;
+import java.util.ArrayList; +import java.util.List; + import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory;
@@ -27,8 +30,12 @@ import org.apache.commons.logging.LogFactory; */ public class SenderResult {
+ /** Message returned for logging purposes */ private String message; + /** Was calling the AlertSender.send() method successful? */ private ResultState state; + /** A list of email addresses that should be notified */ + private List<String> emails = new ArrayList<String>();
public SenderResult(ResultState state, String message) { this.message = message; @@ -51,12 +58,25 @@ public class SenderResult { this.state = state; }
+ public List<String> getEmails() { + return emails; + } + + public void setEmails(List<String> emails) { + this.emails = emails; + } + + public void addEmail(String email) { + emails.add(email); + } + @Override public String toString() { final StringBuilder sb = new StringBuilder(); sb.append("SenderResult"); sb.append("{message='").append(message).append('''); sb.append(", state=").append(state); + sb.append(", emails=").append(emails); sb.append('}'); return sb.toString(); }
commit a96fe7f06472c46cbbf2b5077f6d9af7d5c683db Author: John Sanda john@localhost.localdomain Date: Wed Dec 2 08:43:01 2009 -0500
[US 6] Adding support for updating a resource config that supports structured and raw.
Adding unit tests to cover more cases and modifying the raw-config-test plugin so that StructuredAndRawServer now supports update behavior.
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java index 4bcb2ab..81fada8 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java @@ -63,6 +63,7 @@ import org.rhq.core.domain.configuration.RawConfiguration; import org.rhq.core.domain.configuration.ResourceConfigurationUpdate; import org.rhq.core.domain.configuration.composite.ConfigurationUpdateComposite; import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; +import org.rhq.core.domain.configuration.definition.ConfigurationFormat; import org.rhq.core.domain.configuration.group.AbstractGroupConfigurationUpdate; import org.rhq.core.domain.configuration.group.GroupPluginConfigurationUpdate; import org.rhq.core.domain.configuration.group.GroupResourceConfigurationUpdate; @@ -990,11 +991,15 @@ public class ConfigurationManagerBean implements ConfigurationManagerLocal, Conf Configuration newConfiguration, boolean fromStructured) throws ResourceNotFoundException, ConfigurationUpdateStillInProgressException {
- Configuration translatedConfig = translateResourceConfiguration(subject, resourceId, newConfiguration, + Configuration configToUpdate = newConfiguration; + + if (isStructuredAndRawSupported(resourceId)) { + configToUpdate = translateResourceConfiguration(subject, resourceId, newConfiguration, fromStructured); + }
ResourceConfigurationUpdate newUpdate = - configurationManager.persistNewResourceConfigurationUpdateHistory(subject, resourceId, translatedConfig, + configurationManager.persistNewResourceConfigurationUpdateHistory(subject, resourceId, configToUpdate, ConfigurationUpdateStatus.INPROGRESS, subject.getName(), false);
executeResourceConfigurationUpdate(newUpdate, fromStructured); @@ -1002,6 +1007,13 @@ public class ConfigurationManagerBean implements ConfigurationManagerLocal, Conf return newUpdate; }
+ private boolean isStructuredAndRawSupported(int resourceId) { + Resource resource = entityManager.find(Resource.class, resourceId); + ConfigurationDefinition configDef = resource.getResourceType().getResourceConfigurationDefinition(); + + return ConfigurationFormat.STRUCTURED_AND_RAW == configDef.getConfigurationFormat(); + } + @Nullable public ResourceConfigurationUpdate updateResourceConfiguration(Subject subject, int resourceId, @XmlJavaTypeAdapter(ConfigurationAdapter.class) Configuration newConfiguration) diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBeanUnitTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBeanUnitTest.java index f43f89a..5091edb 100644 --- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBeanUnitTest.java +++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBeanUnitTest.java @@ -34,8 +34,11 @@ import org.rhq.core.domain.configuration.Configuration; import org.rhq.core.domain.configuration.ResourceConfigurationUpdate; import org.rhq.core.domain.configuration.RawConfiguration; import org.rhq.core.domain.configuration.PropertySimple; +import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; +import org.rhq.core.domain.configuration.definition.ConfigurationFormat; import org.rhq.core.domain.resource.Resource; import org.rhq.core.domain.resource.Agent; +import org.rhq.core.domain.resource.ResourceType; import org.rhq.core.clientapi.agent.configuration.ConfigurationAgentService; import org.rhq.core.clientapi.agent.configuration.ConfigurationUpdateRequest; import org.rhq.enterprise.server.core.AgentManagerLocal; @@ -154,6 +157,7 @@ public class ConfigurationManagerBeanUnitTest extends JMockTest { translatedConfig.addRawConfiguration(new RawConfiguration());
final Resource resource = new Resource(resourceId); + resource.setResourceType(createStructuredAndRaw()); resource.setAgent(new Agent("test-agent", "localhost", 7080, null, null));
final ResourceConfigurationUpdate expectedUpdate = new ResourceConfigurationUpdate(resource, translatedConfig, @@ -196,6 +200,51 @@ public class ConfigurationManagerBeanUnitTest extends JMockTest { }
@Test + public void updateResourceConfigShouldNotTranslateStructuredWhenRawNotSupported() throws Exception { + final Subject subject = new Subject("rhqadmin", true, true); + final int resourceId = -1; + final Configuration newConfig = new Configuration(); + final boolean isPartOfGroupUpdate = false; + + final Resource resource = new Resource(resourceId); + resource.setAgent(new Agent("test-agent", "localhost", 7080, null, null)); + resource.setResourceType(createStructurerdOnly()); + + final ResourceConfigurationUpdate expectedUpdate = new ResourceConfigurationUpdate(resource, newConfig, + subject.getName()); + expectedUpdate.setId(-1); + + final AgentClient agentClient = context.mock(AgentClient.class); + final ConfigurationAgentService configAgentService = context.mock(ConfigurationAgentService.class); + + final ConfigurationUpdateRequest expectedUpdateRequest = new ConfigurationUpdateRequest(expectedUpdate.getId(), + expectedUpdate.getConfiguration(), expectedUpdate.getResource().getId()); + + final Sequence configUdpate = context.sequence("structured-config-update"); + + context.checking(new Expectations() {{ + allowing(entityMgr).find(Resource.class, resourceId); will(returnValue(resource)); + + oneOf(configurationMgrLocal).persistNewResourceConfigurationUpdateHistory(subject, resourceId, newConfig, + INPROGRESS, subject.getName(), isPartOfGroupUpdate); + will(returnValue(expectedUpdate)); + inSequence(configUdpate); + + allowing(agentMgr).getAgentClient(expectedUpdate.getResource().getAgent()); will(returnValue(agentClient)); + + allowing(agentClient).getConfigurationAgentService(); will(returnValue(configAgentService)); + + oneOf(configAgentService).updateResourceConfiguration(with(matchingUpdateRequest(expectedUpdateRequest))); + inSequence(configUdpate); + }}); + + ResourceConfigurationUpdate actualUpdate = configurationMgr.updateResourceConfiguration(subject, resourceId, + newConfig, FROM_STRUCTURED); + + assertSame(actualUpdate, expectedUpdate, "Expected to get back the persisted configuration update"); + } + + @Test public void updateResourceConfigShouldTranslateRawWhenRawConfigHasEdits() throws Exception { final Subject subject = new Subject("rhqadmin", true, true); final int resourceId = -1; @@ -207,6 +256,7 @@ public class ConfigurationManagerBeanUnitTest extends JMockTest { translatedConfig.put(new PropertySimple("x", "y"));
final Resource resource = new Resource(resourceId); + resource.setResourceType(createStructuredAndRaw()); resource.setAgent(new Agent("test-agent", "localhost", 7080, null, null));
final ResourceConfigurationUpdate expectedUpdate = new ResourceConfigurationUpdate(resource, translatedConfig, @@ -287,4 +337,24 @@ public class ConfigurationManagerBeanUnitTest extends JMockTest { return new PropertyMatcher<ConfigurationUpdateRequest>(expected); }
+ ResourceType createStructuredAndRaw() { + ConfigurationDefinition configDef = new ConfigurationDefinition("structured-and-raw", "structured and raw"); + configDef.setConfigurationFormat(ConfigurationFormat.STRUCTURED_AND_RAW); + + ResourceType resourceType = new ResourceType(); + resourceType.setResourceConfigurationDefinition(configDef); + + return resourceType; + } + + ResourceType createStructurerdOnly() { + ConfigurationDefinition configDef = new ConfigurationDefinition("structred-config-def", "structured config def"); + configDef.setConfigurationFormat(ConfigurationFormat.STRUCTURED); + + ResourceType resourceType = new ResourceType(); + resourceType.setResourceConfigurationDefinition(configDef); + + return resourceType; + } + } diff --git a/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/StructuredAndRawServer.groovy b/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/StructuredAndRawServer.groovy index 43b421d..5e19aee 100644 --- a/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/StructuredAndRawServer.groovy +++ b/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/StructuredAndRawServer.groovy @@ -8,6 +8,7 @@ import org.rhq.core.domain.configuration.Configuration import org.rhq.core.domain.configuration.RawConfiguration import org.rhq.core.domain.configuration.PropertySimple import org.apache.commons.configuration.PropertiesConfiguration +import groovy.util.AntBuilder
class StructuredAndRawServer implements ResourceComponent, ResourceConfigurationFacet {
@@ -19,6 +20,8 @@ class StructuredAndRawServer implements ResourceComponent, ResourceConfiguration
File rawConfig3
+ def ant = new AntBuilder() + void start(ResourceContext context) { rawConfigDir = new File("${System.getProperty('java.io.tmpdir')}/raw-config-test") rawConfig1 = new File(rawConfigDir, "structured-and-raw-test-1.txt") @@ -153,7 +156,13 @@ class StructuredAndRawServer implements ResourceComponent, ResourceConfiguration void persistStructuredConfiguration(Configuration config) { }
- void persistRawConfiguration(RawConfiguration rawConfig) { + void persistRawConfiguration(RawConfiguration rawConfig) { + ant.copy(file: rawConfig.path, tofile: "${rawConfig.path}.orig") + ant.delete(file: rawConfig.path) + + def file = new File(rawConfig.path) + file.createNewFile() + file << rawConfig.contents }
} \ No newline at end of file
commit b0ec2023c902336e7e9cbd7e715646719ac34410 Author: Heiko W. Rupp pilhuhn@fedorapeople.org Date: Wed Dec 2 11:11:19 2009 +0100
Follow the changes from master
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSenderPluginManager.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSenderPluginManager.java index cb92a91..54cc203 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSenderPluginManager.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSenderPluginManager.java @@ -69,8 +69,8 @@ public class AlertSenderPluginManager extends ServerPluginManager { * @throws Exception */ @Override - public void loadPlugin(ServerPluginEnvironment env) throws Exception { - super.loadPlugin(env); + public void loadPlugin(ServerPluginEnvironment env,boolean enable) throws Exception { + super.loadPlugin(env,enable);
AlertPluginDescriptorType type = (AlertPluginDescriptorType) env.getPluginDescriptor();
@@ -84,7 +84,7 @@ public class AlertSenderPluginManager extends ServerPluginManager { catch (Exception e) { log.warn("Can't find pluginClass " + className + ". Plugin will be ignored"); try { - unloadPlugin(env); + unloadPlugin(env.getPluginKey().getPluginName()); } catch (Throwable t) { log.warn(" +--> unload failed too " + t.getMessage());
commit c5d06edf5fc302d7921c993492ff10f0e1946560 Merge: 81bfb7f... c146853... Author: Heiko W. Rupp pilhuhn@fedorapeople.org Date: Wed Dec 2 10:48:22 2009 +0100
Merge branch 'master' into alertPlugin
diff --cc modules/core/domain/src/main/java/org/rhq/core/domain/plugin/ServerPlugin.java index aa06ea9,714872e..a01a40a --- a/modules/core/domain/src/main/java/org/rhq/core/domain/plugin/ServerPlugin.java +++ b/modules/core/domain/src/main/java/org/rhq/core/domain/plugin/ServerPlugin.java @@@ -36,7 -36,7 +36,7 @@@ import org.rhq.core.domain.configuratio
/** * A server plugin. -- * ++ * * This object contains information about the plugin jar itself (e.g. its name and MD5). * It may also contain the jar contents ({@link #getContent()}). */ @@@ -56,7 -56,7 +56,7 @@@ + " p.type, " // + " p.name) " // + " FROM ServerPlugin AS p " // -- + " WHERE p.enabled = :enabled " // ++ + " WHERE p.enabled = :enabled " // + " AND p.status = 'INSTALLED' "), //
// this query does not load the content blob, but loads everything else @@@ -78,9 -78,9 +78,9 @@@ + " p.type, " // + " p.ctime, " // + " p.mtime) " // -- + " FROM ServerPlugin AS p " // -- + " LEFT JOIN p.pluginConfiguration " // -- + " LEFT JOIN p.scheduledJobsConfiguration " // ++ + " FROM ServerPlugin AS p " // ++ + " LEFT JOIN p.pluginConfiguration " // ++ + " LEFT JOIN p.scheduledJobsConfiguration " // + " WHERE p.id IN (:ids) " // + " AND p.status = 'INSTALLED' "), //
@@@ -103,9 -103,9 +103,9 @@@ + " p.type, " // + " p.ctime, " // + " p.mtime) " // -- + " FROM ServerPlugin AS p " // -- + " LEFT JOIN p.pluginConfiguration " // -- + " LEFT JOIN p.scheduledJobsConfiguration " // ++ + " FROM ServerPlugin AS p " // ++ + " LEFT JOIN p.pluginConfiguration " // ++ + " LEFT JOIN p.scheduledJobsConfiguration " // + " WHERE p.name=:name " // + " AND p.status = 'INSTALLED' "), //
@@@ -129,9 -129,9 +129,9 @@@ + " p.type, " // + " p.ctime, " // + " p.mtime) " // -- + " FROM ServerPlugin AS p " // -- + " LEFT JOIN p.pluginConfiguration " // -- + " LEFT JOIN p.scheduledJobsConfiguration " // ++ + " FROM ServerPlugin AS p " // ++ + " LEFT JOIN p.pluginConfiguration " // ++ + " LEFT JOIN p.scheduledJobsConfiguration " // + " WHERE p.name=:name "), //
// finds all installed - ignores those plugins marked as deleted @@@ -155,7 -155,7 +155,7 @@@ + " p.ctime, " // + " p.mtime) " // + " FROM ServerPlugin AS p " // -- + " LEFT JOIN p.pluginConfiguration " // ++ + " LEFT JOIN p.pluginConfiguration " // + " LEFT JOIN p.scheduledJobsConfiguration " // + " WHERE p.status = 'INSTALLED' "), //
@@@ -231,7 -254,7 +254,7 @@@ public class ServerPlugin extends Abstr
/** * If the plugin, itself, has configuration associated with it, this is that configuration. -- * ++ * * @return the configuration associated with the plugin itself */ public Configuration getPluginConfiguration() { @@@ -244,7 -267,7 +267,7 @@@
/** * If the plugin has jobs associated with it, this is the configuration for those jobs. -- * ++ * * @return scheduled job configuration for jobs that the plugin defined. */ public Configuration getScheduledJobsConfiguration() { @@@ -257,8 -280,8 +280,8 @@@
/** * Plugin type string. -- * -- * @return plugin type ++ * ++ * @return plugin type */ public String getType() { return this.type; diff --cc modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-details.xhtml index 6b29013,5bb4b2a..0268277 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-details.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-details.xhtml @@@ -15,9 -15,9 +15,9 @@@ <h:outputLink value="plugin-list.xhtml" > <h:outputText value="Installed Plugins"/> </h:outputLink> - > + > <h:outputLink value="#" > - <h:outputText value="#{InstalledPluginUIBean.plugin.displayName}"/> + <h:outputText value="#{plugin.displayName}"/> </h:outputLink>
</ui:define> @@@ -45,62 -45,43 +45,45 @@@ <h:panelGrid styleClass="BlockContent" columns="4" width="100%">
<h:outputLabel styleClass="BlockLabel" value="Version:"/> - <h:outputText styleClass="BlockContent" value="#{InstalledPluginUIBean.plugin.version}"/> + <h:outputText styleClass="BlockContent" value="#{plugin.version}"/>
<h:outputLabel styleClass="BlockLabel" value="Enabled:"/> - <h:outputText value="#{InstalledPluginUIBean.plugin.enabled}"/> + <h:outputText value="#{plugin.enabled}"/>
<h:outputLabel styleClass="BlockLabel" value="Type:"/> - <h:outputText value="#{InstalledPluginUIBean.plugin.deployment}"/> + <h:outputText value="#{plugin.deployment}"/>
<h:outputLabel styleClass="BlockLabel" value="MD5:"/> - <h:outputText value="#{InstalledPluginUIBean.plugin.md5}"/> + <h:outputText value="#{plugin.md5}"/>
<h:outputLabel styleClass="BlockLabel" value="Description:"/> - <h:outputText value="#{InstalledPluginUIBean.plugin.description}"/> + <h:outputText value="#{plugin.description}"/>
<h:outputLabel styleClass="BlockLabel" value="Path:"/> - <h:outputText value="#{InstalledPluginUIBean.plugin.path}"/> - + <h:outputText value="#{plugin.path}"/> </h:panelGrid>
+ <br /> + <h:outputLink value="/rhq/admin/plugin/plugin-config.xhtml" rendered="#{plugin.deployment eq 'SERVER'}"> + <f:param name="pluginName" value="#{plugin.name}"/> + <h:outputText value="Configure '#{plugin.displayName}'"/> + </h:outputLink> + <br /> + <br /> - ++ rich:panel <f:facet name="header"> <h:outputText value="Plugin Help"/> </f:facet>
- <h:outputText escape="false" value="<pre> #{InstalledPluginUIBean.plugin.help} </pre>"/> - - </rich:panel> + <h:outputText escape="false" value="<pre> #{plugin.help} </pre>"/>
- <ui:insert name="pre-config" /> - - <rich:panel rendered="#{InstalledPluginUIBean.pluginConfigurationDefinition != null}"> - <f:facet name="header"> - <h:outputText value="Plugin Configuration"/> - </f:facet> - <onc:config - configurationDefinition="#{InstalledPluginUIBean.pluginConfigurationDefinition}" - configuration="#{InstalledPluginUIBean.plugin.pluginConfiguration}" - readOnly="#{not editMode}" /> - </rich:panel> - - <rich:panel rendered="#{InstalledPluginUIBean.scheduledJobsDefinition != null}"> - <f:facet name="header"> - <h:outputText value="Scheduled Jobs"/> - </f:facet> - <onc:config - configurationDefinition="#{InstalledPluginUIBean.scheduledJobsDefinition}" - configuration="#{InstalledPluginUIBean.plugin.scheduledJobsConfiguration}" - readOnly="#{not editMode}" /> </rich:panel> + + <ui:insert name="post-config" /> </rich:panel> - </h:form>
- </ui:define>
</ui:composition> diff --cc modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsLocal.java index 1820fcc,d21e36a..522dfa1 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsLocal.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsLocal.java @@@ -178,11 -179,9 +179,9 @@@ public interface ServerPluginsLocal PluginStatusType getServerPluginStatus(PluginKey pluginKey);
/** - * This will return a map containing all plugins currently known to the master plugin container. - * This will return installed plugins that are both enabled and disabled. - * Note that if the master plugin container is not running, an empty map is returned. + * This will return a map containing all installed plugins that are both enabled and disabled. - * - * @return keys of all enabled and disabled plugins, keyed on their types + * + * @return keys of all enabled and disabled plugins, keyed on their types */ - Map<ServerPluginType, List<PluginKey>> getAllPluginsGroupedByType(); + Map<ServerPluginType, List<PluginKey>> getInstalledServerPluginsGroupedByType(); } diff --cc modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/AbstractTypeServerPluginContainer.java index 3301dcc,fcebe55..3bbcdfc --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/AbstractTypeServerPluginContainer.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/AbstractTypeServerPluginContainer.java @@@ -36,7 -36,7 +36,7 @@@ import org.rhq.enterprise.server.xmlsch
/** * The abstract superclass for all plugin containers of the different {@link ServerPluginType plugin types}. -- * ++ * * @author John Mazzitelli */ public abstract class AbstractTypeServerPluginContainer { @@@ -49,7 -49,7 +49,7 @@@ /** * Instantiates the plugin container. All subclasses must support this and only this * constructor. -- * ++ * * @param master the master plugin container that is creating this instance. */ public AbstractTypeServerPluginContainer(MasterServerPluginContainer master) { @@@ -60,14 -60,14 +60,14 @@@ * Each plugin container will tell the master which plugins it can support via this method; this * method returns the type of plugin that the plugin container can process. Only one * plugin container can support a plugin type. -- * ++ * * @return the type of plugin that this plugin container instance can support */ public abstract ServerPluginType getSupportedServerPluginType();
/** * Returns the master plugin container that is responsible for managing this instance. -- * ++ * * @return this plugin container's master */ public MasterServerPluginContainer getMasterServerPluginContainer() { @@@ -76,7 -76,7 +76,7 @@@
/** * Returns the object that manages the plugins. -- * ++ * * @return the plugin manager for this container */ public ServerPluginManager getPluginManager() { @@@ -86,7 -86,7 +86,7 @@@ /** * The initialize method that prepares the plugin container. This should get the plugin * container ready to accept plugins. -- * ++ * * Subclasses are free to perform additional tasks by overriding this method. * * @throws Exception if the plugin container failed to initialize for some reason @@@ -120,7 -120,7 +120,7 @@@
/** * The shutdown method that will stop and unload all plugins. -- * ++ * * Subclasses are free to perform additional tasks by overriding this method. */ public synchronized void shutdown() { @@@ -147,15 -147,17 +147,17 @@@ }
/** - * Informs the plugin container that it has a plugin that it must being to start managing. - * + * Informs the plugin container that it has a plugin that it must begin to start managing. - * ++ * * @param env the plugin environment, including the plugin jar and its descriptor + * @param enabled <code>true</code> if the plugin should be initialized; <code>false</code> if + * the plugin's existence should be noted but it should not be initialized or started * -- * @throws Exception if failed to load the plugin ++ * @throws Exception if failed to load the plugin */ - public synchronized void loadPlugin(ServerPluginEnvironment env) throws Exception { + public synchronized void loadPlugin(ServerPluginEnvironment env, boolean enabled) throws Exception { if (this.pluginManager != null) { - this.pluginManager.loadPlugin(env); + this.pluginManager.loadPlugin(env, enabled); } else { throw new Exception("Cannot load a plugin; plugin container is not initialized yet"); } @@@ -164,57 -166,91 +166,91 @@@ /** * Informs the plugin container that a plugin should be unloaded and any of its resources * should be released. -- * - * @param env the plugin environment, including the plugin jar and its descriptor + * - * @throws Exception if failed to unload the plugin + * @param pluginKey identifies the plugin that should be shutdown + * - * @throws Exception if failed to unload the plugin ++ * @throws Exception if failed to unload the plugin */ - public synchronized void unloadPlugin(ServerPluginEnvironment env) throws Exception { + public synchronized void unloadPlugin(PluginKey pluginKey) throws Exception { if (this.pluginManager != null) { - this.pluginManager.unloadPlugin(env); + this.pluginManager.unloadPlugin(pluginKey.getPluginName()); } else { throw new Exception("Cannot unload a plugin; plugin container has been shutdown"); } }
/** + * Informs the plugin container that a plugin should be reloaded and any of its resources + * should be started if being enabled. - * ++ * + * @param pluginKey identifies the plugin that should be reloaded + * @param enabled indicates if the plugin should be enabled or disabled after being loaded + * - * @throws Exception if failed to unload the plugin ++ * @throws Exception if failed to unload the plugin + */ + public synchronized void reloadPlugin(PluginKey pluginKey, boolean enabled) throws Exception { + if (this.pluginManager != null) { + this.pluginManager.reloadPlugin(pluginKey.getPluginName(), enabled); + } else { + throw new Exception("Cannot reload a plugin; plugin container has been shutdown"); + } + } + + /** * If a plugin has scheduled jobs, this method will schedule them now. * This particular method implementation schedules the global jobs as defined in the * plugin descriptors. -- * ++ * * Subclasses are free to extend this method to schedule additional plugin jobs, but must * ensure they call this method so the global scheduled jobs get added to the scheduler. -- * ++ * * Note that this is separate from the {@link #start()} method because it is possible that * the plugin container has been started before the scheduler has. In this case, the caller * must wait for the scheduler to be started before this method is called to schedule jobs. -- * ++ * * @throws Exception if failed to schedule jobs */ - public synchronized void schedulePluginJobs() throws Exception { + public synchronized void scheduleAllPluginJobs() throws Exception { if (this.pluginManager != null) { - // process all known plugins and schedule their jobs - List<ScheduledJobDefinition> jobs; for (ServerPluginEnvironment pluginEnv : this.pluginManager.getPluginEnvironments()) { - String pluginName = pluginEnv.getPluginKey().getPluginName(); + schedulePluginJobs(pluginEnv.getPluginKey()); + } + } else { + throw new Exception("Cannot schedule plugins jobs; plugin container is not initialized yet"); + }
- try { - jobs = this.pluginManager.getServerPluginContext(pluginEnv).getSchedules(); - if (jobs != null) { - for (ScheduledJobDefinition job : jobs) { - try { - scheduleJob(job, pluginEnv.getPluginKey()); - } catch (Throwable t) { - log.warn("Failed to schedule job [" + job + "] for plugin [" + pluginName + "]", t); + return; + } + + public synchronized void schedulePluginJobs(PluginKey pluginKey) throws Exception { + if (this.pluginManager != null) { + try { + String pluginName = pluginKey.getPluginName(); + if (this.pluginManager.isPluginEnabled(pluginName)) { + ServerPluginEnvironment pluginEnv = this.pluginManager.getPluginEnvironment(pluginName); + if (pluginEnv != null) { + ServerPluginContext serverPluginContext = this.pluginManager.getServerPluginContext(pluginEnv); + List<ScheduledJobDefinition> jobs = serverPluginContext.getSchedules(); + if (jobs != null) { + for (ScheduledJobDefinition job : jobs) { + try { + scheduleJob(job, pluginKey); + } catch (Throwable t) { + log.warn("Failed to schedule job [" + job + "] for server plugin [" + pluginKey + + "]", t); + } } } + } else { + log.warn("Failed to get server plugin env for [" + pluginKey + "]; cannot schedule jobs"); } - } catch (Throwable t) { - log.warn("Failed to get scheduled jobs for plugin [" + pluginName + "]", t); } + } catch (Throwable t) { + log.warn("Failed to get scheduled jobs for server plugin [" + pluginKey + "]", t); } } else { - throw new Exception("Cannot schedule plugins jobs; plugin container is not initialized yet"); + throw new Exception("Cannot schedule plugins jobs for server plugin [" + pluginKey + + "]; plugin container is not initialized yet"); }
return; @@@ -222,16 -258,16 +258,16 @@@
/** * Unschedules any plugin jobs that are currently scheduled for the named plugin. -- * ++ * * Subclasses are free to extend this method to unschedule those additional plugin jobs * they created, but must ensure they call this method so the global scheduled jobs get * removed from the scheduler. -- * ++ * * Note that this is separate from the {@link #stop()} method because we never want * to unschedule jobs since other plugin containers on other servers may be running * and able to process the jobs. This method should only be called when a plugin * is being disabled or removed. -- * ++ * * @param pluginKey * @throws Exception if failed to unschedule jobs */ @@@ -258,7 -294,7 +294,7 @@@ /** * This will be called when its time for this plugin container to create its plugin manager. * Subclasses are free to override this if they need their own specialized plugin manager. -- * ++ * * @return the plugin manager for use by this plugin container */ protected ServerPluginManager createPluginManager() { @@@ -268,7 -304,7 +304,7 @@@ /** * Returns the logger that can be used to log messages. A convienence object so all * subclasses don't have to explicitly declare and create their own. -- * ++ * * @return this instance's logger object */ protected Log getLog() { @@@ -278,7 -314,7 +314,7 @@@ /** * Schedules a job for periodic execution. Note that if the <code>schedule</code> indicates the * job is not enabled, this method returns immediately as a no-op. -- * ++ * * @param schedule instructs how the job should be scheduled * @param pluginKey the key of the plugin scheduling the job * diff --cc modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/MasterServerPluginContainer.java index fc54bb2,d19ee2a..0c395e4 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/MasterServerPluginContainer.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/MasterServerPluginContainer.java @@@ -344,12 -303,14 +311,14 @@@ public class MasterServerPluginContaine }
/** - * Given a plugin's descriptor, this will return the plugin container that can manage the plugin. + * Given a server plugin type, this will return the plugin container that can manage that type of plugin. + * If the server plugin type is unknown to the master, or if the master plugin is not started, this will + * return <code>null</code>. - * + * - * @param descriptor descriptor to identify a plugin whose container is to be returned - * @return a plugin container that can handle the plugin with the given descriptor + * @param pluginType the type of server plugin whose PC is to be returned + * @return a plugin container that can handle the given type of server plugin */ - protected synchronized AbstractTypeServerPluginContainer getPluginContainerByPluginType(ServerPluginType pluginType) { + public synchronized AbstractTypeServerPluginContainer getPluginContainerByPluginType(ServerPluginType pluginType) { AbstractTypeServerPluginContainer pc = this.pluginContainers.get(pluginType); return pc; } @@@ -371,9 -332,9 +340,9 @@@ /** * Finds all plugins and parses their descriptors. This is only called during * this master plugin container's {@link #initialize(MasterServerPluginContainerConfiguration) initialization}. - * + * - * If a plugin fails to load, it will be ignored - other plugins will still load. + * If a plugin fails to preload, it will be ignored - other plugins will still preload. - * + * * @return a map of plugins, keyed on the plugin jar URL whose values are the parsed descriptors * * @throws Exception on catastrophic failure. Note that if a plugin failed to load, @@@ -434,11 -376,11 +384,11 @@@ /** * This will return a list of plugin keys that represent all the plugins that are to be * disabled. If a plugin jar is found on the filesystem, its plugin key should be checked with - * this "blacklist" - if its key is found, that plugin should not be loaded. + * this "blacklist" - if its key is found, that plugin should be disabled. - * + * - * @return names of "blacklisted" plugins that should not be loaded + * @return names of "blacklisted" plugins that should not be started (i.e. loaded as a disabled plugin) */ - protected List<PluginKey> getDisabledPluginNames() { + protected List<PluginKey> getDisabledPluginKeys() { List<PluginKey> disabledPlugins = LookupUtil.getServerPlugins().getServerPluginKeysByEnabled(false); return disabledPlugins; } diff --cc modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginManager.java index 87f2575,769db26..38cde29 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginManager.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginManager.java @@@ -40,7 -43,11 +43,11 @@@ import org.rhq.enterprise.server.xmlsch /** * Provides functionality to manage plugins for a plugin container. Plugin containers * can install their own plugin managers that are extensions to this class if they need to. -- * ++ * + * Most of the methods here are protected; they are meant for the plugin container's use only. + * Usually, anything an external client needs will be done through a delegation method + * found on the plugin container. - * ++ * * @author John Mazzitelli */ //TODO: need a R/W lock to make this class thread safe @@@ -69,7 -81,7 +81,7 @@@ public class ServerPluginManager
/** * Creates a plugin manager for the given plugin container. -- * ++ * * @param pc the plugin manager's owning plugin container */ public ServerPluginManager(AbstractTypeServerPluginContainer pc) { @@@ -77,14 -89,47 +89,47 @@@ this.loadedPlugins = new HashMap<String, ServerPluginEnvironment>(); this.pluginContextCache = new HashMap<String, ServerPluginContext>(); this.pluginComponentCache = new HashMap<String, ServerPluginComponent>(); + this.enabledPlugins = new HashMap<String, Boolean>(); + } + + /** + * Returns the plugin container that whose plugins are managed by this manager. - * ++ * + * @return the plugin container that owns this plugin manager + */ + public AbstractTypeServerPluginContainer getParentPluginContainer() { + return this.parentPluginContainer; + } + + /** + * Returns the {@link ServerPluginEnvironment}s for every plugin this manager has loaded. + * The returned collection is a copy and not backed by this manager. + * + * @return environments for all the plugins + */ + public Collection<ServerPluginEnvironment> getPluginEnvironments() { + return new ArrayList<ServerPluginEnvironment>(this.loadedPlugins.values()); + } + + /** + * Given a plugin name, this returns that plugin's environment. - * ++ * + * <p>The plugin's name is defined in its plugin descriptor - specifically the XML root node's "name" attribute + * (e.g. <server-plugin name="thePluginName").</p> + * + * @param pluginName the plugin whose environment is to be returned + * @return given plugin's environment + */ + public ServerPluginEnvironment getPluginEnvironment(String pluginName) { + return this.loadedPlugins.get(pluginName); }
/** * Initializes the plugin manager to prepare it to start loading plugins. -- * ++ * * @throws Exception if failed to initialize */ - public void initialize() throws Exception { + protected void initialize() throws Exception { log.debug("Plugin manager initializing"); return; // no-op } @@@ -250,14 -351,14 +351,14 @@@ /** * Returns the main plugin component instance that is responsible for initializing and managing * the plugin. This will return <code>null</code> if a plugin has not defined a plugin component. -- * ++ * * @param pluginName the name of the plugin whose plugin component is to be returned -- * ++ * * @return the plugin component instance that initialized and is managing a plugin. Will -- * return <code>null</code> if the plugin has not defined a plugin component. -- * <code>null</code> is also returned if the plugin is not initialized yet. ++ * return <code>null</code> if the plugin has not defined a plugin component. ++ * <code>null</code> is also returned if the plugin is not initialized yet. */ - public ServerPluginComponent getServerPluginComponent(String pluginName) { + protected ServerPluginComponent getServerPluginComponent(String pluginName) { return this.pluginComponentCache.get(pluginName); }
@@@ -302,9 -399,26 +399,26 @@@ }
/** - * Given a plugin environment, return its Plugin representation, which should also include + * Given a plugin environment, this will rebuild a new one with up-to-date information. + * This means the descriptor will be reparsed. - * ++ * + * @param env the original environment + * @return the new environment that has been rebuild from the original but has newer data + * @throws Exception if the environment could not be rebuilt - probably due to an invalid descriptor + * in the plugin jar or the plugin jar is now missing + */ + protected ServerPluginEnvironment rebuildServerPluginEnvironment(ServerPluginEnvironment env) throws Exception { + URL url = env.getPluginUrl(); + ClassLoader classLoader = env.getPluginClassLoader(); + ServerPluginDescriptorType descriptor = ServerPluginDescriptorUtil.loadPluginDescriptorFromUrl(url); + ServerPluginEnvironment newEnv = new ServerPluginEnvironment(url, classLoader, descriptor); + return newEnv; + } + + /** + * Given a plugin environment, return its {@link ServerPlugin} representation, which should also include * the plugin configuration and scheduled jobs configuration. -- * ++ * * @param pluginEnv * @return the ServerPlugin object for the given plugin */ @@@ -349,7 -464,7 +464,7 @@@ /** * Instantiates a class with the given name within the given environment's classloader using * the class' no-arg constructor. -- * ++ * * @param environment the environment that has the classloader where the class will be loaded * @param className the class to instantiate * @return the new object that is an instance of the given class diff --cc modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/plugin/pc/generic/GenericServerPluginTest.java index 48a5db7,450f4db..73849b7 --- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/plugin/pc/generic/GenericServerPluginTest.java +++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/plugin/pc/generic/GenericServerPluginTest.java @@@ -93,10 -91,68 +91,68 @@@ public class GenericServerPluginTest ex this.pluginService.stopMasterPluginContainer(); assert pc.state == State.UNINITIALIZED; assert component.state == LifecycleState.UNINITIALIZED; + } + + public void testGetInstalledPlugins() throws Exception { + File jar = createPluginJar("testSimpleGenericPlugin.jar", "serverplugins/simple-generic-serverplugin.xml"); + ServerPluginType type = new ServerPluginType(GenericPluginDescriptorType.class); + + ServerPluginDescriptorType descriptor = ServerPluginDescriptorUtil.loadPluginDescriptorFromUrl(jar.toURI() + .toURL());
- // with the master down, this method should return an empty map - map = serverPluginsLocal.getAllPluginsGroupedByType(); - assert map.size() == 0; + ServerPlugin plugin = new ServerPlugin(0, descriptor.getName(), jar.getName(), descriptor.getDisplayName(), + true, PluginStatusType.INSTALLED, descriptor.getDescription(), null, MessageDigestGenerator + .getDigestString(jar), descriptor.getVersion(), descriptor.getApiVersion(), null, null, type + .stringify(), System.currentTimeMillis(), System.currentTimeMillis()); + + ServerPluginsLocal serverPluginsLocal = LookupUtil.getServerPlugins(); + Map<ServerPluginType, List<PluginKey>> original = serverPluginsLocal.getInstalledServerPluginsGroupedByType(); + serverPluginsLocal.registerServerPlugin(LookupUtil.getSubjectManager().getOverlord(), plugin, jar); + + try { + Map<ServerPluginType, List<PluginKey>> map = serverPluginsLocal.getInstalledServerPluginsGroupedByType(); + List<PluginKey> pluginKeys = map.get(type); + + if (original.containsKey(type)) { + assert map.size() == original.size(); + assert pluginKeys.size() == original.get(type).size() + 1; + } else { + assert map.size() == original.size() + 1; + assert pluginKeys.size() == 1; + } + boolean got_it = false; + for (PluginKey pluginKey : pluginKeys) { + if (pluginKey.getPluginName().equals("TestSimpleGenericPlugin")) { + got_it = true; + break; + } + } + assert got_it == true; + } finally { - // make sure we clean this up, even on error ++ // make sure we clean this up, even on error + serverPluginsLocal.purgeServerPlugin(LookupUtil.getSubjectManager().getOverlord(), new PluginKey(plugin)); + } + + // test that purge really deleted it + Map<ServerPluginType, List<PluginKey>> map = serverPluginsLocal.getInstalledServerPluginsGroupedByType(); + List<PluginKey> pluginKeys = map.get(type); + + assert map.size() == original.size(); + if (pluginKeys == null) { + assert !original.containsKey(type) : "we dont have any plugins of this type, neither should original"; + } else { + assert pluginKeys.size() == original.get(type).size(); + boolean got_it = false; + for (PluginKey pluginKey : pluginKeys) { + if (pluginKey.getPluginName().equals("TestSimpleGenericPlugin")) { + got_it = true; + break; + } + } + assert got_it == false : "we still have the plugin, but it should have been purged"; + } + + return; }
private File createPluginJar(String jarName, String descriptorXmlFilename) throws Exception {
commit 81bfb7f1b9b4711b359c58d333442c46c30cf32a Author: Heiko W. Rupp pilhuhn@fedorapeople.org Date: Wed Dec 2 10:10:50 2009 +0100
Try to prevent a NPE
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/ListNotificationsUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/ListNotificationsUIBean.java index 4ff8f20..fcce6fd 100644 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/ListNotificationsUIBean.java +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/ListNotificationsUIBean.java @@ -104,7 +104,10 @@ public class ListNotificationsUIBean { if (alertProperties==null) { if (alertConfigurationDefinition==null) alertConfigurationDefinition = getAlertConfigurationDefinition(); - alertProperties = alertConfigurationDefinition.getDefaultTemplate().getConfiguration(); + if (alertConfigurationDefinition!=null) + alertProperties = alertConfigurationDefinition.getDefaultTemplate().getConfiguration(); + else + alertProperties = new Configuration(); } return alertProperties; } @@ -139,7 +142,6 @@ public class ListNotificationsUIBean { }
public String mySubmitForm() { - log.info("In submit Form "); AlertNotificationManagerLocal mgr = LookupUtil.getAlertNotificationManager(); Subject subject = EnterpriseFacesContextUtility.getSubject(); mgr.addAlertNotification(subject, alertDefinitionId,selectedSender,alertProperties);
commit 1c8da15c35494c44bc23ac7f2a7b0b5e20cf5422 Merge: 97f1d6d... c146853... Author: John Mazzitelli mazz@redhat.com Date: Tue Dec 1 23:07:34 2009 -0500
Merge branch 'master' into pc
commit 97f1d6d568f59b23c8ab10a54e364e1cb0f1ddd0 Author: John Mazzitelli mazz@redhat.com Date: Tue Dec 1 22:32:30 2009 -0500
need to reload/enable the plugin first, before rescheduling jobs
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsBean.java index b0ebbff..d80b5be 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsBean.java @@ -162,14 +162,14 @@ public class ServerPluginsBean implements ServerPluginsLocal { AbstractTypeServerPluginContainer pc = master.getPluginContainerByPlugin(pluginKey); if (pc != null) { try { - pc.schedulePluginJobs(pluginKey); + pc.reloadPlugin(pluginKey, true); } catch (Exception e) { - log.warn("Failed to schedule jobs for plugin [" + pluginKey + "]", e); + log.warn("Failed to enable server plugin [" + pluginKey + "]", e); } try { - pc.reloadPlugin(pluginKey, true); + pc.schedulePluginJobs(pluginKey); } catch (Exception e) { - log.warn("Failed to enable server plugin [" + pluginKey + "]", e); + log.warn("Failed to schedule jobs for plugin [" + pluginKey + "]", e); } } } diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginManager.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginManager.java index 4616644..769db26 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginManager.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginManager.java @@ -323,7 +323,7 @@ public class ServerPluginManager { if (env == null) { throw new IllegalArgumentException("Server plugin [" + pluginName + "] was never loaded, cannot enable it"); } - stopPlugin(pluginName); // under normal circumstances, we should need to do this, but just in case the plugin is somehow already started, stop it + stopPlugin(pluginName); // under normal circumstances, we should not need to do this, but just in case the plugin is somehow already started, stop it unloadPlugin(pluginName); // unloading it will clean up old data and force the plugin context to reload if we later re-enable it env = rebuildServerPluginEnvironment(env); loadPlugin(env, true); // reload it in the enabled state
commit 29ac99053363a78b4645b8d6f22de67928683bf8 Merge: 3d57a60... cde65a0... Author: John Sanda john@localhost.localdomain Date: Tue Dec 1 19:53:36 2009 -0500
Merge branch 'raw-config' of ssh://git.fedorahosted.org/git/rhq/rhq into raw-config
commit 30a8351ac40cde6eb5dcb59910b6ffc02fae3b4b Author: Jay Shaughnessy jshaughn@redhat.com Date: Tue Dec 1 17:15:49 2009 -0500
Working to the point of core menu generation from the core perspective.
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/perspectives/ExtensionPoints.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/perspectives/ExtensionPoints.java deleted file mode 100644 index 5670264..0000000 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/perspectives/ExtensionPoints.java +++ /dev/null @@ -1,449 +0,0 @@ -package org.rhq.enterprise.gui.perspectives; - -public class ExtensionPoints { - - //constants:begin Extension point map - //MENU:ExtensionPoints BEGIN - //root menu item container - public static final String menu = "menu"; - //logo - public static final String logo = menu + ".logo"; - public static final String logo_BEFORE = logo + "_BEFORE"; - public static final String logo_AFTER = logo + "_AFTER"; - //overview - public static final String overview_BEFORE = logo_AFTER;//same spot - public static final String overview = menu + ".overview"; - public static final String subsystemViews = overview + ".subsystemViews"; - public static final String configurationChanges = subsystemViews + ".configurationChanges"; - public static final String suspectMetrics = subsystemViews + ".suspectMetrics"; - public static final String operations = subsystemViews + ".operations"; - public static final String alerts = subsystemViews + ".alerts"; - public static final String alertDefinitions = subsystemViews + ".alertDefinitions"; - public static final String autoDiscoveryQueue = overview + ".autoDiscoveryQueue"; - public static final String dashboard = overview + ".dashboard"; - public static final String overview_AFTER = overview + "_AFTER"; - //resources - public static final String resources_BEFORE = overview_AFTER;//same spot - public static final String resources = menu + ".resources"; - public static final String platforms = resources + ".platforms"; - public static final String servers = resources + ".servers"; - public static final String services = resources + ".services"; - public static final String favoriteResources = resources + ".favoriteResources"; - public static final String recentlyViewedResources = resources + ".recentlyViewedResources"; - public static final String searchResources = resources + ".search"; - public static final String resources_AFTER = resources + "_AFTER"; - //groups - public static final String groups_BEFORE = resources_AFTER;//same spot - public static final String groups = menu + ".groups"; - public static final String compatible = groups + ".compatibleGroups"; - public static final String mixed = groups + ".mixedGroups"; - public static final String definitions = groups + ".groupDefinitions"; - public static final String newGroup = groups + ".newGroup"; - public static final String newGroupDefinition = groups + ".newGroupDefinition"; - public static final String favoriteGroups = groups + ".favoriteGroups"; - public static final String recentlyViewedGroups = groups + ".recentlyViewedGroups"; - public static final String searchGroups = groups + ".search"; - public static final String groups_AFTER = groups + "_AFTER"; - //administration - public static final String administration_BEFORE = groups_AFTER;//same spot - public static final String administration = menu + ".administration"; - public static final String security = administration + ".security"; - public static final String users = security + ".users"; - public static final String roles = security + ".roles"; - public static final String systemConfiguration = administration + ".systemConfiguration"; - public static final String settings = systemConfiguration + ".settings"; - public static final String plugins = systemConfiguration + ".plugins"; - public static final String templates = systemConfiguration + ".templates"; - public static final String content = administration + ".content"; - public static final String contentProviders = content + ".contentProviders"; - public static final String repositories = content + ".repositories"; - public static final String highAvailability = administration + ".highAvailability"; - public static final String haServers = highAvailability + ".servers"; - public static final String agents = highAvailability + ".agents"; - public static final String affinityGroups = highAvailability + ".affinityGroups"; - public static final String partitionEvents = highAvailability + ".partitionEvents"; - public static final String reports = administration + ".reports"; - public static final String resourceVersionInventoryReport = reports + ".resourceVersionInventoryReport"; - public static final String downloads = administration + ".downloads"; - public static final String license = administration + ".license"; - public static final String administration_AFTER = administration + "_AFTER"; - //debug - public static final String debug_BEFORE = administration_AFTER;//same spot - public static final String debug = menu + ".debug"; - public static final String sqlInterface = debug + ".sqlInterface"; - public static final String jpqlHqlInterface = debug + ".jpqlHqlInterface"; - public static final String hibernate = debug + ".hibernate"; - public static final String administrativeControl = debug + ".administrativeControl"; - public static final String testEmail = debug + ".testEmail"; - public static final String testAgent = debug + ".testAgent"; - public static final String debug_AFTER = debug + "_AFTER"; - //help - public static final String help_BEFORE = debug_AFTER;//same spot - public static final String help = menu + ".help"; - public static final String onlineDocumentation = help + ".onlineDocumentation"; - public static final String openASupportCase = help + ".openASupportCase"; - public static final String about = help + ".about"; - public static final String help_AFTER = help + "_AFTER"; - //refresh - public static final String refresh = menu + ".refresh"; - public static final String refresh_BEFORE = refresh + "_BEFORE"; - public static final String stop = refresh + ".stop"; - public static final String refreshEvery1Minute = refresh + ".refreshEvery1Minute"; - public static final String refreshEvery5Minutes = refresh + ".refreshEvery5Minutes"; - public static final String refreshEvery10Minutes = refresh + ".refreshEvery10Minutes"; - public static final String refresh_AFTER = refresh + "_AFTER"; - //loggedInAs - public static final String loggedInAs_BEFORE = refresh_AFTER;//same spot - public static final String loggedInAs = menu + ".loggedInAs"; - public static final String editDetails = loggedInAs + ".editDetails"; - public static final String changePassword = loggedInAs + ".changePassword"; - public static final String logout = loggedInAs + ".logout"; - public static final String loggedInAs_AFTER = loggedInAs + "_AFTER"; - - public ExtensionPoints() { - } - - public String getMenu() { - return menu; - } - - public String getLogo() { - return logo; - } - - public String getLogoBefore() { - return logo_BEFORE; - } - - public String getLogoAfter() { - return logo_AFTER; - } - - public String getOverviewBefore() { - return overview_BEFORE; - } - - public String getOverview() { - return overview; - } - - public String getSubsystemviews() { - return subsystemViews; - } - - public String getConfigurationchanges() { - return configurationChanges; - } - - public String getSuspectmetrics() { - return suspectMetrics; - } - - public String getOperations() { - return operations; - } - - public String getAlerts() { - return alerts; - } - - public String getAlertdefinitions() { - return alertDefinitions; - } - - public String getAutodiscoveryqueue() { - return autoDiscoveryQueue; - } - - public String getDashboard() { - return dashboard; - } - - public String getOverviewAfter() { - return overview_AFTER; - } - - public String getDebugBefore() { - return debug_BEFORE; - } - - public String getDebug() { - return debug; - } - - public String getSqlinterface() { - return sqlInterface; - } - - public String getJpqlhqlinterface() { - return jpqlHqlInterface; - } - - public String getHibernate() { - return hibernate; - } - - public String getAdministrativecontrol() { - return administrativeControl; - } - - public String getTestemail() { - return testEmail; - } - - public String getTestagent() { - return testAgent; - } - - public String getDebugAfter() { - return debug_AFTER; - } - - public String getResourcesBefore() { - return resources_BEFORE; - } - - public String getResources() { - return resources; - } - - public String getPlatforms() { - return platforms; - } - - public String getServers() { - return servers; - } - - public String getServices() { - return services; - } - - public String getFavoriteresources() { - return favoriteResources; - } - - public String getRecentlyviewedresources() { - return recentlyViewedResources; - } - - public String getSearchresources() { - return searchResources; - } - - public String getResourcesAfter() { - return resources_AFTER; - } - - public String getGroupsBefore() { - return groups_BEFORE; - } - - public String getGroups() { - return groups; - } - - public String getCompatible() { - return compatible; - } - - public String getMixed() { - return mixed; - } - - public String getDefinitions() { - return definitions; - } - - public String getNewgroup() { - return newGroup; - } - - public String getNewgroupdefinition() { - return newGroupDefinition; - } - - public String getFavoritegroups() { - return favoriteGroups; - } - - public String getRecentlyviewedgroups() { - return recentlyViewedGroups; - } - - public String getSearchgroups() { - return searchGroups; - } - - public String getGroupsAfter() { - return groups_AFTER; - } - - public String getAdministrationBefore() { - return administration_BEFORE; - } - - public String getAdministration() { - return administration; - } - - public String getSecurity() { - return security; - } - - public String getUsers() { - return users; - } - - public String getRoles() { - return roles; - } - - public String getSystemconfiguration() { - return systemConfiguration; - } - - public String getSettings() { - return settings; - } - - public String getPlugins() { - return plugins; - } - - public String getTemplates() { - return templates; - } - - public String getContent() { - return content; - } - - public String getContentproviders() { - return contentProviders; - } - - public String getRepositories() { - return repositories; - } - - public String getHighavailability() { - return highAvailability; - } - - public String getHaservers() { - return haServers; - } - - public String getAgents() { - return agents; - } - - public String getAffinitygroups() { - return affinityGroups; - } - - public String getPartitionevents() { - return partitionEvents; - } - - public String getReports() { - return reports; - } - - public String getResourceversioninventoryreport() { - return resourceVersionInventoryReport; - } - - public String getDownloads() { - return downloads; - } - - public String getLicense() { - return license; - } - - public String getAdministrationAfter() { - return administration_AFTER; - } - - public String getHelpBefore() { - return help_BEFORE; - } - - public String getHelp() { - return help; - } - - public String getOnlinedocumentation() { - return onlineDocumentation; - } - - public String getOpenasupportcase() { - return openASupportCase; - } - - public String getAbout() { - return about; - } - - public String getHelpAfter() { - return help_AFTER; - } - - public String getRefreshBefore() { - return refresh_BEFORE; - } - - public String getRefresh() { - return refresh; - } - - public String getStop() { - return stop; - } - - public String getRefreshevery1minute() { - return refreshEvery1Minute; - } - - public String getRefreshevery5minutes() { - return refreshEvery5Minutes; - } - - public String getRefreshevery10minutes() { - return refreshEvery10Minutes; - } - - public String getRefreshAfter() { - return refresh_AFTER; - } - - public String getLoggedinasBefore() { - return loggedInAs_BEFORE; - } - - public String getLoggedinas() { - return loggedInAs; - } - - public String getEditdetails() { - return editDetails; - } - - public String getChangepassword() { - return changePassword; - } - - public String getLogout() { - return logout; - } - - public String getLoggedinasAfter() { - return loggedInAs_AFTER; - } - - //MENU:ExtensionPoints END - - //constants:end -} diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/perspectives/MenuItem.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/perspectives/MenuItem.java deleted file mode 100644 index 2ba210e..0000000 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/perspectives/MenuItem.java +++ /dev/null @@ -1,151 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2008 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.gui.perspectives; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; - -/** Features for each menu item. A menu item can be as simple as a logo, - * menu separator bar or as complicated as a root menu item with an arbitrary - * amount of child menuitems. - * - * @author Simeon Pinder - * - */ -public class MenuItem { - - //url to icon image - private String iconUrl = ""; - //width of icon - private int iconWidth = 0; - //height of icon - private int iconHeight = 0; - //url to direct user to onclick - private String url = ""; - //The label to be displayed for this menu item - private String name = ""; - //whether this menu item is to be enabled/visible - private boolean rendered = true; - //whether this menuItem represent a menu separator - private boolean isMenuSeparator = false; - //includes N child MenuItem instances - private List<MenuItem> childMenuItems = new ArrayList<MenuItem>(); - //Stores a unique reference to the ExtensionPoint key for this item. - private String extensionKey = ""; - //whether this menuItem(relevant to top menu items only) is aligned from far left - private boolean alignLeft = true; - - //default no args. To satisfy basic bean functionality. - MenuItem() { - } - - MenuItem(String iconUrl, String url, String name) { - this.iconUrl = iconUrl; - this.url = url; - this.name = name; - } - - MenuItem(String iconUrl, String url, String name, List<MenuItem> children, String key, HashMap<String, MenuItem> map) { - this(iconUrl, url, name); - children.add(this); - map.put(key, this); - this.extensionKey = key; - } - - public String getIconUrl() { - return iconUrl; - } - - public void setIconUrl(String iconUrl) { - this.iconUrl = iconUrl; - } - - public String getUrl() { - return url; - } - - public void setUrl(String url) { - this.url = url; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public boolean isRendered() { - return rendered; - } - - public void setRendered(boolean render) { - this.rendered = render; - } - - public int getIconHeight() { - return iconHeight; - } - - public void setIconHeight(int iconHeight) { - this.iconHeight = iconHeight; - } - - public int getIconWidth() { - return iconWidth; - } - - public void setIconWidth(int iconWidth) { - this.iconWidth = iconWidth; - } - - public boolean isMenuSeparator() { - return isMenuSeparator; - } - - public void setMenuSeparator(boolean isMenuSeparator) { - this.isMenuSeparator = isMenuSeparator; - } - - public void setChildMenuItems(List<MenuItem> childMenuItems) { - this.childMenuItems = childMenuItems; - } - - public List<MenuItem> getChildMenuItems() { - return childMenuItems; - } - - public String getExtensionKey() { - return extensionKey; - } - - public void setExtensionKey(String extensionKey) { - this.extensionKey = extensionKey; - } - - public boolean isAlignLeft() { - return alignLeft; - } - - public void setAlignLeft(boolean alignLeft) { - this.alignLeft = alignLeft; - } -} diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/perspectives/PerspectivesMenuUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/perspectives/PerspectivesMenuUIBean.java index 308ad2b..e1ab2b5 100644 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/perspectives/PerspectivesMenuUIBean.java +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/perspectives/PerspectivesMenuUIBean.java @@ -18,11 +18,16 @@ */ package org.rhq.enterprise.gui.perspectives;
-import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; import java.util.List; -import java.util.Set; + +import javax.faces.application.FacesMessage; + +import org.rhq.core.domain.auth.Subject; +import org.rhq.core.gui.util.FacesContextUtility; +import org.rhq.enterprise.gui.util.EnterpriseFacesContextUtility; +import org.rhq.enterprise.server.perspective.PerspectiveException; +import org.rhq.enterprise.server.perspective.PerspectiveManagerLocal; +import org.rhq.enterprise.server.util.LookupUtil;
/** * Bean dynamically provides menu information used by menu.xhtml. This bean should be viewed @@ -34,331 +39,18 @@ import java.util.Set; */ public class PerspectivesMenuUIBean {
- //Stores reference to the root menu item - private MenuItem CoreMenuBar = null; - - /* Stores all mapped MenuItem information */ - private HashMap<String, MenuItem> menuDefinition = new HashMap<String, MenuItem>(); - - // provides MenuItem mapping lookup via bean accessor - private MenuItem extensionPoint = null; - - {//initialization block - //Root of core menu - MenuItem menu = new MenuItem(); - menu.setExtensionKey(ExtensionPoints.menu); - CoreMenuBar = menu; - menuDefinition.put(ExtensionPoints.menu, menu); - - List<MenuItem> attachPoints = menu.getChildMenuItems(); - - /*===== LOGO TO HOME PAGE =====*/ - MenuItem logoBefore = new MenuItem("", "", "", menu.getChildMenuItems(), ExtensionPoints.logo_BEFORE, - menuDefinition); - logoBefore.setRendered(false); - MenuItem logo = new MenuItem("/images/JBossLogo_small.png", "", "", menu.getChildMenuItems(), - ExtensionPoints.logo, menuDefinition); - logo.setIconHeight(21); - logo.setIconWidth(37); - MenuItem logoAfter = new MenuItem("", "", "", menu.getChildMenuItems(), ExtensionPoints.logo_AFTER, - menuDefinition); - logoAfter.setRendered(false); - /*===== OVERVIEW =====*/ - MenuItem overview = new MenuItem("", "", "Overview", menu.getChildMenuItems(), ExtensionPoints.overview, - menuDefinition); - /*===== Overview.BEFORE extension pt. Ignore same as Logo.after ============= */ - /*===== OVERVIEW.AFTER =====*/ - MenuItem overviewAfter = new MenuItem("", "", "", menu.getChildMenuItems(), ExtensionPoints.overview_AFTER, - menuDefinition); - overviewAfter.setRendered(false); - - /****** Overview > SYSTEM VIEWS ******/ - MenuItem subsystemViews = new MenuItem("", "", "Subsystem Views", overview.getChildMenuItems(), - ExtensionPoints.subsystemViews, menuDefinition); - List<MenuItem> subsystemMenuItems = new ArrayList<MenuItem>(); - { - //SubsystemView menu items - String[] imageNames = { "Configure", "Monitor_failed", "Operation", "Flag_blue", "Flag_grey" }; - String[] pageNames = { "configurationUpdate", "oobHistory", "operationHistory", "alertHistory", - "alertDefinitions" }; - String[] menuNames = { "Configuration Changes", "Suspect Metrics", "Operations", "Alerts", - "Alert Definitions" }; - for (int i = 0; i < imageNames.length; i++) { - String extKey = null; - String name = menuNames[i]; - if (name.indexOf("Configuration") > -1) { - extKey = ExtensionPoints.configurationChanges; - } - if (name.indexOf("Suspect") > -1) { - extKey = ExtensionPoints.suspectMetrics; - } - if (name.indexOf("Operations") > -1) { - extKey = ExtensionPoints.operations; - } - if (name.indexOf("Alerts") > -1) { - extKey = ExtensionPoints.alerts; - } - if (name.indexOf("Alert") > -1) { - extKey = ExtensionPoints.alertDefinitions; - } - MenuItem m = new MenuItem("/images/icons/" + imageNames[i] + "_16.png",//icon url - "/rhq/subsystem/" + pageNames[i] + ".xhtml", // menu item url - menuNames[i], subsystemViews.getChildMenuItems(), extKey, menuDefinition); //menu item name - } - } - /* ***** Overview > AUTO-DISCOVERY QUEUE ***** */ - MenuItem autoDiscoveryQueue = new MenuItem("", "/rhq/discovery/queue.xhtml", "Auto Discovery Queue", overview - .getChildMenuItems(), ExtensionPoints.autoDiscoveryQueue, menuDefinition); - - /* ***** Overview > DASHBOARD ***** */ - MenuItem dashboard = new MenuItem("", "/Dashboard.do", "Dashboard", overview.getChildMenuItems(), - ExtensionPoints.dashboard, menuDefinition); - - /* ===== RESOURCES ===== */ - MenuItem resources = new MenuItem("", "", "Resources", menu.getChildMenuItems(), ExtensionPoints.resources, - menuDefinition); - /*===== RESOURCES.BEFORE extension pt. Ignore same as Overvie.after ============= */ - /*===== Resources.AFTER =====*/ - MenuItem resourcesAfter = new MenuItem("", "", "", menu.getChildMenuItems(), ExtensionPoints.resources_AFTER, - menuDefinition); - resourcesAfter.setRendered(false); - - /* Resources: Platform */ - MenuItem resourcesPlatform = new MenuItem("/images/icons/Platform_up_16.png", - "/ResourceHub.do?resourceCategory=PLATFORM", "", resources.getChildMenuItems(), ExtensionPoints.platforms, - menuDefinition); - /* Resources: Server */ - MenuItem resourcesServer = new MenuItem("/images/icons/Server_up_16.png", - "/ResourceHub.do?resourceCategory=SERVER", "", resources.getChildMenuItems(), ExtensionPoints.servers, - menuDefinition); - /* Resources: Service */ - MenuItem resourcesService = new MenuItem("/images/icons/Service_up_16.png", - "/ResourceHub.do?resourceCategory=SERVICE", "", resources.getChildMenuItems(), ExtensionPoints.services, - menuDefinition); - // Menu bar separator - MenuItem separator = new MenuItem("", "", ""); - separator.setMenuSeparator(true); - resources.getChildMenuItems().add(separator); - /* Resources: Favorites */ - MenuItem resourcesFavorite = new MenuItem("/images/icons/Favorite_16.png", "", "Favorite Resources", resources - .getChildMenuItems(), ExtensionPoints.favoriteResources, menuDefinition); - /* Resources: Recently Viewed */ - MenuItem resourcesRecentlyViewed = new MenuItem("/images/icons/History_16.png", "", - "Recently Viewed Resources", resources.getChildMenuItems(), ExtensionPoints.recentlyViewedResources, - menuDefinition); - //ADD Menu bar separator - resources.getChildMenuItems().add(separator); - /* Resources: Search */ - MenuItem resourcesSearch = new MenuItem("", "", "Search: ", resources.getChildMenuItems(), - ExtensionPoints.searchResources, menuDefinition); - - /* ===== GROUPS ===== */ - MenuItem groups = new MenuItem("", "", "Groups", menu.getChildMenuItems(), ExtensionPoints.groups, - menuDefinition); - /*===== Groups.BEFORE extension pt. Ignore same as Overvie.after ============= */ - /*===== Groups.AFTER =====*/ - MenuItem groupsAfter = new MenuItem("", "", "", menu.getChildMenuItems(), ExtensionPoints.groups_AFTER, - menuDefinition); - groupsAfter.setRendered(false); - /* GROUPS: Compatible */ - MenuItem groupsCompatible = new MenuItem("/images/icons/Cluster_up_16.png", - "/GroupHub.do?groupCategory=COMPATIBLE", "", groups.getChildMenuItems(), ExtensionPoints.compatible, - menuDefinition); - /* GROUPS: Mixed */ - MenuItem groupsMixed = new MenuItem("/images/icons/Group_up_16.png", "/GroupHub.do?groupCategory=MIXED", "", - groups.getChildMenuItems(), ExtensionPoints.mixed, menuDefinition); - /* GROUPS: Group Definitions */ - MenuItem groupsDefinitions = new MenuItem("/images/GroupDefinition_16.png", "/rhq/definition/group/list.xhtml", - "", groups.getChildMenuItems(), ExtensionPoints.definitions, menuDefinition); - /* GROUPS: New Group */ - MenuItem groupsNewResource = new MenuItem("", "/resource/group/Inventory.do?mode=new", "", groups - .getChildMenuItems(), ExtensionPoints.newGroup, menuDefinition); - /* GROUPS: New Group Definition */ - MenuItem groupsNewDefinition = new MenuItem("", "/rhq/definition/group/new.xhtml", "", groups - .getChildMenuItems(), ExtensionPoints.newGroupDefinition, menuDefinition); - // Menu bar separator - groups.getChildMenuItems().add(separator); - - /* GROUPS: Favorites */ - MenuItem groupsFavorite = new MenuItem("/images/icons/Favorite_16.png", "", "Favorite Groups", groups - .getChildMenuItems(), ExtensionPoints.favoriteGroups, menuDefinition); - /* GROUPS: Recently Viewed */ - MenuItem groupsRecentlyViewed = new MenuItem("/images/icons/History_16.png", "", "Recently Viewed Groups", - groups.getChildMenuItems(), ExtensionPoints.recentlyViewedGroups, menuDefinition); - // Menu bar separator - groups.getChildMenuItems().add(separator); - /* GROUPS: Recently Viewed */ - MenuItem groupsSearch = new MenuItem("", "", "Search", groups.getChildMenuItems(), - ExtensionPoints.searchGroups, menuDefinition); - - /* ===== ADMINISTRATION ===== */ - MenuItem administration = new MenuItem("", "", "Administration", menu.getChildMenuItems(), - ExtensionPoints.administration, menuDefinition); - /*===== ADMINISTRATION.BEFORE extension pt. Ignore same as Groups.after ============= */ - /*===== ADMINISTRATION.AFTER =====*/ - MenuItem administrationAfter = new MenuItem("", "", "", menu.getChildMenuItems(), - ExtensionPoints.administration_AFTER, menuDefinition); - administrationAfter.setRendered(false); - MenuItem security = new MenuItem("", "", "Security", administration.getChildMenuItems(), - ExtensionPoints.security, menuDefinition); - MenuItem securityUsers = new MenuItem("", "/admin/user/UserAdmin.do?mode=list", "Users", security - .getChildMenuItems(), ExtensionPoints.users, menuDefinition); - MenuItem securityRoles = new MenuItem("", "/admin/role/RoleAdmin.do?mode=list", "Roles", security - .getChildMenuItems(), ExtensionPoints.roles, menuDefinition); - MenuItem sysconfig = new MenuItem("", "", "System Configuration", administration.getChildMenuItems(), - ExtensionPoints.systemConfiguration, menuDefinition); - MenuItem sysconfigSettings = new MenuItem("", "/admin/config/Config.do?mode=edit", "Settings", sysconfig - .getChildMenuItems(), ExtensionPoints.settings, menuDefinition); - MenuItem sysconfigPlugins = new MenuItem("", "/rhq/admin/plugin/plugin-list.xhtml", "Plugins", sysconfig - .getChildMenuItems(), ExtensionPoints.plugins, menuDefinition); - MenuItem sysconfigTemplates = new MenuItem("", "/admin/config/EditDefaults.do?mode=monitor&viewMode=all", - "Templates", sysconfig.getChildMenuItems(), ExtensionPoints.templates, menuDefinition); - MenuItem content = new MenuItem("", "", "Content", administration.getChildMenuItems(), ExtensionPoints.content, - menuDefinition); - MenuItem contentContentProviders = new MenuItem("", "/rhq/content/listContentProviders.xhtml", - "Content Providers", content.getChildMenuItems(), ExtensionPoints.contentProviders, menuDefinition); - MenuItem contentRepositories = new MenuItem("", "/rhq/content/listRepos.xhtml", "Repositories", content - .getChildMenuItems(), ExtensionPoints.repositories, menuDefinition); - MenuItem ha = new MenuItem("", "", "High Availability", administration.getChildMenuItems(), - ExtensionPoints.highAvailability, menuDefinition); - MenuItem haServers = new MenuItem("", "/rhq/ha/listServers.xhtml", "Servers", ha.getChildMenuItems(), - ExtensionPoints.haServers, menuDefinition); - MenuItem haAgents = new MenuItem("", "/rhq/ha/listAgents.xhtml", "Agents", ha.getChildMenuItems(), - ExtensionPoints.agents, menuDefinition); - MenuItem haAffinityGroups = new MenuItem("", "/rhq/ha/listAffinityGroups.xhtml", "Affinity Groups", ha - .getChildMenuItems(), ExtensionPoints.affinityGroups, menuDefinition); - MenuItem haPartitionEvents = new MenuItem("", "/rhq/ha/listPartitionEvents.xhtml", "Partition Events", ha - .getChildMenuItems(), ExtensionPoints.partitionEvents, menuDefinition); - MenuItem reports = new MenuItem("", "", "Reports", administration.getChildMenuItems(), ExtensionPoints.reports, - menuDefinition); - MenuItem reportsResourceVersion = new MenuItem("", "/rhq/admin/report/resourceInstallReport.xhtml", - "Resource Version Inventory Report", reports.getChildMenuItems(), - ExtensionPoints.resourceVersionInventoryReport, menuDefinition); - MenuItem downloads = new MenuItem("/images/icons/Save_16.png", "/rhq/admin/downloads.xhtml", "Downloads", - administration.getChildMenuItems(), ExtensionPoints.downloads, menuDefinition); - MenuItem license = new MenuItem("", "/admin/license/LicenseAdmin.do?mode=view", "License", administration - .getChildMenuItems(), ExtensionPoints.license, menuDefinition); + PerspectiveManagerLocal perspectiveManager = LookupUtil.getPerspectiveManager();
- //* ------------- DEBUG ------------------- *// - /*===== DEBUG.BEFORE extension pt. Ignore same as Administration.after ============= */ - MenuItem debug = new MenuItem("", "", "Debug", menu.getChildMenuItems(), ExtensionPoints.debug, menuDefinition); - MenuItem sqlInterface = new MenuItem("", "/admin/test/sql.jsp", "SQL Interface", debug.getChildMenuItems(), - ExtensionPoints.sqlInterface, menuDefinition); - MenuItem jpqlHibernateInterface = new MenuItem("", "/admin/test/hibernate.jsp", "JPQL/HQL Interface", debug - .getChildMenuItems(), ExtensionPoints.jpqlHqlInterface, menuDefinition); - MenuItem hibernate = new MenuItem("", "/admin/test/browser.jsp", "Hibernate Entity Browser", debug - .getChildMenuItems(), ExtensionPoints.hibernate, menuDefinition); - MenuItem administrativeControl = new MenuItem("", "/admin/test/control.jsp", "Administrative Control", debug - .getChildMenuItems(), ExtensionPoints.administrativeControl, menuDefinition); - MenuItem testEmail = new MenuItem("", "/admin/test/email.jsp", "Test Email Configuration", debug - .getChildMenuItems(), ExtensionPoints.testEmail, menuDefinition); - MenuItem testAgent = new MenuItem("", "/admin/test/agent.jsp", "Test Agent Communications", debug - .getChildMenuItems(), ExtensionPoints.testAgent, menuDefinition); - /*===== DEBUG.AFTER =====*/ - MenuItem debugAfter = new MenuItem("", "", "", menu.getChildMenuItems(), ExtensionPoints.debug_AFTER, - menuDefinition); - debugAfter.setRendered(false); + public List<org.rhq.enterprise.server.perspective.MenuItem> getCoreMenu() { + Subject subject = EnterpriseFacesContextUtility.getSubject(); + List<org.rhq.enterprise.server.perspective.MenuItem> result = null;
- //* ------------- HELP ------------------- *// - /*===== HELP.BEFORE extension pt. Ignore same as Administration.after ============= */ - MenuItem help = new MenuItem("", "", "Help", attachPoints, ExtensionPoints.help, menuDefinition); - /*===== HELP.AFTER =====*/ - MenuItem helpAfter = new MenuItem("", "", "", attachPoints, ExtensionPoints.help_AFTER, menuDefinition); - helpAfter.setRendered(false); - MenuItem onlineDoc = new MenuItem("", "http://www.redhat.com/docs/en-US/JBoss_ON/", "Online Documentation", - help.getChildMenuItems(), ExtensionPoints.help, menuDefinition); - MenuItem support = new MenuItem("", "https://support.redhat.com/jbossnetwork/restricted/addCase.html", - "Open a Support Case", help.getChildMenuItems(), ExtensionPoints.openASupportCase, menuDefinition); - // Menu bar separator - help.getChildMenuItems().add(separator); - MenuItem about = new MenuItem("/images/icons/availability_grey_16.png", "", "", help.getChildMenuItems(), - ExtensionPoints.about, menuDefinition); - - //* ------------- REFRESH ------------------- *// - /*===== REFRESH.BEFORE extension pt. ============= */ - MenuItem refreshBefore = new MenuItem("", "", "", menu.getChildMenuItems(), ExtensionPoints.refresh_BEFORE, - menuDefinition); - refreshBefore.setRendered(false); - refreshBefore.setAlignLeft(false); - MenuItem refresh = new MenuItem("", "", "", attachPoints, ExtensionPoints.refresh, menuDefinition); - refresh.setAlignLeft(false); - /*===== HELP.AFTER =====*/ - MenuItem refreshAfter = new MenuItem("", "", "", attachPoints, ExtensionPoints.refresh_AFTER, menuDefinition); - refreshAfter.setRendered(false); - refreshAfter.setAlignLeft(false); - MenuItem stop = new MenuItem("", "", "Stop", refresh.getChildMenuItems(), ExtensionPoints.stop, menuDefinition); - MenuItem refresh1 = new MenuItem("", "", "Refresh every 1 minute", refresh.getChildMenuItems(), - ExtensionPoints.refreshEvery1Minute, menuDefinition); - MenuItem refresh5 = new MenuItem("", "", "Refresh every 5 minutes", refresh.getChildMenuItems(), - ExtensionPoints.refreshEvery5Minutes, menuDefinition); - MenuItem refresh10 = new MenuItem("", "", "Refresh every 10 minutes", refresh.getChildMenuItems(), - ExtensionPoints.refreshEvery10Minutes, menuDefinition); - - //* ------------- IS LOGGED IN ------------------- *// - /*===== IS LOGGED IN.BEFORE extension pt. Ignore same as refresh.after ============= */ - MenuItem loggedIn = new MenuItem("", "", "", attachPoints, ExtensionPoints.loggedInAs, menuDefinition); - loggedIn.setAlignLeft(false); - /*===== IS LOGGED IN.AFTER =====*/ - MenuItem loggedInAfter = new MenuItem("", "", "", attachPoints, ExtensionPoints.loggedInAs_AFTER, - menuDefinition); - loggedInAfter.setRendered(false); - loggedInAfter.setAlignLeft(false); - MenuItem edit = new MenuItem("", "", "Edit Details", loggedIn.getChildMenuItems(), ExtensionPoints.stop, - menuDefinition); - MenuItem change = new MenuItem("", "", "Change Password", loggedIn.getChildMenuItems(), - ExtensionPoints.refreshEvery1Minute, menuDefinition); - // Menu bar separator - loggedIn.getChildMenuItems().add(separator); - MenuItem logout = new MenuItem("", "/Logout.do", "Logout", loggedIn.getChildMenuItems(), - ExtensionPoints.refreshEvery5Minutes, menuDefinition); - - } - - public MenuItem getCoreMenuBar() { - return CoreMenuBar; - } - - public void setCoreMenuBar(MenuItem coreMenuBar) { - CoreMenuBar = coreMenuBar; - } - - public HashMap<String, MenuItem> getMenuDefinition() { - return menuDefinition; - } - - public void setMenuDefinition(HashMap<String, MenuItem> menuDefinition) { - this.menuDefinition = menuDefinition; - } - - public static void main(String[] args) { - PerspectivesMenuUIBean bean = new PerspectivesMenuUIBean(); - // System.out.println("Bean:" + bean); - MenuItem coreMenu = bean.getCoreMenuBar(); - HashMap<String, MenuItem> definition = bean.getMenuDefinition(); - //iterate over the coreMenu recursively - recurse(coreMenu, "(TOP)"); - //iterate over the map and display the values - Set<String> keys = definition.keySet(); - ArrayList<String> list = new ArrayList<String>(keys); - Collections.sort(list); - System.out.println("\n Key listing [" + keys.size() + " item(s)] \n"); - for (String key : list) { - System.out.println("KEY:" + key + "=" + definition.get(key)); + try { + result = perspectiveManager.getCoreMenu(subject); + } catch (PerspectiveException e) { + FacesContextUtility.addMessage(FacesMessage.SEVERITY_ERROR, "Failed to get core menu.", e); } - }
- private static void recurse(MenuItem menu, String prefix) { - if ((menu != null)) { - //base case: leaf - if (menu.getChildMenuItems().size() == 0) { - System.out.println(prefix + "#" + menu.getName() + ":" + menu.getExtensionKey() + ":"); - } else { - System.out.println(prefix + "[DIR-(" + menu.getChildMenuItems().size() + ")]" + menu.getName() + ":" - + menu.getExtensionKey() + ":"); - for (MenuItem child : menu.getChildMenuItems()) { - recurse(child, prefix + "\t"); - } - } - } + return result; } } diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/common/menu/menu.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/common/menu/menu.xhtml index 3beaf09..b5f3b15 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/common/menu/menu.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/common/menu/menu.xhtml @@ -1,555 +1,263 @@ -<a4j:region renderRegionOnly="true" selfRendered="true" - xmlns="http://www.w3.org/1999/xhtml" - xmlns:h="http://java.sun.com/jsf/html" - xmlns:c="http://java.sun.com/jstl/core" - xmlns:f="http://java.sun.com/jsf/core" - xmlns:onf="http://jboss.org/on/function" - xmlns:ui="http://java.sun.com/jsf/facelets" - xmlns:rich="http://richfaces.ajax4jsf.org/rich" - xmlns:a4j="http://richfaces.org/a4j%22%3E - - <h:form> - - <ui:include src="/rhq/common/ie6/ie6fix.xhtml" /> - - <f:loadBundle basename="ApplicationResources" var="msg" /> - - <rich:toolBar styleClass="topMenu"> - <rich:toolBarGroup location="left"> - - ui:remove===== If the component is enabled i.e. rendered==true =====</ui:remove> - <c:if test="#{PerspectivesMenuUIBean.coreMenuBar.rendered}"> - ui:remove===== If CoreMenu UI hasn't been disabled =====</ui:remove> - ui:remove===== Iterate through children[Top Menu Items] =====</ui:remove> - <c:forEach var="top" - items="#{PerspectivesMenuUIBean.coreMenuBar.childMenuItems}"> - <c:if test="#{top.rendered and top.alignLeft}"> - ui:remove===== LOGO TO HOME PAGE or other top-level-image menu item =====</ui:remove> - <c:if test="#{ExtensionPoints.logo == top.extensionKey or 'top-level-image' == top.extensionKey}"> - <h:outputLink value="/"> - <h:graphicImage value="#{top.iconUrl}" - width="#{top.iconWidth}" - height="#{top.iconHeight}" - rendered="#{top.rendered}" /> - </h:outputLink> - </c:if> - ui:remove===== DEBUG top-level menu item =====</ui:remove> - <c:if test="#{ExtensionPoints.debug == top.extensionKey}"> - <rich:dropDownMenu rendered="#{GlobalPermissionsUIBean.superuser and - GlobalPermissionsUIBean.debugMode}"> - <f:facet name="label"> - <h:panelGroup> - <h:outputText value="#{top.name}"/> - </h:panelGroup> - </f:facet> - <c:forEach var="child" - items="#{top.childMenuItems}"> - <rich:menuItem submitMode="none" - icon="#{child.iconUrl}" - width="#{child.iconWidth}" height="#{child.iconHeight}" - onclick="window.open('#{child.url}')" - target="blank_"> - <h:outputText value="#{child.name}"/> - </rich:menuItem> - </c:forEach> - </rich:dropDownMenu> - </c:if> - <c:if test="#{ExtensionPoints.logo != top.extensionKey and ExtensionPoints.debug != top.extensionKey}"> - rich:dropDownMenu - <f:facet name="label"> - <h:panelGroup> - <c:choose> - ui:remove= logic for administration =</ui:remove> - <c:when test="${ExtensionPoints.administration == top.extensionKey}"> - <h:outputText value="#{msg['admin.admin.AdministrationTitle']}"/> - </c:when> - ui:remove= logic for help =</ui:remove> - <c:when test="${ExtensionPoints.help == top.extensionKey}"> - <h:outputText value="#{msg['header.help.link']}"/> - </c:when> - <c:otherwise> - <h:outputText value="#{top.name}"/> - </c:otherwise> - </c:choose> - </h:panelGroup> - </f:facet> - ui:remove Now process the children MenuItems if they exist </ui:remove> - - <c:forEach var="child" - items="#{top.childMenuItems}"> - <c:if test="#{child.rendered}"> - <c:choose> - <c:when test="${child.childMenuItems.size > 0}"> - <rich:menuGroup value="#{child.name}"> - <c:forEach var="grandchild" - items="#{child.childMenuItems}"> - <rich:menuItem submitMode="none" icon="#{grandchild.iconUrl}" - width="#{grandchild.iconWidth}" height="#{grandchild.iconHeight}" - onclick="window.location = '#{grandchild.url}'"> - <h:outputText value="#{grandchild.name}" /> - </rich:menuItem> - </c:forEach> - </rich:menuGroup> - </c:when> - <c:otherwise> - <c:choose> - ui:remove= logic for platforms =</ui:remove> - <c:when test="${ExtensionPoints.platforms == child.extensionKey}"> - <rich:menuItem submitMode="none" icon="#{child.iconUrl}" - width="#{child.iconWidth}" height="#{child.iconHeight}" - onclick="window.location = '#{child.url}'"> - <h:outputText value="#{msg['resource.hub.filter.platform']}"/> - </rich:menuItem> - </c:when> - ui:remove= logic for servers =</ui:remove> - <c:when test="${ExtensionPoints.servers == child.extensionKey}"> - <rich:menuItem submitMode="none" icon="#{child.iconUrl}" - width="#{child.iconWidth}" height="#{child.iconHeight}" - onclick="window.location = '#{child.url}'"> - <h:outputText value="#{msg['resource.hub.filter.server']}"/> - </rich:menuItem> - </c:when> - ui:remove= logic for services =</ui:remove> - <c:when test="${ExtensionPoints.services == child.extensionKey}"> - <rich:menuItem submitMode="none" icon="#{child.iconUrl}" - width="#{child.iconWidth}" height="#{child.iconHeight}" - onclick="window.location = '#{child.url}'"> - <h:outputText value="#{msg['resource.hub.filter.service']}"/> - </rich:menuItem> - </c:when> - <c:when test="#{child.menuSeparator}"> - rich:menuSeparator/ - </c:when> - <c:when test="${ExtensionPoints.favoriteresources == child.extensionKey}"> - <rich:menuGroup value="#{child.name}" icon="#{child.iconUrl}" - width="#{child.iconWidth}" height="#{child.iconHeight}"> - <c:forEach var="resource" items="#{UserPreferencesUIBean.resourceFavorites}"> - <rich:menuItem submitMode="none" - icon="/images/icons/#{resource.resourceType.category}_up_16.png" - onclick="window.location = '#{onf:getDefaultResourceTabURL()}?id=#{resource.id}'"> - <h:outputText value="#{resource.name}"/> - </rich:menuItem> - </c:forEach> - </rich:menuGroup> - </c:when> - <c:when test="${ExtensionPoints.recentlyviewedresources == child.extensionKey}"> - ui:remove***** Resources > Recently Viewed *****</ui:remove> - <rich:menuGroup value="#{child.name}" icon="#{child.iconUrl}" - width="#{child.iconWidth}" height="#{child.iconHeight}"> - <c:forEach var="visit" items="#{UserPreferencesUIBean.recentVisits}"> - <c:if test="#{visit.kind == 'PLATFORM' or visit.kind == 'SERVER' or visit.kind == 'SERVICE'}"> - <rich:menuItem submitMode="none" - icon="/images/icons/#{visit.kind.displayName}_up_16.png" - onclick="window.location = '#{onf:getDefaultResourceTabURL()}?id=#{visit.id}'"> - <h:outputText value="#{visit.name}"/> - </rich:menuItem> - </c:if> - </c:forEach> - </rich:menuGroup> - </c:when> - <c:when test="${ExtensionPoints.searchresources == child.extensionKey}"> - ui:remove***** Resources > SEARCH *****</ui:remove> - <rich:menuItem submitMode="none" disabled="true" iconDisabled="/images/icons/Search_16.png"> - <h:outputText value="Search: " style="color: black;"/> - <h:panelGroup> - <h:inputText id="selectedResource" style="width: 250px;" immediate="true" - onkeypress="return ignoreEnterKey(event);" /> - <rich:suggestionbox id="resourceSelectBox" for="selectedResource" tokens=",[]" - ajaxSingle="true" immediate="true" - suggestionAction="#{ResourceSelectUIBean.autocomplete}" - var="result" data="foo" fetchValue="#{result.resource.id}" - nothingLabel="No matching resources found" - style="background-color: #cccccc;" - onselect="document.location.href='#{onf:getDefaultResourceTabURL()}?id=' + #{rich:element('selectedResource')}.value" - usingSuggestObjects="false" width="700" height="400"> - <h:column> - <f:facet name="header">Avail</f:facet> - <h:graphicImage - value="/images/icons/availability_#{result.availability == 'UP' ? 'green' : 'red'}_16.png"/> - </h:column> - <h:column> - <f:facet name="header">Resource</f:facet> - <h:outputText value="#{result.resource.name}"/> - </h:column> - <h:column> - <f:facet name="header">Parent</f:facet> - <h:outputText value="#{result.parent.name}"/> - </h:column> - </rich:suggestionbox> - </h:panelGroup> - </rich:menuItem> - </c:when> - <c:when test="${ExtensionPoints.mixed == child.extensionKey or - ExtensionPoints.compatible == child.extensionKey or - ExtensionPoints.definitions == child.extensionKey}"> - ui:remove***** Groups > COMPATIBLE GROUPS *****</ui:remove> - ui:remove***** Groups > MIXED GROUPS *****</ui:remove> - ui:remove***** Groups > GROUP DEFINITIONS *****</ui:remove> - <rich:menuItem submitMode="none" icon="#{child.iconUrl}" - width="#{child.iconWidth}" height="#{child.iconHeight}" - onclick="window.location = '#{child.url}'"> - <c:choose> - <c:when test="#{ExtensionPoints.compatible == child.extensionKey}"> - <h:outputText value="#{msg['resource.hub.filter.compatibleGroups']}"/> - </c:when> - <c:when test="#{ExtensionPoints.mixed == child.extensionKey}"> - <h:outputText value="#{msg['resource.hub.filter.mixedGroups']}"/> - </c:when> - <c:when test="#{ExtensionPoints.definitions == child.extensionKey}"> - <h:outputText value="#{msg['resource.hub.filter.groupDefinitions']}"/> - </c:when> - </c:choose> - </rich:menuItem> - </c:when> - <c:when test="#{ExtensionPoints.newgroup == child.extensionKey}"> - ui:remove***** Groups > NEW RESOURCE GROUP *****</ui:remove> - <rich:menuSeparator rendered="#{GlobalPermissionsUIBean.inventory}"/> - <rich:menuItem submitMode="none" onclick="window.location = '#{child.url}'" - rendered="#{GlobalPermissionsUIBean.inventory}"> - <h:outputText value="#{msg['resource.hub.NewGroupLink']}"/> - </rich:menuItem> - </c:when> - <c:when test="#{ExtensionPoints.newgroupdefinition == child.extensionKey}"> - ui:remove***** Groups > NEW GROUP DEFINITIONS *****</ui:remove> - <rich:menuItem submitMode="none" onclick="window.location = '#{child.url}'" - rendered="#{GlobalPermissionsUIBean.inventory}"> - <h:outputText value="#{msg['resource.hub.NewGroupDefinitionLink']}"/> - </rich:menuItem> - </c:when> - <c:when test="#{ExtensionPoints.favoritegroups == child.extensionKey}"> - ui:remove***** Groups > FAVORITE GROUPS *****</ui:remove> - <rich:menuGroup value="#{child.name}" icon="#{child.iconUrl}"> - <c:forEach var="group" items="#{UserPreferencesUIBean.groupFavorites}"> - <rich:menuItem submitMode="none" - icon="/images/icons/#{group.groupCategory == 'MIXED' ? 'Group' : 'Cluster'}_up_16.png" - onclick="window.location = '/rhq/group/inventory/view.xhtml?groupId=#{group.id}'"> - <h:outputText value="#{group.name}"/> - </rich:menuItem> - </c:forEach> - </rich:menuGroup> - </c:when> - <c:when test="${ExtensionPoints.recentlyviewedgroups == child.extensionKey}"> - ui:remove***** Groups > RECENTLY VIEWED *****</ui:remove> - <rich:menuGroup value="#{child.name}" icon="#{child.iconUrl}"> - <c:forEach var="visit" items="#{UserPreferencesUIBean.recentVisits}"> - <c:if test="#{visit.kind == 'COMPATIBLE_GROUP' or visit.kind == 'MIXED_GROUP'}"> - <rich:menuItem submitMode="none" - icon="/images/icons/#{visit.kind == 'COMPATIBLE_GROUP' ? 'Cluster' : 'Group'}_up_16.png" - onclick="window.location = '/rhq/group/inventory/view.xhtml?groupId=#{visit.id}'"> - <h:outputText value="#{visit.name}"/> - </rich:menuItem> - </c:if> - </c:forEach> - </rich:menuGroup> - </c:when> - <c:when test="${ExtensionPoints.searchgroups == child.extensionKey}"> - ui:remove***** Groups > SEARCH *****</ui:remove> - <rich:menuItem submitMode="none" disabled="true" iconDisabled="/images/icons/Search_16.png"> - <h:outputText value="Search: " style="color: black;"/> - <h:panelGroup> - <h:inputText id="selectedGroup" style="width: 250px;" immediate="true" - onkeypress="return ignoreEnterKey(event);" /> - <rich:suggestionbox id="groupSelectBox" for="selectedGroup" tokens=",[]" - ajaxSingle="true" immediate="true" - suggestionAction="#{ResourceGroupSelectUIBean.autocomplete}" - var="result" data="foo" fetchValue="#{result.groupQueryString}" - nothingLabel="No matching groups found" - style="background-color: #cccccc;" - onselect="document.location.href='/rhq/group/inventory/view.xhtml?' + #{rich:element('selectedGroup')}.value" - usingSuggestObjects="false" width="700" height="400"> - <h:column> - <f:facet name="header">Avail</f:facet> - <h:graphicImage value="/images/icons/availability_green_16.png" rendered="#{result.implicitUp > 0 and result.implicitDown == 0}"/> - <h:graphicImage value="/images/icons/availability_red_16.png" rendered="#{result.implicitUp == 0 and result.implicitDown > 0}"/> - <h:graphicImage value="/images/icons/availability_yellow_16.png" rendered="#{result.implicitUp > 0 and result.implicitDown > 0}"/> - <h:graphicImage value="/images/icons/availability_grey_16.png" rendered="#{result.implicitUp == 0 and result.implicitDown == 0}"/> - </h:column> - <h:column> - <f:facet name="header">Group</f:facet> - <h:outputText value="#{result.resourceGroup.name}"/> - </h:column> - <h:column> - <f:facet name="header">Category</f:facet> - <h:outputText value="#{result.category.name}" rendered="#{result.category.name == 'MIXED'}"/> - <h:outputText value="#{result.resourceGroup.resourceType.name}" rendered="#{result.category.name == 'COMPATIBLE'}"/> - </h:column> - </rich:suggestionbox> - </h:panelGroup> - </rich:menuItem> - </c:when> - <c:when test="#{ExtensionPoints.about == child.extensionKey}"> - ui:remove***** Help > ABOUT *****</ui:remove> - <rich:menuItem submitMode="none" id="aboutLink" icon="#{child.iconUrl}" - width="#{child.iconWidth}" height="#{child.iconHeight}"> - <h:outputText value="#{msg['header.about.link']}"/> - <rich:componentControl for="aboutPanel" attachTo="aboutLink" operation="show" event="onclick"/> - </rich:menuItem> - </c:when> - <c:otherwise> - <rich:menuItem submitMode="none" icon="#{child.iconUrl}" - width="#{child.iconWidth}" height="#{child.iconHeight}" - onclick="window.location = '#{child.url}'"> - <h:outputText value="#{child.name}" /> - </rich:menuItem> - </c:otherwise> - </c:choose> - </c:otherwise> - </c:choose> - </c:if> - </c:forEach> - </rich:dropDownMenu> - </c:if> - </c:if> - </c:forEach> - </c:if> - </rich:toolBarGroup> - - ui:remove===== Display CoreMenu right aligned components =====</ui:remove> - <rich:toolBarGroup location="right"> - <a4j:status id="commonStatus" layout="block" - startStyle=" filter:alpha(opacity=85); -moz-opacity: 0.85; opacity: 0.85; vertical-align: middle;"> - <f:facet name="start"> - <img src="/images/ajax-loader.gif" alt="" style="vertical-align:middle;"/> <span - style="vertical-align: middle;">Loading...</span> - </f:facet> - </a4j:status> - - <c:if test="#{PerspectivesMenuUIBean.coreMenuBar.rendered}"> - ui:remove===== If CoreMenu UI hasn't been disabled =====</ui:remove> - ui:remove===== Iterate through children[Top Menu Items - RIGHT ALIGNED] =====</ui:remove> - <c:forEach var="top" - items="#{PerspectivesMenuUIBean.coreMenuBar.childMenuItems}"> - <c:if test="#{top.rendered and top.alignLeft == false}"> - - ui:remove===== Refresh item =====</ui:remove> - <c:if test="#{ExtensionPoints.refresh == top.extensionKey}"> - <rich:dropDownMenu rendered="#{request.method == 'GET'}"> - <f:facet name="label"> - <h:panelGroup> - <h:graphicImage value="/images/refreshRunning.gif" rendered="#{UserPreferencesUIBean.pageRefresh != 0}"/> - <h:graphicImage value="/images/refreshStopped.gif" rendered="#{UserPreferencesUIBean.pageRefresh == 0}"/> - <span id="refreshTimeLeft" style="width: 0px;"><h:outputText value="#{UserPreferencesUIBean.pageRefresh}" rendered="#{UserPreferencesUIBean.pageRefresh != 0}"/></span> - </h:panelGroup> - </f:facet> - <rich:menuItem submitMode="none" onclick="updatePageRefresh('#{request.getAttribute('javax.servlet.forward.request_uri')}', 0)"> - <h:outputText value="Stop"/> - <f:facet name="icon"> - <h:graphicImage value="/images/#{UserPreferencesUIBean.pageRefresh == 0 ? 'check.png' : 'spacer.gif'}" width="16" height="16"/> - </f:facet> - </rich:menuItem> - <rich:menuItem submitMode="none" onclick="updatePageRefresh('#{request.getAttribute('javax.servlet.forward.request_uri')}',60)"> - <h:outputText value="Refresh every 1 minute"/> - <f:facet name="icon"> - <h:graphicImage value="/images/#{UserPreferencesUIBean.pageRefresh == 60 ? 'check.png' : 'spacer.gif'}" width="16" height="16"/> - </f:facet> - </rich:menuItem> - <rich:menuItem submitMode="none" onclick="updatePageRefresh('#{request.getAttribute('javax.servlet.forward.request_uri')}',300)"> - <h:outputText value="Refresh every 5 minutes"/> - <f:facet name="icon"> - <h:graphicImage value="/images/#{UserPreferencesUIBean.pageRefresh == 300 ? 'check.png' : 'spacer.gif'}" width="16" height="16"/> - </f:facet> - </rich:menuItem> - <rich:menuItem submitMode="none" onclick="updatePageRefresh('#{request.getAttribute('javax.servlet.forward.request_uri')}',600)"> - <h:outputText value="Refresh every 10 minutes"/> - <f:facet name="icon"> - <h:graphicImage value="/images/#{UserPreferencesUIBean.pageRefresh == 600 ? 'check.png' : 'spacer.gif'}" width="16" height="16"/> - </f:facet> - </rich:menuItem> - </rich:dropDownMenu> - </c:if> - ui:remove===== LoggedInAs item =====</ui:remove> - <c:if test="#{ExtensionPoints.loggedinas == top.extensionKey}"> - rich:dropDownMenu - <f:facet name="label"> - <h:panelGroup> - <h:outputText value="Logged in as #{UserPreferencesUIBean.subject.name}"/> - </h:panelGroup> - </f:facet> - ui:remove Now process the children MenuItems if they exist </ui:remove> - <c:forEach var="child" - items="#{top.childMenuItems}"> - <c:if test="#{child.rendered}"> - <c:choose> - <c:when test="${child.childMenuItems.size > 0}"> - <rich:menuGroup value="#{child.name}"> - <c:forEach var="grandchild" - items="#{child.childMenuItems}"> - <c:choose> - <c:when test="#{grandchild.menuSeparator}"> - rich:menuSeparator/ - </c:when> - <c:otherwise> - <rich:menuItem submitMode="none" icon="#{grandchild.iconUrl}" - width="#{grandchild.iconWidth}" height="#{grandchild.iconHeight}" - onclick="window.location = '#{grandchild.url}'"> - <h:outputText value="#{grandchild.name}" /> - </rich:menuItem> - </c:otherwise> - </c:choose> - </c:forEach> - </rich:menuGroup> - </c:when> - <c:otherwise> - <c:choose> - <c:when test="#{child.menuSeparator}"> - rich:menuSeparator/ - </c:when> - <c:otherwise> - <rich:menuItem submitMode="none" icon="#{child.iconUrl}" - width="#{child.iconWidth}" height="#{child.iconHeight}" - onclick="window.location = '#{child.url}'"> - <h:outputText value="#{child.name}" /> - </rich:menuItem> - </c:otherwise> - </c:choose> - </c:otherwise> - </c:choose> - </c:if> - </c:forEach> - </rich:dropDownMenu> - </c:if> - <c:if test="#{ExtensionPoints.loggedinas != top.extensionKey and ExtensionPoints.refresh != top.extensionKey}"> - rich:dropDownMenu - <f:facet name="label"> - <h:panelGroup> - <h:outputText value="#{top.name}"/> - </h:panelGroup> - </f:facet> - ui:remove Now process the children MenuItems if they exist </ui:remove> - <c:forEach var="child" - items="#{top.childMenuItems}"> - <c:if test="#{child.rendered}"> - <c:choose> - <c:when test="${child.childMenuItems.size > 0}"> - <rich:menuGroup value="#{child.name}"> - <c:forEach var="grandchild" - items="#{child.childMenuItems}"> - <c:choose> - <c:when test="#{grandchild.menuSeparator}"> - rich:menuSeparator/ - </c:when> - <c:otherwise> - <rich:menuItem submitMode="none" icon="#{grandchild.iconUrl}" - width="#{grandchild.iconWidth}" height="#{grandchild.iconHeight}" - onclick="window.location = '#{grandchild.url}'"> - <h:outputText value="#{grandchild.name}" /> - </rich:menuItem> - </c:otherwise> - </c:choose> - </c:forEach> - </rich:menuGroup> - </c:when> - <c:otherwise> - <c:choose> - <c:when test="#{child.menuSeparator}"> - rich:menuSeparator/ - </c:when> - <c:otherwise> - <rich:menuItem submitMode="none" icon="#{child.iconUrl}" - width="#{child.iconWidth}" height="#{child.iconHeight}" - onclick="window.location = '#{child.url}'"> - <h:outputText value="#{child.name}" /> - </rich:menuItem> - </c:otherwise> - </c:choose> - </c:otherwise> - </c:choose> - </c:if> - </c:forEach> - </rich:dropDownMenu> - </c:if> - </c:if> - </c:forEach> - </c:if> - </rich:toolBarGroup> - </rich:toolBar> - - <rich:modalPanel id="aboutPanel" resizeable="false" width="320" - height="250"> - <f:facet name="header"> - <h:panelGroup> - <h:outputText value="#{msg['about.Title']}" /> - </h:panelGroup> - </f:facet> - <f:facet name="controls"> - <h:panelGroup> - <h:graphicImage value="/images/close.png" style="cursor:pointer;" - id="hidelink" /> - <rich:componentControl for="aboutPanel" attachTo="hidelink" - operation="hide" event="onclick" /> - </h:panelGroup> - </f:facet> - - <p><span class="DisplaySubhead"><h:outputText - value="#{msg['footer.aboutLink']}" /></span><br /> - <span class="DisplayLabel"><h:outputText - value="#{msg['footer.version']}: #{msg['product.version']}" /></span><br /> - <span class="DisplayLabel"><h:outputText - value="#{msg['footer.buildNumber']}: #{msg['product.buildNumber']}" /></span> - </p> - - <p><a href="http://jboss.org/"> <img - src="/images/jboss_logo.png" alt="JBoss Homepage" - title="JBoss by Red Hat" height="55" /> </a></p> - - <p><f:verbatim> - <h:outputText value="#{msg['footer.copyright']}" /> - </f:verbatim> <h:outputText value="#{msg['about.Copyright.Content']}" /></p> - - <p><a href="http://jboss.org/jopr"> <h:graphicImage - value="/images/logo_icon.png" style="vertical-align:middle" /> Jopr - Project </a> ui:remove - <!--<h:outputText value="#{msg['about.MoreInfo.Label']}"/><br/>--> - <!-- - <a href='mailto:<h:outputText value="#{msg['about.MoreInfo.LinkSales']}"/>'><h:outputText value="#{msg['about.MoreInfo.LinkSales']}"/></a><br/> - <a href='mailto:<h:outputText value="#{msg['about.MoreInfo.LinkSupport']}"/>'><h:outputText value="#{msg['about.MoreInfo.LinkSupport']}"/></a> - --> - </ui:remove></p> +<a4j:region + renderRegionOnly="true" + selfRendered="true" + xmlns="http://www.w3.org/1999/xhtml" + xmlns:h="http://java.sun.com/jsf/html" + xmlns:c="http://java.sun.com/jstl/core" + xmlns:f="http://java.sun.com/jsf/core" + xmlns:onf="http://jboss.org/on/function" + xmlns:ui="http://java.sun.com/jsf/facelets" + xmlns:rich="http://richfaces.ajax4jsf.org/rich" + xmlns:a4j="http://richfaces.org/a4j%22%3E + + <h:form> + + <ui:include src="/rhq/common/ie6/ie6fix.xhtml" /> + + <f:loadBundle + basename="ApplicationResources" + var="msg" /> + + <rich:toolBar styleClass="topMenu"> + <rich:toolBarGroup location="left"> + + ui:remove===== Grab the core menu from the perspective manager =====</ui:remove> + + <c:forEach + var="menuItem" + items="#{PerspectivesMenuUIBean.coreMenu}"> + + <c:if test="#{not menuItem.item.isDebug or GlobalPermissionsUIBean.debugMode}"> + + <rich:dropDownMenu rendered="${menuItem.menuGroup}"> + <f:facet name="label"> + <h:panelGroup> + <h:outputText value="#{menuItem.item.displayName}" /> + </h:panelGroup> + </f:facet> + + <c:forEach + var="childMenuItem" + items="#{menuItem.children}"> + + <rich:menuGroup + rendered="#{childMenuItem.menuGroup}" + value="#{childMenuItem.item.displayName}"> + <c:forEach + var="grandchildMenuItem" + items="#{childMenuItem.children}"> + + <ui:param + name="currentMenuItem" + value="#{grandchildMenuItem}" /> + <ui:include src="/rhq/common/menu/menuitem.xhtml" /> + + </c:forEach> + </rich:menuGroup>
+ <c:if test="#{not childMenuItem.menuGroup}"> + <ui:param + name="currentMenuItem" + value="#{childMenuItem}" /> + <ui:include src="/rhq/common/menu/menuitem.xhtml" /> + </c:if>
- <input type="button" value="Close" - onclick="Richfaces.hideModalPanel('aboutPanel');" /> - </rich:modalPanel> + </c:forEach> + </rich:dropDownMenu>
- </h:form> + <h:outputLink + rendered="#{menuItem.graphic}" + value="#{menuItem.item.url}"> + <h:graphicImage value="#{menuItem.item.iconUrl}" /> + </h:outputLink>
+ <c:if test="#{not menuItem.menuGroup and not menuItem.graphic}"> + <ui:param + name="currentMenuItem" + value="#{menuItem}" /> + <ui:include src="/rhq/common/menu/menuitem.xhtml" /> + </c:if>
- <a4j:region renderRegionOnly="true" selfRendered="true"> + </c:if>
+ </c:forEach>
- <script type="text/javascript"> + </rich:toolBarGroup>
- function refresh() { + <rich:toolBarGroup location="right">
- timeLeft = timeLeft - 1; - document.getElementById("refreshTimeLeft").innerHTML = timeLeft; + <a4j:status + id="commonStatus" + layout="block" + startStyle=" filter:alpha(opacity=85); -moz-opacity: 0.85; opacity: 0.85; vertical-align: middle;"> + <f:facet name="start"> + <img + src="/images/ajax-loader.gif" + alt="" + style="vertical-align: middle;" /> + <span style="vertical-align: middle;">Loading...</span> + </f:facet> + </a4j:status>
- if (timeLeft < 1) { - window.location.href = window.location.href; - } - setTimeout("refresh()", 1000); - } + ui:remove***** Refresh Graphic *****</ui:remove> + <rich:dropDownMenu rendered="#{request.method == 'GET'}"> + <f:facet name="label"> + <h:panelGroup> + <h:graphicImage + value="/images/refreshRunning.gif" + rendered="#{UserPreferencesUIBean.pageRefresh != 0}" /> + <h:graphicImage + value="/images/refreshStopped.gif" + rendered="#{UserPreferencesUIBean.pageRefresh == 0}" /> + <span + id="refreshTimeLeft" + style="width: 0px;"><h:outputText + value="#{UserPreferencesUIBean.pageRefresh}" + rendered="#{UserPreferencesUIBean.pageRefresh != 0}" /></span>
- var refreshTime = <h:outputText value="#{UserPreferencesUIBean.pageRefresh}"/>; - var timeLeft = refreshTime; + </h:panelGroup> + </f:facet>
- if (refreshTime > 0) { - setTimeout("refresh()", 1000); - } + ui:remove***** Refresh Intervals *****</ui:remove> + <rich:menuItem + submitMode="none" + onclick="updatePageRefresh('#{request.getAttribute('javax.servlet.forward.request_uri')}', 0)"> + <h:outputText value="Stop" /> + <f:facet name="icon"> + <h:graphicImage + value="/images/#{UserPreferencesUIBean.pageRefresh == 0 ? 'check.png' : 'spacer.gif'}" + width="16" + height="16" /> + </f:facet> + </rich:menuItem> + <rich:menuItem + submitMode="none" + onclick="updatePageRefresh('#{request.getAttribute('javax.servlet.forward.request_uri')}',60)"> + <h:outputText value="Refresh every 1 minute" /> + <f:facet name="icon"> + <h:graphicImage + value="/images/#{UserPreferencesUIBean.pageRefresh == 60 ? 'check.png' : 'spacer.gif'}" + width="16" + height="16" /> + </f:facet> + </rich:menuItem> + <rich:menuItem + submitMode="none" + onclick="updatePageRefresh('#{request.getAttribute('javax.servlet.forward.request_uri')}',300)"> + <h:outputText value="Refresh every 5 minutes" /> + <f:facet name="icon"> + <h:graphicImage + value="/images/#{UserPreferencesUIBean.pageRefresh == 300 ? 'check.png' : 'spacer.gif'}" + width="16" + height="16" /> + </f:facet> + </rich:menuItem> + <rich:menuItem + submitMode="none" + onclick="updatePageRefresh('#{request.getAttribute('javax.servlet.forward.request_uri')}',600)"> + <h:outputText value="Refresh every 10 minutes" /> + <f:facet name="icon"> + <h:graphicImage + value="/images/#{UserPreferencesUIBean.pageRefresh == 600 ? 'check.png' : 'spacer.gif'}" + width="16" + height="16" /> + </f:facet> + </rich:menuItem>
+ </rich:dropDownMenu> + + ui:remove***** Logged in as > EDIT DETAILS *****</ui:remove> + rich:dropDownMenu + <f:facet name="label"> + <h:panelGroup> + <h:outputText value="Logged in as #{UserPreferencesUIBean.subject.name}" /> + </h:panelGroup> + </f:facet> + + ui:remove***** Logged in as > EDIT DETAILS *****</ui:remove> + <rich:menuItem + submitMode="none" + onclick="window.location = '/admin/user/UserAdmin.do?mode=edit&u=#{UserPreferencesUIBean.subject.id}'"> + <h:outputText value="Edit Details" /> + </rich:menuItem> + + ui:remove***** Logged in as > CHANGE PASSWORD *****</ui:remove> + <rich:menuItem + submitMode="none" + onclick="window.location = '/admin/user/UserAdmin.do?mode=editPass&u=#{UserPreferencesUIBean.subject.id}'"> + <h:outputText value="Change Password" /> + </rich:menuItem> + + <rich:menuSeparator /> + + ui:remove***** Logged in as > LOGOUT *****</ui:remove> + <rich:menuItem + submitMode="none" + onclick="window.location = '/Logout.do'"> + <h:outputText value="Logout" /> + </rich:menuItem> + </rich:dropDownMenu> + + </rich:toolBarGroup> + + </rich:toolBar> + + <rich:modalPanel + id="aboutPanel" + resizeable="false" + width="320" + height="250"> + <f:facet name="header"> + <h:panelGroup> + <h:outputText value="#{msg['about.Title']}" /> + </h:panelGroup> + </f:facet> + <f:facet name="controls"> + <h:panelGroup> + <h:graphicImage + value="/images/close.png" + style="cursor:pointer;" + id="hidelink" /> + <rich:componentControl + for="aboutPanel" + attachTo="hidelink" + operation="hide" + event="onclick" /> + </h:panelGroup> + </f:facet> + + <p><span class="DisplaySubhead"><h:outputText value="#{msg['footer.aboutLink']}" /></span><br /> + <span class="DisplayLabel"><h:outputText value="#{msg['footer.version']}: #{msg['product.version']}" /></span><br /> + <span class="DisplayLabel"><h:outputText + value="#{msg['footer.buildNumber']}: #{msg['product.buildNumber']}" /></span></p> + + <p><a href="http://jboss.org/"> <img + src="/images/jboss_logo.png" + alt="JBoss Homepage" + title="JBoss by Red Hat" + height="55" /> </a></p> + + <p><f:verbatim> + <h:outputText value="#{msg['footer.copyright']}" /> + </f:verbatim> <h:outputText value="#{msg['about.Copyright.Content']}" /></p> + + <p><a href="http://jboss.org/jopr"> <h:graphicImage + value="/images/logo_icon.png" + style="vertical-align:middle" /> Jopr Project </a> ui:remove + <!--<h:outputText value="#{msg['about.MoreInfo.Label']}"/><br/>--> + <!-- + <a href='mailto:<h:outputText value="#{msg['about.MoreInfo.LinkSales']}"/>'><h:outputText value="#{msg['about.MoreInfo.LinkSales']}"/></a><br/> + <a href='mailto:<h:outputText value="#{msg['about.MoreInfo.LinkSupport']}"/>'><h:outputText value="#{msg['about.MoreInfo.LinkSupport']}"/></a> + --> + </ui:remove></p>
+ <input + type="button" + value="Close" + onclick="Richfaces.hideModalPanel('aboutPanel');" /> + </rich:modalPanel>
- </script>
- a4j:form - <a4j:jsFunction name="updatePageRefresh" status="commonStatus" - oncomplete="window.location.href = window.location.href;"> - <a4j:actionparam name="param1" - assignTo="#{UserPreferencesUIBean.refreshPath}" /> - <a4j:actionparam name="param2" - assignTo="#{UserPreferencesUIBean.pageRefresh}" /> - </a4j:jsFunction> - </a4j:form> - </a4j:region> + </h:form>
</a4j:region> diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/common/menu/menuitem.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/common/menu/menuitem.xhtml new file mode 100644 index 0000000..bfb0140 --- /dev/null +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/common/menu/menuitem.xhtml @@ -0,0 +1,255 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE html + PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html + xmlns:h="http://java.sun.com/jsf/html" + xmlns:f="http://java.sun.com/jsf/core" + xmlns:c="http://java.sun.com/jstl/core" + xmlns:ui="http://java.sun.com/jsf/facelets" + xmlns:rich="http://richfaces.ajax4jsf.org/rich" + xmlns:a4j="https://ajax4jsf.dev.java.net/ajax" + xmlns:onf="http://jboss.org/on/function%22%3E + +<body> +<f:view> + +Usage: The following parameters must be set in the calling page + +currentMenuItem - the org.rhq.enterprise.server.perspective.menuItem to render + +ui:composition + + <c:if test="#{not currentMenuItem.item.isDebug or GlobalPermissionsUIBean.debugMode}"> + + <c:if test="#{currentMenuItem.item.position.addBreak}"> + <rich:menuSeparator /> + </c:if> + + <c:choose> + <c:when test="#{currentMenuItem.item.feature eq null}"> + <c:choose> + <c:when test="#{currentMenuItem.item.newWindow}"> + <rich:menuItem + submitMode="none" + onclick="window.open('#{currentMenuItem.item.url}')" + target="blank_" + icon="#{currentMenuItem.item.iconUrl}" + width="#{currentMenuItem.item.iconWidth}" + height="#{currentMenuItem.item.iconHeight}"> + <h:outputText value="#{currentMenuItem.item.displayName}" /> + </rich:menuItem> + </c:when> + <c:otherwise> + <rich:menuItem + submitMode="none" + onclick="window.location = '#{currentMenuItem.item.url}'" + icon="#{currentMenuItem.item.iconUrl}" + width="#{currentMenuItem.item.iconWidth}" + height="#{currentMenuItem.item.iconHeight}"> + <h:outputText value="#{currentMenuItem.item.displayName}" /> + </rich:menuItem> + </c:otherwise> + </c:choose> + </c:when> + <c:when test="#{currentMenuItem.item.feature eq 'ABOUT_BOX'}"> + <rich:menuItem + submitMode="none" + id="aboutLink" + icon="#{currentMenuItem.item.iconUrl}"> + <h:outputText value="#{currentMenuItem.item.displayName}" /> + <rich:componentControl + for="aboutPanel" + attachTo="aboutLink" + operation="show" + event="onclick" /> + </rich:menuItem> + </c:when> + <c:when test="#{currentMenuItem.item.feature eq 'GROUP_FAVORITES'}"> + <rich:menuGroup + value="#{currentMenuItem.item.displayName}" + icon="#{currentMenuItem.item.iconUrl}"> + <c:forEach + var="group" + items="#{UserPreferencesUIBean.groupFavorites}"> + <rich:menuItem + submitMode="none" + icon="/images/icons/#{group.groupCategory == 'MIXED' ? 'Group' : 'Cluster'}_up_16.png" + onclick="window.location = '/rhq/group/inventory/view.xhtml?groupId=#{group.id}'"> + <h:outputText value="#{group.name}" /> + </rich:menuItem> + </c:forEach> + </rich:menuGroup> + </c:when> + <c:when test="#{currentMenuItem.item.feature eq 'GROUP_RECENTLY_VIEWED'}"> + <rich:menuGroup + value="#{currentMenuItem.item.displayName}" + icon="#{currentMenuItem.item.iconUrl}"> + <c:forEach + var="visit" + items="#{UserPreferencesUIBean.recentVisits}"> + <c:if test="#{visit.kind == 'COMPATIBLE_GROUP' or visit.kind == 'MIXED_GROUP'}"> + <rich:menuItem + submitMode="none" + icon="/images/icons/#{visit.kind == 'COMPATIBLE_GROUP' ? 'Cluster' : 'Group'}_up_16.png" + onclick="window.location = '/rhq/group/inventory/view.xhtml?groupId=#{visit.id}'"> + <h:outputText value="#{visit.name}" /> + </rich:menuItem> + </c:if> + </c:forEach> + </rich:menuGroup> + </c:when> + <c:when test="#{currentMenuItem.item.feature eq 'GROUP_SEARCH'}"> + <rich:menuItem + submitMode="none" + disabled="true" + iconDisabled="#{currentMenuItem.item.iconUrl}"> + <h:outputText + value="#{currentMenuItem.item.displayName} " + style="color: black;" /> + <h:panelGroup> + <h:inputText + id="selectedGroup" + style="width: 250px;" + immediate="true" + onkeypress="return ignoreEnterKey(event);" /> + <rich:suggestionbox + id="groupSelectBox" + for="selectedGroup" + tokens=",[]" + ajaxSingle="true" + immediate="true" + suggestionAction="#{ResourceGroupSelectUIBean.autocomplete}" + var="result" + data="foo" + fetchValue="#{result.groupQueryString}" + nothingLabel="No matching groups found" + style="background-color: #cccccc;" + onselect="document.location.href='/rhq/group/inventory/view.xhtml?' + #{rich:element('selectedGroup')}.value" + usingSuggestObjects="false" + width="700" + height="400"> + <h:column> + <f:facet name="header">Avail</f:facet> + <h:graphicImage + value="/images/icons/availability_green_16.png" + rendered="#{result.implicitUp > 0 and result.implicitDown == 0}" /> + <h:graphicImage + value="/images/icons/availability_red_16.png" + rendered="#{result.implicitUp == 0 and result.implicitDown > 0}" /> + <h:graphicImage + value="/images/icons/availability_yellow_16.png" + rendered="#{result.implicitUp > 0 and result.implicitDown > 0}" /> + <h:graphicImage + value="/images/icons/availability_grey_16.png" + rendered="#{result.implicitUp == 0 and result.implicitDown == 0}" /> + </h:column> + <h:column> + <f:facet name="header">Group</f:facet> + <h:outputText value="#{result.resourceGroup.name}" /> + </h:column> + <h:column> + <f:facet name="header">Category</f:facet> + <h:outputText + value="#{result.category.name}" + rendered="#{result.category.name == 'MIXED'}" /> + <h:outputText + value="#{result.resourceGroup.resourceType.name}" + rendered="#{result.category.name == 'COMPATIBLE'}" /> + </h:column> + </rich:suggestionbox> + </h:panelGroup> + </rich:menuItem> + </c:when> + <c:when test="#{currentMenuItem.item.feature eq 'RESOURCE_FAVORITES'}"> + <rich:menuGroup + value="#{currentMenuItem.item.displayName}" + icon="#{currentMenuItem.item.iconUrl}"> + <c:forEach + var="resource" + items="#{UserPreferencesUIBean.resourceFavorites}"> + <rich:menuItem + submitMode="none" + icon="/images/icons/#{resource.resourceType.category}_up_16.png" + onclick="window.location = '#{onf:getDefaultResourceTabURL()}?id=#{resource.id}'"> + <h:outputText value="#{resource.name}" /> + </rich:menuItem> + </c:forEach> + </rich:menuGroup> + </c:when> + <c:when test="#{currentMenuItem.item.feature eq 'RESOURCE_RECENTLY_VIEWED'}"> + <rich:menuGroup + value="#{currentMenuItem.item.displayName}" + icon="#{currentMenuItem.item.iconUrl}"> + <c:forEach + var="visit" + items="#{UserPreferencesUIBean.recentVisits}"> + <c:if test="#{visit.kind == 'PLATFORM' or visit.kind == 'SERVER' or visit.kind == 'SERVICE'}"> + <rich:menuItem + submitMode="none" + icon="/images/icons/#{visit.kind.displayName}_up_16.png" + onclick="window.location = '#{onf:getDefaultResourceTabURL()}?id=#{visit.id}'"> + <h:outputText value="#{visit.name}" /> + </rich:menuItem> + </c:if> + </c:forEach> + </rich:menuGroup> + </c:when> + <c:when test="#{currentMenuItem.item.feature eq 'RESOURCE_SEARCH'}"> + <rich:menuItem + submitMode="none" + disabled="true" + iconDisabled="#{currentMenuItem.item.iconUrl}"> + <h:outputText + value="#{currentMenuItem.item.displayName} " + style="color: black;" /> + <h:panelGroup> + <h:inputText + id="selectedResource" + style="width: 250px;" + immediate="true" + onkeypress="return ignoreEnterKey(event);" /> + <rich:suggestionbox + id="resourceSelectBox" + for="selectedResource" + tokens=",[]" + ajaxSingle="true" + immediate="true" + suggestionAction="#{ResourceSelectUIBean.autocomplete}" + var="result" + data="foo" + fetchValue="#{result.resource.id}" + nothingLabel="No matching resources found" + style="background-color: #cccccc;" + onselect="document.location.href='#{onf:getDefaultResourceTabURL()}?id=' + #{rich:element('selectedResource')}.value" + usingSuggestObjects="false" + width="700" + height="400"> + <h:column> + <f:facet name="header">Avail</f:facet> + <h:graphicImage + value="/images/icons/availability_#{result.availability == 'UP' ? 'green' : 'red'}_16.png" /> + </h:column> + <h:column> + <f:facet name="header">Resource</f:facet> + <h:outputText value="#{result.resource.name}" /> + </h:column> + <h:column> + <f:facet name="header">Parent</f:facet> + <h:outputText value="#{result.parent.name}" /> + </h:column> + </rich:suggestionbox> + </h:panelGroup> + </rich:menuItem> + </c:when> + </c:choose> + + </c:if> + + <div style="clear: both;" /> + + </ui:composition> + +</f:view> +</body> +</html> \ No newline at end of file diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/perspective/MenuItem.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/perspective/MenuItem.java index 8284b5e..902e05e 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/perspective/MenuItem.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/perspective/MenuItem.java @@ -28,6 +28,15 @@ public class MenuItem { this.children = children; }
+ public boolean isMenuGroup() { + return (null != this.children && this.children.size() > 0); + } + + public boolean isGraphic() { + String displayName = this.item.getDisplayName(); + return (null == displayName || "".equals(displayName.trim())); + } + /** * @return the item */ diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveManagerBean.java index c6638b3..67a08be 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveManagerBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveManagerBean.java @@ -18,7 +18,9 @@ */ package org.rhq.enterprise.server.perspective;
+import java.util.HashMap; import java.util.List; +import java.util.Map;
import javax.ejb.EJB; import javax.ejb.Stateless; @@ -38,6 +40,13 @@ public class PerspectiveManagerBean implements PerspectiveManagerLocal, Perspect
private final Log log = LogFactory.getLog(PerspectiveManagerBean.class);
+ // Map of sessionId to cached menu entry. The cached menu is re-used for the same sessionId. + // This should more appropriately use Subject as the key but since Subject equality is + // based on username it's not quite appropriate. + // The cache is cleaned anytime there is a new entry. + static private Map<Integer, CacheEntry> cache = new HashMap<Integer, CacheEntry>(); + private List<MenuItem> coreMenu; + @PersistenceContext(unitName = RHQConstants.PERSISTENCE_UNIT_NAME) private EntityManager entityManager;
@@ -48,25 +57,53 @@ public class PerspectiveManagerBean implements PerspectiveManagerLocal, Perspect * @see org.rhq.enterprise.server.perspective.PerspectiveManagerLocal#getCoreMenu(org.rhq.core.domain.auth.Subject) */ @Override - public List<MenuItem> getCoreMenu(Subject subject) throws PerspectiveException { - List<MenuItem> coreMenu = null; + public synchronized List<MenuItem> getCoreMenu(Subject subject) throws PerspectiveException { + Integer sessionId = subject.getSessionId(); + CacheEntry cacheEntry = cache.get(sessionId); + + if (null == cacheEntry) { + // take this opportunity to clean the cache + cleanCache();
- try { - coreMenu = PerspectiveManagerHelper.getPluginMetadataManager().getCoreMenu(); - } catch (Exception e) { - throw new PerspectiveException("Failed to get Core Menu.", e); + cacheEntry = new CacheEntry(); + cache.put(sessionId, cacheEntry); }
- // TODO: Apply Activators here + List<MenuItem> coreMenu = cacheEntry.getCoreMenu();
- // TODO: Cache session:menu map here + if (null == coreMenu) { + try { + coreMenu = PerspectiveManagerHelper.getPluginMetadataManager().getCoreMenu();
- // TODO: remove this debug code - printMenu(coreMenu, ""); + // TODO : make safe copy + cacheEntry.setCoreMenu(coreMenu); + } catch (Exception e) { + throw new PerspectiveException("Failed to get Core Menu.", e); + } + } + + // TODO: Apply Activators here
return coreMenu; }
+ private void cleanCache() { + Subject subject; + + for (Integer sessionId : cache.keySet()) { + try { + subject = subjectManager.getSessionSubject(sessionId); + if (null == subject) { + log.debug("Removing perspective cache entry for session " + sessionId); + cache.remove(sessionId); + } + } catch (Exception e) { + log.debug("Removing perspective cache entry for session " + sessionId); + cache.remove(sessionId); + } + } + } + // TODO: remove this debug code @SuppressWarnings("unused") private void printMenu(List<MenuItem> menu, String indent) { @@ -79,4 +116,25 @@ public class PerspectiveManagerBean implements PerspectiveManagerLocal, Perspect } }
+ private static class CacheEntry { + private List<MenuItem> coreMenu = null; + + public CacheEntry() { + } + + /** + * @return the coreMenu + */ + public List<MenuItem> getCoreMenu() { + return coreMenu; + } + + /** + * @param coreMenu the coreMenu to set + */ + public void setCoreMenu(List<MenuItem> coreMenu) { + this.coreMenu = coreMenu; + } + } + } \ No newline at end of file diff --git a/modules/enterprise/server/plugins/perspectives/core/perspective/src/main/resources/META-INF/rhq-serverplugin.xml b/modules/enterprise/server/plugins/perspectives/core/perspective/src/main/resources/META-INF/rhq-serverplugin.xml index 1617ef6..8e0cf4d 100644 --- a/modules/enterprise/server/plugins/perspectives/core/perspective/src/main/resources/META-INF/rhq-serverplugin.xml +++ b/modules/enterprise/server/plugins/perspectives/core/perspective/src/main/resources/META-INF/rhq-serverplugin.xml @@ -54,15 +54,46 @@ placement="after" /> </menuItem> <menuItem + name="debug" + displayName="Debug" + isDebug="true"> + <position + extensionPoint="coreMenu" + name="administration" + placement="after" /> + </menuItem> + <menuItem name="help" displayName="Help"> <position extensionPoint="coreMenu" - name="administration" + name="debug" placement="after" /> </menuItem> - - +<!-- + <menuItem + name="refresh" + displayName="" + iconUrl="/images/refreshStopped.gif" + feature="refreshMenu"> + <position + extensionPoint="coreMenu" + name="help" + placement="after" + location="right" /> + </menuItem> + <menuItem + name="loggedInAs" + displayName="Logged in as " + feature="loggedInAsMenu"> + <position + extensionPoint="coreMenu" + name="refresh" + placement="after" + location="right" /> + </menuItem> + --> + <!-- Core Menu: Overview --> <menuItem name="overview.subsystemViews" @@ -151,7 +182,7 @@ extensionPoint="coreMenu" name="resources.recentlyViewedResources" placement="after" - break="true" /> + addBreak="true" /> </menuItem>
<!-- Core Menu: Groups --> @@ -193,7 +224,7 @@ extensionPoint="coreMenu" name="groups.groupDefinitions" placement="after" - break="true" /> + addBreak="true" /> </menuItem> <menuItem name="groups.newGroupDefinition" @@ -213,7 +244,7 @@ extensionPoint="coreMenu" name="groups.newGroupDefinition" placement="after" - break="true" /> + addBreak="true" /> </menuItem> <menuItem name="groups.recentlyViewedGroups" @@ -234,7 +265,7 @@ extensionPoint="coreMenu" name="groups.recentlyViewedGroups" placement="after" - break="true" /> + addBreak="true" /> </menuItem>
<!-- Core Menu: Administration --> @@ -248,7 +279,7 @@ </menuItem> <menuItem name="administration.systemConfiguration" - displayName="systemConfiguration"> + displayName="System Configuration"> <position extensionPoint="coreMenu" name="administration.security" @@ -298,11 +329,73 @@ placement="after" /> </menuItem>
+ <!-- Core Menu: Debug --> + <menuItem + name="debug.sqlInterface" + displayName="SQL Interface" + isDebug="true" + url="/admin/test/sql.jsp"> + <position + extensionPoint="coreMenu" + name="debug" + placement="start" /> + </menuItem> + <menuItem + name="debug.jpqlHqlInterface" + displayName="JPQL/HQL Interface" + isDebug="true" + url="/admin/test/hibernate.jsp"> + <position + extensionPoint="coreMenu" + name="debug.sqlInterface" + placement="after" /> + </menuItem> + <menuItem + name="debug.hibernateEntityBrowser" + displayName="Hibernate Entity Browser" + isDebug="true" + url="/admin/test/browser.jsp"> + <position + extensionPoint="coreMenu" + name="debug.jpqlHqlInterface" + placement="after" /> + </menuItem> + <menuItem + name="debug.administrativeConsole" + displayName="Administrative Console" + isDebug="true" + url="/admin/test/control.jsp"> + <position + extensionPoint="coreMenu" + name="debug.hibernateEntityBrowser" + placement="after" /> + </menuItem> + <menuItem + name="debug.testEmailConfiguration" + displayName="Test Email Configuration" + isDebug="true" + url="/admin/test/email.jsp"> + <position + extensionPoint="coreMenu" + name="debug.administrativeConsole" + placement="after" /> + </menuItem> + <menuItem + name="debug.testAgentCommunications" + displayName="Test Agent Configurations" + isDebug="true" + url="/admin/test/agent.jsp"> + <position + extensionPoint="coreMenu" + name="debug.testEmailConfiguration" + placement="after" /> + </menuItem> + <!-- Core Menu: Help --> <menuItem name="help.onlineDocumentation" displayName="Online Documentation" - feature="newWindow" + newWindow="true" url="http://www.redhat.com/docs/en-US/JBoss_ON/%22%3E <position extensionPoint="coreMenu" @@ -312,7 +405,7 @@ <menuItem name="help.openASupportCase" displayName="Open a Support Case" - feature="newWindow" + newWindow="true" url="https://support.redhat.com/jbossnetwork/restricted/addCase.html%22%3E <position extensionPoint="coreMenu" @@ -328,7 +421,7 @@ extensionPoint="coreMenu" name="help.openASupportCase" placement="after" - break="true" /> + addBreak="true" /> </menuItem>
<!-- Core Menu: Overview.Subsystem Views --> @@ -344,7 +437,7 @@ </menuItem> <menuItem name="overview.subsystemViews.suspectMetrics" - displayName="suspectMetrics" + displayName="Suspect Metrics" iconUrl="/images/icons/Monitor_failed_16.png" url="/rhq/subsystem/oobHistory.xhtml"> <position diff --git a/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-perspective.xsd b/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-perspective.xsd index 97584b1..4f0858e 100644 --- a/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-perspective.xsd +++ b/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-perspective.xsd @@ -18,7 +18,8 @@ schemaLocation="rhq-serverplugin.xsd" />
xs:annotation - xs:documentationSchema for a Perspective Descriptor. Perspective are deployed as Server Plugins.</xs:documentation> + xs:documentationSchema for a Perspective Descriptor. Perspective are deployed as Server Plugins. + </xs:documentation> xs:appinfo jaxb:schemaBindings <jaxb:package @@ -34,7 +35,8 @@ xs:annotation xs:documentationDefines a Perspective plugin. A Perspective is deployed as a Server Plugin. The Server Plugin Container (SPC) handles simple lifecycle management for the deployed plugins (e.g. start, stop). The plugin - is otherwise standalone and can do everything it needs to do without additional help from the SPC.</xs:documentation> + is otherwise standalone and can do everything it needs to do without additional help from the SPC. + </xs:documentation> xs:appinfo <jaxb:class name="PerspectivePluginElement" /> @@ -110,7 +112,8 @@ minOccurs="0" maxOccurs="unbounded"> xs:annotation - xs:documentationLimit task to the designated task pane extension points. Otherwise, all.</xs:documentation> + xs:documentationLimit task to the designated task pane extension points. Otherwise, all. + </xs:documentation> </xs:annotation> </xs:element> <xs:element @@ -129,7 +132,8 @@ minOccurs="0" maxOccurs="unbounded"> xs:annotation - xs:documentationActivate the extension only if the user has the required global permissions.</xs:documentation> + xs:documentationActivate the extension only if the user has the required global permissions. + </xs:documentation> </xs:annotation> </xs:element> <xs:element @@ -174,7 +178,8 @@ type="xs:anyURI" use="required"> xs:annotation - xs:documentationThe request URL for the task extension. Typically kicks off a wizard or similar workflow.</xs:documentation> + xs:documentationThe request URL for the task extension. Typically kicks off a wizard or similar workflow. + </xs:documentation> </xs:annotation> </xs:attribute> <xs:attribute @@ -202,7 +207,8 @@ name="menuItem" type="perspective:MenuItemType"> xs:annotation - xs:documentationAdd, Replace or Remove a menuItem extension for an existing menu extension point.</xs:documentation> + xs:documentationAdd, Replace or Remove a menuItem extension for an existing menu extension point. + </xs:documentation> xs:appinfo <jaxb:class name="PerspectiveMenuItemElement" /> @@ -236,7 +242,8 @@ minOccurs="0" maxOccurs="unbounded"> xs:annotation - xs:documentationActivate the extension only if the user has the required global permissions.</xs:documentation> + xs:documentationActivate the extension only if the user has the required global permissions. + </xs:documentation> </xs:annotation> </xs:element> </xs:sequence> @@ -264,7 +271,8 @@ type="perspective:DisplayNameType" use="optional"> xs:annotation - xs:documentationThe display name for the menuItem extension. If omitted an icon is required.</xs:documentation> + xs:documentationThe display name for the menuItem extension. If omitted an icon is required. + </xs:documentation> </xs:annotation> </xs:attribute> <xs:attribute @@ -272,7 +280,27 @@ type="perspective:MenuItemFeatureType" use="optional"> xs:annotation - xs:documentationCertain menuItem extensions utilize special built-in rendering features.</xs:documentation> + xs:documentationCertain menuItem extensions utilize special built-in rendering features. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute + name="newWindow" + type="xs:boolean" + use="optional" + default="false"> + xs:annotation + xs:documentationIf true the url should be directed to a new window. Otherwise the content should be + presented in the current page body.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute + name="isDebug" + type="xs:boolean" + use="optional" + default="false"> + xs:annotation + xs:documentationIf true render this menuItem in debug mode only.</xs:documentation> </xs:annotation> </xs:attribute> <xs:attribute @@ -559,7 +587,15 @@ use="required"> </xs:attribute> <xs:attribute - name="break" + name="location" + type="perspective:LocationType" + use="optional"> + xs:annotation + xs:documentationDefault is left.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute + name="addBreak" type="xs:boolean" use="optional" default="false"> @@ -635,6 +671,26 @@ </xs:simpleType>
<xs:simpleType + name="LocationType"> + xs:annotation + xs:documentationSuggests a screen location for an extension.</xs:documentation> + </xs:annotation> + <xs:restriction + base="xs:string"> + <xs:enumeration + value="bottom"></xs:enumeration> + <xs:enumeration + value="center"></xs:enumeration> + <xs:enumeration + value="left"></xs:enumeration> + <xs:enumeration + value="right"></xs:enumeration> + <xs:enumeration + value="top"></xs:enumeration> + </xs:restriction> + </xs:simpleType> + + <xs:simpleType name="MenuItemFeatureType"> <xs:restriction base="xs:string"> @@ -652,10 +708,6 @@ value="resourceRecentlyViewed"></xs:enumeration> <xs:enumeration value="resourceSearch"></xs:enumeration> - <xs:enumeration - value="newWindow"></xs:enumeration> - <xs:enumeration - value="resourceSearch"></xs:enumeration> </xs:restriction> </xs:simpleType>
@@ -704,6 +756,9 @@
<xs:simpleType name="PlacementType"> + xs:annotation + xs:documentationDescribes the relative placement of an extension to another extension.</xs:documentation> + </xs:annotation> <xs:restriction base="xs:string"> <xs:enumeration
commit 3d57a608d12a2cbb4f8c1cd49599ac76a09c2e68 Author: John Sanda john@localhost.localdomain Date: Tue Dec 1 17:10:44 2009 -0500
[US 6] Adding implementation and tests for updating configs that support structured and raw
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java index 06dfaf3..4bcb2ab 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java @@ -989,7 +989,17 @@ public class ConfigurationManagerBean implements ConfigurationManagerLocal, Conf public ResourceConfigurationUpdate updateResourceConfiguration(Subject subject, int resourceId, Configuration newConfiguration, boolean fromStructured) throws ResourceNotFoundException, ConfigurationUpdateStillInProgressException { - return null; + + Configuration translatedConfig = translateResourceConfiguration(subject, resourceId, newConfiguration, + fromStructured); + + ResourceConfigurationUpdate newUpdate = + configurationManager.persistNewResourceConfigurationUpdateHistory(subject, resourceId, translatedConfig, + ConfigurationUpdateStatus.INPROGRESS, subject.getName(), false); + + executeResourceConfigurationUpdate(newUpdate, fromStructured); + + return newUpdate; }
@Nullable @@ -1006,21 +1016,21 @@ public class ConfigurationManagerBean implements ConfigurationManagerLocal, Conf newUpdate = configurationManager.persistNewResourceConfigurationUpdateHistory(subject, resourceId, newConfiguration, ConfigurationUpdateStatus.INPROGRESS, subject.getName(), false);
- executeResourceConfigurationUpdate(newUpdate); + executeResourceConfigurationUpdate(newUpdate, true);
return newUpdate; }
public void executeResourceConfigurationUpdate(int updateId) { ResourceConfigurationUpdate update = getResourceConfigurationUpdate(subjectManager.getOverlord(), updateId); - executeResourceConfigurationUpdate(update); + executeResourceConfigurationUpdate(update, true); }
/** * Tells the Agent to asynchonously update a managed resource's configuration as per the specified * <code>ResourceConfigurationUpdate</code>. */ - private void executeResourceConfigurationUpdate(ResourceConfigurationUpdate update) { + private void executeResourceConfigurationUpdate(ResourceConfigurationUpdate update, boolean fromStructured) { try { AgentClient agentClient = agentManager.getAgentClient(update.getResource().getAgent()); ConfigurationUpdateRequest request = new ConfigurationUpdateRequest(update.getId(), update diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBeanUnitTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBeanUnitTest.java index 00dc735..f43f89a 100644 --- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBeanUnitTest.java +++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBeanUnitTest.java @@ -32,15 +32,19 @@ import org.rhq.test.jmock.PropertyMatcher; import org.rhq.core.domain.auth.Subject; import org.rhq.core.domain.configuration.Configuration; import org.rhq.core.domain.configuration.ResourceConfigurationUpdate; +import org.rhq.core.domain.configuration.RawConfiguration; +import org.rhq.core.domain.configuration.PropertySimple; import org.rhq.core.domain.resource.Resource; import org.rhq.core.domain.resource.Agent; import org.rhq.core.clientapi.agent.configuration.ConfigurationAgentService; import org.rhq.core.clientapi.agent.configuration.ConfigurationUpdateRequest; import org.rhq.enterprise.server.core.AgentManagerLocal; import org.rhq.enterprise.server.agentclient.AgentClient; +import org.rhq.enterprise.server.authz.AuthorizationManagerLocal; import org.testng.annotations.Test; import org.testng.annotations.BeforeMethod; import org.jmock.Expectations; +import org.jmock.Sequence; import org.hamcrest.Matcher;
import javax.persistence.EntityManager; @@ -48,10 +52,15 @@ import java.lang.reflect.Field;
public class ConfigurationManagerBeanUnitTest extends JMockTest {
+ static final boolean FROM_STRUCTURED = true; + static final boolean FROM_RAW = false; + ConfigurationManagerLocal configurationMgrLocal;
AgentManagerLocal agentMgr;
+ AuthorizationManagerLocal authorizationMgr; + EntityManager entityMgr;
ConfigurationManagerBean configurationMgr; @@ -66,6 +75,9 @@ public class ConfigurationManagerBeanUnitTest extends JMockTest { agentMgr = context.mock(AgentManagerLocal.class); setField(configurationMgr, "agentManager", agentMgr);
+ authorizationMgr = context.mock(AuthorizationManagerLocal.class); + setField(configurationMgr, "authorizationManager", authorizationMgr); + entityMgr = context.mock(EntityManager.class); setField(configurationMgr, "entityManager", entityMgr); } @@ -128,7 +140,112 @@ public class ConfigurationManagerBeanUnitTest extends JMockTest { ResourceConfigurationUpdate actualUpdate = configurationMgr.updateResourceConfiguration(subject, resourceId, newConfig);
- assertSame(actualUpdate, expectedUpdate, ""); + assertSame(actualUpdate, expectedUpdate, "Expected to get back the persisted configuration update"); + } + + @Test + public void updateResourceConfigShouldTranslateStructuredWhenStructredConfigHasEdits() throws Exception { + final Subject subject = new Subject("rhqadmin", true, true); + final int resourceId = -1; + final Configuration newConfig = new Configuration(); + final boolean isPartOfGroupUpdate = false; + + final Configuration translatedConfig = newConfig.deepCopy(); + translatedConfig.addRawConfiguration(new RawConfiguration()); + + final Resource resource = new Resource(resourceId); + resource.setAgent(new Agent("test-agent", "localhost", 7080, null, null)); + + final ResourceConfigurationUpdate expectedUpdate = new ResourceConfigurationUpdate(resource, translatedConfig, + subject.getName()); + expectedUpdate.setId(-1); + + final AgentClient agentClient = context.mock(AgentClient.class); + final ConfigurationAgentService configAgentService = context.mock(ConfigurationAgentService.class); + + final ConfigurationUpdateRequest expectedUpdateRequest = new ConfigurationUpdateRequest(expectedUpdate.getId(), + expectedUpdate.getConfiguration(), expectedUpdate.getResource().getId()); + + final Sequence configUdpate = context.sequence("structured-config-update"); + + context.checking(new Expectations() {{ + allowing(entityMgr).find(Resource.class, resourceId); will(returnValue(resource)); + + allowing(authorizationMgr).canViewResource(subject, resourceId); will(returnValue(true)); + + oneOf(configAgentService).merge(newConfig, resourceId, FROM_STRUCTURED); + will(returnValue(translatedConfig)); inSequence(configUdpate); + + oneOf(configurationMgrLocal).persistNewResourceConfigurationUpdateHistory(subject, resourceId, + translatedConfig, INPROGRESS, subject.getName(), isPartOfGroupUpdate); + will(returnValue(expectedUpdate)); + inSequence(configUdpate); + + allowing(agentMgr).getAgentClient(expectedUpdate.getResource().getAgent()); will(returnValue(agentClient)); + + allowing(agentClient).getConfigurationAgentService(); will(returnValue(configAgentService)); + + oneOf(configAgentService).updateResourceConfiguration(with(matchingUpdateRequest(expectedUpdateRequest))); + inSequence(configUdpate); + }}); + + ResourceConfigurationUpdate actualUpdate = configurationMgr.updateResourceConfiguration(subject, resourceId, + newConfig, FROM_STRUCTURED); + + assertSame(actualUpdate, expectedUpdate, "Expected to get back the persisted configuration update"); + } + + @Test + public void updateResourceConfigShouldTranslateRawWhenRawConfigHasEdits() throws Exception { + final Subject subject = new Subject("rhqadmin", true, true); + final int resourceId = -1; + final Configuration newConfig = new Configuration(); + newConfig.addRawConfiguration(new RawConfiguration()); + final boolean isPartOfGroupUpdate = false; + + final Configuration translatedConfig = newConfig.deepCopy(); + translatedConfig.put(new PropertySimple("x", "y")); + + final Resource resource = new Resource(resourceId); + resource.setAgent(new Agent("test-agent", "localhost", 7080, null, null)); + + final ResourceConfigurationUpdate expectedUpdate = new ResourceConfigurationUpdate(resource, translatedConfig, + subject.getName()); + expectedUpdate.setId(-1); + + final AgentClient agentClient = context.mock(AgentClient.class); + final ConfigurationAgentService configAgentService = context.mock(ConfigurationAgentService.class); + + final ConfigurationUpdateRequest expectedUpdateRequest = new ConfigurationUpdateRequest(expectedUpdate.getId(), + expectedUpdate.getConfiguration(), expectedUpdate.getResource().getId()); + + final Sequence configUdpate = context.sequence("raw-config-update"); + + context.checking(new Expectations() {{ + allowing(entityMgr).find(Resource.class, resourceId); will(returnValue(resource)); + + allowing(authorizationMgr).canViewResource(subject, resourceId); will(returnValue(true)); + + oneOf(configAgentService).merge(newConfig, resourceId, FROM_RAW); + will(returnValue(translatedConfig)); inSequence(configUdpate); + + oneOf(configurationMgrLocal).persistNewResourceConfigurationUpdateHistory(subject, resourceId, + translatedConfig, INPROGRESS, subject.getName(), isPartOfGroupUpdate); + will(returnValue(expectedUpdate)); + inSequence(configUdpate); + + allowing(agentMgr).getAgentClient(expectedUpdate.getResource().getAgent()); will(returnValue(agentClient)); + + allowing(agentClient).getConfigurationAgentService(); will(returnValue(configAgentService)); + + oneOf(configAgentService).updateResourceConfiguration(with(matchingUpdateRequest(expectedUpdateRequest))); + inSequence(configUdpate); + }}); + + ResourceConfigurationUpdate actualUpdate = configurationMgr.updateResourceConfiguration(subject, resourceId, + newConfig, FROM_RAW); + + assertSame(actualUpdate, expectedUpdate, "Expected to get back the persisted configuration update"); }
@Test @@ -154,10 +271,10 @@ public class ConfigurationManagerBeanUnitTest extends JMockTest { INPROGRESS, subject.getName(), isPartOfGroupUpdate); will(returnValue(expectedUpdate));
- allowing(agentMgr).getAgentClient(expectedUpdate.getResource().getAgent()); - will(throwException(exception)); - oneOf(configurationMgrLocal).mergeConfigurationUpdate(expectedUpdate); + + allowing(agentMgr).getAgentClient(expectedUpdate.getResource().getAgent()); + will(throwException(exception)); }});
ResourceConfigurationUpdate actualUpdate = configurationMgr.updateResourceConfiguration(subject, resourceId,
commit 6d4f1c395a8816706819b8e186f01d0d2864254e Author: John Sanda john@localhost.localdomain Date: Tue Dec 1 16:12:47 2009 -0500
[US 6] Initial commit for new updateResourceConfiguration() method that handles raw config.
The bulk of this commit involves unit tests for the existing functionality in updateResourceConfiguration().
diff --git a/modules/enterprise/server/jar/pom.xml b/modules/enterprise/server/jar/pom.xml index 9f964ed..4914e77 100644 --- a/modules/enterprise/server/jar/pom.xml +++ b/modules/enterprise/server/jar/pom.xml @@ -355,6 +355,17 @@ <scope>test</scope> </dependency>
+ <dependency> + <groupId>com.redhat.rhn</groupId> + <artifactId>rhn-common</artifactId> + <version>1.0-SNAPSHOT</version> + </dependency> + + <dependency> + <groupId>${groupId}</groupId> + <artifactId>test-utils</artifactId> + <version>${version}</version> + </dependency> </dependencies>
<build> diff --git a/modules/enterprise/server/jar/src/main/java/META-INF/MANIFEST.MF b/modules/enterprise/server/jar/src/main/java/META-INF/MANIFEST.MF new file mode 100644 index 0000000..6bb10a8 --- /dev/null +++ b/modules/enterprise/server/jar/src/main/java/META-INF/MANIFEST.MF @@ -0,0 +1,14 @@ +Manifest-Version: 1.0 +Class-Path: i18nlog-1.0.9.jar junit-3.8.1.jar rhq-enterprise-comm-1.4. + 0-SNAPSHOT.jar rhq-core-util-1.4.0-SNAPSHOT.jar jdom-1.0.jar rhq-core + -comm-api-1.4.0-SNAPSHOT.jar dom4j-1.6.1-jboss.jar getopt-1.0.13.jar + jboss-remoting-2.2.2.SP8.jar jboss-serialization-1.0.3.GA.jar concurr + ent-1.3.4.jar rhq-enterprise-server-xml-schemas-1.4.0-SNAPSHOT.jar rh + q-core-client-api-1.4.0-SNAPSHOT.jar jaxb-impl-2.1.6.jar rhq-core-dbu + tils-1.4.0-SNAPSHOT.jar ant-1.6.5.jar safe-invoker-1.4.0-SNAPSHOT.jar + jbossws-native-core-3.1.1.GA.jar jbossws-spi-1.1.1.GA.jar commons-be + anutils-1.6.1.jar commons-collections-3.2.jar commons-httpclient-3.0. + 1.jar commons-codec-1.2.jar commons-validator-1.1.4.jar xml-apis-1.0. + b2.jar jboss-cache-1.4.1.SP9.jar jbpm-3.1.1.jar snmp4j-1.8.2.jar post + gresql-8.4-701.jdbc3.jar rss4j-0.92-on.2.jar + diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java index caecff7..06dfaf3 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java @@ -986,6 +986,12 @@ public class ConfigurationManagerBean implements ConfigurationManagerLocal, Conf } }
+ public ResourceConfigurationUpdate updateResourceConfiguration(Subject subject, int resourceId, + Configuration newConfiguration, boolean fromStructured) + throws ResourceNotFoundException, ConfigurationUpdateStillInProgressException { + return null; + } + @Nullable public ResourceConfigurationUpdate updateResourceConfiguration(Subject subject, int resourceId, @XmlJavaTypeAdapter(ConfigurationAdapter.class) Configuration newConfiguration) diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerLocal.java index e86fe2f..5ec3e95 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerLocal.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerLocal.java @@ -471,6 +471,10 @@ public interface ConfigurationManagerLocal { ResourceConfigurationUpdate updateResourceConfiguration(Subject subject, int resourceId, Configuration newConfiguration) throws ResourceNotFoundException, ConfigurationUpdateStillInProgressException;
+ ResourceConfigurationUpdate updateResourceConfiguration(Subject subject, int resourceId, + Configuration newConfiguration, boolean fromStructured) + throws ResourceNotFoundException, ConfigurationUpdateStillInProgressException; + Configuration getResourceConfiguration(Subject subject, int resourceId);
/** diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBeanUnitTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBeanUnitTest.java new file mode 100644 index 0000000..00dc735 --- /dev/null +++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBeanUnitTest.java @@ -0,0 +1,173 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2008 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, version 2, as + * published by the Free Software Foundation, and/or the GNU Lesser + * General Public License, version 2.1, also as published by the Free + * Software Foundation. + * + * 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 and the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * and the GNU Lesser 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.enterprise.server.configuration; + +import static org.rhq.test.AssertUtils.*; +import static org.rhq.core.domain.configuration.ConfigurationUpdateStatus.*; +import static org.testng.Assert.*; + +import org.rhq.test.JMockTest; +import org.rhq.test.jmock.PropertyMatcher; +import org.rhq.core.domain.auth.Subject; +import org.rhq.core.domain.configuration.Configuration; +import org.rhq.core.domain.configuration.ResourceConfigurationUpdate; +import org.rhq.core.domain.resource.Resource; +import org.rhq.core.domain.resource.Agent; +import org.rhq.core.clientapi.agent.configuration.ConfigurationAgentService; +import org.rhq.core.clientapi.agent.configuration.ConfigurationUpdateRequest; +import org.rhq.enterprise.server.core.AgentManagerLocal; +import org.rhq.enterprise.server.agentclient.AgentClient; +import org.testng.annotations.Test; +import org.testng.annotations.BeforeMethod; +import org.jmock.Expectations; +import org.hamcrest.Matcher; + +import javax.persistence.EntityManager; +import java.lang.reflect.Field; + +public class ConfigurationManagerBeanUnitTest extends JMockTest { + + ConfigurationManagerLocal configurationMgrLocal; + + AgentManagerLocal agentMgr; + + EntityManager entityMgr; + + ConfigurationManagerBean configurationMgr; + + @BeforeMethod + public void setup() throws Exception { + configurationMgr = new ConfigurationManagerBean(); + + configurationMgrLocal = context.mock(ConfigurationManagerLocal.class); + setField(configurationMgr, "configurationManager", configurationMgrLocal); + + agentMgr = context.mock(AgentManagerLocal.class); + setField(configurationMgr, "agentManager", agentMgr); + + entityMgr = context.mock(EntityManager.class); + setField(configurationMgr, "entityManager", entityMgr); + } + + static void setField(Object src, String fieldName, Object value) { + try { + Field field = src.getClass().getDeclaredField(fieldName); + field.setAccessible(true); + field.set(src, value); + } + catch (SecurityException e) { + throw new RuntimeException(e); + } + catch (IllegalArgumentException e) { + throw new RuntimeException(e); + } + catch (NoSuchFieldException e) { + String msg = "The field <" + fieldName + "> does not exist for " + + src.getClass().getName(); + throw new RuntimeException(e); + } + catch (IllegalAccessException e) { + throw new RuntimeException(e); + } + + } + + @Test + public void updateResourceConfigShouldAddUpdateToAuditTrailAndSendUpdateToAgent() throws Exception { + final Subject subject = new Subject("rhqadmin", true, true); + final int resourceId = -1; + final Configuration newConfig = new Configuration(); + final boolean isPartOfGroupUpdate = false; + + Resource resource = new Resource(resourceId); + resource.setAgent(new Agent("test-agent", "localhost", 7080, null, null)); + + final ResourceConfigurationUpdate expectedUpdate = new ResourceConfigurationUpdate(resource, newConfig, + subject.getName()); + expectedUpdate.setId(-1); + + final AgentClient agentClient = context.mock(AgentClient.class); + final ConfigurationAgentService configAgentService = context.mock(ConfigurationAgentService.class); + + final ConfigurationUpdateRequest expectedUpdateRequest = new ConfigurationUpdateRequest(expectedUpdate.getId(), + expectedUpdate.getConfiguration(), expectedUpdate.getResource().getId()); + + context.checking(new Expectations() {{ + oneOf(configurationMgrLocal).persistNewResourceConfigurationUpdateHistory(subject, resourceId, newConfig, + INPROGRESS, subject.getName(), isPartOfGroupUpdate); + will(returnValue(expectedUpdate)); + + allowing(agentMgr).getAgentClient(expectedUpdate.getResource().getAgent()); will(returnValue(agentClient)); + + allowing(agentClient).getConfigurationAgentService(); will(returnValue(configAgentService)); + + oneOf(configAgentService).updateResourceConfiguration(with(matchingUpdateRequest(expectedUpdateRequest))); + }}); + + ResourceConfigurationUpdate actualUpdate = configurationMgr.updateResourceConfiguration(subject, resourceId, + newConfig); + + assertSame(actualUpdate, expectedUpdate, ""); + } + + @Test + public void updateResourceConfigShouldMarkUpdateAsFailureWhenExceptionOccurs() throws Exception { + final Subject subject = new Subject("rhqadmin", true, true); + final int resourceId = -1; + final Configuration newConfig = new Configuration(); + final boolean isPartOfGroupUpdate = false; + + Resource resource = new Resource(resourceId); + resource.setAgent(new Agent("test-agent", "localhost", 7080, null, null)); + + final RuntimeException exception = new RuntimeException(); + + final ResourceConfigurationUpdate expectedUpdate = new ResourceConfigurationUpdate(resource, newConfig, + subject.getName()); + expectedUpdate.setId(-1); + expectedUpdate.setStatus(FAILURE); + expectedUpdate.setErrorMessageFromThrowable(exception); + + context.checking(new Expectations() {{ + oneOf(configurationMgrLocal).persistNewResourceConfigurationUpdateHistory(subject, resourceId, newConfig, + INPROGRESS, subject.getName(), isPartOfGroupUpdate); + will(returnValue(expectedUpdate)); + + allowing(agentMgr).getAgentClient(expectedUpdate.getResource().getAgent()); + will(throwException(exception)); + + oneOf(configurationMgrLocal).mergeConfigurationUpdate(expectedUpdate); + }}); + + ResourceConfigurationUpdate actualUpdate = configurationMgr.updateResourceConfiguration(subject, resourceId, + newConfig); + + assertPropertiesMatch(expectedUpdate, actualUpdate, "Expected to get back a failure update"); + } + + public static Matcher<ConfigurationUpdateRequest> matchingUpdateRequest(ConfigurationUpdateRequest expected) { + return new PropertyMatcher<ConfigurationUpdateRequest>(expected); + } + +}
commit cde65a0c9f1358860874cdfd5bc1176075e1cbb1 Merge: 0924ffc... b9cc64b... Author: John Sanda jsanda@redhat.com Date: Tue Dec 1 15:43:28 2009 -0500
Merge branch 'master' into raw-config
commit 6dc0cbe7bb53e12234ef21696194901041159b1a Author: Heiko W. Rupp pilhuhn@fedorapeople.org Date: Tue Dec 1 20:34:58 2009 +0100
Fix twitter api url and mention status.net url
diff --git a/modules/enterprise/server/plugins/alert-microblog/src/main/resources/META-INF/rhq-serverplugin.xml b/modules/enterprise/server/plugins/alert-microblog/src/main/resources/META-INF/rhq-serverplugin.xml index 64b5f1d..5136621 100644 --- a/modules/enterprise/server/plugins/alert-microblog/src/main/resources/META-INF/rhq-serverplugin.xml +++ b/modules/enterprise/server/plugins/alert-microblog/src/main/resources/META-INF/rhq-serverplugin.xml @@ -24,8 +24,8 @@ <!-- Global preferences for all mircoblog alerts --> serverplugin:plugin-configuration <c:simple-property name="microblogServerUrl" displayName="Microblog server URL" type="string" - default="http://twitter.com/api" - description="Base URL of the Microblog server"/> + default="http://twitter.com/" + description="Base URL of the Microblog server (twitter.com for twitter, http://identi.ca/api for Status.net)"/> <c:simple-property name="user" displayName="User name" type="string" /> <c:simple-property name="password" displayName="Password" type="password"/>
commit 7b9533b9f039a63dc2198946b18a374b88a18212 Author: Heiko W. Rupp pilhuhn@fedorapeople.org Date: Tue Dec 1 20:04:20 2009 +0100
Fix removal and back to alert definitions link.
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/alert/notif/listAlertSender.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/alert/notif/listAlertSender.xhtml index 850676b..8fae094 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/alert/notif/listAlertSender.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/alert/notif/listAlertSender.xhtml @@ -42,58 +42,61 @@ <h:outputText>Existing notifications for Resource '#{ResourceUIBean.name}' and alert definition '#{ListNotificationsUIBean.alertDefinitionName}':</h:outputText> <br/> <h:form id="notificationListForm"> - <rich:dataTable id="alertNotificationDataTable" - value="#{ListNotificationsUIBean.existingNotifications}" - var="notif" - width="100%" - columnWidth="5% 10% 85%" - headerClass="tableRowHeader" - footerClass="on-pager-footer" - onRowMouseOver="this.style.backgroundColor='#E7E7E7'" - onRowMouseOut="this.style.backgroundColor='#{a4jSkin.tableBackgroundColor}'"> - rich:column - <f:facet name="header"> - <onc:allSelect target="selectedNotification"/> - </f:facet> - - <onc:select name="selectedNotification" value="#{notif.id}"/> - </rich:column> - - rich:column - <f:facet name="header"> - <h:outputText styleClass="headerText" value="ID"/> - </f:facet> - - <h:outputText value="#{notif.id}"/> - </rich:column> - - rich:column - <f:facet name="header"> - <h:outputText styleClass="headerText" value="Sender"/> - </f:facet> - - <h:outputText value="#{notif.senderName}"/> - </rich:column> + <input type="hidden" name="id" value="${param.id}"/> + <input type="hidden" name="ad" value="${param.ad}"/>
- rich:column - <f:facet name="header"> - <h:outputText styleClass="headerText" value="Configuration"/> + <rich:dataTable id="alertNotificationDataTable" + value="#{ListNotificationsUIBean.existingNotifications}" + var="notif" + width="100%" + columnWidth="5% 10% 85%" + headerClass="tableRowHeader" + footerClass="on-pager-footer" + onRowMouseOver="this.style.backgroundColor='#E7E7E7'" + onRowMouseOut="this.style.backgroundColor='#{a4jSkin.tableBackgroundColor}'"> + rich:column + <f:facet name="header"> + <onc:allSelect target="selectedNotification"/> + </f:facet> + + <onc:select name="selectedNotification" value="#{notif.id}"/> + </rich:column> + + rich:column + <f:facet name="header"> + <h:outputText styleClass="headerText" value="ID"/> + </f:facet> + + <h:outputText value="#{notif.id}"/> + </rich:column> + + rich:column + <f:facet name="header"> + <h:outputText styleClass="headerText" value="Sender"/> + </f:facet> + + <h:outputText value="#{notif.senderName}"/> + </rich:column> + + rich:column + <f:facet name="header"> + <h:outputText styleClass="headerText" value="Configuration"/> + </f:facet> + + <h:outputText value="#{notif.configuration.toString(true)}"/> + </rich:column> + <f:facet name="footer"> + rich:columnGroup + <rich:column colspan="5" width="100%"> + <onc:selectCommandButton action="#{ListNotificationsUIBean.removeSelectedNotifications}" + target="selectedNotification" + value="Remove selected" + styleClass="on-pager-button buttonsmall"/> + </rich:column> + </rich:columnGroup> </f:facet>
- <h:outputText value="#{notif.configuration.toString(true)}"/> - </rich:column> - <f:facet name="footer"> - rich:columnGroup - <rich:column colspan="5" width="100%"> - <onc:selectCommandButton action="#{ListNotificationsUIBean.removeSelectedNotifications}" - target="selectedNotification" - value="Remove selected" - styleClass="on-pager-button buttonsmall"/> - </rich:column> - </rich:columnGroup> - </f:facet> - - </rich:dataTable> + </rich:dataTable> </h:form> <p/>
@@ -128,7 +131,7 @@ </rich:panel> </h:form>
- <h:outputLink value="rhq/resource/alert/listAlertDefinitions.xhtml"> + <h:outputLink value="/rhq/resource/alert/listAlertDefinitions.xhtml"> <f:param name="id" value="#{param.id}"/> <h:outputText value="Back to Alert Definitions for Resource '#{ResourceUIBean.name}'"/> </h:outputLink>
commit 0ebdbb35cb38dd1e07fb0d2b391f332f41602410 Author: Heiko W. Rupp pilhuhn@fedorapeople.org Date: Tue Dec 1 20:02:50 2009 +0100
The Microblog (Twitter,laconi.ca) alert sender.
diff --git a/modules/enterprise/server/plugins/alert-microblog/pom.xml b/modules/enterprise/server/plugins/alert-microblog/pom.xml new file mode 100644 index 0000000..ea1d2eb --- /dev/null +++ b/modules/enterprise/server/plugins/alert-microblog/pom.xml @@ -0,0 +1,162 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd%22%3E + <parent> + <artifactId>rhq-enterprise-server-plugins-parent</artifactId> + <groupId>org.rhq</groupId> + <version>1.4.0-SNAPSHOT</version> + </parent> + <modelVersion>4.0.0</modelVersion> + + <groupId>org.rhq</groupId> + <artifactId>alert-microblog</artifactId> + <version>1.4.0-SNAPSHOT</version> + + + <name>RHQ Enterprise Server Microblog Alert Plugin</name> + + <scm> + <connection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/modules/enterprise/server/plugins/alert-microblog/</connection> + <developerConnection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/modules/enterprise/server/plugins/alert-microblog/</developerConnection> + </scm> + + <properties> + <scm.module.path>modules/enterprise/server/plugins/alert-microblog/</scm.module.path> + </properties> + + <dependencies> + + <dependency> + <groupId>org.rhq</groupId> + <artifactId>rhq-enterprise-server</artifactId> + <version>1.4.0-SNAPSHOT</version> + <scope>provided</scope> <!-- by JBossAS --> + </dependency> + + <!-- TODO: This is a fix for the Javac bug requiring annotations to be + available when compiling dependent classes. It is fixed in JDK 6 --> + <dependency> + <groupId>javax.persistence</groupId> + <artifactId>persistence-api</artifactId> + <version>1.0</version> + <scope>provided</scope> + </dependency> + + <dependency> + <groupId>jboss.jboss-embeddable-ejb3</groupId> + <artifactId>hibernate-all</artifactId> + <version>1.0.0.Alpha9</version> + <scope>provided</scope> + <!-- needed for referenced domain entities that use Hibernate annotations --> + </dependency> + + <dependency> + <groupId>net.homeip.yusuke</groupId> + <artifactId>twitter4j</artifactId> + <version>2.0.9</version> + </dependency> + + + </dependencies> + + <build> + <plugins> + + <plugin> + <artifactId>maven-surefire-plugin</artifactId> + <configuration> + <excludedGroups>${rhq.testng.excludedGroups}</excludedGroups> + <!-- + <argLine>-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=y</argLine> + --> + </configuration> + </plugin> + + </plugins> + </build> + + <profiles> + + <profile> + <id>dev</id> + + <properties> + <rhq.rootDir>../../../../..</rhq.rootDir> + <rhq.containerDir>${rhq.rootDir}/${rhq.defaultDevContainerPath}</rhq.containerDir> + <rhq.deploymentDir>${rhq.containerDir}/jbossas/server/default/deploy/${rhq.earName}/rhq-serverplugins</rhq.deploymentDir> + </properties> + + <build> + <plugins> + + <plugin> + <artifactId>maven-antrun-plugin</artifactId> + <version>1.1</version> + <executions> + + <execution> + <id>deploy</id> + <phase>compile</phase> + <configuration> + <tasks> + <mkdir dir="${rhq.deploymentDir}" /> + <property name="deployment.file" location="${rhq.deploymentDir}/${project.build.finalName}.jar" /> + <echo>*** Updating ${deployment.file}...</echo> + <jar destfile="${deployment.file}" basedir="${project.build.outputDirectory}" /> + </tasks> + </configuration> + <goals> + <goal>run</goal> + </goals> + </execution> + + <execution> + <id>undeploy</id> + <phase>clean</phase> + <configuration> + <tasks> + <property name="deployment.file" location="${rhq.deploymentDir}/${project.build.finalName}.jar" /> + <echo>*** Deleting ${deployment.file}...</echo> + <delete file="${deployment.file}" /> + </tasks> + </configuration> + <goals> + <goal>run</goal> + </goals> + </execution> + + </executions> + </plugin> + <plugin> + <artifactId>maven-dependency-plugin</artifactId> + <version>2.0</version> + <executions> + <execution> + <id>copy-twitter4j-jar</id> + <phase>process-resources</phase> + <goals> + <goal>copy</goal> + </goals> + <configuration> + <artifactItems> + <artifactItem> + <groupId>net.homeip.yusuke</groupId> + <artifactId>twitter4j</artifactId> + <version>2.0.9</version> + </artifactItem> + </artifactItems> + <outputDirectory>${project.build.outputDirectory}/lib</outputDirectory> + </configuration> + </execution> + </executions> + </plugin> + + + </plugins> + </build> + </profile> + + </profiles> + +</project> \ No newline at end of file diff --git a/modules/enterprise/server/plugins/alert-microblog/src/main/java/org/rhq/enterprise/server/plugins/alertMicroblog/MicroblogSender.java b/modules/enterprise/server/plugins/alert-microblog/src/main/java/org/rhq/enterprise/server/plugins/alertMicroblog/MicroblogSender.java new file mode 100644 index 0000000..e95b6f0 --- /dev/null +++ b/modules/enterprise/server/plugins/alert-microblog/src/main/java/org/rhq/enterprise/server/plugins/alertMicroblog/MicroblogSender.java @@ -0,0 +1,72 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2009 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.plugins.alertMicroblog; + +import twitter4j.Twitter; +import twitter4j.TwitterException; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.rhq.core.domain.alert.Alert; +import org.rhq.enterprise.server.alert.AlertManagerLocal; +import org.rhq.enterprise.server.plugin.pc.alert.AlertSender; +import org.rhq.enterprise.server.plugin.pc.alert.ResultState; +import org.rhq.enterprise.server.plugin.pc.alert.SenderResult; +import org.rhq.enterprise.server.util.LookupUtil; + +/** + * Send alert notifications via Microblogging services like Twitter or laconi.ca + * @author Heiko W. Rupp + */ +public class MicroblogSender extends AlertSender { + + private final Log log = LogFactory.getLog(MicroblogSender.class); + + @Override + public SenderResult send(Alert alert) { + + String user = preferences.getSimpleValue("user",null); + String password = preferences.getSimpleValue("password",null); + String baseUrl = preferences.getSimpleValue("microblogServerUrl","http://twitter.com/api/"); + if (!baseUrl.endsWith("/")) + baseUrl = baseUrl +"/"; + Twitter twitter = new Twitter(user,password,baseUrl); + AlertManagerLocal alertManager = LookupUtil.getAlertManager(); + twitter.setSource("Jopr"); + StringBuilder b = new StringBuilder("Alert: '"); + b.append(alert.getAlertDefinition().getResource().getName()); + b.append("' ("); + b.append(alert.getAlertDefinition().getResource().getId()); + b.append("): "); + b.append(alertManager.prettyPrintAlertConditions(alert)); + b.append("-by @JBossJopr"); // TODO not for production :-) + // TODO use some alert url shortening service + + SenderResult result ; + try { + twitter.updateStatus(b.toString()); + result = new SenderResult(ResultState.SUCCESS,"Send notification to " + baseUrl + " as user " + user); + } catch (TwitterException e) { + log.warn("Notification via Microblog failed: ", e); + result = new SenderResult(ResultState.FAILURE,"Sending failed :" + e.getMessage()); + } + return result; + } +} diff --git a/modules/enterprise/server/plugins/alert-microblog/src/main/resources/META-INF/rhq-serverplugin.xml b/modules/enterprise/server/plugins/alert-microblog/src/main/resources/META-INF/rhq-serverplugin.xml new file mode 100644 index 0000000..64b5f1d --- /dev/null +++ b/modules/enterprise/server/plugins/alert-microblog/src/main/resources/META-INF/rhq-serverplugin.xml @@ -0,0 +1,40 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<alert-plugin + name="alert-microblog" + displayName="Alert:Microblog" + xmlns="urn:xmlns:rhq-serverplugin.alert" + xmlns:c="urn:xmlns:rhq-configuration" + xmlns:serverplugin="urn:xmlns:rhq-serverplugin" + package="org.rhq.enterprise.server.plugins.alertMicroblog" + description="Alert sender plugin that sends alert notifications via Microblog serviecs (twitter, laconi.ca, ..)" + version="1.0" + > + + serverplugin:help + This alert sender plugin is used to send notifications via Microblogging + services that use a Twitter-like API like laconi.ca / identi.ca or twitter itself + </serverplugin:help> + + <!-- startup & tear down listener, + scheduled jobs + <serverplugin:plugin-component class="Foo" /> + --> + + + <!-- Global preferences for all mircoblog alerts --> + serverplugin:plugin-configuration + <c:simple-property name="microblogServerUrl" displayName="Microblog server URL" type="string" + default="http://twitter.com/api" + description="Base URL of the Microblog server"/> + <c:simple-property name="user" displayName="User name" type="string" /> + <c:simple-property name="password" displayName="Password" type="password"/> + + </serverplugin:plugin-configuration> + + <!-- How does this sender show up in drop downs etc --> + <short-name>Microblog</short-name> + + <!-- Class that does the actual sending --> + <plugin-class>MicroblogSender</plugin-class> + +</alert-plugin> \ No newline at end of file diff --git a/modules/enterprise/server/plugins/pom.xml b/modules/enterprise/server/plugins/pom.xml index 99a7530..cf4e995 100644 --- a/modules/enterprise/server/plugins/pom.xml +++ b/modules/enterprise/server/plugins/pom.xml @@ -41,6 +41,7 @@ <module>rhnhosted</module> <module>alert-email</module> <module>alert-mobicents</module> + <module>alert-microblog</module> </modules>
</project>
commit 6e4c7b2e06312ad89d00d35ae2cffcddebb08b95 Author: Justin Harris jharris@redhat.com Date: Tue Dec 1 13:08:10 2009 -0500
Adding in autoselection of plugin given a request param, and linking in from plugin details page.
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/PluginConfigurationUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/PluginConfigurationUIBean.java index 75747eb..49634bd 100644 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/PluginConfigurationUIBean.java +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/PluginConfigurationUIBean.java @@ -26,6 +26,7 @@ import org.jboss.seam.annotations.Create; import org.jboss.seam.annotations.Logger; import org.jboss.seam.annotations.Name; import org.jboss.seam.annotations.Scope; +import org.jboss.seam.annotations.web.RequestParameter; import org.jboss.seam.log.Log; import org.rhq.core.clientapi.agent.metadata.ConfigurationMetadataParser; import org.rhq.core.domain.auth.Subject; @@ -41,6 +42,7 @@ import org.rhq.enterprise.server.plugin.ServerPluginsLocal; import org.rhq.enterprise.server.plugin.pc.ServerPluginType; import org.rhq.enterprise.server.util.LookupUtil; import org.rhq.enterprise.server.xmlschema.generated.serverplugin.ServerPluginDescriptorType; +import org.richfaces.component.UITree; import org.richfaces.component.html.HtmlTree; import org.richfaces.event.NodeSelectedEvent; import org.richfaces.model.TreeNode; @@ -50,6 +52,8 @@ import org.richfaces.model.TreeNodeImpl; @Name("pluginConfigUIBean") public class PluginConfigurationUIBean {
+ @RequestParameter + private String pluginName; @Logger private Log log; private final ServerPluginsLocal serverPluginsBean = LookupUtil.getServerPlugins(); @@ -123,26 +127,52 @@ public class PluginConfigurationUIBean { return pluginNode; }
- public void processSelection(NodeSelectedEvent event) { - HtmlTree tree = (HtmlTree) event.getSource(); - this.currentPlugin = (ServerPlugin) tree.getRowData(); + public boolean adviseOpened(UITree node) { + // Expand the whole tree by default + return true; + } + + /** + * Advise the plugin tree if the provided node should be selected. + * + * @param node the {@link UITree} in question - will either have data a + * {@link ServerPlugin} or {@link ServerPluginType} is the row + * data. + * + * @return <code>true</code> if this node should be selected, + * <code>false</code> otherise + */ + public boolean adviseSelected(UITree node) { + if (isServerPluginSelected(node)) { + if (this.currentPlugin != null) { + return node.getRowData() == this.currentPlugin; + } else { // there is no plugin currently selected + ServerPlugin plugin = (ServerPlugin) node.getRowData(); + + // if this is the node that matches the request parameter, + // go ahead and load the config and select this node + if (plugin.getName().equals(this.pluginName)) { + this.currentPlugin = plugin; + lookupConfigDefinitions(); + + return true; + } + } + }
- lookupConfigDefinitions(); + // the node is a plugin server type - we don't want to select + // that if we don't have to. + return false; }
- public void lookupConfigDefinitions() { - if (this.currentPlugin.getDeployment() == PluginDeploymentType.SERVER) { - PluginKey pluginKey = new PluginKey(this.currentPlugin); + public void processSelection(NodeSelectedEvent event) { + HtmlTree node = (HtmlTree) event.getSource();
- try { - ServerPluginDescriptorType descriptor = serverPluginsBean.getServerPluginDescriptor(pluginKey); - this.pluginConfigurationDefinition = ConfigurationMetadataParser.parse("pc:" + pluginKey.getPluginName(), descriptor.getPluginConfiguration()); - this.scheduledJobsDefinition = ConfigurationMetadataParser.parse("jobs:" + pluginKey.getPluginName(), descriptor.getScheduledJobs()); - } catch (Exception e) { - String err = "Cannot determine what the plugin configuration or scheduled jobs configuration looks like"; - log.error(err + " - Cause: " + e); - FacesContextUtility.addMessage(FacesMessage.SEVERITY_ERROR, err, e); - } + if (isServerPluginSelected(node)) { + this.currentPlugin = (ServerPlugin) node.getRowData(); + lookupConfigDefinitions(); + + node.setSelected(); } }
@@ -159,6 +189,26 @@ public class PluginConfigurationUIBean { } }
+ private boolean isServerPluginSelected(UITree tree) { + return tree.getRowData() instanceof ServerPlugin; + } + + private void lookupConfigDefinitions() { + if (this.currentPlugin.getDeployment() == PluginDeploymentType.SERVER) { + PluginKey pluginKey = new PluginKey(this.currentPlugin); + + try { + ServerPluginDescriptorType descriptor = serverPluginsBean.getServerPluginDescriptor(pluginKey); + this.pluginConfigurationDefinition = ConfigurationMetadataParser.parse("pc:" + pluginKey.getPluginName(), descriptor.getPluginConfiguration()); + this.scheduledJobsDefinition = ConfigurationMetadataParser.parse("jobs:" + pluginKey.getPluginName(), descriptor.getScheduledJobs()); + } catch (Exception e) { + String err = "Cannot determine what the plugin configuration or scheduled jobs configuration looks like"; + log.error(err + " - Cause: " + e); + FacesContextUtility.addMessage(FacesMessage.SEVERITY_ERROR, err, e); + } + } + } + // TODO: Find a more centralized way to do this - maybe via annotation // on the class?? /** diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-config.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-config.xhtml index fea1d29..e061589 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-config.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-config.xhtml @@ -54,11 +54,13 @@ </f:facet>
<rich:tree nodeSelectListener="#{pluginConfigUIBean.processSelection}" + adviseNodeSelected="#{pluginConfigUIBean.adviseSelected}" + adviseNodeOpened="#{pluginConfigUIBean.adviseOpened}" reRender="pluginConfig" value="#{pluginConfigUIBean.root}" ajaxSubmitSelection="true" switchType="client" - toggleOnClick="true" + toggleOnClick="false" treeNodeVar="node" var="item" nodeFace="#{node.leaf ? 'plugin' : 'pluginType'}"> diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-details.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-details.xhtml index aba7769..5bb4b2a 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-details.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-details.xhtml @@ -61,15 +61,22 @@
<h:outputLabel styleClass="BlockLabel" value="Path:"/> <h:outputText value="#{plugin.path}"/> - </h:panelGrid>
+ <br /> + <h:outputLink value="/rhq/admin/plugin/plugin-config.xhtml" rendered="#{plugin.deployment eq 'SERVER'}"> + <f:param name="pluginName" value="#{plugin.name}"/> + <h:outputText value="Configure '#{plugin.displayName}'"/> + </h:outputLink> + <br /> + <br /> + rich:panel <f:facet name="header"> <h:outputText value="Plugin Help"/> </f:facet>
- <h:outputText escape="false" value="<pre> #{plugin.help} </pre>"/> + <h:outputText escape="false" value="<pre> #{plugin.help} </pre>"/>
</rich:panel> </rich:panel>
commit 9127696c8cf75be90b2dda7d9b4a1ccffecdd6d6 Author: John Sanda john@localhost.localdomain Date: Tue Dec 1 11:58:59 2009 -0500
[US 6] Implementing update functionality for structured and raw
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/StructuredAndRawConfigManagement.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/StructuredAndRawConfigManagement.java index d8a9ed1..30dcc2e 100644 --- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/StructuredAndRawConfigManagement.java +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/StructuredAndRawConfigManagement.java @@ -84,7 +84,12 @@ public class StructuredAndRawConfigManagement extends ConfigManagementSupport { } }
- public void executeUpdate(int resourceId, Configuration configuration) - throws PluginContainerException { + public void executeUpdate(int resourceId, Configuration configuration) throws PluginContainerException { + ResourceConfigurationFacet facet = loadResourceConfigFacetWithWriteLock(resourceId); + + facet.persistStructuredConfiguration(configuration); + for (RawConfiguration rawConfig : configuration.getRawConfigurations()) { + facet.persistRawConfiguration(rawConfig); + } } } diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/StructuredAndRawConfigManagementTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/StructuredAndRawConfigManagementTest.java index 7dbc1b6..4ee7cc2 100644 --- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/StructuredAndRawConfigManagementTest.java +++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/StructuredAndRawConfigManagementTest.java @@ -75,7 +75,7 @@ public class StructuredAndRawConfigManagementTest extends ConfigManagementTest { );
- addDefaultExpectations(config, rawConfigs); + addDefaultExpectationsForLoad(config, rawConfigs);
Configuration loadedConfig = structuredAndRawConfigManagement.execute(resourceId);
@@ -88,7 +88,7 @@ public class StructuredAndRawConfigManagementTest extends ConfigManagementTest { config.put(new PropertySimple("x", "1")); config.put(new PropertySimple("y", "2"));
- addDefaultExpectations(config, EMPTY_SET); + addDefaultExpectationsForLoad(config, EMPTY_SET);
Configuration loadedConfig = structuredAndRawConfigManagement.execute(resourceId);
@@ -100,7 +100,7 @@ public class StructuredAndRawConfigManagementTest extends ConfigManagementTest { Configuration config = new Configuration(); config.setNotes(null);
- addDefaultExpectations(config, EMPTY_SET); + addDefaultExpectationsForLoad(config, EMPTY_SET);
Configuration loadedConfig = structuredAndRawConfigManagement.execute(resourceId);
@@ -113,7 +113,7 @@ public class StructuredAndRawConfigManagementTest extends ConfigManagementTest {
Set<RawConfiguration> rawConfigs = toSet(createRawConfiguration("/tmp/foo.txt"));
- addDefaultExpectations(config, rawConfigs); + addDefaultExpectationsForLoad(config, rawConfigs);
Configuration loadedConfig = structuredAndRawConfigManagement.execute(resourceId);
@@ -131,7 +131,7 @@ public class StructuredAndRawConfigManagementTest extends ConfigManagementTest {
Set<RawConfiguration> rawConfigs = null;
- addDefaultExpectations(config, rawConfigs); + addDefaultExpectationsForLoad(config, rawConfigs);
Configuration loadedConfig = structuredAndRawConfigManagement.execute(resourceId);
@@ -162,7 +162,7 @@ public class StructuredAndRawConfigManagementTest extends ConfigManagementTest { assertNull(loadedConfig, "Expected null to be returned when facet returns null for both structured and raw."); }
- private void addDefaultExpectations(final Configuration config, final Set<RawConfiguration> rawConfigs) + private void addDefaultExpectationsForLoad(final Configuration config, final Set<RawConfiguration> rawConfigs) throws Exception {
context.checking(new Expectations() {{ @@ -188,4 +188,32 @@ public class StructuredAndRawConfigManagementTest extends ConfigManagementTest { }}); }
+ @Test + public void facetShouldBeCalledToUpdateStructuredAndRaw() throws Exception { + final RawConfiguration raw1 = createRawConfiguration("/tmp/raw1.txt"); + final RawConfiguration raw2 = createRawConfiguration("/tmp/raw2.txt"); + + final Configuration config = new Configuration(); + config.addRawConfiguration(raw1); + config.addRawConfiguration(raw2); + + final boolean isDaemonThread = false; + + context.checking(new Expectations() {{ + atLeast(1).of(componentService).getComponent(resourceId, + ResourceConfigurationFacet.class, + FacetLockType.WRITE, + ConfigManagement.FACET_METHOD_TIMEOUT, + isDaemonThread, + onlyIfStarted); + will(returnValue(configFacet)); + + oneOf(configFacet).persistStructuredConfiguration(config); + oneOf(configFacet).persistRawConfiguration(raw1); + oneOf(configFacet).persistRawConfiguration(raw2); + }}); + + structuredAndRawConfigManagement.executeUpdate(resourceId, config); + } + } diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/StructuredConfigManagementTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/StructuredConfigManagementTest.java index cac0ca4..855aab4 100644 --- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/StructuredConfigManagementTest.java +++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/StructuredConfigManagementTest.java @@ -138,7 +138,7 @@ public class StructuredConfigManagementTest extends ConfigManagementTest { onlyIfStarted); will(returnValue(configFacet));
- atLeast(1).of(configFacet).persistStructuredConfiguration(structuredConfig); + oneOf(configFacet).persistStructuredConfiguration(structuredConfig); }});
structuredMgmt.executeUpdate(resourceId, structuredConfig);
commit 0924ffc4234cf3e030e150a43436c31a2ef1cb78 Merge: f384798... b282334... Author: John Sanda john@localhost.localdomain Date: Tue Dec 1 10:31:40 2009 -0500
Merge branch 'raw-config' of ssh://git.fedorahosted.org/git/rhq/rhq into raw-config
commit f384798fd613857bcec5e3bdb7618ca08d30ca6e Author: John Sanda john@localhost.localdomain Date: Tue Dec 1 10:30:41 2009 -0500
[US 910] Adding CLI script test for structured config update using the new API
diff --git a/modules/enterprise/remoting/scripts/src/test/script/org/rhq/enterprise/remoting/cli/test_ConfigurationManager.js b/modules/enterprise/remoting/scripts/src/test/script/org/rhq/enterprise/remoting/cli/test_ConfigurationManager.js index ed964ef..9e9961e 100644 --- a/modules/enterprise/remoting/scripts/src/test/script/org/rhq/enterprise/remoting/cli/test_ConfigurationManager.js +++ b/modules/enterprise/remoting/scripts/src/test/script/org/rhq/enterprise/remoting/cli/test_ConfigurationManager.js @@ -26,7 +26,6 @@ rhq.login('rhqadmin', 'rhqadmin'); skippedTests.push('testUpdateResourceGroupConfiguration');
executeAllTests(); -//executeTests(['testGetAndUpdateRawConfiguration']);
rhq.logout();
@@ -58,9 +57,7 @@ function testGetAndUpdateRawConfiguration() { var resourceName = 'Raw Server' var rawServer = findResourceByNameAndParentName(resourceName, 'localhost');
- Assert.assertNotNull(rawServer, "Failed to find '" + resourceName + "'"); - - var latestUpdate = loadLatestResourceConfigurationUpdate(resourceName, rawServer.id); + var latestUpdate = loadLatestRawConfigUpdate(resourceName, rawServer.id); var rawConfig = getRawConfig(resourceName, latestUpdate.configuration, 0);
var contents = java.lang.String(rawConfig.contents); @@ -72,7 +69,7 @@ function testGetAndUpdateRawConfiguration() {
waitForResourceConfigUpdateToComplete(rawServer.id);
- latestUpdate = loadLatestResourceConfigurationUpdate(resourceName, rawServer.id); + latestUpdate = loadLatestRawConfigUpdate(resourceName, rawServer.id);
rawConfigs = java.util.LinkedList(latestUpdate.configuration.rawConfigurations); rawConfig = rawConfigs.get(0); @@ -85,7 +82,29 @@ function testGetAndUpdateRawConfiguration() { ); }
-function loadLatestResourceConfigurationUpdate(resourceName, resourceId) { +function testGetAndUpdateStructuredConfiguration() { + var resourceName = 'Structured Server'; + var structuredServer = findResourceByNameAndParentName(resourceName, 'localhost'); + + var latestUpdate = loadLatestStructuredConfigUpdate(resourceName, structuredServer.id); + var modifiedConfig = latestUpdate.configuration; + + modifiedConfig.put(PropertySimple("foo", java.util.Date())); + + var configUdpate = ConfigurationManager.updateResourceConfiguration(structuredServer.id, modifiedConfig); + + waitForResourceConfigUpdateToComplete(structuredServer.id); + + latestUpdate = loadLatestStructuredConfigUpdate(resourceName, structuredServer.id); + + Assert.assertEquals( + latestUpdate.configuration, + modifiedConfig, + "Failed to update structured config for '" + resourceName + "'" + ); +} + +function loadLatestRawConfigUpdate(resourceName, resourceId) { var latestUpdate = ConfigurationManager.getLatestResourceConfigurationUpdate(resourceId);
Assert.assertNotNull(latestUpdate, "Failed to find latest resource configuration update for '" + resourceName + "'"); @@ -97,6 +116,13 @@ function loadLatestResourceConfigurationUpdate(resourceName, resourceId) { return latestUpdate; }
+function loadLatestStructuredConfigUpdate(resourceName, resourceId) { + var latestUpdate = ConfigurationManager.getLatestResourceConfigurationUpdate(resourceId); + Assert.assertNotNull(latestUpdate, "Failed to find latest resource configuration update for '" + resourceName + "'"); + + return latestUpdate; +} + function getRawConfig(resourceName, configuration, index) { var rawConfigs = java.util.LinkedList(configuration.rawConfigurations); var rawConfig = rawConfigs.get(index); @@ -185,7 +211,11 @@ function findResourceByNameAndParentName(name, parentName) { criteria.addFilterParentResourceName(parentName); criteria.strict = true;
- return ResourceManager.findResourcesByCriteria(criteria).get(0); + var resource = ResourceManager.findResourcesByCriteria(criteria).get(0); + + Assert.assertNotNull(resource, "Failed to find '" + name + "'"); + + return resource; }
function findBetaServices(parentName) { diff --git a/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/StructuredServer.groovy b/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/StructuredServer.groovy index 61ad25e..d92714f 100644 --- a/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/StructuredServer.groovy +++ b/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/StructuredServer.groovy @@ -8,34 +8,37 @@ import org.rhq.core.domain.configuration.PropertySimple import org.rhq.core.domain.configuration.Configuration import org.apache.commons.configuration.PropertiesConfiguration import org.rhq.core.domain.configuration.RawConfiguration +import groovy.util.AntBuilder
class StructuredServer implements ResourceComponent, ResourceConfigurationFacet {
- File rawConfigDir + File configDir
- File rawConfig1 + File structuredConfigFile + + def ant = new AntBuilder()
void start(ResourceContext context) { - rawConfigDir = new File("${System.getProperty('java.io.tmpdir')}/raw-config-test") - rawConfig1 = new File(rawConfigDir, "structured-test-1.txt") + configDir = new File("${System.getProperty('java.io.tmpdir')}/raw-config-test") + structuredConfigFile = new File(configDir, "structured-test-1.txt")
createRawConfigDir() createConfigFile() }
def createRawConfigDir() { - rawConfigDir.mkdirs() + configDir.mkdirs() }
def createConfigFile() { - if (rawConfig1.exists()) { + if (structuredConfigFile.exists()) { return null }
def properties = ["foo": "1", "bar": "2", "bam": "3"]
- rawConfig1.createNewFile() - rawConfig1.withWriter { writer -> + structuredConfigFile.createNewFile() + structuredConfigFile.withWriter { writer -> properties.each { key, value -> writer.writeLine("${key}=${value}") } } } @@ -48,7 +51,7 @@ class StructuredServer implements ResourceComponent, ResourceConfigurationFacet }
Configuration loadStructuredConfiguration() { - def propertiesConfig = new PropertiesConfiguration(rawConfig1) + def propertiesConfig = new PropertiesConfiguration(structuredConfigFile) def config = new Configuration()
config.put(new PropertySimple("foo", propertiesConfig.getString("foo"))) @@ -70,6 +73,16 @@ class StructuredServer implements ResourceComponent, ResourceConfigurationFacet }
void persistStructuredConfiguration(Configuration configuration) { + ant.copy(file: structuredConfigFile.absolutePath, tofile: "${structuredConfigFile.absolutePath}.orig") + ant.delete(file: structuredConfigFile) + + def file = new File(structuredConfigFile.path) + file.createNewFile() + + def propertiesConfig = new PropertiesConfiguration(structuredConfigFile) + + configuration.properties.each { propertiesConfig.setProperty(it.name, it.stringValue) } + propertiesConfig.save(file) }
void persistRawConfiguration(RawConfiguration rawConfiguration) {
commit 0b73cd3628098f43fcc4f25d0cde64286b209a95 Author: Heiko W. Rupp pilhuhn@fedorapeople.org Date: Tue Dec 1 15:15:46 2009 +0100
Fix help text
diff --git a/modules/enterprise/server/plugins/alert-mobicents/src/main/resources/META-INF/rhq-serverplugin.xml b/modules/enterprise/server/plugins/alert-mobicents/src/main/resources/META-INF/rhq-serverplugin.xml index 48e44f0..eeb5c1e 100644 --- a/modules/enterprise/server/plugins/alert-mobicents/src/main/resources/META-INF/rhq-serverplugin.xml +++ b/modules/enterprise/server/plugins/alert-mobicents/src/main/resources/META-INF/rhq-serverplugin.xml @@ -12,8 +12,7 @@ >
serverplugin:help - This alert sender plugin is used to send emails when alerts were triggered. - Notifications can go via voice calls or short messages etc. + This alert sender plugin is used to send voice calls or SMS when alerts were triggered. </serverplugin:help>
<!-- startup & tear down listener, + scheduled jobs
commit 6aa77d04cf9d3b807ee66c72696acbc47871546e Author: John Mazzitelli mazz@redhat.com Date: Tue Dec 1 08:56:44 2009 -0500
create tests for new queries
diff --git a/modules/core/domain/src/test/java/org/rhq/core/domain/resource/test/ServerPluginTest.java b/modules/core/domain/src/test/java/org/rhq/core/domain/resource/test/ServerPluginTest.java index c8acf79..7186f52 100644 --- a/modules/core/domain/src/test/java/org/rhq/core/domain/resource/test/ServerPluginTest.java +++ b/modules/core/domain/src/test/java/org/rhq/core/domain/resource/test/ServerPluginTest.java @@ -27,6 +27,7 @@ import java.io.InputStream; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; +import java.util.ArrayList; import java.util.Arrays; import java.util.List;
@@ -40,6 +41,7 @@ import org.testng.annotations.Test; import org.rhq.core.domain.configuration.Configuration; import org.rhq.core.domain.configuration.PropertySimple; import org.rhq.core.domain.plugin.PluginDeploymentType; +import org.rhq.core.domain.plugin.PluginKey; import org.rhq.core.domain.plugin.PluginStatusType; import org.rhq.core.domain.plugin.ServerPlugin; import org.rhq.core.domain.test.AbstractEJB3Test; @@ -283,6 +285,7 @@ public class ServerPluginTest extends AbstractEJB3Test { String md5 = MessageDigestGenerator.getDigestString(new String(content)); PluginDeploymentType deployment = PluginDeploymentType.SERVER; String ampsVersion = "1.2"; + String type = "the-type-here";
Configuration pluginConfig = new Configuration(); Configuration jobsConfig = new Configuration(); @@ -301,6 +304,7 @@ public class ServerPluginTest extends AbstractEJB3Test { plugin.setDeployment(deployment); plugin.setPluginConfiguration(pluginConfig); plugin.setScheduledJobsConfiguration(jobsConfig); + plugin.setType(type);
em.persist(plugin); assert plugin.getId() > 0; @@ -320,6 +324,7 @@ public class ServerPluginTest extends AbstractEJB3Test { assert plugin.getPluginConfiguration().equals(pluginConfig); assert plugin.getScheduledJobsConfiguration().equals(jobsConfig); assert plugin.getHelp().equals(help); + assert plugin.getType().equals(type); assert new String(plugin.getContent()).equals(new String(content));
// test our queries that purposefully do not load in the content blob @@ -340,6 +345,7 @@ public class ServerPluginTest extends AbstractEJB3Test { assert plugin.getPluginConfiguration().equals(pluginConfig); assert plugin.getScheduledJobsConfiguration().equals(jobsConfig); assert plugin.getHelp().equals(help); + assert plugin.getType().equals(type); assert plugin.getContent() == null;
query = em.createNamedQuery(ServerPlugin.QUERY_FIND_BY_IDS); @@ -359,6 +365,7 @@ public class ServerPluginTest extends AbstractEJB3Test { assert plugin.getPluginConfiguration().equals(pluginConfig); assert plugin.getScheduledJobsConfiguration().equals(jobsConfig); assert plugin.getHelp().equals(help); + assert plugin.getType().equals(type); assert plugin.getContent() == null;
query = em.createNamedQuery(ServerPlugin.QUERY_FIND_ALL_INSTALLED); @@ -380,12 +387,26 @@ public class ServerPluginTest extends AbstractEJB3Test { assert plugin.getPluginConfiguration().equals(pluginConfig); assert plugin.getScheduledJobsConfiguration().equals(jobsConfig); assert p.getHelp().equals(help); + assert plugin.getType().equals(type); assert p.getContent() == null; break; } } assert got_it : "findAll query failed to get our plugin";
+ query = em.createNamedQuery(ServerPlugin.QUERY_FIND_ALL_INSTALLED_KEYS); + List<PluginKey> allKeys = query.getResultList(); + assert allKeys.size() == 1; + assert allKeys.contains(new PluginKey(plugin)); + + query = em.createNamedQuery(ServerPlugin.QUERY_FIND_KEYS_BY_IDS); + ArrayList<Integer> ids = new ArrayList<Integer>(); + ids.add(plugin.getId()); + query.setParameter("ids", ids); + allKeys = query.getResultList(); + assert allKeys.size() == 1; + assert allKeys.contains(new PluginKey(plugin)); + // mark a plugin deleted - all of our queries should then never see it plugin.setStatus(PluginStatusType.DELETED); em.merge(plugin);
commit db9ff715729d5fb765c24d4fce6a1f68799f7376 Author: Heiko W. Rupp pilhuhn@fedorapeople.org Date: Tue Dec 1 10:58:52 2009 +0100
Mobicents alert sender. Needs to have Mobicents server + alert2voice servlet installed on it.
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerBean.java index 8946a8f..615b1f5 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerBean.java @@ -771,6 +771,16 @@ public class AlertManagerBean implements AlertManagerLocal, AlertManagerRemote { return builder.toString(); }
+ /** + * Create a human readable description of the conditions that led to this alert. + * @param alert Alert to create human readable condition description + * @return human readable condition log + */ + public String prettyPrintAlertConditions(Alert alert) { + entityManager.refresh(alert); + return prettyPrintAlertConditions(alert.getConditionLogs()); + } + private String prettyPrintAlertConditions(Set<AlertConditionLog> conditionLogs) { StringBuilder builder = new StringBuilder();
@@ -954,6 +964,30 @@ public class AlertManagerBean implements AlertManagerLocal, AlertManagerRemote { } }
+ /** + * Tells us if the definition of the passed alert will be disabled after this alert was fired + * @param alert alert to check + * @return true if the definition got disabled + */ + public boolean willDefinitionBeDisabled(Alert alert) { + entityManager.refresh(alert); + AlertDefinition firedDefinition = alert.getAlertDefinition(); + Subject overlord = subjectManager.getOverlord(); + Integer recoveryDefinitionId = firedDefinition.getRecoveryId(); + + if (recoveryDefinitionId != 0) { + AlertDefinition toBeRecoveredDefinition = alertDefinitionManager.getAlertDefinitionById(overlord, + recoveryDefinitionId); + boolean wasEnabled = toBeRecoveredDefinition.getEnabled(); + if (!wasEnabled) + return false; + } else if (firedDefinition.getWillRecover()) { + return true; + } + return false; // Default is not to disable the definition + } + + @SuppressWarnings("unchecked") public PageList<Alert> findAlertsByCriteria(Subject subject, AlertCriteria criteria) { CriteriaQueryGenerator generator = new CriteriaQueryGenerator(criteria);
commit bbc30408fced39cfc5388942b89445f2496d493f Author: Heiko W. Rupp pilhuhn@fedorapeople.org Date: Tue Dec 1 10:57:20 2009 +0100
Mobicents alert sender. Needs to have Mobicents server + alert2voice servlet installed on it.
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerLocal.java index 5b3479c..17615ea 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerLocal.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerLocal.java @@ -100,4 +100,18 @@ public interface AlertManagerLocal { * @return The alert sender plugin manager */ AlertSenderPluginManager getAlertPluginManager(); + + /** + * Create a human readable description of the conditions that led to this alert. + * @param alert Alert to create human readable condition description + * @return human readable condition log + */ + String prettyPrintAlertConditions(Alert alert); + + /** + * Tells us if the definition of the passed alert will be disabled after this alert was fired + * @param alert alert to check + * @return true if the definition got disabled + */ + boolean willDefinitionBeDisabled(Alert alert); } \ No newline at end of file diff --git a/modules/enterprise/server/plugins/alert-mobicents/pom.xml b/modules/enterprise/server/plugins/alert-mobicents/pom.xml new file mode 100644 index 0000000..d231484 --- /dev/null +++ b/modules/enterprise/server/plugins/alert-mobicents/pom.xml @@ -0,0 +1,130 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd%22%3E + <parent> + <artifactId>rhq-enterprise-server-plugins-parent</artifactId> + <groupId>org.rhq</groupId> + <version>1.4.0-SNAPSHOT</version> + </parent> + <modelVersion>4.0.0</modelVersion> + + <groupId>org.rhq</groupId> + <artifactId>alert-mobicents</artifactId> + <version>1.4.0-SNAPSHOT</version> + + <name>RHQ Enterprise Server Mobicents Alert Plugin</name> + + <scm> + <connection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/modules/enterprise/server/plugins/alert-mobicents/</connection> + <developerConnection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/modules/enterprise/server/plugins/alert-mobicents/</developerConnection> + </scm> + + <properties> + <scm.module.path>modules/enterprise/server/plugins/alert-mobicents/</scm.module.path> + </properties> + + <dependencies> + + <dependency> + <groupId>org.rhq</groupId> + <artifactId>rhq-enterprise-server</artifactId> + <version>1.4.0-SNAPSHOT</version> + <scope>provided</scope> <!-- by JBossAS --> + </dependency> + + <!-- TODO: This is a fix for the Javac bug requiring annotations to be + available when compiling dependent classes. It is fixed in JDK 6 --> + <dependency> + <groupId>javax.persistence</groupId> + <artifactId>persistence-api</artifactId> + <version>1.0</version> + <scope>provided</scope> + </dependency> + + <dependency> + <groupId>jboss.jboss-embeddable-ejb3</groupId> + <artifactId>hibernate-all</artifactId> + <version>1.0.0.Alpha9</version> + <scope>provided</scope> + <!-- needed for referenced domain entities that use Hibernate annotations --> + </dependency> + + </dependencies> + + <build> + <plugins> + + <plugin> + <artifactId>maven-surefire-plugin</artifactId> + <configuration> + <excludedGroups>${rhq.testng.excludedGroups}</excludedGroups> + <!-- + <argLine>-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=y</argLine> + --> + </configuration> + </plugin> + + </plugins> + </build> + + <profiles> + + <profile> + <id>dev</id> + + <properties> + <rhq.rootDir>../../../../..</rhq.rootDir> + <rhq.containerDir>${rhq.rootDir}/${rhq.defaultDevContainerPath}</rhq.containerDir> + <rhq.deploymentDir>${rhq.containerDir}/jbossas/server/default/deploy/${rhq.earName}/rhq-serverplugins</rhq.deploymentDir> + </properties> + + <build> + <plugins> + + <plugin> + <artifactId>maven-antrun-plugin</artifactId> + <version>1.1</version> + <executions> + + <execution> + <id>deploy</id> + <phase>compile</phase> + <configuration> + <tasks> + <mkdir dir="${rhq.deploymentDir}" /> + <property name="deployment.file" location="${rhq.deploymentDir}/${project.build.finalName}.jar" /> + <echo>*** Updating ${deployment.file}...</echo> + <jar destfile="${deployment.file}" basedir="${project.build.outputDirectory}" /> + </tasks> + </configuration> + <goals> + <goal>run</goal> + </goals> + </execution> + + <execution> + <id>undeploy</id> + <phase>clean</phase> + <configuration> + <tasks> + <property name="deployment.file" location="${rhq.deploymentDir}/${project.build.finalName}.jar" /> + <echo>*** Deleting ${deployment.file}...</echo> + <delete file="${deployment.file}" /> + </tasks> + </configuration> + <goals> + <goal>run</goal> + </goals> + </execution> + + </executions> + </plugin> + + </plugins> + </build> + </profile> + + </profiles> + +</project> \ No newline at end of file diff --git a/modules/enterprise/server/plugins/alert-mobicents/src/main/java/org/rhq/enterprise/server/plugins/alertMobicents/MobiKind.java b/modules/enterprise/server/plugins/alert-mobicents/src/main/java/org/rhq/enterprise/server/plugins/alertMobicents/MobiKind.java new file mode 100644 index 0000000..33dd87f --- /dev/null +++ b/modules/enterprise/server/plugins/alert-mobicents/src/main/java/org/rhq/enterprise/server/plugins/alertMobicents/MobiKind.java @@ -0,0 +1,30 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2009 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.plugins.alertMobicents; + +/** + * Possible ways of sending stuff over Mobicents + * @author Heiko W. Rupp + */ +public enum MobiKind { + VOICE, + SMS, + MMS, + XMPP +} diff --git a/modules/enterprise/server/plugins/alert-mobicents/src/main/java/org/rhq/enterprise/server/plugins/alertMobicents/MobicentsSender.java b/modules/enterprise/server/plugins/alert-mobicents/src/main/java/org/rhq/enterprise/server/plugins/alertMobicents/MobicentsSender.java new file mode 100644 index 0000000..6111d7e --- /dev/null +++ b/modules/enterprise/server/plugins/alert-mobicents/src/main/java/org/rhq/enterprise/server/plugins/alertMobicents/MobicentsSender.java @@ -0,0 +1,168 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2009 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.plugins.alertMobicents; + +import java.io.OutputStream; +import java.net.HttpURLConnection; +import java.net.URL; +import java.net.URLEncoder; +import java.util.Locale; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.rhq.core.domain.alert.Alert; +import org.rhq.core.domain.resource.Resource; +import org.rhq.enterprise.server.alert.AlertManagerLocal; +import org.rhq.enterprise.server.plugin.pc.alert.AlertSender; +import org.rhq.enterprise.server.plugin.pc.alert.ResultState; +import org.rhq.enterprise.server.plugin.pc.alert.SenderResult; +import org.rhq.enterprise.server.util.LookupUtil; + +/** + * AlertSender that notifies users via Mobicents (voice, sms) + * @author Heiko W. Rupp + */ +public class MobicentsSender extends AlertSender { + + private final Log log = LogFactory.getLog(MobicentsSender.class); + + @Override + public SenderResult send(Alert alert) { + + String baseUrl = preferences.getSimpleValue("mobicentsServerUrl","http://localhost:8080/mobicents"); + String tel = alertParameters.getSimpleValue("targetAddress",null); + if (tel==null) { + log.warn("No number to call given, not sending"); + return new SenderResult(ResultState.FAILURE, "No target address given"); + } + String kindString = alertParameters.getSimpleValue("kind","VOICE"); + MobiKind kind = MobiKind.valueOf(kindString); + + Integer alertId = alert.getId(); + StringBuilder b = new StringBuilder("alertText="); + Resource res = alert.getAlertDefinition().getResource(); + AlertManagerLocal alertManager = LookupUtil.getAlertManager(); + + switch (kind) { + case VOICE: + b.append("Alert on resource "); + do { + b.append(res.getName()); + res = res.getParentResource(); + if (res!=null) + b.append(" with parent "); + } while (res!=null); + b.append(". Cause is "); + + // Switch locale to english, as the voice synthesizer expects this for now + Locale currentLocale = Locale.getDefault(); + Locale.setDefault(Locale.ENGLISH); + b.append(alertManager.prettyPrintAlertConditions(alert)); + Locale.setDefault(currentLocale); + + boolean willBeDisabled = alertManager.willDefinitionBeDisabled(alert); + + if (willBeDisabled) + b.append(" The alert definition will now be disabled. \n\n"); + + // b.append(" Please press "); + // + // if (willBeDisabled) { + // b.append(AlertFeedback.REENABLE.getText()); + // } else { + // b.append(AlertFeedback.DISABLE.getText()); + // } + // b.append(", "); + // b.append(AlertFeedback.DELETE.getText()); + // b.append(" or just hang up to do nothing."); + break; + case SMS: + b.append("Alert: "); + b.append(res.getName()); + b.append(",id=(").append(res.getId()).append(")"); + b.append("Brought by RHQ"); + break; + default: + log.warn("Unsupported Mobicents notification type for now"); + } + + URL url; + int code=0; + HttpURLConnection conn = null; + try { + tel = tel.trim(); + String telEnc = URLEncoder.encode(tel,"UTF-8"); // url encode tel-no, as it can contain '+' + switch (kind) { + case SMS: + baseUrl = baseUrl + "sms"; // No trailing '/' ! + break; + case VOICE: + baseUrl = baseUrl + "call"; // No trailing '/' ! + break; + default: + baseUrl = baseUrl + "--not-supported-yet--"; + } + baseUrl = baseUrl +"?alertId="+alertId; + baseUrl = baseUrl +"&tel="; + if (kind==MobiKind.VOICE) { + if (!tel.startsWith("sip:")) { + baseUrl = baseUrl +"sip:"; + } + } + baseUrl = baseUrl +telEnc; + if (kind==MobiKind.VOICE) { + if (!tel.endsWith("@callwithus.com")) { // TODO parametrize + baseUrl = baseUrl + "@callwithus.com"; + } + } + // TODO SMS url + + log.info("Mobicents alert ["+ kind + "] to baseUrl [" + baseUrl + "] with message:\n" + b.toString()); + url = new URL(baseUrl); + conn = (HttpURLConnection) url.openConnection(); + conn.setRequestMethod("POST"); + conn.setDoOutput(true); + conn.setDoInput(true); + OutputStream out = conn.getOutputStream(); + + //conn.addRequestProperty("text",b.toString()); + // TODO encode? + out.write(b.toString().getBytes()); + out.flush(); + conn.connect(); + code = conn.getResponseCode(); + } catch (Exception e) { + log.warn("Notification via VoIP failed: " + e); + } + finally { + if (conn!=null) + conn.disconnect(); + } + SenderResult result; + if (code!=200) { + log.info("Notification via Mobicents returned code " + code); + result=new SenderResult(ResultState.FAILURE,"Notification via Mobicents returned code " + code); + } + else { + result=new SenderResult(ResultState.SUCCESS,"Mobicents alert ["+ kind + "] to baseUrl [" + baseUrl + "]" ); + } + return result; + } +} diff --git a/modules/enterprise/server/plugins/alert-mobicents/src/main/resources/META-INF/rhq-serverplugin.xml b/modules/enterprise/server/plugins/alert-mobicents/src/main/resources/META-INF/rhq-serverplugin.xml new file mode 100644 index 0000000..48e44f0 --- /dev/null +++ b/modules/enterprise/server/plugins/alert-mobicents/src/main/resources/META-INF/rhq-serverplugin.xml @@ -0,0 +1,54 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<alert-plugin + name="alert-mobicents" + displayName="Alert:Mobicents" + xmlns="urn:xmlns:rhq-serverplugin.alert" + xmlns:c="urn:xmlns:rhq-configuration" + xmlns:serverplugin="urn:xmlns:rhq-serverplugin" + package="org.rhq.enterprise.server.plugins.alertMobicents" + description="Alert sender plugin that sends alert notifications via Mobicents (voice, sms, ..)" + version="1.0" + > + + serverplugin:help + This alert sender plugin is used to send emails when alerts were triggered. + Notifications can go via voice calls or short messages etc. + </serverplugin:help> + + <!-- startup & tear down listener, + scheduled jobs + <serverplugin:plugin-component class="Foo" /> + --> + + + <!-- Global preferences for all email alerts --> + serverplugin:plugin-configuration + <c:simple-property name="mobicentsServerUrl" displayName="Mobicents server URL" type="longString" + default="http://localhost:8080/mobicents" + description="Base URL of the Mobicents server"/> + + </serverplugin:plugin-configuration> + + <!-- How does this sender show up in drop downs etc --> + <short-name>Mobicents</short-name> + + <!-- Class that does the actual sending --> + <plugin-class>MobicentsSender</plugin-class> + + <!-- What can a user configure when defining an alert --> + <alert-configuration> + <c:simple-property name="targetAddress" displayName="Address of the receiver" type="string" + description="Address of the receiver. This may e.g. be a telephone number"/> + <c:simple-property name="kind" displayName="Type of notification" type="string" default="Voice"> + <c:property-options> + <c:option value="VOICE" name="Voice" default="true"/> + <c:option value="SMS" name="SMS"/> + <!-- + <c:option value="MMS"/> + <c:option value="XMPP"/> + --> + </c:property-options> + </c:simple-property> + </alert-configuration> + +</alert-plugin> \ No newline at end of file diff --git a/modules/enterprise/server/plugins/pom.xml b/modules/enterprise/server/plugins/pom.xml index b3717bb..99a7530 100644 --- a/modules/enterprise/server/plugins/pom.xml +++ b/modules/enterprise/server/plugins/pom.xml @@ -40,7 +40,7 @@ <module>url</module> <module>rhnhosted</module> <module>alert-email</module> - <!-- <module>alert-mobicents</module> --> + <module>alert-mobicents</module> </modules>
</project>
commit 60e8a3af40893db5f6b27d4b9982795e03861e8d Author: Heiko W. Rupp pilhuhn@fedorapeople.org Date: Tue Dec 1 10:05:56 2009 +0100
Improve display and start on removing notifications.
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/ListNotificationsUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/ListNotificationsUIBean.java index f50705a..4ff8f20 100644 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/ListNotificationsUIBean.java +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/ListNotificationsUIBean.java @@ -18,6 +18,7 @@ */ package org.rhq.enterprise.gui.alert;
+import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; @@ -34,11 +35,15 @@ import org.jboss.seam.annotations.Name; import org.jboss.seam.annotations.Scope; import org.jboss.seam.annotations.web.RequestParameter;
+import org.rhq.core.domain.alert.AlertDefinition; import org.rhq.core.domain.alert.notification.AlertNotification; import org.rhq.core.domain.auth.Subject; import org.rhq.core.domain.configuration.Configuration; import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; +import org.rhq.core.gui.util.FacesContextUtility; +import org.rhq.core.gui.util.StringUtility; import org.rhq.enterprise.gui.util.EnterpriseFacesContextUtility; +import org.rhq.enterprise.server.alert.AlertDefinitionManagerLocal; import org.rhq.enterprise.server.alert.AlertNotificationManagerLocal; import org.rhq.enterprise.server.util.LookupUtil;
@@ -61,7 +66,7 @@ public class ListNotificationsUIBean { private Configuration alertProperties;
@RequestParameter("ad") - private int alertDefinitionId; + private Integer alertDefinitionId;
public ListNotificationsUIBean() { } @@ -113,9 +118,26 @@ public class ListNotificationsUIBean { }
public void setSelectedSender(String selectedSender) { + // If the user selects a different sender in the drop down, clean out the + // properties that may have been set + if (!selectedSender.equals(this.selectedSender)) { + alertProperties=null; + alertConfigurationDefinition = null; + } this.selectedSender = selectedSender; }
+ public String getAlertDefinitionName() { + if (alertDefinitionId==null) + return "- unset - "; + + AlertDefinitionManagerLocal mgr = LookupUtil.getAlertDefinitionManager(); + Subject subject = EnterpriseFacesContextUtility.getSubject(); + AlertDefinition def = mgr.getAlertDefinitionById(subject,alertDefinitionId); + + return def.getName(); + } + public String mySubmitForm() { log.info("In submit Form "); AlertNotificationManagerLocal mgr = LookupUtil.getAlertNotificationManager(); @@ -127,7 +149,25 @@ public class ListNotificationsUIBean { public Collection<AlertNotification> getExistingNotifications() { AlertNotificationManagerLocal mgr = LookupUtil.getAlertNotificationManager(); Subject subject = EnterpriseFacesContextUtility.getSubject(); + if (alertDefinitionId==null) + return new ArrayList<AlertNotification>(); + List<AlertNotification> notifications = mgr.getNotificationsForAlertDefinition(subject,alertDefinitionId); return notifications; } + + public String removeSelectedNotifications() { + String[] stringItems = FacesContextUtility.getRequest().getParameterValues("selectedNotification"); + if (stringItems == null || stringItems.length == 0) { + return OUTCOME_SUCCESS; // TODO leave message + } + + Integer[] notificationIds = StringUtility.getIntegerArray(stringItems); + + AlertNotificationManagerLocal mgr = LookupUtil.getAlertNotificationManager(); + Subject subject = EnterpriseFacesContextUtility.getSubject(); + mgr.removeNotifications(subject,alertDefinitionId,notificationIds); + + return OUTCOME_SUCCESS; + } } \ No newline at end of file diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/alert/notif/listAlertSender.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/alert/notif/listAlertSender.xhtml index dd24c0b..850676b 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/alert/notif/listAlertSender.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/alert/notif/listAlertSender.xhtml @@ -11,7 +11,7 @@
<ui:composition template="/rhq/layout/main.xhtml">
- <ui:param name="pageTitle" value="List Alert Notifications for Resource"/> <!-- '#{ResourceUIBean.name}'"/> --> + <ui:param name="pageTitle" value="List Alert Notifications for Resource '#{ResourceUIBean.name}'"/>
<ui:define name="breadcrumbs"> <h:outputLink value="http://localhost:7080/alerts/Config.do%22%3E @@ -22,7 +22,7 @@ </h:outputLink> <h:outputText> > </h:outputText> <h:outputLink value="listAlertSender.xhtml"> - Alert Sender stuff + New Alert Sender stuff </h:outputLink> </ui:define>
@@ -39,8 +39,9 @@ width="100%"/>
<p/> - <h:outputText>Existing notifications:</h:outputText> + <h:outputText>Existing notifications for Resource '#{ResourceUIBean.name}' and alert definition '#{ListNotificationsUIBean.alertDefinitionName}':</h:outputText> <br/> + <h:form id="notificationListForm"> <rich:dataTable id="alertNotificationDataTable" value="#{ListNotificationsUIBean.existingNotifications}" var="notif" @@ -51,6 +52,14 @@ onRowMouseOver="this.style.backgroundColor='#E7E7E7'" onRowMouseOut="this.style.backgroundColor='#{a4jSkin.tableBackgroundColor}'"> rich:column + <f:facet name="header"> + <onc:allSelect target="selectedNotification"/> + </f:facet> + + <onc:select name="selectedNotification" value="#{notif.id}"/> + </rich:column> + + rich:column <f:facet name="header"> <h:outputText styleClass="headerText" value="ID"/> </f:facet> @@ -73,10 +82,23 @@
<h:outputText value="#{notif.configuration.toString(true)}"/> </rich:column> - <!-- TODO add configuration --> + <f:facet name="footer"> + rich:columnGroup + <rich:column colspan="5" width="100%"> + <onc:selectCommandButton action="#{ListNotificationsUIBean.removeSelectedNotifications}" + target="selectedNotification" + value="Remove selected" + styleClass="on-pager-button buttonsmall"/> + </rich:column> + </rich:columnGroup> + </f:facet> + </rich:dataTable> + </h:form> + <p/>
- <h:outputText>Hello World</h:outputText> + <h:outputText>Add a sender:</h:outputText> + <br/> <h:form id="listSenderForm"> <input type="hidden" name="id" value="${param.id}"/> <input type="hidden" name="ad" value="${param.ad}"/> @@ -105,6 +127,11 @@ /> </rich:panel> </h:form> + + <h:outputLink value="rhq/resource/alert/listAlertDefinitions.xhtml"> + <f:param name="id" value="#{param.id}"/> + <h:outputText value="Back to Alert Definitions for Resource '#{ResourceUIBean.name}'"/> + </h:outputLink> </ui:define> </ui:composition> </html> \ No newline at end of file
commit dcbc1c34b890f0df371b192bd0a92cc4a175a753 Author: Heiko W. Rupp pilhuhn@fedorapeople.org Date: Tue Dec 1 09:26:09 2009 +0100
Add a comment and remove unneeded code.
diff --git a/modules/enterprise/server/plugins/alert-email/src/main/java/org/rhq/enterprise/server/plugins/alertEmail/EmailSender.java b/modules/enterprise/server/plugins/alert-email/src/main/java/org/rhq/enterprise/server/plugins/alertEmail/EmailSender.java index ad7f0b4..cbf74ee 100644 --- a/modules/enterprise/server/plugins/alert-email/src/main/java/org/rhq/enterprise/server/plugins/alertEmail/EmailSender.java +++ b/modules/enterprise/server/plugins/alert-email/src/main/java/org/rhq/enterprise/server/plugins/alertEmail/EmailSender.java @@ -49,9 +49,6 @@ public class EmailSender extends AlertSender { @Override public SenderResult send(Alert alert) {
- if(preferences!=null) - preferences.getProperties().size(); - String emailAddress = alertParameters.getSimpleValue("emailAddress",null); if (emailAddress==null) { log.warn("Email address was null, should not happen"); @@ -65,7 +62,10 @@ public class EmailSender extends AlertSender {
Properties props = new Properties(); props.put("mail.smtp.host",mailserver); - Session session = Session.getDefaultInstance(props); // TODO pass authenticator + props.put("mail.transport.protocol","smtp"); + props.put("mail.host",mailserver); + // TODO for whatever reason, the passed props are ignored and 'localhost' is used + Session session = Session.getInstance(props); // TODO pass authenticator Message message = new SMTPMessage(session); try { message.setFrom(new InternetAddress(senderAddress));
commit c0090be9128c127998d6f1c1629a755deafa6ec2 Author: John Mazzitelli mazz@redhat.com Date: Tue Dec 1 02:55:17 2009 -0500
using the wrong dir - need to use the jbossas data dir, not home dir
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginService.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginService.java index e72a5d5..f12b99b 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginService.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginService.java @@ -137,7 +137,7 @@ public class ServerPluginService implements ServerPluginServiceManagement {
File pluginDir = getServerPluginsDirectory();
- File serverDataDir = LookupUtil.getCoreServer().getJBossServerHomeDir(); + File serverDataDir = LookupUtil.getCoreServer().getJBossServerDataDir(); File dataDir = new File(serverDataDir, "server-plugins"); dataDir.mkdirs(); // make sure the data directory exists
commit b359b659a3f4d29303597256dd28fc9e8afae51e Author: John Mazzitelli mazz@redhat.com Date: Tue Dec 1 02:32:39 2009 -0500
make sure to schedule/unschedule jobs appropriately when enabling/disabling plugins
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsBean.java index b463d78..b0ebbff 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsBean.java @@ -137,14 +137,46 @@ public class ServerPluginsBean implements ServerPluginsLocal { }
@RequiredPermission(Permission.MANAGE_SETTINGS) - public void enableServerPlugins(Subject subject, List<Integer> pluginIds) throws Exception { + public List<PluginKey> enableServerPlugins(Subject subject, List<Integer> pluginIds) throws Exception { if (pluginIds == null || pluginIds.size() == 0) { - return; // nothing to do + return new ArrayList<PluginKey>(); // nothing to do }
serverPluginsBean.setServerPluginEnabledFlag(subject, pluginIds, true); - reloadPlugins(pluginIds, true); - return; + + ServerPluginServiceManagement serverPluginService = LookupUtil.getServerPluginService(); + MasterServerPluginContainer master = serverPluginService.getMasterPluginContainer(); + + List<PluginKey> enabledPlugins = new ArrayList<PluginKey>(); + + for (Integer pluginId : pluginIds) { + ServerPlugin enabledPlugin = null; + try { + enabledPlugin = entityManager.getReference(ServerPlugin.class, pluginId); + } catch (Exception ignore) { + } + if (enabledPlugin != null) { + PluginKey pluginKey = new PluginKey(enabledPlugin); + enabledPlugins.add(pluginKey); + if (master != null) { + AbstractTypeServerPluginContainer pc = master.getPluginContainerByPlugin(pluginKey); + if (pc != null) { + try { + pc.schedulePluginJobs(pluginKey); + } catch (Exception e) { + log.warn("Failed to schedule jobs for plugin [" + pluginKey + "]", e); + } + try { + pc.reloadPlugin(pluginKey, true); + } catch (Exception e) { + log.warn("Failed to enable server plugin [" + pluginKey + "]", e); + } + } + } + } + } + + return enabledPlugins; }
@RequiredPermission(Permission.MANAGE_SETTINGS) @@ -177,13 +209,16 @@ public class ServerPluginsBean implements ServerPluginsLocal { } catch (Exception e) { log.warn("Failed to unschedule jobs for plugin [" + pluginKey + "]", e); } + try { + pc.reloadPlugin(pluginKey, false); + } catch (Exception e) { + log.warn("Failed to disable server plugin [" + pluginKey + "]", e); + } } } } }
- reloadPlugins(pluginIds, false); - return doomedPlugins; }
@@ -478,66 +513,6 @@ public class ServerPluginsBean implements ServerPluginsLocal { return; }
- /** - * Given a list of plugin IDs, this will reload those plugins with the given - * enabled flag. This does nothing if the master plugin container is not started. - * If <code>enabled</code> is <code>true</code>, the plugins will be restarted; - * if <code>false</code>, the plugins will be stopped if they are already started. - * - * @param pluginIds the IDs of the plugins to restart - * @param enabled whether or not to start or stop the plugins - */ - private void reloadPlugins(List<Integer> pluginIds, boolean enabled) throws Exception { - ServerPluginServiceManagement serverPluginService = LookupUtil.getServerPluginService(); - MasterServerPluginContainer master = serverPluginService.getMasterPluginContainer(); - if (master != null) { - Map<AbstractTypeServerPluginContainer, List<PluginKey>> pcs; - pcs = getPluginContainersForPluginIds(master, pluginIds); - for (Map.Entry<AbstractTypeServerPluginContainer, List<PluginKey>> entry : pcs.entrySet()) { - AbstractTypeServerPluginContainer pc = entry.getKey(); - List<PluginKey> pluginKeys = entry.getValue(); - for (PluginKey pluginKey : pluginKeys) { - pc.reloadPlugin(pluginKey, enabled); - } - } - } - return; - } - - /** - * Given a list IDs of server plugins, this will return all plugin containers that manage those plugins. - * - * @param master the master plugin container - * @param pluginIds the IDs of plugins whose plugin containers are to be returned - * - * @return the plugin containers that manage the plugins with the given IDs - */ - private Map<AbstractTypeServerPluginContainer, List<PluginKey>> getPluginContainersForPluginIds( - MasterServerPluginContainer master, List<Integer> pluginIds) { - - Map<AbstractTypeServerPluginContainer, List<PluginKey>> pcs; - pcs = new HashMap<AbstractTypeServerPluginContainer, List<PluginKey>>(); - - AbstractTypeServerPluginContainer pc; - - List<PluginKey> keys = getPluginKeysFromIds(pluginIds); - for (PluginKey key : keys) { - try { - pc = master.getPluginContainerByPluginType(new ServerPluginType(key.getPluginType())); - List<PluginKey> list = pcs.get(pc); - if (list == null) { - list = new ArrayList<PluginKey>(); - pcs.put(pc, list); - } - list.add(key); - } catch (Exception e) { - log.warn("Cannot determine what PC manages plugin [" + key + "]", e); - } - } - - return pcs; - } - private List<PluginKey> getPluginKeysFromIds(List<Integer> pluginIds) { Query q = entityManager.createNamedQuery(ServerPlugin.QUERY_FIND_KEYS_BY_IDS); q.setParameter("ids", pluginIds); diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsLocal.java index 98957d8..d21e36a 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsLocal.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsLocal.java @@ -77,16 +77,17 @@ public interface ServerPluginsLocal { List<PluginKey> getServerPluginKeysByEnabled(boolean enabled);
/** - * Enables the plugins and restarts the server plugin container. + * Enables the plugins and restarts them. * * @param subject user making the request * @param pluginIds the plugins to be enabled + * @return the list of keys of the plugins that were enabled * @throws Exception if failed to disable a plugin */ - void enableServerPlugins(Subject subject, List<Integer> pluginIds) throws Exception; + List<PluginKey> enableServerPlugins(Subject subject, List<Integer> pluginIds) throws Exception;
/** - * Disables the plugins and restarts the server plugin container. + * Disables the plugins and unschedules their jobs. * * @param subject user making the request * @param pluginIds the plugins to be disabled @@ -96,10 +97,10 @@ public interface ServerPluginsLocal { List<PluginKey> disableServerPlugins(Subject subject, List<Integer> pluginIds) throws Exception;
/** - * Removes the plugin from the system and restarts the server plugin container. + * Removes the plugins from the system and unschedules their jobs. * * @param subject user making the request - * @param pluginIds + * @param pluginIds the plugins to be undeployed * @return the list of keys of plugins that were undeployed * @throws Exception if failed to undeploy a plugin */ diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/AbstractTypeServerPluginContainer.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/AbstractTypeServerPluginContainer.java index 378d9eb..fcebe55 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/AbstractTypeServerPluginContainer.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/AbstractTypeServerPluginContainer.java @@ -210,30 +210,47 @@ public abstract class AbstractTypeServerPluginContainer { * * @throws Exception if failed to schedule jobs */ - public synchronized void schedulePluginJobs() throws Exception { + public synchronized void scheduleAllPluginJobs() throws Exception { if (this.pluginManager != null) { - // process all known plugins and schedule their jobs - List<ScheduledJobDefinition> jobs; for (ServerPluginEnvironment pluginEnv : this.pluginManager.getPluginEnvironments()) { - String pluginName = pluginEnv.getPluginKey().getPluginName(); + schedulePluginJobs(pluginEnv.getPluginKey()); + } + } else { + throw new Exception("Cannot schedule plugins jobs; plugin container is not initialized yet"); + }
- try { - jobs = this.pluginManager.getServerPluginContext(pluginEnv).getSchedules(); - if (jobs != null) { - for (ScheduledJobDefinition job : jobs) { - try { - scheduleJob(job, pluginEnv.getPluginKey()); - } catch (Throwable t) { - log.warn("Failed to schedule job [" + job + "] for plugin [" + pluginName + "]", t); + return; + } + + public synchronized void schedulePluginJobs(PluginKey pluginKey) throws Exception { + if (this.pluginManager != null) { + try { + String pluginName = pluginKey.getPluginName(); + if (this.pluginManager.isPluginEnabled(pluginName)) { + ServerPluginEnvironment pluginEnv = this.pluginManager.getPluginEnvironment(pluginName); + if (pluginEnv != null) { + ServerPluginContext serverPluginContext = this.pluginManager.getServerPluginContext(pluginEnv); + List<ScheduledJobDefinition> jobs = serverPluginContext.getSchedules(); + if (jobs != null) { + for (ScheduledJobDefinition job : jobs) { + try { + scheduleJob(job, pluginKey); + } catch (Throwable t) { + log.warn("Failed to schedule job [" + job + "] for server plugin [" + pluginKey + + "]", t); + } } } + } else { + log.warn("Failed to get server plugin env for [" + pluginKey + "]; cannot schedule jobs"); } - } catch (Throwable t) { - log.warn("Failed to get scheduled jobs for plugin [" + pluginName + "]", t); } + } catch (Throwable t) { + log.warn("Failed to get scheduled jobs for server plugin [" + pluginKey + "]", t); } } else { - throw new Exception("Cannot schedule plugins jobs; plugin container is not initialized yet"); + throw new Exception("Cannot schedule plugins jobs for server plugin [" + pluginKey + + "]; plugin container is not initialized yet"); }
return; diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/MasterServerPluginContainer.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/MasterServerPluginContainer.java index fc2be74..d19ee2a 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/MasterServerPluginContainer.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/MasterServerPluginContainer.java @@ -218,7 +218,7 @@ public class MasterServerPluginContainer {
for (AbstractTypeServerPluginContainer pc : this.pluginContainers.values()) { try { - pc.schedulePluginJobs(); + pc.scheduleAllPluginJobs(); } catch (Exception e) { log.error("Server plugin container for plugin type [" + pc.getSupportedServerPluginType() + "] failed to scheduled some or all of its jobs", e); diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginManager.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginManager.java index d46500f..4616644 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginManager.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginManager.java @@ -93,6 +93,38 @@ public class ServerPluginManager { }
/** + * Returns the plugin container that whose plugins are managed by this manager. + * + * @return the plugin container that owns this plugin manager + */ + public AbstractTypeServerPluginContainer getParentPluginContainer() { + return this.parentPluginContainer; + } + + /** + * Returns the {@link ServerPluginEnvironment}s for every plugin this manager has loaded. + * The returned collection is a copy and not backed by this manager. + * + * @return environments for all the plugins + */ + public Collection<ServerPluginEnvironment> getPluginEnvironments() { + return new ArrayList<ServerPluginEnvironment>(this.loadedPlugins.values()); + } + + /** + * Given a plugin name, this returns that plugin's environment. + * + * <p>The plugin's name is defined in its plugin descriptor - specifically the XML root node's "name" attribute + * (e.g. <server-plugin name="thePluginName").</p> + * + * @param pluginName the plugin whose environment is to be returned + * @return given plugin's environment + */ + public ServerPluginEnvironment getPluginEnvironment(String pluginName) { + return this.loadedPlugins.get(pluginName); + } + + /** * Initializes the plugin manager to prepare it to start loading plugins. * * @throws Exception if failed to initialize @@ -177,7 +209,7 @@ public class ServerPluginManager { }
protected void startPlugin(String pluginName) { - if (Boolean.TRUE.equals(this.enabledPlugins.get(pluginName))) { + if (isPluginEnabled(pluginName)) { ServerPluginComponent component = this.pluginComponentCache.get(pluginName); if (component != null) { ServerPluginEnvironment env = this.loadedPlugins.get(pluginName); @@ -312,27 +344,8 @@ public class ServerPluginManager { return; }
- /** - * Returns the {@link ServerPluginEnvironment}s for every plugin this manager has loaded. - * The returned collection is a copy and not backed by this manager. - * - * @return environments for all the plugins - */ - public Collection<ServerPluginEnvironment> getPluginEnvironments() { - return new ArrayList<ServerPluginEnvironment>(this.loadedPlugins.values()); - } - - /** - * Given a plugin name, this returns that plugin's environment. - * - * <p>The plugin's name is defined in its plugin descriptor - specifically the XML root node's "name" attribute - * (e.g. <server-plugin name="thePluginName").</p> - * - * @param pluginName the plugin whose environment is to be returned - * @return given plugin's environment - */ - public ServerPluginEnvironment getPluginEnvironment(String pluginName) { - return this.loadedPlugins.get(pluginName); + protected boolean isPluginEnabled(String pluginName) { + return Boolean.TRUE.equals(this.enabledPlugins.get(pluginName)); }
/** @@ -349,10 +362,6 @@ public class ServerPluginManager { return this.pluginComponentCache.get(pluginName); }
- public AbstractTypeServerPluginContainer getParentPluginContainer() { - return this.parentPluginContainer; - } - protected Log getLog() { return this.log; } diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/content/ContentServerPluginContainer.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/content/ContentServerPluginContainer.java index e32e858..b1a47a3 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/content/ContentServerPluginContainer.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/content/ContentServerPluginContainer.java @@ -73,8 +73,8 @@ public class ContentServerPluginContainer extends AbstractTypeServerPluginContai }
@Override - public void schedulePluginJobs() throws Exception { - super.schedulePluginJobs(); + public void scheduleAllPluginJobs() throws Exception { + super.scheduleAllPluginJobs(); scheduleSyncJobs(); return; }
commit 0864bd3088b1a4ad5d56b66980dd3c28c60385e4 Author: John Mazzitelli mazz@redhat.com Date: Tue Dec 1 01:36:15 2009 -0500
get the SLSB to unload/reload plugins using new API
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsBean.java index 04f377d..b463d78 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsBean.java @@ -143,7 +143,7 @@ public class ServerPluginsBean implements ServerPluginsLocal { }
serverPluginsBean.setServerPluginEnabledFlag(subject, pluginIds, true); - restartPlugins(pluginIds); + reloadPlugins(pluginIds, true); return; }
@@ -182,7 +182,7 @@ public class ServerPluginsBean implements ServerPluginsLocal { } }
- restartPlugins(pluginIds); + reloadPlugins(pluginIds, false);
return doomedPlugins; } @@ -215,7 +215,12 @@ public class ServerPluginsBean implements ServerPluginsLocal { try { pc.unschedulePluginJobs(pluginKey); } catch (Exception e) { - log.warn("Failed to unschedule jobs for plugin [" + pluginKey + "]", e); + log.warn("Failed to unschedule jobs for server plugin [" + pluginKey + "]", e); + } + try { + pc.unloadPlugin(pluginKey); + } catch (Exception e) { + log.warn("Failed to unload server plugin [" + pluginKey + "]", e); } } } @@ -246,8 +251,6 @@ public class ServerPluginsBean implements ServerPluginsLocal {
log.info("Server plugins " + doomedPlugins + " have been undeployed");
- restartPlugins(pluginIds); - return doomedPlugins; }
@@ -476,12 +479,15 @@ public class ServerPluginsBean implements ServerPluginsLocal { }
/** - * Given a list of plugin IDs, this will restart those plugins. - * this does nothing if the master plugin container is not started. + * Given a list of plugin IDs, this will reload those plugins with the given + * enabled flag. This does nothing if the master plugin container is not started. + * If <code>enabled</code> is <code>true</code>, the plugins will be restarted; + * if <code>false</code>, the plugins will be stopped if they are already started. * * @param pluginIds the IDs of the plugins to restart + * @param enabled whether or not to start or stop the plugins */ - private void restartPlugins(List<Integer> pluginIds) { + private void reloadPlugins(List<Integer> pluginIds, boolean enabled) throws Exception { ServerPluginServiceManagement serverPluginService = LookupUtil.getServerPluginService(); MasterServerPluginContainer master = serverPluginService.getMasterPluginContainer(); if (master != null) { @@ -490,9 +496,12 @@ public class ServerPluginsBean implements ServerPluginsLocal { for (Map.Entry<AbstractTypeServerPluginContainer, List<PluginKey>> entry : pcs.entrySet()) { AbstractTypeServerPluginContainer pc = entry.getKey(); List<PluginKey> pluginKeys = entry.getValue(); - pc.restartPlugins(pluginKeys); + for (PluginKey pluginKey : pluginKeys) { + pc.reloadPlugin(pluginKey, enabled); + } } } + return; }
/**
commit e69e7b2f3e22e2c6a3f26564d5eb3d8f35483add Author: John Mazzitelli mazz@redhat.com Date: Tue Dec 1 00:48:21 2009 -0500
use new API for loading plugins
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/content/ContentServerPluginManager.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/content/ContentServerPluginManager.java index 8d690f9..4f05c08 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/content/ContentServerPluginManager.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/content/ContentServerPluginManager.java @@ -79,40 +79,41 @@ public class ContentServerPluginManager extends ServerPluginManager { }
@Override - public void loadPlugin(ServerPluginEnvironment env) throws Exception { + public void loadPlugin(ServerPluginEnvironment env, boolean enabled) throws Exception {
- super.loadPlugin(env); + super.loadPlugin(env, enabled);
- Collection<ContentSourceType> newTypes; - newTypes = this.metadataManager.loadPlugin((ContentPluginDescriptorType) env.getPluginDescriptor()); + if (enabled) { + Collection<ContentSourceType> newTypes; + newTypes = this.metadataManager.loadPlugin((ContentPluginDescriptorType) env.getPluginDescriptor());
- // double check that the api classes are loadable, if not, very bad - Set<ContentSourceType> newTypesCopy = new HashSet<ContentSourceType>(newTypes); - for (ContentSourceType newType : newTypesCopy) { - try { - String className = newType.getContentSourceApiClass(); - Class<?> apiClass = Class.forName(className, false, env.getPluginClassLoader()); - - if (!ContentProvider.class.isAssignableFrom(apiClass)) { - throw new Exception("The API class [" + className + "] should implement [" - + ContentProvider.class.getName() + "] but does not"); - } - } catch (Exception e) { - // do not deploy this plugin - its stinky + // double check that the api classes are loadable, if not, very bad + Set<ContentSourceType> newTypesCopy = new HashSet<ContentSourceType>(newTypes); + for (ContentSourceType newType : newTypesCopy) { try { - unloadPlugin(env); - } catch (Exception ignore) { + String className = newType.getContentSourceApiClass(); + Class<?> apiClass = Class.forName(className, false, env.getPluginClassLoader()); + + if (!ContentProvider.class.isAssignableFrom(apiClass)) { + throw new Exception("The API class [" + className + "] should implement [" + + ContentProvider.class.getName() + "] but does not"); + } + } catch (Exception e) { + // do not deploy this plugin - its stinky + try { + unloadPlugin(env.getPluginKey().getPluginName()); + } catch (Exception ignore) { + } + throw e; } - throw e; } } - return; }
@Override - public void unloadPlugin(ServerPluginEnvironment env) throws Exception { - metadataManager.unloadPlugin(env.getPluginKey().getPluginName()); - super.unloadPlugin(env); + public void unloadPlugin(String pluginName) throws Exception { + metadataManager.unloadPlugin(pluginName); + super.unloadPlugin(pluginName); }; } \ No newline at end of file diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/plugin/pc/generic/TestGenericServerPluginService.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/plugin/pc/generic/TestGenericServerPluginService.java index 1b577fe..e8cdb51 100644 --- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/plugin/pc/generic/TestGenericServerPluginService.java +++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/plugin/pc/generic/TestGenericServerPluginService.java @@ -97,7 +97,7 @@ public class TestGenericServerPluginService extends ServerPluginService implemen }
@Override - protected List<PluginKey> getDisabledPluginNames() { + protected List<PluginKey> getDisabledPluginKeys() { // in the real world, the db is checked for enable flag, here we say all plugins are enabled return new ArrayList<PluginKey>(); }
commit 26ca7a5ba23dc5114440389ccf23f8033903bfba Author: John Mazzitelli mazz@redhat.com Date: Mon Nov 30 18:05:26 2009 -0500
refactor the plugin container/manager API so we can load, unload individually
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/AbstractTypeServerPluginContainer.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/AbstractTypeServerPluginContainer.java index 3930f21..378d9eb 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/AbstractTypeServerPluginContainer.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/AbstractTypeServerPluginContainer.java @@ -130,7 +130,7 @@ public abstract class AbstractTypeServerPluginContainer { Collection<ServerPluginEnvironment> envs = this.pluginManager.getPluginEnvironments(); for (ServerPluginEnvironment env : envs) { try { - unloadPlugin(env); + unloadPlugin(env.getPluginKey()); } catch (Exception e) { this.log.warn("Failed to unload plugin [" + env.getPluginKey().getPluginName() + "].", e); } @@ -147,15 +147,17 @@ public abstract class AbstractTypeServerPluginContainer { }
/** - * Informs the plugin container that it has a plugin that it must being to start managing. + * Informs the plugin container that it has a plugin that it must begin to start managing. * * @param env the plugin environment, including the plugin jar and its descriptor + * @param enabled <code>true</code> if the plugin should be initialized; <code>false</code> if + * the plugin's existence should be noted but it should not be initialized or started * * @throws Exception if failed to load the plugin */ - public synchronized void loadPlugin(ServerPluginEnvironment env) throws Exception { + public synchronized void loadPlugin(ServerPluginEnvironment env, boolean enabled) throws Exception { if (this.pluginManager != null) { - this.pluginManager.loadPlugin(env); + this.pluginManager.loadPlugin(env, enabled); } else { throw new Exception("Cannot load a plugin; plugin container is not initialized yet"); } @@ -165,19 +167,36 @@ public abstract class AbstractTypeServerPluginContainer { * Informs the plugin container that a plugin should be unloaded and any of its resources * should be released. * - * @param env the plugin environment, including the plugin jar and its descriptor + * @param pluginKey identifies the plugin that should be shutdown * * @throws Exception if failed to unload the plugin */ - public synchronized void unloadPlugin(ServerPluginEnvironment env) throws Exception { + public synchronized void unloadPlugin(PluginKey pluginKey) throws Exception { if (this.pluginManager != null) { - this.pluginManager.unloadPlugin(env); + this.pluginManager.unloadPlugin(pluginKey.getPluginName()); } else { throw new Exception("Cannot unload a plugin; plugin container has been shutdown"); } }
/** + * Informs the plugin container that a plugin should be reloaded and any of its resources + * should be started if being enabled. + * + * @param pluginKey identifies the plugin that should be reloaded + * @param enabled indicates if the plugin should be enabled or disabled after being loaded + * + * @throws Exception if failed to unload the plugin + */ + public synchronized void reloadPlugin(PluginKey pluginKey, boolean enabled) throws Exception { + if (this.pluginManager != null) { + this.pluginManager.reloadPlugin(pluginKey.getPluginName(), enabled); + } else { + throw new Exception("Cannot reload a plugin; plugin container has been shutdown"); + } + } + + /** * If a plugin has scheduled jobs, this method will schedule them now. * This particular method implementation schedules the global jobs as defined in the * plugin descriptors. @@ -256,43 +275,6 @@ public abstract class AbstractTypeServerPluginContainer { }
/** - * This will restart the given set of plugins. The currently running plugins will - * be stopped and unloaded and the new plugins will be loaded and started. - * - * If a plugin is in the given list but is not already started, this method will - * skip that plugin (i.e. it will not start it). - * - * - * - * @param pluginKeys identifies the plugins that need to be restarted - */ - // TODO: This method does not do anything with the scheduled jobs. - // Perhaps we should unschedule them and reschedule them, in case the jobs were reconfigured? - // What happens to the jobs that may currently be running in the HA case? - public synchronized void restartPlugins(List<PluginKey> pluginKeys) { - if (this.pluginManager != null) { - for (PluginKey pluginKey : pluginKeys) { - String pluginName = pluginKey.getPluginName(); - ServerPluginEnvironment env = this.pluginManager.getPluginEnvironment(pluginName); - if (env != null) { - try { - this.pluginManager.stopPlugin(pluginName); - this.pluginManager.unloadPlugin(env); - this.pluginManager.loadPlugin(env); - this.pluginManager.startPlugin(pluginName); - } catch (Exception e) { - log.warn("Failed to restart server plugin [" + pluginName + "]", e); - } - } else { - log.info("Being asked to restart server plugin [" + pluginName - + "] but it isn't started - skipping"); - } - } - } - return; - } - - /** * This will be called when its time for this plugin container to create its plugin manager. * Subclasses are free to override this if they need their own specialized plugin manager. * diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/MasterServerPluginContainer.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/MasterServerPluginContainer.java index 1e9cbc4..fc2be74 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/MasterServerPluginContainer.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/MasterServerPluginContainer.java @@ -21,7 +21,6 @@ package org.rhq.enterprise.server.plugin.pc; import java.io.File; import java.net.URL; import java.util.ArrayList; -import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.List; @@ -58,12 +57,6 @@ public class MasterServerPluginContainer { private ClassLoaderManager classLoaderManager;
/** - * Because the individual plugin containers are only managing enabled plugins (they are never told about plugins that disabled). - * this map contains the lists of plugins that are disabled so others can find out what plugins are registered but not running. - */ - private Map<ServerPluginType, List<PluginKey>> disabledPlugins = new HashMap<ServerPluginType, List<PluginKey>>(); - - /** * Starts the master plugin container, which will load all plugins and begin managing them. * * @param config the master configuration @@ -112,20 +105,24 @@ public class MasterServerPluginContainer {
// Create classloaders/environments for all plugins and load plugins into their plugin containers. // Note that we do not care what order we load plugins - in the future we may want dependencies. + List<PluginKey> allDisabledPlugins = getDisabledPluginKeys(); + for (Map.Entry<URL, ? extends ServerPluginDescriptorType> entry : plugins.entrySet()) { URL pluginUrl = entry.getKey(); ServerPluginDescriptorType descriptor = entry.getValue(); - String pluginName = descriptor.getName(); - ServerPluginType pluginType = new ServerPluginType(descriptor); - PluginKey pluginKey = PluginKey.createServerPluginKey(pluginType.stringify(), pluginName); - ClassLoader classLoader = this.classLoaderManager.obtainServerPluginClassLoader(pluginKey); AbstractTypeServerPluginContainer pc = getPluginContainerByDescriptor(descriptor); if (pc != null) { - log.debug("Loading server plugin [" + pluginUrl + "] into its plugin container"); + String pluginName = descriptor.getName(); + ServerPluginType pluginType = new ServerPluginType(descriptor); + PluginKey pluginKey = PluginKey.createServerPluginKey(pluginType.stringify(), pluginName); + ClassLoader classLoader = this.classLoaderManager.obtainServerPluginClassLoader(pluginKey); + log.debug("Loading server plugin [" + pluginKey + "] from [" + pluginUrl + + "] into its plugin container"); try { ServerPluginEnvironment env = new ServerPluginEnvironment(pluginUrl, classLoader, descriptor); - pc.loadPlugin(env); - log.info("Loaded server plugin [" + pluginUrl + "]"); + boolean enabled = !allDisabledPlugins.contains(pluginKey); + pc.loadPlugin(env, enabled); + log.info("Loaded server plugin [" + pluginKey.getPluginName() + "]"); } catch (Exception e) { log.warn("Failed to load server plugin [" + pluginUrl + "]", e); } @@ -203,7 +200,6 @@ public class MasterServerPluginContainer { }
this.pluginContainers.clear(); - this.disabledPlugins.clear(); this.classLoaderManager = null; this.configuration = null;
@@ -254,43 +250,6 @@ public class MasterServerPluginContainer { }
/** - * Given a plugin type, this will return the keys of all known plugins of that type. - * This includes all types that are currently started as well as plugins - * that have been disabled. - * - * If the master plugin container has not been started, this returns an empty list. - * - * @param pluginType - * - * @return list of both enabled and disabled plugins of the given type - */ - public List<PluginKey> getAllPluginsByPluginType(ServerPluginType pluginType) { - List<PluginKey> allPlugins = new ArrayList<PluginKey>(); - - AbstractTypeServerPluginContainer pc = getPluginContainerByPluginType(pluginType); - if (pc != null) { - // add the enabled plugins - ServerPluginManager pluginManager = pc.getPluginManager(); - if (pluginManager != null) { - Collection<ServerPluginEnvironment> envs = pluginManager.getPluginEnvironments(); - if (envs != null) { - for (ServerPluginEnvironment env : envs) { - allPlugins.add(env.getPluginKey()); - } - } - } - - // add the disabled plugins - List<PluginKey> disabled = this.disabledPlugins.get(pluginType); - if (disabled != null) { - allPlugins.addAll(disabled); - } - } - - return allPlugins; - } - - /** * This will return all known server plugins types. These are the types of plugins * that are supported by a server plugin container. You can obtain the server * plugin container that manages a particular server plugin type via @@ -374,7 +333,7 @@ public class MasterServerPluginContainer { * Finds all plugins and parses their descriptors. This is only called during * this master plugin container's {@link #initialize(MasterServerPluginContainerConfiguration) initialization}. * - * If a plugin fails to load, it will be ignored - other plugins will still load. + * If a plugin fails to preload, it will be ignored - other plugins will still preload. * * @return a map of plugins, keyed on the plugin jar URL whose values are the parsed descriptors * @@ -392,34 +351,15 @@ public class MasterServerPluginContainer { File[] pluginFiles = pluginDirectory.listFiles();
if (pluginFiles != null) { - - List<PluginKey> allDisabledPlugins = getDisabledPluginNames(); - for (File pluginFile : pluginFiles) { if (pluginFile.getName().endsWith(".jar")) { URL pluginUrl = pluginFile.toURI().toURL(); - try { ServerPluginDescriptorType descriptor; descriptor = ServerPluginDescriptorUtil.loadPluginDescriptorFromUrl(pluginUrl); if (descriptor != null) { - PluginKey pluginKey = PluginKey.createServerPluginKey(new ServerPluginType(descriptor) - .stringify(), descriptor.getName()); - - if (!allDisabledPlugins.contains(pluginKey)) { - log.debug("pre-loaded server plugin from URL: " + pluginUrl); - plugins.put(pluginUrl, descriptor); - } else { - log.info("Server plugin [" + descriptor.getName() - + "] is disabled and will not be initialized"); - ServerPluginType pluginType = new ServerPluginType(descriptor); - List<PluginKey> disabledByType = this.disabledPlugins.get(pluginType); - if (disabledByType == null) { - disabledByType = new ArrayList<PluginKey>(1); - this.disabledPlugins.put(pluginType, disabledByType); - } - disabledByType.add(pluginKey); - } + log.debug("pre-loaded server plugin from URL: " + pluginUrl); + plugins.put(pluginUrl, descriptor); } } catch (Throwable t) { // for some reason, the plugin failed to load - it will be ignored @@ -436,11 +376,11 @@ public class MasterServerPluginContainer { /** * This will return a list of plugin keys that represent all the plugins that are to be * disabled. If a plugin jar is found on the filesystem, its plugin key should be checked with - * this "blacklist" - if its key is found, that plugin should not be loaded. + * this "blacklist" - if its key is found, that plugin should be disabled. * - * @return names of "blacklisted" plugins that should not be loaded + * @return names of "blacklisted" plugins that should not be started (i.e. loaded as a disabled plugin) */ - protected List<PluginKey> getDisabledPluginNames() { + protected List<PluginKey> getDisabledPluginKeys() { List<PluginKey> disabledPlugins = LookupUtil.getServerPlugins().getServerPluginKeysByEnabled(false); return disabledPlugins; } diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginManager.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginManager.java index ace80c8..d46500f 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginManager.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginManager.java @@ -20,6 +20,7 @@ package org.rhq.enterprise.server.plugin.pc;
import java.io.File; +import java.net.URL; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; @@ -35,12 +36,18 @@ import org.rhq.enterprise.server.plugin.ServerPluginsLocal; import org.rhq.enterprise.server.util.LookupUtil; import org.rhq.enterprise.server.xmlschema.ScheduledJobDefinition; import org.rhq.enterprise.server.xmlschema.ServerPluginDescriptorMetadataParser; +import org.rhq.enterprise.server.xmlschema.ServerPluginDescriptorUtil; import org.rhq.enterprise.server.xmlschema.generated.serverplugin.ServerPluginComponentType; +import org.rhq.enterprise.server.xmlschema.generated.serverplugin.ServerPluginDescriptorType;
/** * Provides functionality to manage plugins for a plugin container. Plugin containers * can install their own plugin managers that are extensions to this class if they need to. * + * Most of the methods here are protected; they are meant for the plugin container's use only. + * Usually, anything an external client needs will be done through a delegation method + * found on the plugin container. + * * @author John Mazzitelli */ //TODO: need a R/W lock to make this class thread safe @@ -55,6 +62,11 @@ public class ServerPluginManager { private final Map<String, ServerPluginEnvironment> loadedPlugins;
/** + * Indicates which plugins are enabled and which are disabled; keyed on plugin name. + */ + private final Map<String, Boolean> enabledPlugins; + + /** * To avoid having to create contexts multiple times for the same plugin, * contexts are cached here, keyed on plugin name. */ @@ -77,6 +89,7 @@ public class ServerPluginManager { this.loadedPlugins = new HashMap<String, ServerPluginEnvironment>(); this.pluginContextCache = new HashMap<String, ServerPluginContext>(); this.pluginComponentCache = new HashMap<String, ServerPluginComponent>(); + this.enabledPlugins = new HashMap<String, Boolean>(); }
/** @@ -84,7 +97,7 @@ public class ServerPluginManager { * * @throws Exception if failed to initialize */ - public void initialize() throws Exception { + protected void initialize() throws Exception { log.debug("Plugin manager initializing"); return; // no-op } @@ -93,7 +106,7 @@ public class ServerPluginManager { * Shuts down this manager. This should be called only after all of its plugins * have been {@link #unloadPlugin(ServerPluginEnvironment) unloaded}. */ - public void shutdown() { + protected void shutdown() { log.debug("Plugin manager shutting down");
if (this.loadedPlugins.size() > 0) { @@ -104,46 +117,57 @@ public class ServerPluginManager { this.loadedPlugins.clear(); this.pluginContextCache.clear(); this.pluginComponentCache.clear(); + this.enabledPlugins.clear();
return; }
/** * Informs the plugin manager that a plugin with the given environment needs to be loaded. - * Once this method returns, the plugin's components are ready to be created and used. + * Once this method returns, the plugin's components are ready to be created and used, unless + * <code>enabled</code> is <code>false</code>, in which case the plugin will not + * be initialized. * * @param env the environment of the plugin to be loaded + * @param enabled <code>true</code> if the plugin should be initialized; <code>false</code> if + * the plugin's existence should be noted but it should not be initialized or started * * @throws Exception if the plugin manager cannot load the plugin or deems the plugin invalid */ - public void loadPlugin(ServerPluginEnvironment env) throws Exception { + protected void loadPlugin(ServerPluginEnvironment env, boolean enabled) throws Exception { String pluginName = env.getPluginKey().getPluginName(); - log.debug("Loading server plugin [" + pluginName + "] from: " + env.getPluginUrl());
- // tell the plugin we are loading it - ServerPluginComponent component = createServerPluginComponent(env); - if (component != null) { - ServerPluginContext context = getServerPluginContext(env); - log.debug("Initializing plugin component for server plugin [" + pluginName + "]"); - ClassLoader originalContextClassLoader = Thread.currentThread().getContextClassLoader(); - try { - Thread.currentThread().setContextClassLoader(env.getPluginClassLoader()); - component.initialize(context); - } catch (Throwable t) { - throw new Exception("Plugin component failed to initialize plugin", t); - } finally { - Thread.currentThread().setContextClassLoader(originalContextClassLoader); + if (enabled) { + log.debug("Loading server plugin [" + pluginName + "] from: " + env.getPluginUrl()); + + // tell the plugin we are loading it + ServerPluginComponent component = createServerPluginComponent(env); + if (component != null) { + ServerPluginContext context = getServerPluginContext(env); + log.debug("Initializing plugin component for server plugin [" + pluginName + "]"); + ClassLoader originalContextClassLoader = Thread.currentThread().getContextClassLoader(); + try { + Thread.currentThread().setContextClassLoader(env.getPluginClassLoader()); + component.initialize(context); + } catch (Throwable t) { + throw new Exception("Plugin component failed to initialize plugin", t); + } finally { + Thread.currentThread().setContextClassLoader(originalContextClassLoader); + } + this.pluginComponentCache.put(pluginName, component); } - this.pluginComponentCache.put(pluginName, component); + } else { + log.info("Server plugin [" + pluginName + "] is loaded but disabled"); }
// note that we only cache it if the plugin component was successful this.loadedPlugins.put(pluginName, env); + this.enabledPlugins.put(pluginName, Boolean.valueOf(enabled));
return; }
- public void startPlugins() { + protected void startPlugins() { log.debug("Starting server plugins"); for (String pluginName : this.pluginComponentCache.keySet()) { startPlugin(pluginName); @@ -152,25 +176,27 @@ public class ServerPluginManager { return; }
- public void startPlugin(String pluginName) { - ServerPluginComponent component = this.pluginComponentCache.get(pluginName); - if (component != null) { - ServerPluginEnvironment env = this.loadedPlugins.get(pluginName); - log.debug("Starting plugin component for server plugin [" + pluginName + "]"); - ClassLoader originalContextClassLoader = Thread.currentThread().getContextClassLoader(); - try { - Thread.currentThread().setContextClassLoader(env.getPluginClassLoader()); - component.start(); - } catch (Throwable t) { - log.warn("Plugin component failed to start plugin [" + pluginName + "]", t); - } finally { - Thread.currentThread().setContextClassLoader(originalContextClassLoader); + protected void startPlugin(String pluginName) { + if (Boolean.TRUE.equals(this.enabledPlugins.get(pluginName))) { + ServerPluginComponent component = this.pluginComponentCache.get(pluginName); + if (component != null) { + ServerPluginEnvironment env = this.loadedPlugins.get(pluginName); + log.debug("Starting plugin component for server plugin [" + pluginName + "]"); + ClassLoader originalContextClassLoader = Thread.currentThread().getContextClassLoader(); + try { + Thread.currentThread().setContextClassLoader(env.getPluginClassLoader()); + component.start(); + } catch (Throwable t) { + log.warn("Plugin component failed to start plugin [" + pluginName + "]", t); + } finally { + Thread.currentThread().setContextClassLoader(originalContextClassLoader); + } } } return; }
- public void stopPlugins() { + protected void stopPlugins() { log.debug("Stopping server plugins"); for (String pluginName : this.pluginComponentCache.keySet()) { stopPlugin(pluginName); @@ -179,7 +205,7 @@ public class ServerPluginManager { return; }
- public void stopPlugin(String pluginName) { + protected void stopPlugin(String pluginName) { ServerPluginComponent component = this.pluginComponentCache.get(pluginName); if (component != null) { ServerPluginEnvironment env = this.loadedPlugins.get(pluginName); @@ -198,18 +224,23 @@ public class ServerPluginManager { }
/** - * Informs the plugin manager that a plugin with the given environment is to be unloaded. + * Informs the plugin manager that a plugin with the given name is to be unloaded. * Once this method returns, the plugin's components are should no longer be created or used. * - * @param env the environment of the plugin to be unloaded + * @param pluginName the name of the plugin to be unloaded * * @throws Exception if the plugin manager cannot unload the plugin */ - public void unloadPlugin(ServerPluginEnvironment env) throws Exception { - String pluginName = env.getPluginKey().getPluginName(); - log.debug("Unloading server plugin [" + pluginName + "]"); - + protected void unloadPlugin(String pluginName) throws Exception { try { + ServerPluginEnvironment env = getPluginEnvironment(pluginName); + if (env == null) { + log.debug("Server plugin [" + pluginName + "] was never loaded, ignoring unload request"); + return; + } + + log.debug("Unloading server plugin [" + pluginName + "]"); + // tell the plugin we are unloading it ServerPluginComponent component = this.pluginComponentCache.get(pluginName); if (component != null) { @@ -227,12 +258,61 @@ public class ServerPluginManager { } } finally { this.loadedPlugins.remove(pluginName); + this.enabledPlugins.remove(pluginName); + this.pluginContextCache.remove(pluginName); }
return; }
/** + * This will reload a plugin allowing you to enable or disable it. + * This will {@link #startPlugin(String) start the plugin component} if you enable it. + * This will {@link #stopPlugin(String) stop the plugin component} if you disable it. + * This will ensure any new plugin configuration will be re-loaded. + * + * @param pluginName the name of the loaded plugin that is to be enabled or disabled + * @param enabled <code>true</code> if you want to enable the plugin; <code>false</code> + * if you want to disable it + * @throws Exception if the plugin was never loaded before or the reload failed + */ + protected void reloadPlugin(String pluginName, boolean enabled) throws Exception { + if (enabled) { + enablePlugin(pluginName); + } else { + disablePlugin(pluginName); + } + return; + } + + protected void enablePlugin(String pluginName) throws Exception { + log.info("Enabling server plugin [" + pluginName + "]"); + ServerPluginEnvironment env = getPluginEnvironment(pluginName); + if (env == null) { + throw new IllegalArgumentException("Server plugin [" + pluginName + "] was never loaded, cannot enable it"); + } + stopPlugin(pluginName); // under normal circumstances, we should need to do this, but just in case the plugin is somehow already started, stop it + unloadPlugin(pluginName); // unloading it will clean up old data and force the plugin context to reload if we later re-enable it + env = rebuildServerPluginEnvironment(env); + loadPlugin(env, true); // reload it in the enabled state + startPlugin(pluginName); // since we are enabling the plugin, immediately start it + return; + } + + protected void disablePlugin(String pluginName) throws Exception { + log.info("Disabling server plugin [" + pluginName + "]"); + ServerPluginEnvironment env = getPluginEnvironment(pluginName); + if (env == null) { + throw new IllegalArgumentException("Server plugin [" + pluginName + "] was never loaded, cannot disable it"); + } + stopPlugin(pluginName); + unloadPlugin(pluginName); // unloading it will clean up old data and force the plugin context to reload if we later re-enable it + env = rebuildServerPluginEnvironment(env); + loadPlugin(env, false); // re-load it in the disabled state + return; + } + + /** * Returns the {@link ServerPluginEnvironment}s for every plugin this manager has loaded. * The returned collection is a copy and not backed by this manager. * @@ -265,7 +345,7 @@ public class ServerPluginManager { * return <code>null</code> if the plugin has not defined a plugin component. * <code>null</code> is also returned if the plugin is not initialized yet. */ - public ServerPluginComponent getServerPluginComponent(String pluginName) { + protected ServerPluginComponent getServerPluginComponent(String pluginName) { return this.pluginComponentCache.get(pluginName); }
@@ -310,7 +390,24 @@ public class ServerPluginManager { }
/** - * Given a plugin environment, return its Plugin representation, which should also include + * Given a plugin environment, this will rebuild a new one with up-to-date information. + * This means the descriptor will be reparsed. + * + * @param env the original environment + * @return the new environment that has been rebuild from the original but has newer data + * @throws Exception if the environment could not be rebuilt - probably due to an invalid descriptor + * in the plugin jar or the plugin jar is now missing + */ + protected ServerPluginEnvironment rebuildServerPluginEnvironment(ServerPluginEnvironment env) throws Exception { + URL url = env.getPluginUrl(); + ClassLoader classLoader = env.getPluginClassLoader(); + ServerPluginDescriptorType descriptor = ServerPluginDescriptorUtil.loadPluginDescriptorFromUrl(url); + ServerPluginEnvironment newEnv = new ServerPluginEnvironment(url, classLoader, descriptor); + return newEnv; + } + + /** + * Given a plugin environment, return its {@link ServerPlugin} representation, which should also include * the plugin configuration and scheduled jobs configuration. * * @param pluginEnv @@ -320,6 +417,7 @@ public class ServerPluginManager { // get the plugin data from the database ServerPluginsLocal serverPluginsManager = LookupUtil.getServerPlugins(); ServerPlugin plugin = serverPluginsManager.getServerPlugin(pluginEnv.getPluginKey()); + plugin = serverPluginsManager.getServerPluginRelationships(plugin); return plugin; }
commit 58516b06f34883646b3efd6d397438a719e75f90 Author: John Mazzitelli mazz@redhat.com Date: Mon Nov 30 14:02:55 2009 -0500
getting some code to help restart individual plugins while the master is still up
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/plugin/ServerPlugin.java b/modules/core/domain/src/main/java/org/rhq/core/domain/plugin/ServerPlugin.java index 426b62e..714872e 100644 --- a/modules/core/domain/src/main/java/org/rhq/core/domain/plugin/ServerPlugin.java +++ b/modules/core/domain/src/main/java/org/rhq/core/domain/plugin/ServerPlugin.java @@ -169,6 +169,17 @@ import org.rhq.core.domain.configuration.Configuration; + " FROM ServerPlugin AS p " // + " WHERE p.status = 'INSTALLED' "), //
+ // returns all installed plugins, both enabled and disabled + // this is faster than QUERY_FIND_BY_IDS because it doesn't join configs + @NamedQuery(name = ServerPlugin.QUERY_FIND_KEYS_BY_IDS, query = "" // + + " SELECT new org.rhq.core.domain.plugin.PluginKey( " // + + " p.deployment, " // + + " p.type, " // + + " p.name) " // + + " FROM ServerPlugin AS p " // + + " WHERE p.id IN (:ids) " // + + " AND p.status = 'INSTALLED' "), // + // this query is how you enable and disable plugins @NamedQuery(name = ServerPlugin.UPDATE_PLUGINS_ENABLED_BY_IDS, query = "" // + "UPDATE ServerPlugin p " // @@ -187,6 +198,7 @@ public class ServerPlugin extends AbstractPlugin { public static final String QUERY_FIND_ANY_BY_NAME = "ServerPlugin.findAnyByName"; public static final String QUERY_FIND_ALL_INSTALLED = "ServerPlugin.findAllInstalled"; public static final String QUERY_FIND_ALL_INSTALLED_KEYS = "ServerPlugin.findAllInstalledKeys"; + public static final String QUERY_FIND_KEYS_BY_IDS = "ServerPlugin.findKeysByIds"; public static final String UPDATE_PLUGINS_ENABLED_BY_IDS = "ServerPlugin.updatePluginsEnabledByIds";
@JoinColumn(name = "JOBS_CONFIG_ID", referencedColumnName = "ID") diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsBean.java index 5de2a0d..04f377d 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsBean.java @@ -79,6 +79,7 @@ public class ServerPluginsBean implements ServerPluginsLocal { @EJB private ServerPluginsLocal serverPluginsBean; //self
+ @SuppressWarnings("unchecked") public List<ServerPlugin> getServerPlugins() { Query q = entityManager.createNamedQuery(ServerPlugin.QUERY_FIND_ALL_INSTALLED); return q.getResultList(); @@ -142,12 +143,7 @@ public class ServerPluginsBean implements ServerPluginsLocal { }
serverPluginsBean.setServerPluginEnabledFlag(subject, pluginIds, true); - - // only restart the master if it was started to begin with - ServerPluginServiceManagement serverPluginService = LookupUtil.getServerPluginService(); - if (serverPluginService.isMasterPluginContainerStarted()) { - serverPluginService.restartMasterPluginContainer(); - } + restartPlugins(pluginIds); return; }
@@ -186,10 +182,7 @@ public class ServerPluginsBean implements ServerPluginsLocal { } }
- // only restart if the master was started to begin with; otherwise, leave it down - if (master != null) { - serverPluginService.restartMasterPluginContainer(); - } + restartPlugins(pluginIds);
return doomedPlugins; } @@ -253,10 +246,7 @@ public class ServerPluginsBean implements ServerPluginsLocal {
log.info("Server plugins " + doomedPlugins + " have been undeployed");
- // only restart if the master was started to begin with; otherwise, leave it down - if (master != null) { - serverPluginService.restartMasterPluginContainer(); - } + restartPlugins(pluginIds);
return doomedPlugins; } @@ -484,4 +474,65 @@ public class ServerPluginsBean implements ServerPluginsLocal { } return; } + + /** + * Given a list of plugin IDs, this will restart those plugins. + * this does nothing if the master plugin container is not started. + * + * @param pluginIds the IDs of the plugins to restart + */ + private void restartPlugins(List<Integer> pluginIds) { + ServerPluginServiceManagement serverPluginService = LookupUtil.getServerPluginService(); + MasterServerPluginContainer master = serverPluginService.getMasterPluginContainer(); + if (master != null) { + Map<AbstractTypeServerPluginContainer, List<PluginKey>> pcs; + pcs = getPluginContainersForPluginIds(master, pluginIds); + for (Map.Entry<AbstractTypeServerPluginContainer, List<PluginKey>> entry : pcs.entrySet()) { + AbstractTypeServerPluginContainer pc = entry.getKey(); + List<PluginKey> pluginKeys = entry.getValue(); + pc.restartPlugins(pluginKeys); + } + } + } + + /** + * Given a list IDs of server plugins, this will return all plugin containers that manage those plugins. + * + * @param master the master plugin container + * @param pluginIds the IDs of plugins whose plugin containers are to be returned + * + * @return the plugin containers that manage the plugins with the given IDs + */ + private Map<AbstractTypeServerPluginContainer, List<PluginKey>> getPluginContainersForPluginIds( + MasterServerPluginContainer master, List<Integer> pluginIds) { + + Map<AbstractTypeServerPluginContainer, List<PluginKey>> pcs; + pcs = new HashMap<AbstractTypeServerPluginContainer, List<PluginKey>>(); + + AbstractTypeServerPluginContainer pc; + + List<PluginKey> keys = getPluginKeysFromIds(pluginIds); + for (PluginKey key : keys) { + try { + pc = master.getPluginContainerByPluginType(new ServerPluginType(key.getPluginType())); + List<PluginKey> list = pcs.get(pc); + if (list == null) { + list = new ArrayList<PluginKey>(); + pcs.put(pc, list); + } + list.add(key); + } catch (Exception e) { + log.warn("Cannot determine what PC manages plugin [" + key + "]", e); + } + } + + return pcs; + } + + private List<PluginKey> getPluginKeysFromIds(List<Integer> pluginIds) { + Query q = entityManager.createNamedQuery(ServerPlugin.QUERY_FIND_KEYS_BY_IDS); + q.setParameter("ids", pluginIds); + List<PluginKey> keys = q.getResultList(); + return keys; + } } diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/AbstractTypeServerPluginContainer.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/AbstractTypeServerPluginContainer.java index 3301dcc..3930f21 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/AbstractTypeServerPluginContainer.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/AbstractTypeServerPluginContainer.java @@ -256,6 +256,43 @@ public abstract class AbstractTypeServerPluginContainer { }
/** + * This will restart the given set of plugins. The currently running plugins will + * be stopped and unloaded and the new plugins will be loaded and started. + * + * If a plugin is in the given list but is not already started, this method will + * skip that plugin (i.e. it will not start it). + * + * + * + * @param pluginKeys identifies the plugins that need to be restarted + */ + // TODO: This method does not do anything with the scheduled jobs. + // Perhaps we should unschedule them and reschedule them, in case the jobs were reconfigured? + // What happens to the jobs that may currently be running in the HA case? + public synchronized void restartPlugins(List<PluginKey> pluginKeys) { + if (this.pluginManager != null) { + for (PluginKey pluginKey : pluginKeys) { + String pluginName = pluginKey.getPluginName(); + ServerPluginEnvironment env = this.pluginManager.getPluginEnvironment(pluginName); + if (env != null) { + try { + this.pluginManager.stopPlugin(pluginName); + this.pluginManager.unloadPlugin(env); + this.pluginManager.loadPlugin(env); + this.pluginManager.startPlugin(pluginName); + } catch (Exception e) { + log.warn("Failed to restart server plugin [" + pluginName + "]", e); + } + } else { + log.info("Being asked to restart server plugin [" + pluginName + + "] but it isn't started - skipping"); + } + } + } + return; + } + + /** * This will be called when its time for this plugin container to create its plugin manager. * Subclasses are free to override this if they need their own specialized plugin manager. * diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/MasterServerPluginContainer.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/MasterServerPluginContainer.java index 2d2eea7..1e9cbc4 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/MasterServerPluginContainer.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/MasterServerPluginContainer.java @@ -344,12 +344,14 @@ public class MasterServerPluginContainer { }
/** - * Given a plugin's descriptor, this will return the plugin container that can manage the plugin. + * Given a server plugin type, this will return the plugin container that can manage that type of plugin. + * If the server plugin type is unknown to the master, or if the master plugin is not started, this will + * return <code>null</code>. * - * @param descriptor descriptor to identify a plugin whose container is to be returned - * @return a plugin container that can handle the plugin with the given descriptor + * @param pluginType the type of server plugin whose PC is to be returned + * @return a plugin container that can handle the given type of server plugin */ - protected synchronized AbstractTypeServerPluginContainer getPluginContainerByPluginType(ServerPluginType pluginType) { + public synchronized AbstractTypeServerPluginContainer getPluginContainerByPluginType(ServerPluginType pluginType) { AbstractTypeServerPluginContainer pc = this.pluginContainers.get(pluginType); return pc; } diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginManager.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginManager.java index 87f2575..ace80c8 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginManager.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginManager.java @@ -144,12 +144,17 @@ public class ServerPluginManager { }
public void startPlugins() { - log.debug("Starting plugins"); + log.debug("Starting server plugins"); + for (String pluginName : this.pluginComponentCache.keySet()) { + startPlugin(pluginName); + } + log.debug("Server plugins started."); + return; + }
- // tell all plugin components to start - for (Map.Entry<String, ServerPluginComponent> entry : this.pluginComponentCache.entrySet()) { - String pluginName = entry.getKey(); - ServerPluginComponent component = entry.getValue(); + public void startPlugin(String pluginName) { + ServerPluginComponent component = this.pluginComponentCache.get(pluginName); + if (component != null) { ServerPluginEnvironment env = this.loadedPlugins.get(pluginName); log.debug("Starting plugin component for server plugin [" + pluginName + "]"); ClassLoader originalContextClassLoader = Thread.currentThread().getContextClassLoader(); @@ -162,17 +167,21 @@ public class ServerPluginManager { Thread.currentThread().setContextClassLoader(originalContextClassLoader); } } - return; }
public void stopPlugins() { - log.debug("Stopping plugins"); + log.debug("Stopping server plugins"); + for (String pluginName : this.pluginComponentCache.keySet()) { + stopPlugin(pluginName); + } + log.debug("Server plugins stopped."); + return; + }
- // tell all plugin components to stop - for (Map.Entry<String, ServerPluginComponent> entry : this.pluginComponentCache.entrySet()) { - String pluginName = entry.getKey(); - ServerPluginComponent component = entry.getValue(); + public void stopPlugin(String pluginName) { + ServerPluginComponent component = this.pluginComponentCache.get(pluginName); + if (component != null) { ServerPluginEnvironment env = this.loadedPlugins.get(pluginName); log.debug("Stopping plugin component for server plugin [" + pluginName + "]"); ClassLoader originalContextClassLoader = Thread.currentThread().getContextClassLoader(); @@ -185,7 +194,6 @@ public class ServerPluginManager { Thread.currentThread().setContextClassLoader(originalContextClassLoader); } } - return; }
commit 4fc48faeb13369a38ac1b602237672bd60038865 Author: Justin Harris jharris@redhat.com Date: Mon Nov 30 17:30:10 2009 -0500
Pulling out old admin navigation rules.
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-navigation/admin-navigation.xml b/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-navigation/admin-navigation.xml index 37b3bad..93932df 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-navigation/admin-navigation.xml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-navigation/admin-navigation.xml @@ -28,17 +28,6 @@ </navigation-case>
</navigation-rule> - - <navigation-rule> - <from-view-id>/rhq/admin/plugin/plugin-details-edit.xhtml</from-view-id> - - <navigation-case> - <from-outcome>successServerPlugin</from-outcome> - <to-view-id>/rhq/admin/plugin/plugin-details-view.xhtml?plugin=#{plugin.name}&deployment=#{plugin.deployment}&pluginType=#{serverPlugin.type}</to-view-id> - <redirect/> - </navigation-case> - - </navigation-rule>
<navigation-rule> <navigation-case>
commit b28233475d75e80c01c217ac16e86c897ec262f1 Author: Adam Young ayoung@redhat.com Date: Mon Nov 30 17:29:21 2009 -0500
Removed additional files that break the build
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ExistingResourceConfigurationUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ExistingResourceConfigurationUIBean.java index 8097b32..ef7d7df 100644 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ExistingResourceConfigurationUIBean.java +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ExistingResourceConfigurationUIBean.java @@ -152,7 +152,7 @@ public class ExistingResourceConfigurationUIBean extends AbstractConfigurationUI return configuration; }
- private final Log log = LogFactory.getLog(RawConfigCollection.class); + private final Log log = LogFactory.getLog(AbstractConfigurationUIBean.class); private Integer resourceId = null;
private static final long serialVersionUID = 4837157548556168146L; diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/RawConfigDownload.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/RawConfigDownload.java deleted file mode 100644 index 7c4859d..0000000 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/RawConfigDownload.java +++ /dev/null @@ -1,53 +0,0 @@ -package org.rhq.enterprise.gui.configuration.resource; - -import javax.faces.context.ExternalContext; -import javax.faces.context.FacesContext; -import javax.servlet.ServletOutputStream; -import javax.servlet.http.HttpServletResponse; - -import org.jboss.seam.ScopeType; -import org.jboss.seam.annotations.Create; -import org.jboss.seam.annotations.In; -import org.jboss.seam.annotations.Logger; -import org.jboss.seam.annotations.Name; -import org.jboss.seam.annotations.Scope; -import org.jboss.seam.log.Log; - -@Name("rawConfigDownload") -@Scope(ScopeType.PAGE) -public class RawConfigDownload { - - @Logger - private Log log; - - @In(value = "#{rawConfigCollection}") - RawConfigCollection rawConfigCollection; - - @In(value = "#{facesContext}") - FacesContext facesContext; - - @In(value = "#{facesContext.externalContext}") - private ExternalContext extCtx; - - @Create - public void init() { - log.error("starting"); - } - - public String download() { - HttpServletResponse response = (HttpServletResponse) extCtx.getResponse(); - response.setContentType("text/plain"); - response.addHeader("Content-disposition", "attachment; filename="testing.txt""); - try { - ServletOutputStream os = response.getOutputStream(); - os.write(rawConfigCollection.getCurrent().getContents()); - os.flush(); - os.close(); - facesContext.responseComplete(); - } catch (Exception e) { - log.error("\nFailure : " + e.toString() + "\n"); - } - - return null; - } -} \ No newline at end of file diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/RawConfigViewer.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/RawConfigViewer.java deleted file mode 100644 index d794c37..0000000 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/RawConfigViewer.java +++ /dev/null @@ -1,69 +0,0 @@ -package org.rhq.enterprise.gui.configuration.resource; - -import java.util.Iterator; -import java.util.TreeMap; - -import org.jboss.seam.ScopeType; -import org.jboss.seam.annotations.Name; -import org.jboss.seam.annotations.Scope; - -import org.rhq.core.domain.configuration.RawConfiguration; -import org.rhq.enterprise.gui.util.EnterpriseFacesContextUtility; - -@Name("RawConfigViewer") -@Scope(ScopeType.SESSION) -public class RawConfigViewer { - - RawConfigDelegate rawConfigDelegate; - - int getResourceId() { - int resourceId = EnterpriseFacesContextUtility.getResource().getId(); - return resourceId; - } - - public RawConfigDelegate getRawConfigDelegate() { - if (null == rawConfigDelegate || (getResourceId() != rawConfigDelegate.resourceId)) { - rawConfigDelegate = new RawConfigDelegate(getResourceId()); - } - return rawConfigDelegate; - } - - public TreeMap<String, RawConfiguration> getRaws() { - return getRawConfigDelegate().getRaws(); - } - - public void setCurrentPath(String path) { - RawConfiguration raw = getRaws().get(path); - if (null != raw) { - getRawConfigDelegate().current = raw; - } - } - - public String getCurrentContents() { - return new String(getCurrent().getContents()); - } - - public Object[] getPaths() { - return getRaws().keySet().toArray(); - } - - public void select(String s) { - getRawConfigDelegate().selectedPath = s; - setCurrentPath(getRawConfigDelegate().selectedPath); - } - - public RawConfiguration getCurrent() { - if (null == getRawConfigDelegate().current) { - Iterator<RawConfiguration> iterator = getRaws().values().iterator(); - if (iterator.hasNext()) { - getRawConfigDelegate().current = iterator.next(); - } else { - getRawConfigDelegate().current = new RawConfiguration(); - getRawConfigDelegate().current.setPath("/dev/null"); - getRawConfigDelegate().current.setContents("".getBytes()); - } - } - return getRawConfigDelegate().current; - } - -}
commit 66ca6b483d297a7f7dc6185f09525a66a6a76b85 Merge: 6da3b35... f013bcd... Author: Adam Young ayoung@redhat.com Date: Mon Nov 30 17:00:28 2009 -0500
Merge branch 'raw-config' of ssh://git.fedorahosted.org/git/rhq/rhq into raw-config
commit 6da3b35c0f05f6b959efe944dd2fc1a3a6d15b04 Author: Adam Young ayoung@redhat.com Date: Mon Nov 30 17:00:01 2009 -0500
Merged Raw Config Collection Functionality into the class used for Structured, and dropped the ability to maintain multiple edits going at once.
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ExistingResourceConfigurationUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ExistingResourceConfigurationUIBean.java index 846b867..8097b32 100644 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ExistingResourceConfigurationUIBean.java +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ExistingResourceConfigurationUIBean.java @@ -18,18 +18,29 @@ */ package org.rhq.enterprise.gui.configuration.resource;
+import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.util.Collection; +import java.util.Iterator; +import java.util.TreeMap; + import javax.faces.application.FacesMessage;
+import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.jetbrains.annotations.Nullable; +import org.richfaces.event.UploadEvent;
-import org.jboss.seam.ScopeType; -import org.jboss.seam.annotations.In; -import org.jboss.seam.annotations.Name; -import org.jboss.seam.annotations.Scope; +import org.jboss.seam.annotations.Create;
+import org.rhq.core.domain.auth.Subject; import org.rhq.core.domain.configuration.AbstractResourceConfigurationUpdate; import org.rhq.core.domain.configuration.Configuration; +import org.rhq.core.domain.configuration.Property; +import org.rhq.core.domain.configuration.RawConfiguration; import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; +import org.rhq.core.domain.configuration.definition.ConfigurationFormat; import org.rhq.core.gui.configuration.ConfigurationMaskingUtility; import org.rhq.core.gui.util.FacesContextUtility; import org.rhq.enterprise.gui.configuration.AbstractConfigurationUIBean; @@ -40,8 +51,8 @@ import org.rhq.enterprise.server.util.LookupUtil; /** * @author Ian Springer */ -@Name(value = "ExistingResourceConfigurationUIBean") -@Scope(ScopeType.PAGE) +//@ Name(value = "ExistingResourceConfigurationUIBean") +//@ Scope(ScopeType.PAGE) public class ExistingResourceConfigurationUIBean extends AbstractConfigurationUIBean { public static final String MANAGED_BEAN_NAME = "ExistingResourceConfigurationUIBean";
@@ -129,8 +140,6 @@ public class ExistingResourceConfigurationUIBean extends AbstractConfigurationUI
@Nullable protected Configuration lookupConfiguration() { - - /* Subject subject = EnterpriseFacesContextUtility.getSubject(); int resourceId = EnterpriseFacesContextUtility.getResource().getId(); AbstractResourceConfigurationUpdate configurationUpdate = this.configurationManager @@ -141,21 +150,292 @@ public class ExistingResourceConfigurationUIBean extends AbstractConfigurationUI }
return configuration; - */ + } + + private final Log log = LogFactory.getLog(RawConfigCollection.class); + private Integer resourceId = null; + + private static final long serialVersionUID = 4837157548556168146L; + + public String commit() { + + Subject subject = EnterpriseFacesContextUtility.getSubject(); + LookupUtil.getConfigurationManager().updateResourceConfiguration(subject, getResourceId(), + getMergedConfiguration()); + + nullify(); + + return "/rhq/resource/configuration/view.xhtml?id=" + getResourceId(); + } + + private Configuration getMergedConfiguration() { + for (RawConfiguration raw : getModified().values()) { + getRaws().put(raw.getPath(), raw); + log.error("Just merged in raw path =[" + raw.getPath() + "]"); + log.error(" file =[" + new String(raw.getContents()) + "]"); + + } + getConfiguration().getRawConfigurations().clear(); + getConfiguration().getRawConfigurations().addAll(getRaws().values()); + return getConfiguration(); + } + + public String discard() { + nullify(); + return "/rhq/resource/configuration/view.xhtml?id=" + getResourceId(); + } + + public void fileUploadListener(UploadEvent event) throws Exception { + File uploadFile; + log.error("fileUploadListener called"); + uploadFile = event.getUploadItem().getFile(); + if (uploadFile != null) { + log.debug("fileUploadListener got file named " + event.getUploadItem().getFileName()); + log.debug("content type is " + event.getUploadItem().getContentType()); + if (uploadFile != null) { + try { + FileReader fileReader = new FileReader(uploadFile); + char[] buff = new char[1024]; + StringBuffer stringBuffer = new StringBuffer(); + for (int count = fileReader.read(buff); count != -1; count = fileReader.read(buff)) { + stringBuffer.append(buff, 0, count); + } + setCurrentContents(stringBuffer.toString()); + } catch (IOException e) { + log.error("problem reading uploaded file", e); + } + } + } + } + + public int getConfigId() { + return getConfiguration().getId(); + } + + /* + public Configuration getConfiguration() { + if (null == configuration) { + + Subject subject = EnterpriseFacesContextUtility.getSubject(); + int resourceId = EnterpriseFacesContextUtility.getResource().getId(); + AbstractResourceConfigurationUpdate configurationUpdate = LookupUtil.getConfigurationManager() + .getLatestResourceConfigurationUpdate(subject, resourceId); + Configuration configuration = (configurationUpdate != null) ? configurationUpdate.getConfiguration() : null; + if (configuration != null) { + //ConfigurationMaskingUtility.maskConfiguration(configuration, getConfigurationDefinition()); + } + + return configuration; + + } + return configuration; + + } + */ + + private ConfigurationFormat getConfigurationFormat() { + return getConfigurationDefinition().getConfigurationFormat(); + } + + public RawConfiguration getCurrent() { + if (null == current) { + Iterator<RawConfiguration> iterator = getRaws().values().iterator(); + if (iterator.hasNext()) { + current = iterator.next(); + } else { + current = new RawConfiguration(); + current.setPath("/dev/null"); + current.setContents("".getBytes()); + } + } + return current; + } + + public String getCurrentContents() { + return new String(getCurrent().getContents()); + } + + public String getCurrentPath() { + return getCurrent().getPath(); + } + + public TreeMap<String, RawConfiguration> getModified() { + if (modified == null) { + modified = new TreeMap<String, RawConfiguration>(); + } + return modified; + } + + public Object[] getPaths() { + return getRaws().keySet().toArray(); + } + + /** + * + * @return the id associated with the resource. + * The value Cached in order to be available on the upload page, + * where seeing the resource id conflicts with the rich upload tag. + */ + public int getResourceId() { + if (resourceId == null) { + resourceId = EnterpriseFacesContextUtility.getResource().getId(); + } + return resourceId; + } + + /** + * Hack Alert. This bean needs to be initialized on one of the pages that has id or resourceId set + * In order to capture the resource. It will then Keep track of that particular resources until + * commit is called. Ideally, this should be a conversation scoped bean, but that has other issues + * + */ + @Create + public void init() {
- return getRawConfigCollection().getConfiguration(); + } + + public boolean isModified(String path) { + return getModified().keySet().contains(path); + } + + public boolean isRawSupported() { + return getConfigurationFormat().isRawSupported(); + } + + public boolean isStructuredSupported() { + return getConfigurationFormat().isStructuredSupported(); + } + + void nullify() { + + } + + /** + * Indicates which of the raw configuration files is currently selected. + * @param s + */ + public void select(String s) { + selectedPath = s; + setCurrentPath(selectedPath); + } + + public void setCurrentContents(String updated) { + + String original = new String(getCurrent().getContents()); + if (!updated.equals(original)) { + current = current.deepCopy(false); + current.setContents(updated.getBytes()); + //TODO update other values like MD5 + getModified().put(current.getPath(), current); + } + } + + public void setCurrentPath(String path) { + RawConfiguration raw = getModified().get(path); + if (null == raw) { + raw = getRaws().get(path); + } + if (null != raw) { + current = raw; + } + } + + public void setModified(RawConfiguration raw) { + getModified().put(raw.getPath(), raw); + } + + /** + * This is a no-op, since the upload work was done by upload file + * But is kept as a target for the "save" icon from the full screen page + */ + public String update() { + return "/rhq/resource/configuration/edit-raw.xhtml?currentResourceId=" + getResourceId(); + }
+ /** + * This is a no-op, since the upload work was done by upload file + * But is kept as a target for the "action" value + */ + public String upload() { + return "/rhq/resource/configuration/edit-raw.xhtml?currentResourceId=" + getResourceId(); }
- @In(create = true, required = true, value = "rawConfigCollection") - RawConfigCollection rawConfigCollection; + public String switchToraw() { + log.error("switch2raw called"); + dumpProperties(getConfiguration(), log); + Configuration configuration = LookupUtil.getConfigurationManager().translateResourceConfiguration( + EnterpriseFacesContextUtility.getSubject(), getResourceId(), getMergedConfiguration(), true); + log.error("switch2raw post merge"); + dumpProperties(getConfiguration(), log);
- public RawConfigCollection getRawConfigCollection() { - return rawConfigCollection; + setConfiguration(configuration); + for (RawConfiguration raw : configuration.getRawConfigurations()) { + getRaws().put(raw.getPath(), raw); + } + current = null; + setConfiguration(configuration); + + return "/rhq/resource/configuration/edit-raw.xhtml?currentResourceId=" + getResourceId(); + } + + void dumpProperties(Configuration conf, Log log) { + for (String key : conf.getAllProperties().keySet()) { + log.error("property=" + conf.getAllProperties().get(key)); + } + } + + public String switchTostructured() { + log.error("switch2structured called"); + + dumpProperties(getConfiguration(), log); + Configuration configuration = LookupUtil.getConfigurationManager().translateResourceConfiguration( + EnterpriseFacesContextUtility.getSubject(), getResourceId(), getMergedConfiguration(), false); + log.error("switch2structured post merge"); + + dumpProperties(configuration, log); + + for (Property property : configuration.getAllProperties().values()) { + property.setConfiguration(configuration); + } + + for (RawConfiguration raw : configuration.getRawConfigurations()) { + getRaws().put(raw.getPath(), raw); + setConfiguration(configuration); + } + current = null; + setConfiguration(configuration); + + return "/rhq/resource/configuration/edit.xhtml?currentResourceId=" + getResourceId(); + } + + void populateRaws() { + Collection<RawConfiguration> rawConfigurations = getConfiguration().getRawConfigurations(); + + for (RawConfiguration raw : rawConfigurations) { + raws.put(raw.getPath(), raw); + } }
- public void setRawConfigCollection(RawConfigCollection rawConfigCollection) { - this.rawConfigCollection = rawConfigCollection; + public void setRaws(TreeMap<String, RawConfiguration> raws) { + this.raws = raws; }
+ public TreeMap<String, RawConfiguration> getRaws() { + + if (null == raws) { + raws = new TreeMap<String, RawConfiguration>(); + populateRaws(); + } + + return raws; + } + + /** + * + */ + String selectedPath; + private TreeMap<String, RawConfiguration> raws; + TreeMap<String, RawConfiguration> modified = new TreeMap<String, RawConfiguration>(); + RawConfiguration current = null; + } \ No newline at end of file diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/RawConfigCollection.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/RawConfigCollection.java deleted file mode 100644 index 29dbe4b..0000000 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/RawConfigCollection.java +++ /dev/null @@ -1,364 +0,0 @@ -package org.rhq.enterprise.gui.configuration.resource; - -import java.io.File; -import java.io.FileReader; -import java.io.IOException; -import java.io.Serializable; -import java.util.Iterator; -import java.util.TreeMap; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.richfaces.event.UploadEvent; - -import org.jboss.seam.ScopeType; -import org.jboss.seam.annotations.Create; -import org.jboss.seam.annotations.End; -import org.jboss.seam.annotations.In; -import org.jboss.seam.annotations.Name; -import org.jboss.seam.annotations.Scope; - -import org.rhq.core.domain.auth.Subject; -import org.rhq.core.domain.configuration.Configuration; -import org.rhq.core.domain.configuration.Property; -import org.rhq.core.domain.configuration.RawConfiguration; -import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; -import org.rhq.core.domain.configuration.definition.ConfigurationFormat; -import org.rhq.enterprise.gui.configuration.AbstractConfigurationUIBean; -import org.rhq.enterprise.gui.util.EnterpriseFacesContextUtility; -import org.rhq.enterprise.server.util.LookupUtil; - -@Name("rawConfigCollection") -@Scope(ScopeType.PAGE) -/** - * The backing class for all Web based activities for manipulating the set of - * raw configuration files associated with a resource - */ -public class RawConfigCollection extends AbstractConfigurationUIBean implements Serializable { - - private RawConfigDelegate rawConfigDelegate = null; - private RawConfigDelegateMap rawConfigDelegateMap; - - /*This is for development, to prevent actually going to the EJBs. - TODO It should be set to false prior to check in*/ - private static final boolean useMock = false; - - private final Log log = LogFactory.getLog(RawConfigCollection.class); - private Integer resourceId = null; - - private static final long serialVersionUID = 4837157548556168146L; - - public RawConfigCollection() { - } - - @End - public String commit() { - - Subject subject = EnterpriseFacesContextUtility.getSubject(); - LookupUtil.getConfigurationManager().updateResourceConfiguration(subject, getResourceId(), - getMergedConfiguration()); - - nullify(); - - return "/rhq/resource/configuration/view.xhtml?id=" + getResourceId(); - } - - private Configuration getMergedConfiguration() { - for (RawConfiguration raw : getRawConfigDelegate().modified.values()) { - getRaws().put(raw.getPath(), raw); - log.error("Just merged in raw path =[" + raw.getPath() + "]"); - log.error(" file =[" + new String(raw.getContents()) + "]"); - - } - getConfiguration().getRawConfigurations().clear(); - getConfiguration().getRawConfigurations().addAll(getRaws().values()); - return getConfiguration(); - } - - public String discard() { - nullify(); - return "/rhq/resource/configuration/view.xhtml?id=" + getResourceId(); - } - - public void fileUploadListener(UploadEvent event) throws Exception { - File uploadFile; - log.error("fileUploadListener called"); - uploadFile = event.getUploadItem().getFile(); - if (uploadFile != null) { - log.debug("fileUploadListener got file named " + event.getUploadItem().getFileName()); - log.debug("content type is " + event.getUploadItem().getContentType()); - if (uploadFile != null) { - try { - FileReader fileReader = new FileReader(uploadFile); - char[] buff = new char[1024]; - StringBuffer stringBuffer = new StringBuffer(); - for (int count = fileReader.read(buff); count != -1; count = fileReader.read(buff)) { - stringBuffer.append(buff, 0, count); - } - setCurrentContents(stringBuffer.toString()); - } catch (IOException e) { - log.error("problem reading uploaded file", e); - } - } - } - } - - public int getConfigId() { - return getConfiguration().getId(); - } - - public Configuration getConfiguration() { - return getRawConfigDelegate().getConfiguration(); - } - - //TODO Sync this up with the baseclass - public ConfigurationDefinition getConfigurationDefinition() { - if (null == getRawConfigDelegate().configurationDefinition) { - - getRawConfigDelegate().configurationDefinition = LookupUtil.getConfigurationManager() - .getResourceConfigurationDefinitionForResourceType(EnterpriseFacesContextUtility.getSubject(), - EnterpriseFacesContextUtility.getResource().getResourceType().getId()); - } - return getRawConfigDelegate().configurationDefinition; - } - - private ConfigurationFormat getConfigurationFormat() { - if (useMock) - return ConfigurationFormat.STRUCTURED_AND_RAW; - return getConfigurationDefinition().getConfigurationFormat(); - } - - public RawConfiguration getCurrent() { - if (null == getRawConfigDelegate().current) { - Iterator<RawConfiguration> iterator = getRaws().values().iterator(); - if (iterator.hasNext()) { - getRawConfigDelegate().current = iterator.next(); - } else { - getRawConfigDelegate().current = new RawConfiguration(); - getRawConfigDelegate().current.setPath("/dev/null"); - getRawConfigDelegate().current.setContents("".getBytes()); - } - } - return getRawConfigDelegate().current; - } - - public String getCurrentContents() { - return new String(getCurrent().getContents()); - } - - public String getCurrentPath() { - return getCurrent().getPath(); - } - - private RawConfigDelegateMap getDelegates() { - return rawConfigDelegateMap; - } - - public TreeMap<String, RawConfiguration> getModified() { - if (getRawConfigDelegate().modified == null) { - getRawConfigDelegate().modified = new TreeMap<String, RawConfiguration>(); - } - return getRawConfigDelegate().modified; - } - - public Object[] getPaths() { - return getRaws().keySet().toArray(); - } - - RawConfigDelegate getRawConfigDelegate() { - if (null == rawConfigDelegate) { - rawConfigDelegate = getDelegates().get(getResourceId()); - if (null == rawConfigDelegate) { - rawConfigDelegate = new RawConfigDelegate(getResourceId()); - getDelegates().put(getResourceId(), rawConfigDelegate); - } - } - return rawConfigDelegate; - } - - public RawConfigDelegateMap getRawConfigDelegateMap() { - return rawConfigDelegateMap; - } - - public TreeMap<String, RawConfiguration> getRaws() { - return getRawConfigDelegate().getRaws(); - } - - /** - * - * @return the id associated with the resource. - * The value Cached in order to be available on the upload page, - * where seeing the resource id conflicts with the rich upload tag. - */ - public int getResourceId() { - if (resourceId == null) { - resourceId = EnterpriseFacesContextUtility.getResource().getId(); - } - return resourceId; - } - - /** - * Hack Alert. This bean needs to be initialized on one of the pages that has id or resourceId set - * In order to capture the resource. It will then Keep track of that particular resources until - * commit is called. Ideally, this should be a conversation scoped bean, but that has other issues - * - */ - @Create - public void init() { - - } - - public boolean isModified(String path) { - return getModified().keySet().contains(path); - } - - public boolean isRawSupported() { - return getConfigurationFormat().isRawSupported(); - } - - public boolean isStructuredSupported() { - return getConfigurationFormat().isStructuredSupported(); - } - - void nullify() { - getDelegates().remove(getResourceId()); - setRawConfigDelegate(null); - } - - /** - * Indicates which of the raw configuration files is currently selected. - * @param s - */ - public void select(String s) { - getRawConfigDelegate().selectedPath = s; - setCurrentPath(getRawConfigDelegate().selectedPath); - } - - public void setCurrentContents(String updated) { - - String original = new String(getCurrent().getContents()); - if (!updated.equals(original)) { - getRawConfigDelegate().current = getRawConfigDelegate().current.deepCopy(false); - getRawConfigDelegate().current.setContents(updated.getBytes()); - //TODO update other values like MD5 - getModified().put(getRawConfigDelegate().current.getPath(), getRawConfigDelegate().current); - } - } - - public void setCurrentPath(String path) { - RawConfiguration raw = getModified().get(path); - if (null == raw) { - raw = getRaws().get(path); - } - if (null != raw) { - getRawConfigDelegate().current = raw; - } - } - - void setDelegates(RawConfigDelegateMap delegates) { - this.rawConfigDelegateMap = delegates; - } - - public void setModified(RawConfiguration raw) { - getRawConfigDelegate().modified.put(raw.getPath(), raw); - } - - void setRawConfigDelegate(RawConfigDelegate rawConfigDelegate) { - this.rawConfigDelegate = rawConfigDelegate; - } - - @In(create = true, required = true) - public void setRawConfigDelegateMap(RawConfigDelegateMap rawConfigDelegateMap) { - this.rawConfigDelegateMap = rawConfigDelegateMap; - } - - /** - * This is a no-op, since the upload work was done by upload file - * But is kept as a target for the "save" icon from the full screen page - */ - public String update() { - return "/rhq/resource/configuration/edit-raw.xhtml?currentResourceId=" + getResourceId(); - } - - /** - * This is a no-op, since the upload work was done by upload file - * But is kept as a target for the "action" value - */ - public String upload() { - return "/rhq/resource/configuration/edit-raw.xhtml?currentResourceId=" + getResourceId(); - } - - public String switchToraw() { - log.error("switch2raw called"); - dumpProperties(getConfiguration(), log); - Configuration configuration = LookupUtil.getConfigurationManager().translateResourceConfiguration( - EnterpriseFacesContextUtility.getSubject(), getResourceId(), getMergedConfiguration(), true); - log.error("switch2raw post merge"); - dumpProperties(getConfiguration(), log); - - getRawConfigDelegate().setConfiguration(configuration); - for (RawConfiguration raw : configuration.getRawConfigurations()) { - getRawConfigDelegate().getRaws().put(raw.getPath(), raw); - } - getRawConfigDelegate().current = null; - getRawConfigDelegate().setConfiguration(configuration); - getRawConfigDelegateMap().put(getResourceId(), getRawConfigDelegate()); - - return "/rhq/resource/configuration/edit-raw.xhtml?currentResourceId=" + getResourceId(); - } - - void dumpProperties(Configuration conf, Log log) { - for (String key : conf.getAllProperties().keySet()) { - log.error("property=" + conf.getAllProperties().get(key)); - } - } - - public String switchTostructured() { - log.error("switch2structured called"); - - dumpProperties(getConfiguration(), log); - Configuration configuration = LookupUtil.getConfigurationManager().translateResourceConfiguration( - EnterpriseFacesContextUtility.getSubject(), getResourceId(), getMergedConfiguration(), false); - log.error("switch2structured post merge"); - - dumpProperties(configuration, log); - - for (Property property : configuration.getAllProperties().values()) { - property.setConfiguration(configuration); - } - - for (RawConfiguration raw : configuration.getRawConfigurations()) { - getRawConfigDelegate().getRaws().put(raw.getPath(), raw); - getRawConfigDelegate().setConfiguration(configuration); - } - getRawConfigDelegate().current = null; - getRawConfigDelegate().setConfiguration(configuration); - - return "/rhq/resource/configuration/edit.xhtml?currentResourceId=" + getResourceId(); - } - - @Override - protected int getConfigurationDefinitionKey() { - // TODO Auto-generated method stub - return 0; - } - - @Override - protected int getConfigurationKey() { - // TODO Auto-generated method stub - return 0; - } - - @Override - protected Configuration lookupConfiguration() { - // TODO Auto-generated method stub - return null; - } - - @Override - protected ConfigurationDefinition lookupConfigurationDefinition() { - // TODO Auto-generated method stub - return null; - } - -} diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/RawConfigDelegate.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/RawConfigDelegate.java deleted file mode 100644 index d049f35..0000000 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/RawConfigDelegate.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2009 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.gui.configuration.resource; - -import java.io.Serializable; -import java.util.Collection; -import java.util.TreeMap; - -import org.rhq.core.domain.auth.Subject; -import org.rhq.core.domain.configuration.AbstractResourceConfigurationUpdate; -import org.rhq.core.domain.configuration.Configuration; -import org.rhq.core.domain.configuration.RawConfiguration; -import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; -import org.rhq.enterprise.gui.util.EnterpriseFacesContextUtility; -import org.rhq.enterprise.server.util.LookupUtil; - -public class RawConfigDelegate implements Serializable { - - void populateRaws() { - Collection<RawConfiguration> rawConfigurations = LookupUtil.getConfigurationManager() - .getLatestResourceConfigurationUpdate(EnterpriseFacesContextUtility.getSubject(), resourceId) - .getConfiguration().getRawConfigurations(); - - for (RawConfiguration raw : rawConfigurations) { - raws.put(raw.getPath(), raw); - } - } - - public RawConfigDelegate(int resourceId) { - super(); - this.resourceId = resourceId; - } - - public void setRaws(TreeMap<String, RawConfiguration> raws) { - this.raws = raws; - } - - public TreeMap<String, RawConfiguration> getRaws() { - - if (null == raws) { - raws = new TreeMap<String, RawConfiguration>(); - populateRaws(); - } - - return raws; - } - - public void setConfiguration(Configuration configuration) { - this.configuration = configuration; - } - - public Configuration getConfiguration() { - if (null == configuration) { - - Subject subject = EnterpriseFacesContextUtility.getSubject(); - int resourceId = EnterpriseFacesContextUtility.getResource().getId(); - AbstractResourceConfigurationUpdate configurationUpdate = LookupUtil.getConfigurationManager() - .getLatestResourceConfigurationUpdate(subject, resourceId); - Configuration configuration = (configurationUpdate != null) ? configurationUpdate.getConfiguration() : null; - if (configuration != null) { - //ConfigurationMaskingUtility.maskConfiguration(configuration, getConfigurationDefinition()); - } - - return configuration; - - } - return configuration; - } - - /** - * - */ - private static final long serialVersionUID = -9058700205958371765L; - - int resourceId = 0; - String selectedPath; - private TreeMap<String, RawConfiguration> raws; - TreeMap<String, RawConfiguration> modified = new TreeMap<String, RawConfiguration>(); - RawConfiguration current = null; - ConfigurationDefinition configurationDefinition = null; - private Configuration configuration; - -} \ No newline at end of file diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/RawConfigDelegateMap.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/RawConfigDelegateMap.java deleted file mode 100644 index 44b79b7..0000000 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/RawConfigDelegateMap.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2009 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.gui.configuration.resource; - -import java.util.HashMap; -import java.util.Map; - -import org.jboss.seam.ScopeType; -import org.jboss.seam.annotations.Name; -import org.jboss.seam.annotations.Scope; - -@Name("rawConfigDelegateMap") -@Scope(ScopeType.SESSION) -public class RawConfigDelegateMap extends HashMap<Integer, RawConfigDelegate> { - - /** - * - */ - private static final long serialVersionUID = 941352750819758987L; - - public RawConfigDelegateMap() { - super(); - // TODO Auto-generated constructor stub - } - - public RawConfigDelegateMap(int initialCapacity, float loadFactor) { - super(initialCapacity, loadFactor); - // TODO Auto-generated constructor stub - } - - public RawConfigDelegateMap(int initialCapacity) { - super(initialCapacity); - // TODO Auto-generated constructor stub - } - - public RawConfigDelegateMap(Map<? extends Integer, ? extends RawConfigDelegate> m) { - super(m); - // TODO Auto-generated constructor stub - } - -} \ No newline at end of file diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-managed-beans/configuration-beans.xml b/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-managed-beans/configuration-beans.xml index de0dace..70d3f99 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-managed-beans/configuration-beans.xml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-managed-beans/configuration-beans.xml @@ -4,19 +4,19 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd%22%3E
- <!-- /rhq/resource/configuration/view.xhtml, /rhq/resource/configuration/view-map.xhtml + <!-- /rhq/resource/configuration/view.xhtml, /rhq/resource/configuration/view-map.xhtml --> <managed-bean> <managed-bean-name>ExistingResourceConfigurationViewUIBean</managed-bean-name> <managed-bean-class>org.rhq.enterprise.gui.configuration.resource.ExistingResourceConfigurationUIBean</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> - </managed-bean> --> + </managed-bean> <!-- /rhq/resource/configuration/history.xhtml, /rhq/resource/configuration/edit.xhtml, and - /rhq/resource/configuration/edit-map.xhtml + /rhq/resource/configuration/edit-map.xhtml --> <managed-bean> <managed-bean-name>ExistingResourceConfigurationUIBean</managed-bean-name> <managed-bean-class>org.rhq.enterprise.gui.configuration.resource.ExistingResourceConfigurationUIBean</managed-bean-class> <managed-bean-scope>session</managed-bean-scope> - </managed-bean> --> + </managed-bean>
<!-- /rhq/resource/configuration/add-new-simple.xhtml --> <managed-bean> diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit-raw.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit-raw.xhtml index 4bbb24f..060dfc4 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit-raw.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit-raw.xhtml @@ -35,9 +35,9 @@ <a4j:form id="editResourceConfigurationForm"> <h:outputText value="#{messages.youareviewingraw}" /> - <h:panelGroup rendered="#{rawConfigCollection.structuredSupported}"> + <h:panelGroup rendered="#{ExistingResourceConfigurationUIBean.structuredSupported}"> <h:outputText value=" #{messages.switch2}" /> - <h:commandLink action="#{rawConfigCollection.switchTostructured}"> + <h:commandLink action="#{ExistingResourceConfigurationUIBean.switchTostructured}"> <s:conversationId /> <f:param name="id" value="#{ResourceUIBean.id}" /> <h:outputText value=" #{messages.structured}" /> @@ -53,23 +53,23 @@ <h:panelGroup id="changedFiles" layout="vertical"> - <ui:repeat value="#{rawConfigCollection.paths}" var="path"> + <ui:repeat value="#{ExistingResourceConfigurationUIBean.paths}" var="path"> <div><h:outputText value="*" - rendered="#{rawConfigCollection.isModified(path) }" /> <h:commandLink - value="#{path}" action="#{rawConfigCollection.select(path)}" - rendered="#{path != rawConfigCollection.current.path}"> + rendered="#{ExistingResourceConfigurationUIBean.isModified(path) }" /> <h:commandLink + value="#{path}" action="#{ExistingResourceConfigurationUIBean.select(path)}" + rendered="#{path != ExistingResourceConfigurationUIBean.current.path}"> <f:param name="currentPath" value="#{path}" /> </h:commandLink> <h:outputText value="#{path}" - rendered="#{path == rawConfigCollection.current.path}" /></div> + rendered="#{path == ExistingResourceConfigurationUIBean.current.path}" /></div> </ui:repeat> </h:panelGroup> <div>______________________________________</div> <div>* <h:outputText value="#{messages.uncommitted}" /></div> <h:panelGrid columns="2" styleClass="buttons-table" columnClasses="button-cell"> - <a4j:commandButton action="#{rawConfigCollection.commit}" + <a4j:commandButton action="#{ExistingResourceConfigurationUIBean.commit}" value="#{messages.commit}" reRender="changedFiles" styleClass="buttonmed"/> <a4j:commandButton - action="#{rawConfigCollection.discard}" value="#{messages.discard}" + action="#{ExistingResourceConfigurationUIBean.discard}" value="#{messages.discard}" reRender="changedFiles" styleClass="buttonmed"/> </h:panelGrid> </td> @@ -77,7 +77,7 @@ <div> <h:outputText value="#{messages.currentfile}" /> : <h:outputText - value="#{rawConfigCollection.current.path}" styleClass="outhello" /> + value="#{ExistingResourceConfigurationUIBean.current.path}" styleClass="outhello" /> </div> <h:outputLink value="edit-raw-full.xhtml" action="navigateToFullScreen"> <img src="/images/viewfullscreen.png" /> @@ -96,7 +96,7 @@ </s:link> <div><h:inputTextarea cols="80" rows="40" - value="#{rawConfigCollection.currentContents}" /></div> + value="#{ExistingResourceConfigurationUIBean.currentContents}" /></div> </td> </tr>
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit.xhtml index b28ade4..d067d8a 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit.xhtml @@ -30,9 +30,9 @@ THIS TEXT WILL BE REMOVED.
<h:outputText value="#{messages.youareviewingstructured}" /> - <h:panelGroup rendered="#{rawConfigCollection.rawSupported}" > + <h:panelGroup rendered="#{ExistingResourceConfigurationUIBean.rawSupported}" > <h:outputText value=" #{messages.switch2}" /> - <h:commandLink action="#{rawConfigCollection.switchToraw}" > + <h:commandLink action="#{ExistingResourceConfigurationUIBean.switchToraw}" > <f:param name="conversationId" value="#{conversation.id}"/> <f:param name="id" value="#{ResourceUIBean.id}"/> <h:outputText value=" files mode"/> diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view-raw.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view-raw.xhtml index 65ac139..b0b3002 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view-raw.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view-raw.xhtml @@ -34,7 +34,7 @@ </script> <h:outputText value="#{messages.youareviewingraw}" /> - <h:panelGroup rendered="#{rawConfigCollection.structuredSupported}"> + <h:panelGroup rendered="#{ExistingResourceConfigurationViewUIBean.structuredSupported}"> <h:outputText value=" #{messages.switch2}" /> <h:outputLink value="view.xhtml"> <s:conversationId /> @@ -53,10 +53,10 @@
<h:commandButton value="#{messages.editstructured}" action="#{ExistingResourceConfigurationUIBean.editConfiguration}" title="Edit this Configuration" styleClass="buttonmed" - rendered="${ResourceUIBean.permissions.configure and rawConfigCollection.structuredSupported and !ExistingResourceConfigurationUIBean.updateInProgress}" /> + rendered="${ResourceUIBean.permissions.configure and ExistingResourceConfigurationViewUIBean.structuredSupported and !ExistingResourceConfigurationUIBean.updateInProgress}" /> <h:commandButton value="#{messages.editraw}" action="#{ExistingResourceConfigurationUIBean.editRawConfiguration}" title="Advanced Mode Edit of Raw Configuration Files" styleClass="buttonmed" - rendered="${ResourceUIBean.permissions.configure and rawConfigCollection.rawSupported and !ExistingResourceConfigurationUIBean.updateInProgress}" /> + rendered="${ResourceUIBean.permissions.configure and ExistingResourceConfigurationViewUIBean.rawSupported and !ExistingResourceConfigurationUIBean.updateInProgress}" /> </h:panelGrid> diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java index 36f35c0..caecff7 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java @@ -20,12 +20,12 @@ package org.rhq.enterprise.server.configuration;
import java.util.ArrayList; import java.util.Calendar; +import java.util.Collection; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; -import java.util.Collections; -import java.util.Collection;
import javax.ejb.EJB; import javax.ejb.Stateless; @@ -48,9 +48,9 @@ import org.quartz.JobDetail; import org.quartz.SchedulerException; import org.quartz.Trigger;
-import org.rhq.core.clientapi.agent.configuration.ConfigurationUpdateRequest; -import org.rhq.core.clientapi.agent.configuration.ConfigurationAgentService; import org.rhq.core.clientapi.agent.PluginContainerException; +import org.rhq.core.clientapi.agent.configuration.ConfigurationAgentService; +import org.rhq.core.clientapi.agent.configuration.ConfigurationUpdateRequest; import org.rhq.core.clientapi.server.configuration.ConfigurationUpdateResponse; import org.rhq.core.domain.auth.Subject; import org.rhq.core.domain.authz.Permission; @@ -59,8 +59,8 @@ import org.rhq.core.domain.configuration.Configuration; import org.rhq.core.domain.configuration.ConfigurationUpdateStatus; import org.rhq.core.domain.configuration.PluginConfigurationUpdate; import org.rhq.core.domain.configuration.Property; -import org.rhq.core.domain.configuration.ResourceConfigurationUpdate; import org.rhq.core.domain.configuration.RawConfiguration; +import org.rhq.core.domain.configuration.ResourceConfigurationUpdate; import org.rhq.core.domain.configuration.composite.ConfigurationUpdateComposite; import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; import org.rhq.core.domain.configuration.group.AbstractGroupConfigurationUpdate; @@ -702,7 +702,7 @@ public class ConfigurationManagerBean implements ConfigurationManagerLocal, Conf }
public Configuration getLiveResourceConfiguration(Subject subject, int resourceId, boolean pingAgentFirst, - boolean fromStructured) throws Exception { + boolean fromStructured) throws Exception { Resource resource = entityManager.find(Resource.class, resourceId);
if (resource == null) { @@ -980,6 +980,12 @@ public class ConfigurationManagerBean implements ConfigurationManagerLocal, Conf return; }
+ private void dumpProperties(Configuration configuration) { + for (String key : configuration.getAllProperties().keySet()) { + log.error("key = "); + } + } + @Nullable public ResourceConfigurationUpdate updateResourceConfiguration(Subject subject, int resourceId, @XmlJavaTypeAdapter(ConfigurationAdapter.class) Configuration newConfiguration) @@ -988,7 +994,7 @@ public class ConfigurationManagerBean implements ConfigurationManagerLocal, Conf // (consider synchronizing to avoid the condition where someone calls this method twice quickly // in two different txs which would put two updates in INPROGRESS and cause havoc) ResourceConfigurationUpdate newUpdate; - + dumpProperties(newConfiguration); // here we call ourself, but we do so via the EJB interface so we pick up the REQUIRES_NEW semantics // this can return null if newConfiguration is not actually different. newUpdate = configurationManager.persistNewResourceConfigurationUpdateHistory(subject, resourceId, @@ -1321,8 +1327,7 @@ public class ConfigurationManagerBean implements ConfigurationManagerLocal, Conf * * @return the resource's live configuration or <code>null</code> if it could not be retrieved from the agent */ - private Configuration getLiveResourceConfiguration(Resource resource, boolean pingAgentFirst, - boolean fromStructured) { + private Configuration getLiveResourceConfiguration(Resource resource, boolean pingAgentFirst, boolean fromStructured) { Configuration liveConfig = null;
try { @@ -1355,8 +1360,6 @@ public class ConfigurationManagerBean implements ConfigurationManagerLocal, Conf return liveConfig; }
- - @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) public AbstractResourceConfigurationUpdate mergeConfigurationUpdate( AbstractResourceConfigurationUpdate configurationUpdate) { @@ -1900,11 +1903,10 @@ public class ConfigurationManagerBean implements ConfigurationManagerLocal, Conf ConfigurationAgentService configService = agentClient.getConfigurationAgentService();
return configService.merge(configuration, resourceId, fromStructured); - } - catch (PluginContainerException e) { + } catch (PluginContainerException e) { log.error("An error occurred while trying to translate the configuration.", e); return null; } } - + }
commit f013bcd501ef15a8e5f93790629a44ba6796a741 Author: John Sanda john@localhost.localdomain Date: Mon Nov 30 16:57:00 2009 -0500
[US 6] Adding support for updates of structured config with new ResourceConfigurationFacet
Renaming some classes to be consistent with renamed interface.
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigManagementFactoryImpl.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigManagementFactoryImpl.java index 66aef29..6193fd2 100644 --- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigManagementFactoryImpl.java +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigManagementFactoryImpl.java @@ -64,7 +64,7 @@ public class ConfigManagementFactoryImpl implements ConfigManagementFactory { ResourceType resourceType = componentService.getResourceType(resourceId);
if (isStructured(resourceType)) { - return new LoadStructured(); + return new StructuredConfigManagement(); }
if (isRaw(resourceType)) { @@ -72,7 +72,7 @@ public class ConfigManagementFactoryImpl implements ConfigManagementFactory { }
// else format is both structured and raw - return new LoadStructuredAndRaw(); + return new StructuredAndRawConfigManagement(); }
private boolean isLegacyVersion(String ampsVersion) { diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadStructured.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadStructured.java deleted file mode 100644 index 5e76590..0000000 --- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadStructured.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2008 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, version 2, as - * published by the Free Software Foundation, and/or the GNU Lesser - * General Public License, version 2.1, also as published by the Free - * Software Foundation. - * - * 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 and the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * and the GNU Lesser 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.core.pc.configuration; - -import org.rhq.core.domain.configuration.Configuration; -import org.rhq.core.domain.resource.ResourceType; -import org.rhq.core.clientapi.agent.PluginContainerException; -import org.rhq.core.pluginapi.configuration.ResourceConfigurationFacet; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import java.util.List; - -public class LoadStructured extends ConfigManagementSupport { - - private final Log log = LogFactory.getLog(LoadStructured.class); - - public Configuration execute(int resourceId) throws PluginContainerException { - ResourceConfigurationFacet facet = loadResouceConfiguratonFacet(resourceId); - - Configuration configuration = facet.loadStructuredConfiguration(); - - if (configuration == null) { - return null; - } - - ResourceType resourceType = componentService.getResourceType(resourceId); - - if (configuration.getNotes() == null) { - configuration.setNotes("Resource config for " + resourceType.getName() + " Resource w/ id " + resourceId); - } - - configUtilityService.normalizeConfiguration(configuration, resourceType.getResourceConfigurationDefinition()); - List<String> errorMsgs = configUtilityService.validateConfiguration(configuration, - resourceType.getResourceConfigurationDefinition()); - - logErrorMsgs(errorMsgs, resourceType); - - return configuration; - } - - private void logErrorMsgs(List<String> errorMsgs, ResourceType resourceType) { - for (String errorMessage : errorMsgs) { - log.warn("Plugin Error: Invalid " + resourceType.getName() + " Resource configuration returned by " - + resourceType.getPlugin() + " plugin - " + errorMessage); - } - } - - public void executeUpdate(int resourceId, Configuration configuration) - throws PluginContainerException { - } -} diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadStructuredAndRaw.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadStructuredAndRaw.java deleted file mode 100644 index cbfca94..0000000 --- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadStructuredAndRaw.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2008 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, version 2, as - * published by the Free Software Foundation, and/or the GNU Lesser - * General Public License, version 2.1, also as published by the Free - * Software Foundation. - * - * 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 and the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * and the GNU Lesser 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.core.pc.configuration; - -import static java.util.Collections.EMPTY_SET; - -import org.rhq.core.domain.configuration.Configuration; -import org.rhq.core.domain.configuration.RawConfiguration; -import org.rhq.core.domain.resource.ResourceType; -import org.rhq.core.clientapi.agent.PluginContainerException; -import org.rhq.core.pluginapi.configuration.ResourceConfigurationFacet; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import java.util.List; -import java.util.Set; - -public class LoadStructuredAndRaw extends ConfigManagementSupport { - - private final Log log = LogFactory.getLog(LoadStructuredAndRaw.class); - - public Configuration execute(int resourceId) throws PluginContainerException { - ResourceConfigurationFacet facet = loadResouceConfiguratonFacet(resourceId); - - Configuration configuration = facet.loadStructuredConfiguration(); - Set<RawConfiguration> rawConfigs = facet.loadRawConfigurations(); - - if (configuration == null && rawConfigs == null) { - return null; - } - - if (configuration == null) { - configuration = new Configuration(); - } - - if (rawConfigs == null) { - rawConfigs = EMPTY_SET; - } - - for (RawConfiguration rawConfig : rawConfigs) { - configuration.addRawConfiguration(rawConfig); - } - - ResourceType resourceType = componentService.getResourceType(resourceId); - - if (configuration.getNotes() == null) { - configuration.setNotes("Resource config for " + resourceType.getName() + " Resource w/ id " + resourceId); - } - - configUtilityService.normalizeConfiguration(configuration, resourceType.getResourceConfigurationDefinition()); - List<String> errorMsgs = configUtilityService.validateConfiguration(configuration, - resourceType.getResourceConfigurationDefinition()); - - logErrorMsgs(errorMsgs, resourceType); - - return configuration; - } - - private void logErrorMsgs(List<String> errorMsgs, ResourceType resourceType) { - for (String errorMessage : errorMsgs) { - log.warn("Plugin Error: Invalid " + resourceType.getName() + " Resource configuration returned by " - + resourceType.getPlugin() + " plugin - " + errorMessage); - } - } - - public void executeUpdate(int resourceId, Configuration configuration) - throws PluginContainerException { - } -} diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/StructuredAndRawConfigManagement.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/StructuredAndRawConfigManagement.java new file mode 100644 index 0000000..d8a9ed1 --- /dev/null +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/StructuredAndRawConfigManagement.java @@ -0,0 +1,90 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2008 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, version 2, as + * published by the Free Software Foundation, and/or the GNU Lesser + * General Public License, version 2.1, also as published by the Free + * Software Foundation. + * + * 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 and the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * and the GNU Lesser 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.core.pc.configuration; + +import static java.util.Collections.EMPTY_SET; + +import org.rhq.core.domain.configuration.Configuration; +import org.rhq.core.domain.configuration.RawConfiguration; +import org.rhq.core.domain.resource.ResourceType; +import org.rhq.core.clientapi.agent.PluginContainerException; +import org.rhq.core.pluginapi.configuration.ResourceConfigurationFacet; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.util.List; +import java.util.Set; + +public class StructuredAndRawConfigManagement extends ConfigManagementSupport { + + private final Log log = LogFactory.getLog(StructuredAndRawConfigManagement.class); + + public Configuration execute(int resourceId) throws PluginContainerException { + ResourceConfigurationFacet facet = loadResouceConfiguratonFacet(resourceId); + + Configuration configuration = facet.loadStructuredConfiguration(); + Set<RawConfiguration> rawConfigs = facet.loadRawConfigurations(); + + if (configuration == null && rawConfigs == null) { + return null; + } + + if (configuration == null) { + configuration = new Configuration(); + } + + if (rawConfigs == null) { + rawConfigs = EMPTY_SET; + } + + for (RawConfiguration rawConfig : rawConfigs) { + configuration.addRawConfiguration(rawConfig); + } + + ResourceType resourceType = componentService.getResourceType(resourceId); + + if (configuration.getNotes() == null) { + configuration.setNotes("Resource config for " + resourceType.getName() + " Resource w/ id " + resourceId); + } + + configUtilityService.normalizeConfiguration(configuration, resourceType.getResourceConfigurationDefinition()); + List<String> errorMsgs = configUtilityService.validateConfiguration(configuration, + resourceType.getResourceConfigurationDefinition()); + + logErrorMsgs(errorMsgs, resourceType); + + return configuration; + } + + private void logErrorMsgs(List<String> errorMsgs, ResourceType resourceType) { + for (String errorMessage : errorMsgs) { + log.warn("Plugin Error: Invalid " + resourceType.getName() + " Resource configuration returned by " + + resourceType.getPlugin() + " plugin - " + errorMessage); + } + } + + public void executeUpdate(int resourceId, Configuration configuration) + throws PluginContainerException { + } +} diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/StructuredConfigManagement.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/StructuredConfigManagement.java new file mode 100644 index 0000000..7a04d04 --- /dev/null +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/StructuredConfigManagement.java @@ -0,0 +1,75 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2008 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, version 2, as + * published by the Free Software Foundation, and/or the GNU Lesser + * General Public License, version 2.1, also as published by the Free + * Software Foundation. + * + * 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 and the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * and the GNU Lesser 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.core.pc.configuration; + +import org.rhq.core.domain.configuration.Configuration; +import org.rhq.core.domain.resource.ResourceType; +import org.rhq.core.clientapi.agent.PluginContainerException; +import org.rhq.core.pluginapi.configuration.ResourceConfigurationFacet; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.util.List; + +public class StructuredConfigManagement extends ConfigManagementSupport { + + private final Log log = LogFactory.getLog(StructuredConfigManagement.class); + + public Configuration execute(int resourceId) throws PluginContainerException { + ResourceConfigurationFacet facet = loadResouceConfiguratonFacet(resourceId); + + Configuration configuration = facet.loadStructuredConfiguration(); + + if (configuration == null) { + return null; + } + + ResourceType resourceType = componentService.getResourceType(resourceId); + + if (configuration.getNotes() == null) { + configuration.setNotes("Resource config for " + resourceType.getName() + " Resource w/ id " + resourceId); + } + + configUtilityService.normalizeConfiguration(configuration, resourceType.getResourceConfigurationDefinition()); + List<String> errorMsgs = configUtilityService.validateConfiguration(configuration, + resourceType.getResourceConfigurationDefinition()); + + logErrorMsgs(errorMsgs, resourceType); + + return configuration; + } + + private void logErrorMsgs(List<String> errorMsgs, ResourceType resourceType) { + for (String errorMessage : errorMsgs) { + log.warn("Plugin Error: Invalid " + resourceType.getName() + " Resource configuration returned by " + + resourceType.getPlugin() + " plugin - " + errorMessage); + } + } + + public void executeUpdate(int resourceId, Configuration configuration) throws PluginContainerException { + ResourceConfigurationFacet facet = loadResourceConfigFacetWithWriteLock(resourceId); + + facet.persistStructuredConfiguration(configuration); + } +} diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigManagementFactoryImplTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigManagementFactoryImplTest.java index 8ea73cf..4e58e9c 100644 --- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigManagementFactoryImplTest.java +++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigManagementFactoryImplTest.java @@ -103,8 +103,8 @@ public class ConfigManagementFactoryImplTest extends JMockTest { ConfigManagement loadConfig = factory.getStrategy(resourceId);
assertTrue( - loadConfig instanceof LoadStructured, - "Expected to get an instance of " + LoadStructured.class.getSimpleName() + + loadConfig instanceof StructuredConfigManagement, + "Expected to get an instance of " + StructuredConfigManagement.class.getSimpleName() + "when resource is from a plugin having an ampsversion >= " + NON_LEGACY_AMPS_VERSION + " and the resource " + "configuration format is structured." ); @@ -197,8 +197,8 @@ public class ConfigManagementFactoryImplTest extends JMockTest { ConfigManagement loadConfig = factory.getStrategy(resourceId);
assertTrue( - loadConfig instanceof LoadStructuredAndRaw, - "Expected to get an instance of" + LoadStructuredAndRaw.class.getSimpleName() + + loadConfig instanceof StructuredAndRawConfigManagement, + "Expected to get an instance of" + StructuredAndRawConfigManagement.class.getSimpleName() + " when resource is from a plugin having an ampsVersion >= " + NON_LEGACY_AMPS_VERSION + " and the " + "resource configuration format is both (structured and raw)." ); diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadStructuredAndRawTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadStructuredAndRawTest.java deleted file mode 100644 index e275f82..0000000 --- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadStructuredAndRawTest.java +++ /dev/null @@ -1,191 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2008 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, version 2, as - * published by the Free Software Foundation, and/or the GNU Lesser - * General Public License, version 2.1, also as published by the Free - * Software Foundation. - * - * 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 and the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * and the GNU Lesser 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.core.pc.configuration; - -import static org.testng.Assert.*; -import static java.util.Collections.*; - -import org.rhq.core.pc.util.ComponentService; -import org.rhq.core.pc.util.FacetLockType; -import org.rhq.core.pluginapi.configuration.ResourceConfigurationFacet; -import org.rhq.core.domain.configuration.Configuration; -import org.rhq.core.domain.configuration.RawConfiguration; -import org.rhq.core.domain.configuration.PropertySimple; -import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; -import org.rhq.core.domain.resource.ResourceType; -import org.testng.annotations.BeforeMethod; -import org.testng.annotations.Test; -import org.jmock.Expectations; - -import java.util.Set; - -public class LoadStructuredAndRawTest extends ConfigManagementTest { - - ComponentService componentService; - - ConfigurationUtilityService configUtilityService; - - ResourceConfigurationFacet configFacet; - - LoadStructuredAndRaw loadStructuredAndRaw; - - @BeforeMethod - public void setup() { - resourceType = new ResourceType(); - resourceType.setResourceConfigurationDefinition(new ConfigurationDefinition("", "")); - - componentService = context.mock(ComponentService.class); - configUtilityService = context.mock(ConfigurationUtilityService.class); - - configFacet = context.mock(ResourceConfigurationFacet.class); - - loadStructuredAndRaw = new LoadStructuredAndRaw(); - loadStructuredAndRaw.setComponentService(componentService); - loadStructuredAndRaw.setConfigurationUtilityService(configUtilityService); - } - - @Test - public void rawConfigshouldGetLoaded() throws Exception { - Configuration config = new Configuration(); - - Set<RawConfiguration> rawConfigs = toSet( - createRawConfiguration("/tmp/foo.txt"), - createRawConfiguration("/tmp/bar.txt") - ); - - - addDefaultExpectations(config, rawConfigs); - - Configuration loadedConfig = loadStructuredAndRaw.execute(resourceId); - - assertRawsLoaded(rawConfigs, loadedConfig); - } - - @Test - public void structuredConfigShouldGetLoaded() throws Exception { - Configuration config = new Configuration(); - config.put(new PropertySimple("x", "1")); - config.put(new PropertySimple("y", "2")); - - addDefaultExpectations(config, EMPTY_SET); - - Configuration loadedConfig = loadStructuredAndRaw.execute(resourceId); - - assertStructuredLoaded(config, loadedConfig); - } - - @Test - public void theConfigNotesShouldGetSet() throws Exception { - Configuration config = new Configuration(); - config.setNotes(null); - - addDefaultExpectations(config, EMPTY_SET); - - Configuration loadedConfig = loadStructuredAndRaw.execute(resourceId); - - assertNotesSetToDefault(loadedConfig); - } - - @Test - public void nullStructuredShouldBeIgnored() throws Exception { - Configuration config = null; - - Set<RawConfiguration> rawConfigs = toSet(createRawConfiguration("/tmp/foo.txt")); - - addDefaultExpectations(config, rawConfigs); - - Configuration loadedConfig = loadStructuredAndRaw.execute(resourceId); - - Configuration emptyStructured = new Configuration(); - - assertRawsLoaded(rawConfigs, loadedConfig); - assertStructuredLoaded(emptyStructured, loadedConfig); - } - - @Test - public void nullRawsShouldBeIgnored() throws Exception { - Configuration config = new Configuration(); - config.put(new PropertySimple("x", "1")); - config.put(new PropertySimple("y", "2")); - - Set<RawConfiguration> rawConfigs = null; - - addDefaultExpectations(config, rawConfigs); - - Configuration loadedConfig = loadStructuredAndRaw.execute(resourceId); - - assertRawsLoaded(EMPTY_SET, loadedConfig); - assertStructuredLoaded(config, loadedConfig); - } - - @Test - public void nullShouldBeReturnedWhenStructuredAndRawAreNull() throws Exception { - context.checking(new Expectations() {{ - atLeast(1).of(componentService).getComponent(resourceId, - ResourceConfigurationFacet.class, - FacetLockType.READ, - ConfigManagement.FACET_METHOD_TIMEOUT, - daemonThread, - onlyIfStarted); - will(returnValue(configFacet)); - - allowing(componentService).getResourceType(resourceId); will(returnValue(resourceType)); - - oneOf(configFacet).loadStructuredConfiguration(); will(returnValue(null)); - - oneOf(configFacet).loadRawConfigurations(); will(returnValue(null)); - }}); - - Configuration loadedConfig = loadStructuredAndRaw.execute(resourceId); - - assertNull(loadedConfig, "Expected null to be returned when facet returns null for both structured and raw."); - } - - private void addDefaultExpectations(final Configuration config, final Set<RawConfiguration> rawConfigs) - throws Exception { - - context.checking(new Expectations() {{ - atLeast(1).of(componentService).getComponent(resourceId, - ResourceConfigurationFacet.class, - FacetLockType.READ, - ConfigManagement.FACET_METHOD_TIMEOUT, - daemonThread, - onlyIfStarted); - will(returnValue(configFacet)); - - allowing(componentService).getResourceType(resourceId); will(returnValue(resourceType)); - - oneOf(configFacet).loadStructuredConfiguration(); will(returnValue(config)); - - oneOf(configFacet).loadRawConfigurations(); will(returnValue(rawConfigs)); - - atLeast(1).of(configUtilityService).normalizeConfiguration(with(any(Configuration.class)), - with(getResourceConfigDefinition())); - - atLeast(1).of(configUtilityService).validateConfiguration(with(any(Configuration.class)), - with(getResourceConfigDefinition())); - }}); - } - -} diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadStructuredTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadStructuredTest.java deleted file mode 100644 index 3941afd..0000000 --- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadStructuredTest.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2008 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, version 2, as - * published by the Free Software Foundation, and/or the GNU Lesser - * General Public License, version 2.1, also as published by the Free - * Software Foundation. - * - * 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 and the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * and the GNU Lesser 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.core.pc.configuration; - -import org.jmock.Expectations; -import org.rhq.core.domain.configuration.Configuration; -import org.rhq.core.domain.configuration.PropertySimple; -import org.rhq.core.pc.util.ComponentService; -import org.rhq.core.pc.util.FacetLockType; -import org.rhq.core.pluginapi.configuration.ResourceConfigurationFacet; -import static org.testng.Assert.assertNull; -import org.testng.annotations.BeforeMethod; -import org.testng.annotations.Test; - -public class LoadStructuredTest extends ConfigManagementTest { - - ComponentService componentService; - - ConfigurationUtilityService configUtilityService; - - ResourceConfigurationFacet configFacet; - - LoadStructured loadStructured; - - @BeforeMethod - public void setup() { - componentService = context.mock(ComponentService.class); - configUtilityService = context.mock(ConfigurationUtilityService.class); - - configFacet = context.mock(ResourceConfigurationFacet.class); - - loadStructured = new LoadStructured(); - loadStructured.setComponentService(componentService); - loadStructured.setConfigurationUtilityService(configUtilityService); - } - - @Test - public void structuredConfigShouldGetLoaded() throws Exception { - Configuration config = new Configuration(); - config.put(new PropertySimple("x", "1")); - config.put(new PropertySimple("y", "2")); - - addDefaultExpectations(config); - - Configuration loadedConfig = loadStructured.execute(resourceId); - - assertStructuredLoaded(config, loadedConfig); - } - - @Test - public void theConfigNotesShouldGetSet() throws Exception { - final Configuration config = new Configuration(); - config.setNotes(null); - - addDefaultExpectations(config); - - Configuration loadedConfig = loadStructured.execute(resourceId); - - assertNotesSetToDefault(loadedConfig); - } - - @Test - public void nullShouldBeReturnedWhenStructuredIsNull() throws Exception { - final Configuration config = null; - - context.checking(new Expectations() {{ - atLeast(1).of(componentService).getComponent(resourceId, - ResourceConfigurationFacet.class, - FacetLockType.READ, - ConfigManagement.FACET_METHOD_TIMEOUT, - daemonThread, - onlyIfStarted); - will(returnValue(configFacet)); - - allowing(componentService).getResourceType(resourceId); will(returnValue(resourceType)); - - atLeast(1).of(configFacet).loadStructuredConfiguration(); will(returnValue(null)); - }}); - - Configuration loadedConfig = loadStructured.execute(resourceId); - - assertNull(loadedConfig, "Expected null to be returned when facet returns null for structured."); - } - - private void addDefaultExpectations(final Configuration config) throws Exception { - context.checking(new Expectations() {{ - atLeast(1).of(componentService).getComponent(resourceId, - ResourceConfigurationFacet.class, - FacetLockType.READ, - ConfigManagement.FACET_METHOD_TIMEOUT, - daemonThread, - onlyIfStarted); - will(returnValue(configFacet)); - - allowing(componentService).getResourceType(resourceId); will(returnValue(resourceType)); - - atLeast(1).of(configFacet).loadStructuredConfiguration(); will(returnValue(config)); - - atLeast(1).of(configUtilityService).normalizeConfiguration(config, getResourceConfigDefinition()); - - atLeast(1).of(configUtilityService).validateConfiguration(config, getResourceConfigDefinition()); - }}); - } - -} diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/StructuredAndRawConfigManagementTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/StructuredAndRawConfigManagementTest.java new file mode 100644 index 0000000..7dbc1b6 --- /dev/null +++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/StructuredAndRawConfigManagementTest.java @@ -0,0 +1,191 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2008 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, version 2, as + * published by the Free Software Foundation, and/or the GNU Lesser + * General Public License, version 2.1, also as published by the Free + * Software Foundation. + * + * 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 and the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * and the GNU Lesser 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.core.pc.configuration; + +import static org.testng.Assert.*; +import static java.util.Collections.*; + +import org.rhq.core.pc.util.ComponentService; +import org.rhq.core.pc.util.FacetLockType; +import org.rhq.core.pluginapi.configuration.ResourceConfigurationFacet; +import org.rhq.core.domain.configuration.Configuration; +import org.rhq.core.domain.configuration.RawConfiguration; +import org.rhq.core.domain.configuration.PropertySimple; +import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; +import org.rhq.core.domain.resource.ResourceType; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; +import org.jmock.Expectations; + +import java.util.Set; + +public class StructuredAndRawConfigManagementTest extends ConfigManagementTest { + + ComponentService componentService; + + ConfigurationUtilityService configUtilityService; + + ResourceConfigurationFacet configFacet; + + StructuredAndRawConfigManagement structuredAndRawConfigManagement; + + @BeforeMethod + public void setup() { + resourceType = new ResourceType(); + resourceType.setResourceConfigurationDefinition(new ConfigurationDefinition("", "")); + + componentService = context.mock(ComponentService.class); + configUtilityService = context.mock(ConfigurationUtilityService.class); + + configFacet = context.mock(ResourceConfigurationFacet.class); + + structuredAndRawConfigManagement = new StructuredAndRawConfigManagement(); + structuredAndRawConfigManagement.setComponentService(componentService); + structuredAndRawConfigManagement.setConfigurationUtilityService(configUtilityService); + } + + @Test + public void rawConfigshouldGetLoaded() throws Exception { + Configuration config = new Configuration(); + + Set<RawConfiguration> rawConfigs = toSet( + createRawConfiguration("/tmp/foo.txt"), + createRawConfiguration("/tmp/bar.txt") + ); + + + addDefaultExpectations(config, rawConfigs); + + Configuration loadedConfig = structuredAndRawConfigManagement.execute(resourceId); + + assertRawsLoaded(rawConfigs, loadedConfig); + } + + @Test + public void structuredConfigShouldGetLoaded() throws Exception { + Configuration config = new Configuration(); + config.put(new PropertySimple("x", "1")); + config.put(new PropertySimple("y", "2")); + + addDefaultExpectations(config, EMPTY_SET); + + Configuration loadedConfig = structuredAndRawConfigManagement.execute(resourceId); + + assertStructuredLoaded(config, loadedConfig); + } + + @Test + public void theConfigNotesShouldGetSet() throws Exception { + Configuration config = new Configuration(); + config.setNotes(null); + + addDefaultExpectations(config, EMPTY_SET); + + Configuration loadedConfig = structuredAndRawConfigManagement.execute(resourceId); + + assertNotesSetToDefault(loadedConfig); + } + + @Test + public void nullStructuredShouldBeIgnored() throws Exception { + Configuration config = null; + + Set<RawConfiguration> rawConfigs = toSet(createRawConfiguration("/tmp/foo.txt")); + + addDefaultExpectations(config, rawConfigs); + + Configuration loadedConfig = structuredAndRawConfigManagement.execute(resourceId); + + Configuration emptyStructured = new Configuration(); + + assertRawsLoaded(rawConfigs, loadedConfig); + assertStructuredLoaded(emptyStructured, loadedConfig); + } + + @Test + public void nullRawsShouldBeIgnored() throws Exception { + Configuration config = new Configuration(); + config.put(new PropertySimple("x", "1")); + config.put(new PropertySimple("y", "2")); + + Set<RawConfiguration> rawConfigs = null; + + addDefaultExpectations(config, rawConfigs); + + Configuration loadedConfig = structuredAndRawConfigManagement.execute(resourceId); + + assertRawsLoaded(EMPTY_SET, loadedConfig); + assertStructuredLoaded(config, loadedConfig); + } + + @Test + public void nullShouldBeReturnedWhenStructuredAndRawAreNull() throws Exception { + context.checking(new Expectations() {{ + atLeast(1).of(componentService).getComponent(resourceId, + ResourceConfigurationFacet.class, + FacetLockType.READ, + ConfigManagement.FACET_METHOD_TIMEOUT, + daemonThread, + onlyIfStarted); + will(returnValue(configFacet)); + + allowing(componentService).getResourceType(resourceId); will(returnValue(resourceType)); + + oneOf(configFacet).loadStructuredConfiguration(); will(returnValue(null)); + + oneOf(configFacet).loadRawConfigurations(); will(returnValue(null)); + }}); + + Configuration loadedConfig = structuredAndRawConfigManagement.execute(resourceId); + + assertNull(loadedConfig, "Expected null to be returned when facet returns null for both structured and raw."); + } + + private void addDefaultExpectations(final Configuration config, final Set<RawConfiguration> rawConfigs) + throws Exception { + + context.checking(new Expectations() {{ + atLeast(1).of(componentService).getComponent(resourceId, + ResourceConfigurationFacet.class, + FacetLockType.READ, + ConfigManagement.FACET_METHOD_TIMEOUT, + daemonThread, + onlyIfStarted); + will(returnValue(configFacet)); + + allowing(componentService).getResourceType(resourceId); will(returnValue(resourceType)); + + oneOf(configFacet).loadStructuredConfiguration(); will(returnValue(config)); + + oneOf(configFacet).loadRawConfigurations(); will(returnValue(rawConfigs)); + + atLeast(1).of(configUtilityService).normalizeConfiguration(with(any(Configuration.class)), + with(getResourceConfigDefinition())); + + atLeast(1).of(configUtilityService).validateConfiguration(with(any(Configuration.class)), + with(getResourceConfigDefinition())); + }}); + } + +} diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/StructuredConfigManagementTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/StructuredConfigManagementTest.java new file mode 100644 index 0000000..cac0ca4 --- /dev/null +++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/StructuredConfigManagementTest.java @@ -0,0 +1,147 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2008 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, version 2, as + * published by the Free Software Foundation, and/or the GNU Lesser + * General Public License, version 2.1, also as published by the Free + * Software Foundation. + * + * 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 and the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * and the GNU Lesser 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.core.pc.configuration; + +import org.jmock.Expectations; +import org.rhq.core.domain.configuration.Configuration; +import org.rhq.core.domain.configuration.PropertySimple; +import org.rhq.core.pc.util.ComponentService; +import org.rhq.core.pc.util.FacetLockType; +import org.rhq.core.pluginapi.configuration.ResourceConfigurationFacet; +import static org.testng.Assert.assertNull; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +public class StructuredConfigManagementTest extends ConfigManagementTest { + + ComponentService componentService; + + ConfigurationUtilityService configUtilityService; + + ResourceConfigurationFacet configFacet; + + StructuredConfigManagement structuredMgmt; + + @BeforeMethod + public void setup() { + componentService = context.mock(ComponentService.class); + configUtilityService = context.mock(ConfigurationUtilityService.class); + + configFacet = context.mock(ResourceConfigurationFacet.class); + + structuredMgmt = new StructuredConfigManagement(); + structuredMgmt.setComponentService(componentService); + structuredMgmt.setConfigurationUtilityService(configUtilityService); + } + + @Test + public void structuredConfigShouldGetLoaded() throws Exception { + Configuration config = new Configuration(); + config.put(new PropertySimple("x", "1")); + config.put(new PropertySimple("y", "2")); + + addDefaultExpectationsForLoad(config); + + Configuration loadedConfig = structuredMgmt.execute(resourceId); + + assertStructuredLoaded(config, loadedConfig); + } + + @Test + public void theConfigNotesShouldGetSet() throws Exception { + final Configuration config = new Configuration(); + config.setNotes(null); + + addDefaultExpectationsForLoad(config); + + Configuration loadedConfig = structuredMgmt.execute(resourceId); + + assertNotesSetToDefault(loadedConfig); + } + + @Test + public void nullShouldBeReturnedWhenStructuredIsNull() throws Exception { + final Configuration config = null; + + context.checking(new Expectations() {{ + atLeast(1).of(componentService).getComponent(resourceId, + ResourceConfigurationFacet.class, + FacetLockType.READ, + ConfigManagement.FACET_METHOD_TIMEOUT, + daemonThread, + onlyIfStarted); + will(returnValue(configFacet)); + + allowing(componentService).getResourceType(resourceId); will(returnValue(resourceType)); + + atLeast(1).of(configFacet).loadStructuredConfiguration(); will(returnValue(null)); + }}); + + Configuration loadedConfig = structuredMgmt.execute(resourceId); + + assertNull(loadedConfig, "Expected null to be returned when facet returns null for structured."); + } + + private void addDefaultExpectationsForLoad(final Configuration config) throws Exception { + context.checking(new Expectations() {{ + atLeast(1).of(componentService).getComponent(resourceId, + ResourceConfigurationFacet.class, + FacetLockType.READ, + ConfigManagement.FACET_METHOD_TIMEOUT, + daemonThread, + onlyIfStarted); + will(returnValue(configFacet)); + + allowing(componentService).getResourceType(resourceId); will(returnValue(resourceType)); + + atLeast(1).of(configFacet).loadStructuredConfiguration(); will(returnValue(config)); + + atLeast(1).of(configUtilityService).normalizeConfiguration(config, getResourceConfigDefinition()); + + atLeast(1).of(configUtilityService).validateConfiguration(config, getResourceConfigDefinition()); + }}); + } + + @Test + public void facetShouldBeCalledToUpdateStructured() throws Exception { + final Configuration structuredConfig = new Configuration(); + + final boolean isDaemonThread = false; + + context.checking(new Expectations() {{ + atLeast(1).of(componentService).getComponent(resourceId, + ResourceConfigurationFacet.class, + FacetLockType.WRITE, + ConfigManagement.FACET_METHOD_TIMEOUT, + isDaemonThread, + onlyIfStarted); + will(returnValue(configFacet)); + + atLeast(1).of(configFacet).persistStructuredConfiguration(structuredConfig); + }}); + + structuredMgmt.executeUpdate(resourceId, structuredConfig); + } + +}
commit 9e269d8ce6dc397d83bb3836748f23fca49a58e0 Merge: 2f7c427... 8bdcdaf... Author: John Sanda john@localhost.localdomain Date: Mon Nov 30 16:25:51 2009 -0500
Merge branch 'raw-config' of ssh://git.fedorahosted.org/git/rhq/rhq into raw-config
commit 2f7c42750ea87ff28fbb86adf36f3ed6315839ee Author: John Sanda john@localhost.localdomain Date: Mon Nov 30 16:23:07 2009 -0500
[US 910] Refactoring testGetAndUpdateRawConfiguration() to eliminate some duplicate code
diff --git a/modules/enterprise/remoting/scripts/src/test/script/org/rhq/enterprise/remoting/cli/test_ConfigurationManager.js b/modules/enterprise/remoting/scripts/src/test/script/org/rhq/enterprise/remoting/cli/test_ConfigurationManager.js index f70682d..ed964ef 100644 --- a/modules/enterprise/remoting/scripts/src/test/script/org/rhq/enterprise/remoting/cli/test_ConfigurationManager.js +++ b/modules/enterprise/remoting/scripts/src/test/script/org/rhq/enterprise/remoting/cli/test_ConfigurationManager.js @@ -60,21 +60,8 @@ function testGetAndUpdateRawConfiguration() {
Assert.assertNotNull(rawServer, "Failed to find '" + resourceName + "'");
- var latestUpdate = ConfigurationManager.getLatestResourceConfigurationUpdate(rawServer.id); - - Assert.assertNotNull(latestUpdate, "Failed to find latest resource configuration update for '" + resourceName + "'"); - Assert.assertTrue( - latestUpdate.configuration.rawConfigurations.size() > 0, - "Expected to find at least one raw config file for '" + "'" - ); - - var rawConfigs = java.util.LinkedList(latestUpdate.configuration.rawConfigurations); - var rawConfig = rawConfigs.get(0); - - Assert.assertTrue( - rawConfig.contents.length > 0, - "Contents of raw config file for '" + resourceName + "' should not be empty." - ); + var latestUpdate = loadLatestResourceConfigurationUpdate(resourceName, rawServer.id); + var rawConfig = getRawConfig(resourceName, latestUpdate.configuration, 0);
var contents = java.lang.String(rawConfig.contents); var modifiedContents = java.lang.StringBuilder(contents).append("\nModified at ").append(getDate()).toString(); @@ -83,16 +70,9 @@ function testGetAndUpdateRawConfiguration() {
var configUdpate = ConfigurationManager.updateResourceConfiguration(rawServer.id, latestUpdate.configuration);
- while (ConfigurationManager.isResourceConfigurationUpdateInProgress(rawServer.id)) { - java.lang.Thread.sleep(1000); - } + waitForResourceConfigUpdateToComplete(rawServer.id);
- latestUpdate = ConfigurationManager.getLatestResourceConfigurationUpdate(rawServer.id); - Assert.assertNotNull(latestUpdate, "Failed to find latest resource configuration update for '" + resourceName + "'"); - Assert.assertTrue( - latestUpdate.configuration.rawConfigurations.size() > 0, - "Expected to find at least one raw config file for '" + "'" - ); + latestUpdate = loadLatestResourceConfigurationUpdate(resourceName, rawServer.id);
rawConfigs = java.util.LinkedList(latestUpdate.configuration.rawConfigurations); rawConfig = rawConfigs.get(0); @@ -105,11 +85,41 @@ function testGetAndUpdateRawConfiguration() { ); }
+function loadLatestResourceConfigurationUpdate(resourceName, resourceId) { + var latestUpdate = ConfigurationManager.getLatestResourceConfigurationUpdate(resourceId); + + Assert.assertNotNull(latestUpdate, "Failed to find latest resource configuration update for '" + resourceName + "'"); + Assert.assertTrue( + latestUpdate.configuration.rawConfigurations.size() > 0, + "Expected to find at least one raw config file for '" + "'" + ); + + return latestUpdate; +} + +function getRawConfig(resourceName, configuration, index) { + var rawConfigs = java.util.LinkedList(configuration.rawConfigurations); + var rawConfig = rawConfigs.get(index); + + Assert.assertTrue( + rawConfig.contents.length > 0, + "Contents of raw config file for '" + resourceName + "' should not be empty." + ); + + return rawConfig; +} + function getDate() { var format = java.text.DateFormat.getDateInstance(); return format.format(java.util.Date()); }
+function waitForResourceConfigUpdateToComplete(resourceId) { + while (ConfigurationManager.isResourceConfigurationUpdateInProgress(resourceId)) { + java.lang.Thread.sleep(1000); + } +} + //function testUpdatePluginConfiguration() { // var resource = findService('service-beta-0', 'server-omega-0'); // var pluginConfig = ConfigurationManager.getPluginConfiguration(resource.id);
commit 591b1f7c41600eeed97f5e307fb426fc1904cc69 Author: Justin Harris jharris@redhat.com Date: Mon Nov 30 16:22:06 2009 -0500
Cleaning out editing of server plugins on details page.
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/InstalledPluginComponent.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/InstalledPluginComponent.java index a1400ac..43e9e41 100644 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/InstalledPluginComponent.java +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/InstalledPluginComponent.java @@ -18,7 +18,6 @@ */ package org.rhq.enterprise.gui.admin.plugin;
-import org.jboss.seam.ScopeType; import org.jboss.seam.annotations.Factory; import org.jboss.seam.annotations.Name; import org.jboss.seam.annotations.web.RequestParameter; @@ -71,7 +70,7 @@ public class InstalledPluginComponent { this.pluginType = pluginType; }
- @Factory(value = "plugin", autoCreate = true, scope = ScopeType.PAGE) + @Factory(value = "plugin", autoCreate = true) public AbstractPlugin lookupPlugin() { if (this.deployment == PluginDeploymentType.AGENT) { return LookupUtil.getResourceMetadataManager().getPlugin(this.name); diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/InstalledPluginUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/InstalledPluginUIBean.java deleted file mode 100644 index 9351385..0000000 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/InstalledPluginUIBean.java +++ /dev/null @@ -1,142 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2008 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.gui.admin.plugin; - -import javax.faces.application.FacesMessage; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.jboss.seam.ScopeType; -import org.jboss.seam.annotations.Create; -import org.jboss.seam.annotations.In; -import org.jboss.seam.annotations.Name; -import org.jboss.seam.annotations.Scope; - -import org.rhq.core.clientapi.agent.metadata.ConfigurationMetadataParser; -import org.rhq.core.domain.auth.Subject; -import org.rhq.core.domain.authz.Permission; -import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; -import org.rhq.core.domain.plugin.AbstractPlugin; -import org.rhq.core.domain.plugin.PluginDeploymentType; -import org.rhq.core.domain.plugin.PluginKey; -import org.rhq.core.domain.plugin.ServerPlugin; -import org.rhq.core.gui.util.FacesContextUtility; -import org.rhq.enterprise.gui.util.EnterpriseFacesContextUtility; -import org.rhq.enterprise.server.authz.PermissionException; -import org.rhq.enterprise.server.plugin.ServerPluginsLocal; -import org.rhq.enterprise.server.util.LookupUtil; -import org.rhq.enterprise.server.xmlschema.generated.serverplugin.ServerPluginDescriptorType; - -/** - * @author Greg Hinkle - * @author John Mazzitelli - */ -@Scope(ScopeType.PAGE) -@Name("InstalledPluginUIBean") -public class InstalledPluginUIBean { - - private static final String OUTCOME_SUCCESS_SERVER_PLUGIN = "successServerPlugin"; - public static final String MANAGED_BEAN_NAME = InstalledPluginUIBean.class.getSimpleName(); - private final Log log = LogFactory.getLog(InstalledPluginUIBean.class); - @In - private AbstractPlugin plugin; - private ConfigurationDefinition pluginConfigurationDefinition; - private ConfigurationDefinition scheduledJobsDefinition; - - public AbstractPlugin getPlugin() { - return plugin; - } - - public void setPlugin(AbstractPlugin plugin) { - this.plugin = plugin; - } - - public ServerPlugin getServerPlugin() { - return (ServerPlugin) this.plugin; - } - - public void setServerPlugin(ServerPlugin plugin) { - this.plugin = plugin; - } - - public ConfigurationDefinition getPluginConfigurationDefinition() { - return this.pluginConfigurationDefinition; - } - - public ConfigurationDefinition getScheduledJobsDefinition() { - return this.scheduledJobsDefinition; - } - - public boolean isEditable() { - return this.pluginConfigurationDefinition != null || this.scheduledJobsDefinition != null; - } - - public String updatePlugin() { - // note we assume we are editing a server plugin - we don't support editing agent plugins yet - try { - ServerPluginsLocal serverPlugins = LookupUtil.getServerPlugins(); - Subject subject = EnterpriseFacesContextUtility.getSubject(); - serverPlugins.updateServerPluginExceptContent(subject, getServerPlugin()); - FacesContextUtility.addMessage(FacesMessage.SEVERITY_INFO, "Configuration settings saved."); - - return OUTCOME_SUCCESS_SERVER_PLUGIN; - } catch (Exception e) { - log.error("Error updating the plugin configurations.", e); - FacesContextUtility.addMessage(FacesMessage.SEVERITY_ERROR, - "There was an error changing the configuration settings.", e); - - return null; - } - } - - @Create - public void lookupConfigDefinitions() { - hasPermission(); - String pluginName = this.plugin.getName(); - - if (this.plugin.getDeployment() == PluginDeploymentType.SERVER) { - try { - ServerPluginsLocal serverPluginsBean = LookupUtil.getServerPlugins(); - PluginKey pluginKey = new PluginKey((ServerPlugin) plugin); - ServerPluginDescriptorType descriptor = serverPluginsBean.getServerPluginDescriptor(pluginKey); - this.pluginConfigurationDefinition = ConfigurationMetadataParser.parse("pc:" + pluginName, descriptor - .getPluginConfiguration()); - this.scheduledJobsDefinition = ConfigurationMetadataParser.parse("jobs:" + pluginName, descriptor - .getScheduledJobs()); - } catch (Exception e) { - String err = "Cannot determine what the plugin configuration or scheduled jobs configuration looks like"; - log.error(err + " - Cause: " + e); - FacesContextUtility.addMessage(FacesMessage.SEVERITY_ERROR, err, e); - return; - } - } - } - - /** - * Throws a permission exception if the user is not allowed to access this functionality. - */ - private void hasPermission() { - Subject subject = EnterpriseFacesContextUtility.getSubject(); - if (!LookupUtil.getAuthorizationManager().hasGlobalPermission(subject, Permission.MANAGE_SETTINGS)) { - throw new PermissionException("User [" + subject.getName() - + "] does not have the proper permissions to view or manage plugins"); - } - } -} diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-details-edit.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-details-edit.xhtml deleted file mode 100644 index d88afe7..0000000 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-details-edit.xhtml +++ /dev/null @@ -1,24 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> - -<html xmlns="http://www.w3.org/1999/xhtml" - xmlns:h="http://java.sun.com/jsf/html" - xmlns:f="http://java.sun.com/jsf/core" - xmlns:ui="http://java.sun.com/jsf/facelets" - xmlns:c="http://java.sun.com/jstl/core" - xmlns:onc="http://jboss.org/on/component" - xmlns:rich="http://richfaces.ajax4jsf.org/rich%22%3E - -<ui:composition template="/rhq/admin/plugin/plugin-details.xhtml"> - <ui:param name="editMode" value="true"/> - - <ui:define name="post-config"> - <rich:panel rendered="#{InstalledPluginUIBean.editable}"> - <h:commandButton value="SAVE" type="submit" action="#{InstalledPluginUIBean.updatePlugin}" - alt="Click to Save Changes" styleClass="buttonmed" /> - <h:commandButton value="RESET" type="reset" immediate="true" - title="Click to Reset Fields" styleClass="buttonmed"/> - </rich:panel> - </ui:define> -</ui:composition> - -</html> \ No newline at end of file diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-details-view.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-details-view.xhtml deleted file mode 100644 index 92d36f3..0000000 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-details-view.xhtml +++ /dev/null @@ -1,28 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> - -<html xmlns="http://www.w3.org/1999/xhtml" - xmlns:h="http://java.sun.com/jsf/html" - xmlns:f="http://java.sun.com/jsf/core" - xmlns:ui="http://java.sun.com/jsf/facelets" - xmlns:c="http://java.sun.com/jstl/core" - xmlns:onc="http://jboss.org/on/component" - xmlns:rich="http://richfaces.ajax4jsf.org/rich%22%3E - -<ui:composition template="/rhq/admin/plugin/plugin-details.xhtml"> - <ui:param name="editMode" value="false"/> - - <ui:define name="pre-config"> - <h:panelGrid columns="1" styleClass="buttons-table" columnClasses="button-cell" - rendered="#{InstalledPluginUIBean.editable}"> - <h:outputLink value="/rhq/admin/plugin/plugin-details-edit.xhtml" - styleClass="buttonmed"> - <f:param name="plugin" value="#{installedPlugin.name}"/> - <f:param name="deployment" value="#{installedPlugin.deployment}"/> - <f:param name="pluginType" value="#{installedPlugin.pluginType}"/> - <h:outputText value="EDIT"/> - </h:outputLink> - </h:panelGrid> - </ui:define> - </ui:composition> - -</html> \ No newline at end of file diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-details.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-details.xhtml index 5e32efa..aba7769 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-details.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-details.xhtml @@ -9,7 +9,7 @@ xmlns:rich="http://richfaces.ajax4jsf.org/rich%22%3E
<ui:composition template="/rhq/layout/main.xhtml"> - <ui:param name="pageTitle" value="#{InstalledPluginUIBean.plugin.name}"/> + <ui:param name="pageTitle" value="#{plugin.name}"/>
<ui:define name="breadcrumbs"> <h:outputLink value="plugin-list.xhtml" > @@ -17,7 +17,7 @@ </h:outputLink> > <h:outputLink value="#" > - <h:outputText value="#{InstalledPluginUIBean.plugin.displayName}"/> + <h:outputText value="#{plugin.displayName}"/> </h:outputLink>
</ui:define> @@ -39,28 +39,28 @@
rich:panel <f:facet name="header"> - <h:outputText value="Plugin: #{InstalledPluginUIBean.plugin.displayName} (#{InstalledPluginUIBean.plugin.name})"/> + <h:outputText value="Plugin: #{plugin.displayName} (#{plugin.name})"/> </f:facet>
<h:panelGrid styleClass="BlockContent" columns="4" width="100%">
<h:outputLabel styleClass="BlockLabel" value="Version:"/> - <h:outputText styleClass="BlockContent" value="#{InstalledPluginUIBean.plugin.version}"/> + <h:outputText styleClass="BlockContent" value="#{plugin.version}"/>
<h:outputLabel styleClass="BlockLabel" value="Enabled:"/> - <h:outputText value="#{InstalledPluginUIBean.plugin.enabled}"/> + <h:outputText value="#{plugin.enabled}"/>
<h:outputLabel styleClass="BlockLabel" value="Type:"/> - <h:outputText value="#{InstalledPluginUIBean.plugin.deployment}"/> + <h:outputText value="#{plugin.deployment}"/>
<h:outputLabel styleClass="BlockLabel" value="MD5:"/> - <h:outputText value="#{InstalledPluginUIBean.plugin.md5}"/> + <h:outputText value="#{plugin.md5}"/>
<h:outputLabel styleClass="BlockLabel" value="Description:"/> - <h:outputText value="#{InstalledPluginUIBean.plugin.description}"/> + <h:outputText value="#{plugin.description}"/>
<h:outputLabel styleClass="BlockLabel" value="Path:"/> - <h:outputText value="#{InstalledPluginUIBean.plugin.path}"/> + <h:outputText value="#{plugin.path}"/>
</h:panelGrid>
@@ -69,38 +69,12 @@ <h:outputText value="Plugin Help"/> </f:facet>
- <h:outputText escape="false" value="<pre> #{InstalledPluginUIBean.plugin.help} </pre>"/> + <h:outputText escape="false" value="<pre> #{plugin.help} </pre>"/>
</rich:panel> - - <ui:insert name="pre-config" /> - - <rich:panel rendered="#{InstalledPluginUIBean.pluginConfigurationDefinition != null}"> - <f:facet name="header"> - <h:outputText value="Plugin Configuration"/> - </f:facet> - <onc:config - configurationDefinition="#{InstalledPluginUIBean.pluginConfigurationDefinition}" - configuration="#{InstalledPluginUIBean.plugin.pluginConfiguration}" - readOnly="#{not editMode}" /> - </rich:panel> - - <rich:panel rendered="#{InstalledPluginUIBean.scheduledJobsDefinition != null}"> - <f:facet name="header"> - <h:outputText value="Scheduled Jobs"/> - </f:facet> - <onc:config - configurationDefinition="#{InstalledPluginUIBean.scheduledJobsDefinition}" - configuration="#{InstalledPluginUIBean.plugin.scheduledJobsConfiguration}" - readOnly="#{not editMode}" /> - </rich:panel> - - <ui:insert name="post-config" /> </rich:panel> - </h:form>
- </ui:define>
</ui:composition> diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-list.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-list.xhtml index ba128c1..0b020b3 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-list.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-list.xhtml @@ -160,7 +160,7 @@ <h:outputText styleClass="headerText" value="Name"/> </f:facet>
- <h:outputLink value="/rhq/admin/plugin/plugin-details-view.xhtml"> + <h:outputLink value="/rhq/admin/plugin/plugin-details.xhtml"> <f:param name="plugin" value="#{serverPlugin.name}"/> <f:param name="deployment" value="SERVER"/> <f:param name="pluginType" value="#{serverPlugin.type}"/>
commit 9735ccd93be5c8d7bbd7578f014106f655fcbf25 Author: John Sanda john@localhost.localdomain Date: Mon Nov 30 16:05:12 2009 -0500
[US 910]
Adding a CLI script test to read and update a raw config.
diff --git a/modules/enterprise/remoting/scripts/src/test/script/org/rhq/enterprise/remoting/cli/test_ConfigurationManager.js b/modules/enterprise/remoting/scripts/src/test/script/org/rhq/enterprise/remoting/cli/test_ConfigurationManager.js index 7157fb9..f70682d 100644 --- a/modules/enterprise/remoting/scripts/src/test/script/org/rhq/enterprise/remoting/cli/test_ConfigurationManager.js +++ b/modules/enterprise/remoting/scripts/src/test/script/org/rhq/enterprise/remoting/cli/test_ConfigurationManager.js @@ -26,11 +26,12 @@ rhq.login('rhqadmin', 'rhqadmin'); skippedTests.push('testUpdateResourceGroupConfiguration');
executeAllTests(); +//executeTests(['testGetAndUpdateRawConfiguration']);
rhq.logout();
function testUpdateResourceConfiguration() { - var resource = findService('service-beta-1', 'server-omega-1'); + var resource = findResourceByNameAndParentName('service-beta-1', 'server-omega-1'); var config = ConfigurationManager.getResourceConfiguration(resource.id);
var propertyName = 'beta-config0'; @@ -53,25 +54,81 @@ function testUpdateResourceConfiguration() { Assert.assertEquals(updatedProperty.stringValue, propertyValue, 'Failed to update resource configuration'); }
-function testUpdatePluginConfiguration() { - var resource = findService('service-beta-0', 'server-omega-0'); - var pluginConfig = ConfigurationManager.getPluginConfiguration(resource.id); +function testGetAndUpdateRawConfiguration() { + var resourceName = 'Raw Server' + var rawServer = findResourceByNameAndParentName(resourceName, 'localhost');
- var propertyName = 'beta-property0'; - var propertyValue = 'updated property value -- ' + java.util.Date(); + Assert.assertNotNull(rawServer, "Failed to find '" + resourceName + "'");
- var property = pluginConfig.getSimple(propertyName); + var latestUpdate = ConfigurationManager.getLatestResourceConfigurationUpdate(rawServer.id);
- property.setStringValue(propertyValue); + Assert.assertNotNull(latestUpdate, "Failed to find latest resource configuration update for '" + resourceName + "'"); + Assert.assertTrue( + latestUpdate.configuration.rawConfigurations.size() > 0, + "Expected to find at least one raw config file for '" + "'" + ); + + var rawConfigs = java.util.LinkedList(latestUpdate.configuration.rawConfigurations); + var rawConfig = rawConfigs.get(0); + + Assert.assertTrue( + rawConfig.contents.length > 0, + "Contents of raw config file for '" + resourceName + "' should not be empty." + ); + + var contents = java.lang.String(rawConfig.contents); + var modifiedContents = java.lang.StringBuilder(contents).append("\nModified at ").append(getDate()).toString(); + + rawConfig.contents = modifiedContents.getBytes();
- var configUpdate = ConfigurationManager.updatePluginConfiguration(resource.id, pluginConfig); + var configUdpate = ConfigurationManager.updateResourceConfiguration(rawServer.id, latestUpdate.configuration);
- pluginConfig = ConfigurationManager.getPluginConfiguration(resource.id); - var updatedProperty = pluginConfig.getSimple(propertyName); + while (ConfigurationManager.isResourceConfigurationUpdateInProgress(rawServer.id)) { + java.lang.Thread.sleep(1000); + } + + latestUpdate = ConfigurationManager.getLatestResourceConfigurationUpdate(rawServer.id); + Assert.assertNotNull(latestUpdate, "Failed to find latest resource configuration update for '" + resourceName + "'"); + Assert.assertTrue( + latestUpdate.configuration.rawConfigurations.size() > 0, + "Expected to find at least one raw config file for '" + "'" + ); + + rawConfigs = java.util.LinkedList(latestUpdate.configuration.rawConfigurations); + rawConfig = rawConfigs.get(0); + var updatedContents = rawConfig.contents; + + Assert.assertEquals( + java.lang.String(updatedContents), + java.lang.String(modifiedContents), + "Failed to update raw config for '" + resourceName + "'" + ); +}
- Assert.assertEquals(updatedProperty.stringValue, propertyValue, 'Failed to update plugin configuration'); +function getDate() { + var format = java.text.DateFormat.getDateInstance(); + return format.format(java.util.Date()); }
+//function testUpdatePluginConfiguration() { +// var resource = findService('service-beta-0', 'server-omega-0'); +// var pluginConfig = ConfigurationManager.getPluginConfiguration(resource.id); +// +// var propertyName = 'beta-property0'; +// var propertyValue = 'updated property value -- ' + java.util.Date(); +// +// var property = pluginConfig.getSimple(propertyName); +// +// property.setStringValue(propertyValue); +// +// var configUpdate = ConfigurationManager.updatePluginConfiguration(resource.id, pluginConfig); +// +// pluginConfig = ConfigurationManager.getPluginConfiguration(resource.id); +// var updatedProperty = pluginConfig.getSimple(propertyName); +// +// Assert.assertEquals(updatedProperty.stringValue, propertyValue, 'Failed to update plugin configuration'); +//} + // This test is failing I think due to the asynchronous nature of the operations involved. I have verified through the // web UI that the configuration updates are actually happening. I just need to figure out how to make the test wait // so that it can (consistently) get the udpated values. @@ -112,10 +169,11 @@ function testUpdateResourceGroupConfiguration() { } }
-function findService(name, parentName) { +function findResourceByNameAndParentName(name, parentName) { var criteria = ResourceCriteria(); criteria.addFilterName(name); criteria.addFilterParentResourceName(parentName); + criteria.strict = true;
return ResourceManager.findResourcesByCriteria(criteria).get(0); }
commit bc45354dc2691e227986b89fd86d13cb6b91bd5b Author: Justin Harris jharris@redhat.com Date: Mon Nov 30 15:43:59 2009 -0500
Adding in server plugins page link from the server settings page.
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/PluginConfigurationUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/PluginConfigurationUIBean.java index 675dd9e..75747eb 100644 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/PluginConfigurationUIBean.java +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/PluginConfigurationUIBean.java @@ -75,8 +75,8 @@ public class PluginConfigurationUIBean { }
public boolean isEditable() { - return this.currentPlugin != null && ( - this.currentPlugin.getPluginConfiguration() != null || + return this.currentPlugin != null && + (this.currentPlugin.getPluginConfiguration() != null || this.currentPlugin.getScheduledJobsConfiguration() != null); }
@@ -114,8 +114,11 @@ public class PluginConfigurationUIBean { }
private TreeNode createPluginNode(PluginKey pluginKey) { + ServerPlugin plugin = serverPluginsBean.getServerPlugin(pluginKey); + plugin = serverPluginsBean.getServerPluginRelationships(plugin); + TreeNode pluginNode = new TreeNodeImpl(); - pluginNode.setData(serverPluginsBean.getServerPlugin(pluginKey)); + pluginNode.setData(plugin);
return pluginNode; } @@ -123,7 +126,6 @@ public class PluginConfigurationUIBean { public void processSelection(NodeSelectedEvent event) { HtmlTree tree = (HtmlTree) event.getSource(); this.currentPlugin = (ServerPlugin) tree.getRowData(); - this.currentPlugin = serverPluginsBean.getServerPluginRelationships(currentPlugin);
lookupConfigDefinitions(); } diff --git a/modules/enterprise/gui/portal-war/src/main/webapp-filtered/WEB-INF/classes/ApplicationResources.properties b/modules/enterprise/gui/portal-war/src/main/webapp-filtered/WEB-INF/classes/ApplicationResources.properties index 6ef4d86..34e1218 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp-filtered/WEB-INF/classes/ApplicationResources.properties +++ b/modules/enterprise/gui/portal-war/src/main/webapp-filtered/WEB-INF/classes/ApplicationResources.properties @@ -653,6 +653,8 @@ admin.settings.SNMPGenericID=Generic ID: admin.settings.SNMPSpecificID=Specific ID: admin.settings.SNMPAgentAddress=Agent Address:
+admin.settings.ServerPluginsConfigPropTab=Server Plugins Configuration Properties + admin.settings.UseCAMAuth=Use ${product.shortName} Internal Authentication admin.settings.UseLDAPAuth=Use LDAP Authentication
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/admin/config/EditServerConfig.jsp b/modules/enterprise/gui/portal-war/src/main/webapp/admin/config/EditServerConfig.jsp index 99caf2c..e2c5478 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/admin/config/EditServerConfig.jsp +++ b/modules/enterprise/gui/portal-war/src/main/webapp/admin/config/EditServerConfig.jsp @@ -50,6 +50,9 @@ <br> <br> <tiles:insert page="/admin/config/SNMPForm.jsp"/> +<br> +<br> +<tiles:insert page="/admin/config/ServerConfigForm.jsp"/>
<%--<tiles:insert page="/admin/config/MiscForm.jsp"/>--%>
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/admin/config/ServerConfigForm.jsp b/modules/enterprise/gui/portal-war/src/main/webapp/admin/config/ServerConfigForm.jsp new file mode 100644 index 0000000..008f1cb --- /dev/null +++ b/modules/enterprise/gui/portal-war/src/main/webapp/admin/config/ServerConfigForm.jsp @@ -0,0 +1,22 @@ +<%@ page language="java" %> +<%@ page errorPage="/common/Error.jsp" %> +<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %> +<%@ taglib uri="http://jakarta.apache.org/struts/tags-html-el" prefix="html" %> +<%@ taglib uri="http://jakarta.apache.org/struts/tags-tiles" prefix="tiles" %> +<%@ taglib uri="http://jakarta.apache.org/struts/tags-logic" prefix="logic" %> +<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> + +<tiles:insert definition=".header.tab"> + <tiles:put name="tabKey" value="admin.settings.ServerPluginsConfigPropTab"/> +</tiles:insert> + +<table width="100%" cellpadding="0" cellspacing="0" border="0"> + <tr> + <td class="BlockCheckboxLabel" align="left" colspan="4"> + <a href="/rhq/admin/plugin/plugin-config.xhtml">Configure Server Plugins</a> + </td> + </tr> + <tr> + <td colspan="4" class="BlockBottomLine"><html:img page="/images/spacer.gif" width="1" height="1" border="0"/></td> + </tr> +</table> \ No newline at end of file diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-config.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-config.xhtml index 49425e4..fea1d29 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-config.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-config.xhtml @@ -25,7 +25,13 @@ </ui:define>
<ui:define name="breadcrumbs"> - <h:outputLink value="plugin-config.xhtml" >Plugin Configuration</h:outputLink> + <h:outputLink value="/admin/config/Config.do?mode=edit"> + <h:outputText value="Server Settings"/> + </h:outputLink> + > + <h:outputLink value="plugin-config.xhtml"> + <h:outputText value="Server Plugins Configuration"/> + </h:outputLink> </ui:define>
<ui:define name="body">
commit 51c19a88267f01650244ee46e85f5b52bd9020f0 Author: Justin Harris jharris@redhat.com Date: Mon Nov 30 13:44:45 2009 -0500
Adding the ability to edit server plugin configs and tweaking the display in the plugin tree.
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/PluginConfigurationUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/PluginConfigurationUIBean.java index 2e7b96b..675dd9e 100644 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/PluginConfigurationUIBean.java +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/PluginConfigurationUIBean.java @@ -21,9 +21,11 @@ package org.rhq.enterprise.gui.admin.plugin; import java.util.List; import java.util.Map; import javax.faces.application.FacesMessage; +import org.jboss.seam.ScopeType; import org.jboss.seam.annotations.Create; import org.jboss.seam.annotations.Logger; import org.jboss.seam.annotations.Name; +import org.jboss.seam.annotations.Scope; import org.jboss.seam.log.Log; import org.rhq.core.clientapi.agent.metadata.ConfigurationMetadataParser; import org.rhq.core.domain.auth.Subject; @@ -44,24 +46,22 @@ import org.richfaces.event.NodeSelectedEvent; import org.richfaces.model.TreeNode; import org.richfaces.model.TreeNodeImpl;
+@Scope(ScopeType.PAGE) @Name("pluginConfigUIBean") public class PluginConfigurationUIBean {
@Logger private Log log; - private final ServerPluginsLocal serverPluginsBean = LookupUtil.getServerPlugins(); - private TreeNode root; private ServerPlugin currentPlugin; private ConfigurationDefinition pluginConfigurationDefinition; private ConfigurationDefinition scheduledJobsDefinition;
- public TreeNode getRoot() { return root; } - + public ServerPlugin getCurrentPlugin() { return currentPlugin; } @@ -74,6 +74,12 @@ public class PluginConfigurationUIBean { return this.scheduledJobsDefinition; }
+ public boolean isEditable() { + return this.currentPlugin != null && ( + this.currentPlugin.getPluginConfiguration() != null || + this.currentPlugin.getScheduledJobsConfiguration() != null); + } + @Create public void createTree() { hasPermission(); @@ -109,16 +115,14 @@ public class PluginConfigurationUIBean {
private TreeNode createPluginNode(PluginKey pluginKey) { TreeNode pluginNode = new TreeNodeImpl(); - pluginNode.setData(pluginKey); + pluginNode.setData(serverPluginsBean.getServerPlugin(pluginKey));
return pluginNode; }
public void processSelection(NodeSelectedEvent event) { HtmlTree tree = (HtmlTree) event.getSource(); - PluginKey pluginKey = (PluginKey) tree.getRowData(); - - this.currentPlugin = serverPluginsBean.getServerPlugin(pluginKey); + this.currentPlugin = (ServerPlugin) tree.getRowData(); this.currentPlugin = serverPluginsBean.getServerPluginRelationships(currentPlugin);
lookupConfigDefinitions(); @@ -127,7 +131,7 @@ public class PluginConfigurationUIBean { public void lookupConfigDefinitions() { if (this.currentPlugin.getDeployment() == PluginDeploymentType.SERVER) { PluginKey pluginKey = new PluginKey(this.currentPlugin); - + try { ServerPluginDescriptorType descriptor = serverPluginsBean.getServerPluginDescriptor(pluginKey); this.pluginConfigurationDefinition = ConfigurationMetadataParser.parse("pc:" + pluginKey.getPluginName(), descriptor.getPluginConfiguration()); @@ -140,6 +144,19 @@ public class PluginConfigurationUIBean { } }
+ public void updatePlugin() { + try { + ServerPluginsLocal serverPlugins = LookupUtil.getServerPlugins(); + Subject subject = EnterpriseFacesContextUtility.getSubject(); + serverPlugins.updateServerPluginExceptContent(subject, this.currentPlugin); + FacesContextUtility.addMessage(FacesMessage.SEVERITY_INFO, "Configuration settings saved."); + } catch (Exception e) { + log.error("Error updating the plugin configurations.", e); + FacesContextUtility.addMessage(FacesMessage.SEVERITY_ERROR, + "There was an error changing the configuration settings.", e); + } + } + // TODO: Find a more centralized way to do this - maybe via annotation // on the class?? /** @@ -148,8 +165,7 @@ public class PluginConfigurationUIBean { private void hasPermission() { Subject subject = EnterpriseFacesContextUtility.getSubject(); if (!LookupUtil.getAuthorizationManager().hasGlobalPermission(subject, Permission.MANAGE_SETTINGS)) { - throw new PermissionException("User [" + subject.getName() - + "] does not have the proper permissions to view or manage plugins"); + throw new PermissionException("User [" + subject.getName() + "] does not have the proper permissions to view or manage plugins"); } } -} \ No newline at end of file +} diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-config.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-config.xhtml index 8172e02..49425e4 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-config.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-config.xhtml @@ -61,7 +61,7 @@ <h:outputText value="#{item}s" /> </rich:treeNode> <rich:treeNode type="plugin"> - <h:outputText value="#{item.pluginName}" /> + <h:outputText value="#{item.displayName}" /> </rich:treeNode> </rich:tree> </rich:panel> @@ -72,8 +72,7 @@ <h:outputText value="Plugin Configuration"/> </f:facet> <onc:config configurationDefinition="#{pluginConfigUIBean.pluginConfigurationDefinition}" - configuration="#{pluginConfigUIBean.currentPlugin.pluginConfiguration}" - readOnly="true" /> + configuration="#{pluginConfigUIBean.currentPlugin.pluginConfiguration}" /> </rich:panel>
<rich:panel rendered="#{pluginConfigUIBean.currentPlugin.scheduledJobsConfiguration != null}"> @@ -81,9 +80,15 @@ <h:outputText value="Scheduled Jobs"/> </f:facet> <onc:config configurationDefinition="#{pluginConfigUIBean.scheduledJobsDefinition}" - configuration="#{pluginConfigUIBean.currentPlugin.scheduledJobsConfiguration}" - readOnly="true" /> + configuration="#{pluginConfigUIBean.currentPlugin.scheduledJobsConfiguration}" /> </rich:panel> + + <h:panelGroup id="pluginButtons" rendered="#{pluginConfigUIBean.editable}"> + <h:commandButton value="SAVE" type="submit" action="#{pluginConfigUIBean.updatePlugin}" + alt="Click to Save Changes" styleClass="buttonmed" /> + <h:commandButton value="RESET" type="reset" immediate="true" + title="Click to Reset Fields" styleClass="buttonmed"/> + </h:panelGroup> </h:panelGroup> </h:panelGrid> </h:form> diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginType.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginType.java index 3e6bb34..730e60e 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginType.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginType.java @@ -18,6 +18,7 @@ */ package org.rhq.enterprise.server.plugin.pc;
+import org.rhq.core.domain.util.StringUtils; import org.rhq.enterprise.server.xmlschema.generated.serverplugin.ServerPluginDescriptorType;
/** @@ -83,7 +84,8 @@ public class ServerPluginType {
@Override public String toString() { - return this.descriptorType.getSimpleName().replace("DescriptorType", ""); + String typeName = this.descriptorType.getSimpleName().replace("DescriptorType", ""); + return StringUtils.deCamelCase(typeName); }
@Override
commit 9aa21f67a40a33b54728a6db880625ac27c7811f Author: Justin Harris jharris@redhat.com Date: Mon Nov 30 11:51:26 2009 -0500
Adding in first cut at the server plugin config UI.
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/PluginConfigurationUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/PluginConfigurationUIBean.java new file mode 100644 index 0000000..2e7b96b --- /dev/null +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/PluginConfigurationUIBean.java @@ -0,0 +1,155 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2009 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.gui.admin.plugin; + +import java.util.List; +import java.util.Map; +import javax.faces.application.FacesMessage; +import org.jboss.seam.annotations.Create; +import org.jboss.seam.annotations.Logger; +import org.jboss.seam.annotations.Name; +import org.jboss.seam.log.Log; +import org.rhq.core.clientapi.agent.metadata.ConfigurationMetadataParser; +import org.rhq.core.domain.auth.Subject; +import org.rhq.core.domain.authz.Permission; +import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; +import org.rhq.core.domain.plugin.PluginDeploymentType; +import org.rhq.core.domain.plugin.PluginKey; +import org.rhq.core.domain.plugin.ServerPlugin; +import org.rhq.core.gui.util.FacesContextUtility; +import org.rhq.enterprise.gui.util.EnterpriseFacesContextUtility; +import org.rhq.enterprise.server.authz.PermissionException; +import org.rhq.enterprise.server.plugin.ServerPluginsLocal; +import org.rhq.enterprise.server.plugin.pc.ServerPluginType; +import org.rhq.enterprise.server.util.LookupUtil; +import org.rhq.enterprise.server.xmlschema.generated.serverplugin.ServerPluginDescriptorType; +import org.richfaces.component.html.HtmlTree; +import org.richfaces.event.NodeSelectedEvent; +import org.richfaces.model.TreeNode; +import org.richfaces.model.TreeNodeImpl; + +@Name("pluginConfigUIBean") +public class PluginConfigurationUIBean { + + @Logger + private Log log; + + private final ServerPluginsLocal serverPluginsBean = LookupUtil.getServerPlugins(); + + private TreeNode root; + private ServerPlugin currentPlugin; + private ConfigurationDefinition pluginConfigurationDefinition; + private ConfigurationDefinition scheduledJobsDefinition; + + + public TreeNode getRoot() { + return root; + } + + public ServerPlugin getCurrentPlugin() { + return currentPlugin; + } + + public ConfigurationDefinition getPluginConfigurationDefinition() { + return this.pluginConfigurationDefinition; + } + + public ConfigurationDefinition getScheduledJobsDefinition() { + return this.scheduledJobsDefinition; + } + + @Create + public void createTree() { + hasPermission(); + + this.root = new TreeNodeImpl(); + Map<ServerPluginType, List<PluginKey>> types = serverPluginsBean.getInstalledServerPluginsGroupedByType(); + + for (ServerPluginType type : types.keySet()) { + TreeNode typeNode = createTypeNode(type, types.get(type)); + + if (typeNode != null) { + typeNode.setParent(root); + root.addChild(type, typeNode); + } + } + } + + private TreeNode createTypeNode(ServerPluginType type, List<PluginKey> plugins) { + TreeNode typeNode = new TreeNodeImpl(); + typeNode.setData(type); + + if (plugins != null && plugins.size() > 0) { + for (PluginKey pluginKey : plugins) { + TreeNode pluginNode = createPluginNode(pluginKey); + pluginNode.setParent(typeNode); + + typeNode.addChild(pluginKey, pluginNode); + } + } + + return typeNode; + } + + private TreeNode createPluginNode(PluginKey pluginKey) { + TreeNode pluginNode = new TreeNodeImpl(); + pluginNode.setData(pluginKey); + + return pluginNode; + } + + public void processSelection(NodeSelectedEvent event) { + HtmlTree tree = (HtmlTree) event.getSource(); + PluginKey pluginKey = (PluginKey) tree.getRowData(); + + this.currentPlugin = serverPluginsBean.getServerPlugin(pluginKey); + this.currentPlugin = serverPluginsBean.getServerPluginRelationships(currentPlugin); + + lookupConfigDefinitions(); + } + + public void lookupConfigDefinitions() { + if (this.currentPlugin.getDeployment() == PluginDeploymentType.SERVER) { + PluginKey pluginKey = new PluginKey(this.currentPlugin); + + try { + ServerPluginDescriptorType descriptor = serverPluginsBean.getServerPluginDescriptor(pluginKey); + this.pluginConfigurationDefinition = ConfigurationMetadataParser.parse("pc:" + pluginKey.getPluginName(), descriptor.getPluginConfiguration()); + this.scheduledJobsDefinition = ConfigurationMetadataParser.parse("jobs:" + pluginKey.getPluginName(), descriptor.getScheduledJobs()); + } catch (Exception e) { + String err = "Cannot determine what the plugin configuration or scheduled jobs configuration looks like"; + log.error(err + " - Cause: " + e); + FacesContextUtility.addMessage(FacesMessage.SEVERITY_ERROR, err, e); + } + } + } + + // TODO: Find a more centralized way to do this - maybe via annotation + // on the class?? + /** + * Throws a permission exception if the user is not allowed to access this functionality. + */ + private void hasPermission() { + Subject subject = EnterpriseFacesContextUtility.getSubject(); + if (!LookupUtil.getAuthorizationManager().hasGlobalPermission(subject, Permission.MANAGE_SETTINGS)) { + throw new PermissionException("User [" + subject.getName() + + "] does not have the proper permissions to view or manage plugins"); + } + } +} \ No newline at end of file diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-config.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-config.xhtml new file mode 100644 index 0000000..8172e02 --- /dev/null +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-config.xhtml @@ -0,0 +1,94 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<html xmlns="http://www.w3.org/1999/xhtml" + xmlns:h="http://java.sun.com/jsf/html" + xmlns:f="http://java.sun.com/jsf/core" + xmlns:ui="http://java.sun.com/jsf/facelets" + xmlns:c="http://java.sun.com/jstl/core" + xmlns:onc="http://jboss.org/on/component" + xmlns:rich="http://richfaces.ajax4jsf.org/rich%22%3E + +<ui:composition template="/rhq/layout/main.xhtml"> + <ui:param name="pageTitle" value="Server Plugins Configuration"/> + + <ui:define name="metaHeaders"> + <style> + .col1 { + width: 20%; + vertical-align: top; + } + + .col2 { + width: 80%; + } + </style> + </ui:define> + + <ui:define name="breadcrumbs"> + <h:outputLink value="plugin-config.xhtml" >Plugin Configuration</h:outputLink> + </ui:define> + + <ui:define name="body"> + <br/> + <h:messages showSummary="true" + showDetail="true" + infoClass="InfoBlock" + warnClass="WarnBlock" + errorClass="ErrorBlock" + fatalClass="FatalBlock" + globalOnly="true" + layout="table" + width="100%"/> + + <h:form id="pluginsConfigForm"> + <h:panelGrid columns="2" width="100%" columnClasses="col1,col2"> + rich:panel + <f:facet name="header"> + <h:outputText value="Available Plugins" /> + </f:facet> + + <rich:tree nodeSelectListener="#{pluginConfigUIBean.processSelection}" + reRender="pluginConfig" + value="#{pluginConfigUIBean.root}" + ajaxSubmitSelection="true" + switchType="client" + toggleOnClick="true" + treeNodeVar="node" + var="item" + nodeFace="#{node.leaf ? 'plugin' : 'pluginType'}"> + + <rich:treeNode type="pluginType" disabled="true"> + <h:outputText value="#{item}s" /> + </rich:treeNode> + <rich:treeNode type="plugin"> + <h:outputText value="#{item.pluginName}" /> + </rich:treeNode> + </rich:tree> + </rich:panel> + + <h:panelGroup id="pluginConfig"> + <rich:panel rendered="#{pluginConfigUIBean.currentPlugin.pluginConfiguration != null}"> + <f:facet name="header"> + <h:outputText value="Plugin Configuration"/> + </f:facet> + <onc:config configurationDefinition="#{pluginConfigUIBean.pluginConfigurationDefinition}" + configuration="#{pluginConfigUIBean.currentPlugin.pluginConfiguration}" + readOnly="true" /> + </rich:panel> + + <rich:panel rendered="#{pluginConfigUIBean.currentPlugin.scheduledJobsConfiguration != null}"> + <f:facet name="header"> + <h:outputText value="Scheduled Jobs"/> + </f:facet> + <onc:config configurationDefinition="#{pluginConfigUIBean.scheduledJobsDefinition}" + configuration="#{pluginConfigUIBean.currentPlugin.scheduledJobsConfiguration}" + readOnly="true" /> + </rich:panel> + </h:panelGroup> + </h:panelGrid> + </h:form> + </ui:define> + +</ui:composition> + +</html> \ No newline at end of file
commit e67beedcbfcf016cae615c4fd02d83dae2562349 Author: Heiko W. Rupp pilhuhn@fedorapeople.org Date: Mon Nov 30 16:30:52 2009 +0100
Use the defined alert sender
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerBean.java index 0c1a1a5..8946a8f 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerBean.java @@ -662,20 +662,21 @@ public class AlertManagerBean implements AlertManagerLocal, AlertManagerRemote {
sendAlertSnmpTrap(alert, snmpNotification); } - }
- AlertNotification test = new AlertNotification(alert.getAlertDefinition()); - test.setSenderName("Email"); - test.setConfiguration(new Configuration()); - Property prop = new PropertySimple("emailAddress","hwr@redhat.com"); - test.getConfiguration().getProperties().add(prop); - AlertSender sender = getAlertSender(test); - if (sender!=null) { - try { - SenderResult result = sender.send(alert); - } - catch (Throwable t) { - log.error("Sender failed: " + t.getMessage()); + + // Send over the new AlertSenders + if (alertNotification.getSenderName()==null) + continue; + + AlertSender sender = getAlertSender(alertNotification); + if (sender!=null) { + try { + SenderResult result = sender.send(alert); + // TODO log result + } + catch (Throwable t) { + log.error("Sender failed: " + t.getMessage()); + } } }
commit 344cfe46e538fc771ead0a4e7c48a74d8df447d7 Author: Heiko W. Rupp pilhuhn@fedorapeople.org Date: Mon Nov 30 16:01:43 2009 +0100
Show the configuration
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/alert/notif/listAlertSender.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/alert/notif/listAlertSender.xhtml index f365463..dd24c0b 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/alert/notif/listAlertSender.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/alert/notif/listAlertSender.xhtml @@ -45,6 +45,7 @@ value="#{ListNotificationsUIBean.existingNotifications}" var="notif" width="100%" + columnWidth="5% 10% 85%" headerClass="tableRowHeader" footerClass="on-pager-footer" onRowMouseOver="this.style.backgroundColor='#E7E7E7'" @@ -65,6 +66,13 @@ <h:outputText value="#{notif.senderName}"/> </rich:column>
+ rich:column + <f:facet name="header"> + <h:outputText styleClass="headerText" value="Configuration"/> + </f:facet> + + <h:outputText value="#{notif.configuration.toString(true)}"/> + </rich:column> <!-- TODO add configuration --> </rich:dataTable>
commit a6aad438dc5aac56cbafb65464700d5901569a8e Author: Heiko W. Rupp pilhuhn@fedorapeople.org Date: Mon Nov 30 15:52:48 2009 +0100
List exising notifications and be able to add new ones.
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/alert/notification/AlertNotification.java b/modules/core/domain/src/main/java/org/rhq/core/domain/alert/notification/AlertNotification.java index eec3a6c..7efa51b 100644 --- a/modules/core/domain/src/main/java/org/rhq/core/domain/alert/notification/AlertNotification.java +++ b/modules/core/domain/src/main/java/org/rhq/core/domain/alert/notification/AlertNotification.java @@ -75,7 +75,7 @@ public class AlertNotification implements Serializable { private AlertDefinition alertDefinition;
@JoinColumn(name = "ALERT_CONFIG_ID", referencedColumnName = "ID") - @OneToOne(cascade = { CascadeType.REMOVE }, fetch = FetchType.LAZY) + @OneToOne(cascade = { CascadeType.ALL }, fetch = FetchType.LAZY) private Configuration configuration;
@Column(name = "ALERT_SENDER_NAME") diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/ListNotificationsUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/ListNotificationsUIBean.java index 7e79bab..f50705a 100644 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/ListNotificationsUIBean.java +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/ListNotificationsUIBean.java @@ -18,20 +18,27 @@ */ package org.rhq.enterprise.gui.alert;
+import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map;
+import javax.faces.context.ExternalContext; +import javax.faces.context.FacesContext; + import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory;
import org.jboss.seam.ScopeType; import org.jboss.seam.annotations.Name; import org.jboss.seam.annotations.Scope; +import org.jboss.seam.annotations.web.RequestParameter;
+import org.rhq.core.domain.alert.notification.AlertNotification; +import org.rhq.core.domain.auth.Subject; import org.rhq.core.domain.configuration.Configuration; -import org.rhq.core.domain.configuration.PropertySimple; import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; +import org.rhq.enterprise.gui.util.EnterpriseFacesContextUtility; import org.rhq.enterprise.server.alert.AlertNotificationManagerLocal; import org.rhq.enterprise.server.util.LookupUtil;
@@ -52,8 +59,9 @@ public class ListNotificationsUIBean {
private ConfigurationDefinition alertConfigurationDefinition; private Configuration alertProperties; - int ad;
+ @RequestParameter("ad") + private int alertDefinitionId;
public ListNotificationsUIBean() { } @@ -109,16 +117,17 @@ public class ListNotificationsUIBean { }
public String mySubmitForm() { - System.out.println("In submit Form "); log.info("In submit Form "); + AlertNotificationManagerLocal mgr = LookupUtil.getAlertNotificationManager(); + Subject subject = EnterpriseFacesContextUtility.getSubject(); + mgr.addAlertNotification(subject, alertDefinitionId,selectedSender,alertProperties); return OUTCOME_SUCCESS; }
- public int getAd() { - return ad; - } - - public void setAd(int ad) { - this.ad = ad; + public Collection<AlertNotification> getExistingNotifications() { + AlertNotificationManagerLocal mgr = LookupUtil.getAlertNotificationManager(); + Subject subject = EnterpriseFacesContextUtility.getSubject(); + List<AlertNotification> notifications = mgr.getNotificationsForAlertDefinition(subject,alertDefinitionId); + return notifications; } } \ No newline at end of file diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-managed-beans/alert-beans.xml b/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-managed-beans/alert-beans.xml index d41bd31..8be8f7a 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-managed-beans/alert-beans.xml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-managed-beans/alert-beans.xml @@ -25,12 +25,4 @@ <managed-bean-scope>request</managed-bean-scope> </managed-bean>
- <!-- /rhq/resource/alert/notif --> - <managed-bean> - <description>Handling of alert senders</description> - <managed-bean-name>ListNotificationsUIBean</managed-bean-name> - <managed-bean-class>org.rhq.enterprise.gui.alert.ListNotificationsUIBean</managed-bean-class> - <managed-bean-scope>request</managed-bean-scope> - </managed-bean> - </faces-config> \ No newline at end of file diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/alert/notif/listAlertSender.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/alert/notif/listAlertSender.xhtml index e902b81..f365463 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/alert/notif/listAlertSender.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/alert/notif/listAlertSender.xhtml @@ -39,6 +39,35 @@ width="100%"/>
<p/> + <h:outputText>Existing notifications:</h:outputText> + <br/> + <rich:dataTable id="alertNotificationDataTable" + value="#{ListNotificationsUIBean.existingNotifications}" + var="notif" + width="100%" + headerClass="tableRowHeader" + footerClass="on-pager-footer" + onRowMouseOver="this.style.backgroundColor='#E7E7E7'" + onRowMouseOut="this.style.backgroundColor='#{a4jSkin.tableBackgroundColor}'"> + rich:column + <f:facet name="header"> + <h:outputText styleClass="headerText" value="ID"/> + </f:facet> + + <h:outputText value="#{notif.id}"/> + </rich:column> + + rich:column + <f:facet name="header"> + <h:outputText styleClass="headerText" value="Sender"/> + </f:facet> + + <h:outputText value="#{notif.senderName}"/> + </rich:column> + + <!-- TODO add configuration --> + </rich:dataTable> + <h:outputText>Hello World</h:outputText> <h:form id="listSenderForm"> <input type="hidden" name="id" value="${param.id}"/> diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerBean.java index de7362e..9a0399c 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerBean.java @@ -482,11 +482,6 @@ public class AlertNotificationManagerBean implements AlertNotificationManagerLoc } }
- public Configuration getDefaultAlertConfiguration(ConfigurationDefinition def) { - Configuration config = configManager.getConfigurationFromDefaultTemplate(def); - - return config; - }
/** * Return a list of all available AlertSenders in the system by their shortname. @@ -497,4 +492,56 @@ public class AlertNotificationManagerBean implements AlertNotificationManagerLoc List<String> senders = pluginmanager.getPluginList(); return senders; } + + /** + * Add a new AlertNotification to the passed definition + * @param user subject of the caller + * @param alertDefinitionId Id of the alert definition + * @param senderName shortName of the {@link AlertSender} + * @param configuration Properties for this alert sender. + */ + public void addAlertNotification(Subject user, int alertDefinitionId, String senderName, Configuration configuration) { + + AlertDefinition definition = alertDefinitionManager.getAlertDefinition(user,alertDefinitionId); + if (definition==null) { + LOG.error("DId not find definition for id [" + alertDefinitionId+ "]"); + return; + } + + entityManager.persist(configuration); + AlertNotification notif = new AlertNotification(definition); + notif.setSenderName(senderName); + notif.setConfiguration(configuration); + entityManager.persist(notif); + definition.getAlertNotifications().add(notif); + + } + + /** + * Return notifications for a certain alertDefinitionId + * + * NOTE: this only returns notifications that have an AlertSender defined. + * + * @param user Subject of the caller + * @param alertDefinitionId Id of the alert definition + * @return list of defined notification of the passed alert definition + * + * + */ + public List<AlertNotification> getNotificationsForAlertDefinition(Subject user, int alertDefinitionId) { + AlertDefinition definition = alertDefinitionManager.getAlertDefinition(user,alertDefinitionId); + if (definition==null) { + LOG.error("DId not find definition for id [" + alertDefinitionId+ "]"); + return new ArrayList<AlertNotification>(); + } + Set<AlertNotification> notifs = definition.getAlertNotifications(); + List<AlertNotification> result = new ArrayList<AlertNotification>(); + for (AlertNotification notif : notifs) { + if (notif.getSenderName()!=null) { + notif.getConfiguration().getProperties().size(); // Eager load + result.add(notif); + } + } + return result; + } } \ No newline at end of file diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerLocal.java index 532bd95..debec43 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerLocal.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerLocal.java @@ -82,5 +82,25 @@ public interface AlertNotificationManagerLocal {
ConfigurationDefinition getConfigurationDefinitionForSender(String shortName);
- Configuration getDefaultAlertConfiguration(ConfigurationDefinition def); + /** + * Add a new AlertNotification to the passed definition + * @param user subject of the caller + * @param alertDefinitionId Id of the alert definition + * @param senderName shortName of the {@link AlertSender} + * @param configuration Properties for this alert sender. + */ + void addAlertNotification(Subject user, int alertDefinitionId, String senderName, Configuration configuration); + + /** + * Return notifications for a certain alertDefinitionId + * + * NOTE: this only returns notifications that have an AlertSender defined. + * + * @param user Subject of the caller + * @param alertDefinitionId Id of the alert definition + * @return list of defined notification of the passed alert definition + * + * + */ + List<AlertNotification> getNotificationsForAlertDefinition(Subject user, int alertDefinitionId); } \ No newline at end of file
commit a7a472991d9fcf6adcbb7a198c1ec8d287ee0abf Author: Heiko W. Rupp pilhuhn@fedorapeople.org Date: Mon Nov 30 10:57:53 2009 +0100
Enable building of the alert-email sender.
diff --git a/modules/enterprise/server/plugins/pom.xml b/modules/enterprise/server/plugins/pom.xml index 960616b..b3717bb 100644 --- a/modules/enterprise/server/plugins/pom.xml +++ b/modules/enterprise/server/plugins/pom.xml @@ -39,6 +39,8 @@ <module>yum</module> <module>url</module> <module>rhnhosted</module> + <module>alert-email</module> + <!-- <module>alert-mobicents</module> --> </modules>
</project>
commit ecd12c57abf6fb6b51993882babeb6b69d974583 Author: Heiko W. Rupp pilhuhn@fedorapeople.org Date: Mon Nov 30 10:38:29 2009 +0100
Support for alert sender plugins and configuring them. WIP
diff --git a/modules/core/dbutils/pom.xml b/modules/core/dbutils/pom.xml index 83fa2a2..0ab3e72 100644 --- a/modules/core/dbutils/pom.xml +++ b/modules/core/dbutils/pom.xml @@ -22,7 +22,7 @@
<properties> <scm.module.path>modules/core/dbutils/</scm.module.path> - <db.schema.version>2.69.3</db.schema.version> + <db.schema.version>2.70</db.schema.version> </properties>
<dependencies> @@ -48,14 +48,14 @@ <!-- NOTE: The version is defined in the root POM's dependencyManagement section. --> <scope>test</scope> </dependency> - + <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <!-- NOTE: The version is defined in the root POM's dependencyManagement section. --> <scope>test</scope> </dependency> - + <dependency> <groupId>net.sourceforge.jtds</groupId> <artifactId>jtds</artifactId> diff --git a/modules/core/dbutils/src/main/scripts/dbsetup/alert-schema.xml b/modules/core/dbutils/src/main/scripts/dbsetup/alert-schema.xml index 30d179b..f9560c1 100644 --- a/modules/core/dbutils/src/main/scripts/dbsetup/alert-schema.xml +++ b/modules/core/dbutils/src/main/scripts/dbsetup/alert-schema.xml @@ -78,6 +78,8 @@ <column name="RECOVERY_ID" type="INTEGER" required="true"/> <!-- required, but 0 effectively means null --> <column name="WILL_RECOVER" required="true" default="false" type="BOOLEAN"/> + <column name="ACK_TIME" required="false" type="LONG"/> + <column name="ACK_BY_ID" required="false" type="INTEGER" references="RHQ_SUBJECT(ID)"/> <index name="RHQ_ALERT_IDX_TIME" unique="false"> <field ref="CTIME"/> </index> @@ -127,6 +129,8 @@ <column name="SNMP_HOST" size="100" type="VARCHAR2"/> <column name="SNMP_PORT" type="INTEGER"/> <column name="SNMP_OID" size="250" type="VARCHAR2"/> + <column name="ALERT_CONFIG_ID" required="false" type="INTEGER" references="RHQ_CONFIG(ID)"/> + <column name="ALERT_SENDER_NAME" required="false" type="VARCHAR2" /> <!-- TODO make required = true --> </table>
</dbsetup> diff --git a/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml b/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml index c28b862..b2532b7 100644 --- a/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml +++ b/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml @@ -2199,6 +2199,29 @@ <!-- add the new column that indicates what type of plugin this is (e.g. alert, generic, content) - for server plugins only --> <schema-addColumn table="RHQ_PLUGIN" column="PTYPE" columnType="VARCHAR2" precision="200"/> </schemaSpec> + <schemaSpec version="2.70"> + <schema-addColumn table="RHQ_ALERT" column="ACK_TIME" columnType="LONG" /> + <schema-addColumn table="RHQ_ALERT" column="ACK_BY_ID" columnType="INTEGER" /> + <schema-directSQL> + <statement> + ALTER TABLE RHQ_ALERT + ADD CONSTRAINT RHQ_ALERT_SUBJECT_ID_FKEY + FOREIGN KEY (ACK_BY_ID) + REFERENCES RHQ_SUBJECT(ID) + </statement> + </schema-directSQL> + <schema-addColumn table="RHQ_ALERT_NOTIFICATION" column="ALERT_SENDER_NAME" type="VARCHAR2"/> + <schema-addColumn table="RHQ_ALERT_NOTIFICATION" column="ALERT_CONFIG_ID" type="INTEGER"/> + <schema-directSQL> + <statement> + ALTER TABLE RHQ_ALERT_NOTIFICATION + ADD CONSTRAINT RHQ_ALERT_CONFIG_ID_FKEY + FOREIGN KEY (ALERT_CONFIG_ID) + REFERENCES RHQ_CONFIG(ID) + </statement> + </schema-directSQL> + + </schemaSpec>
</dbupgrade> </target> diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/alert/Alert.java b/modules/core/domain/src/main/java/org/rhq/core/domain/alert/Alert.java index 7842e19..9f0f76a 100644 --- a/modules/core/domain/src/main/java/org/rhq/core/domain/alert/Alert.java +++ b/modules/core/domain/src/main/java/org/rhq/core/domain/alert/Alert.java @@ -43,6 +43,7 @@ import javax.persistence.SequenceGenerator; import javax.persistence.Table;
import org.rhq.core.domain.alert.notification.AlertNotificationLog; +import org.rhq.core.domain.auth.Subject;
/** * @author Joseph Marques @@ -66,7 +67,7 @@ import org.rhq.core.domain.alert.notification.AlertNotificationLog; + " AND ( :priority = a.alertDefinition.priority OR :priority IS NULL ) " + " AND res.id IN ( :resourceIds )"), @NamedQuery(name = Alert.QUERY_FIND_BY_RESOURCE, // - query = "SELECT a " // + query = "SELECT a " // + " FROM Alert AS a " + " WHERE a.alertDefinition.resource.id = :id " + " AND (a.alertDefinition.id = :alertDefinitionId OR :alertDefinitionId IS NULL) " @@ -138,16 +139,16 @@ import org.rhq.core.domain.alert.notification.AlertNotificationLog; + " FROM AlertDefinition ad " // + " WHERE ad.resource.id IN ( :resourceIds ) )"), @NamedQuery(name = Alert.QUERY_FIND_ALL_COMPOSITES_ADMIN, query = "" // - + " SELECT new org.rhq.core.domain.alert.composite.AlertHistoryComposite" // + + " SELECT new org.rhq.core.domain.alert.composite.AlertHistoryComposite" // + " ( a, parent.id, parent.name ) " // + " FROM Alert a " // + " JOIN a.alertDefinition ad " // + " JOIN ad.resource res " // + "LEFT JOIN res.parentResource parent " // - /* + /* * as much as i want to (for efficiency of the query [namely roundtrips to the db]) i can't use fetching here - * because, when added, the query parser chokes with "query specified join fetching, but the owner of the - * fetched association was not present in the select list"...even though it clearly is ;/ + * because, when added, the query parser chokes with "query specified join fetching, but the owner of the + * fetched association was not present in the select list"...even though it clearly is ;/ */ //+ " JOIN FETCH a.conditionLogs acl " // + " WHERE (UPPER(res.name) LIKE :resourceFilter OR :resourceFilter IS NULL) " // @@ -155,21 +156,21 @@ import org.rhq.core.domain.alert.notification.AlertNotificationLog; + " AND (a.ctime > :startTime OR :startTime IS NULL) " // + " AND (a.ctime < :endTime OR :endTime IS NULL) " // + " AND (a.id IN ( SELECT aa.id FROM Alert aa " // - + " JOIN aa.conditionLogs aacl " // + + " JOIN aa.conditionLogs aacl " // + " JOIN aacl.condition ac " // + " WHERE ac.category = :category ) " // + " OR :category IS NULL) "), // @NamedQuery(name = Alert.QUERY_FIND_ALL_COMPOSITES, query = "" // - + " SELECT new org.rhq.core.domain.alert.composite.AlertHistoryComposite" // + + " SELECT new org.rhq.core.domain.alert.composite.AlertHistoryComposite" // + " ( a, parent.id, parent.name ) " // + " FROM Alert a " // + " JOIN a.alertDefinition ad " // + " JOIN ad.resource res " // + "LEFT JOIN res.parentResource parent " // - /* + /* * as much as i want to (for efficiency of the query [namely roundtrips to the db]) i can't use fetching here - * because, when added, the query parser chokes with "query specified join fetching, but the owner of the - * fetched association was not present in the select list"...even though it clearly is ;/ + * because, when added, the query parser chokes with "query specified join fetching, but the owner of the + * fetched association was not present in the select list"...even though it clearly is ;/ */ //+ " JOIN FETCH a.conditionLogs acl " // + " WHERE res.id IN ( SELECT rr.id FROM Resource rr " // @@ -180,7 +181,7 @@ import org.rhq.core.domain.alert.notification.AlertNotificationLog; + " AND (a.ctime > :startTime OR :startTime IS NULL) " // + " AND (a.ctime < :endTime OR :endTime IS NULL) " // + " AND (a.id IN ( SELECT aa.id FROM Alert aa " // - + " JOIN aa.conditionLogs aacl " // + + " JOIN aa.conditionLogs aacl " // + " JOIN aacl.condition ac " // + " WHERE ac.category = :category ) " // + " OR :category IS NULL) ") }) @@ -233,6 +234,7 @@ public class Alert implements Serializable { @OneToOne(mappedBy = "alert") private AlertNotificationLog alertNotificationLog;
+ @Deprecated @Column(name = "TRIGGERED_OPERATION", nullable = true) private String triggeredOperation;
@@ -247,6 +249,18 @@ public class Alert implements Serializable { @Column(name = "WILL_RECOVER", nullable = false) private boolean willRecover;
+ + + + @Column(name ="ACK_TIME") + private long ackTime; + + @JoinColumn(name = "ACK_BY_ID", referencedColumnName = "ID") + @ManyToOne + private Subject ackBy; + + + /** * Creates a new alert. (required by EJB3 spec, but not used) */ @@ -265,7 +279,7 @@ public class Alert implements Serializable { this.willRecover = alertDefinition.getWillRecover(); // Do not load the collection side from a one-to-many, This is very slow to load all existing alerts // and unnecessary for creating the link - // alertDefinition.addAlert(this); + // alertDefinition.addAlert(this); this.ctime = ctime; if (alertDefinition.getOperationDefinition() != null) { setTriggeredOperation(alertDefinition.getOperationDefinition().getDisplayName()); @@ -314,6 +328,22 @@ public class Alert implements Serializable { this.triggeredOperation = triggeredOperation; }
+ public long getAckTime() { + return ackTime; + } + + public void setAckTime(long ackTime) { + this.ackTime = ackTime; + } + + public Subject getAckBy() { + return ackBy; + } + + public void setAckBy(Subject ackBy) { + this.ackBy = ackBy; + } + public boolean getWillRecover() { return this.willRecover; } @@ -368,4 +398,4 @@ public class Alert implements Serializable { return "org.rhq.core.domain.alert.Alert[id=" + this.id + ", alertDefinition=" + this.alertDefinition + ", ctime=" + this.ctime + "]"; } -} \ No newline at end of file +} diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/alert/notification/AlertNotification.java b/modules/core/domain/src/main/java/org/rhq/core/domain/alert/notification/AlertNotification.java index 940b0f1..eec3a6c 100644 --- a/modules/core/domain/src/main/java/org/rhq/core/domain/alert/notification/AlertNotification.java +++ b/modules/core/domain/src/main/java/org/rhq/core/domain/alert/notification/AlertNotification.java @@ -24,10 +24,12 @@ package org.rhq.core.domain.alert.notification;
import java.io.Serializable;
+import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.DiscriminatorColumn; import javax.persistence.DiscriminatorType; import javax.persistence.Entity; +import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; @@ -37,12 +39,14 @@ import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.NamedQueries; import javax.persistence.NamedQuery; +import javax.persistence.OneToOne; import javax.persistence.SequenceGenerator; import javax.persistence.Table;
import org.jetbrains.annotations.NotNull;
import org.rhq.core.domain.alert.AlertDefinition; +import org.rhq.core.domain.configuration.Configuration;
@DiscriminatorColumn(name = "NOTIFICATION_TYPE", discriminatorType = DiscriminatorType.STRING) @Entity @@ -53,7 +57,7 @@ import org.rhq.core.domain.alert.AlertDefinition; @NamedQuery(name = AlertNotification.QUERY_DELETE_ORPHANED, query = "DELETE FROM AlertNotification an WHERE an.alertDefinition IS NULL") }) @SequenceGenerator(name = "RHQ_ALERT_NOTIFICATION_ID_SEQ", sequenceName = "RHQ_ALERT_NOTIFICATION_ID_SEQ") @Table(name = "RHQ_ALERT_NOTIFICATION") -public abstract class AlertNotification implements Serializable { +public class AlertNotification implements Serializable {
private static final long serialVersionUID = 1L;
@@ -70,17 +74,35 @@ public abstract class AlertNotification implements Serializable { @ManyToOne private AlertDefinition alertDefinition;
+ @JoinColumn(name = "ALERT_CONFIG_ID", referencedColumnName = "ID") + @OneToOne(cascade = { CascadeType.REMOVE }, fetch = FetchType.LAZY) + private Configuration configuration; + + @Column(name = "ALERT_SENDER_NAME") + private String senderName; + protected AlertNotification() { } // JPA spec
- public AlertNotification(@NotNull AlertDefinition alertDefinition) { + public AlertNotification(AlertDefinition alertDefinition) { + if (alertDefinition == null) { + throw new IllegalArgumentException("alertDefinition must be non-null."); + } + + this.alertDefinition = alertDefinition; + } + + public AlertNotification(AlertDefinition alertDefinition, Configuration config) { if (alertDefinition == null) { throw new IllegalArgumentException("alertDefinition must be non-null."); }
this.alertDefinition = alertDefinition; + this.configuration = config.deepCopy(); }
+ + public int getId() { return id; } @@ -102,9 +124,27 @@ public abstract class AlertNotification implements Serializable { return results; }
- protected abstract AlertNotification copy(); + protected AlertNotification copy() { + return new AlertNotification(this.alertDefinition,this.configuration); + }
public void prepareForOrphanDelete() { this.alertDefinition = null; } -} \ No newline at end of file + + public String getSenderName() { + return senderName; + } + + public void setSenderName(String senderName) { + this.senderName = senderName; + } + + public Configuration getConfiguration() { + return configuration; + } + + public void setConfiguration(Configuration configuration) { + this.configuration = configuration; + } +} diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/alert/notification/EmailNotification.java b/modules/core/domain/src/main/java/org/rhq/core/domain/alert/notification/EmailNotification.java index 6e52e92..da713bc 100644 --- a/modules/core/domain/src/main/java/org/rhq/core/domain/alert/notification/EmailNotification.java +++ b/modules/core/domain/src/main/java/org/rhq/core/domain/alert/notification/EmailNotification.java @@ -39,6 +39,7 @@ import org.rhq.core.domain.alert.AlertDefinition; + " FROM EmailNotification en " + " WHERE en.alertDefinition.id = :alertDefinitionId "), @NamedQuery(name = EmailNotification.QUERY_FIND_BY_IDS, query = "SELECT en " + " FROM EmailNotification en " + " WHERE en.id IN ( :ids )") }) +@Deprecated public class EmailNotification extends AlertNotification {
private static final long serialVersionUID = 1L; @@ -107,4 +108,4 @@ public class EmailNotification extends AlertNotification { + ", " + "]"; }
-} \ No newline at end of file +} diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/alert/notification/RoleNotification.java b/modules/core/domain/src/main/java/org/rhq/core/domain/alert/notification/RoleNotification.java index f234ae2..696895b 100644 --- a/modules/core/domain/src/main/java/org/rhq/core/domain/alert/notification/RoleNotification.java +++ b/modules/core/domain/src/main/java/org/rhq/core/domain/alert/notification/RoleNotification.java @@ -43,6 +43,7 @@ import org.rhq.core.domain.authz.Role; + " WHERE rn.id IN ( :ids )"), @NamedQuery(name = RoleNotification.QUERY_FIND_BY_ROLE_IDS, query = "SELECT rn " + " FROM RoleNotification rn " + " WHERE rn.role.id IN ( :ids )") }) +@Deprecated public class RoleNotification extends AlertNotification {
private static final long serialVersionUID = 1L; @@ -125,4 +126,4 @@ public class RoleNotification extends AlertNotification { public String toString() { return this.getClass().getSimpleName() + "[" + "id=" + getId() + ", " + "role=" + this.role + ", " + "]"; } -} \ No newline at end of file +} diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/alert/notification/SnmpNotification.java b/modules/core/domain/src/main/java/org/rhq/core/domain/alert/notification/SnmpNotification.java index 4775c34..1507cb8 100644 --- a/modules/core/domain/src/main/java/org/rhq/core/domain/alert/notification/SnmpNotification.java +++ b/modules/core/domain/src/main/java/org/rhq/core/domain/alert/notification/SnmpNotification.java @@ -42,6 +42,7 @@ import org.rhq.core.domain.alert.AlertDefinition; @Entity @NamedQueries( { @NamedQuery(name = SnmpNotification.QUERY_FIND_ALL_BY_ALERT_DEFINITION_ID, query = "SELECT sn " + " FROM SnmpNotification sn " + " WHERE sn.alertDefinition.id = :alertDefinitionId ") }) +@Deprecated public class SnmpNotification extends AlertNotification {
private static final long serialVersionUID = 1L; @@ -141,4 +142,4 @@ public class SnmpNotification extends AlertNotification { return this.getClass().getSimpleName() + "[" + "id=" + getId() + ", " + "host=" + this.host + ", " + "port=" + this.port + ", " + "oid=" + this.oid + ", " + "]"; } -} \ No newline at end of file +} diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/alert/notification/SubjectNotification.java b/modules/core/domain/src/main/java/org/rhq/core/domain/alert/notification/SubjectNotification.java index 1c80727..18a90bc 100644 --- a/modules/core/domain/src/main/java/org/rhq/core/domain/alert/notification/SubjectNotification.java +++ b/modules/core/domain/src/main/java/org/rhq/core/domain/alert/notification/SubjectNotification.java @@ -43,6 +43,7 @@ import org.rhq.core.domain.auth.Subject; + " WHERE sn.id IN ( :ids )"), @NamedQuery(name = SubjectNotification.QUERY_FIND_BY_SUBJECT_IDS, query = "SELECT sn " + " FROM SubjectNotification sn " + " WHERE sn.subject.id IN ( :ids )") }) +@Deprecated public class SubjectNotification extends AlertNotification {
private static final long serialVersionUID = 1L; @@ -125,4 +126,4 @@ public class SubjectNotification extends AlertNotification { public String toString() { return this.getClass().getSimpleName() + "[" + "id=" + getId() + ", " + "subject=" + this.subject + ", " + "]"; } -} \ No newline at end of file +} diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/ListNotificationsUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/ListNotificationsUIBean.java new file mode 100644 index 0000000..7e79bab --- /dev/null +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/ListNotificationsUIBean.java @@ -0,0 +1,124 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2009 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.gui.alert; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.jboss.seam.ScopeType; +import org.jboss.seam.annotations.Name; +import org.jboss.seam.annotations.Scope; + +import org.rhq.core.domain.configuration.Configuration; +import org.rhq.core.domain.configuration.PropertySimple; +import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; +import org.rhq.enterprise.server.alert.AlertNotificationManagerLocal; +import org.rhq.enterprise.server.util.LookupUtil; + +/** + * Backing bean for the new AlertNotifications stuff + * @author Heiko W. Rupp + */ +@Scope(ScopeType.PAGE) +@Name("ListNotificationsUIBean") +public class ListNotificationsUIBean { + + public static final String MANAGED_BEAN_NAME = "ListNotificationsUIBean"; + private static final String OUTCOME_SUCCESS = "success"; + + private final Log log = LogFactory.getLog(ListNotificationsUIBean.class); + + private String selectedSender; + + private ConfigurationDefinition alertConfigurationDefinition; + private Configuration alertProperties; + int ad; + + + public ListNotificationsUIBean() { + } + + public Map<String,String> getAllAlertSenders() { + AlertNotificationManagerLocal notificationManager = LookupUtil.getAlertNotificationManager(); + List<String> senders = notificationManager.listAllAlertSenders(); + Map<String,String> result = new HashMap<String,String>(); + for (String sender: senders) + result.put(sender,sender); + + return result; + } + + + public ConfigurationDefinition getAlertConfigurationDefinition() { + + if (alertConfigurationDefinition==null) { + lookupAlertConfigDefinition(); + } + + return alertConfigurationDefinition; + } + + private void lookupAlertConfigDefinition() { + AlertNotificationManagerLocal mgr = LookupUtil.getAlertNotificationManager(); + alertConfigurationDefinition = mgr.getConfigurationDefinitionForSender(selectedSender); + + } + + public Configuration getAlertProperties() { + AlertNotificationManagerLocal mgr = LookupUtil.getAlertNotificationManager(); + + // TODO in case of listing an existing notification get this from the properties on the notification + if (alertProperties==null) { + if (alertConfigurationDefinition==null) + alertConfigurationDefinition = getAlertConfigurationDefinition(); + alertProperties = alertConfigurationDefinition.getDefaultTemplate().getConfiguration(); + } + return alertProperties; + } + + public void setAlertProperties(Configuration alertProperties) { + this.alertProperties = alertProperties; + } + + public String getSelectedSender() { + return selectedSender; + } + + public void setSelectedSender(String selectedSender) { + this.selectedSender = selectedSender; + } + + public String mySubmitForm() { + System.out.println("In submit Form "); + log.info("In submit Form "); + return OUTCOME_SUCCESS; + } + + public int getAd() { + return ad; + } + + public void setAd(int ad) { + this.ad = ad; + } +} \ No newline at end of file diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-managed-beans/alert-beans.xml b/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-managed-beans/alert-beans.xml index 5f93540..d41bd31 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-managed-beans/alert-beans.xml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-managed-beans/alert-beans.xml @@ -10,14 +10,14 @@ <managed-bean-class>org.rhq.enterprise.gui.alert.ListAlertDefinitionsUIBean</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean> - + <!-- /rhq/resource/alert/listAlertHistory.xhtml --> <managed-bean> <managed-bean-name>ListAlertHistoryUIBean</managed-bean-name> <managed-bean-class>org.rhq.enterprise.gui.alert.ListAlertHistoryUIBean</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean> - + <!-- /rhq/admin/listAlertTemplates.xhtml --> <managed-bean> <managed-bean-name>ListAlertTemplatesUIBean</managed-bean-name> @@ -25,4 +25,12 @@ <managed-bean-scope>request</managed-bean-scope> </managed-bean>
+ <!-- /rhq/resource/alert/notif --> + <managed-bean> + <description>Handling of alert senders</description> + <managed-bean-name>ListNotificationsUIBean</managed-bean-name> + <managed-bean-class>org.rhq.enterprise.gui.alert.ListNotificationsUIBean</managed-bean-class> + <managed-bean-scope>request</managed-bean-scope> + </managed-bean> + </faces-config> \ No newline at end of file diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/resource/common/monitor/alerts/config/ViewDefinition.jsp b/modules/enterprise/gui/portal-war/src/main/webapp/resource/common/monitor/alerts/config/ViewDefinition.jsp index 66300cf..c445744 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/resource/common/monitor/alerts/config/ViewDefinition.jsp +++ b/modules/enterprise/gui/portal-war/src/main/webapp/resource/common/monitor/alerts/config/ViewDefinition.jsp @@ -1,10 +1,13 @@ <%@ page language="java" %> <%@ page errorPage="/common/Error.jsp" %> <%@ taglib uri="http://jakarta.apache.org/struts/tags-tiles" prefix="tiles" %> +<%@ taglib uri="http://jakarta.apache.org/struts/tags-html-el" prefix="html" %>
<tiles:insert definition=".page.title.events"> <tiles:put name="titleKey" value="alert.config.props.ViewDef.PageTitle"/> </tiles:insert> +<tiles:importAttribute name="id" ignore="true"/> +<tiles:importAttribute name="ad" ignore="true"/>
<tiles:insert definition=".portlet.error"/> <tiles:insert definition=".portlet.confirm"/> @@ -23,4 +26,6 @@
<tiles:insert definition=".events.config.view.nav"/>
+<a href="/rhq/resource/alert/notif/listAlertSender.xhtml?id=${param.id}&ad=${param.ad}">Alert sender stuff</a> <!-- TODO fix and pass real id + ad--> + <tiles:insert definition=".page.footer"/> diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/alert/notif/listAlertSender.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/alert/notif/listAlertSender.xhtml new file mode 100644 index 0000000..e902b81 --- /dev/null +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/alert/notif/listAlertSender.xhtml @@ -0,0 +1,73 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<html xmlns="http://www.w3.org/1999/xhtml" + xmlns:h="http://java.sun.com/jsf/html" + xmlns:f="http://java.sun.com/jsf/core" + xmlns:ui="http://java.sun.com/jsf/facelets" + xmlns:c="http://java.sun.com/jstl/core" + xmlns:onc="http://jboss.org/on/component" + xmlns:a4j="https://richfaces.org/a4j" + xmlns:rich="http://richfaces.ajax4jsf.org/rich%22%3E + +<ui:composition template="/rhq/layout/main.xhtml"> + + <ui:param name="pageTitle" value="List Alert Notifications for Resource"/> <!-- '#{ResourceUIBean.name}'"/> --> + + <ui:define name="breadcrumbs"> + <h:outputLink value="http://localhost:7080/alerts/Config.do%22%3E + <f:param name="mode" value="viewRoles"/> + <f:param name="id" value="#{param.id}"/> + <f:param name="ad" value="#{param.ad}"/> + <h:outputText>Alert Definitions</h:outputText> + </h:outputLink> + <h:outputText> > </h:outputText> + <h:outputLink value="listAlertSender.xhtml"> + Alert Sender stuff + </h:outputLink> + </ui:define> + + <ui:define name="body"> + <br/> + <h:messages showSummary="true" + showDetail="true" + infoClass="InfoBlock" + warnClass="WarnBlock" + errorClass="ErrorBlock" + fatalClass="FatalBlock" + globalOnly="true" + layout="table" + width="100%"/> + + <p/> + <h:outputText>Hello World</h:outputText> + <h:form id="listSenderForm"> + <input type="hidden" name="id" value="${param.id}"/> + <input type="hidden" name="ad" value="${param.ad}"/> + <h:selectOneMenu id="senderList" value="#{ListNotificationsUIBean.selectedSender}"> + <f:selectItems value="#{ListNotificationsUIBean.allAlertSenders}"/> + </h:selectOneMenu> + <h:commandButton + id="submit" + value="go" + action="nextPage"/> + + <p/> + <rich:panel rendered="#{ListNotificationsUIBean.selectedSender != null}"> + <h:outputText>Properties for: #{ListNotificationsUIBean.selectedSender}</h:outputText> + <h:outputText>Rendered:</h:outputText> + <h:outputText value="#{ListNotificationsUIBean.selectedSender}"/> + <onc:config + configurationDefinition="#{ListNotificationsUIBean.alertConfigurationDefinition}" + configuration="#{ListNotificationsUIBean.alertProperties}" + readOnly="false"/> + <h:commandButton + id="submit2" + value="Submit it" + type="submit" + action="#{ListNotificationsUIBean.mySubmitForm}" + /> + </rich:panel> + </h:form> + </ui:define> +</ui:composition> +</html> \ No newline at end of file diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerBean.java index 78d4342..0c1a1a5 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerBean.java @@ -61,6 +61,9 @@ import org.rhq.core.domain.alert.notification.SnmpNotification; import org.rhq.core.domain.alert.notification.SubjectNotification; import org.rhq.core.domain.auth.Subject; import org.rhq.core.domain.authz.Permission; +import org.rhq.core.domain.configuration.Configuration; +import org.rhq.core.domain.configuration.Property; +import org.rhq.core.domain.configuration.PropertySimple; import org.rhq.core.domain.criteria.AlertCriteria; import org.rhq.core.domain.measurement.MeasurementSchedule; import org.rhq.core.domain.measurement.MeasurementUnits; @@ -83,6 +86,11 @@ import org.rhq.enterprise.server.core.EmailManagerLocal; import org.rhq.enterprise.server.measurement.instrumentation.MeasurementMonitor; import org.rhq.enterprise.server.measurement.util.MeasurementFormatter; import org.rhq.enterprise.server.operation.OperationManagerLocal; +import org.rhq.enterprise.server.plugin.pc.MasterServerPluginContainer; +import org.rhq.enterprise.server.plugin.pc.alert.AlertSender; +import org.rhq.enterprise.server.plugin.pc.alert.AlertSenderPluginManager; +import org.rhq.enterprise.server.plugin.pc.alert.AlertServerPluginContainer; +import org.rhq.enterprise.server.plugin.pc.alert.SenderResult; import org.rhq.enterprise.server.resource.ResourceManagerLocal; import org.rhq.enterprise.server.system.SystemManagerLocal; import org.rhq.enterprise.server.util.CriteriaQueryGenerator; @@ -182,7 +190,7 @@ public class AlertManagerBean implements AlertManagerLocal, AlertManagerRemote { }
/* - * Since BULK delete JPQL doesn't enforce cascade options, we need to delete the logs first and then the + * Since BULK delete JPQL doesn't enforce cascade options, we need to delete the logs first and then the * corresponding Alerts */ long totalTime = 0L; @@ -533,6 +541,22 @@ public class AlertManagerBean implements AlertManagerLocal, AlertManagerRemote { } }
+ /** + * Mark the matching alert as acknowledged by the user + * @param alertId Id of the alert to acknowledge + * @param user user who acknowledged the alert + */ + public void acknowledgeAlert(int alertId, Subject user) { + Alert alert = entityManager.find(Alert.class,alertId); + if (alert==null) { + log.warn("Alert [ " + alertId + " ] to acknowledge was not found "); + return; + } + alert.setAckBy(user); + alert.setAckTime(System.currentTimeMillis()); + } + + public void fireAlert(int alertDefinitionId) { log.debug("Firing an alert for alertDefinition with id=" + alertDefinitionId + "...");
@@ -640,12 +664,45 @@ public class AlertManagerBean implements AlertManagerLocal, AlertManagerRemote { } }
+ AlertNotification test = new AlertNotification(alert.getAlertDefinition()); + test.setSenderName("Email"); + test.setConfiguration(new Configuration()); + Property prop = new PropertySimple("emailAddress","hwr@redhat.com"); + test.getConfiguration().getProperties().add(prop); + AlertSender sender = getAlertSender(test); + if (sender!=null) { + try { + SenderResult result = sender.send(alert); + } + catch (Throwable t) { + log.error("Sender failed: " + t.getMessage()); + } + } + sendAlertNotificationEmails(alert, emailAddresses); } catch (Exception e) { log.error("Failed to send all notifications for " + alert.toSimpleString(), e); } }
+ /** + * Return the plugin manager that is managing alert sender plugins + * @return The alert sender plugin manager + */ + public AlertSenderPluginManager getAlertPluginManager() { + MasterServerPluginContainer container = LookupUtil.getServerPluginService().getMasterPluginContainer(); + AlertServerPluginContainer pc = container.getPluginContainerByClass(AlertServerPluginContainer.class); + AlertSenderPluginManager manager = (AlertSenderPluginManager) pc.getPluginManager(); + + return manager; + } + + AlertSender getAlertSender(AlertNotification notification) { + AlertSenderPluginManager manager = getAlertPluginManager(); + AlertSender sender = manager.getAlertSenderForNotification(notification); + return sender; + } + private void processEmailAddress(Alert alert, String emailAddress, Set<String> emailAddresses) { if (emailAddress == null) { return; @@ -872,10 +929,10 @@ public class AlertManagerBean implements AlertManagerLocal, AlertManagerRemote { }
/* - * there's no reason to update the cache directly anymore. even though this direct type of update is safe + * there's no reason to update the cache directly anymore. even though this direct type of update is safe * (because we know the AlertManager will only be executing on the same server instance that is processing - * these recovery alerts now) it's unnecessary because changes made via the AlertDefinitionManager will - * update the cache indirectly via the status field on the owning agent and the periodic job that checks it. + * these recovery alerts now) it's unnecessary because changes made via the AlertDefinitionManager will + * update the cache indirectly via the status field on the owning agent and the periodic job that checks it. */ } else if (firedDefinition.getWillRecover()) { log.debug("Disabling " + firedDefinition + " until recovered manually or by recovery definition"); @@ -888,10 +945,10 @@ public class AlertManagerBean implements AlertManagerLocal, AlertManagerRemote { alertDefinitionManager.disableAlertDefinitions(overlord, new Integer[] { firedDefinition.getId() });
/* - * there's no reason to update the cache directly anymore. even though this direct type of update is safe + * there's no reason to update the cache directly anymore. even though this direct type of update is safe * (because we know the AlertManager will only be executing on the same server instance that is processing - * these recovery alerts now) it's unnecessary because changes made via the AlertDefinitionManager will - * update the cache indirectly via the status field on the owning agent and the periodic job that checks it. + * these recovery alerts now) it's unnecessary because changes made via the AlertDefinitionManager will + * update the cache indirectly via the status field on the owning agent and the periodic job that checks it. */ } } @@ -911,4 +968,4 @@ public class AlertManagerBean implements AlertManagerLocal, AlertManagerRemote {
return alerts; } -} \ No newline at end of file +} diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerLocal.java index 3fde62d..5b3479c 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerLocal.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerLocal.java @@ -30,6 +30,7 @@ import org.rhq.core.domain.auth.Subject; import org.rhq.core.domain.criteria.AlertCriteria; import org.rhq.core.domain.util.PageControl; import org.rhq.core.domain.util.PageList; +import org.rhq.enterprise.server.plugin.pc.alert.AlertSenderPluginManager;
/** * @author Joseph Marques @@ -86,4 +87,17 @@ public interface AlertManagerLocal { // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
PageList<Alert> findAlertsByCriteria(Subject subject, AlertCriteria criteria); + + /** + * Mark the matching alert as acknowledged by the user + * @param alertId Id of the alert to acknowledge + * @param user user who acknowledged the alert + */ + void acknowledgeAlert(int alertId, Subject user); + + /** + * Return the plugin manager that is managing alert sender plugins + * @return The alert sender plugin manager + */ + AlertSenderPluginManager getAlertPluginManager(); } \ No newline at end of file diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerBean.java index c8d4c54..de7362e 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerBean.java @@ -34,6 +34,8 @@ import javax.persistence.Query; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory;
+import org.rhq.core.clientapi.agent.metadata.ConfigurationMetadataParser; +import org.rhq.core.clientapi.descriptor.configuration.ConfigurationDescriptor; import org.rhq.core.domain.alert.AlertDefinition; import org.rhq.core.domain.alert.AlertDefinitionContext; import org.rhq.core.domain.alert.notification.AlertNotification; @@ -44,6 +46,9 @@ import org.rhq.core.domain.alert.notification.SubjectNotification; import org.rhq.core.domain.auth.Subject; import org.rhq.core.domain.authz.Permission; import org.rhq.core.domain.authz.Role; +import org.rhq.core.domain.configuration.Configuration; +import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; +import org.rhq.core.domain.plugin.PluginKey; import org.rhq.core.domain.util.PageControl; import org.rhq.core.domain.util.PageList; import org.rhq.core.domain.util.PersistenceUtility; @@ -52,6 +57,12 @@ import org.rhq.enterprise.server.auth.SubjectManagerLocal; import org.rhq.enterprise.server.authz.AuthorizationManagerLocal; import org.rhq.enterprise.server.authz.PermissionException; import org.rhq.enterprise.server.authz.RoleManagerLocal; +import org.rhq.enterprise.server.configuration.ConfigurationManagerLocal; +import org.rhq.enterprise.server.configuration.metadata.ConfigurationMetadataManagerLocal; +import org.rhq.enterprise.server.plugin.ServerPluginsLocal; +import org.rhq.enterprise.server.plugin.pc.alert.AlertSenderPluginManager; +import org.rhq.enterprise.server.xmlschema.generated.serverplugin.ServerPluginDescriptorType; +import org.rhq.enterprise.server.xmlschema.generated.serverplugin.alert.AlertPluginDescriptorType;
/** * @author Joseph Marques @@ -66,6 +77,8 @@ public class AlertNotificationManagerBean implements AlertNotificationManagerLoc @EJB private AlertTemplateManagerLocal alertTemplateManager; @EJB + private AlertManagerLocal alertManager; + @EJB private GroupAlertDefinitionManagerLocal groupAlertDefintionManager; @EJB private AuthorizationManagerLocal authorizationManager; @@ -73,6 +86,12 @@ public class AlertNotificationManagerBean implements AlertNotificationManagerLoc private RoleManagerLocal roleManager; @EJB private SubjectManagerLocal subjectManager; + @EJB + private ConfigurationMetadataManagerLocal confMeMan; + @EJB + private ServerPluginsLocal serverPluginsBean; + @EJB + private ConfigurationManagerLocal configManager;
@PersistenceContext(unitName = RHQConstants.PERSISTENCE_UNIT_NAME) private EntityManager entityManager; @@ -84,7 +103,7 @@ public class AlertNotificationManagerBean implements AlertNotificationManagerLoc * into AlertDefinitionManager.updateAlertDefinition() which starts a new transaction, the work will be * performed at the AlertTemplate layer twice. This would result in duplicate notifications (RHQ-629) as * well as errors during removal (which would be attempted twice for each being removed). - * + * * Must, however, return an AlertDefinition with a copy of the ids because the removeNotifications method * needs to compare ids to figure out what to remove from the set of notifications. */ @@ -430,4 +449,52 @@ public class AlertNotificationManagerBean implements AlertNotificationManagerLoc } } } + + public void handleAlertConfigurationDefinition(ConfigurationDefinition desc) { + + // TODO + } + + public Configuration getAlertPropertiesConfiguration(AlertNotification notification) { + Configuration config = notification.getConfiguration(); + if (config!=null) + config = config.deepCopy(); + + return config; + } + + public ConfigurationDefinition getConfigurationDefinitionForSender(String shortName) { + AlertSenderPluginManager pluginmanager = alertManager.getAlertPluginManager(); + String pluginName = pluginmanager.getPluginNameForShortName(shortName); + PluginKey key = pluginmanager.getAlertSenderInfo(shortName).getPluginKey(); + try { + AlertPluginDescriptorType descriptor = (AlertPluginDescriptorType) serverPluginsBean.getServerPluginDescriptor(key); + // TODO get alert-propertis, not plugin-configuration + //ConfigurationDefinition pluginConfigurationDefinition = ConfigurationMetadataParser.parse("pc:" + pluginName, descriptor.getPluginConfiguration()); + ConfigurationDefinition pluginConfigurationDefinition = ConfigurationMetadataParser.parse("alerts:" + pluginName, descriptor.getAlertConfiguration()); + + + return pluginConfigurationDefinition; + } + catch (Exception e) { + LOG.error(e); + return null; + } + } + + public Configuration getDefaultAlertConfiguration(ConfigurationDefinition def) { + Configuration config = configManager.getConfigurationFromDefaultTemplate(def); + + return config; + } + + /** + * Return a list of all available AlertSenders in the system by their shortname. + * @return list of senders. + */ + public List<String> listAllAlertSenders() { + AlertSenderPluginManager pluginmanager = alertManager.getAlertPluginManager(); + List<String> senders = pluginmanager.getPluginList(); + return senders; + } } \ No newline at end of file diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerLocal.java index ac42a32..532bd95 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerLocal.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerLocal.java @@ -18,13 +18,19 @@ */ package org.rhq.enterprise.server.alert;
+import java.util.List; + import javax.ejb.Local;
+import org.rhq.core.clientapi.descriptor.configuration.ConfigurationDescriptor; +import org.rhq.core.domain.alert.notification.AlertNotification; import org.rhq.core.domain.alert.notification.EmailNotification; import org.rhq.core.domain.alert.notification.RoleNotification; import org.rhq.core.domain.alert.notification.SnmpNotification; import org.rhq.core.domain.alert.notification.SubjectNotification; import org.rhq.core.domain.auth.Subject; +import org.rhq.core.domain.configuration.Configuration; +import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; import org.rhq.core.domain.util.PageControl; import org.rhq.core.domain.util.PageList;
@@ -63,4 +69,18 @@ public interface AlertNotificationManagerLocal { int removeNotifications(Subject subject, Integer alertDefinitionId, Integer[] notificationIds);
int purgeOrphanedAlertNotifications(); + + void handleAlertConfigurationDefinition(ConfigurationDefinition desc); + + public Configuration getAlertPropertiesConfiguration(AlertNotification notification); + + /** + * Return a list of all available AlertSenders in the system by their shortname. + * @return list of senders. + */ + List<String> listAllAlertSenders(); + + ConfigurationDefinition getConfigurationDefinitionForSender(String shortName); + + Configuration getDefaultAlertConfiguration(ConfigurationDefinition def); } \ No newline at end of file diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSenderInfo.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSenderInfo.java new file mode 100644 index 0000000..ac03577 --- /dev/null +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSenderInfo.java @@ -0,0 +1,67 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2009 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.plugin.pc.alert; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.rhq.core.domain.plugin.PluginKey; + +/** + * Information about an {@link AlertSender} + * @author Heiko W. Rupp + */ +public class AlertSenderInfo { + + private String shortName; + private String description; + private String pluginName; + private PluginKey pluginKey; + + public AlertSenderInfo(String shortName, String description, PluginKey key) { + this.shortName = shortName; + this.description = description; + this.pluginKey = key; + this.pluginName = key.getPluginName(); + } + + public String getShortName() { + return shortName; + } + + public void setShortName(String shortName) { + this.shortName = shortName; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getPluginName() { + return pluginName; + } + + public PluginKey getPluginKey() { + return pluginKey; + } +} diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSenderPluginManager.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSenderPluginManager.java index bc939bf..cb92a91 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSenderPluginManager.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSenderPluginManager.java @@ -25,17 +25,26 @@ import java.util.Map;
import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.w3c.dom.Element;
+import org.rhq.core.clientapi.descriptor.configuration.ConfigurationDescriptor; +import org.rhq.core.domain.alert.notification.AlertNotification; import org.rhq.core.domain.configuration.Configuration; +import org.rhq.core.domain.plugin.Plugin; +import org.rhq.core.domain.plugin.PluginKey; +import org.rhq.core.domain.plugin.ServerPlugin; +import org.rhq.enterprise.server.alert.AlertNotificationManagerLocal; +import org.rhq.enterprise.server.plugin.ServerPluginsLocal; import org.rhq.enterprise.server.plugin.pc.AbstractTypeServerPluginContainer; +import org.rhq.enterprise.server.plugin.pc.ServerPluginContext; import org.rhq.enterprise.server.plugin.pc.ServerPluginEnvironment; import org.rhq.enterprise.server.plugin.pc.ServerPluginManager; +import org.rhq.enterprise.server.util.LookupUtil; import org.rhq.enterprise.server.xmlschema.generated.serverplugin.alert.AlertPluginDescriptorType;
/** - * TODO + * Plugin manager that takes care of loading the plug-ins and instantiating + * of {@link AlertSender} etc. * @author Heiko W. Rupp */ public class AlertSenderPluginManager extends ServerPluginManager { @@ -44,14 +53,24 @@ public class AlertSenderPluginManager extends ServerPluginManager { private Map<String,String> pluginNameToType = new HashMap<String, String>(); private Map<String,String> pluginClassByName = new HashMap<String, String>(); private Map<String,ServerPluginEnvironment> pluginEnvByName = new HashMap<String, ServerPluginEnvironment>(); + private Map<String,AlertSenderInfo> senderInfoByName = new HashMap<String, AlertSenderInfo>();
public AlertSenderPluginManager(AbstractTypeServerPluginContainer pc) { super(pc); }
+ /** + * Postprocess the loading of the plugin - the actual load is done + * in the super class. + * Here we verify that the passed <plugin-class> is valid and build the + * list of plugins that can be queried by the UI etc. + * @param env the environment of the plugin to be loaded + * + * @throws Exception + */ @Override public void loadPlugin(ServerPluginEnvironment env) throws Exception { - super.loadPlugin(env); // TODO: Customise this generated block + super.loadPlugin(env);
AlertPluginDescriptorType type = (AlertPluginDescriptorType) env.getPluginDescriptor();
@@ -64,20 +83,37 @@ public class AlertSenderPluginManager extends ServerPluginManager { } catch (Exception e) { log.warn("Can't find pluginClass " + className + ". Plugin will be ignored"); + try { + unloadPlugin(env); + } + catch (Throwable t) { + log.warn(" +--> unload failed too " + t.getMessage()); + } return; } String shortName = ((Element) type.getShortName()).getTextContent(); pluginClassByName.put(shortName,className); - pluginNameToType.put(shortName,env.getPluginName()); + senderInfoByName.put(shortName,new AlertSenderInfo(shortName,"-TODO-",env.getPluginKey())); + pluginEnvByName.put(shortName,env);
- } + ConfigurationDescriptor desc = type.getAlertConfiguration();
+ AlertNotificationManagerLocal mgr = LookupUtil.getAlertNotificationManager(); + mgr.handleAlertConfigurationDefinition(null); // TODO + }
- public AlertSender getAlertSenderForType(String shortName) { + /** + * Instantiate an AlertSender for the passed shortName, which is the name you have provided + * in the plugin descriptor in the <shortName> element + * @param notification + * @return a new AlertSender with preferences set + * @see AlertSender + */ + public AlertSender getAlertSenderForNotification(AlertNotification notification) {
- String className = pluginClassByName.get(shortName); - ServerPluginEnvironment env = pluginEnvByName.get(shortName); + String className = pluginClassByName.get(notification.getSenderName()); + ServerPluginEnvironment env = pluginEnvByName.get(notification.getSenderName()); Class clazz; try { clazz = Class.forName(className,true,env.getPluginClassLoader()); @@ -98,8 +134,27 @@ public class AlertSenderPluginManager extends ServerPluginManager { return null; }
- sender.alertParameters = new Configuration(); // TODO - sender.preferences = new Configuration(); // TODO + // TODO We have no entityManager lying around here, which means + // Configuration is an uninitialized Proxy and we'd get a LazyInit + // Exception later. + // So lets get a session and attach the stuff... TODO + ServerPluginContext ctx = getServerPluginContext(env); + AlertNotificationManagerLocal mgr = LookupUtil.getAlertNotificationManager(); + + + sender.alertParameters = mgr.getAlertPropertiesConfiguration(notification); + if (sender.alertParameters == null) + sender.alertParameters = new Configuration(); // Safety measure + + ServerPluginsLocal pluginsMgr = LookupUtil.getServerPlugins(); + + PluginKey key = ctx.getPluginEnvironment().getPluginKey(); + ServerPlugin plugin = pluginsMgr.getServerPlugin(key); + plugin = pluginsMgr.getServerPluginRelationships(plugin); + + sender.preferences = plugin.getPluginConfiguration(); + if (sender.preferences==null) + sender.preferences = new Configuration(); // Safety measure
return sender; } @@ -111,4 +166,13 @@ public class AlertSenderPluginManager extends ServerPluginManager { public List<String> getPluginList() { return new ArrayList<String>(pluginClassByName.keySet()); } + + + public String getPluginNameForShortName(String shortName) { + return pluginNameToType.get(shortName); + } + + public AlertSenderInfo getAlertSenderInfo(String shortName) { + return senderInfoByName.get(shortName); + } } diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertServerPluginContainer.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertServerPluginContainer.java index d9025a9..3de6d0d 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertServerPluginContainer.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertServerPluginContainer.java @@ -57,6 +57,12 @@ public class AlertServerPluginContainer extends AbstractTypeServerPluginContaine }
@Override + public void shutdown() { + //getPluginManager().un + super.shutdown(); // TODO: Customise this generated block + } + + @Override protected ServerPluginManager createPluginManager() { return new AlertSenderPluginManager(this); } diff --git a/modules/enterprise/server/plugins/alert-email/pom.xml b/modules/enterprise/server/plugins/alert-email/pom.xml index d76bdbb..85dbd6d 100644 --- a/modules/enterprise/server/plugins/alert-email/pom.xml +++ b/modules/enterprise/server/plugins/alert-email/pom.xml @@ -9,7 +9,7 @@ </parent> <modelVersion>4.0.0</modelVersion>
- <groupId>org.rhq</groupId> + <groupId>org.rhq.server</groupId> <artifactId>alert-email</artifactId> <version>1.4.0-SNAPSHOT</version>
@@ -21,7 +21,7 @@ </scm>
<properties> - <scm.module.path>modules/enterprise/server/plugins/disk/</scm.module.path> + <scm.module.path>modules/enterprise/server/plugins/alert-email/</scm.module.path> </properties>
<dependencies> @@ -55,7 +55,7 @@ <scope>provided</scope> <!-- needed for referenced domain entities that use Hibernate annotations --> </dependency> - + </dependencies>
<build> @@ -134,4 +134,4 @@ </profiles>
-</project> \ No newline at end of file +</project> diff --git a/modules/enterprise/server/plugins/alert-email/src/main/java/org/rhq/enterprise/server/plugins/alertEmail/EmailSender.java b/modules/enterprise/server/plugins/alert-email/src/main/java/org/rhq/enterprise/server/plugins/alertEmail/EmailSender.java index 581eb94..ad7f0b4 100644 --- a/modules/enterprise/server/plugins/alert-email/src/main/java/org/rhq/enterprise/server/plugins/alertEmail/EmailSender.java +++ b/modules/enterprise/server/plugins/alert-email/src/main/java/org/rhq/enterprise/server/plugins/alertEmail/EmailSender.java @@ -42,18 +42,26 @@ import org.rhq.enterprise.server.plugin.pc.alert.SenderResult; public class EmailSender extends AlertSender {
private final Log log = LogFactory.getLog(EmailSender.class); + private static final String SMTP_HOST = "rhq.server.email.smtp-host"; + private static final String SMTP_PORT = "rhq.server.email.smtp-port"; + private static final String EMAIL_FROM = "rhq.server.email.from-address";
@Override public SenderResult send(Alert alert) {
+ if(preferences!=null) + preferences.getProperties().size(); + String emailAddress = alertParameters.getSimpleValue("emailAddress",null); if (emailAddress==null) { log.warn("Email address was null, should not happen"); return new SenderResult(ResultState.FAILURE,"No email address given"); }
- String mailserver = preferences.getSimpleValue("mailserver","localhost"); // TODO get RHQ default one - String senderAddress = preferences.getSimpleValue("senderEmail","rhqadmin@localhost"); // TODO get RHQ default one + String tmp = System.getProperty(SMTP_HOST,"localhost"); + String mailserver = preferences.getSimpleValue("mailserver",tmp); + tmp = System.getProperty(EMAIL_FROM, "rhqadmin@localhost"); + String senderAddress = preferences.getSimpleValue("senderEmail",tmp);
Properties props = new Properties(); props.put("mail.smtp.host",mailserver); @@ -61,7 +69,7 @@ public class EmailSender extends AlertSender { Message message = new SMTPMessage(session); try { message.setFrom(new InternetAddress(senderAddress)); - message.setRecipient(Message.RecipientType.TO,new InternetAddress("hwr@redhat.com")); + message.setRecipient(Message.RecipientType.TO,new InternetAddress(emailAddress)); message.setSubject("Alert on " + "Dummy - TODO"); message.setText("Li la lu, nur der Mann im Mond schaut zu"); Transport.send(message); diff --git a/modules/enterprise/server/plugins/alert-email/src/main/resources/META-INF/rhq-serverplugin.xml b/modules/enterprise/server/plugins/alert-email/src/main/resources/META-INF/rhq-serverplugin.xml index 2590490..663185e 100644 --- a/modules/enterprise/server/plugins/alert-email/src/main/resources/META-INF/rhq-serverplugin.xml +++ b/modules/enterprise/server/plugins/alert-email/src/main/resources/META-INF/rhq-serverplugin.xml @@ -23,13 +23,16 @@ <!-- Global preferences for all email alerts --> serverplugin:plugin-configuration <c:simple-property name="mailserver" displayName="Mail server address" type="longString" - description="Address of the mail server to use (if not the default RHQ one )"/> + description="Address of the mail server to use (if not the default RHQ one )" + required="false"/> <c:simple-property name="senderEmail" displayName="Email of sender" type="string" - description="Email of the account from which alert emails should come from"/> + description="Email of the account from which alert emails should come from" + required="false"/> <c:simple-property name="needsLogin" displayName="Needs credentials?" - description="Mark this field if the server needs credentials to send email and give them below" type="boolean"/> - <c:simple-property name="user" type="string"/> - <c:simple-property name="password" type="password" /> + description="Mark this field if the server needs credentials to send email and give them below" type="boolean" + default="false"/> + <c:simple-property name="user" type="string" required="false"/> + <c:simple-property name="password" type="password" required="false"/>
</serverplugin:plugin-configuration>
@@ -45,4 +48,4 @@ description="Email addresses (separated by comma) used for notifications."/> </alert-configuration>
-</alert-plugin> \ No newline at end of file +</alert-plugin>
commit aa1bd4318448550ea1418dd82deb373d40de6c8b Author: Heiko W. Rupp pilhuhn@fedorapeople.org Date: Mon Nov 30 08:55:21 2009 +0100
Pull up master/master and fix the conflicts that I had.
diff --git a/etc/samples/custom-serverplugin/src/main/java/org/custom/MyLifecycleListener.java b/etc/samples/custom-serverplugin/src/main/java/org/custom/MyLifecycleListener.java index 699ac49..51397c6 100644 --- a/etc/samples/custom-serverplugin/src/main/java/org/custom/MyLifecycleListener.java +++ b/etc/samples/custom-serverplugin/src/main/java/org/custom/MyLifecycleListener.java @@ -66,7 +66,7 @@ public class MyLifecycleListener implements ServerPluginComponent { }
StringBuilder str = new StringBuilder(); - str.append("plugin-name=").append(this.context.getPluginEnvironment().getPluginName()).append(","); + str.append("plugin-key=").append(this.context.getPluginEnvironment().getPluginKey()).append(","); str.append("plugin-url=").append(this.context.getPluginEnvironment().getPluginUrl()).append(","); str.append("plugin-config=[").append(getPluginConfigurationString()).append(']'); // do not append , return str.toString(); diff --git a/modules/core/dbutils/pom.xml b/modules/core/dbutils/pom.xml index 8f466be..83fa2a2 100644 --- a/modules/core/dbutils/pom.xml +++ b/modules/core/dbutils/pom.xml @@ -22,7 +22,7 @@
<properties> <scm.module.path>modules/core/dbutils/</scm.module.path> - <db.schema.version>2.69.1</db.schema.version> + <db.schema.version>2.69.3</db.schema.version> </properties>
<dependencies> diff --git a/modules/core/dbutils/src/main/scripts/dbsetup/amps-schema.xml b/modules/core/dbutils/src/main/scripts/dbsetup/amps-schema.xml index dbc4a19..1d111cf 100644 --- a/modules/core/dbutils/src/main/scripts/dbsetup/amps-schema.xml +++ b/modules/core/dbutils/src/main/scripts/dbsetup/amps-schema.xml @@ -19,12 +19,14 @@ <column name="CTIME" type="LONG" required="true"/> <column name="MTIME" type="LONG" required="true"/> <column name="DEPLOYMENT" size="8" type="VARCHAR2" required="true"/> + <column name="PTYPE" size="200" type="VARCHAR2" required="false"/> <column name="PLUGIN_CONFIG_ID" type="INTEGER" references="RHQ_CONFIG" required="false"/> <column name="JOBS_CONFIG_ID" type="INTEGER" references="RHQ_CONFIG" required="false"/> <column name="CONTENT" type="BLOB" required="false"/>
- <index name="RHQ_PLUGIN_NAME_IDX" unique="true"> + <index name="RHQ_PLUGIN_NAME_DEPLOY_IDX" unique="true"> <field ref="NAME"/> + <field ref="DEPLOYMENT"/> </index> </table>
diff --git a/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml b/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml index 07831eb..c28b862 100644 --- a/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml +++ b/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml @@ -2183,6 +2183,23 @@ <schema-alterColumn table="RHQ_PLUGIN" column="STATUS" nullable="FALSE"/> </schemaSpec>
+ <schemaSpec version="2.69.2"> + <!-- plugin names must be unique only if they are deployed on the same side (agent vs. server) --> + <schema-directSQL> + <statement desc="Dropping unique index on RHQ_PLUGIN (NAME)"> + DROP INDEX RHQ_PLUGIN_NAME_IDX + </statement> + <statement desc="Creating unique index on RHQ_PLUGIN (NAME, DEPLOYMENT) so server plugin names need not be unique with agent plugins"> + CREATE UNIQUE INDEX RHQ_PLUGIN_NAME_DEPLOY_IDX ON RHQ_PLUGIN (NAME, DEPLOYMENT) + </statement> + </schema-directSQL> + </schemaSpec> + + <schemaSpec version="2.69.3"> + <!-- add the new column that indicates what type of plugin this is (e.g. alert, generic, content) - for server plugins only --> + <schema-addColumn table="RHQ_PLUGIN" column="PTYPE" columnType="VARCHAR2" precision="200"/> + </schemaSpec> + </dbupgrade> </target> </project> diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/plugin/AbstractPlugin.java b/modules/core/domain/src/main/java/org/rhq/core/domain/plugin/AbstractPlugin.java new file mode 100644 index 0000000..6ff9cb5 --- /dev/null +++ b/modules/core/domain/src/main/java/org/rhq/core/domain/plugin/AbstractPlugin.java @@ -0,0 +1,401 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2009 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, version 2, as + * published by the Free Software Foundation, and/or the GNU Lesser + * General Public License, version 2.1, also as published by the Free + * Software Foundation. + * + * 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 and the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * and the GNU Lesser 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.core.domain.plugin; + +import java.io.ByteArrayInputStream; +import java.io.Serializable; + +import javax.persistence.Column; +import javax.persistence.DiscriminatorColumn; +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Inheritance; +import javax.persistence.InheritanceType; +import javax.persistence.PrePersist; +import javax.persistence.SequenceGenerator; +import javax.persistence.Table; + +import org.rhq.core.util.MessageDigestGenerator; + +/** + * Base plugin implementation that agent and server plugin implementations extend. + * + * @author John Mazzitelli + */ +@DiscriminatorColumn(name = "DEPLOYMENT") +@Inheritance(strategy = InheritanceType.SINGLE_TABLE) +@Entity +@SequenceGenerator(name = "SEQ", sequenceName = "RHQ_PLUGIN_ID_SEQ") +@Table(name = Plugin.TABLE_NAME) +public class AbstractPlugin implements Serializable { + private static final long serialVersionUID = 1L; + + public static final String TABLE_NAME = "RHQ_PLUGIN"; + + @Column(name = "ID", nullable = false) + @GeneratedValue(strategy = GenerationType.AUTO, generator = "SEQ") + @Id + private int id; + + @Column(name = "DEPLOYMENT", nullable = false, insertable = false, updatable = false) + @Enumerated(EnumType.STRING) + private PluginDeploymentType deployment; + + @Column(name = "NAME", nullable = false) + private String name; + + @Column(name = "DISPLAY_NAME", nullable = false) + private String displayName; + + @Column(name = "DESCRIPTION", nullable = true) + private String description; + + @Column(name = "ENABLED", nullable = false) + private boolean enabled = true; + + @Column(name = "STATUS", nullable = false) + @Enumerated(EnumType.STRING) + private PluginStatusType status = PluginStatusType.INSTALLED; + + @Column(name = "HELP", nullable = true) + private String help; + + @Column(name = "VERSION", nullable = true) + private String version; + + @Column(name = "AMPS_VERSION", nullable = true) + private String ampsVersion; + + @Column(name = "PATH", nullable = false) + private String path; + + @Column(name = "MD5", nullable = false) + private String md5; + + @Column(name = "CTIME", nullable = false) + private long ctime; + + @Column(name = "MTIME", nullable = false) + private long mtime; + + @Column(name = "CONTENT", nullable = true) + private byte[] content; + + public AbstractPlugin() { + } + + /** + * Constructor for {@link Plugin}. + * + * @param name the logical name of the plugin + * @param path the actual filename of the plugin jar (see {@link #getPath()}) + */ + public AbstractPlugin(String name, String path) { + this.name = name; + this.path = path; + } + + /** + * Constructor for {@link Plugin}. + * Note that this allows you to provide an MD5 without providing the plugin's + * actual content. If you wish to persist this entity in the database, you should + * either provide the {@link #setContent(byte[]) content} or update the entity + * later by streaming the file content to the content column. + * + * @param name the logical name of the plugin + * @param path the actual filename of the plugin jar (see {@link #getPath()}) + * @param md5 the MD5 hash string of the plugin jar contents + */ + public AbstractPlugin(String name, String path, String md5) { + this.name = name; + this.path = path; + this.md5 = md5; + } + + /** + * Constructor for {@link Plugin}. + * + * @param name the logical name of the plugin + * @param path the actual filename of the plugin jar (see {@link #getPath()}) + * @param content the actual jar file contents (the MD5 hash string will be generated from this) + */ + public AbstractPlugin(String name, String path, byte[] content) { + this.name = name; + this.path = path; + this.content = content; + + try { + ByteArrayInputStream stream = new ByteArrayInputStream(content); + this.md5 = MessageDigestGenerator.getDigestString(stream); + } catch (Exception e) { + throw new RuntimeException("Cannot determine plugin's MD5!", e); + } + } + + /** + * Constructor that can build the full object except for the content byte array. + * This is used mainly for the named queries that want to return a Plugin object + * but does not eagerly load in the content array. + */ + public AbstractPlugin(int id, String name, String path, String displayName, boolean enabled, + PluginStatusType status, String description, String help, String md5, String version, String ampsVersion, + PluginDeploymentType deployment, long ctime, long mtime) { + this.id = id; + this.name = name; + this.path = path; + this.displayName = displayName; + this.enabled = enabled; + this.status = status; + this.description = description; + this.help = help; + this.md5 = md5; + this.version = version; + this.ampsVersion = ampsVersion; + this.deployment = deployment; + this.ctime = ctime; + this.mtime = mtime; + } + + public int getId() { + return this.id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + + /** + * See the javadoc of {@link #getMtime()} for + * information about this field and its relationship + * with "mtime". + * + * @return the time when this entity was persisted + */ + public long getCtime() { + return this.ctime; + } + + public void setCtime(long ctime) { + this.ctime = ctime; + } + + /** + * The "mtime" of the plugin has slightly different semantics + * than other "mtime" values found elsewhere. The "mtime" + * will typically be the time that the content field was modified, + * not necessarily the time when any field was modified. In other + * words, look at "mtime" if you want to know when the actual + * plugin content was last updated. Note that this "mtime" may in + * fact be the last modified time of the plugin file from which + * the content came from - this means mtime may actually be earlier + * in time than "ctime" (in the case when the plugin jar file was + * last touched prior to this entity being created). + * + * Note that the "ctime" field semantics remains the same as always, + * it is the time when this entity was originally created. + * + * @return mtime of the content + */ + public long getMtime() { + return this.mtime; + } + + /** + * This entity does not automatically update the "mtime" when it + * is updated via a PreUpdate annotation, therefore, the owner of + * this entity needs to explicitly call this setter in order to + * set the "mtime". You normally set this value to the last + * modified time of the plugin jar that provided + * this plugin entity's {@link #getContent() content}. + * + * @param mtime + */ + public void setMtime(long mtime) { + this.mtime = mtime; + } + + public String getDisplayName() { + return displayName; + } + + public void setDisplayName(String displayName) { + this.displayName = displayName; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public boolean isEnabled() { + return enabled; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + public PluginStatusType getStatus() { + return status; + } + + public void setStatus(PluginStatusType status) { + this.status = status; + if (this.status == PluginStatusType.DELETED) { + this.enabled = false; + } + } + + public String getHelp() { + return help; + } + + public void setHelp(String help) { + this.help = help; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public String getAmpsVersion() { + return ampsVersion; + } + + public void setAmpsVersion(String ampsVersion) { + this.ampsVersion = ampsVersion; + } + + public String getMd5() { + return md5; + } + + public void setMd5(String md5) { + this.md5 = md5; + } + + public String getMD5() { + return getMd5(); + } + + public void setMD5(String md5) { + setMd5(md5); + } + + /** + * Returns the actual name of the plugin jar. This is not the absolute path, in fact, it does not include any + * directory paths. It is strictly the name of the plugin jar as found on the file system (aka the filename). + * + * @return plugin filename + */ + public String getPath() { + return this.path; + } + + /** + * Ensure that the path being set does not include any directory names. The plugin path is the filename. See + * {@link #getPath()}. + * + * @param path the filename of the plugin, not including directory names + */ + public void setPath(String path) { + this.path = path; + } + + /** + * Indicates how the plugin gets deployed (e.g. running in the agent or in the server). + * + * @return plugin deployment type + */ + public PluginDeploymentType getDeployment() { + return deployment; + } + + public void setDeployment(PluginDeploymentType deployment) { + this.deployment = deployment; + } + + /** + * Returns the actual content of the plugin file. Be careful calling this + * in an entity context - the entire plugin file content will be loaded in + * memory (which may trigger an OutOfMemoryError if the file is very large). + * + * @return the content of the plugin file + */ + public byte[] getContent() { + return this.content; + } + + public void setContent(byte[] content) { + this.content = content; + } + + @PrePersist + void onPersist() { + this.ctime = System.currentTimeMillis(); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if ((obj == null) || !(obj instanceof AbstractPlugin)) { + return false; + } + + AbstractPlugin that = (AbstractPlugin) obj; + return name.equals(that.name); + } + + @Override + public int hashCode() { + return name.hashCode(); + } + + @Override + public String toString() { + return "[id=" + id + ", name=" + name + ", md5=" + md5 + "]"; + } +} diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/plugin/Plugin.java b/modules/core/domain/src/main/java/org/rhq/core/domain/plugin/Plugin.java index 4047d10..cdd3254 100644 --- a/modules/core/domain/src/main/java/org/rhq/core/domain/plugin/Plugin.java +++ b/modules/core/domain/src/main/java/org/rhq/core/domain/plugin/Plugin.java @@ -1,6 +1,6 @@ /* * RHQ Management Platform - * Copyright (C) 2005-2008 Red Hat, Inc. + * Copyright (C) 2005-2009 Red Hat, Inc. * All rights reserved. * * This program is free software; you can redistribute it and/or modify @@ -22,52 +22,35 @@ */ package org.rhq.core.domain.plugin;
-import java.io.ByteArrayInputStream; -import java.io.Serializable; - -import javax.persistence.CascadeType; -import javax.persistence.Column; +import javax.persistence.DiscriminatorValue; import javax.persistence.Entity; -import javax.persistence.EnumType; -import javax.persistence.Enumerated; -import javax.persistence.FetchType; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.JoinColumn; import javax.persistence.NamedQueries; import javax.persistence.NamedQuery; -import javax.persistence.OneToOne; -import javax.persistence.PrePersist; -import javax.persistence.SequenceGenerator; -import javax.persistence.Table; - -import org.jetbrains.annotations.NotNull; - -import org.rhq.core.domain.configuration.Configuration; -import org.rhq.core.util.MessageDigestGenerator;
/** * An agent plugin. - * + * * This object contains information about the plugin jar itself (e.g. its name and MD5). * It may also contain the jar contents ({@link #getContent()}). */ -@Entity +@DiscriminatorValue("AGENT") @NamedQueries( { // - @NamedQuery(name = Plugin.QUERY_GET_STATUS_BY_NAME_AND_TYPE, query = "" // + // helps you determine if a plugin is installed or was deleted + @NamedQuery(name = Plugin.QUERY_GET_STATUS_BY_NAME, query = "" // + " SELECT p.status " // + " FROM Plugin AS p " // - + " WHERE p.name = :name AND p.deployment = :type "), // + + " WHERE p.name = :name)"), //
- @NamedQuery(name = Plugin.QUERY_GET_NAMES_BY_ENABLED_AND_TYPE, query = "" // + // helps you determine which installed plugins are enabled or disabled + @NamedQuery(name = Plugin.QUERY_GET_NAMES_BY_ENABLED, query = "" // + " SELECT p.name " // + " FROM Plugin AS p " // - + " WHERE p.enabled = :enabled AND p.deployment = :type AND p.status = 'INSTALLED' "), // + + " WHERE p.enabled = :enabled " // + + " AND p.status = 'INSTALLED' "), //
// this query does not load the content blob, but loads everything else - @NamedQuery(name = Plugin.QUERY_FIND_BY_IDS_AND_TYPE, query = "" // + @NamedQuery(name = Plugin.QUERY_FIND_BY_IDS, query = "" // + " SELECT new org.rhq.core.domain.plugin.Plugin( " // + " p.id, " // + " p.name, " // @@ -80,15 +63,11 @@ import org.rhq.core.util.MessageDigestGenerator; + " p.md5, " // + " p.version, " // + " p.ampsVersion, " // - + " p.deployment, " // - + " p.pluginConfiguration, " // - + " p.scheduledJobsConfiguration, " // + " p.ctime, " // + " p.mtime) " // - + " FROM Plugin AS p " // - + " LEFT JOIN p.pluginConfiguration " // - + " LEFT JOIN p.scheduledJobsConfiguration " // - + " WHERE p.id IN (:ids) AND p.deployment = :type AND p.status = 'INSTALLED' "), // + + " FROM Plugin AS p " // + + " WHERE p.id IN (:ids) " // + + " AND p.status = 'INSTALLED' "), //
// this query does not load the content blob, but loads everything else @NamedQuery(name = Plugin.QUERY_FIND_BY_NAME, query = "" // @@ -104,43 +83,15 @@ import org.rhq.core.util.MessageDigestGenerator; + " p.md5, " // + " p.version, " // + " p.ampsVersion, " // - + " p.deployment, " // - + " p.pluginConfiguration, " // - + " p.scheduledJobsConfiguration, " // + " p.ctime, " // + " p.mtime) " // - + " FROM Plugin AS p " // - + " LEFT JOIN p.pluginConfiguration " // - + " LEFT JOIN p.scheduledJobsConfiguration " // - + " WHERE p.name=:name AND p.status = 'INSTALLED' "), // + + " FROM Plugin AS p " // + + " WHERE p.name=:name " // + + " AND p.status = 'INSTALLED' "), //
// gets the plugin, even if it is deleted // this query does not load the content blob, but loads everything else - @NamedQuery(name = Plugin.QUERY_FIND_ANY_BY_NAME_AND_TYPE, query = "" // - + " SELECT new org.rhq.core.domain.plugin.Plugin( " // - + " p.id, " // - + " p.name, " // - + " p.path, " // - + " p.displayName, " // - + " p.enabled, " // - + " p.status, " // - + " p.description, " // - + " p.help, " // - + " p.md5, " // - + " p.version, " // - + " p.ampsVersion, " // - + " p.deployment, " // - + " p.pluginConfiguration, " // - + " p.scheduledJobsConfiguration, " // - + " p.ctime, " // - + " p.mtime) " // - + " FROM Plugin AS p " // - + " LEFT JOIN p.pluginConfiguration " // - + " LEFT JOIN p.scheduledJobsConfiguration " // - + " WHERE p.name=:name AND p.deployment = :type "), // - - // this query does not load the content blob, but loads everything else - @NamedQuery(name = Plugin.QUERY_FIND_ALL_AGENT, query = "" // + @NamedQuery(name = Plugin.QUERY_FIND_ANY_BY_NAME, query = "" // + " SELECT new org.rhq.core.domain.plugin.Plugin( " // + " p.id, " // + " p.name, " // @@ -153,18 +104,14 @@ import org.rhq.core.util.MessageDigestGenerator; + " p.md5, " // + " p.version, " // + " p.ampsVersion, " // - + " p.deployment, " // - + " p.pluginConfiguration, " // - + " p.scheduledJobsConfiguration, " // + " p.ctime, " // + " p.mtime) " // + " FROM Plugin AS p " // - + " LEFT JOIN p.pluginConfiguration " // - + " LEFT JOIN p.scheduledJobsConfiguration " // - + " WHERE p.deployment = 'AGENT' AND p.status = 'INSTALLED' "), // + + " WHERE p.name=:name "), //
+ // finds all installed - ignores those plugins marked as deleted // this query does not load the content blob, but loads everything else - @NamedQuery(name = Plugin.QUERY_FIND_ALL_SERVER, query = "" // + @NamedQuery(name = Plugin.QUERY_FIND_ALL_INSTALLED, query = "" // + " SELECT new org.rhq.core.domain.plugin.Plugin( " // + " p.id, " // + " p.name, " // @@ -177,15 +124,10 @@ import org.rhq.core.util.MessageDigestGenerator; + " p.md5, " // + " p.version, " // + " p.ampsVersion, " // - + " p.deployment, " // - + " p.pluginConfiguration, " // - + " p.scheduledJobsConfiguration, " // + " p.ctime, " // + " p.mtime) " // + " FROM Plugin AS p " // - + " LEFT JOIN p.pluginConfiguration " // - + " LEFT JOIN p.scheduledJobsConfiguration " // - + " WHERE p.deployment = 'SERVER' AND p.status = 'INSTALLED' "), // + + " WHERE p.status = 'INSTALLED' "), //
// this query is how you enable and disable plugins @NamedQuery(name = Plugin.UPDATE_PLUGINS_ENABLED_BY_IDS, query = "" // @@ -207,408 +149,63 @@ import org.rhq.core.util.MessageDigestGenerator; + " p.md5, " // + " p.version, " // + " p.ampsVersion, " // - + " p.deployment, " // - + " p.pluginConfiguration, " // - + " p.scheduledJobsConfiguration, " // + " p.ctime, " // + " p.mtime) " // + " FROM Plugin p " // - + " LEFT JOIN p.pluginConfiguration " // - + " LEFT JOIN p.scheduledJobsConfiguration " // + " WHERE p.status = 'INSTALLED' AND " // + " p.name IN ( SELECT rt.plugin " // + " FROM Resource res " // + " JOIN res.resourceType rt " // + " WHERE ( rt.category = :resourceCategory OR :resourceCategory IS NULL ) " // + " AND ( rt.name = :resourceTypeName OR :resourceTypeName IS NULL ) ) " // - + "ORDER BY p.name") }) -@SequenceGenerator(name = "SEQ", sequenceName = "RHQ_PLUGIN_ID_SEQ") -@Table(name = Plugin.TABLE_NAME) -public class Plugin implements Serializable { + + " ORDER BY p.name") // +}) +@Entity +public class Plugin extends AbstractPlugin { private static final long serialVersionUID = 1L;
- public static final String TABLE_NAME = "RHQ_PLUGIN"; - - public static final String QUERY_FIND_BY_RESOURCE_TYPE_AND_CATEGORY = "Plugin.findByResourceType"; - public static final String QUERY_FIND_ALL_AGENT = "Plugin.findAllAgent"; - public static final String QUERY_FIND_ALL_SERVER = "Plugin.findAllServer"; + public static final String QUERY_GET_STATUS_BY_NAME = "Plugin.queryGetStatusByName"; + public static final String QUERY_GET_NAMES_BY_ENABLED = "Plugin.queryGetNamesByEnabled"; + public static final String QUERY_FIND_BY_IDS = "Plugin.findByIds"; public static final String QUERY_FIND_BY_NAME = "Plugin.findByName"; - public static final String QUERY_FIND_ANY_BY_NAME_AND_TYPE = "Plugin.findAnyByNameAndType"; - public static final String QUERY_FIND_BY_IDS_AND_TYPE = "Plugin.findByIdsAndType"; - public static final String QUERY_GET_NAMES_BY_ENABLED_AND_TYPE = "Plugin.findByEnabledAndType"; - public static final String QUERY_GET_STATUS_BY_NAME_AND_TYPE = "Plugin.getStatusByNameAndType"; + public static final String QUERY_FIND_ANY_BY_NAME = "Plugin.findAnyByName"; + public static final String QUERY_FIND_ALL_INSTALLED = "Plugin.findAllInstalled"; public static final String UPDATE_PLUGINS_ENABLED_BY_IDS = "Plugin.updatePluginsEnabledByIds"; - - @Column(name = "ID", nullable = false) - @GeneratedValue(strategy = GenerationType.AUTO, generator = "SEQ") - @Id - private int id; - - @Column(name = "DEPLOYMENT", nullable = false) - @Enumerated(EnumType.STRING) - private PluginDeploymentType deployment = PluginDeploymentType.AGENT; // assume agent - - @JoinColumn(name = "JOBS_CONFIG_ID", referencedColumnName = "ID") - @OneToOne(cascade = { CascadeType.ALL }, fetch = FetchType.LAZY) - private Configuration scheduledJobsConfiguration; - - @JoinColumn(name = "PLUGIN_CONFIG_ID", referencedColumnName = "ID") - @OneToOne(cascade = { CascadeType.ALL }, fetch = FetchType.LAZY) - private Configuration pluginConfiguration; - - @Column(name = "NAME", nullable = false) - private String name; - - @Column(name = "DISPLAY_NAME", nullable = false) - private String displayName; - - @Column(name = "DESCRIPTION", nullable = true) - private String description; - - @Column(name = "ENABLED", nullable = false) - private boolean enabled = true; - - @Column(name = "STATUS", nullable = false) - @Enumerated(EnumType.STRING) - private PluginStatusType status = PluginStatusType.INSTALLED; - - @Column(name = "HELP", nullable = true) - private String help; - - @Column(name = "VERSION", nullable = true) - private String version; - - @Column(name = "AMPS_VERSION", nullable = true) - private String ampsVersion; - - @Column(name = "PATH", nullable = false) - private String path; - - @Column(name = "MD5", nullable = false) - private String md5; - - @Column(name = "CTIME", nullable = false) - private long ctime; - - @Column(name = "MTIME", nullable = false) - private long mtime; - - @Column(name = "CONTENT", nullable = true) - private byte[] content; + public static final String QUERY_FIND_BY_RESOURCE_TYPE_AND_CATEGORY = "Plugin.findByResourceType";
public Plugin() { + super(); + setDeployment(PluginDeploymentType.AGENT); }
- /** - * Constructor for {@link Plugin}. - * - * @param name the logical name of the plugin - * @param path the actual filename of the plugin jar (see {@link #getPath()}) - */ - public Plugin(@NotNull String name, String path) { - this.name = name; - this.path = path; + public Plugin(String name, String path) { + super(name, path); + setDeployment(PluginDeploymentType.AGENT); }
- /** - * Constructor for {@link Plugin}. - * Note that this allows you to provide an MD5 without providing the plugin's - * actual content. If you wish to persist this entity in the database, you should - * either provide the {@link #setContent(byte[]) content} or update the entity - * later by streaming the file content to the content column. - * - * @param name the logical name of the plugin - * @param path the actual filename of the plugin jar (see {@link #getPath()}) - * @param md5 the MD5 hash string of the plugin jar contents - */ public Plugin(String name, String path, String md5) { - this.name = name; - this.path = path; - this.md5 = md5; + super(name, path, md5); + setDeployment(PluginDeploymentType.AGENT); }
- /** - * Constructor for {@link Plugin}. - * - * @param name the logical name of the plugin - * @param path the actual filename of the plugin jar (see {@link #getPath()}) - * @param content the actual jar file contents (the MD5 hash string will be generated from this) - */ public Plugin(String name, String path, byte[] content) { - this.name = name; - this.path = path; - this.content = content; - - try { - ByteArrayInputStream stream = new ByteArrayInputStream(content); - this.md5 = MessageDigestGenerator.getDigestString(stream); - } catch (Exception e) { - throw new RuntimeException("Cannot determine plugin's MD5!", e); - } + super(name, path, content); + setDeployment(PluginDeploymentType.AGENT); }
- /** - * Constructor that can build the full object except for the content byte array. - * This is used mainly for the named queries that want to return a Plugin object - * but does not eagerly load in the content array. - * - * @param id - * @param name - * @param path - * @param displayName - * @param enabled - * @param status - * @param description - * @param help - * @param md5 - * @param version - * @param ampsVersion - * @param deployment - * @param pluginConfig - * @param scheduledJobsConfig - * @param ctime - * @param mtime - */ public Plugin(int id, String name, String path, String displayName, boolean enabled, PluginStatusType status, - String description, String help, String md5, String version, String ampsVersion, - PluginDeploymentType deployment, Configuration pluginConfig, Configuration scheduledJobsConfig, long ctime, - long mtime) { - this.id = id; - this.name = name; - this.path = path; - this.displayName = displayName; - this.enabled = enabled; - this.status = status; - this.description = description; - this.help = help; - this.md5 = md5; - this.version = version; - this.ampsVersion = ampsVersion; - this.deployment = deployment; - this.pluginConfiguration = pluginConfig; - this.scheduledJobsConfiguration = scheduledJobsConfig; - this.ctime = ctime; - this.mtime = mtime; - } - - public int getId() { - return this.id; - } - - public void setId(int id) { - this.id = id; - } - - public String getName() { - return this.name; - } - - public void setName(String name) { - this.name = name; - } - - /** - * See the javadoc of {@link #getMtime()} for - * information about this field and its relationship - * with "mtime". - * - * @return the time when this entity was persisted - */ - public long getCtime() { - return this.ctime; - } - - public void setCtime(long ctime) { - this.ctime = ctime; - } - - /** - * The "mtime" of the plugin has slightly different semantics - * than other "mtime" values found elsewhere. The "mtime" - * will typically be the time that the content field was modified, - * not necessarily the time when any field was modified. In other - * words, look at "mtime" if you want to know when the actual - * plugin content was last updated. Note that this "mtime" may in - * fact be the last modified time of the plugin file from which - * the content came from - this means mtime may actually be earlier - * in time than "ctime" (in the case when the plugin jar file was - * last touched prior to this entity being created). - * - * Note that the "ctime" field semantics remains the same as always, - * it is the time when this entity was originally created. - * - * @return mtime of the content - */ - public long getMtime() { - return this.mtime; - } - - /** - * This entity does not automatically update the "mtime" when it - * is updated via a PreUpdate annotation, therefore, the owner of - * this entity needs to explicitly call this setter in order to - * set the "mtime". You normally set this value to the last - * modified time of the plugin jar that provided - * this plugin entity's {@link #getContent() content}. - * - * @param mtime - */ - public void setMtime(long mtime) { - this.mtime = mtime; - } - - public String getDisplayName() { - return displayName; - } - - public void setDisplayName(String displayName) { - this.displayName = displayName; - } - - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } - - public boolean isEnabled() { - return enabled; - } - - public void setEnabled(boolean enabled) { - this.enabled = enabled; - } - - public PluginStatusType getStatus() { - return status; - } - - public void setStatus(PluginStatusType status) { - this.status = status; - if (this.status == PluginStatusType.DELETED) { - this.enabled = false; - } - } - - public String getHelp() { - return help; - } - - public void setHelp(String help) { - this.help = help; - } - - public String getVersion() { - return version; - } - - public void setVersion(String version) { - this.version = version; - } - - public String getAmpsVersion() { - return ampsVersion; - } + String description, String help, String md5, String version, String ampsVersion, long ctime, long mtime) {
- public void setAmpsVersion(String ampsVersion) { - this.ampsVersion = ampsVersion; - } - - public String getMd5() { - return md5; - } - - public void setMd5(String md5) { - this.md5 = md5; - } - - public String getMD5() { - return getMd5(); - } - - public void setMD5(String md5) { - setMd5(md5); - } - - /** - * Returns the actual name of the plugin jar. This is not the absolute path, in fact, it does not include any - * directory paths. It is strictly the name of the plugin jar as found on the file system (aka the filename). - * - * @return plugin filename - */ - public String getPath() { - return this.path; - } - - /** - * Ensure that the path being set does not include any directory names. The plugin path is the filename. See - * {@link #getPath()}. - * - * @param path the filename of the plugin, not including directory names - */ - public void setPath(String path) { - this.path = path; - } - - /** - * Indicates how the plugin gets deployed (e.g. running in the agent or in the server). - * - * @return plugin deployment type - */ - public PluginDeploymentType getDeployment() { - return deployment; + super(id, name, path, displayName, enabled, status, description, help, md5, version, ampsVersion, + PluginDeploymentType.AGENT, ctime, mtime); }
+ @Override public void setDeployment(PluginDeploymentType deployment) { - this.deployment = deployment; - } - - /** - * If the plugin has jobs associated with it, this is the configuration for those jobs. - * - * @return scheduled job configuration for jobs that the plugin defined. - */ - public Configuration getScheduledJobsConfiguration() { - return scheduledJobsConfiguration; - } - - public void setScheduledJobsConfiguration(Configuration scheduledJobsConfiguration) { - this.scheduledJobsConfiguration = scheduledJobsConfiguration; - } - - /** - * If the plugin, itself, has configuration associated with it, this is that configuration. - * - * @return the configuration associated with the plugin itself - */ - public Configuration getPluginConfiguration() { - return pluginConfiguration; - } - - public void setPluginConfiguration(Configuration pluginConfiguration) { - this.pluginConfiguration = pluginConfiguration; - } - - /** - * Returns the actual content of the plugin file. Be careful calling this - * in an entity context - the entire plugin file content will be loaded in - * memory (which may trigger an OutOfMemoryError if the file is very large). - * - * @return the content of the plugin file - */ - public byte[] getContent() { - return this.content; - } - - public void setContent(byte[] content) { - this.content = content; - } - - @PrePersist - void onPersist() { - this.ctime = System.currentTimeMillis(); + if (deployment != PluginDeploymentType.AGENT) { + throw new IllegalArgumentException("Plugin can only ever have deployment type of AGENT: " + deployment); + } + super.setDeployment(deployment); }
@Override @@ -621,17 +218,16 @@ public class Plugin implements Serializable { return false; }
- Plugin that = (Plugin) obj; - return name.equals(that.name); + return super.equals(obj); }
@Override public int hashCode() { - return name.hashCode(); + return super.hashCode(); }
@Override public String toString() { - return "Plugin[id=" + id + ", name=" + name + ", md5=" + md5 + "]"; + return "AgentPlugin " + super.toString(); } } diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/plugin/PluginKey.java b/modules/core/domain/src/main/java/org/rhq/core/domain/plugin/PluginKey.java new file mode 100644 index 0000000..5240a65 --- /dev/null +++ b/modules/core/domain/src/main/java/org/rhq/core/domain/plugin/PluginKey.java @@ -0,0 +1,153 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2009 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.core.domain.plugin; + +/** + * Encapsulates informaton that can uniquely identify a plugin. + * + * @author John Mazzitelli + */ +public class PluginKey { + private final PluginDeploymentType deployment; + private final String pluginType; + private final String pluginName; + + /** + * Creates a plugin key that identifies an agent plugin. There is only + * one plugin container that runs in the agent, thus there is only + * one "type" of an agent plugin. Therefore, {@link #getPluginType()} on the + * returned object will return <code>null</code> to signify this. + * + * @param pluginName the name of the plugin + * @return the plugin key for the agent plugin + */ + public static PluginKey createAgentPluginKey(String pluginName) { + return new PluginKey(PluginDeploymentType.AGENT, null, pluginName); + } + + /** + * Creates a plugin key that identifies a server plugin. All server plugins + * must have a type and a name. + * + * @param pluginType the type of plugin - must not be null or an empty string + * @param pluginName the name of the plugin + * @return the plugin key for the server plugin + */ + public static PluginKey createServerPluginKey(String pluginType, String pluginName) { + // for server plugins, cannot allow an empty string for plugin type + if (pluginType == null || pluginType.length() == 0) { + throw new IllegalArgumentException("invalid pluginType: " + pluginType); + } + return new PluginKey(PluginDeploymentType.SERVER, pluginType, pluginName); + } + + /** + * Create a plugin key that identifies the given agent plugin. + * + * @param plugin agent plugin + */ + public PluginKey(Plugin plugin) { + this(plugin.getDeployment(), null, plugin.getName()); + } + + /** + * Create a plugin key that identifies the given server plugin. + * + * @param plugin server plugin + */ + public PluginKey(ServerPlugin plugin) { + this(plugin.getDeployment(), plugin.getType(), plugin.getName()); + } + + public PluginKey(PluginDeploymentType deployment, String pluginType, String pluginName) { + if (deployment == null) { + throw new IllegalArgumentException("deployment==null"); + } + if (pluginType == null && deployment != PluginDeploymentType.AGENT) { + throw new IllegalArgumentException("only agent plugins can have null type"); + } + if (pluginType != null && deployment == PluginDeploymentType.AGENT) { + throw new IllegalArgumentException("agent plugins must have null type"); + } + if (pluginName == null || pluginName.length() == 0) { + throw new IllegalArgumentException("invalid pluginName: " + pluginName); + } + + this.deployment = deployment; + this.pluginType = pluginType; + this.pluginName = pluginName; + } + + public PluginDeploymentType getDeployment() { + return deployment; + } + + public String getPluginName() { + return pluginName; + } + + public String getPluginType() { + return pluginType; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("PluginKey [deployment=").append(deployment).append(", pluginType=").append(pluginType).append( + ", pluginName=").append(pluginName).append("]"); + return builder.toString(); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + deployment.hashCode(); + result = prime * result + ((pluginType == null) ? 0 : pluginType.hashCode()); + result = prime * result + pluginName.hashCode(); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof PluginKey)) { + return false; + } + PluginKey other = (PluginKey) obj; + if (!pluginName.equals(other.pluginName)) { + return false; + } + if (pluginType == null) { + if (other.pluginType != null) { + return false; + } + } else if (!pluginType.equals(other.pluginType)) { + return false; + + } + if (deployment != other.deployment) { + return false; + } + return true; + } +} diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/plugin/ServerPlugin.java b/modules/core/domain/src/main/java/org/rhq/core/domain/plugin/ServerPlugin.java new file mode 100644 index 0000000..aa06ea9 --- /dev/null +++ b/modules/core/domain/src/main/java/org/rhq/core/domain/plugin/ServerPlugin.java @@ -0,0 +1,293 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2009 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, version 2, as + * published by the Free Software Foundation, and/or the GNU Lesser + * General Public License, version 2.1, also as published by the Free + * Software Foundation. + * + * 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 and the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * and the GNU Lesser 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.core.domain.plugin; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.DiscriminatorValue; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.JoinColumn; +import javax.persistence.NamedQueries; +import javax.persistence.NamedQuery; +import javax.persistence.OneToOne; + +import org.rhq.core.domain.configuration.Configuration; + +/** + * A server plugin. + * + * This object contains information about the plugin jar itself (e.g. its name and MD5). + * It may also contain the jar contents ({@link #getContent()}). + */ +@DiscriminatorValue("SERVER") +@NamedQueries( { +// + // helps you determine if a plugin is installed or was deleted + @NamedQuery(name = ServerPlugin.QUERY_GET_STATUS_BY_NAME, query = "" // + + " SELECT p.status " // + + " FROM ServerPlugin AS p " // + + " WHERE p.name = :name)"), // + + // helps you determine which installed plugins are enabled or disabled + @NamedQuery(name = ServerPlugin.QUERY_GET_NAMES_BY_ENABLED, query = "" // + + " SELECT new org.rhq.core.domain.plugin.PluginKey( " // + + " p.deployment, " // + + " p.type, " // + + " p.name) " // + + " FROM ServerPlugin AS p " // + + " WHERE p.enabled = :enabled " // + + " AND p.status = 'INSTALLED' "), // + + // this query does not load the content blob, but loads everything else + @NamedQuery(name = ServerPlugin.QUERY_FIND_BY_IDS, query = "" // + + " SELECT new org.rhq.core.domain.plugin.ServerPlugin( " // + + " p.id, " // + + " p.name, " // + + " p.path, " // + + " p.displayName, " // + + " p.enabled, " // + + " p.status, " // + + " p.description, " // + + " p.help, " // + + " p.md5, " // + + " p.version, " // + + " p.ampsVersion, " // + + " p.pluginConfiguration, " // + + " p.scheduledJobsConfiguration, " // + + " p.type, " // + + " p.ctime, " // + + " p.mtime) " // + + " FROM ServerPlugin AS p " // + + " LEFT JOIN p.pluginConfiguration " // + + " LEFT JOIN p.scheduledJobsConfiguration " // + + " WHERE p.id IN (:ids) " // + + " AND p.status = 'INSTALLED' "), // + + // this query does not load the content blob, but loads everything else + @NamedQuery(name = ServerPlugin.QUERY_FIND_BY_NAME, query = "" // + + " SELECT new org.rhq.core.domain.plugin.ServerPlugin( " // + + " p.id, " // + + " p.name, " // + + " p.path, " // + + " p.displayName, " // + + " p.enabled, " // + + " p.status, " // + + " p.description, " // + + " p.help, " // + + " p.md5, " // + + " p.version, " // + + " p.ampsVersion, " // + + " p.pluginConfiguration, " // + + " p.scheduledJobsConfiguration, " // + + " p.type, " // + + " p.ctime, " // + + " p.mtime) " // + + " FROM ServerPlugin AS p " // + + " LEFT JOIN p.pluginConfiguration " // + + " LEFT JOIN p.scheduledJobsConfiguration " // + + " WHERE p.name=:name " // + + " AND p.status = 'INSTALLED' "), // + + // gets the plugin, even if it is deleted + // this query does not load the content blob, but loads everything else + @NamedQuery(name = ServerPlugin.QUERY_FIND_ANY_BY_NAME, query = "" // + + " SELECT new org.rhq.core.domain.plugin.ServerPlugin( " // + + " p.id, " // + + " p.name, " // + + " p.path, " // + + " p.displayName, " // + + " p.enabled, " // + + " p.status, " // + + " p.description, " // + + " p.help, " // + + " p.md5, " // + + " p.version, " // + + " p.ampsVersion, " // + + " p.pluginConfiguration, " // + + " p.scheduledJobsConfiguration, " // + + " p.type, " // + + " p.ctime, " // + + " p.mtime) " // + + " FROM ServerPlugin AS p " // + + " LEFT JOIN p.pluginConfiguration " // + + " LEFT JOIN p.scheduledJobsConfiguration " // + + " WHERE p.name=:name "), // + + // finds all installed - ignores those plugins marked as deleted + // this query does not load the content blob, but loads everything else + @NamedQuery(name = ServerPlugin.QUERY_FIND_ALL_INSTALLED, query = "" // + + " SELECT new org.rhq.core.domain.plugin.ServerPlugin( " // + + " p.id, " // + + " p.name, " // + + " p.path, " // + + " p.displayName, " // + + " p.enabled, " // + + " p.status, " // + + " p.description, " // + + " p.help, " // + + " p.md5, " // + + " p.version, " // + + " p.ampsVersion, " // + + " p.pluginConfiguration, " // + + " p.scheduledJobsConfiguration, " // + + " p.type, " // + + " p.ctime, " // + + " p.mtime) " // + + " FROM ServerPlugin AS p " // + + " LEFT JOIN p.pluginConfiguration " // + + " LEFT JOIN p.scheduledJobsConfiguration " // + + " WHERE p.status = 'INSTALLED' "), // + + // this query is how you enable and disable plugins + @NamedQuery(name = ServerPlugin.UPDATE_PLUGINS_ENABLED_BY_IDS, query = "" // + + "UPDATE ServerPlugin p " // + + " SET p.enabled = :enabled " // + + " WHERE p.id IN (:ids)") + +}) +@Entity +public class ServerPlugin extends AbstractPlugin { + private static final long serialVersionUID = 1L; + + public static final String QUERY_GET_STATUS_BY_NAME = "ServerPlugin.queryGetStatusByName"; + public static final String QUERY_GET_NAMES_BY_ENABLED = "ServerPlugin.queryGetNamesByEnabled"; + public static final String QUERY_FIND_BY_IDS = "ServerPlugin.findByIds"; + public static final String QUERY_FIND_BY_NAME = "ServerPlugin.findByName"; + public static final String QUERY_FIND_ANY_BY_NAME = "ServerPlugin.findAnyByName"; + public static final String QUERY_FIND_ALL_INSTALLED = "ServerPlugin.findAllInstalled"; + public static final String UPDATE_PLUGINS_ENABLED_BY_IDS = "ServerPlugin.updatePluginsEnabledByIds"; + + @JoinColumn(name = "JOBS_CONFIG_ID", referencedColumnName = "ID") + @OneToOne(cascade = { CascadeType.ALL }, fetch = FetchType.LAZY) + private Configuration scheduledJobsConfiguration; + + @JoinColumn(name = "PLUGIN_CONFIG_ID", referencedColumnName = "ID") + @OneToOne(cascade = { CascadeType.ALL }, fetch = FetchType.LAZY) + private Configuration pluginConfiguration; + + @Column(name = "PTYPE") + private String type; + + public ServerPlugin() { + super(); + setDeployment(PluginDeploymentType.SERVER); + } + + public ServerPlugin(String name, String path) { + super(name, path); + setDeployment(PluginDeploymentType.SERVER); + } + + public ServerPlugin(String name, String path, String md5) { + super(name, path, md5); + setDeployment(PluginDeploymentType.SERVER); + } + + public ServerPlugin(String name, String path, byte[] content) { + super(name, path, content); + setDeployment(PluginDeploymentType.SERVER); + } + + public ServerPlugin(int id, String name, String path, String displayName, boolean enabled, PluginStatusType status, + String description, String help, String md5, String version, String ampsVersion, Configuration pluginConfig, + Configuration scheduledJobsConfig, String type, long ctime, long mtime) { + + super(id, name, path, displayName, enabled, status, description, help, md5, version, ampsVersion, + PluginDeploymentType.SERVER, ctime, mtime); + this.pluginConfiguration = pluginConfig; + this.scheduledJobsConfiguration = scheduledJobsConfig; + this.type = type; + } + + @Override + public void setDeployment(PluginDeploymentType deployment) { + if (deployment != PluginDeploymentType.SERVER) { + throw new IllegalArgumentException("ServerPlugin can only ever have deployment type of SERVER: " + + deployment); + } + super.setDeployment(deployment); + } + + /** + * If the plugin, itself, has configuration associated with it, this is that configuration. + * + * @return the configuration associated with the plugin itself + */ + public Configuration getPluginConfiguration() { + return this.pluginConfiguration; + } + + public void setPluginConfiguration(Configuration pluginConfiguration) { + this.pluginConfiguration = pluginConfiguration; + } + + /** + * If the plugin has jobs associated with it, this is the configuration for those jobs. + * + * @return scheduled job configuration for jobs that the plugin defined. + */ + public Configuration getScheduledJobsConfiguration() { + return this.scheduledJobsConfiguration; + } + + public void setScheduledJobsConfiguration(Configuration scheduledJobsConfiguration) { + this.scheduledJobsConfiguration = scheduledJobsConfiguration; + } + + /** + * Plugin type string. + * + * @return plugin type + */ + public String getType() { + return this.type; + } + + public void setType(String type) { + this.type = type; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if ((obj == null) || !(obj instanceof ServerPlugin)) { + return false; + } + + return super.equals(obj); + } + + @Override + public int hashCode() { + return super.hashCode(); + } + + @Override + public String toString() { + return "ServerPlugin " + super.toString(); + } +} diff --git a/modules/core/domain/src/test/java/org/rhq/core/domain/resource/test/PluginTest.java b/modules/core/domain/src/test/java/org/rhq/core/domain/resource/test/PluginTest.java index 729f7c2..c7afe81 100644 --- a/modules/core/domain/src/test/java/org/rhq/core/domain/resource/test/PluginTest.java +++ b/modules/core/domain/src/test/java/org/rhq/core/domain/resource/test/PluginTest.java @@ -73,20 +73,16 @@ public class PluginTest extends AbstractEJB3Test { plugin.setHelp(null); plugin.setContent(content);
- Query q = em.createNamedQuery(Plugin.QUERY_GET_STATUS_BY_NAME_AND_TYPE); + Query q = em.createNamedQuery(Plugin.QUERY_GET_STATUS_BY_NAME); q.setParameter("name", plugin.getName()); - q.setParameter("type", plugin.getDeployment()); assert q.getResultList().size() == 0; // not in the db yet
em.persist(plugin); id = plugin.getId(); assert id > 0; - assert plugin.getPluginConfiguration() == null : "there was no config that should have been here"; - assert plugin.getScheduledJobsConfiguration() == null : "there was no config that should have been here";
- q = em.createNamedQuery(Plugin.QUERY_GET_STATUS_BY_NAME_AND_TYPE); + q = em.createNamedQuery(Plugin.QUERY_GET_STATUS_BY_NAME); q.setParameter("name", plugin.getName()); - q.setParameter("type", plugin.getDeployment()); assert ((PluginStatusType) q.getSingleResult()) == PluginStatusType.INSTALLED;
plugin = em.find(Plugin.class, id); @@ -100,9 +96,7 @@ public class PluginTest extends AbstractEJB3Test { assert plugin.getMD5().equals(md5); assert plugin.getVersion() == null; assert plugin.getDescription() == null; - assert plugin.getDeployment() == PluginDeploymentType.AGENT; // default is agent - assert plugin.getPluginConfiguration() == null; - assert plugin.getScheduledJobsConfiguration() == null; + assert plugin.getDeployment() == PluginDeploymentType.AGENT; assert plugin.getHelp() == null; assert new String(plugin.getContent()).equals(new String(content));
@@ -116,33 +110,15 @@ public class PluginTest extends AbstractEJB3Test { String ampsVersion = "2.1"; String description = "description-UPDATED"; String help = "help-UPDATED"; - PluginDeploymentType deployment = PluginDeploymentType.SERVER; - Configuration pluginConfig = new Configuration(); - Configuration jobsConfig = new Configuration(); - pluginConfig.put(new PropertySimple("first", "last")); - jobsConfig.put(new PropertySimple("aaa", "bbb")); + PluginDeploymentType deployment = PluginDeploymentType.AGENT;
em.close(); getTransactionManager().commit(); // we will be doing an update - needs to be in own tx getTransactionManager().begin(); em = getEntityManager();
- em.persist(pluginConfig); - em.persist(jobsConfig); em.flush(); // gotta get those two persists to flush to the DB
- // do what ServerPluginsBean/ResourceMetadataManagerBean.updateServerPluginExceptContent does - Configuration config = plugin.getPluginConfiguration(); - if (config != null) { - config = em.merge(config); - plugin.setPluginConfiguration(config); - } - config = plugin.getScheduledJobsConfiguration(); - if (config != null) { - config = em.merge(config); - plugin.setScheduledJobsConfiguration(config); - } - Plugin pluginEntity = em.getReference(Plugin.class, plugin.getId()); pluginEntity.setName(name); pluginEntity.setPath(path); @@ -153,8 +129,6 @@ public class PluginTest extends AbstractEJB3Test { pluginEntity.setVersion(version); pluginEntity.setAmpsVersion(ampsVersion); pluginEntity.setDeployment(deployment); - pluginEntity.setPluginConfiguration(pluginConfig); - pluginEntity.setScheduledJobsConfiguration(jobsConfig); pluginEntity.setDescription(description); pluginEntity.setHelp(help); pluginEntity.setMtime(System.currentTimeMillis()); @@ -181,9 +155,7 @@ public class PluginTest extends AbstractEJB3Test { assert plugin.getVersion().equals(version); assert plugin.getAmpsVersion().equals(ampsVersion); assert plugin.getDescription().equals(description); - assert plugin.getDeployment() == PluginDeploymentType.SERVER; - assert plugin.getPluginConfiguration().equals(pluginConfig); - assert plugin.getScheduledJobsConfiguration().equals(jobsConfig); + assert plugin.getDeployment() == PluginDeploymentType.AGENT; assert plugin.getHelp().equals(help); // and what we really want to test - ensure the content remained intact after the update assert new String(plugin.getContent()).equals(new String(content)); @@ -193,9 +165,8 @@ public class PluginTest extends AbstractEJB3Test { getTransactionManager().commit(); getTransactionManager().begin(); em = getEntityManager(); - q = em.createNamedQuery(Plugin.QUERY_FIND_ANY_BY_NAME_AND_TYPE); + q = em.createNamedQuery(Plugin.QUERY_FIND_ANY_BY_NAME); q.setParameter("name", plugin.getName()); - q.setParameter("type", plugin.getDeployment()); Plugin doomed = (Plugin) q.getSingleResult(); doomed = em.getReference(Plugin.class, doomed.getId()); em.remove(doomed); @@ -250,9 +221,7 @@ public class PluginTest extends AbstractEJB3Test { assert plugin.getMD5().equals(md5); assert plugin.getVersion() == null; assert plugin.getDescription() == null; - assert plugin.getDeployment() == PluginDeploymentType.AGENT; // default is agent - assert plugin.getPluginConfiguration() == null; - assert plugin.getScheduledJobsConfiguration() == null; + assert plugin.getDeployment() == PluginDeploymentType.AGENT; assert plugin.getHelp() == null; assert plugin.getContent() == null;
@@ -284,7 +253,7 @@ public class PluginTest extends AbstractEJB3Test { String help = "the test help string is here"; byte[] content = "this is the test content".getBytes(); String md5 = MessageDigestGenerator.getDigestString(new String(content)); - PluginDeploymentType deployment = PluginDeploymentType.SERVER; + PluginDeploymentType deployment = PluginDeploymentType.AGENT; String ampsVersion = "1.2";
Configuration pluginConfig = new Configuration(); @@ -302,8 +271,6 @@ public class PluginTest extends AbstractEJB3Test { plugin.setHelp(help); plugin.setContent(content); plugin.setDeployment(deployment); - plugin.setPluginConfiguration(pluginConfig); - plugin.setScheduledJobsConfiguration(jobsConfig);
em.persist(plugin); assert plugin.getId() > 0; @@ -320,8 +287,6 @@ public class PluginTest extends AbstractEJB3Test { assert plugin.getAmpsVersion().equals(ampsVersion); assert plugin.getDescription().equals(description); assert plugin.getDeployment() == deployment; - assert plugin.getPluginConfiguration().equals(pluginConfig); - assert plugin.getScheduledJobsConfiguration().equals(jobsConfig); assert plugin.getHelp().equals(help); assert new String(plugin.getContent()).equals(new String(content));
@@ -340,14 +305,11 @@ public class PluginTest extends AbstractEJB3Test { assert plugin.getAmpsVersion().equals(ampsVersion); assert plugin.getDescription().equals(description); assert plugin.getDeployment() == deployment; - assert plugin.getPluginConfiguration().equals(pluginConfig); - assert plugin.getScheduledJobsConfiguration().equals(jobsConfig); assert plugin.getHelp().equals(help); assert plugin.getContent() == null;
- query = em.createNamedQuery(Plugin.QUERY_FIND_BY_IDS_AND_TYPE); + query = em.createNamedQuery(Plugin.QUERY_FIND_BY_IDS); query.setParameter("ids", Arrays.asList(Integer.valueOf(plugin.getId()))); - query.setParameter("type", plugin.getDeployment()); plugin = (Plugin) query.getSingleResult(); assert plugin != null; assert plugin.getId() > 0; @@ -360,12 +322,10 @@ public class PluginTest extends AbstractEJB3Test { assert plugin.getAmpsVersion().equals(ampsVersion); assert plugin.getDescription().equals(description); assert plugin.getDeployment() == deployment; - assert plugin.getPluginConfiguration().equals(pluginConfig); - assert plugin.getScheduledJobsConfiguration().equals(jobsConfig); assert plugin.getHelp().equals(help); assert plugin.getContent() == null;
- query = em.createNamedQuery(Plugin.QUERY_FIND_ALL_SERVER); + query = em.createNamedQuery(Plugin.QUERY_FIND_ALL_INSTALLED); List<Plugin> all = query.getResultList(); boolean got_it = false; for (Plugin p : all) { @@ -381,8 +341,6 @@ public class PluginTest extends AbstractEJB3Test { assert plugin.getAmpsVersion().equals(ampsVersion); assert p.getDescription().equals(description); assert plugin.getDeployment() == deployment; - assert plugin.getPluginConfiguration().equals(pluginConfig); - assert plugin.getScheduledJobsConfiguration().equals(jobsConfig); assert p.getHelp().equals(help); assert p.getContent() == null; break; @@ -399,13 +357,12 @@ public class PluginTest extends AbstractEJB3Test { List<?> results = query.getResultList(); assert results.size() == 0;
- query = em.createNamedQuery(Plugin.QUERY_FIND_BY_IDS_AND_TYPE); + query = em.createNamedQuery(Plugin.QUERY_FIND_BY_IDS); query.setParameter("ids", Arrays.asList(Integer.valueOf(plugin.getId()))); - query.setParameter("type", plugin.getDeployment()); results = query.getResultList(); assert results.size() == 0;
- query = em.createNamedQuery(Plugin.QUERY_FIND_ALL_SERVER); + query = em.createNamedQuery(Plugin.QUERY_FIND_ALL_INSTALLED); results = query.getResultList(); assert results.size() == 0;
@@ -513,9 +470,8 @@ public class PluginTest extends AbstractEJB3Test { getTransactionManager().commit(); getTransactionManager().begin(); em = getEntityManager(); - Query q = em.createNamedQuery(Plugin.QUERY_FIND_ANY_BY_NAME_AND_TYPE); + Query q = em.createNamedQuery(Plugin.QUERY_FIND_ANY_BY_NAME); q.setParameter("name", plugin.getName()); - q.setParameter("type", plugin.getDeployment()); Plugin doomed = (Plugin) q.getSingleResult(); doomed = em.getReference(Plugin.class, doomed.getId()); em.remove(doomed); @@ -628,9 +584,8 @@ public class PluginTest extends AbstractEJB3Test { getTransactionManager().commit(); getTransactionManager().begin(); em = getEntityManager(); - Query q = em.createNamedQuery(Plugin.QUERY_FIND_ANY_BY_NAME_AND_TYPE); + Query q = em.createNamedQuery(Plugin.QUERY_FIND_ANY_BY_NAME); q.setParameter("name", plugin.getName()); - q.setParameter("type", plugin.getDeployment()); Plugin doomed = (Plugin) q.getSingleResult(); doomed = em.getReference(Plugin.class, doomed.getId()); em.remove(doomed); diff --git a/modules/core/domain/src/test/java/org/rhq/core/domain/resource/test/ServerPluginTest.java b/modules/core/domain/src/test/java/org/rhq/core/domain/resource/test/ServerPluginTest.java new file mode 100644 index 0000000..c8acf79 --- /dev/null +++ b/modules/core/domain/src/test/java/org/rhq/core/domain/resource/test/ServerPluginTest.java @@ -0,0 +1,650 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2008 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, version 2, as + * published by the Free Software Foundation, and/or the GNU Lesser + * General Public License, version 2.1, also as published by the Free + * Software Foundation. + * + * 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 and the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * and the GNU Lesser 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.core.domain.resource.test; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.util.Arrays; +import java.util.List; + +import javax.naming.InitialContext; +import javax.persistence.EntityManager; +import javax.persistence.Query; +import javax.sql.DataSource; + +import org.testng.annotations.Test; + +import org.rhq.core.domain.configuration.Configuration; +import org.rhq.core.domain.configuration.PropertySimple; +import org.rhq.core.domain.plugin.PluginDeploymentType; +import org.rhq.core.domain.plugin.PluginStatusType; +import org.rhq.core.domain.plugin.ServerPlugin; +import org.rhq.core.domain.test.AbstractEJB3Test; +import org.rhq.core.util.MessageDigestGenerator; +import org.rhq.core.util.stream.StreamUtil; + +@Test +public class ServerPluginTest extends AbstractEJB3Test { + public void testUpdate() throws Throwable { + boolean done = false; + getTransactionManager().begin(); + EntityManager em = getEntityManager(); + try { + int id; + + String name = "ServerPluginTest-testUpdate"; + String path = "/test/Update"; + String displayName = "Server Plugin Test - testUpdate"; + boolean enabled = true; + PluginStatusType status = PluginStatusType.INSTALLED; + String md5 = "abcdef"; + byte[] content = "the content is here".getBytes(); + + ServerPlugin plugin = new ServerPlugin(name, path); + plugin.setDisplayName(displayName); + plugin.setEnabled(enabled); + plugin.setStatus(status); + plugin.setMD5(md5); + plugin.setVersion(null); + plugin.setDescription(null); + plugin.setHelp(null); + plugin.setContent(content); + + Query q = em.createNamedQuery(ServerPlugin.QUERY_GET_STATUS_BY_NAME); + q.setParameter("name", plugin.getName()); + assert q.getResultList().size() == 0; // not in the db yet + + em.persist(plugin); + id = plugin.getId(); + assert id > 0; + assert plugin.getPluginConfiguration() == null : "there was no config that should have been here"; + assert plugin.getScheduledJobsConfiguration() == null : "there was no config that should have been here"; + + q = em.createNamedQuery(ServerPlugin.QUERY_GET_STATUS_BY_NAME); + q.setParameter("name", plugin.getName()); + assert ((PluginStatusType) q.getSingleResult()) == PluginStatusType.INSTALLED; + + plugin = em.find(ServerPlugin.class, id); + assert plugin != null; + assert plugin.getId() == id; + assert plugin.getName().equals(name); + assert plugin.getPath().equals(path); + assert plugin.getDisplayName().equals(displayName); + assert plugin.isEnabled() == enabled; + assert plugin.getStatus() == PluginStatusType.INSTALLED; + assert plugin.getMD5().equals(md5); + assert plugin.getVersion() == null; + assert plugin.getDescription() == null; + assert plugin.getDeployment() == PluginDeploymentType.SERVER; + assert plugin.getPluginConfiguration() == null; + assert plugin.getScheduledJobsConfiguration() == null; + assert plugin.getHelp() == null; + assert new String(plugin.getContent()).equals(new String(content)); + + // everything persisted fine, let's update it and see the content is left alone + name = name + "-UPDATED"; + path = path + "-UPDATED"; + displayName = displayName + "-UPDATED"; + enabled = !enabled; + md5 = md5 + "00000"; + String version = "version-UPDATED"; + String ampsVersion = "2.1"; + String description = "description-UPDATED"; + String help = "help-UPDATED"; + PluginDeploymentType deployment = PluginDeploymentType.SERVER; + Configuration pluginConfig = new Configuration(); + Configuration jobsConfig = new Configuration(); + pluginConfig.put(new PropertySimple("first", "last")); + jobsConfig.put(new PropertySimple("aaa", "bbb")); + + em.close(); + getTransactionManager().commit(); // we will be doing an update - needs to be in own tx + getTransactionManager().begin(); + em = getEntityManager(); + + em.persist(pluginConfig); + em.persist(jobsConfig); + em.flush(); // gotta get those two persists to flush to the DB + + // do what ServerPluginsBean.updateServerPluginExceptContent does + Configuration config = plugin.getPluginConfiguration(); + if (config != null) { + config = em.merge(config); + plugin.setPluginConfiguration(config); + } + config = plugin.getScheduledJobsConfiguration(); + if (config != null) { + config = em.merge(config); + plugin.setScheduledJobsConfiguration(config); + } + + ServerPlugin pluginEntity = em.getReference(ServerPlugin.class, plugin.getId()); + pluginEntity.setName(name); + pluginEntity.setPath(path); + pluginEntity.setDisplayName(displayName); + pluginEntity.setEnabled(enabled); + pluginEntity.setStatus(status); + pluginEntity.setMd5(md5); + pluginEntity.setVersion(version); + pluginEntity.setAmpsVersion(ampsVersion); + pluginEntity.setDeployment(deployment); + pluginEntity.setPluginConfiguration(pluginConfig); + pluginEntity.setScheduledJobsConfiguration(jobsConfig); + pluginEntity.setDescription(description); + pluginEntity.setHelp(help); + pluginEntity.setMtime(System.currentTimeMillis()); + + try { + em.flush(); // make sure we push this out to the DB now + } catch (Exception e) { + throw new Exception("Failed to update a plugin that matches [" + plugin + "]", e); + } + + em.close(); + getTransactionManager().commit(); // must commit now + getTransactionManager().begin(); + em = getEntityManager(); + + plugin = em.find(ServerPlugin.class, id); + assert plugin != null; + assert plugin.getId() == id; + assert plugin.getName().equals(name); + assert plugin.getPath().equals(path); + assert plugin.getDisplayName().equals(displayName); + assert plugin.isEnabled() == enabled; + assert plugin.getMD5().equals(md5); + assert plugin.getVersion().equals(version); + assert plugin.getAmpsVersion().equals(ampsVersion); + assert plugin.getDescription().equals(description); + assert plugin.getDeployment() == PluginDeploymentType.SERVER; + assert plugin.getPluginConfiguration().equals(pluginConfig); + assert plugin.getScheduledJobsConfiguration().equals(jobsConfig); + assert plugin.getHelp().equals(help); + // and what we really want to test - ensure the content remained intact after the update + assert new String(plugin.getContent()).equals(new String(content)); + + // clean up - delete our test plugin + em.close(); + getTransactionManager().commit(); + getTransactionManager().begin(); + em = getEntityManager(); + q = em.createNamedQuery(ServerPlugin.QUERY_FIND_ANY_BY_NAME); + q.setParameter("name", plugin.getName()); + ServerPlugin doomed = (ServerPlugin) q.getSingleResult(); + doomed = em.getReference(ServerPlugin.class, doomed.getId()); + em.remove(doomed); + assert q.getResultList().size() == 0 : "didn't remove the plugin"; + em.close(); + getTransactionManager().commit(); + done = true; + } catch (Throwable t) { + t.printStackTrace(); + throw t; + } finally { + if (!done) { + getTransactionManager().rollback(); + } + } + } + + public void testPersistMinimal() throws Exception { + getTransactionManager().begin(); + EntityManager em = getEntityManager(); + try { + String name = "ServerPluginTest-testPersist"; + String path = "/test/Persist"; + String displayName = "Server Plugin Test - testPersist"; + boolean enabled = true; + PluginStatusType status = PluginStatusType.INSTALLED; + String md5 = "abcdef"; + + ServerPlugin plugin = new ServerPlugin(name, path); + plugin.setDisplayName(displayName); + plugin.setEnabled(enabled); + plugin.setStatus(status); + plugin.setMD5(md5); + + // the following are the only nullable fields + plugin.setVersion(null); + plugin.setDescription(null); + plugin.setHelp(null); + plugin.setContent(null); + + em.persist(plugin); + assert plugin.getId() > 0; + + plugin = em.find(ServerPlugin.class, plugin.getId()); + assert plugin != null; + assert plugin.getId() > 0; + assert plugin.getName().equals(name); + assert plugin.getPath().equals(path); + assert plugin.getDisplayName().equals(displayName); + assert plugin.isEnabled() == enabled; + assert plugin.getStatus() == PluginStatusType.INSTALLED; + assert plugin.getMD5().equals(md5); + assert plugin.getVersion() == null; + assert plugin.getDescription() == null; + assert plugin.getDeployment() == PluginDeploymentType.SERVER; + assert plugin.getPluginConfiguration() == null; + assert plugin.getScheduledJobsConfiguration() == null; + assert plugin.getHelp() == null; + assert plugin.getContent() == null; + + // side check - see that "deleting" a plugin also sets enabled to false + assert plugin.isEnabled() == true; + assert plugin.getStatus() == PluginStatusType.INSTALLED; + plugin.setStatus(PluginStatusType.DELETED); + assert plugin.getStatus() == PluginStatusType.DELETED; + assert plugin.isEnabled() == false; + plugin = em.merge(plugin); + assert plugin.getStatus() == PluginStatusType.DELETED; + assert plugin.isEnabled() == false; + + } finally { + getTransactionManager().rollback(); + } + } + + public void testPersistFull() throws Exception { + getTransactionManager().begin(); + EntityManager em = getEntityManager(); + try { + String name = "ServerPluginTest-testPersist"; + String path = "/test/Persist"; + String displayName = "Server Plugin Test - testPersist"; + boolean enabled = true; + String version = "1.0"; + String description = "the test description is here"; + String help = "the test help string is here"; + byte[] content = "this is the test content".getBytes(); + String md5 = MessageDigestGenerator.getDigestString(new String(content)); + PluginDeploymentType deployment = PluginDeploymentType.SERVER; + String ampsVersion = "1.2"; + + Configuration pluginConfig = new Configuration(); + Configuration jobsConfig = new Configuration(); + pluginConfig.put(new PropertySimple("first", "last")); + jobsConfig.put(new PropertySimple("aaa", "bbb")); + + ServerPlugin plugin = new ServerPlugin(name, path); + plugin.setDisplayName(displayName); + plugin.setEnabled(enabled); + plugin.setMD5(md5); + plugin.setVersion(version); + plugin.setAmpsVersion(ampsVersion); + plugin.setDescription(description); + plugin.setHelp(help); + plugin.setContent(content); + plugin.setDeployment(deployment); + plugin.setPluginConfiguration(pluginConfig); + plugin.setScheduledJobsConfiguration(jobsConfig); + + em.persist(plugin); + assert plugin.getId() > 0; + + plugin = em.find(ServerPlugin.class, plugin.getId()); + assert plugin != null; + assert plugin.getId() > 0; + assert plugin.getName().equals(name); + assert plugin.getPath().equals(path); + assert plugin.getDisplayName().equals(displayName); + assert plugin.isEnabled() == enabled; + assert plugin.getMD5().equals(md5); + assert plugin.getVersion().equals(version); + assert plugin.getAmpsVersion().equals(ampsVersion); + assert plugin.getDescription().equals(description); + assert plugin.getDeployment() == deployment; + assert plugin.getPluginConfiguration().equals(pluginConfig); + assert plugin.getScheduledJobsConfiguration().equals(jobsConfig); + assert plugin.getHelp().equals(help); + assert new String(plugin.getContent()).equals(new String(content)); + + // test our queries that purposefully do not load in the content blob + Query query = em.createNamedQuery(ServerPlugin.QUERY_FIND_BY_NAME); + query.setParameter("name", name); + plugin = (ServerPlugin) query.getSingleResult(); + assert plugin != null; + assert plugin.getId() > 0; + assert plugin.getName().equals(name); + assert plugin.getPath().equals(path); + assert plugin.getDisplayName().equals(displayName); + assert plugin.isEnabled() == enabled; + assert plugin.getMD5().equals(md5); + assert plugin.getVersion().equals(version); + assert plugin.getAmpsVersion().equals(ampsVersion); + assert plugin.getDescription().equals(description); + assert plugin.getDeployment() == deployment; + assert plugin.getPluginConfiguration().equals(pluginConfig); + assert plugin.getScheduledJobsConfiguration().equals(jobsConfig); + assert plugin.getHelp().equals(help); + assert plugin.getContent() == null; + + query = em.createNamedQuery(ServerPlugin.QUERY_FIND_BY_IDS); + query.setParameter("ids", Arrays.asList(Integer.valueOf(plugin.getId()))); + plugin = (ServerPlugin) query.getSingleResult(); + assert plugin != null; + assert plugin.getId() > 0; + assert plugin.getName().equals(name); + assert plugin.getPath().equals(path); + assert plugin.getDisplayName().equals(displayName); + assert plugin.isEnabled() == enabled; + assert plugin.getMD5().equals(md5); + assert plugin.getVersion().equals(version); + assert plugin.getAmpsVersion().equals(ampsVersion); + assert plugin.getDescription().equals(description); + assert plugin.getDeployment() == deployment; + assert plugin.getPluginConfiguration().equals(pluginConfig); + assert plugin.getScheduledJobsConfiguration().equals(jobsConfig); + assert plugin.getHelp().equals(help); + assert plugin.getContent() == null; + + query = em.createNamedQuery(ServerPlugin.QUERY_FIND_ALL_INSTALLED); + List<ServerPlugin> all = query.getResultList(); + boolean got_it = false; + for (ServerPlugin p : all) { + if (p.getName().equals(name)) { + got_it = true; + assert p.getId() > 0; + assert p.getName().equals(name); + assert p.getPath().equals(path); + assert p.getDisplayName().equals(displayName); + assert p.isEnabled() == enabled; + assert p.getMD5().equals(md5); + assert p.getVersion().equals(version); + assert plugin.getAmpsVersion().equals(ampsVersion); + assert p.getDescription().equals(description); + assert plugin.getDeployment() == deployment; + assert plugin.getPluginConfiguration().equals(pluginConfig); + assert plugin.getScheduledJobsConfiguration().equals(jobsConfig); + assert p.getHelp().equals(help); + assert p.getContent() == null; + break; + } + } + assert got_it : "findAll query failed to get our plugin"; + + // mark a plugin deleted - all of our queries should then never see it + plugin.setStatus(PluginStatusType.DELETED); + em.merge(plugin); + + query = em.createNamedQuery(ServerPlugin.QUERY_FIND_BY_NAME); + query.setParameter("name", name); + List<?> results = query.getResultList(); + assert results.size() == 0; + + query = em.createNamedQuery(ServerPlugin.QUERY_FIND_BY_IDS); + query.setParameter("ids", Arrays.asList(Integer.valueOf(plugin.getId()))); + results = query.getResultList(); + assert results.size() == 0; + + query = em.createNamedQuery(ServerPlugin.QUERY_FIND_ALL_INSTALLED); + results = query.getResultList(); + assert results.size() == 0; + + } finally { + getTransactionManager().rollback(); + } + } + + public void testPersistStreamContent() throws Exception { + Connection conn = null; + PreparedStatement ps = null; + ResultSet rs = null; + boolean done = false; + + getTransactionManager().begin(); + EntityManager em = getEntityManager(); + try { + String name = "ServerPluginTest-testPersist"; + String path = "/test/Persist"; + String displayName = "Server Plugin Test - testPersist"; + boolean enabled = true; + String version = "1.0"; + String description = "the test description is here"; + String help = "the test help string is here"; + byte[] content = "this is the test content".getBytes(); + String md5 = MessageDigestGenerator.getDigestString(new String(content)); + + // persist the plugin, but without any content + ServerPlugin plugin = new ServerPlugin(name, path); + plugin.setDisplayName(displayName); + plugin.setEnabled(enabled); + plugin.setMD5(md5); + plugin.setVersion(version); + plugin.setDescription(description); + plugin.setHelp(help); + + em.persist(plugin); + assert plugin.getId() > 0; + + // verify we have a content-less plugin in the db + plugin = em.find(ServerPlugin.class, plugin.getId()); + assert plugin != null; + assert plugin.getId() > 0; + assert plugin.getName().equals(name); + assert plugin.getPath().equals(path); + assert plugin.getDisplayName().equals(displayName); + assert plugin.isEnabled() == enabled; + assert plugin.getMD5().equals(md5); + assert plugin.getVersion().equals(version); + assert plugin.getDescription().equals(description); + assert plugin.getHelp().equals(help); + assert plugin.getContent() == null; + + em.close(); + getTransactionManager().commit(); // must commit since we are going to use a second connection now + getTransactionManager().begin(); + + // now stream the content into the plugin's table + InitialContext context = getInitialContext(); + DataSource ds = (DataSource) context.lookup("java:/RHQDS"); + assert ds != null : "Could not get the data source!"; + conn = ds.getConnection(); + ps = conn.prepareStatement("UPDATE " + ServerPlugin.TABLE_NAME + " SET CONTENT = ? WHERE ID = ?"); + ps.setBinaryStream(1, new ByteArrayInputStream(content), content.length); + ps.setInt(2, plugin.getId()); + int updateResults = ps.executeUpdate(); + assert updateResults == 1 : "Failed to stream the content blob: " + updateResults; + ps.close(); + ps = null; + conn.close(); + conn = null; + + getTransactionManager().commit(); + getTransactionManager().begin(); + em = getEntityManager(); + + // verify the content made it into the database via hibernate + plugin = em.find(ServerPlugin.class, plugin.getId()); + assert new String(plugin.getContent()).equals(new String(content)); + + em.close(); + getTransactionManager().commit(); + getTransactionManager().begin(); + + // verify the content made it into the database via jdbc streaming + conn = ds.getConnection(); + ps = conn.prepareStatement("SELECT CONTENT FROM " + ServerPlugin.TABLE_NAME + " WHERE ID = ?"); + ps.setInt(1, plugin.getId()); + rs = ps.executeQuery(); + rs.next(); + InputStream dbStream = rs.getBinaryStream(1); + assert dbStream != null : "Could not read the plugin content stream from the db"; + byte[] contentFromDb = StreamUtil.slurp(dbStream); + assert contentFromDb.length == content.length; + assert new String(contentFromDb).equals(new String(content)); + assert MessageDigestGenerator.getDigestString(new String(contentFromDb)).equals(md5); + rs.close(); + rs = null; + ps.close(); + ps = null; + conn.close(); + conn = null; + + // clean up - delete our test plugin + getTransactionManager().commit(); + getTransactionManager().begin(); + em = getEntityManager(); + Query q = em.createNamedQuery(ServerPlugin.QUERY_FIND_ANY_BY_NAME); + q.setParameter("name", plugin.getName()); + ServerPlugin doomed = (ServerPlugin) q.getSingleResult(); + doomed = em.getReference(ServerPlugin.class, doomed.getId()); + em.remove(doomed); + assert q.getResultList().size() == 0 : "didn't remove the plugin"; + em.close(); + getTransactionManager().commit(); + done = true; + + } finally { + if (rs != null) { + rs.close(); + } + if (ps != null) { + ps.close(); + } + if (conn != null) { + conn.close(); + } + if (!done) { + getTransactionManager().rollback(); + } + } + } + + public void testPersistStreamContent2() throws Exception { + Connection conn = null; + PreparedStatement ps = null; + ResultSet rs = null; + boolean done = false; + + getTransactionManager().begin(); + EntityManager em = getEntityManager(); + try { + byte[] content = "this is the test content".getBytes(); + String path = "/test/Persist"; + + // persist a content-less plugin + ServerPlugin plugin = new ServerPlugin("ServerPluginTest-testPersist", path); + plugin.setDisplayName("Server Plugin Test - testPersist"); + plugin.setEnabled(true); + plugin.setMD5(MessageDigestGenerator.getDigestString(new String(content))); + em.persist(plugin); + assert plugin.getId() > 0; + + em.close(); + getTransactionManager().commit(); // must commit since we are going to use a second connection now + getTransactionManager().begin(); + + // test that we can get a null content stream + InitialContext context = getInitialContext(); + DataSource ds = (DataSource) context.lookup("java:/RHQDS"); + assert ds != null : "Could not get the data source!"; + conn = ds.getConnection(); + ps = conn.prepareStatement("SELECT PATH, CONTENT FROM " + ServerPlugin.TABLE_NAME + " WHERE ID = ?"); + ps.setInt(1, plugin.getId()); + rs = ps.executeQuery(); + rs.next(); + String dbPath = rs.getString(1); + assert dbPath.equals(path); + InputStream dbStream = rs.getBinaryStream(2); + assert dbStream == null : "Was expecting a null stream but got a non-null stream from db"; + rs.close(); + ps.close(); + conn.close(); + rs = null; + ps = null; + conn = null; + + getTransactionManager().commit(); + getTransactionManager().begin(); + + // now stream the content into the plugin's table + conn = ds.getConnection(); + ps = conn.prepareStatement("UPDATE " + ServerPlugin.TABLE_NAME + " SET CONTENT = ? WHERE ID = ?"); + ps.setBinaryStream(1, new ByteArrayInputStream(content), content.length); + ps.setInt(2, plugin.getId()); + int updateResults = ps.executeUpdate(); + assert updateResults == 1 : "Failed to stream the content blob: " + updateResults; + ps.close(); + ps = null; + conn.close(); + conn = null; + + getTransactionManager().commit(); + getTransactionManager().begin(); + + // verify we can get the content stream along with another column in the same query + conn = ds.getConnection(); + ps = conn.prepareStatement("SELECT PATH, CONTENT FROM " + ServerPlugin.TABLE_NAME + " WHERE ID = ?"); + ps.setInt(1, plugin.getId()); + rs = ps.executeQuery(); + rs.next(); + dbPath = rs.getString(1); + assert dbPath.equals(path); + dbStream = rs.getBinaryStream(2); + assert dbStream != null : "Could not read the plugin content stream from the db"; + byte[] contentFromDb = StreamUtil.slurp(dbStream); + assert contentFromDb.length == content.length; + assert new String(contentFromDb).equals(new String(content)); + assert MessageDigestGenerator.getDigestString(new String(contentFromDb)).equals( + MessageDigestGenerator.getDigestString(new String(content))); + rs.close(); + rs = null; + ps.close(); + ps = null; + conn.close(); + conn = null; + + // clean up - delete our test plugin + getTransactionManager().commit(); + getTransactionManager().begin(); + em = getEntityManager(); + Query q = em.createNamedQuery(ServerPlugin.QUERY_FIND_ANY_BY_NAME); + q.setParameter("name", plugin.getName()); + ServerPlugin doomed = (ServerPlugin) q.getSingleResult(); + doomed = em.getReference(ServerPlugin.class, doomed.getId()); + em.remove(doomed); + assert q.getResultList().size() == 0 : "didn't remove the plugin"; + getTransactionManager().commit(); + done = true; + + } finally { + if (rs != null) { + rs.close(); + } + if (ps != null) { + ps.close(); + } + if (conn != null) { + conn.close(); + } + if (!done) { + getTransactionManager().rollback(); + } + } + } + +} diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/InstalledPluginComponent.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/InstalledPluginComponent.java index 0bb87bd..a1400ac 100644 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/InstalledPluginComponent.java +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/InstalledPluginComponent.java @@ -19,12 +19,15 @@ package org.rhq.enterprise.gui.admin.plugin;
import org.jboss.seam.ScopeType; -import org.jboss.seam.annotations.AutoCreate; import org.jboss.seam.annotations.Factory; import org.jboss.seam.annotations.Name; import org.jboss.seam.annotations.web.RequestParameter; + +import org.rhq.core.domain.plugin.AbstractPlugin; import org.rhq.core.domain.plugin.Plugin; import org.rhq.core.domain.plugin.PluginDeploymentType; +import org.rhq.core.domain.plugin.PluginKey; +import org.rhq.core.domain.plugin.ServerPlugin; import org.rhq.enterprise.server.plugin.ServerPluginsLocal; import org.rhq.enterprise.server.util.LookupUtil;
@@ -39,8 +42,10 @@ public class InstalledPluginComponent {
@RequestParameter("plugin") private String name; + @RequestParameter("deployment") + private PluginDeploymentType deployment; @RequestParameter("pluginType") - private PluginDeploymentType type; + private String pluginType;
public String getName() { return this.name; @@ -50,21 +55,30 @@ public class InstalledPluginComponent { this.name = name; }
- public PluginDeploymentType getType() { - return this.type; + public PluginDeploymentType getDeployment() { + return this.deployment; + } + + public void setType(PluginDeploymentType deployment) { + this.deployment = deployment; + } + + public String getPluginType() { + return this.pluginType; }
- public void setType(PluginDeploymentType type) { - this.type = type; + public void setPluginType(String pluginType) { + this.pluginType = pluginType; }
- @Factory(value="plugin", autoCreate=true, scope=ScopeType.PAGE) - public Plugin lookupPlugin() { - if (this.type == PluginDeploymentType.AGENT) { + @Factory(value = "plugin", autoCreate = true, scope = ScopeType.PAGE) + public AbstractPlugin lookupPlugin() { + if (this.deployment == PluginDeploymentType.AGENT) { return LookupUtil.getResourceMetadataManager().getPlugin(this.name); - } else if (this.type == PluginDeploymentType.SERVER) { + } else if (this.deployment == PluginDeploymentType.SERVER) { + PluginKey pluginKey = new PluginKey(this.deployment, this.pluginType, this.name); ServerPluginsLocal serverPluginsBean = LookupUtil.getServerPlugins(); - Plugin plugin = serverPluginsBean.getServerPlugin(this.name); + ServerPlugin plugin = serverPluginsBean.getServerPlugin(pluginKey); return serverPluginsBean.getServerPluginRelationships(plugin); }
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/InstalledPluginUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/InstalledPluginUIBean.java index 3fe6988..192d933 100644 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/InstalledPluginUIBean.java +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/InstalledPluginUIBean.java @@ -21,19 +21,22 @@ package org.rhq.enterprise.gui.admin.plugin; import javax.faces.application.FacesMessage;
import org.apache.commons.logging.Log; - import org.apache.commons.logging.LogFactory; + import org.jboss.seam.ScopeType; import org.jboss.seam.annotations.Create; import org.jboss.seam.annotations.In; import org.jboss.seam.annotations.Name; import org.jboss.seam.annotations.Scope; + import org.rhq.core.clientapi.agent.metadata.ConfigurationMetadataParser; import org.rhq.core.domain.auth.Subject; import org.rhq.core.domain.authz.Permission; import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; -import org.rhq.core.domain.plugin.Plugin; +import org.rhq.core.domain.plugin.AbstractPlugin; import org.rhq.core.domain.plugin.PluginDeploymentType; +import org.rhq.core.domain.plugin.PluginKey; +import org.rhq.core.domain.plugin.ServerPlugin; import org.rhq.core.gui.util.FacesContextUtility; import org.rhq.enterprise.gui.util.EnterpriseFacesContextUtility; import org.rhq.enterprise.server.authz.PermissionException; @@ -49,19 +52,27 @@ import org.rhq.enterprise.server.xmlschema.generated.serverplugin.ServerPluginDe @Name("InstalledPluginUIBean") public class InstalledPluginUIBean {
- private static final String OUTCOME_SUCCESS = "success"; + private static final String OUTCOME_SUCCESS_SERVER_PLUGIN = "successServerPlugin"; public static final String MANAGED_BEAN_NAME = InstalledPluginUIBean.class.getSimpleName(); private final Log log = LogFactory.getLog(InstalledPluginUIBean.class); @In - private Plugin plugin; + private AbstractPlugin plugin; private ConfigurationDefinition pluginConfigurationDefinition; private ConfigurationDefinition scheduledJobsDefinition;
- public Plugin getPlugin() { + public AbstractPlugin getPlugin() { return plugin; }
- public void setPlugin(Plugin plugin) { + public void setPlugin(AbstractPlugin plugin) { + this.plugin = plugin; + } + + public ServerPlugin getServerPlugin() { + return (ServerPlugin) this.plugin; + } + + public void setServerPlugin(ServerPlugin plugin) { this.plugin = plugin; }
@@ -78,18 +89,18 @@ public class InstalledPluginUIBean { }
public String updatePlugin() { - ServerPluginsLocal serverPlugins = LookupUtil.getServerPlugins(); - + // note we assume we are editing a server plugin - we don't support editing agent plugins yet try { - serverPlugins.updateServerPluginExceptContent(EnterpriseFacesContextUtility.getSubject(), plugin); - FacesContextUtility.addMessage(FacesMessage.SEVERITY_INFO, - "Configuration settings saved."); + ServerPluginsLocal serverPlugins = LookupUtil.getServerPlugins(); + Subject subject = EnterpriseFacesContextUtility.getSubject(); + serverPlugins.updateServerPluginExceptContent(subject, getServerPlugin()); + FacesContextUtility.addMessage(FacesMessage.SEVERITY_INFO, "Configuration settings saved.");
- return OUTCOME_SUCCESS; + return OUTCOME_SUCCESS_SERVER_PLUGIN; } catch (Exception e) { log.error("Error updating the plugin configurations.", e); FacesContextUtility.addMessage(FacesMessage.SEVERITY_ERROR, - "There was an error changing the configuration settings.", e); + "There was an error changing the configuration settings.", e);
return null; } @@ -103,9 +114,12 @@ public class InstalledPluginUIBean { if (this.plugin.getDeployment() == PluginDeploymentType.SERVER) { try { ServerPluginsLocal serverPluginsBean = LookupUtil.getServerPlugins(); - ServerPluginDescriptorType descriptor = serverPluginsBean.getServerPluginDescriptor(pluginName); - this.pluginConfigurationDefinition = ConfigurationMetadataParser.parse("pc:" + pluginName, descriptor.getPluginConfiguration()); - this.scheduledJobsDefinition = ConfigurationMetadataParser.parse("jobs:" + pluginName, descriptor.getScheduledJobs()); + PluginKey pluginKey = new PluginKey((ServerPlugin) plugin); + ServerPluginDescriptorType descriptor = serverPluginsBean.getServerPluginDescriptor(pluginKey); + this.pluginConfigurationDefinition = ConfigurationMetadataParser.parse("pc:" + pluginName, descriptor + .getPluginConfiguration()); + this.scheduledJobsDefinition = ConfigurationMetadataParser.parse("jobs:" + pluginName, descriptor + .getScheduledJobs()); } catch (Exception e) { String err = "Cannot determine what the plugin configuration or scheduled jobs configuration looks like"; log.error(err + " - Cause: " + e); @@ -116,7 +130,7 @@ public class InstalledPluginUIBean { }
/** - * Throws a permission exception if the user is not allowed to access this functionality. + * Throws a permission exception if the user is not allowed to access this functionality. */ private void hasPermission() { Subject subject = EnterpriseFacesContextUtility.getSubject(); diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/InstalledPluginsUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/InstalledPluginsUIBean.java index cfc99cf..6fac7a3 100644 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/InstalledPluginsUIBean.java +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/InstalledPluginsUIBean.java @@ -35,7 +35,9 @@ import org.richfaces.event.UploadEvent;
import org.rhq.core.domain.auth.Subject; import org.rhq.core.domain.authz.Permission; +import org.rhq.core.domain.plugin.AbstractPlugin; import org.rhq.core.domain.plugin.Plugin; +import org.rhq.core.domain.plugin.ServerPlugin; import org.rhq.core.gui.util.FacesContextUtility; import org.rhq.core.gui.util.StringUtility; import org.rhq.core.util.exception.ThrowableUtil; @@ -66,7 +68,7 @@ public class InstalledPluginsUIBean { return resourceMetadataManagerBean.getPlugins(); }
- public Collection<Plugin> getInstalledServerPlugins() { + public Collection<ServerPlugin> getInstalledServerPlugins() {
hasPermission(); return serverPluginsBean.getServerPlugins(); @@ -124,9 +126,9 @@ public class InstalledPluginsUIBean { }
public void enableServerPlugins() { - List<Plugin> selectedPlugins = getSelectedServerPlugins(); + List<ServerPlugin> selectedPlugins = getSelectedServerPlugins(); List<String> selectedPluginNames = new ArrayList<String>(); - for (Plugin selectedPlugin : selectedPlugins) { + for (ServerPlugin selectedPlugin : selectedPlugins) { selectedPluginNames.add(selectedPlugin.getName()); }
@@ -142,9 +144,9 @@ public class InstalledPluginsUIBean { }
public void disableServerPlugins() { - List<Plugin> selectedPlugins = getSelectedServerPlugins(); + List<ServerPlugin> selectedPlugins = getSelectedServerPlugins(); List<String> selectedPluginNames = new ArrayList<String>(); - for (Plugin selectedPlugin : selectedPlugins) { + for (ServerPlugin selectedPlugin : selectedPlugins) { selectedPluginNames.add(selectedPlugin.getName()); }
@@ -160,9 +162,9 @@ public class InstalledPluginsUIBean { }
public void undeployServerPlugins() { - List<Plugin> selectedPlugins = getSelectedServerPlugins(); + List<? extends AbstractPlugin> selectedPlugins = getSelectedServerPlugins(); List<String> selectedPluginNames = new ArrayList<String>(); - for (Plugin selectedPlugin : selectedPlugins) { + for (AbstractPlugin selectedPlugin : selectedPlugins) { selectedPluginNames.add(selectedPlugin.getName()); }
@@ -177,18 +179,18 @@ public class InstalledPluginsUIBean { return; }
- private List<Integer> getIds(List<Plugin> plugins) { + private List<Integer> getIds(List<? extends AbstractPlugin> plugins) { ArrayList<Integer> ids = new ArrayList<Integer>(plugins.size()); - for (Plugin plugin : plugins) { + for (AbstractPlugin plugin : plugins) { ids.add(plugin.getId()); } return ids; }
- private List<Plugin> getSelectedServerPlugins() { + private List<ServerPlugin> getSelectedServerPlugins() { Integer[] integerItems = getSelectedPluginIds(); List<Integer> ids = Arrays.asList(integerItems); - List<Plugin> plugins = serverPluginsBean.getServerPluginsById(ids); + List<ServerPlugin> plugins = serverPluginsBean.getServerPluginsById(ids); return plugins; }
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-navigation/admin-navigation.xml b/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-navigation/admin-navigation.xml index 7f19f4d..377523c 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-navigation/admin-navigation.xml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-navigation/admin-navigation.xml @@ -13,7 +13,7 @@ <to-view-id>/rhq/admin/largeenv.xhtml</to-view-id> <redirect/> </navigation-case> - + </navigation-rule>
<navigation-rule> @@ -26,20 +26,20 @@ <to-view-id>/rhq/admin/plugin/plugin-list.xhtml</to-view-id> <redirect/> </navigation-case> - + </navigation-rule>
<navigation-rule> <from-view-id>/rhq/admin/plugin/plugin-details-edit.xhtml</from-view-id>
<navigation-case> - <from-outcome>success</from-outcome> - <to-view-id>/rhq/admin/plugin/plugin-details-view.xhtml?plugin=#{plugin.name}&pluginType=#{plugin.deployment}</to-view-id> + <from-outcome>successServerPlugin</from-outcome> + <to-view-id>/rhq/admin/plugin/plugin-details-view.xhtml?plugin=#{plugin.name}&deployment=#{plugin.deployment}&pluginType=#{serverPlugin.type}</to-view-id> <redirect/> </navigation-case>
</navigation-rule> - + <navigation-rule> <navigation-case> <from-outcome>sessionExpired</from-outcome> @@ -47,5 +47,5 @@ <redirect/> </navigation-case> </navigation-rule> - + </faces-config> \ No newline at end of file diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/admin/test/control.jsp b/modules/enterprise/gui/portal-war/src/main/webapp/admin/test/control.jsp index 2c47b0a..25f3e25 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/admin/test/control.jsp +++ b/modules/enterprise/gui/portal-war/src/main/webapp/admin/test/control.jsp @@ -24,7 +24,9 @@ <%@ page import="org.rhq.enterprise.server.system.SystemManagerLocal" %> <%@ page import="org.rhq.enterprise.server.auth.SubjectManagerLocal" %> <%@ page import="org.rhq.enterprise.server.support.SupportManagerLocal" %> -<%@page import="org.rhq.enterprise.server.plugin.ServerPluginsLocal"%><html> +<%@page import="org.rhq.enterprise.server.plugin.ServerPluginsLocal"%> +<%@page import="org.rhq.core.domain.plugin.PluginKey"%> +<%@page import="org.rhq.core.domain.plugin.PluginDeploymentType"%><html> <%@ page import="org.rhq.enterprise.server.util.LookupUtil" %> <%@ page import="org.rhq.enterprise.server.scheduler.jobs.DataPurgeJob"%>
@@ -203,7 +205,8 @@ else if ("purgeServerPlugin".equals(mode)) { String serverPluginName = request.getParameter("serverPluginName"); - serverPlugins.purgeServerPlugin(subjectManager.getOverlord(), serverPluginName); + PluginKey key = new PluginKey(PluginDeploymentType.SERVER, "not-needed", serverPluginName); + serverPlugins.purgeServerPlugin(subjectManager.getOverlord(), key); result = "OK - you can now try to re-register a plugin with the name [" + serverPluginName + "]"; } else if ("typeManagerRemote".equals(mode)) diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-details-view.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-details-view.xhtml index 389923a..92d36f3 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-details-view.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-details-view.xhtml @@ -17,7 +17,8 @@ <h:outputLink value="/rhq/admin/plugin/plugin-details-edit.xhtml" styleClass="buttonmed"> <f:param name="plugin" value="#{installedPlugin.name}"/> - <f:param name="pluginType" value="#{installedPlugin.type}"/> + <f:param name="deployment" value="#{installedPlugin.deployment}"/> + <f:param name="pluginType" value="#{installedPlugin.pluginType}"/> <h:outputText value="EDIT"/> </h:outputLink> </h:panelGrid> diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-details.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-details.xhtml index cc11203..6b29013 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-details.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-details.xhtml @@ -15,7 +15,7 @@ <h:outputLink value="plugin-list.xhtml" > <h:outputText value="Installed Plugins"/> </h:outputLink> - > + > <h:outputLink value="#" > <h:outputText value="#{InstalledPluginUIBean.plugin.displayName}"/> </h:outputLink> @@ -75,7 +75,7 @@
<ui:insert name="pre-config" />
- <rich:panel rendered="#{InstalledPluginUIBean.plugin.pluginConfiguration != null}"> + <rich:panel rendered="#{InstalledPluginUIBean.pluginConfigurationDefinition != null}"> <f:facet name="header"> <h:outputText value="Plugin Configuration"/> </f:facet> @@ -85,7 +85,7 @@ readOnly="#{not editMode}" /> </rich:panel>
- <rich:panel rendered="#{InstalledPluginUIBean.plugin.scheduledJobsConfiguration != null}"> + <rich:panel rendered="#{InstalledPluginUIBean.scheduledJobsDefinition != null}"> <f:facet name="header"> <h:outputText value="Scheduled Jobs"/> </f:facet> diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-list.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-list.xhtml index 5654368..ba128c1 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-list.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-list.xhtml @@ -77,7 +77,7 @@
<h:outputLink value="/rhq/admin/plugin/plugin-details-view.xhtml"> <f:param name="plugin" value="#{agentPlugin.name}"/> - <f:param name="pluginType" value="AGENT"/> + <f:param name="deployment" value="AGENT"/> <h:outputText value="#{agentPlugin.displayName}"/> </h:outputLink>
@@ -162,7 +162,8 @@
<h:outputLink value="/rhq/admin/plugin/plugin-details-view.xhtml"> <f:param name="plugin" value="#{serverPlugin.name}"/> - <f:param name="pluginType" value="SERVER"/> + <f:param name="deployment" value="SERVER"/> + <f:param name="pluginType" value="#{serverPlugin.type}"/> <h:outputText value="#{serverPlugin.displayName}"/> </h:outputLink>
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/CoreServerServiceImpl.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/CoreServerServiceImpl.java index 8695d35..4eeb177 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/CoreServerServiceImpl.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/CoreServerServiceImpl.java @@ -259,7 +259,7 @@ public class CoreServerServiceImpl implements CoreServerService {
try { em = LookupUtil.getEntityManager(); - Query q = em.createNamedQuery(Plugin.QUERY_FIND_ALL_AGENT); + Query q = em.createNamedQuery(Plugin.QUERY_FIND_ALL_INSTALLED); List<Plugin> resultList = q.getResultList(); for (Plugin potentialPlugin : resultList) { if (potentialPlugin.isEnabled()) { diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/plugin/ServerPluginScanner.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/plugin/ServerPluginScanner.java index 6bd8c0f..853ce9c 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/plugin/ServerPluginScanner.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/plugin/ServerPluginScanner.java @@ -51,14 +51,15 @@ import org.rhq.core.db.PostgresqlDatabaseType; import org.rhq.core.db.SQLServerDatabaseType; import org.rhq.core.domain.configuration.Configuration; import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; -import org.rhq.core.domain.plugin.Plugin; -import org.rhq.core.domain.plugin.PluginDeploymentType; +import org.rhq.core.domain.plugin.PluginKey; import org.rhq.core.domain.plugin.PluginStatusType; +import org.rhq.core.domain.plugin.ServerPlugin; import org.rhq.core.util.MessageDigestGenerator; import org.rhq.core.util.jdbc.JDBCUtil; import org.rhq.core.util.stream.StreamUtil; import org.rhq.enterprise.server.auth.SubjectManagerLocal; import org.rhq.enterprise.server.plugin.ServerPluginsLocal; +import org.rhq.enterprise.server.plugin.pc.ServerPluginType; import org.rhq.enterprise.server.util.LookupUtil; import org.rhq.enterprise.server.xmlschema.ServerPluginDescriptorMetadataParser; import org.rhq.enterprise.server.xmlschema.ServerPluginDescriptorUtil; @@ -159,8 +160,7 @@ public class ServerPluginScanner {
log.info("Registering RHQ server plugin [" + pluginName + "], version " + version);
- Plugin plugin = new Plugin(pluginName, pluginFile.getName()); - plugin.setDeployment(PluginDeploymentType.SERVER); + ServerPlugin plugin = new ServerPlugin(pluginName, pluginFile.getName()); plugin.setDisplayName((displayName != null) ? displayName : pluginName); plugin.setEnabled(!descriptor.isDisabledOnDiscovery()); plugin.setDescription(descriptor.getDescription()); @@ -170,6 +170,7 @@ public class ServerPluginScanner { plugin.setMD5(MessageDigestGenerator.getDigestString(pluginFile)); plugin.setPluginConfiguration(getDefaultPluginConfiguration(descriptor)); plugin.setScheduledJobsConfiguration(getDefaultScheduledJobsConfiguration(descriptor)); + plugin.setType(new ServerPluginType(descriptor).stringify());
if (descriptor.getHelp() != null && !descriptor.getHelp().getContent().isEmpty()) { plugin.setHelp(String.valueOf(descriptor.getHelp().getContent().get(0))); @@ -178,7 +179,7 @@ public class ServerPluginScanner { ServerPluginsLocal serverPluginsManager = LookupUtil.getServerPlugins();
// see if this plugin has been deleted previously; if so, don't register and delete the file - PluginStatusType status = serverPluginsManager.getServerPluginStatus(pluginName); + PluginStatusType status = serverPluginsManager.getServerPluginStatus(new PluginKey(plugin)); if (PluginStatusType.DELETED == status) { log.warn("Plugin file [" + pluginFile + "] has been detected but that plugin with name [" + pluginName + "] was previously undeployed. Will not re-register that plugin and the file will be deleted."); @@ -251,7 +252,7 @@ public class ServerPluginScanner { String md5 = null;
PluginWithDescriptor pluginWithDescriptor = this.serverPluginsOnFilesystem.get(pluginJar); - Plugin plugin = null; + ServerPlugin plugin = null; if (pluginWithDescriptor != null) { plugin = pluginWithDescriptor.plugin; } @@ -283,15 +284,16 @@ public class ServerPluginScanner { // Let's check to see if there are any obsolete plugins that need to be deleted. // This is needed if plugin-A-1.0.jar exists and someone deployed plugin-A-1.1.jar but fails to delete plugin-A-1.0.jar. doomedPluginFiles.clear(); - HashMap<String, Plugin> pluginsByName = new HashMap<String, Plugin>(); + HashMap<String, ServerPlugin> pluginsByName = new HashMap<String, ServerPlugin>(); for (Entry<File, PluginWithDescriptor> currentPluginFileEntry : this.serverPluginsOnFilesystem.entrySet()) { - Plugin currentPlugin = currentPluginFileEntry.getValue().plugin; - Plugin existingPlugin = pluginsByName.get(currentPlugin.getName()); + ServerPlugin currentPlugin = currentPluginFileEntry.getValue().plugin; + ServerPlugin existingPlugin = pluginsByName.get(currentPlugin.getName()); if (existingPlugin == null) { // this is the usual case - this is the only plugin with the given name we've seen pluginsByName.put(currentPlugin.getName(), currentPlugin); } else { - Plugin obsolete = ServerPluginDescriptorUtil.determineObsoletePlugin(currentPlugin, existingPlugin); + ServerPlugin obsolete = ServerPluginDescriptorUtil.determineObsoletePlugin(currentPlugin, + existingPlugin); if (obsolete == null) { obsolete = currentPlugin; // both were identical, but we only want one file so pick one to get rid of } @@ -317,13 +319,13 @@ public class ServerPluginScanner { }
/** - * Creates a {@link Plugin} object for the given plugin jar and caches it. + * Creates a {@link ServerPlugin} object for the given plugin jar and caches it. * @param pluginJar information about this plugin jar will be cached * @param md5 if known, this is the plugin jar's MD5, <code>null</code> if not known * @return the plugin jar files's information that has been cached * @throws Exception if failed to get information about the plugin */ - private Plugin cacheFilesystemServerPluginJar(File pluginJar, String md5) throws Exception { + private ServerPlugin cacheFilesystemServerPluginJar(File pluginJar, String md5) throws Exception { if (md5 == null) { // don't calculate the MD5 is we've already done it before md5 = MessageDigestGenerator.getDigestString(pluginJar); } @@ -331,11 +333,10 @@ public class ServerPluginScanner { ServerPluginDescriptorType descriptor = ServerPluginDescriptorUtil.loadPluginDescriptorFromUrl(pluginUrl); String version = ServerPluginDescriptorUtil.getPluginVersion(pluginJar, descriptor).toString(); String name = descriptor.getName(); - Plugin plugin = new Plugin(name, pluginJar.getName()); + ServerPlugin plugin = new ServerPlugin(name, pluginJar.getName()); plugin.setMd5(md5); plugin.setVersion(version); plugin.setMtime(pluginJar.lastModified()); - plugin.setDeployment(PluginDeploymentType.SERVER); this.serverPluginsOnFilesystem.put(pluginJar, new PluginWithDescriptor(plugin, descriptor)); return plugin; } @@ -352,7 +353,7 @@ public class ServerPluginScanner { ResultSet rs = null;
// these are plugins (name/path/md5/mtime) that have changed in the DB but are missing from the file system - List<Plugin> updatedPlugins = new ArrayList<Plugin>(); + List<ServerPlugin> updatedPlugins = new ArrayList<ServerPlugin>();
// the same list as above, only they are the files that are written to the filesystem and no longer missing List<File> updatedFiles = new ArrayList<File>(); @@ -362,7 +363,7 @@ public class ServerPluginScanner { conn = ds.getConnection();
// get all the plugins - ps = conn.prepareStatement("SELECT NAME, PATH, MD5, MTIME, VERSION FROM " + Plugin.TABLE_NAME + ps = conn.prepareStatement("SELECT NAME, PATH, MD5, MTIME, VERSION FROM " + ServerPlugin.TABLE_NAME + " WHERE DEPLOYMENT = 'SERVER' AND STATUS = 'INSTALLED' "); rs = ps.executeQuery(); while (rs.next()) { @@ -402,13 +403,12 @@ public class ServerPluginScanner { }
if (pluginWithDescriptor != null && currentFile != null && currentFile.exists()) { - Plugin dbPlugin = new Plugin(name, path); + ServerPlugin dbPlugin = new ServerPlugin(name, path); dbPlugin.setMd5(md5); dbPlugin.setVersion(version); dbPlugin.setMtime(mtime); - dbPlugin.setDeployment(PluginDeploymentType.SERVER);
- Plugin obsoletePlugin = ServerPluginDescriptorUtil.determineObsoletePlugin(dbPlugin, + ServerPlugin obsoletePlugin = ServerPluginDescriptorUtil.determineObsoletePlugin(dbPlugin, pluginWithDescriptor.plugin);
if (obsoletePlugin == pluginWithDescriptor.plugin) { // yes use == for reference equality! @@ -449,10 +449,9 @@ public class ServerPluginScanner { } } else { log.info("Found server plugin in the DB that we do not yet have: " + name); - Plugin plugin = new Plugin(name, path, md5); + ServerPlugin plugin = new ServerPlugin(name, path, md5); plugin.setMtime(mtime); plugin.setVersion(version); - plugin.setDeployment(PluginDeploymentType.SERVER); updatedPlugins.add(plugin); this.serverPluginsOnFilesystem.remove(expectedFile); // paranoia, make sure the cache doesn't have this } @@ -460,9 +459,9 @@ public class ServerPluginScanner { JDBCUtil.safeClose(ps, rs);
// write all our updated plugins to the file system - ps = conn.prepareStatement("SELECT CONTENT FROM " + Plugin.TABLE_NAME + ps = conn.prepareStatement("SELECT CONTENT FROM " + ServerPlugin.TABLE_NAME + " WHERE DEPLOYMENT = 'SERVER' AND STATUS = 'INSTALLED' AND NAME = ?"); - for (Plugin plugin : updatedPlugins) { + for (ServerPlugin plugin : updatedPlugins) { File file = new File(this.getServerPluginDir(), plugin.getPath());
ps.setString(1, plugin.getName()); @@ -527,7 +526,7 @@ public class ServerPluginScanner { TransactionManager tm = null;
String sql = "UPDATE " - + Plugin.TABLE_NAME + + ServerPlugin.TABLE_NAME + " SET CONTENT = ?, MD5 = ?, MTIME = ?, PATH = ? WHERE DEPLOYMENT = 'SERVER' AND STATUS = 'INSTALLED' AND NAME = ?";
// if 'different' is true, give bogus data so the plugin deployer will think the plugin on the file system is new @@ -573,12 +572,12 @@ public class ServerPluginScanner { }
private class PluginWithDescriptor { - public PluginWithDescriptor(Plugin plugin, ServerPluginDescriptorType descriptor) { + public PluginWithDescriptor(ServerPlugin plugin, ServerPluginDescriptorType descriptor) { this.plugin = plugin; this.descriptor = descriptor; }
- public Plugin plugin; + public ServerPlugin plugin; public ServerPluginDescriptorType descriptor; } } diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsBean.java index 49d6e53..eec126a 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsBean.java @@ -46,9 +46,10 @@ import org.apache.commons.logging.LogFactory; import org.rhq.core.domain.auth.Subject; import org.rhq.core.domain.authz.Permission; import org.rhq.core.domain.configuration.Configuration; -import org.rhq.core.domain.plugin.Plugin; import org.rhq.core.domain.plugin.PluginDeploymentType; +import org.rhq.core.domain.plugin.PluginKey; import org.rhq.core.domain.plugin.PluginStatusType; +import org.rhq.core.domain.plugin.ServerPlugin; import org.rhq.core.util.exception.ThrowableUtil; import org.rhq.core.util.jdbc.JDBCUtil; import org.rhq.enterprise.server.RHQConstants; @@ -63,7 +64,7 @@ import org.rhq.enterprise.server.xmlschema.generated.serverplugin.ServerPluginDe
/** * A server API into the server plugin infrastructure. - * + * * @author John Mazzitelli */ @Stateless @@ -78,23 +79,22 @@ public class ServerPluginsBean implements ServerPluginsLocal { @EJB private ServerPluginsLocal serverPluginsBean; //self
- public List<Plugin> getServerPlugins() { - Query q = entityManager.createNamedQuery(Plugin.QUERY_FIND_ALL_SERVER); + public List<ServerPlugin> getServerPlugins() { + Query q = entityManager.createNamedQuery(ServerPlugin.QUERY_FIND_ALL_INSTALLED); return q.getResultList(); }
- public Plugin getServerPlugin(String name) { - Query query = entityManager.createNamedQuery(Plugin.QUERY_FIND_BY_NAME); - query.setParameter("name", name); - Plugin plugin = (Plugin) query.getSingleResult(); - if (plugin.getDeployment() != PluginDeploymentType.SERVER) { - throw new IllegalArgumentException("Plugin named [" + name + "] is not a server plugin"); - } + public ServerPlugin getServerPlugin(PluginKey key) { + Query query = entityManager.createNamedQuery(ServerPlugin.QUERY_FIND_BY_NAME); + query.setParameter("name", key.getPluginName()); + ServerPlugin plugin = (ServerPlugin) query.getSingleResult(); return plugin; }
- public Plugin getServerPluginRelationships(Plugin plugin) { - plugin = getServerPlugin(plugin.getName()); // refresh all but the content field + public ServerPlugin getServerPluginRelationships(ServerPlugin plugin) { + Query query = entityManager.createNamedQuery(ServerPlugin.QUERY_FIND_BY_NAME); + query.setParameter("name", plugin.getName()); + plugin = (ServerPlugin) query.getSingleResult();
Configuration config = plugin.getPluginConfiguration(); if (config != null) { @@ -111,18 +111,17 @@ public class ServerPluginsBean implements ServerPluginsLocal { return plugin; }
- public List<Plugin> getServerPluginsById(List<Integer> pluginIds) { + public List<ServerPlugin> getServerPluginsById(List<Integer> pluginIds) { if (pluginIds == null || pluginIds.size() == 0) { - return new ArrayList<Plugin>(); // nothing to do + return new ArrayList<ServerPlugin>(); // nothing to do } - Query query = entityManager.createNamedQuery(Plugin.QUERY_FIND_BY_IDS_AND_TYPE); + Query query = entityManager.createNamedQuery(ServerPlugin.QUERY_FIND_BY_IDS); query.setParameter("ids", pluginIds); - query.setParameter("type", PluginDeploymentType.SERVER); return query.getResultList(); }
- public ServerPluginDescriptorType getServerPluginDescriptor(String pluginName) throws Exception { - Plugin plugin = getServerPlugin(pluginName); + public ServerPluginDescriptorType getServerPluginDescriptor(PluginKey pluginKey) throws Exception { + ServerPlugin plugin = getServerPlugin(pluginKey); File pluginsDir = LookupUtil.getServerPluginService().getServerPluginsDirectory(); File pluginJar = new File(pluginsDir, plugin.getPath()); URL url = pluginJar.toURI().toURL(); @@ -130,10 +129,9 @@ public class ServerPluginsBean implements ServerPluginsLocal { return descriptor; }
- public List<String> getServerPluginNamesByEnabled(boolean enabled) { - Query query = entityManager.createNamedQuery(Plugin.QUERY_GET_NAMES_BY_ENABLED_AND_TYPE); + public List<PluginKey> getServerPluginKeysByEnabled(boolean enabled) { + Query query = entityManager.createNamedQuery(ServerPlugin.QUERY_GET_NAMES_BY_ENABLED); query.setParameter("enabled", Boolean.valueOf(enabled)); - query.setParameter("type", PluginDeploymentType.SERVER); return query.getResultList(); }
@@ -154,9 +152,9 @@ public class ServerPluginsBean implements ServerPluginsLocal { }
@RequiredPermission(Permission.MANAGE_SETTINGS) - public List<String> disableServerPlugins(Subject subject, List<Integer> pluginIds) throws Exception { + public List<PluginKey> disableServerPlugins(Subject subject, List<Integer> pluginIds) throws Exception { if (pluginIds == null || pluginIds.size() == 0) { - return new ArrayList<String>(); // nothing to do + return new ArrayList<PluginKey>(); // nothing to do }
serverPluginsBean.setServerPluginEnabledFlag(subject, pluginIds, false); @@ -164,24 +162,24 @@ public class ServerPluginsBean implements ServerPluginsLocal { ServerPluginServiceManagement serverPluginService = LookupUtil.getServerPluginService(); MasterServerPluginContainer master = serverPluginService.getMasterPluginContainer();
- List<String> doomedPlugins = new ArrayList<String>(); + List<PluginKey> doomedPlugins = new ArrayList<PluginKey>();
for (Integer pluginId : pluginIds) { - Plugin doomedPlugin = null; + ServerPlugin doomedPlugin = null; try { - doomedPlugin = entityManager.getReference(Plugin.class, pluginId); + doomedPlugin = entityManager.getReference(ServerPlugin.class, pluginId); } catch (Exception ignore) { } if (doomedPlugin != null) { - String pluginName = doomedPlugin.getName(); - doomedPlugins.add(pluginName); + PluginKey pluginKey = new PluginKey(doomedPlugin); + doomedPlugins.add(pluginKey); if (master != null) { - AbstractTypeServerPluginContainer pc = master.getPluginContainerByPlugin(pluginName); + AbstractTypeServerPluginContainer pc = master.getPluginContainerByPlugin(pluginKey); if (pc != null) { try { - pc.unschedulePluginJobs(pluginName); + pc.unschedulePluginJobs(pluginKey); } catch (Exception e) { - log.warn("Failed to unschedule jobs for plugin [" + pluginName + "]", e); + log.warn("Failed to unschedule jobs for plugin [" + pluginKey + "]", e); } } } @@ -197,9 +195,9 @@ public class ServerPluginsBean implements ServerPluginsLocal { }
@RequiredPermission(Permission.MANAGE_SETTINGS) - public List<String> undeployServerPlugins(Subject subject, List<Integer> pluginIds) throws Exception { + public List<PluginKey> undeployServerPlugins(Subject subject, List<Integer> pluginIds) throws Exception { if (pluginIds == null || pluginIds.size() == 0) { - return new ArrayList<String>(); // nothing to do + return new ArrayList<PluginKey>(); // nothing to do }
serverPluginsBean.setServerPluginEnabledFlag(subject, pluginIds, false); @@ -207,24 +205,24 @@ public class ServerPluginsBean implements ServerPluginsLocal { ServerPluginServiceManagement serverPluginService = LookupUtil.getServerPluginService(); MasterServerPluginContainer master = serverPluginService.getMasterPluginContainer();
- List<String> doomedPlugins = new ArrayList<String>(); + List<PluginKey> doomedPlugins = new ArrayList<PluginKey>();
for (Integer pluginId : pluginIds) { - Plugin doomedPlugin = null; + ServerPlugin doomedPlugin = null; try { - doomedPlugin = entityManager.getReference(Plugin.class, pluginId); + doomedPlugin = entityManager.getReference(ServerPlugin.class, pluginId); } catch (Exception ignore) { } if (doomedPlugin != null) { - String pluginName = doomedPlugin.getName(); - doomedPlugins.add(pluginName); + PluginKey pluginKey = new PluginKey(doomedPlugin); + doomedPlugins.add(pluginKey); if (master != null) { - AbstractTypeServerPluginContainer pc = master.getPluginContainerByPlugin(pluginName); + AbstractTypeServerPluginContainer pc = master.getPluginContainerByPlugin(pluginKey); if (pc != null) { try { - pc.unschedulePluginJobs(pluginName); + pc.unschedulePluginJobs(pluginKey); } catch (Exception e) { - log.warn("Failed to unschedule jobs for plugin [" + pluginName + "]", e); + log.warn("Failed to unschedule jobs for plugin [" + pluginKey + "]", e); } } } @@ -269,7 +267,7 @@ public class ServerPluginsBean implements ServerPluginsLocal { if (pluginIds == null || pluginIds.size() == 0) { return; // nothing to do } - Query q = entityManager.createNamedQuery(Plugin.UPDATE_PLUGINS_ENABLED_BY_IDS); + Query q = entityManager.createNamedQuery(ServerPlugin.UPDATE_PLUGINS_ENABLED_BY_IDS); q.setParameter("ids", pluginIds); q.setParameter("enabled", Boolean.valueOf(enabled)); int count = q.executeUpdate(); @@ -288,8 +286,8 @@ public class ServerPluginsBean implements ServerPluginsLocal { if (pluginIds == null || pluginIds.size() == 0) { return; // nothing to do } - List<Plugin> plugins = getServerPluginsById(pluginIds); - for (Plugin plugin : plugins) { + List<ServerPlugin> plugins = getServerPluginsById(pluginIds); + for (ServerPlugin plugin : plugins) { plugin.setStatus(status); updateServerPluginExceptContent(subject, plugin); } @@ -297,17 +295,17 @@ public class ServerPluginsBean implements ServerPluginsLocal { }
@RequiredPermission(Permission.MANAGE_SETTINGS) - public Plugin registerServerPlugin(Subject subject, Plugin plugin, File pluginFile) throws Exception { + public ServerPlugin registerServerPlugin(Subject subject, ServerPlugin plugin, File pluginFile) throws Exception {
if (plugin.getDeployment() != PluginDeploymentType.SERVER) { throw new IllegalArgumentException("Plugin [" + plugin.getName() + "] must be a server plugin to be registered"); }
- Plugin existingPlugin = null; + ServerPlugin existingPlugin = null; boolean newOrUpdated = false; try { - existingPlugin = getServerPlugin(plugin.getName()); + existingPlugin = getServerPlugin(new PluginKey(plugin)); } catch (NoResultException nre) { newOrUpdated = true; // this is expected for new plugins } @@ -317,7 +315,7 @@ public class ServerPluginsBean implements ServerPluginsLocal { throw new IllegalArgumentException("Cannot register plugin [" + plugin.getName() + "], it has been marked as deleted"); } - Plugin obsolete = ServerPluginDescriptorUtil.determineObsoletePlugin(plugin, existingPlugin); + ServerPlugin obsolete = ServerPluginDescriptorUtil.determineObsoletePlugin(plugin, existingPlugin); if (obsolete == existingPlugin) { // yes use == for reference equality newOrUpdated = true; } @@ -331,7 +329,7 @@ public class ServerPluginsBean implements ServerPluginsLocal { }
if (plugin.getId() == 0) { - PluginStatusType status = getServerPluginStatus(plugin.getName()); + PluginStatusType status = getServerPluginStatus(new PluginKey(plugin)); if (PluginStatusType.DELETED == status) { throw new IllegalArgumentException("Cannot register plugin [" + plugin.getName() + "], it has been previously marked as deleted."); @@ -353,33 +351,27 @@ public class ServerPluginsBean implements ServerPluginsLocal {
@RequiredPermission(Permission.MANAGE_SETTINGS) @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) - public void purgeServerPlugin(Subject subject, String pluginName) { - Query q = this.entityManager.createNamedQuery(Plugin.QUERY_FIND_ANY_BY_NAME_AND_TYPE); - q.setParameter("name", pluginName); - q.setParameter("type", PluginDeploymentType.SERVER); - Plugin doomed = (Plugin) q.getSingleResult(); + public void purgeServerPlugin(Subject subject, PluginKey pluginKey) { + Query q = this.entityManager.createNamedQuery(ServerPlugin.QUERY_FIND_ANY_BY_NAME); + q.setParameter("name", pluginKey.getPluginName()); + ServerPlugin doomed = (ServerPlugin) q.getSingleResult();
// get the reference to attach to em and use the em.remove. this cascade deletes too. - doomed = this.entityManager.getReference(Plugin.class, doomed.getId()); + doomed = this.entityManager.getReference(ServerPlugin.class, doomed.getId()); this.entityManager.remove(doomed);
- log.debug("Server plugin [" + pluginName + "] has been purged from the db"); + log.debug("Server plugin [" + pluginKey + "] has been purged from the db"); return; }
@RequiredPermission(Permission.MANAGE_SETTINGS) - public Plugin updateServerPluginExceptContent(Subject subject, Plugin plugin) throws Exception { + public ServerPlugin updateServerPluginExceptContent(Subject subject, ServerPlugin plugin) throws Exception {
// this method is here because we need a way to update the plugin's information // without blowing away the content data. Because we do not want to load the // content blob in memory, the plugin's content field will be null - if we were // to entityManager.merge that plugin POJO, it would null out that blob column.
- if (plugin.getDeployment() != PluginDeploymentType.SERVER) { - throw new IllegalArgumentException("Plugin [" + plugin.getName() - + "] must be a server plugin to be updated"); - } - if (plugin.getId() == 0) { throw new IllegalArgumentException("Plugin must already exist to update it"); } else { @@ -395,7 +387,7 @@ public class ServerPluginsBean implements ServerPluginsLocal { plugin.setScheduledJobsConfiguration(config); }
- Plugin pluginEntity = entityManager.getReference(Plugin.class, plugin.getId()); + ServerPlugin pluginEntity = entityManager.getReference(ServerPlugin.class, plugin.getId()); pluginEntity.setName(plugin.getName()); pluginEntity.setPath(plugin.getPath()); pluginEntity.setDisplayName(plugin.getDisplayName()); @@ -407,6 +399,7 @@ public class ServerPluginsBean implements ServerPluginsLocal { pluginEntity.setDeployment(plugin.getDeployment()); pluginEntity.setPluginConfiguration(plugin.getPluginConfiguration()); pluginEntity.setScheduledJobsConfiguration(plugin.getScheduledJobsConfiguration()); + pluginEntity.setType(plugin.getType()); pluginEntity.setDescription(plugin.getDescription()); pluginEntity.setHelp(plugin.getHelp()); pluginEntity.setMtime(plugin.getMtime()); @@ -420,10 +413,9 @@ public class ServerPluginsBean implements ServerPluginsLocal { return plugin; }
- public PluginStatusType getServerPluginStatus(String pluginName) { - Query q = entityManager.createNamedQuery(Plugin.QUERY_GET_STATUS_BY_NAME_AND_TYPE); - q.setParameter("name", pluginName); - q.setParameter("type", PluginDeploymentType.SERVER); + public PluginStatusType getServerPluginStatus(PluginKey pluginKey) { + Query q = entityManager.createNamedQuery(ServerPlugin.QUERY_GET_STATUS_BY_NAME); + q.setParameter("name", pluginKey.getPluginName()); PluginStatusType status; try { status = (PluginStatusType) q.getSingleResult(); @@ -439,14 +431,14 @@ public class ServerPluginsBean implements ServerPluginsLocal { // if of type "alert plugin" or "generic plugin". That is only known when the plugin descriptor // is parsed, which happens when the master plugin container is initialized. Therefore, this // needs to get plugin info from the master plugin container while the master is running. - public Map<ServerPluginType, List<String>> getAllPluginsGroupedByType() { - Map<ServerPluginType, List<String>> allPlugins = new HashMap<ServerPluginType, List<String>>(); + public Map<ServerPluginType, List<PluginKey>> getAllPluginsGroupedByType() { + Map<ServerPluginType, List<PluginKey>> allPlugins = new HashMap<ServerPluginType, List<PluginKey>>();
MasterServerPluginContainer master = LookupUtil.getServerPluginService().getMasterPluginContainer(); if (master != null) { List<ServerPluginType> types = master.getServerPluginTypes(); for (ServerPluginType type : types) { - List<String> plugins = master.getAllPluginsByPluginType(type); + List<PluginKey> plugins = master.getAllPluginsByPluginType(type); allPlugins.put(type, plugins); } } @@ -474,7 +466,7 @@ public class ServerPluginsBean implements ServerPluginsLocal { try {
conn = this.dataSource.getConnection(); - ps = conn.prepareStatement("UPDATE " + Plugin.TABLE_NAME + " SET CONTENT = ? WHERE ID = ?"); + ps = conn.prepareStatement("UPDATE " + ServerPlugin.TABLE_NAME + " SET CONTENT = ? WHERE ID = ?"); ps.setBinaryStream(1, new BufferedInputStream(fis), (int) file.length()); ps.setInt(2, id); int updateResults = ps.executeUpdate(); diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsLocal.java index a6a09bf..1820fcc 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsLocal.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsLocal.java @@ -8,72 +8,73 @@ import javax.ejb.Local; import javax.persistence.NoResultException;
import org.rhq.core.domain.auth.Subject; -import org.rhq.core.domain.plugin.Plugin; +import org.rhq.core.domain.plugin.PluginKey; import org.rhq.core.domain.plugin.PluginStatusType; +import org.rhq.core.domain.plugin.ServerPlugin; import org.rhq.enterprise.server.plugin.pc.ServerPluginType; import org.rhq.enterprise.server.xmlschema.generated.serverplugin.ServerPluginDescriptorType;
/** * Interface to the methods that interact with the serve-side plugin infrastructure. - * + * * @author John Mazzitelli */ @Local public interface ServerPluginsLocal { /** * Returns a list of all the server plugins in the database. - * + * * @return all plugins found in the DB */ - List<Plugin> getServerPlugins(); + List<ServerPlugin> getServerPlugins();
/** - * Returns a plugin with the given name. - * @param name name of plugin to find + * Returns a plugin with the given key. + * @param key identifies the plugin to find * @return the named plugin * @throws NoResultException when no plugin with that name exists */ - Plugin getServerPlugin(String name); + ServerPlugin getServerPlugin(PluginKey key);
/** * Methods in this object that return plugins normally do not include * the data from relationships with the plugin (for example, the * plugin configuration and scheduled jobs related to the plugin). - * + * * Call this method to fill in that data that wasn't originally loaded. - * + * * @param plugin * @return the same plugin, with the relationship data loaded * @throws NoResultException when no plugin with that name exists */ - Plugin getServerPluginRelationships(Plugin plugin); + ServerPlugin getServerPluginRelationships(ServerPlugin plugin);
/** * Get a list of plugins from their IDs. - * + * * @param pluginIds the IDs of the plugins to load. * @return plugins matching the given IDs */ - List<Plugin> getServerPluginsById(List<Integer> pluginIds); + List<ServerPlugin> getServerPluginsById(List<Integer> pluginIds);
/** - * Given a plugin name, returns the descriptor for that plugin. - * - * @param pluginName + * Given a plugin key, returns the descriptor for that plugin. + * + * @param pluginKey * @return descriptor parsed from the file in the plugin jar * @throws Exception if the descriptor could not be retrieved or parsed for the given plugin */ - ServerPluginDescriptorType getServerPluginDescriptor(String pluginName) throws Exception; + ServerPluginDescriptorType getServerPluginDescriptor(PluginKey pluginKey) throws Exception;
/** - * Returns a list of plugin names for only those server plugins whose + * Returns a list of plugin keys for only those server plugins whose * enabled flag is equal to the given parameter. - * - * @param enabled if <code>true</code>, return only the names of plugins that are enabled; - * if <code>false</code>, return only the names of plugins that are disabled. - * @return list of plugin names that match the enabled criteria + * + * @param enabled if <code>true</code>, return only the keys of plugins that are enabled; + * if <code>false</code>, return only the keys of plugins that are disabled. + * @return list of plugin keys that match the enabled criteria */ - List<String> getServerPluginNamesByEnabled(boolean enabled); + List<PluginKey> getServerPluginKeysByEnabled(boolean enabled);
/** * Enables the plugins and restarts the server plugin container. @@ -89,25 +90,25 @@ public interface ServerPluginsLocal { * * @param subject user making the request * @param pluginIds the plugins to be disabled - * @return the list of names of the plugins that were disabled + * @return the list of keys of the plugins that were disabled * @throws Exception if failed to disable a plugin */ - List<String> disableServerPlugins(Subject subject, List<Integer> pluginIds) throws Exception; + List<PluginKey> disableServerPlugins(Subject subject, List<Integer> pluginIds) throws Exception;
/** * Removes the plugin from the system and restarts the server plugin container. * * @param subject user making the request * @param pluginIds - * @return the list of names of plugins that were undeployed + * @return the list of keys of plugins that were undeployed * @throws Exception if failed to undeploy a plugin */ - List<String> undeployServerPlugins(Subject subject, List<Integer> pluginIds) throws Exception; + List<PluginKey> undeployServerPlugins(Subject subject, List<Integer> pluginIds) throws Exception;
/** * Turns on or off the enabled flag in the database but does NOT restart the server plugin container. * This has "requires new" semantics, so the results are committed immediately upon return. - * + * * @param subject user making the request * @param pluginIds the plugins to be enabled * @param enabled the value of the enabled flag for the plugins @@ -120,7 +121,7 @@ public interface ServerPluginsLocal { * If the status is {@link PluginStatusType#DELETED}, the enabled flag is also flipped to <code>false</code>. * * This has "requires new" semantics, so the results are committed immediately upon return. - * + * * @param subject user making the request * @param pluginIds the plugins to be enabled * @param enabled the value of the enabled flag for the plugins @@ -131,14 +132,14 @@ public interface ServerPluginsLocal { /** * Registers the given plugin to the database. This does nothing with the master plugin container, * all it does is ensure the database is up-to-date with this new plugin. - * + * * @param subject the user that needs to have permissions to add a plugin to the system * @param plugin the plugin definition * @param pluginFile the actual plugin file itself * @return the plugin after being persisted - * @throws Exception if failed to fully register the plugin + * @throws Exception if failed to fully register the plugin */ - Plugin registerServerPlugin(Subject subject, Plugin plugin, File pluginFile) throws Exception; + ServerPlugin registerServerPlugin(Subject subject, ServerPlugin plugin, File pluginFile) throws Exception;
/** * Given a plugin that already exists, this will update that plugin's data in the database, @@ -150,38 +151,38 @@ public interface ServerPluginsLocal { * @return the updated plugin * @throws Exception if the plugin did not already exist or an error occurred that caused the update to fail */ - Plugin updateServerPluginExceptContent(Subject subject, Plugin plugin) throws Exception; + ServerPlugin updateServerPluginExceptContent(Subject subject, ServerPlugin plugin) throws Exception;
/** * Purges the server plugin from the database. This ensures that, after this method returns, * the given plugin will be unknown. The plugin can be installed again later. - * + * * This has "requires new" semantics, so the results are committed immediately upon return. - * This is really a supporting method for {@link #reRegisterServerPlugin(Subject, Plugin, File)} - you'll + * This is really a supporting method for {@link #reRegisterServerPlugin(Subject, ServerPlugin, File)} - you'll * probably want to use that instead. Do not blindly purge server plugins using this method unless you * know what you are doing. - * + * * @param subject user making the request - * @param pluginName the name of the server plugin to delete + * @param pluginKey the key of the server plugin to delete */ - void purgeServerPlugin(Subject subject, String pluginName); + void purgeServerPlugin(Subject subject, PluginKey pluginKey);
/** - * Given the name of a server plugin, this will return the status of that plugin. + * Given the key of a server plugin, this will return the status of that plugin. * Use this to determine if a plugin has been deleted or not. - * - * @param pluginName the name of the plugin whose status is to be returned. + * + * @param pluginKey the key of the plugin whose status is to be returned. * @return the status of the plugin, to indicate if the plugin has been deleted or is installed. * <code>null</code> indicates an unknown plugin. */ - PluginStatusType getServerPluginStatus(String pluginName); + PluginStatusType getServerPluginStatus(PluginKey pluginKey);
/** * This will return a map containing all plugins currently known to the master plugin container. * This will return installed plugins that are both enabled and disabled. * Note that if the master plugin container is not running, an empty map is returned. - * - * @return names of all enabled and disabled plugins, keyed on their types + * + * @return keys of all enabled and disabled plugins, keyed on their types */ - Map<ServerPluginType, List<String>> getAllPluginsGroupedByType(); + Map<ServerPluginType, List<PluginKey>> getAllPluginsGroupedByType(); } diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/AbstractTypeServerPluginContainer.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/AbstractTypeServerPluginContainer.java index e88e5fd..3301dcc 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/AbstractTypeServerPluginContainer.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/AbstractTypeServerPluginContainer.java @@ -27,6 +27,7 @@ import org.apache.commons.logging.LogFactory; import org.quartz.Job; import org.quartz.JobDataMap;
+import org.rhq.core.domain.plugin.PluginKey; import org.rhq.enterprise.server.scheduler.SchedulerLocal; import org.rhq.enterprise.server.util.LookupUtil; import org.rhq.enterprise.server.xmlschema.CronScheduleType; @@ -131,7 +132,7 @@ public abstract class AbstractTypeServerPluginContainer { try { unloadPlugin(env); } catch (Exception e) { - this.log.warn("Failed to unload plugin [" + env.getPluginName() + "].", e); + this.log.warn("Failed to unload plugin [" + env.getPluginKey().getPluginName() + "].", e); } }
@@ -195,14 +196,14 @@ public abstract class AbstractTypeServerPluginContainer { // process all known plugins and schedule their jobs List<ScheduledJobDefinition> jobs; for (ServerPluginEnvironment pluginEnv : this.pluginManager.getPluginEnvironments()) { - String pluginName = pluginEnv.getPluginName(); + String pluginName = pluginEnv.getPluginKey().getPluginName();
try { jobs = this.pluginManager.getServerPluginContext(pluginEnv).getSchedules(); if (jobs != null) { for (ScheduledJobDefinition job : jobs) { try { - scheduleJob(job, pluginName); + scheduleJob(job, pluginEnv.getPluginKey()); } catch (Throwable t) { log.warn("Failed to schedule job [" + job + "] for plugin [" + pluginName + "]", t); } @@ -231,13 +232,14 @@ public abstract class AbstractTypeServerPluginContainer { * and able to process the jobs. This method should only be called when a plugin * is being disabled or removed. * + * @param pluginKey * @throws Exception if failed to unschedule jobs */ - public void unschedulePluginJobs(String pluginName) throws Exception { + public void unschedulePluginJobs(PluginKey pluginKey) throws Exception { SchedulerLocal scheduler = LookupUtil.getSchedulerBean();
// note: all jobs for a plugin are placed in the same group, where the group name is the plugin name - String groupName = pluginName; + String groupName = pluginKey.getPluginName();
scheduler.pauseJobGroup(groupName); String[] jobNames = scheduler.getJobNames(groupName); @@ -245,7 +247,7 @@ public abstract class AbstractTypeServerPluginContainer { for (String jobName : jobNames) { boolean deleted = scheduler.deleteJob(jobName, groupName); if (!deleted) { - log.warn("Plugin [" + pluginName + "] failed to get its job [" + jobName + "] unscheduled!"); + log.warn("Plugin [" + pluginKey + "] failed to get its job [" + jobName + "] unscheduled!"); } } } @@ -278,17 +280,17 @@ public abstract class AbstractTypeServerPluginContainer { * job is not enabled, this method returns immediately as a no-op. * * @param schedule instructs how the job should be scheduled - * @param pluginName the name of the plugin scheduling the job + * @param pluginKey the key of the plugin scheduling the job * * @throws Exception if failed to schedule the job */ - protected void scheduleJob(ScheduledJobDefinition schedule, String pluginName) throws Exception { + protected void scheduleJob(ScheduledJobDefinition schedule, PluginKey pluginKey) throws Exception {
if (!schedule.isEnabled()) { return; }
- String groupName = pluginName; + String groupName = pluginKey.getPluginName(); boolean rescheduleIfExists = true; // just in case the parameters change, we'll always want to reschedule it if it exists boolean isVolatile = true; // if plugin is removed, this allows for the schedule to go away upon restart automatically
@@ -302,8 +304,8 @@ public abstract class AbstractTypeServerPluginContainer {
// build the data map for the job, setting some values we need, plus adding the callback data for the plugin itself JobDataMap jobData = new JobDataMap(); - jobData.put(AbstractJobWrapper.DATAMAP_PLUGIN_NAME, pluginName); - jobData.put(AbstractJobWrapper.DATAMAP_PLUGIN_TYPE, getSupportedServerPluginType().stringify()); + jobData.put(AbstractJobWrapper.DATAMAP_PLUGIN_NAME, pluginKey.getPluginName()); + jobData.put(AbstractJobWrapper.DATAMAP_PLUGIN_TYPE, pluginKey.getPluginType().toString()); jobData.put(AbstractJobWrapper.DATAMAP_JOB_ID, schedule.getJobId()); jobData.put(AbstractJobWrapper.DATAMAP_SCHEDULE_TYPE, schedule.getScheduleType().getTypeName()); jobData.put(AbstractJobWrapper.DATAMAP_SCHEDULE_TRIGGER, schedule.getScheduleType().getScheduleTrigger()); diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ClassLoaderManager.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ClassLoaderManager.java index 0a9b61c..ae3bbe4 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ClassLoaderManager.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ClassLoaderManager.java @@ -34,6 +34,7 @@ import java.util.Set; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory;
+import org.rhq.core.domain.plugin.PluginKey; import org.rhq.enterprise.server.xmlschema.generated.serverplugin.ServerPluginDescriptorType;
/** @@ -50,9 +51,9 @@ public class ClassLoaderManager { private final File tmpDir;
/** - * Provides a map keyed on plugin name whose values are the URLs to those plugin jars. + * Provides a map keyed on plugin keys whose values are the URLs to those plugin jars. */ - private final Map<String, URL> pluginNamesUrls; + private final Map<PluginKey, URL> pluginKeysUrls;
/** * The parent classloader for those classloaders at the top of the classloader hierarchy. @@ -61,11 +62,10 @@ public class ClassLoaderManager {
/** * These are the classloaders that are built for each plugin. - * This map is keyed on plugin name. * * @see #obtainServerPluginClassLoader(String) */ - private final Map<String, ClassLoader> serverPluginClassLoaders; + private final Map<PluginKey, ClassLoader> serverPluginClassLoaders;
/** * Creates the object that will manage all classloaders for the plugins deployed in the server. @@ -79,11 +79,13 @@ public class ClassLoaderManager {
this.rootClassLoader = rootClassLoader; this.tmpDir = tmpDir; - this.serverPluginClassLoaders = new HashMap<String, ClassLoader>(); + this.serverPluginClassLoaders = new HashMap<PluginKey, ClassLoader>();
- this.pluginNamesUrls = new HashMap<String, URL>(plugins.size()); + this.pluginKeysUrls = new HashMap<PluginKey, URL>(plugins.size()); for (Map.Entry<URL, ? extends ServerPluginDescriptorType> entry : plugins.entrySet()) { - this.pluginNamesUrls.put(entry.getValue().getName(), entry.getKey()); + ServerPluginType pluginType = new ServerPluginType(entry.getValue()); + PluginKey pluginKey = PluginKey.createServerPluginKey(pluginType.stringify(), entry.getValue().getName()); + this.pluginKeysUrls.put(pluginKey, entry.getKey()); }
return; @@ -133,24 +135,24 @@ public class ClassLoaderManager { /** * Returns a plugin classloader (creating it if necessary). * - * @param pluginName the plugin whose classloader is to be created + * @param pluginKey the plugin whose classloader is to be created * @return the plugin classloader * @throws Exception */ - public synchronized ClassLoader obtainServerPluginClassLoader(String pluginName) throws Exception { + public synchronized ClassLoader obtainServerPluginClassLoader(PluginKey pluginKey) throws Exception {
- ClassLoader cl = this.serverPluginClassLoaders.get(pluginName); + ClassLoader cl = this.serverPluginClassLoaders.get(pluginKey);
if (cl == null) { - URL pluginJarUrl = this.pluginNamesUrls.get(pluginName); + URL pluginJarUrl = this.pluginKeysUrls.get(pluginKey);
if (log.isDebugEnabled()) { - log.debug("Creating classloader for plugin [" + pluginName + "] from URL [" + pluginJarUrl + ']'); + log.debug("Creating classloader for plugin [" + pluginKey + "] from URL [" + pluginJarUrl + ']'); }
ClassLoader parentClassLoader = this.rootClassLoader; cl = createClassLoader(pluginJarUrl, null, parentClassLoader); - this.serverPluginClassLoaders.put(pluginName, cl); + this.serverPluginClassLoaders.put(pluginKey, cl); }
return cl; @@ -167,7 +169,7 @@ public class ClassLoaderManager { }
/** - * Returns a shallow copy of the plugin classloaders keyed on plugin name. This method is here + * Returns a shallow copy of the plugin classloaders keyed on plugin key. This method is here * just to support a plugin container management MBean. * * Do not use this method to obtain a plugin's classloader, instead, you want to use @@ -175,8 +177,8 @@ public class ClassLoaderManager { * * @return all plugin classloaders currently assigned to plugins (will never be <code>null</code>) */ - public synchronized Map<String, ClassLoader> getServerPluginClassLoaders() { - return new HashMap<String, ClassLoader>(this.serverPluginClassLoaders); + public synchronized Map<PluginKey, ClassLoader> getServerPluginClassLoaders() { + return new HashMap<PluginKey, ClassLoader>(this.serverPluginClassLoaders); }
private synchronized Set<ClassLoader> getUniqueServerPluginClassLoaders() { diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/MasterServerPluginContainer.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/MasterServerPluginContainer.java index 4ab3fb2..fc54bb2 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/MasterServerPluginContainer.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/MasterServerPluginContainer.java @@ -30,6 +30,7 @@ import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory;
+import org.rhq.core.domain.plugin.PluginKey; import org.rhq.enterprise.server.plugin.pc.alert.AlertServerPluginContainer; import org.rhq.enterprise.server.plugin.pc.content.ContentServerPluginContainer; import org.rhq.enterprise.server.plugin.pc.generic.GenericServerPluginContainer; @@ -60,7 +61,7 @@ public class MasterServerPluginContainer { * Because the individual plugin containers are only managing enabled plugins (they are never told about plugins that disabled). * this map contains the lists of plugins that are disabled so others can find out what plugins are registered but not running. */ - private Map<ServerPluginType, List<String>> disabledPlugins = new HashMap<ServerPluginType, List<String>>(); + private Map<ServerPluginType, List<PluginKey>> disabledPlugins = new HashMap<ServerPluginType, List<PluginKey>>();
/** * Starts the master plugin container, which will load all plugins and begin managing them. @@ -115,7 +116,9 @@ public class MasterServerPluginContainer { URL pluginUrl = entry.getKey(); ServerPluginDescriptorType descriptor = entry.getValue(); String pluginName = descriptor.getName(); - ClassLoader classLoader = this.classLoaderManager.obtainServerPluginClassLoader(pluginName); + ServerPluginType pluginType = new ServerPluginType(descriptor); + PluginKey pluginKey = PluginKey.createServerPluginKey(pluginType.stringify(), pluginName); + ClassLoader classLoader = this.classLoaderManager.obtainServerPluginClassLoader(pluginKey); AbstractTypeServerPluginContainer pc = getPluginContainerByDescriptor(descriptor); if (pc != null) { log.debug("Loading server plugin [" + pluginUrl + "] into its plugin container"); @@ -243,7 +246,7 @@ public class MasterServerPluginContainer {
/** * Returns the manager that is responsible for created classloaders for plugins. - * + * * @return classloader manager */ public ClassLoaderManager getClassLoaderManager() { @@ -251,18 +254,18 @@ public class MasterServerPluginContainer { }
/** - * Given a plugin type, this will return the names of all known plugins of that type. + * Given a plugin type, this will return the keys of all known plugins of that type. * This includes all types that are currently started as well as plugins * that have been disabled. - * + * * If the master plugin container has not been started, this returns an empty list. - * + * * @param pluginType * * @return list of both enabled and disabled plugins of the given type */ - public List<String> getAllPluginsByPluginType(ServerPluginType pluginType) { - List<String> allPlugins = new ArrayList<String>(); + public List<PluginKey> getAllPluginsByPluginType(ServerPluginType pluginType) { + List<PluginKey> allPlugins = new ArrayList<PluginKey>();
AbstractTypeServerPluginContainer pc = getPluginContainerByPluginType(pluginType); if (pc != null) { @@ -272,13 +275,13 @@ public class MasterServerPluginContainer { Collection<ServerPluginEnvironment> envs = pluginManager.getPluginEnvironments(); if (envs != null) { for (ServerPluginEnvironment env : envs) { - allPlugins.add(env.getPluginName()); + allPlugins.add(env.getPluginKey()); } } }
// add the disabled plugins - List<String> disabled = this.disabledPlugins.get(pluginType); + List<PluginKey> disabled = this.disabledPlugins.get(pluginType); if (disabled != null) { allPlugins.addAll(disabled); } @@ -292,7 +295,7 @@ public class MasterServerPluginContainer { * that are supported by a server plugin container. You can obtain the server * plugin container that manages a particular server plugin type via * {@link #getPluginContainerByPluginType(ServerPluginType)}. - * + * * @return all known server plugin types */ public synchronized List<ServerPluginType> getServerPluginTypes() { @@ -302,7 +305,7 @@ public class MasterServerPluginContainer { /** * Get the plugin container of the given class. This method provides a strongly typed return value, * based on the type of plugin container the caller wants returned. - * + * * @param clazz the class name of the plugin container that the caller wants * @return the plugin container of the given class (<code>null</code> if none found) */ @@ -317,17 +320,24 @@ public class MasterServerPluginContainer { }
/** - * Given the name of a deployed plugin, this returns the plugin container that is hosting - * that plugin. If there is no plugin with the given name or that plugin is not + * Given the key of a deployed plugin, this returns the plugin container that is hosting + * that plugin. If there is no plugin with the given key or that plugin is not * loaded in any plugin container (e.g. when it is disabled), then <code>null</code> is returned. - * - * @param pluginName - * @return the plugin container that is managing the named plugin of <code>null</code> + * + * @param pluginKey + * @return the plugin container that is managing the named plugin or <code>null</code> */ - public synchronized <T extends AbstractTypeServerPluginContainer> T getPluginContainerByPlugin(String pluginName) { + public synchronized <T extends AbstractTypeServerPluginContainer> T getPluginContainerByPlugin(PluginKey pluginKey) { for (AbstractTypeServerPluginContainer pc : this.pluginContainers.values()) { - if (null != pc.getPluginManager().getPluginEnvironment(pluginName)) { - return (T) pc; + try { + if (pc.getSupportedServerPluginType().equals(new ServerPluginType(pluginKey.getPluginType()))) { + if (null != pc.getPluginManager().getPluginEnvironment(pluginKey.getPluginName())) { + return (T) pc; + } + } + } catch (Exception skip) { + // should never really happen + log.error("Bad plugin key: " + pluginKey); } } return null; @@ -335,7 +345,7 @@ public class MasterServerPluginContainer {
/** * Given a plugin's descriptor, this will return the plugin container that can manage the plugin. - * + * * @param descriptor descriptor to identify a plugin whose container is to be returned * @return a plugin container that can handle the plugin with the given descriptor */ @@ -346,7 +356,7 @@ public class MasterServerPluginContainer {
/** * Given a plugin's descriptor, this will return the plugin container that can manage the plugin. - * + * * @param descriptor descriptor to identify a plugin whose container is to be returned * @return a plugin container that can handle the plugin with the given descriptor */ @@ -361,9 +371,9 @@ public class MasterServerPluginContainer { /** * Finds all plugins and parses their descriptors. This is only called during * this master plugin container's {@link #initialize(MasterServerPluginContainerConfiguration) initialization}. - * + * * If a plugin fails to load, it will be ignored - other plugins will still load. - * + * * @return a map of plugins, keyed on the plugin jar URL whose values are the parsed descriptors * * @throws Exception on catastrophic failure. Note that if a plugin failed to load, @@ -381,7 +391,7 @@ public class MasterServerPluginContainer {
if (pluginFiles != null) {
- List<String> allDisabledPlugins = getDisabledPluginNames(); + List<PluginKey> allDisabledPlugins = getDisabledPluginNames();
for (File pluginFile : pluginFiles) { if (pluginFile.getName().endsWith(".jar")) { @@ -391,19 +401,22 @@ public class MasterServerPluginContainer { ServerPluginDescriptorType descriptor; descriptor = ServerPluginDescriptorUtil.loadPluginDescriptorFromUrl(pluginUrl); if (descriptor != null) { - if (!allDisabledPlugins.contains(descriptor.getName())) { + PluginKey pluginKey = PluginKey.createServerPluginKey(new ServerPluginType(descriptor) + .stringify(), descriptor.getName()); + + if (!allDisabledPlugins.contains(pluginKey)) { log.debug("pre-loaded server plugin from URL: " + pluginUrl); plugins.put(pluginUrl, descriptor); } else { log.info("Server plugin [" + descriptor.getName() + "] is disabled and will not be initialized"); ServerPluginType pluginType = new ServerPluginType(descriptor); - List<String> disabledByType = this.disabledPlugins.get(pluginType); + List<PluginKey> disabledByType = this.disabledPlugins.get(pluginType); if (disabledByType == null) { - disabledByType = new ArrayList<String>(1); + disabledByType = new ArrayList<PluginKey>(1); this.disabledPlugins.put(pluginType, disabledByType); } - disabledByType.add(descriptor.getName()); + disabledByType.add(pluginKey); } } } catch (Throwable t) { @@ -419,22 +432,22 @@ public class MasterServerPluginContainer { }
/** - * This will return a list of plugin names that represent all the plugins that are to be - * disabled. If a plugin jar is found on the filesystem, its plugin name should be checked with - * this "blacklist" if it its name is found, that plugin should not be loaded. - * + * This will return a list of plugin keys that represent all the plugins that are to be + * disabled. If a plugin jar is found on the filesystem, its plugin key should be checked with + * this "blacklist" - if its key is found, that plugin should not be loaded. + * * @return names of "blacklisted" plugins that should not be loaded */ - protected List<String> getDisabledPluginNames() { - List<String> disabledPlugins = LookupUtil.getServerPlugins().getServerPluginNamesByEnabled(false); + protected List<PluginKey> getDisabledPluginNames() { + List<PluginKey> disabledPlugins = LookupUtil.getServerPlugins().getServerPluginKeysByEnabled(false); return disabledPlugins; }
/** * Creates the individual plugin containers that can be used to deploy different plugin types. - * + * * <p>This is protected to allow subclasses to override the PCs that are created by this service (mainly to support tests).</p> - * + * * @return the new plugin containers created by this method */ protected List<AbstractTypeServerPluginContainer> createPluginContainers() { @@ -448,7 +461,7 @@ public class MasterServerPluginContainer {
/** * Create the root classloader that will be the ancester to all plugin classloaders. - * + * * @return the root server plugin classloader */ protected ClassLoader createRootServerPluginClassLoader() { @@ -463,7 +476,7 @@ public class MasterServerPluginContainer { * @param plugins maps plugin URLs with their parsed descriptors * @param rootClassLoader the classloader at the top of the classloader hierarchy * @param tmpDir where the classloaders can write out the jars that are embedded in the plugin jars - * + * * @return the classloader manager instance */ protected ClassLoaderManager createClassLoaderManager(Map<URL, ? extends ServerPluginDescriptorType> plugins, diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginEnvironment.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginEnvironment.java index e0809a6..5a7dc61 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginEnvironment.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginEnvironment.java @@ -20,6 +20,7 @@ package org.rhq.enterprise.server.plugin.pc;
import java.net.URL;
+import org.rhq.core.domain.plugin.PluginKey; import org.rhq.enterprise.server.xmlschema.generated.serverplugin.ServerPluginDescriptorType;
/** @@ -29,7 +30,7 @@ import org.rhq.enterprise.server.xmlschema.generated.serverplugin.ServerPluginDe */ public class ServerPluginEnvironment { private final URL pluginUrl; - private final String pluginName; + private final PluginKey pluginKey; private final ClassLoader pluginClassLoader; private final ServerPluginDescriptorType pluginDescriptor;
@@ -47,11 +48,12 @@ public class ServerPluginEnvironment { this.pluginUrl = pluginUrl; this.pluginClassLoader = classLoader; this.pluginDescriptor = descriptor; - this.pluginName = this.pluginDescriptor.getName(); + String pluginTypeStr = new ServerPluginType(descriptor).stringify(); + this.pluginKey = PluginKey.createServerPluginKey(pluginTypeStr, this.pluginDescriptor.getName()); }
- public String getPluginName() { - return this.pluginName; + public PluginKey getPluginKey() { + return this.pluginKey; }
public URL getPluginUrl() { @@ -68,6 +70,6 @@ public class ServerPluginEnvironment {
@Override public String toString() { - return this.pluginName + ": url=[" + this.pluginUrl + "]"; + return this.pluginKey + ": url=[" + this.pluginUrl + "]"; } } \ No newline at end of file diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginManager.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginManager.java index 36fa5bd..87f2575 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginManager.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginManager.java @@ -30,7 +30,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory;
import org.rhq.core.domain.configuration.Configuration; -import org.rhq.core.domain.plugin.Plugin; +import org.rhq.core.domain.plugin.ServerPlugin; import org.rhq.enterprise.server.plugin.ServerPluginsLocal; import org.rhq.enterprise.server.util.LookupUtil; import org.rhq.enterprise.server.xmlschema.ScheduledJobDefinition; @@ -117,7 +117,7 @@ public class ServerPluginManager { * @throws Exception if the plugin manager cannot load the plugin or deems the plugin invalid */ public void loadPlugin(ServerPluginEnvironment env) throws Exception { - String pluginName = env.getPluginName(); + String pluginName = env.getPluginKey().getPluginName(); log.debug("Loading server plugin [" + pluginName + "] from: " + env.getPluginUrl());
// tell the plugin we are loading it @@ -198,7 +198,7 @@ public class ServerPluginManager { * @throws Exception if the plugin manager cannot unload the plugin */ public void unloadPlugin(ServerPluginEnvironment env) throws Exception { - String pluginName = env.getPluginName(); + String pluginName = env.getPluginKey().getPluginName(); log.debug("Unloading server plugin [" + pluginName + "]");
try { @@ -271,7 +271,7 @@ public class ServerPluginManager {
protected ServerPluginContext getServerPluginContext(ServerPluginEnvironment env) {
- String pluginName = env.getPluginName(); + String pluginName = env.getPluginKey().getPluginName(); ServerPluginContext context = this.pluginContextCache.get(pluginName);
// if we already created it, return it immediately and don't create another @@ -288,7 +288,7 @@ public class ServerPluginManager { List<ScheduledJobDefinition> schedules;
try { - Plugin plugin = getPlugin(env); + ServerPlugin plugin = getPlugin(env); plugnConfig = plugin.getPluginConfiguration(); Configuration scheduledJobsConfig = plugin.getScheduledJobsConfiguration(); schedules = ServerPluginDescriptorMetadataParser.getScheduledJobs(scheduledJobsConfig); @@ -306,12 +306,12 @@ public class ServerPluginManager { * the plugin configuration and scheduled jobs configuration. * * @param pluginEnv - * @return the Plugin object for the given plugin + * @return the ServerPlugin object for the given plugin */ - protected Plugin getPlugin(ServerPluginEnvironment pluginEnv) { + protected ServerPlugin getPlugin(ServerPluginEnvironment pluginEnv) { // get the plugin data from the database ServerPluginsLocal serverPluginsManager = LookupUtil.getServerPlugins(); - Plugin plugin = serverPluginsManager.getServerPlugin(pluginEnv.getPluginName()); + ServerPlugin plugin = serverPluginsManager.getServerPlugin(pluginEnv.getPluginKey()); return plugin; }
@@ -332,7 +332,7 @@ public class ServerPluginManager { */ protected ServerPluginComponent createServerPluginComponent(ServerPluginEnvironment environment) throws Exception {
- String pluginName = environment.getPluginName(); + String pluginName = environment.getPluginKey().getPluginName(); ServerPluginComponent instance = null;
ServerPluginComponentType componentXml = environment.getPluginDescriptor().getPluginComponent(); diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/content/ContentServerPluginManager.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/content/ContentServerPluginManager.java index 6f42c5e..8d690f9 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/content/ContentServerPluginManager.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/content/ContentServerPluginManager.java @@ -112,7 +112,7 @@ public class ContentServerPluginManager extends ServerPluginManager {
@Override public void unloadPlugin(ServerPluginEnvironment env) throws Exception { - metadataManager.unloadPlugin(env.getPluginName()); + metadataManager.unloadPlugin(env.getPluginKey().getPluginName()); super.unloadPlugin(env); }; } \ No newline at end of file diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/metadata/ResourceMetadataManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/metadata/ResourceMetadataManagerBean.java index d502f4e..a72c8c3 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/metadata/ResourceMetadataManagerBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/metadata/ResourceMetadataManagerBean.java @@ -50,7 +50,6 @@ import org.rhq.core.clientapi.descriptor.AgentPluginDescriptorUtil; import org.rhq.core.clientapi.descriptor.plugin.PluginDescriptor; import org.rhq.core.domain.auth.Subject; import org.rhq.core.domain.authz.Permission; -import org.rhq.core.domain.configuration.Configuration; import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; import org.rhq.core.domain.content.PackageType; import org.rhq.core.domain.event.EventDefinition; @@ -125,7 +124,7 @@ public class ResourceMetadataManagerBean implements ResourceMetadataManagerLocal */ @SuppressWarnings("unchecked") public List<Plugin> getPlugins() { - Query q = entityManager.createNamedQuery(Plugin.QUERY_FIND_ALL_AGENT); + Query q = entityManager.createNamedQuery(Plugin.QUERY_FIND_ALL_INSTALLED); return q.getResultList(); }
@@ -197,19 +196,6 @@ public class ResourceMetadataManagerBean implements ResourceMetadataManagerLocal if (plugin.getId() == 0) { entityManager.persist(plugin); } else { - // agent plugins don't support these configs, but if/when they do in the future, this will support it - // make sure we create (if necessary) and attach the configs - Configuration config = plugin.getPluginConfiguration(); - if (config != null) { - config = entityManager.merge(config); - plugin.setPluginConfiguration(config); - } - config = plugin.getScheduledJobsConfiguration(); - if (config != null) { - config = entityManager.merge(config); - plugin.setScheduledJobsConfiguration(config); - } - // update all the fields except content Plugin pluginEntity = entityManager.getReference(Plugin.class, plugin.getId()); pluginEntity.setName(plugin.getName()); @@ -221,8 +207,6 @@ public class ResourceMetadataManagerBean implements ResourceMetadataManagerLocal pluginEntity.setVersion(plugin.getVersion()); pluginEntity.setAmpsVersion(plugin.getAmpsVersion()); pluginEntity.setDeployment(plugin.getDeployment()); - pluginEntity.setPluginConfiguration(plugin.getPluginConfiguration()); - pluginEntity.setScheduledJobsConfiguration(plugin.getScheduledJobsConfiguration()); pluginEntity.setDescription(plugin.getDescription()); pluginEntity.setHelp(plugin.getHelp()); pluginEntity.setMtime(plugin.getMtime()); diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/plugin/ServerPluginsBeanTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/plugin/ServerPluginsBeanTest.java index d1a6aba..63f2e1d 100644 --- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/plugin/ServerPluginsBeanTest.java +++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/plugin/ServerPluginsBeanTest.java @@ -34,12 +34,15 @@ import org.rhq.core.domain.auth.Subject; import org.rhq.core.domain.configuration.Configuration; import org.rhq.core.domain.configuration.PropertyMap; import org.rhq.core.domain.configuration.PropertySimple; -import org.rhq.core.domain.plugin.Plugin; import org.rhq.core.domain.plugin.PluginDeploymentType; +import org.rhq.core.domain.plugin.PluginKey; import org.rhq.core.domain.plugin.PluginStatusType; +import org.rhq.core.domain.plugin.ServerPlugin; +import org.rhq.enterprise.server.plugin.pc.ServerPluginType; import org.rhq.enterprise.server.plugin.pc.generic.TestGenericServerPluginService; import org.rhq.enterprise.server.test.AbstractEJB3Test; import org.rhq.enterprise.server.util.LookupUtil; +import org.rhq.enterprise.server.xmlschema.generated.serverplugin.generic.GenericPluginDescriptorType;
/** * @author John Mazzitelli @@ -75,10 +78,10 @@ public class ServerPluginsBeanTest extends AbstractEJB3Test { em = getEntityManager();
Query q = em - .createQuery("SELECT p FROM Plugin p LEFT JOIN FETCH p.pluginConfiguration LEFT JOIN FETCH p.scheduledJobsConfiguration WHERE p.name LIKE 'serverplugintest%'"); - List<Plugin> doomed = q.getResultList(); - for (Plugin plugin : doomed) { - em.remove(em.getReference(Plugin.class, plugin.getId())); + .createQuery("SELECT p FROM ServerPlugin p LEFT JOIN FETCH p.pluginConfiguration LEFT JOIN FETCH p.scheduledJobsConfiguration WHERE p.name LIKE 'serverplugintest%'"); + List<ServerPlugin> doomed = q.getResultList(); + for (ServerPlugin plugin : doomed) { + em.remove(em.getReference(ServerPlugin.class, plugin.getId())); }
getTransactionManager().commit(); @@ -98,16 +101,18 @@ public class ServerPluginsBeanTest extends AbstractEJB3Test { }
public void testGetPlugins() throws Exception { - Plugin p1 = registerPlugin(1); - Plugin p2 = registerPlugin(2); - List<String> pluginNames = this.serverPluginsBean.getServerPluginNamesByEnabled(true); - assert pluginNames.contains(p1.getName()) : pluginNames; - assert pluginNames.contains(p2.getName()) : pluginNames; - pluginNames = this.serverPluginsBean.getServerPluginNamesByEnabled(false); - assert !pluginNames.contains(p1.getName()) : pluginNames; - assert !pluginNames.contains(p2.getName()) : pluginNames; - - Plugin plugin = this.serverPluginsBean.getServerPlugin(p1.getName()); + ServerPlugin p1 = registerPlugin(1); + ServerPlugin p2 = registerPlugin(2); + PluginKey p1key = new PluginKey(p1); + PluginKey p2key = new PluginKey(p2); + List<PluginKey> pluginKeys = this.serverPluginsBean.getServerPluginKeysByEnabled(true); + assert pluginKeys.contains(p1key) : pluginKeys; + assert pluginKeys.contains(p2key) : pluginKeys; + pluginKeys = this.serverPluginsBean.getServerPluginKeysByEnabled(false); + assert !pluginKeys.contains(p1key) : pluginKeys; + assert !pluginKeys.contains(p2key) : pluginKeys; + + ServerPlugin plugin = this.serverPluginsBean.getServerPlugin(p1key); assert plugin.getId() == p1.getId() : plugin; assert plugin.getName().equals(p1.getName()) : plugin; assetLazyInitializationException(plugin); @@ -118,7 +123,7 @@ public class ServerPluginsBeanTest extends AbstractEJB3Test { assert plugin.getPluginConfiguration().equals(p1.getPluginConfiguration()); assert plugin.getScheduledJobsConfiguration().equals(p1.getScheduledJobsConfiguration());
- List<Plugin> plugins = this.serverPluginsBean.getServerPlugins(); + List<ServerPlugin> plugins = this.serverPluginsBean.getServerPlugins(); assert plugins.contains(p1) : plugins; assert plugins.contains(p2) : plugins; assetLazyInitializationException(plugins.get(0)); @@ -136,11 +141,13 @@ public class ServerPluginsBeanTest extends AbstractEJB3Test { }
public void testUpdatePlugins() throws Exception { - Plugin p1 = registerPlugin(1); - p1 = this.serverPluginsBean.getServerPlugin(p1.getName()); + ServerPlugin p1 = registerPlugin(1); + PluginKey p1key = new PluginKey(p1); + + p1 = this.serverPluginsBean.getServerPlugin(p1key); p1 = this.serverPluginsBean.getServerPluginRelationships(p1);
- Plugin p1update = this.serverPluginsBean.updateServerPluginExceptContent(getOverlord(), p1); + ServerPlugin p1update = this.serverPluginsBean.updateServerPluginExceptContent(getOverlord(), p1); p1update = this.serverPluginsBean.getServerPluginRelationships(p1update);
assert p1update.getId() == p1.getId() : p1update; @@ -154,41 +161,43 @@ public class ServerPluginsBeanTest extends AbstractEJB3Test { }
public void testDisableEnablePlugins() throws Exception { - Plugin p1 = registerPlugin(1); - Plugin p2 = registerPlugin(2); + ServerPlugin p1 = registerPlugin(1); + ServerPlugin p2 = registerPlugin(2); + PluginKey p1key = new PluginKey(p1); + PluginKey p2key = new PluginKey(p2);
List<Integer> ids = new ArrayList<Integer>(2); ids.add(p1.getId()); ids.add(p2.getId()); - List<String> disabled = this.serverPluginsBean.disableServerPlugins(getOverlord(), ids); + List<PluginKey> disabled = this.serverPluginsBean.disableServerPlugins(getOverlord(), ids); assert disabled.size() == 2 : disabled; - assert disabled.contains(p1.getName()) : disabled; - assert disabled.contains(p2.getName()) : disabled; + assert disabled.contains(p1key) : disabled; + assert disabled.contains(p2key) : disabled; ; - assert this.serverPluginsBean.getServerPlugin(p1.getName()).getStatus() == PluginStatusType.INSTALLED; // still installed - assert this.serverPluginsBean.getServerPlugin(p2.getName()).getStatus() == PluginStatusType.INSTALLED; // still installed - List<String> pluginNames = this.serverPluginsBean.getServerPluginNamesByEnabled(false); - assert pluginNames.contains(p1.getName()) : pluginNames; - assert pluginNames.contains(p2.getName()) : pluginNames; - pluginNames = this.serverPluginsBean.getServerPluginNamesByEnabled(true); - assert !pluginNames.contains(p1.getName()) : pluginNames; - assert !pluginNames.contains(p2.getName()) : pluginNames; + assert this.serverPluginsBean.getServerPlugin(p1key).getStatus() == PluginStatusType.INSTALLED; // still installed + assert this.serverPluginsBean.getServerPlugin(p2key).getStatus() == PluginStatusType.INSTALLED; // still installed + List<PluginKey> pluginKeys = this.serverPluginsBean.getServerPluginKeysByEnabled(false); + assert pluginKeys.contains(p1key) : pluginKeys; + assert pluginKeys.contains(p2key) : pluginKeys; + pluginKeys = this.serverPluginsBean.getServerPluginKeysByEnabled(true); + assert !pluginKeys.contains(p1key) : pluginKeys; + assert !pluginKeys.contains(p2key) : pluginKeys;
// re-enable them this.serverPluginsBean.enableServerPlugins(getOverlord(), ids); - pluginNames = this.serverPluginsBean.getServerPluginNamesByEnabled(true); - assert pluginNames.contains(p1.getName()) : pluginNames; - assert pluginNames.contains(p2.getName()) : pluginNames; - pluginNames = this.serverPluginsBean.getServerPluginNamesByEnabled(false); - assert !pluginNames.contains(p1.getName()) : pluginNames; - assert !pluginNames.contains(p2.getName()) : pluginNames; + pluginKeys = this.serverPluginsBean.getServerPluginKeysByEnabled(true); + assert pluginKeys.contains(p1key) : pluginKeys; + assert pluginKeys.contains(p2key) : pluginKeys; + pluginKeys = this.serverPluginsBean.getServerPluginKeysByEnabled(false); + assert !pluginKeys.contains(p1key) : pluginKeys; + assert !pluginKeys.contains(p2key) : pluginKeys;
// make sure none of these enable/disable settings lost our config - Plugin plugin = this.serverPluginsBean.getServerPlugin(p1.getName()); + ServerPlugin plugin = this.serverPluginsBean.getServerPlugin(p1key); plugin = this.serverPluginsBean.getServerPluginRelationships(plugin); assert plugin.getPluginConfiguration() != null; // no LazyInitException should be thrown! assert plugin.getPluginConfiguration().equals(p1.getPluginConfiguration()); - plugin = this.serverPluginsBean.getServerPlugin(p2.getName()); + plugin = this.serverPluginsBean.getServerPlugin(p2key); plugin = this.serverPluginsBean.getServerPluginRelationships(plugin); assert plugin.getPluginConfiguration() != null; // no LazyInitException should be thrown! assert plugin.getPluginConfiguration().equals(p1.getPluginConfiguration()); @@ -198,82 +207,96 @@ public class ServerPluginsBeanTest extends AbstractEJB3Test {
PluginStatusType status;
- status = this.serverPluginsBean.getServerPluginStatus(TEST_PLUGIN_NAME_PREFIX + "1"); + PluginKey missingKey; + missingKey = new PluginKey(PluginDeploymentType.SERVER, new ServerPluginType(GenericPluginDescriptorType.class) + .stringify(), TEST_PLUGIN_NAME_PREFIX + "1"); + status = this.serverPluginsBean.getServerPluginStatus(missingKey); assert status == null; - status = this.serverPluginsBean.getServerPluginStatus(TEST_PLUGIN_NAME_PREFIX + "2"); + missingKey = new PluginKey(PluginDeploymentType.SERVER, new ServerPluginType(GenericPluginDescriptorType.class) + .stringify(), TEST_PLUGIN_NAME_PREFIX + "2"); + status = this.serverPluginsBean.getServerPluginStatus(missingKey); assert status == null;
- Plugin p1 = registerPlugin(1); - Plugin p2 = registerPlugin(2); + ServerPlugin p1 = registerPlugin(1); + ServerPlugin p2 = registerPlugin(2); + PluginKey p1key = new PluginKey(p1); + PluginKey p2key = new PluginKey(p2);
- status = this.serverPluginsBean.getServerPluginStatus(p1.getName()); + status = this.serverPluginsBean.getServerPluginStatus(p1key); assert status == PluginStatusType.INSTALLED; - status = this.serverPluginsBean.getServerPluginStatus(p2.getName()); + status = this.serverPluginsBean.getServerPluginStatus(p2key); assert status == PluginStatusType.INSTALLED;
List<Integer> ids = new ArrayList<Integer>(2); ids.add(p1.getId()); ids.add(p2.getId()); - List<String> undeployed = this.serverPluginsBean.undeployServerPlugins(getOverlord(), ids); + List<PluginKey> undeployed = this.serverPluginsBean.undeployServerPlugins(getOverlord(), ids); assert undeployed.size() == 2 : undeployed; - assert undeployed.contains(p1.getName()) : undeployed; - assert undeployed.contains(p2.getName()) : undeployed; - Plugin p1deleted = getDeletedPluginInTx(p1.getName()); - Plugin p2deleted = getDeletedPluginInTx(p2.getName()); + assert undeployed.contains(p1key) : undeployed; + assert undeployed.contains(p2key) : undeployed; + ServerPlugin p1deleted = getDeletedPluginInTx(p1.getName()); + ServerPlugin p2deleted = getDeletedPluginInTx(p2.getName()); assert p1deleted.getStatus() == PluginStatusType.DELETED; assert p2deleted.getStatus() == PluginStatusType.DELETED;
- List<String> pluginNames = this.serverPluginsBean.getServerPluginNamesByEnabled(false); - assert !pluginNames.contains(p1.getName()) : "deleted plugins should not be returned even here" + pluginNames; - assert !pluginNames.contains(p2.getName()) : "deleted plugins should not be returned even here" + pluginNames; - pluginNames = this.serverPluginsBean.getServerPluginNamesByEnabled(true); - assert !pluginNames.contains(p1.getName()) : pluginNames; - assert !pluginNames.contains(p2.getName()) : pluginNames; + List<PluginKey> pluginKeys = this.serverPluginsBean.getServerPluginKeysByEnabled(false); + assert !pluginKeys.contains(p1key) : "deleted plugins should not be returned even here" + pluginKeys; + assert !pluginKeys.contains(p2key) : "deleted plugins should not be returned even here" + pluginKeys; + pluginKeys = this.serverPluginsBean.getServerPluginKeysByEnabled(true); + assert !pluginKeys.contains(p1.getName()) : pluginKeys; + assert !pluginKeys.contains(p2.getName()) : pluginKeys; }
public void testReRegisterPlugins() throws Exception {
PluginStatusType status;
- status = this.serverPluginsBean.getServerPluginStatus(TEST_PLUGIN_NAME_PREFIX + "1"); + PluginKey missingKey; + missingKey = new PluginKey(PluginDeploymentType.SERVER, new ServerPluginType(GenericPluginDescriptorType.class) + .stringify(), TEST_PLUGIN_NAME_PREFIX + "1"); + status = this.serverPluginsBean.getServerPluginStatus(missingKey); assert status == null; - status = this.serverPluginsBean.getServerPluginStatus(TEST_PLUGIN_NAME_PREFIX + "2"); + missingKey = new PluginKey(PluginDeploymentType.SERVER, new ServerPluginType(GenericPluginDescriptorType.class) + .stringify(), TEST_PLUGIN_NAME_PREFIX + "2"); + status = this.serverPluginsBean.getServerPluginStatus(missingKey); assert status == null;
- Plugin p1 = registerPlugin(1); - Plugin p2 = registerPlugin(2); + ServerPlugin p1 = registerPlugin(1); + ServerPlugin p2 = registerPlugin(2); + PluginKey p1key = new PluginKey(p1); + PluginKey p2key = new PluginKey(p2);
- status = this.serverPluginsBean.getServerPluginStatus(p1.getName()); + status = this.serverPluginsBean.getServerPluginStatus(p1key); assert status == PluginStatusType.INSTALLED; - status = this.serverPluginsBean.getServerPluginStatus(p2.getName()); + status = this.serverPluginsBean.getServerPluginStatus(p2key); assert status == PluginStatusType.INSTALLED;
List<Integer> ids = new ArrayList<Integer>(2); ids.add(p1.getId()); ids.add(p2.getId()); - List<String> undeployed = this.serverPluginsBean.undeployServerPlugins(getOverlord(), ids); + List<PluginKey> undeployed = this.serverPluginsBean.undeployServerPlugins(getOverlord(), ids); assert undeployed.size() == 2 : undeployed; - assert undeployed.contains(p1.getName()) : undeployed; - assert undeployed.contains(p2.getName()) : undeployed; - Plugin p1deleted = getDeletedPluginInTx(p1.getName()); + assert undeployed.contains(p1key) : undeployed; + assert undeployed.contains(p2key) : undeployed; + ServerPlugin p1deleted = getDeletedPluginInTx(p1.getName()); assert p1deleted.getStatus() == PluginStatusType.DELETED; assert p1deleted.getPluginConfiguration() == null; // undeploy should have removed this assert p1deleted.getScheduledJobsConfiguration() == null; // undeploy should have removed this - Plugin p2deleted = getDeletedPluginInTx(p1.getName()); + ServerPlugin p2deleted = getDeletedPluginInTx(p1.getName()); assert p2deleted.getStatus() == PluginStatusType.DELETED; assert p2deleted.getPluginConfiguration() == null; // undeploy should have removed this assert p2deleted.getScheduledJobsConfiguration() == null; // undeploy should have removed this
- List<String> pluginNames = this.serverPluginsBean.getServerPluginNamesByEnabled(false); - assert !pluginNames.contains(p1.getName()) : "deleted plugins should not be returned even here" + pluginNames; - assert !pluginNames.contains(p2.getName()) : "deleted plugins should not be returned even here" + pluginNames; - pluginNames = this.serverPluginsBean.getServerPluginNamesByEnabled(true); - assert !pluginNames.contains(p1.getName()) : pluginNames; - assert !pluginNames.contains(p2.getName()) : pluginNames; + List<PluginKey> pluginKeys = this.serverPluginsBean.getServerPluginKeysByEnabled(false); + assert !pluginKeys.contains(p1key) : "deleted plugins should not be returned even here" + pluginKeys; + assert !pluginKeys.contains(p2key) : "deleted plugins should not be returned even here" + pluginKeys; + pluginKeys = this.serverPluginsBean.getServerPluginKeysByEnabled(true); + assert !pluginKeys.contains(p1key) : pluginKeys; + assert !pluginKeys.contains(p2key) : pluginKeys;
// purge them completely from the DB to prepare to re-register them - this.serverPluginsBean.purgeServerPlugin(getOverlord(), p1.getName()); - this.serverPluginsBean.purgeServerPlugin(getOverlord(), p2.getName()); + this.serverPluginsBean.purgeServerPlugin(getOverlord(), p1key); + this.serverPluginsBean.purgeServerPlugin(getOverlord(), p2key);
// we just purged the database, make sure our entity ID's are all zero, since the original IDs are gone p1.setId(0); @@ -284,24 +307,24 @@ public class ServerPluginsBeanTest extends AbstractEJB3Test { p2.setScheduledJobsConfiguration(p2.getScheduledJobsConfiguration().deepCopy(false));
// re-register them now - Plugin p1again = this.serverPluginsBean.registerServerPlugin(getOverlord(), p1, null); - Plugin p2again = this.serverPluginsBean.registerServerPlugin(getOverlord(), p2, null); + ServerPlugin p1again = this.serverPluginsBean.registerServerPlugin(getOverlord(), p1, null); + ServerPlugin p2again = this.serverPluginsBean.registerServerPlugin(getOverlord(), p2, null);
- pluginNames = this.serverPluginsBean.getServerPluginNamesByEnabled(true); - assert pluginNames.contains(p1.getName()) : pluginNames; - assert pluginNames.contains(p2.getName()) : pluginNames; + pluginKeys = this.serverPluginsBean.getServerPluginKeysByEnabled(true); + assert pluginKeys.contains(p1key) : pluginKeys; + assert pluginKeys.contains(p2key) : pluginKeys; assert p1again.getStatus() == PluginStatusType.INSTALLED; assert p2again.getStatus() == PluginStatusType.INSTALLED; - pluginNames = this.serverPluginsBean.getServerPluginNamesByEnabled(false); - assert !pluginNames.contains(p1.getName()) : pluginNames; - assert !pluginNames.contains(p2.getName()) : pluginNames; + pluginKeys = this.serverPluginsBean.getServerPluginKeysByEnabled(false); + assert !pluginKeys.contains(p1key) : pluginKeys; + assert !pluginKeys.contains(p2key) : pluginKeys; }
- private Plugin registerPlugin(int index) throws Exception { - Plugin plugin = new Plugin(0, TEST_PLUGIN_NAME_PREFIX + index, "path", "displayName", true, + private ServerPlugin registerPlugin(int index) throws Exception { + ServerPlugin plugin = new ServerPlugin(0, TEST_PLUGIN_NAME_PREFIX + index, "path", "displayName", true, PluginStatusType.INSTALLED, "description", "help", "md5", "version", "ampsVersion", - PluginDeploymentType.SERVER, createPluginConfiguration(), createScheduledJobsConfiguration(), System - .currentTimeMillis(), System.currentTimeMillis()); + createPluginConfiguration(), createScheduledJobsConfiguration(), new ServerPluginType( + GenericPluginDescriptorType.class).stringify(), System.currentTimeMillis(), System.currentTimeMillis());
plugin = this.serverPluginsBean.registerServerPlugin(getOverlord(), plugin, null); assert plugin.getId() > 0; @@ -310,10 +333,11 @@ public class ServerPluginsBeanTest extends AbstractEJB3Test { assert plugin.getStatus() == PluginStatusType.INSTALLED; assert plugin.getPluginConfiguration() != null; assert plugin.getScheduledJobsConfiguration() != null; + assert plugin.getType().equals(new ServerPluginType(GenericPluginDescriptorType.class).stringify()); return plugin; }
- private void assetLazyInitializationException(Plugin plugin) { + private void assetLazyInitializationException(ServerPlugin plugin) { try { plugin.getPluginConfiguration().toString(); assert false : "Should have thrown a lazy-initialization exception - we didn't load config"; @@ -344,14 +368,13 @@ public class ServerPluginsBeanTest extends AbstractEJB3Test { return LookupUtil.getSubjectManager().getOverlord(); }
- private Plugin getDeletedPluginInTx(String pluginName) throws Exception { + private ServerPlugin getDeletedPluginInTx(String pluginName) throws Exception { EntityManager em = getEntityManager(); getTransactionManager().begin(); try { - Query q = em.createNamedQuery(Plugin.QUERY_FIND_ANY_BY_NAME_AND_TYPE); + Query q = em.createNamedQuery(ServerPlugin.QUERY_FIND_ANY_BY_NAME); q.setParameter("name", pluginName); - q.setParameter("type", PluginDeploymentType.SERVER); - return (Plugin) q.getSingleResult(); + return (ServerPlugin) q.getSingleResult(); } finally { getTransactionManager().rollback(); } diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/plugin/pc/generic/GenericServerPluginTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/plugin/pc/generic/GenericServerPluginTest.java index 9f0026b..48a5db7 100644 --- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/plugin/pc/generic/GenericServerPluginTest.java +++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/plugin/pc/generic/GenericServerPluginTest.java @@ -32,6 +32,7 @@ import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test;
import org.rhq.core.domain.configuration.Configuration; +import org.rhq.core.domain.plugin.PluginKey; import org.rhq.core.util.stream.StreamUtil; import org.rhq.enterprise.server.plugin.ServerPluginsLocal; import org.rhq.enterprise.server.plugin.pc.ServerPluginType; @@ -82,11 +83,11 @@ public class GenericServerPluginTest extends AbstractEJB3Test { assert schedules == null;
ServerPluginsLocal serverPluginsLocal = LookupUtil.getServerPlugins(); - Map<ServerPluginType, List<String>> map = serverPluginsLocal.getAllPluginsGroupedByType(); + Map<ServerPluginType, List<PluginKey>> map = serverPluginsLocal.getAllPluginsGroupedByType(); assert map.size() == 1; - List<String> pluginNames = map.get(new ServerPluginType(GenericPluginDescriptorType.class)); + List<PluginKey> pluginNames = map.get(new ServerPluginType(GenericPluginDescriptorType.class)); assert pluginNames.size() == 1; - assert pluginNames.get(0).equals("TestSimpleGenericPlugin"); + assert pluginNames.get(0).getPluginName().equals("TestSimpleGenericPlugin");
// make sure everything is shutdown this.pluginService.stopMasterPluginContainer(); diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/plugin/pc/generic/TestGenericServerPluginService.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/plugin/pc/generic/TestGenericServerPluginService.java index 592a3d9..1b577fe 100644 --- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/plugin/pc/generic/TestGenericServerPluginService.java +++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/plugin/pc/generic/TestGenericServerPluginService.java @@ -27,9 +27,9 @@ import java.util.Map;
import org.rhq.core.domain.configuration.Configuration; import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; -import org.rhq.core.domain.plugin.Plugin; -import org.rhq.core.domain.plugin.PluginDeploymentType; +import org.rhq.core.domain.plugin.PluginKey; import org.rhq.core.domain.plugin.PluginStatusType; +import org.rhq.core.domain.plugin.ServerPlugin; import org.rhq.core.util.MessageDigestGenerator; import org.rhq.enterprise.server.plugin.pc.AbstractTypeServerPluginContainer; import org.rhq.enterprise.server.plugin.pc.MasterServerPluginContainer; @@ -38,6 +38,7 @@ import org.rhq.enterprise.server.plugin.pc.ServerPluginComponent; import org.rhq.enterprise.server.plugin.pc.ServerPluginEnvironment; import org.rhq.enterprise.server.plugin.pc.ServerPluginManager; import org.rhq.enterprise.server.plugin.pc.ServerPluginService; +import org.rhq.enterprise.server.plugin.pc.ServerPluginType; import org.rhq.enterprise.server.xmlschema.ServerPluginDescriptorMetadataParser; import org.rhq.enterprise.server.xmlschema.generated.serverplugin.ServerPluginDescriptorType;
@@ -96,9 +97,9 @@ public class TestGenericServerPluginService extends ServerPluginService implemen }
@Override - protected List<String> getDisabledPluginNames() { + protected List<PluginKey> getDisabledPluginNames() { // in the real world, the db is checked for enable flag, here we say all plugins are enabled - return new ArrayList<String>(); + return new ArrayList<PluginKey>(); } }
@@ -175,7 +176,7 @@ public class TestGenericServerPluginService extends ServerPluginService implemen }
@Override - protected Plugin getPlugin(ServerPluginEnvironment env) { + protected ServerPlugin getPlugin(ServerPluginEnvironment env) {
try { Configuration pluginConfig = null; @@ -195,11 +196,12 @@ public class TestGenericServerPluginService extends ServerPluginService implemen }
File pluginFile = new File(env.getPluginUrl().toURI()); - Plugin plugin = new Plugin(0, env.getPluginName(), pluginFile.getName(), pluginDescriptor - .getDisplayName(), true, PluginStatusType.INSTALLED, pluginDescriptor.getDescription(), "", - MessageDigestGenerator.getDigestString(pluginFile), pluginDescriptor.getVersion(), pluginDescriptor - .getVersion(), PluginDeploymentType.SERVER, pluginConfig, scheduledJobsConfig, System - .currentTimeMillis(), System.currentTimeMillis()); + ServerPlugin plugin = new ServerPlugin(0, env.getPluginKey().getPluginName(), pluginFile.getName(), + pluginDescriptor.getDisplayName(), true, PluginStatusType.INSTALLED, pluginDescriptor + .getDescription(), "", MessageDigestGenerator.getDigestString(pluginFile), pluginDescriptor + .getVersion(), pluginDescriptor.getVersion(), pluginConfig, scheduledJobsConfig, + new ServerPluginType(pluginDescriptor).stringify(), System.currentTimeMillis(), System + .currentTimeMillis()); return plugin; } catch (Exception e) { throw new RuntimeException(e); @@ -210,7 +212,7 @@ public class TestGenericServerPluginService extends ServerPluginService implemen protected ServerPluginComponent createServerPluginComponent(ServerPluginEnvironment environment) throws Exception { ServerPluginComponent component = super.createServerPluginComponent(environment); - components.put(environment.getPluginName(), component); + components.put(environment.getPluginKey().getPluginName(), component); return component; } } diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/plugin/pc/generic/TestLifecycleListener.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/plugin/pc/generic/TestLifecycleListener.java index 0b095e5..9b84ddd 100644 --- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/plugin/pc/generic/TestLifecycleListener.java +++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/plugin/pc/generic/TestLifecycleListener.java @@ -18,8 +18,8 @@ */ package org.rhq.enterprise.server.plugin.pc.generic;
-import org.rhq.enterprise.server.plugin.pc.ServerPluginContext; import org.rhq.enterprise.server.plugin.pc.ServerPluginComponent; +import org.rhq.enterprise.server.plugin.pc.ServerPluginContext;
/** * A sample lifecycle listener for the sample generic plugin. This listener will be @@ -82,7 +82,7 @@ public class TestLifecycleListener implements ServerPluginComponent { }
StringBuilder str = new StringBuilder(); - str.append("plugin-name=").append(this.context.getPluginEnvironment().getPluginName()).append(","); + str.append("plugin-key=").append(this.context.getPluginEnvironment().getPluginKey()).append(","); str.append("plugin-url=").append(this.context.getPluginEnvironment().getPluginUrl()).append(","); str.append("data-dir=").append(this.context.getDataDirectory()).append(","); str.append("tmp-dir=").append(this.context.getTemporaryDirectory()); // do not append , diff --git a/modules/enterprise/server/xml-schemas/src/main/java/org/rhq/enterprise/server/xmlschema/ServerPluginDescriptorUtil.java b/modules/enterprise/server/xml-schemas/src/main/java/org/rhq/enterprise/server/xmlschema/ServerPluginDescriptorUtil.java index ac89223..0487d19 100644 --- a/modules/enterprise/server/xml-schemas/src/main/java/org/rhq/enterprise/server/xmlschema/ServerPluginDescriptorUtil.java +++ b/modules/enterprise/server/xml-schemas/src/main/java/org/rhq/enterprise/server/xmlschema/ServerPluginDescriptorUtil.java @@ -48,7 +48,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.maven.artifact.versioning.ComparableVersion;
-import org.rhq.core.domain.plugin.Plugin; +import org.rhq.core.domain.plugin.ServerPlugin; import org.rhq.enterprise.server.xmlschema.generated.serverplugin.ServerPluginDescriptorType;
/** @@ -103,7 +103,7 @@ public abstract class ServerPluginDescriptorUtil { * <code>null</code> is returned if they are the same (i.e. they have the same MD5) * @throws IllegalArgumentException if the two plugins have different logical names */ - public static Plugin determineObsoletePlugin(Plugin plugin1, Plugin plugin2) { + public static ServerPlugin determineObsoletePlugin(ServerPlugin plugin1, ServerPlugin plugin2) { if (!plugin1.getName().equals(plugin2.getName())) { throw new IllegalArgumentException("The two plugins don't have the same name:" + plugin1 + ":" + plugin2); }
commit fff2771d008518f57516efb2607e9b1704973fb3 Author: John Mazzitelli mazz@redhat.com Date: Sat Nov 28 13:13:48 2009 -0500
now that we have the type in the data model, we can get all installed plugins grouped by their type this was needed for the UI
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/plugin/ServerPlugin.java b/modules/core/domain/src/main/java/org/rhq/core/domain/plugin/ServerPlugin.java index aa06ea9..426b62e 100644 --- a/modules/core/domain/src/main/java/org/rhq/core/domain/plugin/ServerPlugin.java +++ b/modules/core/domain/src/main/java/org/rhq/core/domain/plugin/ServerPlugin.java @@ -50,7 +50,7 @@ import org.rhq.core.domain.configuration.Configuration; + " WHERE p.name = :name)"), //
// helps you determine which installed plugins are enabled or disabled - @NamedQuery(name = ServerPlugin.QUERY_GET_NAMES_BY_ENABLED, query = "" // + @NamedQuery(name = ServerPlugin.QUERY_GET_KEYS_BY_ENABLED, query = "" // + " SELECT new org.rhq.core.domain.plugin.PluginKey( " // + " p.deployment, " // + " p.type, " // @@ -159,6 +159,16 @@ import org.rhq.core.domain.configuration.Configuration; + " LEFT JOIN p.scheduledJobsConfiguration " // + " WHERE p.status = 'INSTALLED' "), //
+ // returns all installed plugins, both enabled and disabled + // this is faster than QUERY_FIND_ALL_INSTALLED because it doesn't join configs + @NamedQuery(name = ServerPlugin.QUERY_FIND_ALL_INSTALLED_KEYS, query = "" // + + " SELECT new org.rhq.core.domain.plugin.PluginKey( " // + + " p.deployment, " // + + " p.type, " // + + " p.name) " // + + " FROM ServerPlugin AS p " // + + " WHERE p.status = 'INSTALLED' "), // + // this query is how you enable and disable plugins @NamedQuery(name = ServerPlugin.UPDATE_PLUGINS_ENABLED_BY_IDS, query = "" // + "UPDATE ServerPlugin p " // @@ -171,11 +181,12 @@ public class ServerPlugin extends AbstractPlugin { private static final long serialVersionUID = 1L;
public static final String QUERY_GET_STATUS_BY_NAME = "ServerPlugin.queryGetStatusByName"; - public static final String QUERY_GET_NAMES_BY_ENABLED = "ServerPlugin.queryGetNamesByEnabled"; + public static final String QUERY_GET_KEYS_BY_ENABLED = "ServerPlugin.queryGetKeysByEnabled"; public static final String QUERY_FIND_BY_IDS = "ServerPlugin.findByIds"; public static final String QUERY_FIND_BY_NAME = "ServerPlugin.findByName"; public static final String QUERY_FIND_ANY_BY_NAME = "ServerPlugin.findAnyByName"; public static final String QUERY_FIND_ALL_INSTALLED = "ServerPlugin.findAllInstalled"; + public static final String QUERY_FIND_ALL_INSTALLED_KEYS = "ServerPlugin.findAllInstalledKeys"; public static final String UPDATE_PLUGINS_ENABLED_BY_IDS = "ServerPlugin.updatePluginsEnabledByIds";
@JoinColumn(name = "JOBS_CONFIG_ID", referencedColumnName = "ID") diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsBean.java index b3808ab..5de2a0d 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsBean.java @@ -130,7 +130,7 @@ public class ServerPluginsBean implements ServerPluginsLocal { }
public List<PluginKey> getServerPluginKeysByEnabled(boolean enabled) { - Query query = entityManager.createNamedQuery(ServerPlugin.QUERY_GET_NAMES_BY_ENABLED); + Query query = entityManager.createNamedQuery(ServerPlugin.QUERY_GET_KEYS_BY_ENABLED); query.setParameter("enabled", Boolean.valueOf(enabled)); return query.getResultList(); } @@ -425,24 +425,25 @@ public class ServerPluginsBean implements ServerPluginsLocal { return status; }
- // we need this method to talk to the master plugin container because the plugin data model - // does not contain information as to what type a plugin is. It only has information about - // where the plugin is deployed (agent or server) but it doesn't indicate if a plugin - // if of type "alert plugin" or "generic plugin". That is only known when the plugin descriptor - // is parsed, which happens when the master plugin container is initialized. Therefore, this - // needs to get plugin info from the master plugin container while the master is running. - public Map<ServerPluginType, List<PluginKey>> getAllPluginsGroupedByType() { + public Map<ServerPluginType, List<PluginKey>> getInstalledServerPluginsGroupedByType() { + Query q = entityManager.createNamedQuery(ServerPlugin.QUERY_FIND_ALL_INSTALLED_KEYS); + List<PluginKey> keys = q.getResultList(); // all installed plugins, both enabled and disabled + Map<ServerPluginType, List<PluginKey>> allPlugins = new HashMap<ServerPluginType, List<PluginKey>>();
- MasterServerPluginContainer master = LookupUtil.getServerPluginService().getMasterPluginContainer(); - if (master != null) { - List<ServerPluginType> types = master.getServerPluginTypes(); - for (ServerPluginType type : types) { - List<PluginKey> plugins = master.getAllPluginsByPluginType(type); - allPlugins.put(type, plugins); + for (PluginKey key : keys) { + try { + ServerPluginType type = new ServerPluginType(key.getPluginType()); + List<PluginKey> knownPluginsForType = allPlugins.get(type); + if (knownPluginsForType == null) { + knownPluginsForType = new ArrayList<PluginKey>(); + allPlugins.put(type, knownPluginsForType); + } + knownPluginsForType.add(key); + } catch (Exception e) { + log.warn("Invalid plugin key found [" + key + "]", e); } } - return allPlugins; }
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsLocal.java index a1e0a40..98957d8 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsLocal.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsLocal.java @@ -178,11 +178,9 @@ public interface ServerPluginsLocal { PluginStatusType getServerPluginStatus(PluginKey pluginKey);
/** - * This will return a map containing all plugins currently known to the master plugin container. - * This will return installed plugins that are both enabled and disabled. - * Note that if the master plugin container is not running, an empty map is returned. + * This will return a map containing all installed plugins that are both enabled and disabled. * * @return keys of all enabled and disabled plugins, keyed on their types */ - Map<ServerPluginType, List<PluginKey>> getAllPluginsGroupedByType(); + Map<ServerPluginType, List<PluginKey>> getInstalledServerPluginsGroupedByType(); } diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/plugin/pc/generic/GenericServerPluginTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/plugin/pc/generic/GenericServerPluginTest.java index 48a5db7..450f4db 100644 --- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/plugin/pc/generic/GenericServerPluginTest.java +++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/plugin/pc/generic/GenericServerPluginTest.java @@ -33,6 +33,9 @@ import org.testng.annotations.Test;
import org.rhq.core.domain.configuration.Configuration; import org.rhq.core.domain.plugin.PluginKey; +import org.rhq.core.domain.plugin.PluginStatusType; +import org.rhq.core.domain.plugin.ServerPlugin; +import org.rhq.core.util.MessageDigestGenerator; import org.rhq.core.util.stream.StreamUtil; import org.rhq.enterprise.server.plugin.ServerPluginsLocal; import org.rhq.enterprise.server.plugin.pc.ServerPluginType; @@ -43,6 +46,8 @@ import org.rhq.enterprise.server.plugin.pc.generic.TestLifecycleListener.Lifecyc import org.rhq.enterprise.server.test.AbstractEJB3Test; import org.rhq.enterprise.server.util.LookupUtil; import org.rhq.enterprise.server.xmlschema.ScheduledJobDefinition; +import org.rhq.enterprise.server.xmlschema.ServerPluginDescriptorUtil; +import org.rhq.enterprise.server.xmlschema.generated.serverplugin.ServerPluginDescriptorType; import org.rhq.enterprise.server.xmlschema.generated.serverplugin.generic.GenericPluginDescriptorType;
@Test @@ -82,21 +87,72 @@ public class GenericServerPluginTest extends AbstractEJB3Test { List<ScheduledJobDefinition> schedules = component.context.getSchedules(); assert schedules == null;
- ServerPluginsLocal serverPluginsLocal = LookupUtil.getServerPlugins(); - Map<ServerPluginType, List<PluginKey>> map = serverPluginsLocal.getAllPluginsGroupedByType(); - assert map.size() == 1; - List<PluginKey> pluginNames = map.get(new ServerPluginType(GenericPluginDescriptorType.class)); - assert pluginNames.size() == 1; - assert pluginNames.get(0).getPluginName().equals("TestSimpleGenericPlugin"); - // make sure everything is shutdown this.pluginService.stopMasterPluginContainer(); assert pc.state == State.UNINITIALIZED; assert component.state == LifecycleState.UNINITIALIZED; + } + + public void testGetInstalledPlugins() throws Exception { + File jar = createPluginJar("testSimpleGenericPlugin.jar", "serverplugins/simple-generic-serverplugin.xml"); + ServerPluginType type = new ServerPluginType(GenericPluginDescriptorType.class); + + ServerPluginDescriptorType descriptor = ServerPluginDescriptorUtil.loadPluginDescriptorFromUrl(jar.toURI() + .toURL()); + + ServerPlugin plugin = new ServerPlugin(0, descriptor.getName(), jar.getName(), descriptor.getDisplayName(), + true, PluginStatusType.INSTALLED, descriptor.getDescription(), null, MessageDigestGenerator + .getDigestString(jar), descriptor.getVersion(), descriptor.getApiVersion(), null, null, type + .stringify(), System.currentTimeMillis(), System.currentTimeMillis()); + + ServerPluginsLocal serverPluginsLocal = LookupUtil.getServerPlugins(); + Map<ServerPluginType, List<PluginKey>> original = serverPluginsLocal.getInstalledServerPluginsGroupedByType(); + serverPluginsLocal.registerServerPlugin(LookupUtil.getSubjectManager().getOverlord(), plugin, jar); + + try { + Map<ServerPluginType, List<PluginKey>> map = serverPluginsLocal.getInstalledServerPluginsGroupedByType(); + List<PluginKey> pluginKeys = map.get(type); + + if (original.containsKey(type)) { + assert map.size() == original.size(); + assert pluginKeys.size() == original.get(type).size() + 1; + } else { + assert map.size() == original.size() + 1; + assert pluginKeys.size() == 1; + } + boolean got_it = false; + for (PluginKey pluginKey : pluginKeys) { + if (pluginKey.getPluginName().equals("TestSimpleGenericPlugin")) { + got_it = true; + break; + } + } + assert got_it == true; + } finally { + // make sure we clean this up, even on error + serverPluginsLocal.purgeServerPlugin(LookupUtil.getSubjectManager().getOverlord(), new PluginKey(plugin)); + }
- // with the master down, this method should return an empty map - map = serverPluginsLocal.getAllPluginsGroupedByType(); - assert map.size() == 0; + // test that purge really deleted it + Map<ServerPluginType, List<PluginKey>> map = serverPluginsLocal.getInstalledServerPluginsGroupedByType(); + List<PluginKey> pluginKeys = map.get(type); + + assert map.size() == original.size(); + if (pluginKeys == null) { + assert !original.containsKey(type) : "we dont have any plugins of this type, neither should original"; + } else { + assert pluginKeys.size() == original.get(type).size(); + boolean got_it = false; + for (PluginKey pluginKey : pluginKeys) { + if (pluginKey.getPluginName().equals("TestSimpleGenericPlugin")) { + got_it = true; + break; + } + } + assert got_it == false : "we still have the plugin, but it should have been purged"; + } + + return; }
private File createPluginJar(String jarName, String descriptorXmlFilename) throws Exception {
commit 8bdcdafb19b0963ff7756f3de2b1e15c1114f81c Merge: 1453e14... a6ef401... Author: John Sanda jsanda@redhat.com Date: Fri Nov 27 16:49:35 2009 -0500
Merge branch 'raw-config' of ssh://jsanda@git.fedorahosted.org/git/rhq/rhq into raw-config
commit 1453e1407ce8fb6a75281d9425b5558d7eae94f1 Author: John Sanda jsanda@redhat.com Date: Fri Nov 27 16:46:00 2009 -0500
Fixing ordering of updates
diff --git a/modules/core/dbutils/pom.xml.orig b/modules/core/dbutils/pom.xml.orig new file mode 100644 index 0000000..df61dc2 --- /dev/null +++ b/modules/core/dbutils/pom.xml.orig @@ -0,0 +1,279 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.rhq</groupId> + <artifactId>rhq-core-parent</artifactId> + <version>1.4.0-SNAPSHOT</version> + </parent> + + <groupId>org.rhq</groupId> + <artifactId>rhq-core-dbutils</artifactId> + <packaging>jar</packaging> + + <name>RHQ Database Utilities</name> + <description>Database schema setup, upgrade and other utilities</description> + + <scm> + <connection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/modules/core/dbutils</connection> + <developerConnection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/modules/core/dbutils</developerConnection> + </scm> + + <properties> + <scm.module.path>modules/core/dbutils/</scm.module.path> +<<<<<<< HEAD:modules/core/dbutils/pom.xml + <db.schema.version>2.62.2</db.schema.version> +======= + <db.schema.version>2.69.1</db.schema.version> +>>>>>>> master:modules/core/dbutils/pom.xml + </properties> + + <dependencies> + + <!-- 3rd Party Deps --> + + <dependency> + <groupId>ant</groupId> + <artifactId>ant</artifactId> + <version>1.6.5</version> + </dependency> + + <dependency> + <groupId>ant</groupId> + <artifactId>ant-launcher</artifactId> + <version>1.6.5</version> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>postgresql</groupId> + <artifactId>postgresql</artifactId> + <!-- NOTE: The version is defined in the root POM's dependencyManagement section. --> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>com.h2database</groupId> + <artifactId>h2</artifactId> + <!-- NOTE: The version is defined in the root POM's dependencyManagement section. --> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>net.sourceforge.jtds</groupId> + <artifactId>jtds</artifactId> + <!-- NOTE: The version is defined in the root POM's dependencyManagement section. --> + <scope>test</scope> + </dependency> + + </dependencies> + + <build> + <plugins> + + <plugin> + <artifactId>maven-antrun-plugin</artifactId> + <executions> + <execution> + <phase>process-classes</phase> + <configuration> + <tasks> + <!-- generate the I18N resource bundles --> + <taskdef name="i18n" classpathref="maven.runtime.classpath" classname="mazz.i18n.ant.I18NAntTask" /> + + <i18n outputdir="${project.build.outputDirectory}" defaultlocale="en" verbose="false" append="false" verify="true"> + <classpath refid="maven.runtime.classpath" /> + <classfileset dir="${project.build.outputDirectory}"> + <include name="**/*I18NResourceKeys.class" /> + </classfileset> + </i18n> + </tasks> + </configuration> + <goals> + <goal>run</goal> + </goals> + </execution> + + <execution> + <id>dbsetup-worker</id> + <phase>test</phase> + <configuration> + <tasks> + <property name="settings.localRepository" location="${user.home}/.m2/repository" /> + <ant antfile="${basedir}/src/main/scripts/dbsetup-build.xml"> + <property name="settings.localRepository" value="${settings.localRepository}" /> + <!--<property name="ojdbc14.version" value="${ojdbc14.version}" />--> + <property name="ojdbc5.version" value="${ojdbc5.version}" /> + <property name="postgresql.version" value="${postgresql.version}" /> + <property name="h2.version" value="${h2.version}" /> + <property name="jtds.version" value="${jtds.version}" /> + <property name="task.classpath.property" refid="maven.test.classpath" /> + <property name="rhq.ds.type-mapping" value="${rhq.test.ds.type-mapping}" /> + <property name="rhq.ds.connection-url" value="${rhq.test.ds.connection-url}" /> + <property name="rhq.ds.user-name" value="${rhq.test.ds.user-name}" /> + <property name="rhq.ds.password" value="${rhq.test.ds.password}" /> + <property name="project.version" value="${project.version}" /> + <property name="db.schema.version" value="${db.schema.version}" /> + <property name="dbsetup" value="${dbsetup}" /> + <property name="dbsetup-uninstall" value="${dbsetup-uninstall}" /> + <property name="dbsetup-upgrade" value="${dbsetup-upgrade}" /> + <property name="dbsetup-export" value="${dbsetup-export}" /> + </ant> + </tasks> + </configuration> + <goals> + <goal>run</goal> + </goals> + </execution> + + <execution> + <id>generate-dbsetup-dbupgrade-xml-files</id> + <phase>process-classes</phase> + <configuration> + <tasks> + <property name="settings.localRepository" location="${user.home}/.m2/repository" /> + <ant antfile="${basedir}/src/main/scripts/dbsetup-build.xml" target="dbsetup-combine"> + <property name="settings.localRepository" value="${settings.localRepository}" /> + <!--<property name="ojdbc14.version" value="${ojdbc14.version}" />--> + <property name="ojdbc5.version" value="${ojdbc5.version}" /> + <property name="postgresql.version" value="${postgresql.version}" /> + <property name="h2.version" value="${h2.version}" /> + <property name="jtds.version" value="${jtds.version}" /> + <property name="task.classpath.property" refid="maven.test.classpath" /> + <property name="rhq.ds.type-mapping" value="${rhq.test.ds.type-mapping}" /> + <property name="rhq.ds.connection-url" value="${rhq.test.ds.connection-url}" /> + <property name="rhq.ds.user-name" value="${rhq.test.ds.user-name}" /> + <property name="rhq.ds.password" value="${rhq.test.ds.password}" /> + <property name="project.version" value="${project.version}" /> + <property name="db.schema.version" value="${db.schema.version}" /> + </ant> + </tasks> + </configuration> + <goals> + <goal>run</goal> + </goals> + </execution> + + <execution> + <!-- + This execution will abort the build if the database schema is not up to date. + If you want the build to continue, regardless of your currently installed schema, + then pass -Ddbsetup-do-not-check-schema to the mvn command line. + --> + <id>test-db-schema-version</id> + <phase>test</phase> + <configuration> + <tasks> + <property name="settings.localRepository" location="${user.home}/.m2/repository" /> + <ant antfile="${basedir}/src/main/scripts/dbsetup-build.xml" target="dbsetup-check-schema"> + <property name="settings.localRepository" value="${settings.localRepository}" /> + <!--<property name="ojdbc14.version" value="${ojdbc14.version}" />--> + <property name="ojdbc5.version" value="${ojdbc5.version}" /> + <property name="postgresql.version" value="${postgresql.version}" /> + <property name="h2.version" value="${h2.version}" /> + <property name="jtds.version" value="${jtds.version}" /> + <property name="task.classpath.property" refid="maven.test.classpath" /> + <property name="rhq.ds.type-mapping" value="${rhq.test.ds.type-mapping}" /> + <property name="rhq.ds.connection-url" value="${rhq.test.ds.connection-url}" /> + <property name="rhq.ds.user-name" value="${rhq.test.ds.user-name}" /> + <property name="rhq.ds.password" value="${rhq.test.ds.password}" /> + <property name="project.version" value="${project.version}" /> + <property name="db.schema.version" value="${db.schema.version}" /> + <property name="rhq.ds.driver-class" value="${rhq.test.ds.driver-class}" /> + <property name="dbsetup-do-not-check-schema" value="${dbsetup-do-not-check-schema}" /> + </ant> + </tasks> + </configuration> + <goals> + <goal>run</goal> + </goals> + </execution> + + </executions> + </plugin> + + <plugin> + <artifactId>maven-surefire-plugin</artifactId> + <configuration> + <systemProperties> + <property> + <name>DatabaseTest.nofail</name> + <value>${DatabaseTest.nofail}</value> + </property> + <property> + <name>AntDatabaseTest.test-resources</name> + <value>${basedir}/src/test/resources</value> + </property> + </systemProperties> + <!-- The below is required for tests to run against Oracle. --> + <additionalClasspathElements> + <!--<additionalClasspathElement>${settings.localRepository}/ojdbc14/ojdbc14/${ojdbc14.version}/ojdbc14-${ojdbc14.version}.jar</additionalClasspathElement>--> + <additionalClasspathElement>${settings.localRepository}/com/oracle/ojdbc5/${ojdbc5.version}/ojdbc5-${ojdbc5.version}.jar</additionalClasspathElement> + </additionalClasspathElements> + </configuration> + </plugin> + + </plugins> + </build> + + <profiles> + + <profile> + <id>dev</id> + + <properties> + <rhq.rootDir>../../..</rhq.rootDir> + <rhq.containerDir>${rhq.rootDir}/${rhq.defaultDevContainerPath}</rhq.containerDir> + <rhq.deploymentDir>${rhq.containerDir}/jbossas/server/default/deploy/${rhq.earName}/lib</rhq.deploymentDir> + </properties> + + <build> + <plugins> + + <plugin> + <artifactId>maven-antrun-plugin</artifactId> + <version>1.1</version> + <executions> + + <execution> + <id>deploy</id> + <phase>compile</phase> + <configuration> + <tasks> + <mkdir dir="${rhq.deploymentDir}" /> + <property name="deployment.file" location="${rhq.deploymentDir}/${project.build.finalName}.jar" /> + <echo>*** Updating ${deployment.file}...</echo> + <jar destfile="${deployment.file}" basedir="${project.build.outputDirectory}" /> + </tasks> + </configuration> + <goals> + <goal>run</goal> + </goals> + </execution> + + <execution> + <id>undeploy</id> + <phase>clean</phase> + <configuration> + <tasks> + <property name="deployment.file" location="${rhq.deploymentDir}/${project.build.finalName}.jar" /> + <echo>*** Deleting ${deployment.file}...</echo> + <delete file="${deployment.file}" /> + </tasks> + </configuration> + <goals> + <goal>run</goal> + </goals> + </execution> + + </executions> + </plugin> + + </plugins> + </build> + </profile> + + </profiles> + +</project> diff --git a/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml b/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml index 744794e..8eee404 100644 --- a/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml +++ b/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml @@ -2019,12 +2019,6 @@ precision="255" /> </schemaSpec>
- - <schemaSpec version="2.63"> - <schema-addColumn table="RHQ_REPO" column="IS_CANDIDATE" columnType="BOOLEAN"/> - <schema-alterColumn table="RHQ_REPO" column="IS_CANDIDATE" nullable="false" /> - </schemaSpec> - <schemaSpec version="2.62.2"> <schema-addColumn table="RHQ_CONFIG_DEF" column="CONFIG_FORMAT" columnType="VARCHAR2" /> <schema-alterColumn table="RHQ_CONFIG_DEF" @@ -2033,6 +2027,11 @@ nullable="true" /> </schemaSpec>
+ <schemaSpec version="2.63"> + <schema-addColumn table="RHQ_REPO" column="IS_CANDIDATE" columnType="BOOLEAN"/> + <schema-alterColumn table="RHQ_REPO" column="IS_CANDIDATE" nullable="false" /> + </schemaSpec> + <!-- Generic tagging support --> <schemaSpec version="2.64"> <schema-createSequence name="RHQ_TAG_ID_SEQ" initial="10001" />
commit e6b1d75091f0c36afe77bfe9d51dea6af498b865 Merge: c2f668e... db605e7... Author: John Sanda jsanda@redhat.com Date: Fri Nov 27 16:07:25 2009 -0500
Merge branch 'master' into raw-config
Conflicts: .classpath modules/core/dbutils/pom.xml modules/core/domain/src/main/java/org/rhq/core/domain/configuration/Configuration.java modules/core/domain/src/test/java/org/rhq/core/domain/configuration/ConfigurationTest.java modules/core/domain/src/test/java/org/rhq/core/domain/configuration/RawConfigurationTest.java modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/RawConfigCollection.java
diff --cc .gitignore index 8def9cb,55de495..1d53abe --- a/.gitignore +++ b/.gitignore @@@ -12,10 -12,7 +12,9 @@@ log *.iml *.ipr *.iws +.idea +.idea/* dev-container - modules/dev-container dev-agent antlr-generated/ *.tokens diff --cc modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml index 2a078b8,07831eb..744794e --- a/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml +++ b/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml @@@ -1923,9 -1900,9 +1900,9 @@@ <schema-addColumn table="RHQ_REPO_KS_TREE" column="KICKSTART_TREE_ID" columnType="INTEGER" /> <schema-alterColumn table="RHQ_REPO_KS_TREE" column="KICKSTART_TREE_ID" nullable="false" /> <schema-addColumn table="RHQ_REPO_KS_TREE" column="LAST_MODIFIED" columnType="LONG" /> - <schema-alterColumn table="RHQ_REPO_KS_TREE" column="LAST_MODIFIED" nullable="false" /> + <schema-alterColumn table="RHQ_REPO_KS_TREE" column="LAST_MODIFIED" nullable="false" precision="16" /> <schema-directSQL> - <statement> + <statement> ALTER TABLE RHQ_REPO_KS_TREE ADD CONSTRAINT RHQ_REPO_KS_MAP_KEY PRIMARY KEY ( REPO_ID, KICKSTART_TREE_ID ) @@@ -2028,20 -2005,184 +2005,192 @@@ - </schema-directSQL> </schemaSpec>
- <schemaSpec version="2.62.1"> + <schemaSpec version="2.62"> + <schema-alterColumn + table="RHQ_CONFIG_PROP_DEF" + column="NAME" + columnType="VARCHAR2" + precision="255" /> + + <schema-alterColumn + table="RHQ_CONFIG_PROPERTY" + column="NAME" + columnType="VARCHAR2" + precision="255" /> + </schemaSpec> + + + <schemaSpec version="2.63"> <schema-addColumn table="RHQ_REPO" column="IS_CANDIDATE" columnType="BOOLEAN"/> <schema-alterColumn table="RHQ_REPO" column="IS_CANDIDATE" nullable="false" /> + </schemaSpec> + + <schemaSpec version="2.62.2"> + <schema-addColumn table="RHQ_CONFIG_DEF" column="CONFIG_FORMAT" columnType="VARCHAR2" /> + <schema-alterColumn table="RHQ_CONFIG_DEF" + column="CONFIG_FORMAT" + precision="32" + nullable="true" /> </schemaSpec>
+ <!-- Generic tagging support --> + <schemaSpec version="2.64"> + <schema-createSequence name="RHQ_TAG_ID_SEQ" initial="10001" /> + <schema-directSQL> + <statement> + CREATE TABLE RHQ_TAG ( ID INTEGER PRIMARY KEY ) + </statement> + </schema-directSQL> + <schema-alterColumn table="RHQ_TAG" column="ID" nullable="false" /> + <schema-addColumn table="RHQ_TAG" column="NAME" precision="200" columnType="VARCHAR2" /> + <schema-alterColumn table="RHQ_TAG" column="NAME" nullable="false" /> + <schema-addColumn table="RHQ_TAG" column="DESCRIPTION" precision="500" columnType="VARCHAR2" /> + </schemaSpec> + + <!-- Distribution Files --> + <schemaSpec version="2.65"> + <schema-directSQL> + <statement> + CREATE TABLE RHQ_DISTRIBUTION_FILE ( DISTRIBUTION_ID INTEGER ) + </statement> + </schema-directSQL> + <schema-alterColumn table="RHQ_DISTRIBUTION_FILE" column="DISTRIBUTION_ID" nullable="false" /> + <schema-addColumn table="RHQ_DISTRIBUTION_FILE" column="RELATIVE_FILENAME" precision="256" columnType="VARCHAR2" /> + <schema-alterColumn table="RHQ_DISTRIBUTION_FILE" column="RELATIVE_FILENAME" nullable="false" /> + <schema-addColumn table="RHQ_DISTRIBUTION_FILE" column="MD5SUM" precision="64" columnType="VARCHAR2" /> + <schema-alterColumn table="RHQ_DISTRIBUTION_FILE" column="MD5SUM" nullable="false" /> + <schema-addColumn table="RHQ_DISTRIBUTION_FILE" column="LAST_MODIFIED" columnType="LONG" /> + <schema-alterColumn table="RHQ_DISTRIBUTION_FILE" column="LAST_MODIFIED" nullable="false" /> + <schema-directSQL> + <statement targetDBVendor="postgresql"> + CREATE UNIQUE INDEX RHQ_DISTRIBUTION_FILE_IDX + ON RHQ_DISTRIBUTION_FILE ( DISTRIBUTION_ID, RELATIVE_FILENAME ) + </statement> + <statement targetDBVendor="oracle"> + CREATE UNIQUE INDEX RHQ_DISTRIBUTION_FILE_IDX + ON RHQ_DISTRIBUTION_FILE ( DISTRIBUTION_ID, RELATIVE_FILENAME ) + </statement> + </schema-directSQL> + <schema-directSQL> + <statement targetDBVendor="oracle"> + ALTER TABLE RHQ_DISTRIBUTION_FILE + ADD CONSTRAINT RHQ_DIST_FILE_FKEY + FOREIGN KEY ( DISTRIBUTION_ID) + REFERENCES RHQ_DISTRIBUTION ( ID ) + </statement> + <statement targetDBVendor="postgresql"> + ALTER TABLE RHQ_DISTRIBUTION_FILE + ADD CONSTRAINT RHQ_DIST_FILE_FKEY + FOREIGN KEY ( DISTRIBUTION_ID) + REFERENCES RHQ_DISTRIBUTION ( ID ) + </statement> + </schema-directSQL> + </schemaSpec> + + <!-- RHQ_REPO_TAG_MAP --> + <schemaSpec version="2.66"> + <schema-directSQL> + <statement> + CREATE TABLE RHQ_REPO_TAG_MAP ( REPO_ID INTEGER ) + </statement> + </schema-directSQL> + <schema-alterColumn table="RHQ_REPO_TAG_MAP" column="REPO_ID" nullable="false" /> + <schema-addColumn table="RHQ_REPO_TAG_MAP" column="TAG_ID" columnType="INTEGER" /> + <schema-alterColumn table="RHQ_REPO_TAG_MAP" column="TAG_ID" nullable="false" /> + <schema-directSQL> + <statement> + ALTER TABLE RHQ_REPO_TAG_MAP + ADD CONSTRAINT RHQ_REPO_TAG_MAP_KEY + PRIMARY KEY ( REPO_ID, TAG_ID ) + </statement> + <statement targetDBVendor="postgresql"> + ALTER TABLE RHQ_REPO_TAG_MAP + ADD CONSTRAINT RHQ_REPO_TAG_MAP_REPO_ID_FKEY + FOREIGN KEY ( REPO_ID ) + REFERENCES RHQ_REPO ( ID ) + </statement> + <statement targetDBVendor="oracle"> + ALTER TABLE RHQ_REPO_TAG_MAP + ADD FOREIGN KEY ( REPO_ID ) + REFERENCES RHQ_REPO ( ID ) + </statement> + <statement targetDBVendor="postgresql"> + ALTER TABLE RHQ_REPO_TAG_MAP + ADD CONSTRAINT RHQ_REPO_TAG_MAP_TAG_ID_FKEY + FOREIGN KEY ( TAG_ID ) + REFERENCES RHQ_TAG ( ID ) + </statement> + <statement targetDBVendor="oracle"> + ALTER TABLE RHQ_REPO_TAG_MAP + ADD FOREIGN KEY ( TAG_ID ) + REFERENCES RHQ_TAG ( ID ) + </statement> + </schema-directSQL> + </schemaSpec> + + <schemaSpec version="2.68"> + <schema-createSequence name="RHQ_DISTRIBUTION_FILE_SEQ" initial="10001" /> + <schema-directSQL> + <statement> + ALTER TABLE RHQ_DISTRIBUTION_FILE DROP CONSTRAINT RHQ_DISTRIBUTION_FILE_PKEY + </statement> + </schema-directSQL> + + <schema-addColumn table="RHQ_DISTRIBUTION_FILE" column="ID" columnType="INTEGER" /> + <schema-alterColumn table="RHQ_DISTRIBUTION_FILE" column="ID" nullable="false" /> + + <schema-directSQL> + <statement> + ALTER TABLE RHQ_DISTRIBUTION_FILE ALTER COLUMN ID SET DEFAULT NEXTVAL('RHQ_DISTRIBUTION_FILE_ID_SEQ') + </statement> + </schema-directSQL> + </schemaSpec> + + <!-- Add support for server-side plugins --> + <schemaSpec version="2.69"> + <!-- add the new column that indicates if this is deployed on the SERVER or AGENT --> + <schema-addColumn table="RHQ_PLUGIN" column="DEPLOYMENT" columnType="VARCHAR2" precision="8"/> + <schema-directSQL> + <statement desc="Updating existing plugins with default deployment of AGENT"> + UPDATE RHQ_PLUGIN SET DEPLOYMENT = 'AGENT' + </statement> + </schema-directSQL> + <schema-alterColumn table="RHQ_PLUGIN" column="DEPLOYMENT" nullable="FALSE"/> + + <!-- add the new column that provides configuration to a plugin --> + <schema-addColumn table="RHQ_PLUGIN" column="PLUGIN_CONFIG_ID" columnType="INTEGER" /> + <schema-directSQL> + <statement desc="Creating RHQ_PLUGIN foreign key relation to RHQ_CONFIG for plugin config"> + ALTER TABLE RHQ_PLUGIN + ADD CONSTRAINT RHQ_PLUGIN_P_CFG_ID_FKEY + FOREIGN KEY (PLUGIN_CONFIG_ID) + REFERENCES RHQ_CONFIG (ID) + </statement> + </schema-directSQL> + + <!-- add the new column that provides configuration to a plugin --> + <schema-addColumn table="RHQ_PLUGIN" column="JOBS_CONFIG_ID" columnType="INTEGER" /> + <schema-directSQL> + <statement desc="Creating RHQ_PLUGIN foreign key relation to RHQ_CONFIG for scheduled jobs"> + ALTER TABLE RHQ_PLUGIN + ADD CONSTRAINT RHQ_PLUGIN_JOBS_CFG_ID_FKEY + FOREIGN KEY (JOBS_CONFIG_ID) + REFERENCES RHQ_CONFIG (ID) + </statement> + </schema-directSQL> + </schemaSpec> + + <schemaSpec version="2.69.1"> + <!-- add the new column that indicates if this is plugin has been deleted --> + <schema-addColumn table="RHQ_PLUGIN" column="STATUS" columnType="VARCHAR2" precision="16"/> + <schema-directSQL> + <statement desc="Updating existing plugins with status of INSTALLED"> + UPDATE RHQ_PLUGIN SET STATUS = 'INSTALLED' + </statement> + </schema-directSQL> + <schema-alterColumn table="RHQ_PLUGIN" column="STATUS" nullable="FALSE"/> + </schemaSpec> + </dbupgrade> </target> </project>
commit a6ef40107c68996f85a6d433c483657d11aed289 Author: John Sanda john@localhost.localdomain Date: Fri Nov 27 12:05:11 2009 -0500
Refactoring tests to use common TestUtil class that now contains the serializeAndDeserialize() method that was formerly a private helper method.
diff --git a/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/ConfigurationTest.java b/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/ConfigurationTest.java index 72da7c0..3da4922 100644 --- a/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/ConfigurationTest.java +++ b/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/ConfigurationTest.java @@ -465,7 +465,7 @@ public class ConfigurationTest { Configuration config = new Configuration(); config.setId(id);
- Configuration serializedConfig = serializeAndDeserialize(config); + Configuration serializedConfig = TestUtil.serializeAndDeserialize(config);
assertEquals(serializedConfig.getId(), id, "Failed to properly serialize the id property"); } @@ -495,7 +495,7 @@ public class ConfigurationTest { Configuration config = new Configuration(); config.put(new PropertySimple("x", "1"));
- Configuration serializedConfig = serializeAndDeserialize(config); + Configuration serializedConfig = TestUtil.serializeAndDeserialize(config);
assertEquals(serializedConfig.getMap(), config.getMap(), "Failed to property serialize the map property"); } @@ -526,7 +526,7 @@ public class ConfigurationTest { Configuration config = new Configuration(); config.setNotes("notes");
- Configuration serializedConfig = serializeAndDeserialize(config); + Configuration serializedConfig = TestUtil.serializeAndDeserialize(config);
assertEquals(serializedConfig.getNotes(), config.getNotes(), "Failed to properly serialize the notes property"); } @@ -556,7 +556,7 @@ public class ConfigurationTest { Configuration config = new Configuration(); config.setVersion(1L);
- Configuration serializedConfig = serializeAndDeserialize(config); + Configuration serializedConfig = TestUtil.serializeAndDeserialize(config);
assertEquals( serializedConfig.getVersion(), @@ -590,7 +590,7 @@ public class ConfigurationTest { Configuration config = new Configuration(); updateModifiedTime(config);
- Configuration serializedConfig = serializeAndDeserialize(config); + Configuration serializedConfig = TestUtil.serializeAndDeserialize(config);
assertEquals( @@ -625,7 +625,7 @@ public class ConfigurationTest { Configuration config = new Configuration(); updateCreatedTime(config);
- Configuration serializedConfig = serializeAndDeserialize(config); + Configuration serializedConfig = TestUtil.serializeAndDeserialize(config);
assertEquals( serializedConfig.getCreatedTime(), @@ -660,7 +660,7 @@ public class ConfigurationTest { config.addRawConfiguration(createRawConfiguration("/tmp/foo.txt")); config.addRawConfiguration(createRawConfiguration("/tmp/bar.txt"));
- Configuration serializedConfig = serializeAndDeserialize(config); + Configuration serializedConfig = TestUtil.serializeAndDeserialize(config);
assertRawConfigurationsEquals( serializedConfig.getRawConfigurations(), @@ -677,16 +677,4 @@ public class ConfigurationTest { config.onPersist(); }
- private Configuration serializeAndDeserialize(Configuration config) throws Exception { - ByteArrayOutputStream byteOutputStream = new ByteArrayOutputStream(); - ObjectOutputStream ostream = new ObjectOutputStream(byteOutputStream); - - ostream.writeObject(config); - - ByteArrayInputStream byteInputStream = new ByteArrayInputStream(byteOutputStream.toByteArray()); - ObjectInputStream istream = new ObjectInputStream(byteInputStream); - - return (Configuration) istream.readObject(); - } - }
commit 1bc8c0ef34db2b4584914fea447befe023a62efb Author: Heiko W. Rupp pilhuhn@fedorapeople.org Date: Thu Nov 26 20:19:20 2009 +0100
Squashed commit of the following:
commit db605e78ebfb82d01f0ce4130f327c45170540c7 Author: John Mazzitelli mazz@redhat.com Date: Wed Nov 25 17:18:29 2009 -0500
get rid of the update query we don't need anymore fix tests so they don't rely on that old update query
commit dfd17347dd6d8c2707bfab6ced27bd44b66f9120 Author: John Mazzitelli mazz@redhat.com Date: Wed Nov 25 16:42:23 2009 -0500
fix the update method so it can handle the config updates
commit aadfbe12066b4cab890bc04fbd9a55c76df87fb4 Author: John Mazzitelli mazz@redhat.com Date: Wed Nov 25 13:19:15 2009 -0500
provide an API to get a list of all enabled and disabled plugins grouped by their type
commit 07ae93f34338458daa75082ef519b4b1851ddc0c Merge: 5e17b2f 2d97557 Author: John Mazzitelli mazz@redhat.com Date: Wed Nov 25 11:08:38 2009 -0500
Merge branch 'master' into pc
commit 2d97557a1e09ab13248f5da0e81a8d530731ed78 Author: John Sanda john@localhost.localdomain Date: Wed Nov 25 11:03:16 2009 -0500
Eagerly initializing underlying list and map in PropertyList and PropertyMap to avoid NPEs
This change was already made in the raw-config branch a while back, and needed to be ported over.
commit 5e17b2f3837504924ab1ec1b7ba48d017f258ef2 Merge: 45e0f2f ee2e8e8 Author: John Mazzitelli mazz@redhat.com Date: Wed Nov 25 10:17:56 2009 -0500
Merge branch 'master' into pc
commit 45e0f2f25b7230d65bc561bc63bd1e1cdd7c65f8 Author: John Mazzitelli mazz@redhat.com Date: Wed Nov 25 10:15:39 2009 -0500
use the new deepCopy()
commit b3a962cfa61b2f05b4258b9a25e6e72819473191 Merge: c995032 37bb080 Author: John Mazzitelli mazz@redhat.com Date: Wed Nov 25 09:57:31 2009 -0500
Merge branch 'master' into pc
commit ee2e8e847b18491a6093135b6ca906d6063679de Merge: 1bca0f7 37bb080 Author: John Sanda john@localhost.localdomain Date: Wed Nov 25 09:54:22 2009 -0500
Merge branch 'master' of ssh://git.fedorahosted.org/git/rhq/rhq
commit 1bca0f7c0327498c0dcb7ccb5953d3158c83a563 Author: John Sanda john@localhost.localdomain Date: Wed Nov 25 09:53:41 2009 -0500
Fixing compilation error that happened as a result of my refactoring RawConfiguration.deepCopy()
commit c995032cbc61261e353c523259810d076d586519 Author: John Mazzitelli mazz@redhat.com Date: Wed Nov 25 09:51:34 2009 -0500
fix NPE when plugin config or scheduled jobs config is null
commit 37bb080675c956c976ffc3110361c11e19ae87a0 Author: Galder Zamarreno rnd@zamarreno.com Date: Wed Nov 25 15:20:34 2009 +0100
Operation returns only one result now.
commit cc1b2af501010b1734b42d4a70e30a43db65d3ee Author: Galder Zamarreno rnd@zamarreno.com Date: Wed Nov 25 14:37:33 2009 +0100
Returns for operations can now be generated.
commit a0ab1b28c3ef8ab152c4decf9e8dbaebbede80dd Author: John Sanda john@localhost.localdomain Date: Wed Nov 25 00:08:22 2009 -0500
Deleting directory that accidentally included in a previous commit
commit 1643800fb94b472d11bedc1d5d4d756b4ad54ee0 Author: John Sanda john@localhost.localdomain Date: Wed Nov 25 00:07:18 2009 -0500
[US 6] Refactoring Configuration.deepCopy() to properly handle hibernate proxies.
Refactoring implementors of DeepCopyable to take a boolean flag that indicates whether or not to copy the id field. Unit tests have been updated to reflect the change.
Conflicts:
modules/core/domain/src/main/java/org/rhq/core/domain/configuration/Configuration.java modules/core/domain/src/test/java/org/rhq/core/domain/configuration/RawConfigurationTest.java
commit 9994ec529ecf93914ab48d25023327ee0eb3f503 Author: John Mazzitelli mazz@redhat.com Date: Tue Nov 24 16:41:38 2009 -0500
add a test to confirm that snapshot versions are considered older than candidate releases or releases
commit 93cd6e74d101d7dc645ac38168b4d0157752bf8d Author: Justin Harris jharris@redhat.com Date: Tue Nov 24 14:57:46 2009 -0500
Moving in some seam functionality to allow for page scoped beans in form submission.
commit c8a8622dce3142a91725a0a152bee94be64a9259 Author: John Mazzitelli mazz@redhat.com Date: Mon Nov 23 14:05:06 2009 -0500
because we put the byte[] content directly in the plugin entity, we can't entityManager.find() because that would load the full plugin content. instead, use getReference. when we need to load the relationships, we have to play games by loading in the configs directly and doing a deep copy (mainly to workaround a hibernate bug)
commit 263227e335728de980194c0632ae04938396536e Author: John Mazzitelli mazz@redhat.com Date: Mon Nov 23 11:36:47 2009 -0500
put the proper values in the query params
commit e77a657abf17907a25dba4498b6e4993604ed38c Author: John Mazzitelli mazz@redhat.com Date: Mon Nov 23 10:48:13 2009 -0500
the column should be "enabled" since everywhere else we talk about a plugin being enabled or disabled, not active/inactive
commit 9af95de196ccc8b854a8f1c952af3a6cfa18e78d Author: Justin Harris jharris@redhat.com Date: Mon Nov 23 10:18:55 2009 -0500
Updating update plugin call to new naming scheme.
commit 556be90ec7e0285dc9205766805aaa91da2ef258 Author: Justin Harris jharris@redhat.com Date: Fri Nov 20 18:34:52 2009 -0500
Adding save button to plugin details page.
commit e144f9a55590182e130ae768b9b494b13f03c2a6 Author: John Mazzitelli mazz@redhat.com Date: Sun Nov 22 22:42:30 2009 -0500
convert CRLF to LF
commit f04ef82719012571ecfa157eb270c6b0424ad0ac Author: John Mazzitelli mazz@redhat.com Date: Sun Nov 22 22:39:34 2009 -0500
mistakenly deleted the html tag, put it back
commit a5fcd064dc1d1eea47c2806754c3244e1c000235 Author: John Mazzitelli mazz@redhat.com Date: Sun Nov 22 01:59:12 2009 -0500
since there is no current way to "revive" a undeployed plugin from the real GUI, at least provide _some_ way to get back to a state that will let you re-register a plugin again using the test control.jsp page
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/Configuration.java b/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/Configuration.java index 3ce2965..62bd8ce 100644 --- a/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/Configuration.java +++ b/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/Configuration.java @@ -454,55 +454,40 @@ public class Configuration implements Externalizable, Cloneable, AbstractPropert * @return the new copy */ public Configuration deepCopy(boolean keepIds) { - Configuration copy; + Configuration copy = new Configuration();
- try { - copy = clone(); - } catch (CloneNotSupportedException e) { - throw new RuntimeException("CloneNotSupported can't happen"); + if (keepIds) { + copy.id = this.id; }
- if (!keepIds) { - copy.id = 0; - - for (Property property : copy.properties.values()) { - clearIds(property); - } - } + copy.notes = this.notes; + copy.version = this.version; + createDeepCopyOfProperties(copy, keepIds); + createDeepCopyOfRawConfigs(copy, keepIds);
return copy; }
- private void clearIds(Property property) { - property.setId(0); - - if (property instanceof PropertyList) { - for (Property childProperty : ((PropertyList) property).getList()) { - clearIds(childProperty); - } - } else if (property instanceof PropertyMap) { - for (Property childProperty : ((PropertyMap) property).getMap().values()) { - clearIds(childProperty); - } - } - - return; - } - public Configuration deepCopyWithoutProxies() { Configuration copy = new Configuration(); copy.notes = this.notes; copy.version = this.version; + createDeepCopyOfProperties(copy, false); + createDeepCopyOfRawConfigs(copy, false);
- for (Property property : this.properties.values()) { - copy.put(property.deepCopy()); - } + return copy; + }
+ private void createDeepCopyOfRawConfigs(Configuration copy, boolean keepId) { for (RawConfiguration rawConfig : rawConfigurations) { - copy.addRawConfiguration(rawConfig.deepCopy()); + copy.addRawConfiguration(rawConfig.deepCopy(keepId)); } + }
- return copy; + private void createDeepCopyOfProperties(Configuration copy, boolean keepId) { + for (Property property : this.properties.values()) { + copy.put(property.deepCopy(keepId)); + } }
/** @@ -664,7 +649,22 @@ public class Configuration implements Externalizable, Cloneable, AbstractPropert out.writeLong(version); out.writeLong(ctime); out.writeLong(mtime); + } // Explicitly do not send the history relationship + private Map<String, Property> createDeepCopyOfMap() { + Map<String, Property> copy = new HashMap<String, Property>(); + for (Map.Entry<String, Property> entry : this.properties.entrySet()) { + copy.put(entry.getKey(), entry.getValue().deepCopy(true)); + } + return copy; + } + + private Set<RawConfiguration> createDeepCopyOfRawConfigs() { + Set<RawConfiguration> copy = new HashSet<RawConfiguration>(); + for (RawConfiguration rawConfig : this.rawConfigurations) { + copy.add(rawConfig.deepCopy(true)); + } + return copy; }
@SuppressWarnings("unchecked") @@ -694,4 +694,4 @@ public class Configuration implements Externalizable, Cloneable, AbstractPropert public Map<String, Property> getAllProperties() { return this.properties; } -} \ No newline at end of file +} diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/DeepCopyable.java b/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/DeepCopyable.java index e3e56d5..c680b04 100644 --- a/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/DeepCopyable.java +++ b/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/DeepCopyable.java @@ -25,6 +25,6 @@ package org.rhq.core.domain.configuration;
public interface DeepCopyable<T> {
- T deepCopy(); + T deepCopy(boolean keepId);
} diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/Property.java b/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/Property.java index f4494c8..5c1ba79 100644 --- a/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/Property.java +++ b/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/Property.java @@ -127,7 +127,10 @@ public class Property implements Externalizable, DeepCopyable<Property> { public Property() { }
- protected Property(Property original) { + protected Property(Property original, boolean keepId) { + if (keepId) { + this.id = original.id; + } this.errorMessage = original.errorMessage; this.name = original.name; } @@ -284,7 +287,7 @@ public class Property implements Externalizable, DeepCopyable<Property> { return ((this.name != null) ? this.name.hashCode() : 0); }
- public Property deepCopy() { + public Property deepCopy(boolean keepId) { return null; }
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/PropertyList.java b/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/PropertyList.java index a2223d9..c3e26a0 100644 --- a/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/PropertyList.java +++ b/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/PropertyList.java @@ -68,7 +68,7 @@ public class PropertyList extends Property { @Cascade( { CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH, CascadeType.DELETE_ORPHAN }) @OneToMany(mappedBy = "parentList", targetEntity = Property.class, fetch = FetchType.EAGER) //@IndexColumn(name = "list_index") TODO GH: This seems broken - private List<Property> list; + private List<Property> list = new ArrayList<Property>();
@Transient String memberPropertyName; @@ -86,8 +86,8 @@ public class PropertyList extends Property { setName(name); }
- protected PropertyList(PropertyList original) { - super(original); + protected PropertyList(PropertyList original, boolean keepId) { + super(original, keepId); }
/** @@ -212,11 +212,11 @@ public class PropertyList extends Property { return result; }
- public PropertyList deepCopy() { - PropertyList copy = new PropertyList(this); + public PropertyList deepCopy(boolean keepId) { + PropertyList copy = new PropertyList(this, keepId);
for (Property property : list) { - copy.add(property.deepCopy()); + copy.add(property.deepCopy(false)); }
return copy; diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/PropertyMap.java b/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/PropertyMap.java index 137c6fe..e8e15b7 100644 --- a/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/PropertyMap.java +++ b/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/PropertyMap.java @@ -68,7 +68,7 @@ public class PropertyMap extends Property implements AbstractPropertyMap { @Cascade( { CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH, CascadeType.DELETE_ORPHAN }) @MapKey(name = "name") @OneToMany(mappedBy = "parentMap", fetch = FetchType.EAGER) - private Map<String, Property> map; + private Map<String, Property> map = new LinkedHashMap<String, Property>();
/** * Creates a new unnamed and empty {@link PropertyMap} object. @@ -76,8 +76,8 @@ public class PropertyMap extends Property implements AbstractPropertyMap { public PropertyMap() { }
- protected PropertyMap(PropertyMap original) { - super(original); + protected PropertyMap(PropertyMap original, boolean keepId) { + super(original, keepId); }
/** @@ -263,11 +263,11 @@ public class PropertyMap extends Property implements AbstractPropertyMap { return result; }
- public PropertyMap deepCopy() { - PropertyMap copy = new PropertyMap(this); + public PropertyMap deepCopy(boolean keepId) { + PropertyMap copy = new PropertyMap(this, keepId);
for (Property property : map.values()) { - copy.put(property.deepCopy()); + copy.put(property.deepCopy(keepId)); }
return copy; diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/PropertySimple.java b/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/PropertySimple.java index 0824553..04aeb7e 100644 --- a/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/PropertySimple.java +++ b/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/PropertySimple.java @@ -70,8 +70,8 @@ public class PropertySimple extends Property implements Externalizable { override = Boolean.FALSE; }
- protected PropertySimple(PropertySimple original) { - super(original); + protected PropertySimple(PropertySimple original, boolean keepId) { + super(original, keepId); this.override = original.override; this.unmaskedStringValue = original.unmaskedStringValue; this.stringValue = original.stringValue; @@ -85,9 +85,7 @@ public class PropertySimple extends Property implements Externalizable { * @param name * @param value */ - public PropertySimple(@NotNull - String name, @Nullable - Object value) { + public PropertySimple(@NotNull String name, @Nullable Object value) { setName(name); setValue(value); } @@ -98,8 +96,7 @@ public class PropertySimple extends Property implements Externalizable { * * @param value */ - public void setValue(@Nullable - Object value) { + public void setValue(@Nullable Object value) { if (value == null) { stringValue = null; return; @@ -131,8 +128,7 @@ public class PropertySimple extends Property implements Externalizable { * * @param value */ - public void setStringValue(@Nullable - String value) { + public void setStringValue(@Nullable String value) { this.setValue(value); }
@@ -157,8 +153,7 @@ public class PropertySimple extends Property implements Externalizable { * * @param value */ - public void setBooleanValue(@Nullable - Boolean value) { + public void setBooleanValue(@Nullable Boolean value) { this.setValue(value); }
@@ -207,8 +202,7 @@ public class PropertySimple extends Property implements Externalizable { * * @param value */ - public void setIntegerValue(@Nullable - Integer value) { + public void setIntegerValue(@Nullable Integer value) { this.setValue(value); }
@@ -232,8 +226,7 @@ public class PropertySimple extends Property implements Externalizable { * * @param value */ - public void setFloatValue(@Nullable - Float value) { + public void setFloatValue(@Nullable Float value) { this.setValue(value); }
@@ -257,8 +250,7 @@ public class PropertySimple extends Property implements Externalizable { * * @param value */ - public void setDoubleValue(@Nullable - Double value) { + public void setDoubleValue(@Nullable Double value) { this.setValue(value); }
@@ -336,8 +328,8 @@ public class PropertySimple extends Property implements Externalizable { return result; }
- public PropertySimple deepCopy() { - return new PropertySimple(this); + public PropertySimple deepCopy(boolean keepId) { + return new PropertySimple(this, keepId); }
@Override diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/RawConfiguration.java b/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/RawConfiguration.java index ca02070..22a7161 100644 --- a/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/RawConfiguration.java +++ b/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/RawConfiguration.java @@ -243,9 +243,14 @@ public class RawConfiguration implements Serializable, DeepCopyable<RawConfigura .toString(); }
- public RawConfiguration deepCopy() { + public RawConfiguration deepCopy(boolean keepId) { RawConfiguration copy = new RawConfiguration(); + if (keepId) { + copy.id = this.id; + } + copy.path = this.path; + if (this.contents != null) { copy.setContents(this.getContents()); } diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/plugin/Plugin.java b/modules/core/domain/src/main/java/org/rhq/core/domain/plugin/Plugin.java index eda26d8..4047d10 100644 --- a/modules/core/domain/src/main/java/org/rhq/core/domain/plugin/Plugin.java +++ b/modules/core/domain/src/main/java/org/rhq/core/domain/plugin/Plugin.java @@ -187,25 +187,6 @@ import org.rhq.core.util.MessageDigestGenerator; + " LEFT JOIN p.scheduledJobsConfiguration " // + " WHERE p.deployment = 'SERVER' AND p.status = 'INSTALLED' "), //
- // this query does not update the content blob or ctime - @NamedQuery(name = Plugin.UPDATE_ALL_BUT_CONTENT, query = "" // - + "UPDATE Plugin p " // - + " SET p.name = :name, " // - + " p.displayName = :displayName, " // - + " p.description = :description, " // - + " p.enabled = :enabled, " // - + " p.status = :status, " // - + " p.help = :help, " // - + " p.version = :version, " // - + " p.ampsVersion = :ampsVersion," // - + " p.deployment = :deployment, " // - + " p.pluginConfiguration = :pluginConfiguration, " // - + " p.scheduledJobsConfiguration = :scheduledJobsConfiguration, " // - + " p.path = :path, " // - + " p.md5 = :md5, " // - + " p.mtime = :mtime " // - + " WHERE p.id = :id"), - // this query is how you enable and disable plugins @NamedQuery(name = Plugin.UPDATE_PLUGINS_ENABLED_BY_IDS, query = "" // + "UPDATE Plugin p " // @@ -256,7 +237,6 @@ public class Plugin implements Serializable { public static final String QUERY_FIND_BY_IDS_AND_TYPE = "Plugin.findByIdsAndType"; public static final String QUERY_GET_NAMES_BY_ENABLED_AND_TYPE = "Plugin.findByEnabledAndType"; public static final String QUERY_GET_STATUS_BY_NAME_AND_TYPE = "Plugin.getStatusByNameAndType"; - public static final String UPDATE_ALL_BUT_CONTENT = "Plugin.updateAllButContent"; public static final String UPDATE_PLUGINS_ENABLED_BY_IDS = "Plugin.updatePluginsEnabledByIds";
@Column(name = "ID", nullable = false) diff --git a/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/ConfigurationTest.java b/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/ConfigurationTest.java index 36084ec..85afc00 100644 --- a/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/ConfigurationTest.java +++ b/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/ConfigurationTest.java @@ -38,59 +38,107 @@ import java.util.Set; public class ConfigurationTest {
@Test - public void deepCopyWithoutProxiesShouldNotReturnReferenceToOriginalObject() { + public void deepCopyShouldNotReturnReferenceToOriginalObjectWhenKeepingIds() { Configuration original = createConfiguration(); - Configuration copy = original.deepCopyWithoutProxies(); + Configuration copy = original.deepCopy(true);
assertNotSame(copy, original, "Expected a reference to a new Configuration object, not the original object being copied"); }
@Test - public void deepCopyWithoutProxiesShouldCopySimpleFields() { + public void deepCopyShouldNotReturnReferenceToOriginalObjectWhenNotKeepingIds() { Configuration original = createConfiguration(); - Configuration copy = original.deepCopyWithoutProxies(); + Configuration copy = original.deepCopy(false);
+ assertNotSame(copy, original, "Expected a reference to a new Configuration object, not the original object being copied"); + } + + @Test + public void deepCopyShouldCopyAllSimpleFieldsWhenKeepingIds() { + Configuration original = createConfiguration(); + Configuration copy = original.deepCopy(true); + + assertEquals(copy.getId(), original.getId(), "Failed to copy the id property"); assertEquals(copy.getNotes(), original.getNotes(), "Failed to copy the notes property"); assertEquals(copy.getVersion(), original.getVersion(), "Failed to copy version property"); }
@Test - public void deepCopyWithoutProxiesShouldNotCopyIdProperty() { + public void deepCopyShouldNotCopyIdWhenNotKeepingIds() { Configuration original = createConfiguration(); - Configuration copy = original.deepCopyWithoutProxies(); + Configuration copy = original.deepCopy(false);
assertFalse(copy.getId() == original.getId(), "The original id property should not be copied"); + assertEquals(copy.getNotes(), original.getNotes(), "Failed to copy the notes property"); + assertEquals(copy.getVersion(), original.getVersion(), "Failed to copy version property"); + } + + @Test + public void deepCopyShouldCopyPropertiesWhenKeepingIds() { + Configuration original = createConfiguration(); + original.put(new PropertySimple("simpleProperty", "Simple Property")); + + Configuration copy = original.deepCopy(true); + + assertNotSame(copy.getProperties(), original.getProperties(), "The properties property should not refer to the properties in the original object"); + assertEquals(copy.getProperties(), original.getProperties(), "Failed to copy the contents of the properties collection"); }
@Test - public void deepCopyWithoutProxiesShouldCopyProperties() { + public void deepCopyShouldCopyPropertiesWhenNotKeepingIds() { Configuration original = createConfiguration(); original.put(new PropertySimple("simpleProperty", "Simple Property"));
- Configuration copy = original.deepCopyWithoutProxies(); + Configuration copy = original.deepCopy(false);
assertNotSame(copy.getProperties(), original.getProperties(), "The properties property should not refer to the properties in the original object"); assertEquals(copy.getProperties(), original.getProperties(), "Failed to copy the contents of the properties collection"); }
@Test - public void deepCopyWithoutProxiesShouldNotReturnCopyReferenceOfOriginalProperty() { + public void deepCopyShouldNotReturnCopyReferenceOfOriginalPropertyWhenKeepingIds() { Configuration original = createConfiguration(); String propertyName = "simpleProperty"; original.put(new PropertySimple(propertyName, "Simple Property"));
- Configuration copy = original.deepCopyWithoutProxies(); + Configuration copy = original.deepCopy(true);
assertNotSame(copy.get(propertyName), original.get(propertyName), "Expected a refernce to a new property, not the original property being copied"); }
@Test - public void deepCopyWithoutProxiesShouldSetParentReferenceOfCopiedProperties() { + public void deepCopyShouldNotReturnCopyReferenceOfOriginalPropertyWhenNotKeepingIds() { + Configuration original = createConfiguration(); + String propertyName = "simpleProperty"; + original.put(new PropertySimple(propertyName, "Simple Property")); + + Configuration copy = original.deepCopy(false); + + assertNotSame(copy.get(propertyName), original.get(propertyName), "Expected a refernce to a new property, not the original property being copied"); + } + + @Test + public void deepCopyShouldSetParentReferenceOfCopiedPropertiesWhenKeepingIds() { + Configuration original = createConfiguration(); + String propertyName = "simpleProperty"; + original.put(new PropertySimple(propertyName, "Simple Property")); + + Configuration copy = original.deepCopy(true); + + assertSame( + copy.get(propertyName).getConfiguration(), + copy, + "The reference to the parent configuration should point to the newly copied configuration, not the original configuration" + ); + } + + @Test + public void deepCopyShouldSetParentReferenceOfCopiedPropertiesWhenNotKeepingIds() { Configuration original = createConfiguration(); String propertyName = "simpleProperty"; original.put(new PropertySimple(propertyName, "Simple Property"));
- Configuration copy = original.deepCopyWithoutProxies(); + Configuration copy = original.deepCopy(false);
assertSame( copy.get(propertyName).getConfiguration(), @@ -100,11 +148,27 @@ public class ConfigurationTest { }
@Test - public void deepCopyWithoutProxiesShouldCopyRawConfigurations() { + public void deepCopyShouldCopyRawConfigurationsWhenKeepingIds() { Configuration original = createConfiguration(); original.addRawConfiguration(createRawConfiguration("/tmp/foo"));
- Configuration copy = original.deepCopyWithoutProxies(); + Configuration copy = original.deepCopy(true); + + assertNotSame( + copy.getRawConfigurations(), + original.getRawConfigurations(), + "The rawConfigurations property should not refer to the original rawConfigurations of the copied object." + ); + + assertRawConfigurationsEquals(copy.getRawConfigurations(), original.getRawConfigurations(), "Failed to copy rawConfigurations property."); + } + + @Test + public void deepCopyShouldCopyRawConfigurationsWhenNotKeepingIds() { + Configuration original = createConfiguration(); + original.addRawConfiguration(createRawConfiguration("/tmp/foo")); + + Configuration copy = original.deepCopy(false);
assertNotSame( copy.getRawConfigurations(), @@ -123,11 +187,26 @@ public class ConfigurationTest { }
@Test - public void deepCopyWithoutProxiesShouldSetParentReferenceOfCopiedRawConfigurations() { + public void deepCopyShouldSetParentReferenceOfCopiedRawConfigurationsWhenKeepingIds() { + Configuration original = createConfiguration(); + original.addRawConfiguration(createRawConfiguration("/tmp/foo")); + + Configuration copy = original.deepCopy(true); + RawConfiguration copiedRawConfig = getCopiedRawConfiguration(copy); + + assertSame( + copiedRawConfig.getConfiguration(), + copy, + "The reference to the parent configuration should point to the newly copied configuration, not the original configuration." + ); + } + + @Test + public void deepCopyShouldSetParentReferenceOfCopiedRawConfigurationsWhenNotKeepingIds() { Configuration original = createConfiguration(); original.addRawConfiguration(createRawConfiguration("/tmp/foo"));
- Configuration copy = original.deepCopyWithoutProxies(); + Configuration copy = original.deepCopy(false); RawConfiguration copiedRawConfig = getCopiedRawConfiguration(copy);
assertSame( diff --git a/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/PropertyListTest.java b/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/PropertyListTest.java index d298001..56d3887 100644 --- a/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/PropertyListTest.java +++ b/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/PropertyListTest.java @@ -30,41 +30,52 @@ import org.testng.annotations.Test; public class PropertyListTest {
@Test - public void deepCopyShouldCopySimpleFields() { + public void deepCopyShouldCopyAllSimpleFields() { PropertyList original = createPropertyList();
- PropertyList copy = original.deepCopy(); + PropertyList copy = original.deepCopy(true);
assertNotSame(copy, original, "The copy should not reference the original object"); - + + assertEquals(copy.getId(), original.getId(), "Failed to copy the id property"); assertEquals(copy.getName(), original.getName(), "Failed to copy the name property"); assertEquals(copy.getErrorMessage(), original.getErrorMessage(), "Failed to copy the errorMessage property"); }
@Test - public void deepCopyShouldNotCopyIdField() { + public void deepCopyShouldNotCopyIdFieldWhenFlagIsFalse() { PropertyList original = createPropertyList(); - PropertyList copy = original.deepCopy(); + PropertyList copy = original.deepCopy(false);
assertFalse(copy.getId() == original.getId(), "The original id property should not be copied."); + assertEquals(copy.getName(), original.getName(), "Failed to copy the name property"); + assertEquals(copy.getErrorMessage(), original.getErrorMessage(), "Failed to copy the errorMessage property"); + } + + @Test + public void deepCopyShouldNotCopyReferenceOfUnderlyingListWhenIdIncluded() { + PropertyList original = createPropertyList(); + PropertyList copy = original.deepCopy(true); + + assertNotSame(original.getList(), copy.getList(), "The values in the underlying list should be copied, not the variable reference to the list."); }
@Test - public void deepCopyShouldNotCopyReferenceOfUnderlyingList() { + public void deepCopyShouldNotCopyReferenceOfUnderlyingListWhenIdNotIncluded() { PropertyList original = createPropertyList(); - PropertyList copy = original.deepCopy(); + PropertyList copy = original.deepCopy(false);
assertNotSame(original.getList(), copy.getList(), "The values in the underlying list should be copied, not the variable reference to the list."); }
@Test - public void deepCopyShouldCopyProperty() { + public void deepCopyShouldCopyPropertyWhenIdIncluded() { PropertyList original = createPropertyList();
PropertySimple simpleProperty = new PropertySimple("simeplProperty", "Simple Property"); original.add(simpleProperty);
- PropertyList copy = original.deepCopy(); + PropertyList copy = original.deepCopy(true);
assertEquals(copy.getList().size(), original.getList().size(), "Failed to copy simple property contained in original property list");
@@ -72,13 +83,39 @@ public class PropertyListTest { }
@Test - public void deepCopyShouldSetParentOfCopiedProperty() { + public void deepCopyShouldCopyPropertyWhenIdNotIncluded() { + PropertyList original = createPropertyList(); + + PropertySimple simpleProperty = new PropertySimple("simeplProperty", "Simple Property"); + original.add(simpleProperty); + + PropertyList copy = original.deepCopy(false); + + assertEquals(copy.getList().size(), original.getList().size(), "Failed to copy simple property contained in original property list"); + + assertNotSame(copy.getList().get(0), original.getList().get(0), "Properties in the list should be copied by value as opposed to just copying the references"); + } + + @Test + public void deepCopyShouldSetParentOfCopiedPropertyWhenIdIncluded() { + PropertyList original = createPropertyList(); + + PropertySimple simpleProperty = new PropertySimple("simpleProperty", "Simple Property"); + original.add(simpleProperty); + + PropertyList copy = original.deepCopy(true); + + assertSame(copy.getList().get(0).getParentList(), copy, "The parentList property of copied properties should be set to the new PropertyList"); + } + + @Test + public void deepCopyShouldSetParentOfCopiedPropertyWhenIdNotIncluded() { PropertyList original = createPropertyList();
PropertySimple simpleProperty = new PropertySimple("simpleProperty", "Simple Property"); original.add(simpleProperty);
- PropertyList copy = original.deepCopy(); + PropertyList copy = original.deepCopy(false);
assertSame(copy.getList().get(0).getParentList(), copy, "The parentList property of copied properties should be set to the new PropertyList"); } diff --git a/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/PropertyMapTest.java b/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/PropertyMapTest.java index 4a999b6..e73d835 100644 --- a/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/PropertyMapTest.java +++ b/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/PropertyMapTest.java @@ -30,40 +30,55 @@ import org.testng.annotations.Test; public class PropertyMapTest {
@Test - public void deepCopyShouldCopySimpleFields() { + public void deepCopyShouldCopyAllSimpleFields() { PropertyMap original = createPropertyMap(); - PropertyMap copy = original.deepCopy(); + PropertyMap copy = original.deepCopy(true);
assertNotSame(copy, original, "The copy should not reference the original object");
+ assertEquals(copy.getId(), original.getId(), "Failed to copy the id property"); assertEquals(copy.getName(), original.getName(), "Failed to copy the name property"); assertEquals(copy.getErrorMessage(), original.getErrorMessage(), "Failed to copy the errorMessage property"); }
@Test - public void deepCopyShouldNotCopyIdField() { + public void deepCopyShouldNotCopyIdFieldWhenFlagIsFalse() { PropertyMap original = createPropertyMap(); - PropertyMap copy = original.deepCopy(); + PropertyMap copy = original.deepCopy(false); + + assertNotSame(copy, original, "The copy should not reference the original object");
assertFalse(copy.getId() == original.getId(), "The original id property should not be copied."); + assertEquals(copy.getName(), original.getName(), "Failed to copy the name property"); + assertEquals(copy.getErrorMessage(), original.getErrorMessage(), "Failed to copy the errorMessage property"); }
@Test - public void deepCopyShouldNotCopyReferenceOfUnderlyingMap() { + public void deepCopyShouldCopyPropertyWhenIdIncluded() { PropertyMap original = createPropertyMap(); - PropertyMap copy = original.deepCopy();
- assertNotSame(copy.getMap(), original.getMap(), "The values in the underlying map should be copied, not the reference to the map itself"); + PropertySimple simpleProperty = new PropertySimple("simeplProperty", "Simple Property"); + original.put(simpleProperty); + + PropertyMap copy = original.deepCopy(true); + + assertEquals(copy.getMap().size(), original.getMap().size(), "Failed to copy simple property contained in original property map"); + + assertNotSame( + copy.getMap().get(simpleProperty.getName()), + original.getMap().get(simpleProperty.getName()), + "Properties in the map should be copied by value as opposed to just copying the references" + ); }
@Test - public void deepCopyShouldCopyProperty() { + public void deepCopyShouldCopyPropertyWhenIdNotIncluded() { PropertyMap original = createPropertyMap();
PropertySimple simpleProperty = new PropertySimple("simeplProperty", "Simple Property"); original.put(simpleProperty);
- PropertyMap copy = original.deepCopy(); + PropertyMap copy = original.deepCopy(false);
assertEquals(copy.getMap().size(), original.getMap().size(), "Failed to copy simple property contained in original property map");
@@ -75,13 +90,29 @@ public class PropertyMapTest { }
@Test - public void deepCopyShouldSetParentOfCopiedProperty() { + public void deepCopyShouldSetParentOfCopiedPropertyWhenIdIncluded() { + PropertyMap original = createPropertyMap(); + + PropertySimple simpleProperty = new PropertySimple("simpleProperty", "Simple Property"); + original.put(simpleProperty); + + PropertyMap copy = original.deepCopy(true); + + assertSame( + copy.get(simpleProperty.getName()).getParentMap(), + copy, + "The parentMap property of copied properties should be set to the new PropertyMap" + ); + } + + @Test + public void deepCopyShouldSetParentOfCopiedPropertyWhenIdNotIncluded() { PropertyMap original = createPropertyMap();
PropertySimple simpleProperty = new PropertySimple("simpleProperty", "Simple Property"); original.put(simpleProperty);
- PropertyMap copy = original.deepCopy(); + PropertyMap copy = original.deepCopy(false);
assertSame( copy.get(simpleProperty.getName()).getParentMap(), diff --git a/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/PropertySimpleTest.java b/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/PropertySimpleTest.java index c1b76aa..7b49837 100644 --- a/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/PropertySimpleTest.java +++ b/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/PropertySimpleTest.java @@ -30,13 +30,14 @@ import org.testng.annotations.Test; public class PropertySimpleTest {
@Test - public void deepCopyShouldCopySimpleFields() { + public void deepCopyShouldCopyAllSimpleFields() { PropertySimple original = createProperty();
- PropertySimple copy = original.deepCopy(); + PropertySimple copy = original.deepCopy(true);
assertNotSame(copy, original, "The copy should not reference the original object"); - + + assertEquals(copy.getId(), original.getId(), "Failed to copy the id property"); assertEquals(copy.getName(), original.getName(), "Failed to copy the name property"); assertEquals(copy.getErrorMessage(), original.getErrorMessage(), "Failed to copy the errorMessage property"); assertEquals(copy.getOverride(), original.getOverride(), "Failed to copy the override property"); @@ -45,12 +46,17 @@ public class PropertySimpleTest { }
@Test - public void deepCopyShouldNotCopyIdField() { + public void deepCopyShouldNotCopyIdFieldWhenFlagIsFalse() { PropertySimple original = createProperty();
- PropertySimple copy = original.deepCopy(); + PropertySimple copy = original.deepCopy(false);
assertFalse(copy.getId() == original.getId(), "The original id property should not be copied."); + assertEquals(copy.getName(), original.getName(), "Failed to copy the name property"); + assertEquals(copy.getErrorMessage(), original.getErrorMessage(), "Failed to copy the errorMessage property"); + assertEquals(copy.getOverride(), original.getOverride(), "Failed to copy the override property"); + assertEquals(copy.getUnmaskedStringValue(), original.getUnmaskedStringValue(), "Failed to copy the unmaskedStringValue property"); + assertEquals(copy.getStringValue(), original.getStringValue(), "Failed to copy the stringValue property"); }
private PropertySimple createProperty() { diff --git a/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/RawConfigurationTest.java b/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/RawConfigurationTest.java index fb926af..8f0aac8 100644 --- a/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/RawConfigurationTest.java +++ b/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/RawConfigurationTest.java @@ -212,33 +212,49 @@ public class RawConfigurationTest { }
@Test - public void deepCopyShouldCopyPath() { + public void deepCopyShouldCopyPathAndIdWhenIdIncluded() { RawConfiguration original = new RawConfiguration(); original.setPath("/tmp/foo"); + original.setId(-1);
- RawConfiguration copy = original.deepCopy(); + RawConfiguration copy = original.deepCopy(true);
+ assertEquals(copy.getId(), copy.getId(), "Failed to copy the id property."); assertEquals(copy.getPath(), original.getPath(), "Failed to copy the path property."); }
@Test - public void deepCopyShouldCopyContents() { + public void deepCopyShouldCopyPathAndIdWhenIdNotIncluded() { + RawConfiguration original = new RawConfiguration(); + original.setPath("/tmp/foo"); + original.setId(-1); + + RawConfiguration copy = original.deepCopy(false); + + assertFalse(copy.getId() == original.getId(), "The original id property should not be copied."); + assertEquals(copy.getPath(), original.getPath(), "Failed to copy the path property."); + } + + @Test + public void deepCopyShouldCopyContentsWhenCopyingId() { RawConfiguration original = new RawConfiguration(); original.setContents(new byte[] {1, 2, 3, 4, 5});
- RawConfiguration copy = original.deepCopy(); + RawConfiguration copy = original.deepCopy(true);
assertFalse(original.getContents() == copy.getContents(), "The values in the contents array should be copied, not the reference to the original object."); assertEquals(copy.getContents(), original.getContents(), "Failed to copy contents property."); }
@Test - public void deepCopyShouldNotCopyIdProperty() { + public void deepCopyShouldCopyContentsWhenNotCopyingId() { RawConfiguration original = new RawConfiguration(); - original.setId(1); + original.setContents(new byte[] {1, 2, 3, 4, 5});
- RawConfiguration copy = original.deepCopy(); + RawConfiguration copy = original.deepCopy(false);
- assertFalse(original.getId() == copy.getId(), "The id property should not be copied."); + assertFalse(original.getContents() == copy.getContents(), "The values in the contents array should be copied, not the reference to the original object."); + assertEquals(copy.getContents(), original.getContents(), "Failed to copy contents property."); } + } diff --git a/modules/core/domain/src/test/java/org/rhq/core/domain/resource/test/PluginTest.java b/modules/core/domain/src/test/java/org/rhq/core/domain/resource/test/PluginTest.java index 07f8f97..729f7c2 100644 --- a/modules/core/domain/src/test/java/org/rhq/core/domain/resource/test/PluginTest.java +++ b/modules/core/domain/src/test/java/org/rhq/core/domain/resource/test/PluginTest.java @@ -131,23 +131,39 @@ public class PluginTest extends AbstractEJB3Test { em.persist(jobsConfig); em.flush(); // gotta get those two persists to flush to the DB
- q = em.createNamedQuery(Plugin.UPDATE_ALL_BUT_CONTENT); - q.setParameter("id", id); // same as the one we just persisted - q.setParameter("name", name); - q.setParameter("path", path); - q.setParameter("displayName", displayName); - q.setParameter("enabled", enabled); - q.setParameter("status", status); - q.setParameter("md5", md5); - q.setParameter("version", version); - q.setParameter("ampsVersion", ampsVersion); - q.setParameter("deployment", deployment); - q.setParameter("pluginConfiguration", pluginConfig); - q.setParameter("scheduledJobsConfiguration", jobsConfig); - q.setParameter("description", description); - q.setParameter("help", help); - q.setParameter("mtime", System.currentTimeMillis()); - assert q.executeUpdate() == 1 : "Failed to update the plugin"; + // do what ServerPluginsBean/ResourceMetadataManagerBean.updateServerPluginExceptContent does + Configuration config = plugin.getPluginConfiguration(); + if (config != null) { + config = em.merge(config); + plugin.setPluginConfiguration(config); + } + config = plugin.getScheduledJobsConfiguration(); + if (config != null) { + config = em.merge(config); + plugin.setScheduledJobsConfiguration(config); + } + + Plugin pluginEntity = em.getReference(Plugin.class, plugin.getId()); + pluginEntity.setName(name); + pluginEntity.setPath(path); + pluginEntity.setDisplayName(displayName); + pluginEntity.setEnabled(enabled); + pluginEntity.setStatus(status); + pluginEntity.setMd5(md5); + pluginEntity.setVersion(version); + pluginEntity.setAmpsVersion(ampsVersion); + pluginEntity.setDeployment(deployment); + pluginEntity.setPluginConfiguration(pluginConfig); + pluginEntity.setScheduledJobsConfiguration(jobsConfig); + pluginEntity.setDescription(description); + pluginEntity.setHelp(help); + pluginEntity.setMtime(System.currentTimeMillis()); + + try { + em.flush(); // make sure we push this out to the DB now + } catch (Exception e) { + throw new Exception("Failed to update a plugin that matches [" + plugin + "]", e); + }
em.close(); getTransactionManager().commit(); // must commit now @@ -163,7 +179,7 @@ public class PluginTest extends AbstractEJB3Test { assert plugin.isEnabled() == enabled; assert plugin.getMD5().equals(md5); assert plugin.getVersion().equals(version); - q.setParameter("ampsVersion", ampsVersion); + assert plugin.getAmpsVersion().equals(ampsVersion); assert plugin.getDescription().equals(description); assert plugin.getDeployment() == PluginDeploymentType.SERVER; assert plugin.getPluginConfiguration().equals(pluginConfig); diff --git a/modules/core/util/src/test/java/org/apache/maven/artifact/versioning/ComparableVersionTest.java b/modules/core/util/src/test/java/org/apache/maven/artifact/versioning/ComparableVersionTest.java index d9c2a9f..dfee3a5 100644 --- a/modules/core/util/src/test/java/org/apache/maven/artifact/versioning/ComparableVersionTest.java +++ b/modules/core/util/src/test/java/org/apache/maven/artifact/versioning/ComparableVersionTest.java @@ -161,5 +161,14 @@ public class ComparableVersionTest { assert ver2.compareTo(ver2) == 0; assert ver1.compareTo(ver2) > 0; // ver1 is after ver2! assert ver2.compareTo(ver1) < 0; // ver1 is after ver2! + + ver1 = new ComparableVersion("4.0.0-SNAPSHOT"); + ver2 = new ComparableVersion("4.0.0.CR2"); // CR is an alias for RC + assert !ver1.equals(ver2); + assert !ver2.equals(ver1); + assert ver1.compareTo(ver1) == 0; + assert ver2.compareTo(ver2) == 0; + assert ver1.compareTo(ver2) < 0; + assert ver2.compareTo(ver1) > 0; } } diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/InstalledPluginComponent.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/InstalledPluginComponent.java new file mode 100644 index 0000000..0bb87bd --- /dev/null +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/InstalledPluginComponent.java @@ -0,0 +1,73 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2009 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.gui.admin.plugin; + +import org.jboss.seam.ScopeType; +import org.jboss.seam.annotations.AutoCreate; +import org.jboss.seam.annotations.Factory; +import org.jboss.seam.annotations.Name; +import org.jboss.seam.annotations.web.RequestParameter; +import org.rhq.core.domain.plugin.Plugin; +import org.rhq.core.domain.plugin.PluginDeploymentType; +import org.rhq.enterprise.server.plugin.ServerPluginsLocal; +import org.rhq.enterprise.server.util.LookupUtil; + +/** + * Component responsible for looking up a {@link Plugin}, obtaining + * the <code>name</code> and <code>type</code> from request parameters. + * + * @author jharris + */ +@Name("installedPlugin") +public class InstalledPluginComponent { + + @RequestParameter("plugin") + private String name; + @RequestParameter("pluginType") + private PluginDeploymentType type; + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + + public PluginDeploymentType getType() { + return this.type; + } + + public void setType(PluginDeploymentType type) { + this.type = type; + } + + @Factory(value="plugin", autoCreate=true, scope=ScopeType.PAGE) + public Plugin lookupPlugin() { + if (this.type == PluginDeploymentType.AGENT) { + return LookupUtil.getResourceMetadataManager().getPlugin(this.name); + } else if (this.type == PluginDeploymentType.SERVER) { + ServerPluginsLocal serverPluginsBean = LookupUtil.getServerPlugins(); + Plugin plugin = serverPluginsBean.getServerPlugin(this.name); + return serverPluginsBean.getServerPluginRelationships(plugin); + } + + return null; + } +} diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/InstalledPluginUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/InstalledPluginUIBean.java index f6eee0d..3fe6988 100644 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/InstalledPluginUIBean.java +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/plugin/InstalledPluginUIBean.java @@ -21,8 +21,13 @@ package org.rhq.enterprise.gui.admin.plugin; import javax.faces.application.FacesMessage;
import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory;
+import org.apache.commons.logging.LogFactory; +import org.jboss.seam.ScopeType; +import org.jboss.seam.annotations.Create; +import org.jboss.seam.annotations.In; +import org.jboss.seam.annotations.Name; +import org.jboss.seam.annotations.Scope; import org.rhq.core.clientapi.agent.metadata.ConfigurationMetadataParser; import org.rhq.core.domain.auth.Subject; import org.rhq.core.domain.authz.Permission; @@ -40,21 +45,24 @@ import org.rhq.enterprise.server.xmlschema.generated.serverplugin.ServerPluginDe * @author Greg Hinkle * @author John Mazzitelli */ +@Scope(ScopeType.PAGE) +@Name("InstalledPluginUIBean") public class InstalledPluginUIBean { - private final Log log = LogFactory.getLog(InstalledPluginUIBean.class);
+ private static final String OUTCOME_SUCCESS = "success"; public static final String MANAGED_BEAN_NAME = InstalledPluginUIBean.class.getSimpleName(); - + private final Log log = LogFactory.getLog(InstalledPluginUIBean.class); + @In private Plugin plugin; private ConfigurationDefinition pluginConfigurationDefinition; private ConfigurationDefinition scheduledJobsDefinition;
- public InstalledPluginUIBean() { - lookupPlugin(); + public Plugin getPlugin() { + return plugin; }
- public Plugin getPlugin() { - return this.plugin; + public void setPlugin(Plugin plugin) { + this.plugin = plugin; }
public ConfigurationDefinition getPluginConfigurationDefinition() { @@ -65,23 +73,39 @@ public class InstalledPluginUIBean { return this.scheduledJobsDefinition; }
- private void lookupPlugin() { + public boolean isEditable() { + return this.pluginConfigurationDefinition != null || this.scheduledJobsDefinition != null; + } + + public String updatePlugin() { + ServerPluginsLocal serverPlugins = LookupUtil.getServerPlugins(); + + try { + serverPlugins.updateServerPluginExceptContent(EnterpriseFacesContextUtility.getSubject(), plugin); + FacesContextUtility.addMessage(FacesMessage.SEVERITY_INFO, + "Configuration settings saved."); + + return OUTCOME_SUCCESS; + } catch (Exception e) { + log.error("Error updating the plugin configurations.", e); + FacesContextUtility.addMessage(FacesMessage.SEVERITY_ERROR, + "There was an error changing the configuration settings.", e); + + return null; + } + } + + @Create + public void lookupConfigDefinitions() { hasPermission(); - String pluginName = FacesContextUtility.getRequiredRequestParameter("plugin", String.class); - String pluginType = FacesContextUtility.getRequiredRequestParameter("pluginType", String.class); - PluginDeploymentType deploymentType = PluginDeploymentType.valueOf(pluginType); - if (deploymentType == PluginDeploymentType.AGENT) { - this.plugin = LookupUtil.getResourceMetadataManager().getPlugin(pluginName); - } else { - ServerPluginsLocal serverPluginsBean = LookupUtil.getServerPlugins(); - this.plugin = serverPluginsBean.getServerPlugin(pluginName); - this.plugin = serverPluginsBean.getServerPluginRelationships(this.plugin); + String pluginName = this.plugin.getName(); + + if (this.plugin.getDeployment() == PluginDeploymentType.SERVER) { try { + ServerPluginsLocal serverPluginsBean = LookupUtil.getServerPlugins(); ServerPluginDescriptorType descriptor = serverPluginsBean.getServerPluginDescriptor(pluginName); - this.pluginConfigurationDefinition = ConfigurationMetadataParser.parse("pc:" + pluginName, descriptor - .getPluginConfiguration()); - this.scheduledJobsDefinition = ConfigurationMetadataParser.parse("jobs:" + pluginName, descriptor - .getScheduledJobs()); + this.pluginConfigurationDefinition = ConfigurationMetadataParser.parse("pc:" + pluginName, descriptor.getPluginConfiguration()); + this.scheduledJobsDefinition = ConfigurationMetadataParser.parse("jobs:" + pluginName, descriptor.getScheduledJobs()); } catch (Exception e) { String err = "Cannot determine what the plugin configuration or scheduled jobs configuration looks like"; log.error(err + " - Cause: " + e); @@ -97,8 +121,7 @@ public class InstalledPluginUIBean { private void hasPermission() { Subject subject = EnterpriseFacesContextUtility.getSubject(); if (!LookupUtil.getAuthorizationManager().hasGlobalPermission(subject, Permission.MANAGE_SETTINGS)) { - throw new PermissionException("User [" + subject.getName() - + "] does not have the proper permissions to view or manage plugins"); + throw new PermissionException("User [" + subject.getName() + "] does not have the proper permissions to view or manage plugins"); } } -} \ No newline at end of file +} diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/RawConfigCollection.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/RawConfigCollection.java index a4ce93b..491612a 100644 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/RawConfigCollection.java +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/RawConfigCollection.java @@ -165,7 +165,7 @@ public class RawConfigCollection implements Serializable { String u2 = updated.substring(2); String original = new String(getCurrent().getContents()); if (!u2.equals(original)) { - current = current.deepCopy(); + current = current.deepCopy(false); current.setContents(updated.getBytes()); //TODO update other values like MD5 modified.put(current.getPath(), current); diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/components.xml b/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/components.xml index bacb535..64bd31e 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/components.xml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/components.xml @@ -11,6 +11,7 @@ <component name="org.jboss.seam.core.init"> <property name="debug">false</property> <!-- enable only when needed --> <property name="transactionManagementEnabled">false</property> + <property name="jndi-pattern">rhq/#{ejbName}/local</property> </component>
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-managed-beans/admin-beans.xml b/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-managed-beans/admin-beans.xml index 11dadd0..a80402b 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-managed-beans/admin-beans.xml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-managed-beans/admin-beans.xml @@ -20,13 +20,6 @@ <managed-bean-class>org.rhq.enterprise.gui.admin.plugin.InstalledPluginsUIBean</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean> - <managed-bean> - <description>Visibility for the installed agent and server plugins</description> - <display-name>Installed Plugin</display-name> - <managed-bean-name>InstalledPluginUIBean</managed-bean-name> - <managed-bean-class>org.rhq.enterprise.gui.admin.plugin.InstalledPluginUIBean</managed-bean-class> - <managed-bean-scope>request</managed-bean-scope> - </managed-bean>
<managed-bean> <description>Access to downloads information</description> diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-navigation/admin-navigation.xml b/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-navigation/admin-navigation.xml index 93932df..7f19f4d 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-navigation/admin-navigation.xml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-navigation/admin-navigation.xml @@ -28,6 +28,17 @@ </navigation-case>
</navigation-rule> + + <navigation-rule> + <from-view-id>/rhq/admin/plugin/plugin-details-edit.xhtml</from-view-id> + + <navigation-case> + <from-outcome>success</from-outcome> + <to-view-id>/rhq/admin/plugin/plugin-details-view.xhtml?plugin=#{plugin.name}&pluginType=#{plugin.deployment}</to-view-id> + <redirect/> + </navigation-case> + + </navigation-rule>
<navigation-rule> <navigation-case> diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/admin/test/control.jsp b/modules/enterprise/gui/portal-war/src/main/webapp/admin/test/control.jsp index f3f0a35..2c47b0a 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/admin/test/control.jsp +++ b/modules/enterprise/gui/portal-war/src/main/webapp/admin/test/control.jsp @@ -1,378 +1,397 @@ -<%@ page import="java.io.ByteArrayOutputStream" %> -<%@ page import="java.io.PrintStream" %> - -<%@ page import="org.rhq.core.domain.auth.Subject" %> -<%@ page import="org.rhq.core.domain.util.PersistenceUtility" %> - -<%@ page import="org.rhq.enterprise.gui.legacy.util.SessionUtils"%> -<%@ page import="org.rhq.enterprise.gui.util.WebUtility"%> - -<%@ page import="org.rhq.enterprise.server.measurement.MeasurementPreferences" %> -<%@ page import="org.rhq.enterprise.server.measurement.MeasurementPreferences.MetricRangePreferences" %> - -<%@ page import="org.rhq.enterprise.server.test.CoreTestLocal" %> -<%@ page import="org.rhq.enterprise.server.test.DiscoveryTestLocal" %> -<%@ page import="org.rhq.enterprise.server.test.MeasurementTestLocal" %> -<%@ page import="org.rhq.enterprise.server.test.ResourceGroupTestBeanLocal" %> -<%@ page import="org.rhq.enterprise.server.test.SubjectRoleTestBeanLocal" %> -<%@ page import="org.rhq.enterprise.server.test.AlertTemplateTestLocal" %> -<%@ page import="org.rhq.enterprise.server.cloud.instance.ServerManagerLocal" %> -<%@ page import="org.rhq.enterprise.server.test.ResourceGroupTestBeanLocal" %> -<%@ page import="org.rhq.enterprise.server.measurement.MeasurementBaselineManagerLocal" %> -<%@ page import="org.rhq.enterprise.server.measurement.MeasurementScheduleManagerLocal" %> -<%@ page import="org.rhq.enterprise.server.core.AgentManagerLocal" %> -<%@ page import="org.rhq.enterprise.server.system.SystemManagerLocal" %> -<%@ page import="org.rhq.enterprise.server.auth.SubjectManagerLocal" %> -<%@ page import="org.rhq.enterprise.server.support.SupportManagerLocal" %> -<%@ page import="org.rhq.enterprise.server.util.LookupUtil" %> -<%@ page import="org.rhq.enterprise.server.scheduler.jobs.DataPurgeJob"%> - -<%@ page import="org.rhq.enterprise.server.resource.ResourceTypeManagerRemote"%> -<%@ page import="org.rhq.core.domain.criteria.ResourceTypeCriteria"%> -<%@ page import="org.rhq.core.domain.resource.ResourceType"%> - -<%@ page import="javax.naming.NamingException" %> - -<%@ page contentType="text/html;charset=UTF-8" language="java" %> -<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %> -<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> - -<html> -<head><title>RHQ Test Control Page</title></head> -<body> - -<jsp:include page="/admin/include/adminTestLinks.html" flush="true" /> - -<% - CoreTestLocal coreTestBean; - DiscoveryTestLocal discoveryTestBean; - MeasurementTestLocal measurementTestBean; - ResourceGroupTestBeanLocal resourceGroupTestBean; - SubjectRoleTestBeanLocal subjectRoleTestBean; - ServerManagerLocal serverManager; - AlertTemplateTestLocal alertTemplateTestBean; - MeasurementBaselineManagerLocal measurementBaselineManager; - MeasurementScheduleManagerLocal measurementScheduleManager; - AgentManagerLocal agentManager; - SystemManagerLocal systemManager; - SubjectManagerLocal subjectManager; - SupportManagerLocal supportManager; - ResourceTypeManagerRemote typeManager; - - coreTestBean = LookupUtil.getCoreTest(); - discoveryTestBean = LookupUtil.getDiscoveryTest(); - measurementTestBean = LookupUtil.getMeasurementTest(); - resourceGroupTestBean = LookupUtil.getResourceGroupTestBean(); - subjectRoleTestBean = LookupUtil.getSubjectRoleTestBean(); - serverManager = LookupUtil.getServerManager(); - alertTemplateTestBean = LookupUtil.getAlertTemplateTestBean(); - measurementBaselineManager = LookupUtil.getMeasurementBaselineManager(); - measurementScheduleManager = LookupUtil.getMeasurementScheduleManager(); - agentManager = LookupUtil.getAgentManager(); - systemManager = LookupUtil.getSystemManager(); - subjectManager = LookupUtil.getSubjectManager(); - supportManager = LookupUtil.getSupportManager(); - typeManager = LookupUtil.getResourceTypeManagerRemote(); - - String result = null; - String mode = pageContext.getRequest().getParameter("mode"); - String failure = null; - try - { - if ("registerTestAgent".equals(mode)) - { - coreTestBean.registerTestAgent(); - } - else if ("registerTestPluginAndTypeInfo".equals(mode)) - { - discoveryTestBean.registerTestPluginAndTypeInfo(); - } - else if ("removeTestPluginAndTypeInfo".equals(mode)) - { - discoveryTestBean.removeTestPluginAndTypeInfo(); - } - else if ("sendTestFullInventoryReport".equals(mode)) - { - discoveryTestBean.sendTestFullInventoryReport(); - } - else if ("sendTestRuntimeInventoryReport".equals(mode)) - { - discoveryTestBean.sendTestRuntimeInventoryReport(); - } - else if ("sendTestMeasurementReport".equals(mode)) - { - measurementTestBean.sendTestMeasurementReport(); - } - else if ("sendNewPlatform".equals(mode)) - { - String address = request.getParameter("address"); - int servers = Integer.parseInt(request.getParameter("servers")); - int servicesPerServer = Integer.parseInt(request.getParameter("servicesPerServer")); - discoveryTestBean.sendNewPlatform(address, servers, servicesPerServer); - } - else if ("setupCompatibleGroups".equals(mode)) - { - resourceGroupTestBean.setupCompatibleGroups(); - } - else if ("setupUberMixedGroup".equals(mode)) - { - resourceGroupTestBean.setupUberMixedGroup(); - } - else if ("startStats".equals(mode)) - { - coreTestBean.enableHibernateStatistics(); - } - else if ("addProblemResource".equals(mode)) - { - measurementTestBean.addProblemResource(); - } - else if ("setAgentCurrentlyScheduledMetrics".equals(mode)) - { - String value = pageContext.getRequest().getParameter("v"); - measurementTestBean.setAgentCurrentlyScheduledMetrics(Double.valueOf(value)); - } - else if ("addSubjectsAndRoles".equals(mode)) - { - String roleCount = pageContext.getRequest().getParameter("roleCount"); - String usersInRoleCount = pageContext.getRequest().getParameter("usersInRoleCount"); - subjectRoleTestBean.createRolesAndUsers(Integer.parseInt(roleCount), Integer.parseInt(usersInRoleCount)); - } - else if ("clusterGetIdentity".equals(mode)) - { - String serverName = serverManager.getIdentity(); - pageContext.setAttribute("serverName", "(serverName = " + serverName + ")"); - } - else if ("cloneAlertTemplate".equals(mode)) - { - String alertTemplateId = pageContext.getRequest().getParameter("alertTemplateId"); - String numberOfClones = pageContext.getRequest().getParameter("numberOfClones"); - alertTemplateTestBean.cloneAlertTemplate(Integer.parseInt(alertTemplateId), Integer.parseInt(numberOfClones)); - } - else if ("calculateAutoBaselines".equals(mode)) - { - // for now, baselines aren't calculated until we hit our day limit, we force it here - java.util.Properties props = systemManager.getSystemConfiguration(); - props.put("CAM_BASELINE_LASTTIME", "0"); - systemManager.setSystemConfiguration(subjectManager.getOverlord(), props,true); - - measurementBaselineManager.calculateAutoBaselines(); - } - else if ("calculateOOBs".equals(mode)) - { - DataPurgeJob dpj = new DataPurgeJob(); - dpj.calculateOOBs(); - } - else if ("checkForSuspectAgents".equals(mode)) - { - agentManager.checkForSuspectAgents(); - } - else if ("dataPurgeJob".equals(mode)) - { - DataPurgeJob.purgeNow(); - } - else if ("dbMaintenance".equals(mode)) - { - systemManager.vacuum(subjectManager.getOverlord()); - systemManager.reindex(subjectManager.getOverlord()); - systemManager.analyze(subjectManager.getOverlord()); - } - else if ("metricDisplayRange".equals(mode)) - { - int lastHours = Integer.parseInt(pageContext.getRequest().getParameter("lastHours")); - Subject subject = WebUtility.getSubject(request); - MeasurementPreferences prefs = new MeasurementPreferences(subject); - MetricRangePreferences rangePrefs = prefs.getMetricRangePreferences(); - rangePrefs.lastN = lastHours; - prefs.setMetricRangePreferences(rangePrefs); - } - else if ("errorCorrectSchedules".equals("mode")) - { - measurementScheduleManager.errorCorrectSchedules(); - } - else if ("generateSnapshotReport".equals(mode)) - { - int resourceId = Integer.parseInt(request.getParameter("resourceId")); - String name = request.getParameter("name"); - String description = request.getParameter("description"); - java.net.URL url = supportManager.getSnapshotReport(subjectManager.getOverlord(), resourceId, name, description); - result = "Snapshot Report is located here: " + url.toString(); - } - else if ("typeManagerRemote".equals(mode)) - { - int typeId = Integer.parseInt(request.getParameter("typeId")); - ResourceTypeCriteria criteria = new ResourceTypeCriteria(); - criteria.addFilterId(typeId); - criteria.fetchMetricDefinitions(true); - java.util.List<ResourceType> types = typeManager.findResourceTypesByCriteria(subjectManager.getOverlord(), criteria); - result = ""; - for (ResourceType type : types) { - result += type.getName() + " has " + (type.getMetricDefinitions() != null ? type.getMetricDefinitions().size() : "empty") + " metric definitions"; - } - } - } - catch (Exception e) - { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - e.printStackTrace(new PrintStream(baos)); - failure = baos.toString(); - } - - pageContext.setAttribute("executed", mode); - pageContext.setAttribute("result", result); - pageContext.setAttribute("failure", failure); - pageContext.setAttribute("testAgentReported", Boolean.valueOf(coreTestBean.isTestAgentReported())); - -%> - -<c:if test="${executed != null}"> - <b>Executed <c:out value="${executed}"/>: </b> <c:out value="${result}"/><br> - <c:if test="${failure != null}"> - <pre style="background-color: yellow;"><c:out value="${failure}"/></pre> - </c:if> -</c:if> - -<h2>Administration</h2> - -<c:url var="url" value="/admin/test/control.jsp?mode=addSubjectsAndRoles"/> -Add Lots of Users and Roles -<form action="<c:out value="${url}"/>" method="get"> - <input type="hidden" name="mode" value="addSubjectsAndRoles"/> - Number of Roles: <input type="text" name="roleCount" size="5"/><br/> - Number of Users in each Role: <input type="text" name="usersInRoleCount" size="5"/><br/> - <input type="submit" value="Send" name="Send"/> -</form> - - -<ul> - <li><c:url var="url" value="/admin/test/control.jsp?mode=addSubjectsAndRoles"/> - <a href="<c:out value="${url}"/>">Report Test Agent</a> (done = <c:out value="${testAgentReported}"/>)</li> - <li><c:url var="url" value="/admin/test/control.jsp?mode=registerTestPluginAndTypeInfo"/> - <a href="<c:out value="${url}"/>">Register test plugin metadata</a></li> - <li><c:url var="url" value="/admin/test/control.jsp?mode=removeTestPluginAndTypeInfo"/> - <a href="<c:out value="${url}"/>">Remove test plugin metadata</a></li> -</ul> - -<h2>Core</h2> - -<ul> - <li><c:url var="url" value="/admin/test/control.jsp?mode=registerTestAgent"/> - <a href="<c:out value="${url}"/>">Report Test Agent</a> (done = <c:out value="${testAgentReported}"/>)</li> - <li><c:url var="url" value="/admin/test/control.jsp?mode=registerTestPluginAndTypeInfo"/> - <a href="<c:out value="${url}"/>">Register test plugin metadata</a></li> - <li><c:url var="url" value="/admin/test/control.jsp?mode=removeTestPluginAndTypeInfo"/> - <a href="<c:out value="${url}"/>">Remove test plugin metadata</a></li> - <li><c:url var="url" value="/admin/test/control.jsp?mode=dbMaintenance"/> - <a href="<c:out value="${url}"/>">Perform All Database Maintenance Now</a></li> -</ul> - -<h2>Cluster</h2> - -<ul> - <li><c:url var="url" value="/admin/test/control.jsp?mode=clusterGetIdentity"/> - <a href="<c:out value="${url}"/>">Get Identity</a> <c:out value="${serverName}"/></li> -</ul> - -<h2>Inventory</h2> - -<ul> - <li><c:url var="url" value="/admin/test/control.jsp?mode=sendTestFullInventoryReport"/> - <a href="<c:out value="${url}"/>">Send Full Inventory Report</a></li> - <li><c:url var="url" value="/admin/test/control.jsp?mode=sendTestRuntimeInventoryReport"/> - <a href="<c:out value="${url}"/>">Send Runtime Inventory Report</a></li> - <li><c:url var="url" value="/admin/test/control.jsp?mode=setupCompatibleGroups"/> - <a href="<c:out value="${url}"/>">Setup Compatible Groups</a></li> - <li><c:url var="url" value="/admin/test/control.jsp?mode=setupUberMixedGroup"/> - <a href="<c:out value="${url}"/>">Setup Uber Mixed Group</a></li> -</ul> - -<c:url var="url" value="/admin/test/control.jsp?mode=sendNewPlatform"/> -Send New Platform Inventory Report -<form action="<c:out value="${url}"/>" method="get"> - <input type="hidden" name="mode" value="sendNewPlatform"/> - Address: <input type="text" name="address" size="30"/><br/> - Servers: <input type="text" name="servers" size="5"/><br/> - Services Per Server: <input type="text" name="servicesPerServer" size="5"/><br/> - <input type="submit" value="Send" name="Send"/> -</form> - - -<h2>Measurement</h2> - -<ul> - <li><c:url var="url" value="/admin/test/control.jsp?mode=calculateAutoBaselines"/> - <a href="<c:out value="${url}"/>">Calculate Auto Baselines</a></li> - <li><c:url var="url" value="/admin/test/control.jsp?mode=sendTestMeasurementReport"/> - <a href="<c:out value="${url}"/>">Send Measurement Report</a></li> - <li><c:url var="url" value="/admin/test/control.jsp?mode=addProblemResource"/> - <a href="<c:out value="${url}"/>">Add problem Resource</a></li> - <li><c:url var="url" value="/admin/test/control.jsp?mode=setAgentCurrentlyScheduledMetrics&v=100"/> - <a href="<c:out value="${url}"/>">Set RHQ Agent 'CurrentlyScheduleMetrics' to 100</a></li> - <li><c:url var="url" value="/admin/test/control.jsp?mode=setAgentCurrentlyScheduledMetrics&v=50"/> - <a href="<c:out value="${url}"/>">Set RHQ Agent 'CurrentlyScheduleMetrics' to 50</a></li> - <li><c:url var="url" value="/admin/test/control.jsp?mode=checkForSuspectAgents"/> - <a href="<c:out value="${url}"/>">Check For Suspect Agents</a></li> - <li><c:url var="url" value="/admin/test/control.jsp?mode=dataPurgeJob"/> - <a href="<c:out value="${url}"/>">Force Data Purge Now</a></li> - <li><c:url var="url" value="/admin/test/control.jsp?mode=calculateOOBs"/> - <a href="<c:out value="${url}"/>">Force calculation of OOBs</a></li> - <li><c:url var="url" value="/admin/test/control.jsp?mode=errorCorrectSchedules"/> - <a href="<c:out value="${url}"/>">Error-Correct Measurement Schedules</a></li> -</ul> - -<h2>Alerts</h2> - -<c:url var="url" value="/admin/test/control.jsp?mode=cloneAlertTemplate"/> -Template Cloning -<form action="<c:out value="${url}"/>" method="get"> - <input type="hidden" name="mode" value="cloneAlertTemplate"/> - Alert Template ID: <input type="text" name="alertTemplateId" size="5"/><br/> - Number of Clones: <input type="text" name="numberOfClones" size="5"/><br/> - <input type="submit" value="Send" name="Send"/> -</form> - -<h2>Utilities</h2> -<ul> - <li><c:url var="url" value="/admin/test/control.jsp?mode=startStats"/> - <a href="<c:out value="${url}"/>">Start Hibernate Statistics Collection</a></li> -</ul> - - -<h2>User Preferences</h2> -<% - Subject subject = WebUtility.getSubject(request); - MeasurementPreferences prefs = new MeasurementPreferences(subject); - MetricRangePreferences rangePrefs = prefs.getMetricRangePreferences(); - pageContext.setAttribute("lastHours", String.valueOf(rangePrefs.lastN)); -%> -<form action="<c:out value="${url}"/>" method="get"> - <input type="hidden" name="mode" value="metricDisplayRange"/> - Last X hours: <input type="text" name="lastHours" size="5" value="<c:out value="${lastHours}"/>"/><br/> - <input type="submit" value="Send" name="Send"/> -</form> - -<h2>Snapshot Report</h2> - -<c:url var="url" value="/admin/test/control.jsp?mode=generateSnapshotReport"/> -Generate Snapshot Report -<form action="<c:out value="${url}"/>" method="get"> - <input type="hidden" name="mode" value="generateSnapshotReport"/> - Resource ID: <input type="text" name="resourceId" size="10"/><br/> - Name: <input type="text" name="name" size="30"/><br/> - Description: <input type="text" name="description" size="100"/><br/> - <input type="submit" value="Generate Snapshot" name="Generate Snapshot"/> -</form> - -<h2>Resource Type Criteria</h2> - -<c:url var="url" value="/admin/test/control.jsp?mode=typeManagerRemote"/> -Query ResourceTypes by Criteria -<form action="<c:out value="${url}"/>" method="get"> - <input type="hidden" name="mode" value="typeManagerRemote"/> - ResourceType ID: <input type="text" name="typeId" size="10"/><br/> - <input type="submit" value="Query by Criteria" name="Query by Criteria"/> -</form> - - - -</body> -</html> +<%@ page import="java.io.ByteArrayOutputStream" %> +<%@ page import="java.io.PrintStream" %> + +<%@ page import="org.rhq.core.domain.auth.Subject" %> +<%@ page import="org.rhq.core.domain.util.PersistenceUtility" %> + +<%@ page import="org.rhq.enterprise.gui.legacy.util.SessionUtils"%> +<%@ page import="org.rhq.enterprise.gui.util.WebUtility"%> + +<%@ page import="org.rhq.enterprise.server.measurement.MeasurementPreferences" %> +<%@ page import="org.rhq.enterprise.server.measurement.MeasurementPreferences.MetricRangePreferences" %> + +<%@ page import="org.rhq.enterprise.server.test.CoreTestLocal" %> +<%@ page import="org.rhq.enterprise.server.test.DiscoveryTestLocal" %> +<%@ page import="org.rhq.enterprise.server.test.MeasurementTestLocal" %> +<%@ page import="org.rhq.enterprise.server.test.ResourceGroupTestBeanLocal" %> +<%@ page import="org.rhq.enterprise.server.test.SubjectRoleTestBeanLocal" %> +<%@ page import="org.rhq.enterprise.server.test.AlertTemplateTestLocal" %> +<%@ page import="org.rhq.enterprise.server.cloud.instance.ServerManagerLocal" %> +<%@ page import="org.rhq.enterprise.server.test.ResourceGroupTestBeanLocal" %> +<%@ page import="org.rhq.enterprise.server.measurement.MeasurementBaselineManagerLocal" %> +<%@ page import="org.rhq.enterprise.server.measurement.MeasurementScheduleManagerLocal" %> +<%@ page import="org.rhq.enterprise.server.core.AgentManagerLocal" %> +<%@ page import="org.rhq.enterprise.server.system.SystemManagerLocal" %> +<%@ page import="org.rhq.enterprise.server.auth.SubjectManagerLocal" %> +<%@ page import="org.rhq.enterprise.server.support.SupportManagerLocal" %> +<%@page import="org.rhq.enterprise.server.plugin.ServerPluginsLocal"%><html> +<%@ page import="org.rhq.enterprise.server.util.LookupUtil" %> +<%@ page import="org.rhq.enterprise.server.scheduler.jobs.DataPurgeJob"%> + +<%@ page import="org.rhq.enterprise.server.resource.ResourceTypeManagerRemote"%> +<%@ page import="org.rhq.core.domain.criteria.ResourceTypeCriteria"%> +<%@ page import="org.rhq.core.domain.resource.ResourceType"%> + +<%@ page import="javax.naming.NamingException" %> + +<%@ page contentType="text/html;charset=UTF-8" language="java" %> +<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %> +<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> + +<html> +<head><title>RHQ Test Control Page</title></head> +<body> + +<jsp:include page="/admin/include/adminTestLinks.html" flush="true" /> + +<% + CoreTestLocal coreTestBean; + DiscoveryTestLocal discoveryTestBean; + MeasurementTestLocal measurementTestBean; + ResourceGroupTestBeanLocal resourceGroupTestBean; + SubjectRoleTestBeanLocal subjectRoleTestBean; + ServerManagerLocal serverManager; + AlertTemplateTestLocal alertTemplateTestBean; + MeasurementBaselineManagerLocal measurementBaselineManager; + MeasurementScheduleManagerLocal measurementScheduleManager; + AgentManagerLocal agentManager; + SystemManagerLocal systemManager; + SubjectManagerLocal subjectManager; + SupportManagerLocal supportManager; + ResourceTypeManagerRemote typeManager; + ServerPluginsLocal serverPlugins; + + coreTestBean = LookupUtil.getCoreTest(); + discoveryTestBean = LookupUtil.getDiscoveryTest(); + measurementTestBean = LookupUtil.getMeasurementTest(); + resourceGroupTestBean = LookupUtil.getResourceGroupTestBean(); + subjectRoleTestBean = LookupUtil.getSubjectRoleTestBean(); + serverManager = LookupUtil.getServerManager(); + alertTemplateTestBean = LookupUtil.getAlertTemplateTestBean(); + measurementBaselineManager = LookupUtil.getMeasurementBaselineManager(); + measurementScheduleManager = LookupUtil.getMeasurementScheduleManager(); + agentManager = LookupUtil.getAgentManager(); + systemManager = LookupUtil.getSystemManager(); + subjectManager = LookupUtil.getSubjectManager(); + supportManager = LookupUtil.getSupportManager(); + typeManager = LookupUtil.getResourceTypeManagerRemote(); + serverPlugins = LookupUtil.getServerPlugins(); + + String result = null; + String mode = pageContext.getRequest().getParameter("mode"); + String failure = null; + try + { + if ("registerTestAgent".equals(mode)) + { + coreTestBean.registerTestAgent(); + } + else if ("registerTestPluginAndTypeInfo".equals(mode)) + { + discoveryTestBean.registerTestPluginAndTypeInfo(); + } + else if ("removeTestPluginAndTypeInfo".equals(mode)) + { + discoveryTestBean.removeTestPluginAndTypeInfo(); + } + else if ("sendTestFullInventoryReport".equals(mode)) + { + discoveryTestBean.sendTestFullInventoryReport(); + } + else if ("sendTestRuntimeInventoryReport".equals(mode)) + { + discoveryTestBean.sendTestRuntimeInventoryReport(); + } + else if ("sendTestMeasurementReport".equals(mode)) + { + measurementTestBean.sendTestMeasurementReport(); + } + else if ("sendNewPlatform".equals(mode)) + { + String address = request.getParameter("address"); + int servers = Integer.parseInt(request.getParameter("servers")); + int servicesPerServer = Integer.parseInt(request.getParameter("servicesPerServer")); + discoveryTestBean.sendNewPlatform(address, servers, servicesPerServer); + } + else if ("setupCompatibleGroups".equals(mode)) + { + resourceGroupTestBean.setupCompatibleGroups(); + } + else if ("setupUberMixedGroup".equals(mode)) + { + resourceGroupTestBean.setupUberMixedGroup(); + } + else if ("startStats".equals(mode)) + { + coreTestBean.enableHibernateStatistics(); + } + else if ("addProblemResource".equals(mode)) + { + measurementTestBean.addProblemResource(); + } + else if ("setAgentCurrentlyScheduledMetrics".equals(mode)) + { + String value = pageContext.getRequest().getParameter("v"); + measurementTestBean.setAgentCurrentlyScheduledMetrics(Double.valueOf(value)); + } + else if ("addSubjectsAndRoles".equals(mode)) + { + String roleCount = pageContext.getRequest().getParameter("roleCount"); + String usersInRoleCount = pageContext.getRequest().getParameter("usersInRoleCount"); + subjectRoleTestBean.createRolesAndUsers(Integer.parseInt(roleCount), Integer.parseInt(usersInRoleCount)); + } + else if ("clusterGetIdentity".equals(mode)) + { + String serverName = serverManager.getIdentity(); + pageContext.setAttribute("serverName", "(serverName = " + serverName + ")"); + } + else if ("cloneAlertTemplate".equals(mode)) + { + String alertTemplateId = pageContext.getRequest().getParameter("alertTemplateId"); + String numberOfClones = pageContext.getRequest().getParameter("numberOfClones"); + alertTemplateTestBean.cloneAlertTemplate(Integer.parseInt(alertTemplateId), Integer.parseInt(numberOfClones)); + } + else if ("calculateAutoBaselines".equals(mode)) + { + // for now, baselines aren't calculated until we hit our day limit, we force it here + java.util.Properties props = systemManager.getSystemConfiguration(); + props.put("CAM_BASELINE_LASTTIME", "0"); + systemManager.setSystemConfiguration(subjectManager.getOverlord(), props,true); + + measurementBaselineManager.calculateAutoBaselines(); + } + else if ("calculateOOBs".equals(mode)) + { + DataPurgeJob dpj = new DataPurgeJob(); + dpj.calculateOOBs(); + } + else if ("checkForSuspectAgents".equals(mode)) + { + agentManager.checkForSuspectAgents(); + } + else if ("dataPurgeJob".equals(mode)) + { + DataPurgeJob.purgeNow(); + } + else if ("dbMaintenance".equals(mode)) + { + systemManager.vacuum(subjectManager.getOverlord()); + systemManager.reindex(subjectManager.getOverlord()); + systemManager.analyze(subjectManager.getOverlord()); + } + else if ("metricDisplayRange".equals(mode)) + { + int lastHours = Integer.parseInt(pageContext.getRequest().getParameter("lastHours")); + Subject subject = WebUtility.getSubject(request); + MeasurementPreferences prefs = new MeasurementPreferences(subject); + MetricRangePreferences rangePrefs = prefs.getMetricRangePreferences(); + rangePrefs.lastN = lastHours; + prefs.setMetricRangePreferences(rangePrefs); + } + else if ("errorCorrectSchedules".equals("mode")) + { + measurementScheduleManager.errorCorrectSchedules(); + } + else if ("generateSnapshotReport".equals(mode)) + { + int resourceId = Integer.parseInt(request.getParameter("resourceId")); + String name = request.getParameter("name"); + String description = request.getParameter("description"); + java.net.URL url = supportManager.getSnapshotReport(subjectManager.getOverlord(), resourceId, name, description); + result = "Snapshot Report is located here: " + url.toString(); + } + else if ("purgeServerPlugin".equals(mode)) + { + String serverPluginName = request.getParameter("serverPluginName"); + serverPlugins.purgeServerPlugin(subjectManager.getOverlord(), serverPluginName); + result = "OK - you can now try to re-register a plugin with the name [" + serverPluginName + "]"; + } + else if ("typeManagerRemote".equals(mode)) + { + int typeId = Integer.parseInt(request.getParameter("typeId")); + ResourceTypeCriteria criteria = new ResourceTypeCriteria(); + criteria.addFilterId(typeId); + criteria.fetchMetricDefinitions(true); + java.util.List<ResourceType> types = typeManager.findResourceTypesByCriteria(subjectManager.getOverlord(), criteria); + result = ""; + for (ResourceType type : types) { + result += type.getName() + " has " + (type.getMetricDefinitions() != null ? type.getMetricDefinitions().size() : "empty") + " metric definitions"; + } + } + } + catch (Exception e) + { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + e.printStackTrace(new PrintStream(baos)); + failure = baos.toString(); + } + + pageContext.setAttribute("executed", mode); + pageContext.setAttribute("result", result); + pageContext.setAttribute("failure", failure); + pageContext.setAttribute("testAgentReported", Boolean.valueOf(coreTestBean.isTestAgentReported())); + +%> + +<c:if test="${executed != null}"> + <b>Executed <c:out value="${executed}"/>: </b> <c:out value="${result}"/><br> + <c:if test="${failure != null}"> + <pre style="background-color: yellow;"><c:out value="${failure}"/></pre> + </c:if> +</c:if> + +<h2>Administration</h2> + +<c:url var="url" value="/admin/test/control.jsp?mode=addSubjectsAndRoles"/> +Add Lots of Users and Roles +<form action="<c:out value="${url}"/>" method="get"> + <input type="hidden" name="mode" value="addSubjectsAndRoles"/> + Number of Roles: <input type="text" name="roleCount" size="5"/><br/> + Number of Users in each Role: <input type="text" name="usersInRoleCount" size="5"/><br/> + <input type="submit" value="Send" name="Send"/> +</form> + + +<ul> + <li><c:url var="url" value="/admin/test/control.jsp?mode=addSubjectsAndRoles"/> + <a href="<c:out value="${url}"/>">Report Test Agent</a> (done = <c:out value="${testAgentReported}"/>)</li> + <li><c:url var="url" value="/admin/test/control.jsp?mode=registerTestPluginAndTypeInfo"/> + <a href="<c:out value="${url}"/>">Register test plugin metadata</a></li> + <li><c:url var="url" value="/admin/test/control.jsp?mode=removeTestPluginAndTypeInfo"/> + <a href="<c:out value="${url}"/>">Remove test plugin metadata</a></li> +</ul> + +<h2>Core</h2> + +<ul> + <li><c:url var="url" value="/admin/test/control.jsp?mode=registerTestAgent"/> + <a href="<c:out value="${url}"/>">Report Test Agent</a> (done = <c:out value="${testAgentReported}"/>)</li> + <li><c:url var="url" value="/admin/test/control.jsp?mode=registerTestPluginAndTypeInfo"/> + <a href="<c:out value="${url}"/>">Register test plugin metadata</a></li> + <li><c:url var="url" value="/admin/test/control.jsp?mode=removeTestPluginAndTypeInfo"/> + <a href="<c:out value="${url}"/>">Remove test plugin metadata</a></li> + <li><c:url var="url" value="/admin/test/control.jsp?mode=dbMaintenance"/> + <a href="<c:out value="${url}"/>">Perform All Database Maintenance Now</a></li> +</ul> + +<h2>Cluster</h2> + +<ul> + <li><c:url var="url" value="/admin/test/control.jsp?mode=clusterGetIdentity"/> + <a href="<c:out value="${url}"/>">Get Identity</a> <c:out value="${serverName}"/></li> +</ul> + +<h2>Inventory</h2> + +<ul> + <li><c:url var="url" value="/admin/test/control.jsp?mode=sendTestFullInventoryReport"/> + <a href="<c:out value="${url}"/>">Send Full Inventory Report</a></li> + <li><c:url var="url" value="/admin/test/control.jsp?mode=sendTestRuntimeInventoryReport"/> + <a href="<c:out value="${url}"/>">Send Runtime Inventory Report</a></li> + <li><c:url var="url" value="/admin/test/control.jsp?mode=setupCompatibleGroups"/> + <a href="<c:out value="${url}"/>">Setup Compatible Groups</a></li> + <li><c:url var="url" value="/admin/test/control.jsp?mode=setupUberMixedGroup"/> + <a href="<c:out value="${url}"/>">Setup Uber Mixed Group</a></li> +</ul> + +<c:url var="url" value="/admin/test/control.jsp?mode=sendNewPlatform"/> +Send New Platform Inventory Report +<form action="<c:out value="${url}"/>" method="get"> + <input type="hidden" name="mode" value="sendNewPlatform"/> + Address: <input type="text" name="address" size="30"/><br/> + Servers: <input type="text" name="servers" size="5"/><br/> + Services Per Server: <input type="text" name="servicesPerServer" size="5"/><br/> + <input type="submit" value="Send" name="Send"/> +</form> + + +<h2>Measurement</h2> + +<ul> + <li><c:url var="url" value="/admin/test/control.jsp?mode=calculateAutoBaselines"/> + <a href="<c:out value="${url}"/>">Calculate Auto Baselines</a></li> + <li><c:url var="url" value="/admin/test/control.jsp?mode=sendTestMeasurementReport"/> + <a href="<c:out value="${url}"/>">Send Measurement Report</a></li> + <li><c:url var="url" value="/admin/test/control.jsp?mode=addProblemResource"/> + <a href="<c:out value="${url}"/>">Add problem Resource</a></li> + <li><c:url var="url" value="/admin/test/control.jsp?mode=setAgentCurrentlyScheduledMetrics&v=100"/> + <a href="<c:out value="${url}"/>">Set RHQ Agent 'CurrentlyScheduleMetrics' to 100</a></li> + <li><c:url var="url" value="/admin/test/control.jsp?mode=setAgentCurrentlyScheduledMetrics&v=50"/> + <a href="<c:out value="${url}"/>">Set RHQ Agent 'CurrentlyScheduleMetrics' to 50</a></li> + <li><c:url var="url" value="/admin/test/control.jsp?mode=checkForSuspectAgents"/> + <a href="<c:out value="${url}"/>">Check For Suspect Agents</a></li> + <li><c:url var="url" value="/admin/test/control.jsp?mode=dataPurgeJob"/> + <a href="<c:out value="${url}"/>">Force Data Purge Now</a></li> + <li><c:url var="url" value="/admin/test/control.jsp?mode=calculateOOBs"/> + <a href="<c:out value="${url}"/>">Force calculation of OOBs</a></li> + <li><c:url var="url" value="/admin/test/control.jsp?mode=errorCorrectSchedules"/> + <a href="<c:out value="${url}"/>">Error-Correct Measurement Schedules</a></li> +</ul> + +<h2>Alerts</h2> + +<c:url var="url" value="/admin/test/control.jsp?mode=cloneAlertTemplate"/> +Template Cloning +<form action="<c:out value="${url}"/>" method="get"> + <input type="hidden" name="mode" value="cloneAlertTemplate"/> + Alert Template ID: <input type="text" name="alertTemplateId" size="5"/><br/> + Number of Clones: <input type="text" name="numberOfClones" size="5"/><br/> + <input type="submit" value="Send" name="Send"/> +</form> + +<h2>Utilities</h2> +<ul> + <li><c:url var="url" value="/admin/test/control.jsp?mode=startStats"/> + <a href="<c:out value="${url}"/>">Start Hibernate Statistics Collection</a></li> +</ul> + + +<h2>User Preferences</h2> +<% + Subject subject = WebUtility.getSubject(request); + MeasurementPreferences prefs = new MeasurementPreferences(subject); + MetricRangePreferences rangePrefs = prefs.getMetricRangePreferences(); + pageContext.setAttribute("lastHours", String.valueOf(rangePrefs.lastN)); +%> +<form action="<c:out value="${url}"/>" method="get"> + <input type="hidden" name="mode" value="metricDisplayRange"/> + Last X hours: <input type="text" name="lastHours" size="5" value="<c:out value="${lastHours}"/>"/><br/> + <input type="submit" value="Send" name="Send"/> +</form> + +<h2>Snapshot Report</h2> + +<c:url var="url" value="/admin/test/control.jsp?mode=generateSnapshotReport"/> +Generate Snapshot Report +<form action="<c:out value="${url}"/>" method="get"> + <input type="hidden" name="mode" value="generateSnapshotReport"/> + Resource ID: <input type="text" name="resourceId" size="10"/><br/> + Name: <input type="text" name="name" size="30"/><br/> + Description: <input type="text" name="description" size="100"/><br/> + <input type="submit" value="Generate Snapshot" name="Generate Snapshot"/> +</form> + +<h2>Server Plugins</h2> + +<c:url var="url" value="/admin/test/control.jsp?mode=purgeServerPlugin"/> +Purge Server Plugin (allowing you to re-register it again later) +<form action="<c:out value="${url}"/>" method="get"> + <input type="hidden" name="mode" value="purgeServerPlugin"/> + ServerPluginName: <input type="text" name="serverPluginName" size="30"/><br/> + <input type="submit" value="Purge Server Plugin" name="Purge Server Plugin"/> +</form> + +<h2>Resource Type Criteria</h2> + +<c:url var="url" value="/admin/test/control.jsp?mode=typeManagerRemote"/> +Query ResourceTypes by Criteria +<form action="<c:out value="${url}"/>" method="get"> + <input type="hidden" name="mode" value="typeManagerRemote"/> + ResourceType ID: <input type="text" name="typeId" size="10"/><br/> + <input type="submit" value="Query by Criteria" name="Query by Criteria"/> +</form> + + + +</body> +</html> diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-details-edit.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-details-edit.xhtml new file mode 100644 index 0000000..d88afe7 --- /dev/null +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-details-edit.xhtml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<html xmlns="http://www.w3.org/1999/xhtml" + xmlns:h="http://java.sun.com/jsf/html" + xmlns:f="http://java.sun.com/jsf/core" + xmlns:ui="http://java.sun.com/jsf/facelets" + xmlns:c="http://java.sun.com/jstl/core" + xmlns:onc="http://jboss.org/on/component" + xmlns:rich="http://richfaces.ajax4jsf.org/rich%22%3E + +<ui:composition template="/rhq/admin/plugin/plugin-details.xhtml"> + <ui:param name="editMode" value="true"/> + + <ui:define name="post-config"> + <rich:panel rendered="#{InstalledPluginUIBean.editable}"> + <h:commandButton value="SAVE" type="submit" action="#{InstalledPluginUIBean.updatePlugin}" + alt="Click to Save Changes" styleClass="buttonmed" /> + <h:commandButton value="RESET" type="reset" immediate="true" + title="Click to Reset Fields" styleClass="buttonmed"/> + </rich:panel> + </ui:define> +</ui:composition> + +</html> \ No newline at end of file diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-details-view.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-details-view.xhtml new file mode 100644 index 0000000..389923a --- /dev/null +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-details-view.xhtml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<html xmlns="http://www.w3.org/1999/xhtml" + xmlns:h="http://java.sun.com/jsf/html" + xmlns:f="http://java.sun.com/jsf/core" + xmlns:ui="http://java.sun.com/jsf/facelets" + xmlns:c="http://java.sun.com/jstl/core" + xmlns:onc="http://jboss.org/on/component" + xmlns:rich="http://richfaces.ajax4jsf.org/rich%22%3E + +<ui:composition template="/rhq/admin/plugin/plugin-details.xhtml"> + <ui:param name="editMode" value="false"/> + + <ui:define name="pre-config"> + <h:panelGrid columns="1" styleClass="buttons-table" columnClasses="button-cell" + rendered="#{InstalledPluginUIBean.editable}"> + <h:outputLink value="/rhq/admin/plugin/plugin-details-edit.xhtml" + styleClass="buttonmed"> + <f:param name="plugin" value="#{installedPlugin.name}"/> + <f:param name="pluginType" value="#{installedPlugin.type}"/> + <h:outputText value="EDIT"/> + </h:outputLink> + </h:panelGrid> + </ui:define> + </ui:composition> + +</html> \ No newline at end of file diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-details.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-details.xhtml index 3921b8e..cc11203 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-details.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-details.xhtml @@ -35,8 +35,6 @@ layout="table" width="100%"/>
- - <h:form id="pluginsForm">
rich:panel @@ -66,7 +64,6 @@
</h:panelGrid>
- rich:panel <f:facet name="header"> <h:outputText value="Plugin Help"/> @@ -76,25 +73,29 @@
</rich:panel>
- rich:panel + <ui:insert name="pre-config" /> + + <rich:panel rendered="#{InstalledPluginUIBean.plugin.pluginConfiguration != null}"> <f:facet name="header"> <h:outputText value="Plugin Configuration"/> </f:facet> <onc:config configurationDefinition="#{InstalledPluginUIBean.pluginConfigurationDefinition}" configuration="#{InstalledPluginUIBean.plugin.pluginConfiguration}" - readOnly="true" /> + readOnly="#{not editMode}" /> </rich:panel>
- rich:panel + <rich:panel rendered="#{InstalledPluginUIBean.plugin.scheduledJobsConfiguration != null}"> <f:facet name="header"> <h:outputText value="Scheduled Jobs"/> </f:facet> <onc:config configurationDefinition="#{InstalledPluginUIBean.scheduledJobsDefinition}" configuration="#{InstalledPluginUIBean.plugin.scheduledJobsConfiguration}" - readOnly="true" /> + readOnly="#{not editMode}" /> </rich:panel> + + <ui:insert name="post-config" /> </rich:panel>
</h:form> diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-list.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-list.xhtml index 9f7f6b7..5654368 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-list.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/plugin/plugin-list.xhtml @@ -75,7 +75,7 @@ <h:outputText styleClass="headerText" value="Name"/> </f:facet>
- <h:outputLink value="/rhq/admin/plugin/plugin-details.xhtml"> + <h:outputLink value="/rhq/admin/plugin/plugin-details-view.xhtml"> <f:param name="plugin" value="#{agentPlugin.name}"/> <f:param name="pluginType" value="AGENT"/> <h:outputText value="#{agentPlugin.displayName}"/> @@ -105,7 +105,7 @@
rich:column <f:facet name="header"> - <h:outputText styleClass="headerText" value="Active"/> + <h:outputText styleClass="headerText" value="Enabled"/> </f:facet>
<h:outputText value="#{agentPlugin.enabled}"/> @@ -160,7 +160,7 @@ <h:outputText styleClass="headerText" value="Name"/> </f:facet>
- <h:outputLink value="/rhq/admin/plugin/plugin-details.xhtml"> + <h:outputLink value="/rhq/admin/plugin/plugin-details-view.xhtml"> <f:param name="plugin" value="#{serverPlugin.name}"/> <f:param name="pluginType" value="SERVER"/> <h:outputText value="#{serverPlugin.displayName}"/> @@ -190,7 +190,7 @@
rich:column <f:facet name="header"> - <h:outputText styleClass="headerText" value="Active"/> + <h:outputText styleClass="headerText" value="Enabled"/> </f:facet>
<h:outputText value="#{serverPlugin.enabled}"/> diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerHelper.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerHelper.java index a79dff5..bbeb84c 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerHelper.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerHelper.java @@ -42,7 +42,7 @@ public class ContentManagerHelper { }
MasterServerPluginContainer master = mbean.getMasterPluginContainer(); - pc = master.getPluginContainer(ContentServerPluginContainer.class); + pc = master.getPluginContainerByClass(ContentServerPluginContainer.class); } catch (IllegalStateException ise) { throw ise; } catch (Exception e) { diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsBean.java index 3697caa..49d6e53 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsBean.java @@ -16,7 +16,6 @@ * 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.plugin;
import java.io.BufferedInputStream; @@ -27,7 +26,9 @@ import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map;
import javax.ejb.EJB; import javax.ejb.Stateless; @@ -55,6 +56,7 @@ import org.rhq.enterprise.server.authz.RequiredPermission; import org.rhq.enterprise.server.plugin.pc.AbstractTypeServerPluginContainer; import org.rhq.enterprise.server.plugin.pc.MasterServerPluginContainer; import org.rhq.enterprise.server.plugin.pc.ServerPluginServiceManagement; +import org.rhq.enterprise.server.plugin.pc.ServerPluginType; import org.rhq.enterprise.server.util.LookupUtil; import org.rhq.enterprise.server.xmlschema.ServerPluginDescriptorUtil; import org.rhq.enterprise.server.xmlschema.generated.serverplugin.ServerPluginDescriptorType; @@ -67,14 +69,12 @@ import org.rhq.enterprise.server.xmlschema.generated.serverplugin.ServerPluginDe @Stateless @javax.annotation.Resource(name = "RHQ_DS", mappedName = RHQConstants.DATASOURCE_JNDI_NAME) public class ServerPluginsBean implements ServerPluginsLocal { - private final Log log = LogFactory.getLog(ServerPluginsBean.class);
+ private final Log log = LogFactory.getLog(ServerPluginsBean.class); @PersistenceContext(unitName = RHQConstants.PERSISTENCE_UNIT_NAME) private EntityManager entityManager; - @javax.annotation.Resource(name = "RHQ_DS") private DataSource dataSource; - @EJB private ServerPluginsLocal serverPluginsBean; //self
@@ -94,11 +94,19 @@ public class ServerPluginsBean implements ServerPluginsLocal { }
public Plugin getServerPluginRelationships(Plugin plugin) { - plugin = entityManager.find(Plugin.class, plugin.getId()); + plugin = getServerPlugin(plugin.getName()); // refresh all but the content field + + Configuration config = plugin.getPluginConfiguration(); + if (config != null) { + config = entityManager.find(Configuration.class, config.getId()); + plugin.setPluginConfiguration(config.deepCopy()); + }
- // force eager load - plugin.getPluginConfiguration().getProperties().size(); - plugin.getScheduledJobsConfiguration().getProperties().size(); + config = plugin.getScheduledJobsConfiguration(); + if (config != null) { + config = entityManager.find(Configuration.class, config.getId()); + plugin.setScheduledJobsConfiguration(config.deepCopy()); + }
return plugin; } @@ -146,9 +154,9 @@ public class ServerPluginsBean implements ServerPluginsLocal { }
@RequiredPermission(Permission.MANAGE_SETTINGS) - public List<Plugin> disableServerPlugins(Subject subject, List<Integer> pluginIds) throws Exception { + public List<String> disableServerPlugins(Subject subject, List<Integer> pluginIds) throws Exception { if (pluginIds == null || pluginIds.size() == 0) { - return new ArrayList<Plugin>(); // nothing to do + return new ArrayList<String>(); // nothing to do }
serverPluginsBean.setServerPluginEnabledFlag(subject, pluginIds, false); @@ -156,19 +164,24 @@ public class ServerPluginsBean implements ServerPluginsLocal { ServerPluginServiceManagement serverPluginService = LookupUtil.getServerPluginService(); MasterServerPluginContainer master = serverPluginService.getMasterPluginContainer();
- List<Plugin> doomedPlugins = new ArrayList<Plugin>(); + List<String> doomedPlugins = new ArrayList<String>();
for (Integer pluginId : pluginIds) { - Plugin doomedPlugin = entityManager.find(Plugin.class, pluginId); + Plugin doomedPlugin = null; + try { + doomedPlugin = entityManager.getReference(Plugin.class, pluginId); + } catch (Exception ignore) { + } if (doomedPlugin != null) { - doomedPlugins.add(doomedPlugin); + String pluginName = doomedPlugin.getName(); + doomedPlugins.add(pluginName); if (master != null) { - AbstractTypeServerPluginContainer pc = master.getPluginContainer(doomedPlugin.getName()); + AbstractTypeServerPluginContainer pc = master.getPluginContainerByPlugin(pluginName); if (pc != null) { try { - pc.unschedulePluginJobs(doomedPlugin.getName()); + pc.unschedulePluginJobs(pluginName); } catch (Exception e) { - log.warn("Failed to unschedule jobs for plugin [" + doomedPlugin.getName() + "]", e); + log.warn("Failed to unschedule jobs for plugin [" + pluginName + "]", e); } } } @@ -184,9 +197,9 @@ public class ServerPluginsBean implements ServerPluginsLocal { }
@RequiredPermission(Permission.MANAGE_SETTINGS) - public List<Plugin> undeployServerPlugins(Subject subject, List<Integer> pluginIds) throws Exception { + public List<String> undeployServerPlugins(Subject subject, List<Integer> pluginIds) throws Exception { if (pluginIds == null || pluginIds.size() == 0) { - return new ArrayList<Plugin>(); // nothing to do + return new ArrayList<String>(); // nothing to do }
serverPluginsBean.setServerPluginEnabledFlag(subject, pluginIds, false); @@ -194,19 +207,24 @@ public class ServerPluginsBean implements ServerPluginsLocal { ServerPluginServiceManagement serverPluginService = LookupUtil.getServerPluginService(); MasterServerPluginContainer master = serverPluginService.getMasterPluginContainer();
- List<Plugin> doomedPlugins = new ArrayList<Plugin>(); + List<String> doomedPlugins = new ArrayList<String>();
for (Integer pluginId : pluginIds) { - Plugin doomedPlugin = entityManager.find(Plugin.class, pluginId); + Plugin doomedPlugin = null; + try { + doomedPlugin = entityManager.getReference(Plugin.class, pluginId); + } catch (Exception ignore) { + } if (doomedPlugin != null) { - doomedPlugins.add(doomedPlugin); + String pluginName = doomedPlugin.getName(); + doomedPlugins.add(pluginName); if (master != null) { - AbstractTypeServerPluginContainer pc = master.getPluginContainer(doomedPlugin.getName()); + AbstractTypeServerPluginContainer pc = master.getPluginContainerByPlugin(pluginName); if (pc != null) { try { - pc.unschedulePluginJobs(doomedPlugin.getName()); + pc.unschedulePluginJobs(pluginName); } catch (Exception e) { - log.warn("Failed to unschedule jobs for plugin [" + doomedPlugin.getName() + "]", e); + log.warn("Failed to unschedule jobs for plugin [" + pluginName + "]", e); } } } @@ -365,56 +383,39 @@ public class ServerPluginsBean implements ServerPluginsLocal { if (plugin.getId() == 0) { throw new IllegalArgumentException("Plugin must already exist to update it"); } else { - // make sure the configs are in the DB properly and we have their refs - // this is because we are using JPQL update, so we need to do some of this "manually" - boolean needFlush = false; + // make sure we create (if necessary) and attach the configs Configuration config = plugin.getPluginConfiguration(); if (config != null) { - if (config.getId() > 0) { - config = entityManager.getReference(Configuration.class, config.getId()); - plugin.setPluginConfiguration(config); - } else { - entityManager.persist(config); - needFlush = true; - } + config = entityManager.merge(config); + plugin.setPluginConfiguration(config); } config = plugin.getScheduledJobsConfiguration(); if (config != null) { - if (config.getId() > 0) { - config = entityManager.getReference(Configuration.class, config.getId()); - plugin.setScheduledJobsConfiguration(config); - } else { - entityManager.persist(config); - needFlush = true; - } - } - if (needFlush) { - entityManager.flush(); // must be flushed to the DB so the JPQL update below works + config = entityManager.merge(config); + plugin.setScheduledJobsConfiguration(config); }
- // now we can JPQL update the row - all but content is updated here. - // we assured our configs are persisted/attached above - Query q = entityManager.createNamedQuery(Plugin.UPDATE_ALL_BUT_CONTENT); - q.setParameter("id", plugin.getId()); - q.setParameter("name", plugin.getName()); - q.setParameter("path", plugin.getPath()); - q.setParameter("displayName", plugin.getDisplayName()); - q.setParameter("enabled", plugin.isEnabled()); - q.setParameter("status", plugin.getStatus()); - q.setParameter("md5", plugin.getMD5()); - q.setParameter("version", plugin.getVersion()); - q.setParameter("ampsVersion", plugin.getAmpsVersion()); - q.setParameter("deployment", plugin.getDeployment()); - q.setParameter("pluginConfiguration", config); - q.setParameter("scheduledJobsConfiguration", config); - q.setParameter("description", plugin.getDescription()); - q.setParameter("help", plugin.getHelp()); - q.setParameter("mtime", plugin.getMtime()); - if (q.executeUpdate() != 1) { - throw new Exception("Failed to update a plugin that matches [" + plugin + "]"); - } + Plugin pluginEntity = entityManager.getReference(Plugin.class, plugin.getId()); + pluginEntity.setName(plugin.getName()); + pluginEntity.setPath(plugin.getPath()); + pluginEntity.setDisplayName(plugin.getDisplayName()); + pluginEntity.setEnabled(plugin.isEnabled()); + pluginEntity.setStatus(plugin.getStatus()); + pluginEntity.setMd5(plugin.getMD5()); + pluginEntity.setVersion(plugin.getVersion()); + pluginEntity.setAmpsVersion(plugin.getAmpsVersion()); + pluginEntity.setDeployment(plugin.getDeployment()); + pluginEntity.setPluginConfiguration(plugin.getPluginConfiguration()); + pluginEntity.setScheduledJobsConfiguration(plugin.getScheduledJobsConfiguration()); + pluginEntity.setDescription(plugin.getDescription()); + pluginEntity.setHelp(plugin.getHelp()); + pluginEntity.setMtime(plugin.getMtime());
- entityManager.flush(); // make sure we push this out to the DB now + try { + entityManager.flush(); // make sure we push this out to the DB now + } catch (Exception e) { + throw new Exception("Failed to update a plugin that matches [" + plugin + "]", e); + } } return plugin; } @@ -432,6 +433,27 @@ public class ServerPluginsBean implements ServerPluginsLocal { return status; }
+ // we need this method to talk to the master plugin container because the plugin data model + // does not contain information as to what type a plugin is. It only has information about + // where the plugin is deployed (agent or server) but it doesn't indicate if a plugin + // if of type "alert plugin" or "generic plugin". That is only known when the plugin descriptor + // is parsed, which happens when the master plugin container is initialized. Therefore, this + // needs to get plugin info from the master plugin container while the master is running. + public Map<ServerPluginType, List<String>> getAllPluginsGroupedByType() { + Map<ServerPluginType, List<String>> allPlugins = new HashMap<ServerPluginType, List<String>>(); + + MasterServerPluginContainer master = LookupUtil.getServerPluginService().getMasterPluginContainer(); + if (master != null) { + List<ServerPluginType> types = master.getServerPluginTypes(); + for (ServerPluginType type : types) { + List<String> plugins = master.getAllPluginsByPluginType(type); + allPlugins.put(type, plugins); + } + } + + return allPlugins; + } + /** * This will write the contents of the given plugin file to the database. * This will assume the MD5 in the database is already correct, so this diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsLocal.java index 6f3600e..a6a09bf 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsLocal.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/ServerPluginsLocal.java @@ -2,6 +2,7 @@ package org.rhq.enterprise.server.plugin;
import java.io.File; import java.util.List; +import java.util.Map;
import javax.ejb.Local; import javax.persistence.NoResultException; @@ -9,6 +10,7 @@ import javax.persistence.NoResultException; import org.rhq.core.domain.auth.Subject; import org.rhq.core.domain.plugin.Plugin; import org.rhq.core.domain.plugin.PluginStatusType; +import org.rhq.enterprise.server.plugin.pc.ServerPluginType; import org.rhq.enterprise.server.xmlschema.generated.serverplugin.ServerPluginDescriptorType;
/** @@ -42,6 +44,7 @@ public interface ServerPluginsLocal { * * @param plugin * @return the same plugin, with the relationship data loaded + * @throws NoResultException when no plugin with that name exists */ Plugin getServerPluginRelationships(Plugin plugin);
@@ -86,20 +89,20 @@ public interface ServerPluginsLocal { * * @param subject user making the request * @param pluginIds the plugins to be disabled - * @return the list of plugins that were disabled + * @return the list of names of the plugins that were disabled * @throws Exception if failed to disable a plugin */ - List<Plugin> disableServerPlugins(Subject subject, List<Integer> pluginIds) throws Exception; + List<String> disableServerPlugins(Subject subject, List<Integer> pluginIds) throws Exception;
/** * Removes the plugin from the system and restarts the server plugin container. * * @param subject user making the request * @param pluginIds - * @return the list of plugins that were undeployed + * @return the list of names of plugins that were undeployed * @throws Exception if failed to undeploy a plugin */ - List<Plugin> undeployServerPlugins(Subject subject, List<Integer> pluginIds) throws Exception; + List<String> undeployServerPlugins(Subject subject, List<Integer> pluginIds) throws Exception;
/** * Turns on or off the enabled flag in the database but does NOT restart the server plugin container. @@ -172,4 +175,13 @@ public interface ServerPluginsLocal { * <code>null</code> indicates an unknown plugin. */ PluginStatusType getServerPluginStatus(String pluginName); + + /** + * This will return a map containing all plugins currently known to the master plugin container. + * This will return installed plugins that are both enabled and disabled. + * Note that if the master plugin container is not running, an empty map is returned. + * + * @return names of all enabled and disabled plugins, keyed on their types + */ + Map<ServerPluginType, List<String>> getAllPluginsGroupedByType(); } diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/MasterServerPluginContainer.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/MasterServerPluginContainer.java index 8ebabd4..4ab3fb2 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/MasterServerPluginContainer.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/MasterServerPluginContainer.java @@ -21,6 +21,7 @@ package org.rhq.enterprise.server.plugin.pc; import java.io.File; import java.net.URL; import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.List; @@ -46,11 +47,22 @@ import org.rhq.enterprise.server.xmlschema.generated.serverplugin.ServerPluginDe public class MasterServerPluginContainer { private static final Log log = LogFactory.getLog(MasterServerPluginContainer.class);
+ /** The configuration for the master plugin container itself. */ private MasterServerPluginContainerConfiguration configuration; + + /** the plugin containers for all the different types of plugins that are supported */ private Map<ServerPluginType, AbstractTypeServerPluginContainer> pluginContainers = new HashMap<ServerPluginType, AbstractTypeServerPluginContainer>(); + + /** the object that provides all the classloaders for all plugins */ private ClassLoaderManager classLoaderManager;
/** + * Because the individual plugin containers are only managing enabled plugins (they are never told about plugins that disabled). + * this map contains the lists of plugins that are disabled so others can find out what plugins are registered but not running. + */ + private Map<ServerPluginType, List<String>> disabledPlugins = new HashMap<ServerPluginType, List<String>>(); + + /** * Starts the master plugin container, which will load all plugins and begin managing them. * * @param config the master configuration @@ -188,6 +200,7 @@ public class MasterServerPluginContainer { }
this.pluginContainers.clear(); + this.disabledPlugins.clear(); this.classLoaderManager = null; this.configuration = null;
@@ -238,6 +251,55 @@ public class MasterServerPluginContainer { }
/** + * Given a plugin type, this will return the names of all known plugins of that type. + * This includes all types that are currently started as well as plugins + * that have been disabled. + * + * If the master plugin container has not been started, this returns an empty list. + * + * @param pluginType + * + * @return list of both enabled and disabled plugins of the given type + */ + public List<String> getAllPluginsByPluginType(ServerPluginType pluginType) { + List<String> allPlugins = new ArrayList<String>(); + + AbstractTypeServerPluginContainer pc = getPluginContainerByPluginType(pluginType); + if (pc != null) { + // add the enabled plugins + ServerPluginManager pluginManager = pc.getPluginManager(); + if (pluginManager != null) { + Collection<ServerPluginEnvironment> envs = pluginManager.getPluginEnvironments(); + if (envs != null) { + for (ServerPluginEnvironment env : envs) { + allPlugins.add(env.getPluginName()); + } + } + } + + // add the disabled plugins + List<String> disabled = this.disabledPlugins.get(pluginType); + if (disabled != null) { + allPlugins.addAll(disabled); + } + } + + return allPlugins; + } + + /** + * This will return all known server plugins types. These are the types of plugins + * that are supported by a server plugin container. You can obtain the server + * plugin container that manages a particular server plugin type via + * {@link #getPluginContainerByPluginType(ServerPluginType)}. + * + * @return all known server plugin types + */ + public synchronized List<ServerPluginType> getServerPluginTypes() { + return new ArrayList<ServerPluginType>(this.pluginContainers.keySet()); + } + + /** * Get the plugin container of the given class. This method provides a strongly typed return value, * based on the type of plugin container the caller wants returned. * @@ -245,7 +307,7 @@ public class MasterServerPluginContainer { * @return the plugin container of the given class (<code>null</code> if none found) */ @SuppressWarnings("unchecked") - public synchronized <T extends AbstractTypeServerPluginContainer> T getPluginContainer(Class<T> clazz) { + public synchronized <T extends AbstractTypeServerPluginContainer> T getPluginContainerByClass(Class<T> clazz) { for (AbstractTypeServerPluginContainer pc : this.pluginContainers.values()) { if (clazz.isInstance(pc)) { return (T) pc; @@ -262,7 +324,7 @@ public class MasterServerPluginContainer { * @param pluginName * @return the plugin container that is managing the named plugin of <code>null</code> */ - public synchronized <T extends AbstractTypeServerPluginContainer> T getPluginContainer(String pluginName) { + public synchronized <T extends AbstractTypeServerPluginContainer> T getPluginContainerByPlugin(String pluginName) { for (AbstractTypeServerPluginContainer pc : this.pluginContainers.values()) { if (null != pc.getPluginManager().getPluginEnvironment(pluginName)) { return (T) pc; @@ -319,7 +381,7 @@ public class MasterServerPluginContainer {
if (pluginFiles != null) {
- List<String> disabledPlugins = getDisabledPluginNames(); + List<String> allDisabledPlugins = getDisabledPluginNames();
for (File pluginFile : pluginFiles) { if (pluginFile.getName().endsWith(".jar")) { @@ -329,12 +391,19 @@ public class MasterServerPluginContainer { ServerPluginDescriptorType descriptor; descriptor = ServerPluginDescriptorUtil.loadPluginDescriptorFromUrl(pluginUrl); if (descriptor != null) { - if (!disabledPlugins.contains(descriptor.getName())) { + if (!allDisabledPlugins.contains(descriptor.getName())) { log.debug("pre-loaded server plugin from URL: " + pluginUrl); plugins.put(pluginUrl, descriptor); } else { log.info("Server plugin [" + descriptor.getName() + "] is disabled and will not be initialized"); + ServerPluginType pluginType = new ServerPluginType(descriptor); + List<String> disabledByType = this.disabledPlugins.get(pluginType); + if (disabledByType == null) { + disabledByType = new ArrayList<String>(1); + this.disabledPlugins.put(pluginType, disabledByType); + } + disabledByType.add(descriptor.getName()); } } } catch (Throwable t) { diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginType.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginType.java index feba2fc..3e6bb34 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginType.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginType.java @@ -29,6 +29,22 @@ import org.rhq.enterprise.server.xmlschema.generated.serverplugin.ServerPluginDe public class ServerPluginType { private final Class<? extends ServerPluginDescriptorType> descriptorType;
+ /** + * Given an actual plugin descriptor object, this will create a plugin type + * that represents that kind of plugin. + * + * @param descriptor an actual descriptor parsed from a plugin + */ + public ServerPluginType(ServerPluginDescriptorType descriptor) { + this((descriptor != null) ? descriptor.getClass() : null); + } + + /** + * Given a type of plugin descriptor, this will create a plugin type + * that represents that kind of plugin. + * + * @param descriptorType + */ public ServerPluginType(Class<? extends ServerPluginDescriptorType> descriptorType) { if (descriptorType == null) { throw new NullPointerException("descriptorType must not be null"); diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/metadata/ResourceMetadataManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/metadata/ResourceMetadataManagerBean.java index 9c971e0..d502f4e 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/metadata/ResourceMetadataManagerBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/metadata/ResourceMetadataManagerBean.java @@ -198,49 +198,38 @@ public class ResourceMetadataManagerBean implements ResourceMetadataManagerLocal entityManager.persist(plugin); } else { // agent plugins don't support these configs, but if/when they do in the future, this will support it - boolean needFlush = false; + // make sure we create (if necessary) and attach the configs Configuration config = plugin.getPluginConfiguration(); if (config != null) { - if (config.getId() > 0) { - config = entityManager.getReference(Configuration.class, config.getId()); - plugin.setPluginConfiguration(config); - } else { - entityManager.persist(config); - needFlush = true; - } + config = entityManager.merge(config); + plugin.setPluginConfiguration(config); } config = plugin.getScheduledJobsConfiguration(); if (config != null) { - if (config.getId() > 0) { - config = entityManager.getReference(Configuration.class, config.getId()); - plugin.setScheduledJobsConfiguration(config); - } else { - entityManager.persist(config); - needFlush = true; - } - } - if (needFlush) { - entityManager.flush(); // must be flushed to the DB so the JPQL update below works + config = entityManager.merge(config); + plugin.setScheduledJobsConfiguration(config); }
// update all the fields except content - Query q = entityManager.createNamedQuery(Plugin.UPDATE_ALL_BUT_CONTENT); - q.setParameter("id", plugin.getId()); - q.setParameter("name", plugin.getName()); - q.setParameter("path", plugin.getPath()); - q.setParameter("displayName", plugin.getDisplayName()); - q.setParameter("enabled", plugin.isEnabled()); - q.setParameter("status", plugin.getStatus()); - q.setParameter("md5", plugin.getMD5()); - q.setParameter("version", plugin.getVersion()); - q.setParameter("ampsVersion", plugin.getAmpsVersion()); - q.setParameter("deployment", plugin.getDeployment()); - q.setParameter("pluginConfiguration", plugin.getPluginConfiguration()); - q.setParameter("scheduledJobsConfiguration", plugin.getScheduledJobsConfiguration()); - q.setParameter("description", plugin.getDescription()); - q.setParameter("help", plugin.getHelp()); - q.setParameter("mtime", plugin.getMtime()); - if (q.executeUpdate() != 1) { + Plugin pluginEntity = entityManager.getReference(Plugin.class, plugin.getId()); + pluginEntity.setName(plugin.getName()); + pluginEntity.setPath(plugin.getPath()); + pluginEntity.setDisplayName(plugin.getDisplayName()); + pluginEntity.setEnabled(plugin.isEnabled()); + pluginEntity.setStatus(plugin.getStatus()); + pluginEntity.setMd5(plugin.getMD5()); + pluginEntity.setVersion(plugin.getVersion()); + pluginEntity.setAmpsVersion(plugin.getAmpsVersion()); + pluginEntity.setDeployment(plugin.getDeployment()); + pluginEntity.setPluginConfiguration(plugin.getPluginConfiguration()); + pluginEntity.setScheduledJobsConfiguration(plugin.getScheduledJobsConfiguration()); + pluginEntity.setDescription(plugin.getDescription()); + pluginEntity.setHelp(plugin.getHelp()); + pluginEntity.setMtime(plugin.getMtime()); + + try { + entityManager.flush(); // make sure we push this out to the DB now + } catch (Exception e) { throw new Exception("Failed to update a plugin that matches [" + plugin + "]"); } } diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/plugin/ServerPluginsBeanTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/plugin/ServerPluginsBeanTest.java index e1796bf..d1a6aba 100644 --- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/plugin/ServerPluginsBeanTest.java +++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/plugin/ServerPluginsBeanTest.java @@ -135,6 +135,24 @@ public class ServerPluginsBeanTest extends AbstractEJB3Test { assetLazyInitializationException(plugins.get(1)); }
+ public void testUpdatePlugins() throws Exception { + Plugin p1 = registerPlugin(1); + p1 = this.serverPluginsBean.getServerPlugin(p1.getName()); + p1 = this.serverPluginsBean.getServerPluginRelationships(p1); + + Plugin p1update = this.serverPluginsBean.updateServerPluginExceptContent(getOverlord(), p1); + p1update = this.serverPluginsBean.getServerPluginRelationships(p1update); + + assert p1update.getId() == p1.getId() : p1update; + assert p1update.getId() == p1.getId() : p1update; + assert p1update.getName().equals(p1.getName()) : p1update; + assert p1update.getName().equals(p1.getName()) : p1update; + assert p1update.getPluginConfiguration().equals(p1.getPluginConfiguration()) : p1update; + assert p1update.getScheduledJobsConfiguration().equals(p1.getScheduledJobsConfiguration()) : p1update; + p1update.getPluginConfiguration().equals(p1.getPluginConfiguration()); + p1update.getScheduledJobsConfiguration().equals(p1.getScheduledJobsConfiguration()); + } + public void testDisableEnablePlugins() throws Exception { Plugin p1 = registerPlugin(1); Plugin p2 = registerPlugin(2); @@ -142,12 +160,13 @@ public class ServerPluginsBeanTest extends AbstractEJB3Test { List<Integer> ids = new ArrayList<Integer>(2); ids.add(p1.getId()); ids.add(p2.getId()); - List<Plugin> disabled = this.serverPluginsBean.disableServerPlugins(getOverlord(), ids); + List<String> disabled = this.serverPluginsBean.disableServerPlugins(getOverlord(), ids); assert disabled.size() == 2 : disabled; - assert disabled.contains(p1) : disabled; - assert disabled.contains(p2) : disabled; - assert disabled.get(0).getStatus() == PluginStatusType.INSTALLED; // still installed - assert disabled.get(1).getStatus() == PluginStatusType.INSTALLED; // still installed + assert disabled.contains(p1.getName()) : disabled; + assert disabled.contains(p2.getName()) : disabled; + ; + assert this.serverPluginsBean.getServerPlugin(p1.getName()).getStatus() == PluginStatusType.INSTALLED; // still installed + assert this.serverPluginsBean.getServerPlugin(p2.getName()).getStatus() == PluginStatusType.INSTALLED; // still installed List<String> pluginNames = this.serverPluginsBean.getServerPluginNamesByEnabled(false); assert pluginNames.contains(p1.getName()) : pluginNames; assert pluginNames.contains(p2.getName()) : pluginNames; @@ -195,12 +214,14 @@ public class ServerPluginsBeanTest extends AbstractEJB3Test { List<Integer> ids = new ArrayList<Integer>(2); ids.add(p1.getId()); ids.add(p2.getId()); - List<Plugin> undeployed = this.serverPluginsBean.undeployServerPlugins(getOverlord(), ids); + List<String> undeployed = this.serverPluginsBean.undeployServerPlugins(getOverlord(), ids); assert undeployed.size() == 2 : undeployed; - assert undeployed.contains(p1) : undeployed; - assert undeployed.contains(p2) : undeployed; - assert undeployed.get(0).getStatus() == PluginStatusType.DELETED; - assert undeployed.get(1).getStatus() == PluginStatusType.DELETED; + assert undeployed.contains(p1.getName()) : undeployed; + assert undeployed.contains(p2.getName()) : undeployed; + Plugin p1deleted = getDeletedPluginInTx(p1.getName()); + Plugin p2deleted = getDeletedPluginInTx(p2.getName()); + assert p1deleted.getStatus() == PluginStatusType.DELETED; + assert p2deleted.getStatus() == PluginStatusType.DELETED;
List<String> pluginNames = this.serverPluginsBean.getServerPluginNamesByEnabled(false); assert !pluginNames.contains(p1.getName()) : "deleted plugins should not be returned even here" + pluginNames; @@ -230,16 +251,18 @@ public class ServerPluginsBeanTest extends AbstractEJB3Test { List<Integer> ids = new ArrayList<Integer>(2); ids.add(p1.getId()); ids.add(p2.getId()); - List<Plugin> undeployed = this.serverPluginsBean.undeployServerPlugins(getOverlord(), ids); + List<String> undeployed = this.serverPluginsBean.undeployServerPlugins(getOverlord(), ids); assert undeployed.size() == 2 : undeployed; - assert undeployed.contains(p1) : undeployed; - assert undeployed.contains(p2) : undeployed; - assert undeployed.get(0).getStatus() == PluginStatusType.DELETED; - assert undeployed.get(0).getPluginConfiguration() == null; // undeploy should have removed this - assert undeployed.get(0).getScheduledJobsConfiguration() == null; // undeploy should have removed this - assert undeployed.get(1).getStatus() == PluginStatusType.DELETED; - assert undeployed.get(1).getPluginConfiguration() == null; // undeploy should have removed this - assert undeployed.get(1).getScheduledJobsConfiguration() == null; // undeploy should have removed this + assert undeployed.contains(p1.getName()) : undeployed; + assert undeployed.contains(p2.getName()) : undeployed; + Plugin p1deleted = getDeletedPluginInTx(p1.getName()); + assert p1deleted.getStatus() == PluginStatusType.DELETED; + assert p1deleted.getPluginConfiguration() == null; // undeploy should have removed this + assert p1deleted.getScheduledJobsConfiguration() == null; // undeploy should have removed this + Plugin p2deleted = getDeletedPluginInTx(p1.getName()); + assert p2deleted.getStatus() == PluginStatusType.DELETED; + assert p2deleted.getPluginConfiguration() == null; // undeploy should have removed this + assert p2deleted.getScheduledJobsConfiguration() == null; // undeploy should have removed this
List<String> pluginNames = this.serverPluginsBean.getServerPluginNamesByEnabled(false); assert !pluginNames.contains(p1.getName()) : "deleted plugins should not be returned even here" + pluginNames; @@ -320,4 +343,17 @@ public class ServerPluginsBeanTest extends AbstractEJB3Test { private Subject getOverlord() { return LookupUtil.getSubjectManager().getOverlord(); } + + private Plugin getDeletedPluginInTx(String pluginName) throws Exception { + EntityManager em = getEntityManager(); + getTransactionManager().begin(); + try { + Query q = em.createNamedQuery(Plugin.QUERY_FIND_ANY_BY_NAME_AND_TYPE); + q.setParameter("name", pluginName); + q.setParameter("type", PluginDeploymentType.SERVER); + return (Plugin) q.getSingleResult(); + } finally { + getTransactionManager().rollback(); + } + } } diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/plugin/pc/generic/GenericServerPluginTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/plugin/pc/generic/GenericServerPluginTest.java index 1dace0b..9f0026b 100644 --- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/plugin/pc/generic/GenericServerPluginTest.java +++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/plugin/pc/generic/GenericServerPluginTest.java @@ -23,6 +23,7 @@ import java.io.File; import java.io.FileOutputStream; import java.io.InputStream; import java.util.List; +import java.util.Map; import java.util.jar.JarEntry; import java.util.jar.JarOutputStream;
@@ -32,12 +33,16 @@ import org.testng.annotations.Test;
import org.rhq.core.domain.configuration.Configuration; import org.rhq.core.util.stream.StreamUtil; +import org.rhq.enterprise.server.plugin.ServerPluginsLocal; +import org.rhq.enterprise.server.plugin.pc.ServerPluginType; import org.rhq.enterprise.server.plugin.pc.generic.TestGenericServerPluginService.State; import org.rhq.enterprise.server.plugin.pc.generic.TestGenericServerPluginService.TestGenericPluginManager; import org.rhq.enterprise.server.plugin.pc.generic.TestGenericServerPluginService.TestGenericServerPluginContainer; import org.rhq.enterprise.server.plugin.pc.generic.TestLifecycleListener.LifecycleState; import org.rhq.enterprise.server.test.AbstractEJB3Test; +import org.rhq.enterprise.server.util.LookupUtil; import org.rhq.enterprise.server.xmlschema.ScheduledJobDefinition; +import org.rhq.enterprise.server.xmlschema.generated.serverplugin.generic.GenericPluginDescriptorType;
@Test public class GenericServerPluginTest extends AbstractEJB3Test { @@ -76,10 +81,21 @@ public class GenericServerPluginTest extends AbstractEJB3Test { List<ScheduledJobDefinition> schedules = component.context.getSchedules(); assert schedules == null;
+ ServerPluginsLocal serverPluginsLocal = LookupUtil.getServerPlugins(); + Map<ServerPluginType, List<String>> map = serverPluginsLocal.getAllPluginsGroupedByType(); + assert map.size() == 1; + List<String> pluginNames = map.get(new ServerPluginType(GenericPluginDescriptorType.class)); + assert pluginNames.size() == 1; + assert pluginNames.get(0).equals("TestSimpleGenericPlugin"); + // make sure everything is shutdown this.pluginService.stopMasterPluginContainer(); assert pc.state == State.UNINITIALIZED; assert component.state == LifecycleState.UNINITIALIZED; + + // with the master down, this method should return an empty map + map = serverPluginsLocal.getAllPluginsGroupedByType(); + assert map.size() == 0; }
private File createPluginJar(String jarName, String descriptorXmlFilename) throws Exception { diff --git a/modules/helpers/pluginGen/src/main/java/org/rhq/helpers/pluginGen/Props.java b/modules/helpers/pluginGen/src/main/java/org/rhq/helpers/pluginGen/Props.java index 76b374b..a657f42 100644 --- a/modules/helpers/pluginGen/src/main/java/org/rhq/helpers/pluginGen/Props.java +++ b/modules/helpers/pluginGen/src/main/java/org/rhq/helpers/pluginGen/Props.java @@ -527,6 +527,7 @@ public class Props { private String displayName; private String description; private Set<SimpleProperty> params = new LinkedHashSet<SimpleProperty>(); + private SimpleProperty result;
public OperationProps(String name) { this.name = name; @@ -555,5 +556,13 @@ public class Props { public Set<SimpleProperty> getParams() { return params; } + + public SimpleProperty getResult() { + return result; + } + + public void setResult(SimpleProperty result) { + this.result = result; + } } } diff --git a/modules/helpers/pluginGen/src/main/resources/descriptorMain.ftl b/modules/helpers/pluginGen/src/main/resources/descriptorMain.ftl index a148a61..0343787 100644 --- a/modules/helpers/pluginGen/src/main/resources/descriptorMain.ftl +++ b/modules/helpers/pluginGen/src/main/resources/descriptorMain.ftl @@ -60,6 +60,11 @@ name="${props.name}" <#-- TODO separate out plugin name and service name --> </#list> </parameters> </#if> + <#if operation.result??> + <results> + <c:simple-property name="${operation.result.name}" /> + </results> + </#if> </operation> </#list> <#else>
commit a3290f235cb329a4bdda1d05574190ddee327c26 Author: Heiko W. Rupp pilhuhn@fedorapeople.org Date: Thu Nov 26 17:58:07 2009 +0100
Follow schema conventions to separate words by dash and don't do camelCase
diff --git a/modules/enterprise/server/plugins/alert-email/src/main/resources/META-INF/rhq-serverplugin.xml b/modules/enterprise/server/plugins/alert-email/src/main/resources/META-INF/rhq-serverplugin.xml index 7f97f64..2590490 100644 --- a/modules/enterprise/server/plugins/alert-email/src/main/resources/META-INF/rhq-serverplugin.xml +++ b/modules/enterprise/server/plugins/alert-email/src/main/resources/META-INF/rhq-serverplugin.xml @@ -34,10 +34,10 @@ </serverplugin:plugin-configuration>
<!-- How does this sender show up in drop downs etc --> - <shortName>Email</shortName> + <short-name>Email</short-name>
<!-- Class that does the actual sending --> - <pluginClass>EmailSender</pluginClass> + <plugin-class>EmailSender</plugin-class>
<!-- What can a user configure when defining an alert --> <alert-configuration> diff --git a/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-alert.xsd b/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-alert.xsd index dc4d925..404887f 100644 --- a/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-alert.xsd +++ b/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-alert.xsd @@ -40,14 +40,14 @@ xs:complexContent <xs:extension base="serverplugin:ServerPluginDescriptorType"> xs:sequence - <xs:element name="shortName" minOccurs="1" maxOccurs="1"> + <xs:element name="short-name" minOccurs="1" maxOccurs="1"> xs:annotation xs:documentation The short name of this plugin as it will be shown in Headers and drop down boxes </xs:documentation> </xs:annotation> </xs:element> - <xs:element name="pluginClass" minOccurs="1" maxOccurs="1"> + <xs:element name="plugin-class" minOccurs="1" maxOccurs="1"> xs:annotation xs:documentation The name of the class implementing the plugin functionality. This class needs to
commit 2f9837111d710e0365e8969f64019c8809c396c3 Author: Heiko W. Rupp pilhuhn@fedorapeople.org Date: Thu Nov 26 13:46:28 2009 +0100
This logger is not needed.
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSender.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSender.java index 6adc6f6..4acf335 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSender.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSender.java @@ -37,8 +37,6 @@ import org.rhq.core.domain.configuration.Configuration; */ public abstract class AlertSender {
- private final Log log = LogFactory.getLog(AlertSender.class); - /** Configuration from the global per plugin type preferences */ protected Configuration preferences;
commit f6cf4f19e4fe10bbb853c138a67b5653ca16c5ed Author: Heiko W. Rupp pilhuhn@fedorapeople.org Date: Thu Nov 26 11:47:07 2009 +0100
A first implementation of an AlertSender that sends via email
diff --git a/modules/enterprise/server/plugins/alert-email/pom.xml b/modules/enterprise/server/plugins/alert-email/pom.xml new file mode 100644 index 0000000..d76bdbb --- /dev/null +++ b/modules/enterprise/server/plugins/alert-email/pom.xml @@ -0,0 +1,137 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd%22%3E + <parent> + <artifactId>rhq-enterprise-server-plugins-parent</artifactId> + <groupId>org.rhq</groupId> + <version>1.4.0-SNAPSHOT</version> + </parent> + <modelVersion>4.0.0</modelVersion> + + <groupId>org.rhq</groupId> + <artifactId>alert-email</artifactId> + <version>1.4.0-SNAPSHOT</version> + + <name>RHQ Enterprise Server Email Alert Plugin</name> + + <scm> + <connection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/modules/enterprise/server/plugins/alert-email/</connection> + <developerConnection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/modules/enterprise/server/plugins/alert-email/</developerConnection> + </scm> + + <properties> + <scm.module.path>modules/enterprise/server/plugins/disk/</scm.module.path> + </properties> + + <dependencies> + <dependency> + <groupId>javax.mail</groupId> + <artifactId>mail</artifactId> + <version>1.3.1</version> + <scope>provided</scope> <!-- by JBossAS --> + </dependency> + + <dependency> + <groupId>org.rhq</groupId> + <artifactId>rhq-enterprise-server</artifactId> + <version>1.4.0-SNAPSHOT</version> + <scope>provided</scope> <!-- by JBossAS --> + </dependency> + + <!-- TODO: This is a fix for the Javac bug requiring annotations to be + available when compiling dependent classes. It is fixed in JDK 6 --> + <dependency> + <groupId>javax.persistence</groupId> + <artifactId>persistence-api</artifactId> + <version>1.0</version> + <scope>provided</scope> + </dependency> + + <dependency> + <groupId>jboss.jboss-embeddable-ejb3</groupId> + <artifactId>hibernate-all</artifactId> + <version>1.0.0.Alpha9</version> + <scope>provided</scope> + <!-- needed for referenced domain entities that use Hibernate annotations --> + </dependency> + + </dependencies> + + <build> + <plugins> + + <plugin> + <artifactId>maven-surefire-plugin</artifactId> + <configuration> + <excludedGroups>${rhq.testng.excludedGroups}</excludedGroups> + <!-- + <argLine>-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=y</argLine> + --> + </configuration> + </plugin> + + </plugins> + </build> + + <profiles> + + <profile> + <id>dev</id> + + <properties> + <rhq.rootDir>../../../../..</rhq.rootDir> + <rhq.containerDir>${rhq.rootDir}/${rhq.defaultDevContainerPath}</rhq.containerDir> + <rhq.deploymentDir>${rhq.containerDir}/jbossas/server/default/deploy/${rhq.earName}/rhq-serverplugins</rhq.deploymentDir> + </properties> + + <build> + <plugins> + + <plugin> + <artifactId>maven-antrun-plugin</artifactId> + <version>1.1</version> + <executions> + + <execution> + <id>deploy</id> + <phase>compile</phase> + <configuration> + <tasks> + <mkdir dir="${rhq.deploymentDir}" /> + <property name="deployment.file" location="${rhq.deploymentDir}/${project.build.finalName}.jar" /> + <echo>*** Updating ${deployment.file}...</echo> + <jar destfile="${deployment.file}" basedir="${project.build.outputDirectory}" /> + </tasks> + </configuration> + <goals> + <goal>run</goal> + </goals> + </execution> + + <execution> + <id>undeploy</id> + <phase>clean</phase> + <configuration> + <tasks> + <property name="deployment.file" location="${rhq.deploymentDir}/${project.build.finalName}.jar" /> + <echo>*** Deleting ${deployment.file}...</echo> + <delete file="${deployment.file}" /> + </tasks> + </configuration> + <goals> + <goal>run</goal> + </goals> + </execution> + + </executions> + </plugin> + + </plugins> + </build> + </profile> + + </profiles> + + +</project> \ No newline at end of file diff --git a/modules/enterprise/server/plugins/alert-email/src/main/java/org/rhq/enterprise/server/plugins/alertEmail/EmailAlertComponent.java b/modules/enterprise/server/plugins/alert-email/src/main/java/org/rhq/enterprise/server/plugins/alertEmail/EmailAlertComponent.java new file mode 100644 index 0000000..8d858af --- /dev/null +++ b/modules/enterprise/server/plugins/alert-email/src/main/java/org/rhq/enterprise/server/plugins/alertEmail/EmailAlertComponent.java @@ -0,0 +1,50 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2009 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.plugins.alertEmail; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.rhq.enterprise.server.plugin.pc.ServerPluginComponent; +import org.rhq.enterprise.server.plugin.pc.ServerPluginContext; + +/** + * Stateful component class of this plugin + * @author Heiko W. Rupp + */ +public class EmailAlertComponent implements ServerPluginComponent { + + private final Log log = LogFactory.getLog(EmailAlertComponent.class); + + public void start() { + log.info("Alert:Email - start()"); + } + + public void initialize(ServerPluginContext context) throws Exception { + log.info("Alert:Email - initialize()"); + } + + public void shutdown() { + log.info("Alert:Email - shutdown"); + } + + public void stop() { + log.info("Alert:Email - stop"); + } +} diff --git a/modules/enterprise/server/plugins/alert-email/src/main/java/org/rhq/enterprise/server/plugins/alertEmail/EmailSender.java b/modules/enterprise/server/plugins/alert-email/src/main/java/org/rhq/enterprise/server/plugins/alertEmail/EmailSender.java new file mode 100644 index 0000000..581eb94 --- /dev/null +++ b/modules/enterprise/server/plugins/alert-email/src/main/java/org/rhq/enterprise/server/plugins/alertEmail/EmailSender.java @@ -0,0 +1,75 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2009 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.plugins.alertEmail; + +import java.util.Properties; + +import javax.mail.Message; +import javax.mail.Session; +import javax.mail.Transport; +import javax.mail.internet.InternetAddress; + +import com.sun.mail.smtp.SMTPMessage; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.rhq.core.domain.alert.Alert; +import org.rhq.enterprise.server.plugin.pc.alert.AlertSender; +import org.rhq.enterprise.server.plugin.pc.alert.ResultState; +import org.rhq.enterprise.server.plugin.pc.alert.SenderResult; + +/** + * Class to send emails. + * @author Heiko W. Rupp + */ +public class EmailSender extends AlertSender { + + private final Log log = LogFactory.getLog(EmailSender.class); + + @Override + public SenderResult send(Alert alert) { + + String emailAddress = alertParameters.getSimpleValue("emailAddress",null); + if (emailAddress==null) { + log.warn("Email address was null, should not happen"); + return new SenderResult(ResultState.FAILURE,"No email address given"); + } + + String mailserver = preferences.getSimpleValue("mailserver","localhost"); // TODO get RHQ default one + String senderAddress = preferences.getSimpleValue("senderEmail","rhqadmin@localhost"); // TODO get RHQ default one + + Properties props = new Properties(); + props.put("mail.smtp.host",mailserver); + Session session = Session.getDefaultInstance(props); // TODO pass authenticator + Message message = new SMTPMessage(session); + try { + message.setFrom(new InternetAddress(senderAddress)); + message.setRecipient(Message.RecipientType.TO,new InternetAddress("hwr@redhat.com")); + message.setSubject("Alert on " + "Dummy - TODO"); + message.setText("Li la lu, nur der Mann im Mond schaut zu"); + Transport.send(message); + } + catch (Exception e) { + log.warn("Sending of email failed: " + e); + return new SenderResult(ResultState.FAILURE,"Send failed: " + e.getMessage()); + } + return new SenderResult(ResultState.SUCCESS, "Emails sent to XXXX"); + } +} diff --git a/modules/enterprise/server/plugins/alert-email/src/main/resources/META-INF/rhq-serverplugin.xml b/modules/enterprise/server/plugins/alert-email/src/main/resources/META-INF/rhq-serverplugin.xml new file mode 100644 index 0000000..7f97f64 --- /dev/null +++ b/modules/enterprise/server/plugins/alert-email/src/main/resources/META-INF/rhq-serverplugin.xml @@ -0,0 +1,48 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<alert-plugin + name="alert-email" + displayName="Alert:Email" + xmlns="urn:xmlns:rhq-serverplugin.alert" + xmlns:c="urn:xmlns:rhq-configuration" + xmlns:serverplugin="urn:xmlns:rhq-serverplugin" + package="org.rhq.enterprise.server.plugins.alertEmail" + description="Alert sender plugin that sends alert notifications via email" + version="1.0" + > + + serverplugin:help + This alert sender plugin is used to send emails when alerts were triggered. + </serverplugin:help> + + <!-- startup & tear down listener, + scheduled jobs + <serverplugin:plugin-component class="Foo" /> + --> + + + <!-- Global preferences for all email alerts --> + serverplugin:plugin-configuration + <c:simple-property name="mailserver" displayName="Mail server address" type="longString" + description="Address of the mail server to use (if not the default RHQ one )"/> + <c:simple-property name="senderEmail" displayName="Email of sender" type="string" + description="Email of the account from which alert emails should come from"/> + <c:simple-property name="needsLogin" displayName="Needs credentials?" + description="Mark this field if the server needs credentials to send email and give them below" type="boolean"/> + <c:simple-property name="user" type="string"/> + <c:simple-property name="password" type="password" /> + + </serverplugin:plugin-configuration> + + <!-- How does this sender show up in drop downs etc --> + <shortName>Email</shortName> + + <!-- Class that does the actual sending --> + <pluginClass>EmailSender</pluginClass> + + <!-- What can a user configure when defining an alert --> + <alert-configuration> + <c:simple-property name="emailAddress" displayName="Receiver Email Address(es)" type="longString" + description="Email addresses (separated by comma) used for notifications."/> + </alert-configuration> + +</alert-plugin> \ No newline at end of file
commit 8536432a274b918a2e78bfa2d9e1ceaf253937b3 Author: Heiko W. Rupp pilhuhn@fedorapeople.org Date: Thu Nov 26 11:45:03 2009 +0100
Start of PluginManager implementation for alerts.
This provides listing of plugins and instantiation of senders.
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSenderPluginManager.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSenderPluginManager.java new file mode 100644 index 0000000..bc939bf --- /dev/null +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSenderPluginManager.java @@ -0,0 +1,114 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2009 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.plugin.pc.alert; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.w3c.dom.Element; + +import org.rhq.core.domain.configuration.Configuration; +import org.rhq.enterprise.server.plugin.pc.AbstractTypeServerPluginContainer; +import org.rhq.enterprise.server.plugin.pc.ServerPluginEnvironment; +import org.rhq.enterprise.server.plugin.pc.ServerPluginManager; +import org.rhq.enterprise.server.xmlschema.generated.serverplugin.alert.AlertPluginDescriptorType; + +/** + * TODO + * @author Heiko W. Rupp + */ +public class AlertSenderPluginManager extends ServerPluginManager { + + private final Log log = getLog(); + private Map<String,String> pluginNameToType = new HashMap<String, String>(); + private Map<String,String> pluginClassByName = new HashMap<String, String>(); + private Map<String,ServerPluginEnvironment> pluginEnvByName = new HashMap<String, ServerPluginEnvironment>(); + + public AlertSenderPluginManager(AbstractTypeServerPluginContainer pc) { + super(pc); + } + + @Override + public void loadPlugin(ServerPluginEnvironment env) throws Exception { + super.loadPlugin(env); // TODO: Customise this generated block + + AlertPluginDescriptorType type = (AlertPluginDescriptorType) env.getPluginDescriptor(); + + String className = ((Element)type.getPluginClass()).getTextContent(); + if (!className.contains(".")) { + className = type.getPackage() + "." + className; + } + try { + Class.forName(className,false,env.getPluginClassLoader()); + } + catch (Exception e) { + log.warn("Can't find pluginClass " + className + ". Plugin will be ignored"); + return; + } + String shortName = ((Element) type.getShortName()).getTextContent(); + pluginClassByName.put(shortName,className); + pluginNameToType.put(shortName,env.getPluginName()); + pluginEnvByName.put(shortName,env); + + } + + + public AlertSender getAlertSenderForType(String shortName) { + + String className = pluginClassByName.get(shortName); + ServerPluginEnvironment env = pluginEnvByName.get(shortName); + Class clazz; + try { + clazz = Class.forName(className,true,env.getPluginClassLoader()); + } + catch (Exception e) { + log.error(e); // TODO + return null; + } + + AlertSender sender; + try { + sender = (AlertSender) clazz.newInstance(); + } catch (InstantiationException e) { + e.printStackTrace(); // TODO: Customise this generated block + return null; + } catch (IllegalAccessException e) { + e.printStackTrace(); // TODO: Customise this generated block + return null; + } + + sender.alertParameters = new Configuration(); // TODO + sender.preferences = new Configuration(); // TODO + + return sender; + } + + /** + * Return the list of deployed alert sender plug-ins by their <shortName> + * @return List of plugin names + */ + public List<String> getPluginList() { + return new ArrayList<String>(pluginClassByName.keySet()); + } +} diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertServerPluginContainer.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertServerPluginContainer.java index 2c3068f..d9025a9 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertServerPluginContainer.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertServerPluginContainer.java @@ -21,12 +21,13 @@ package org.rhq.enterprise.server.plugin.pc.alert;
import org.rhq.enterprise.server.plugin.pc.AbstractTypeServerPluginContainer; import org.rhq.enterprise.server.plugin.pc.MasterServerPluginContainer; +import org.rhq.enterprise.server.plugin.pc.ServerPluginManager; import org.rhq.enterprise.server.plugin.pc.ServerPluginType; import org.rhq.enterprise.server.xmlschema.generated.serverplugin.alert.AlertPluginDescriptorType;
/** * Manages alert plugins. - * + * * @author John Mazzitelli */ public class AlertServerPluginContainer extends AbstractTypeServerPluginContainer { @@ -39,4 +40,24 @@ public class AlertServerPluginContainer extends AbstractTypeServerPluginContaine public ServerPluginType getSupportedServerPluginType() { return new ServerPluginType(AlertPluginDescriptorType.class); } + + @Override + public ServerPluginManager getPluginManager() { + return super.getPluginManager(); // TODO: Customise this generated block + } + + @Override + public void initialize() throws Exception { + super.initialize(); // TODO: Customise this generated block + } + + @Override + public void start() { + super.start(); // TODO: Customise this generated block + } + + @Override + protected ServerPluginManager createPluginManager() { + return new AlertSenderPluginManager(this); + } }
commit c2f668eb47020a14173e897e02ef84b0e29fc6a4 Merge: 4743488... 6a2d6ad... Author: John Sanda john@localhost.localdomain Date: Wed Nov 25 22:31:11 2009 -0500
Merge branch 'raw-config' of ssh://git.fedorahosted.org/git/rhq/rhq into raw-config
commit 4743488a8b743afb2965cb9a242b5dc8c7fb37cd Author: John Sanda john@localhost.localdomain Date: Wed Nov 25 22:24:44 2009 -0500
[BZ 541486] Fixing serialization bug for configuration update objects
The fix involved nothing more than making AbstractConfigurationUpdate implement Serializable. I have also added unit tests for all implementing classes to verify correct serialization behavior.
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/AbstractConfigurationUpdate.java b/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/AbstractConfigurationUpdate.java index 8fd3150..0231f78 100644 --- a/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/AbstractConfigurationUpdate.java +++ b/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/AbstractConfigurationUpdate.java @@ -24,6 +24,7 @@ package org.rhq.core.domain.configuration;
import java.io.ByteArrayOutputStream; import java.io.PrintStream; +import java.io.Serializable;
import javax.persistence.CascadeType; import javax.persistence.Column; @@ -44,7 +45,10 @@ import javax.xml.bind.annotation.XmlTransient; * Base class for resource configuration and plugin configuration updates (i.e. history items). */ @XmlAccessorType(XmlAccessType.FIELD) -public abstract class AbstractConfigurationUpdate { +public abstract class AbstractConfigurationUpdate implements Serializable { + + private static final long serialVersionUID = 1L; + @JoinColumn(name = "CONFIGURATION_ID", referencedColumnName = "ID", nullable = false) @OneToOne(cascade = { CascadeType.ALL }, fetch = FetchType.EAGER) @XmlTransient diff --git a/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/AbstractConfigurationUpdateTest.java b/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/AbstractConfigurationUpdateTest.java new file mode 100644 index 0000000..7195cde --- /dev/null +++ b/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/AbstractConfigurationUpdateTest.java @@ -0,0 +1,114 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2008 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, version 2, as + * published by the Free Software Foundation, and/or the GNU Lesser + * General Public License, version 2.1, also as published by the Free + * Software Foundation. + * + * 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 and the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * and the GNU Lesser 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.core.domain.configuration; + +import org.testng.annotations.Test; + +public abstract class AbstractConfigurationUpdateTest { + + + @Test + public void serializationShouldCopyConfiguration() throws Exception { + Configuration config = new Configuration(); + config.put(new PropertySimple("x", "1")); + + ResourceConfigurationUpdate update = new ResourceConfigurationUpdate(); + update.setConfiguration(config); + + ResourceConfigurationUpdate serializedUpdate = TestUtil.serializeAndDeserialize(update); + + org.testng.Assert.assertEquals( + serializedUpdate.getConfiguration(), + update.getConfiguration(), + "Failed to properly serialize the 'configuration' property" + ); + } + + @Test + public void serializationShouldCopyErrorMessage() throws Exception { + ResourceConfigurationUpdate update = new ResourceConfigurationUpdate(); + update.setErrorMessage("update error"); + + ResourceConfigurationUpdate serializedUpdate = TestUtil.serializeAndDeserialize(update); + + org.testng.Assert.assertEquals( + serializedUpdate.getErrorMessage(), + update.getErrorMessage(), + "Failed to properly serialize the 'errorMessage' property" + ); + } + + @Test + public void serializationShouldCopyStatus() throws Exception { + ResourceConfigurationUpdate update = new ResourceConfigurationUpdate(); + update.setStatus(ConfigurationUpdateStatus.SUCCESS); + + ResourceConfigurationUpdate serializedUpdate = TestUtil.serializeAndDeserialize(update); + + org.testng.Assert.assertEquals( + serializedUpdate.getStatus(), + update.getStatus(), + "Failed to properly serialize the 'status' property" + ); + } + + @Test + public void serializationShouldCopySubjectName() throws Exception { + ResourceConfigurationUpdate update = new ResourceConfigurationUpdate(null, new Configuration(), "rhqadmin"); + + ResourceConfigurationUpdate serializedUpdate = TestUtil.serializeAndDeserialize(update); + + org.testng.Assert.assertEquals( + serializedUpdate.getSubjectName(), + update.getSubjectName(), + "Failed to properly serialize the 'subjectName' property" + ); + } + + @Test + public void serializationShouldCopyCreatedTime() throws Exception { + ResourceConfigurationUpdate update = new ResourceConfigurationUpdate(); + + ResourceConfigurationUpdate serializedUpdate = TestUtil.serializeAndDeserialize(update); + + org.testng.Assert.assertEquals( + serializedUpdate.getCreatedTime(), + update.getCreatedTime(), + "Failed to properly serialize the 'createdTime' property" + ); + } + + @Test + public void serializationShouldCopyModifiedTime() throws Exception { + ResourceConfigurationUpdate update = new ResourceConfigurationUpdate(); + + ResourceConfigurationUpdate serializedUpdate = TestUtil.serializeAndDeserialize(update); + + org.testng.Assert.assertEquals( + serializedUpdate.getModifiedTime(), + update.getModifiedTime(), + "Failed to properly serialize the 'modifiedTime' property" + ); + } +} diff --git a/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/PluginConfigurationUpdateTest.java b/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/PluginConfigurationUpdateTest.java new file mode 100644 index 0000000..ee63afd --- /dev/null +++ b/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/PluginConfigurationUpdateTest.java @@ -0,0 +1,67 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2008 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, version 2, as + * published by the Free Software Foundation, and/or the GNU Lesser + * General Public License, version 2.1, also as published by the Free + * Software Foundation. + * + * 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 and the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * and the GNU Lesser 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.core.domain.configuration; + +import org.testng.annotations.Test; +import static org.testng.Assert.assertEquals; +import org.rhq.core.domain.resource.Resource; +import org.rhq.core.domain.resource.group.ResourceGroup; +import org.rhq.core.domain.configuration.group.GroupResourceConfigurationUpdate; +import org.rhq.core.domain.configuration.group.GroupPluginConfigurationUpdate; + +public class PluginConfigurationUpdateTest extends AbstractConfigurationUpdateTest { + + @Test + public void serializationShouldCopyResource() throws Exception { + Resource resource = new Resource(); + resource.setUuid("1234"); + + PluginConfigurationUpdate update = new PluginConfigurationUpdate(); + update.setResource(resource); + + PluginConfigurationUpdate serializedUpdate = TestUtil.serializeAndDeserialize(update); + + assertEquals( + serializedUpdate.getResource(), + update.getResource(), + "Failed to properly serialize the 'resource' property" + ); + } + + @Test + public void serializationShouldCopyGroupConfigurationUpdate() throws Exception { + PluginConfigurationUpdate update = new PluginConfigurationUpdate(); + update.setGroupConfigurationUpdate(new GroupPluginConfigurationUpdate(new ResourceGroup("resourceGroup"), + "rhqadmin")); + + PluginConfigurationUpdate serializedUpdate = TestUtil.serializeAndDeserialize(update); + + assertEquals( + serializedUpdate.getGroupConfigurationUpdate(), + update.getGroupConfigurationUpdate(), + "Failed to properly serialize the 'groupConfigurationUpdate' property" + ); + } + +} diff --git a/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/ResourceConfigurationUpdateTest.java b/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/ResourceConfigurationUpdateTest.java new file mode 100644 index 0000000..8a967a6 --- /dev/null +++ b/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/ResourceConfigurationUpdateTest.java @@ -0,0 +1,67 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2008 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, version 2, as + * published by the Free Software Foundation, and/or the GNU Lesser + * General Public License, version 2.1, also as published by the Free + * Software Foundation. + * + * 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 and the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * and the GNU Lesser 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.core.domain.configuration; + +import static org.testng.Assert.*; + +import org.testng.annotations.Test; +import org.rhq.core.domain.resource.Resource; +import org.rhq.core.domain.resource.group.ResourceGroup; +import org.rhq.core.domain.configuration.group.GroupResourceConfigurationUpdate; + +public class ResourceConfigurationUpdateTest extends AbstractConfigurationUpdateTest { + + @Test + public void serializationShouldCopyResource() throws Exception { + Resource resource = new Resource(); + resource.setUuid("1234"); + + ResourceConfigurationUpdate update = new ResourceConfigurationUpdate(); + update.setResource(resource); + + ResourceConfigurationUpdate serializedUpdate = TestUtil.serializeAndDeserialize(update); + + assertEquals( + serializedUpdate.getResource(), + update.getResource(), + "Failed to properly serialize the 'resource' property" + ); + } + + @Test + public void serializationShouldCopyGroupConfigurationUpdate() throws Exception { + ResourceConfigurationUpdate update = new ResourceConfigurationUpdate(); + update.setGroupConfigurationUpdate(new GroupResourceConfigurationUpdate(new ResourceGroup("resourceGroup"), + "rhqadmin")); + + ResourceConfigurationUpdate serializedUpdate = TestUtil.serializeAndDeserialize(update); + + assertEquals( + serializedUpdate.getGroupConfigurationUpdate(), + update.getGroupConfigurationUpdate(), + "Failed to properly serialize the 'groupConfigurationUpdate' property" + ); + } + +} diff --git a/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/TestUtil.java b/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/TestUtil.java new file mode 100644 index 0000000..c1fac86 --- /dev/null +++ b/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/TestUtil.java @@ -0,0 +1,45 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2008 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, version 2, as + * published by the Free Software Foundation, and/or the GNU Lesser + * General Public License, version 2.1, also as published by the Free + * Software Foundation. + * + * 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 and the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * and the GNU Lesser 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.core.domain.configuration; + +import java.io.ByteArrayOutputStream; +import java.io.ObjectOutputStream; +import java.io.ByteArrayInputStream; +import java.io.ObjectInputStream; + +public class TestUtil { + + public static <T> T serializeAndDeserialize(T object) throws Exception { + ByteArrayOutputStream byteOutputStream = new ByteArrayOutputStream(); + ObjectOutputStream ostream = new ObjectOutputStream(byteOutputStream); + + ostream.writeObject(object); + + ByteArrayInputStream byteInputStream = new ByteArrayInputStream(byteOutputStream.toByteArray()); + ObjectInputStream istream = new ObjectInputStream(byteInputStream); + + return (T) istream.readObject(); + } + +} diff --git a/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/group/GroupPluginConfigurationUpdateTest.java b/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/group/GroupPluginConfigurationUpdateTest.java new file mode 100644 index 0000000..0be4172 --- /dev/null +++ b/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/group/GroupPluginConfigurationUpdateTest.java @@ -0,0 +1,51 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2008 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, version 2, as + * published by the Free Software Foundation, and/or the GNU Lesser + * General Public License, version 2.1, also as published by the Free + * Software Foundation. + * + * 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 and the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * and the GNU Lesser 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.core.domain.configuration.group; + +import org.rhq.core.domain.configuration.AbstractConfigurationUpdateTest; +import org.rhq.core.domain.configuration.ResourceConfigurationUpdate; +import org.rhq.core.domain.configuration.Configuration; +import org.rhq.core.domain.configuration.TestUtil; +import org.rhq.core.domain.configuration.PluginConfigurationUpdate; +import org.rhq.core.domain.resource.Resource; +import org.testng.annotations.Test; +import static org.testng.Assert.assertEquals; + +public class GroupPluginConfigurationUpdateTest extends AbstractConfigurationUpdateTest { + + @Test + public void serializationShouldCopyConfigurationUpdates() throws Exception { + GroupPluginConfigurationUpdate update = new GroupPluginConfigurationUpdate(); + update.getConfigurationUpdates().add(new PluginConfigurationUpdate(new Resource(), new Configuration(), + "rhqadmin")); + + GroupPluginConfigurationUpdate serializedUpdate = TestUtil.serializeAndDeserialize(update); + + assertEquals( + serializedUpdate.getConfigurationUpdates(), + update.getConfigurationUpdates(), + "Failed to properly serialize the 'configurationUpdate' property" + ); + } +} diff --git a/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/group/GroupResourceConfigurationUpdateTest.java b/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/group/GroupResourceConfigurationUpdateTest.java new file mode 100644 index 0000000..ebb9008 --- /dev/null +++ b/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/group/GroupResourceConfigurationUpdateTest.java @@ -0,0 +1,51 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2008 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, version 2, as + * published by the Free Software Foundation, and/or the GNU Lesser + * General Public License, version 2.1, also as published by the Free + * Software Foundation. + * + * 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 and the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * and the GNU Lesser 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.core.domain.configuration.group; + +import static org.testng.Assert.*; + +import org.rhq.core.domain.configuration.AbstractConfigurationUpdateTest; +import org.rhq.core.domain.configuration.ResourceConfigurationUpdate; +import org.rhq.core.domain.configuration.Configuration; +import org.rhq.core.domain.configuration.TestUtil; +import org.rhq.core.domain.resource.Resource; +import org.testng.annotations.Test; + +public class GroupResourceConfigurationUpdateTest extends AbstractConfigurationUpdateTest { + + @Test + public void serializationShouldCopyConfigurationUpdates() throws Exception { + GroupResourceConfigurationUpdate update = new GroupResourceConfigurationUpdate(); + update.addConfigurationUpdate(new ResourceConfigurationUpdate(new Resource(), new Configuration(), "rhqadmin")); + + GroupResourceConfigurationUpdate serializedUpdate = TestUtil.serializeAndDeserialize(update); + + assertEquals( + serializedUpdate.getConfigurationUpdates(), + update.getConfigurationUpdates(), + "Failed to properly serialize the 'configurationUpdate' property" + ); + } + +}
commit 6f93ae97534f65ffffeb87fded7464def6da0f57 Merge: a26e3ec... c823eb5... Author: Jay Shaughnessy jshaughn@redhat.com Date: Wed Nov 25 16:44:48 2009 -0500
Merge branch 'linux-config' into linux-config-dev
commit a26e3ec9b6affb0379614dee3e5f7b874403bd63 Author: Jay Shaughnessy jshaughn@redhat.com Date: Wed Nov 25 16:37:47 2009 -0500
Add custom menu items to sample perspective
diff --git a/etc/samples/perspectives/sample-perspective/perspective/src/main/resources/META-INF/rhq-serverplugin.xml b/etc/samples/perspectives/sample-perspective/perspective/src/main/resources/META-INF/rhq-serverplugin.xml index 36430f3..1fefde4 100644 --- a/etc/samples/perspectives/sample-perspective/perspective/src/main/resources/META-INF/rhq-serverplugin.xml +++ b/etc/samples/perspectives/sample-perspective/perspective/src/main/resources/META-INF/rhq-serverplugin.xml @@ -11,4 +11,43 @@ xmlns:serverplugin="urn:xmlns:rhq-serverplugin" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance%22%3E
+ <!-- Add Custom menuItem to Core Menu --> + <menuItem + name="custom" + displayName="Custom"> + <position + extensionPoint="coreMenu" + name="help" + placement="after" /> + </menuItem> + + <menuItem + name="custom.child1" + displayName="Child1"> + <position + extensionPoint="coreMenu" + name="custom" + placement="start" /> + </menuItem> + + <menuItem + name="custom.child2" + displayName="Child-2"> + <position + extensionPoint="coreMenu" + name="custom.child1" + placement="after" /> + </menuItem> + + <menuItem + name="custom.grandchild1" + displayName="GrandChild 1" + feature="aboutBox" + iconUrl="http://127.0.0.1:7080/images/icons/availability_grey_16.png%22%3E + <position + extensionPoint="coreMenu" + name="custom.child1" + placement="start" /> + </menuItem> + </perspectivePlugin> \ No newline at end of file diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveManagerBean.java index c33120b..c6638b3 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveManagerBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveManagerBean.java @@ -62,7 +62,7 @@ public class PerspectiveManagerBean implements PerspectiveManagerLocal, Perspect // TODO: Cache session:menu map here
// TODO: remove this debug code - // printMenu(coreMenu, ""); + printMenu(coreMenu, "");
return coreMenu; } diff --git a/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-perspective.xsd b/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-perspective.xsd index 9223e1b..97584b1 100644 --- a/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-perspective.xsd +++ b/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-perspective.xsd @@ -18,9 +18,7 @@ schemaLocation="rhq-serverplugin.xsd" />
xs:annotation - xs:documentation - Schema for a Perspective Descriptor. Perspective are deployed as Server Plugins. - </xs:documentation> + xs:documentationSchema for a Perspective Descriptor. Perspective are deployed as Server Plugins.</xs:documentation> xs:appinfo jaxb:schemaBindings <jaxb:package @@ -34,14 +32,9 @@ type="perspective:PerspectivePluginDescriptorType" substitutionGroup="serverplugin:server-plugin"> xs:annotation - xs:documentation - Defines a Perspective plugin. A Perspective is deployed as a Server Plugin. - The Server Plugin - Container (SPC) handles simple lifecycle management for - the deployed plugins (e.g. start, stop). The plugin - is otherwise standalone - and can do everything it needs to do without additional help from the SPC. - </xs:documentation> + xs:documentationDefines a Perspective plugin. A Perspective is deployed as a Server Plugin. The Server Plugin + Container (SPC) handles simple lifecycle management for the deployed plugins (e.g. start, stop). The plugin + is otherwise standalone and can do everything it needs to do without additional help from the SPC.</xs:documentation> xs:appinfo <jaxb:class name="PerspectivePluginElement" /> @@ -89,9 +82,7 @@ name="globalTask" type="perspective:TaskType"> xs:annotation - xs:documentation - Add a Global Task extension. - </xs:documentation> + xs:documentationAdd a Global Task extension.</xs:documentation> xs:appinfo <jaxb:class name="PerspectiveGlobalTaskElement" /> @@ -103,9 +94,7 @@ name="resourceTask" type="perspective:TaskType"> xs:annotation - xs:documentation - Add a Resource Task extension. - </xs:documentation> + xs:documentationAdd a Resource Task extension.</xs:documentation> xs:appinfo <jaxb:class name="PerspectiveResourceTaskElement" /> @@ -121,9 +110,7 @@ minOccurs="0" maxOccurs="unbounded"> xs:annotation - xs:documentation - Limit task to the designated task pane extension points. Otherwise, all. - </xs:documentation> + xs:documentationLimit task to the designated task pane extension points. Otherwise, all.</xs:documentation> </xs:annotation> </xs:element> <xs:element @@ -131,17 +118,10 @@ minOccurs="0" maxOccurs="unbounded"> xs:annotation - xs:documentation - Activate the extension only if the user has resources of the specified type in - inventory. - Activated - only if the user has the required permissions. At least one resource - activator - required for - resource task extensions. Activated for resources only if specified trait - conditions are - also met. - </xs:documentation> + xs:documentationActivate the extension only if the user has resources of the specified type in + inventory. Activated only if the user has the required permissions. At least one resource activator + required for resource task extensions. Activated for resources only if specified trait conditions are + also met.</xs:documentation> </xs:annotation> </xs:element> <xs:element @@ -149,9 +129,7 @@ minOccurs="0" maxOccurs="unbounded"> xs:annotation - xs:documentation - Activate the extension only if the user has the required global permissions. - </xs:documentation> + xs:documentationActivate the extension only if the user has the required global permissions.</xs:documentation> </xs:annotation> </xs:element> <xs:element @@ -180,9 +158,7 @@ type="perspective:DisplayNameType" use="required"> xs:annotation - xs:documentation - The display name for the task extension. - </xs:documentation> + xs:documentationThe display name for the task extension.</xs:documentation> </xs:annotation> </xs:attribute> <xs:attribute @@ -190,9 +166,7 @@ type="perspective:DescriptionType" use="required"> xs:annotation - xs:documentation - The display description for the task extension. - </xs:documentation> + xs:documentationThe display description for the task extension.</xs:documentation> </xs:annotation> </xs:attribute> <xs:attribute @@ -200,9 +174,7 @@ type="xs:anyURI" use="required"> xs:annotation - xs:documentation - The request URL for the task extension. Typically kicks off a wizard or similar workflow. - </xs:documentation> + xs:documentationThe request URL for the task extension. Typically kicks off a wizard or similar workflow.</xs:documentation> </xs:annotation> </xs:attribute> <xs:attribute @@ -210,11 +182,8 @@ type="xs:string" use="optional"> xs:annotation - xs:documentation - The display category for the task extension (optional). Tasks with the same category will - be grouped - together in the task pane. - </xs:documentation> + xs:documentationThe display category for the task extension (optional). Tasks with the same category will + be grouped together in the task pane.</xs:documentation> </xs:annotation> </xs:attribute> </xs:complexType> @@ -233,9 +202,7 @@ name="menuItem" type="perspective:MenuItemType"> xs:annotation - xs:documentation - Add, Replace or Remove a menuItem extension for an existing menu extension point. - </xs:documentation> + xs:documentationAdd, Replace or Remove a menuItem extension for an existing menu extension point.</xs:documentation> xs:appinfo <jaxb:class name="PerspectiveMenuItemElement" /> @@ -251,9 +218,7 @@ minOccurs="1" maxOccurs="1"> xs:annotation - xs:documentation - Required positioning element for the menuItem extension. - </xs:documentation> + xs:documentationRequired positioning element for the menuItem extension.</xs:documentation> </xs:annotation> </xs:element> <xs:element @@ -261,14 +226,9 @@ minOccurs="0" maxOccurs="unbounded"> xs:annotation - xs:documentation - Activate the extension only if the user has resources of the specified type in - inventory. - Activated only if the user has the required permissions. Activated for - resources only if - specified trait - conditions are also met. - </xs:documentation> + xs:documentationActivate the extension only if the user has resources of the specified type in + inventory. Activated only if the user has the required permissions. Activated for resources only if + specified trait conditions are also met.</xs:documentation> </xs:annotation> </xs:element> <xs:element @@ -276,9 +236,7 @@ minOccurs="0" maxOccurs="unbounded"> xs:annotation - xs:documentation - Activate the extension only if the user has the required global permissions. - </xs:documentation> + xs:documentationActivate the extension only if the user has the required global permissions.</xs:documentation> </xs:annotation> </xs:element> </xs:sequence> @@ -288,11 +246,8 @@ use="optional" default="add"> xs:annotation - xs:documentation - Add, Replace or Remove the menuItem extension. For removal all but the name attribute are - ignored. - Default is add. - </xs:documentation> + xs:documentationAdd, Replace or Remove the menuItem extension. For removal all but the name attribute are + ignored. Default is add.</xs:documentation> </xs:annotation> </xs:attribute> <xs:attribute @@ -300,10 +255,8 @@ type="perspective:NameType" use="required"> xs:annotation - xs:documentation - Internal name for the menuItem extension. Unique within extension names defined by the - perspective. - </xs:documentation> + xs:documentationInternal name for the menuItem extension. Unique within extension names defined by the + perspective.</xs:documentation> </xs:annotation> </xs:attribute> <xs:attribute @@ -311,9 +264,7 @@ type="perspective:DisplayNameType" use="optional"> xs:annotation - xs:documentation - The display name for the menuItem extension. If omitted an icon is required. - </xs:documentation> + xs:documentationThe display name for the menuItem extension. If omitted an icon is required.</xs:documentation> </xs:annotation> </xs:attribute> <xs:attribute @@ -321,9 +272,7 @@ type="perspective:MenuItemFeatureType" use="optional"> xs:annotation - xs:documentation - Certain menuItem extensions utilize special built-in rendering features. - </xs:documentation> + xs:documentationCertain menuItem extensions utilize special built-in rendering features.</xs:documentation> </xs:annotation> </xs:attribute> <xs:attribute @@ -331,12 +280,8 @@ type="xs:anyURI" use="optional"> xs:annotation - xs:documentation - The request URL for the menuItem extension. If omitted it is assumed - the menuItem - exists as - a navigation element to child menuItems. - </xs:documentation> + xs:documentationThe request URL for the menuItem extension. If omitted it is assumed the menuItem exists + as a navigation element to child menuItems.</xs:documentation> </xs:annotation> </xs:attribute> <xs:attribute @@ -344,10 +289,8 @@ type="xs:anyURI" use="optional"> xs:annotation - xs:documentation - The request URL for the icon displayed for this menuItem extension. If omitted no image is - displayed. Required if displayName if omitted. - </xs:documentation> + xs:documentationThe request URL for the icon displayed for this menuItem extension. If omitted no image is + displayed. Required if displayName if omitted.</xs:documentation> </xs:annotation> </xs:attribute> <xs:attribute @@ -398,9 +341,7 @@ minOccurs="1" maxOccurs="1"> xs:annotation - xs:documentation - Required positioning element for the Tab or SubTab extension. - </xs:documentation> + xs:documentationRequired positioning element for the Tab or SubTab extension.</xs:documentation> </xs:annotation> </xs:element> <xs:element @@ -408,14 +349,9 @@ minOccurs="0" maxOccurs="unbounded"> xs:annotation - xs:documentation - Activate the extension only if the user has resources of the specified type in - inventory. - Activated only if the user has the required permissions. Activated for - resources only if - specified trait - conditions are also met. - </xs:documentation> + xs:documentationActivate the extension only if the user has resources of the specified type in + inventory. Activated only if the user has the required permissions. Activated for resources only if + specified trait conditions are also met.</xs:documentation> </xs:annotation> </xs:element> <xs:element @@ -423,9 +359,7 @@ minOccurs="0" maxOccurs="unbounded"> xs:annotation - xs:documentation - Activate task only if the user has the required global permissions. - </xs:documentation> + xs:documentationActivate task only if the user has the required global permissions.</xs:documentation> </xs:annotation> </xs:element> </xs:sequence> @@ -435,8 +369,7 @@ use="optional" default="add"> xs:annotation - xs:documentation - Add, Replace or Remove the tab extension. For removal all but the name attribute are + xs:documentationAdd, Replace or Remove the tab extension. For removal all but the name attribute are ignored. Default is add.</xs:documentation> </xs:annotation> </xs:attribute> @@ -445,8 +378,7 @@ type="perspective:NameType" use="required"> xs:annotation - xs:documentation - Internal name for the tab extension. Unique within extension names defined by the + xs:documentationInternal name for the tab extension. Unique within extension names defined by the perspective.</xs:documentation> </xs:annotation> </xs:attribute> @@ -455,9 +387,7 @@ type="perspective:DisplayNameType" use="required"> xs:annotation - xs:documentation - The display name for the tab extension. - </xs:documentation> + xs:documentationThe display name for the tab extension.</xs:documentation> </xs:annotation> </xs:attribute> <xs:attribute @@ -465,9 +395,7 @@ type="xs:anyURI" use="required"> xs:annotation - xs:documentation - The request URL for the tab extension. - </xs:documentation> + xs:documentationThe request URL for the tab extension.</xs:documentation> </xs:annotation> </xs:attribute> <xs:attribute @@ -475,10 +403,8 @@ type="xs:anyURI" use="optional"> xs:annotation - xs:documentation - The request URL for the icon displayed for this tab extension. If omitted no image is - displayed. - </xs:documentation> + xs:documentationThe request URL for the icon displayed for this tab extension. If omitted no image is + displayed.</xs:documentation> </xs:annotation> </xs:attribute> <xs:attribute
commit c823eb53d8d4a52546fd628fd32cbee0ddd68321 Merge: d0ad9d3... 2ce39c2... Author: Simeon Pinder spinder@redhat.com Date: Wed Nov 25 15:45:13 2009 -0500
Merge branch 'linux-config' of ssh://spinder@git.fedorahosted.org/git/rhq/rhq into linux-config
commit d0ad9d3db7ef2e756bf7f4eda10b9f8bfc65ad31 Author: Simeon Pinder spinder@redhat.com Date: Wed Nov 25 15:19:39 2009 -0500
Modified menu.xhtml to pull most content dynamically
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/perspectives/ExtensionPoints.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/perspectives/ExtensionPoints.java new file mode 100644 index 0000000..5670264 --- /dev/null +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/perspectives/ExtensionPoints.java @@ -0,0 +1,449 @@ +package org.rhq.enterprise.gui.perspectives; + +public class ExtensionPoints { + + //constants:begin Extension point map + //MENU:ExtensionPoints BEGIN + //root menu item container + public static final String menu = "menu"; + //logo + public static final String logo = menu + ".logo"; + public static final String logo_BEFORE = logo + "_BEFORE"; + public static final String logo_AFTER = logo + "_AFTER"; + //overview + public static final String overview_BEFORE = logo_AFTER;//same spot + public static final String overview = menu + ".overview"; + public static final String subsystemViews = overview + ".subsystemViews"; + public static final String configurationChanges = subsystemViews + ".configurationChanges"; + public static final String suspectMetrics = subsystemViews + ".suspectMetrics"; + public static final String operations = subsystemViews + ".operations"; + public static final String alerts = subsystemViews + ".alerts"; + public static final String alertDefinitions = subsystemViews + ".alertDefinitions"; + public static final String autoDiscoveryQueue = overview + ".autoDiscoveryQueue"; + public static final String dashboard = overview + ".dashboard"; + public static final String overview_AFTER = overview + "_AFTER"; + //resources + public static final String resources_BEFORE = overview_AFTER;//same spot + public static final String resources = menu + ".resources"; + public static final String platforms = resources + ".platforms"; + public static final String servers = resources + ".servers"; + public static final String services = resources + ".services"; + public static final String favoriteResources = resources + ".favoriteResources"; + public static final String recentlyViewedResources = resources + ".recentlyViewedResources"; + public static final String searchResources = resources + ".search"; + public static final String resources_AFTER = resources + "_AFTER"; + //groups + public static final String groups_BEFORE = resources_AFTER;//same spot + public static final String groups = menu + ".groups"; + public static final String compatible = groups + ".compatibleGroups"; + public static final String mixed = groups + ".mixedGroups"; + public static final String definitions = groups + ".groupDefinitions"; + public static final String newGroup = groups + ".newGroup"; + public static final String newGroupDefinition = groups + ".newGroupDefinition"; + public static final String favoriteGroups = groups + ".favoriteGroups"; + public static final String recentlyViewedGroups = groups + ".recentlyViewedGroups"; + public static final String searchGroups = groups + ".search"; + public static final String groups_AFTER = groups + "_AFTER"; + //administration + public static final String administration_BEFORE = groups_AFTER;//same spot + public static final String administration = menu + ".administration"; + public static final String security = administration + ".security"; + public static final String users = security + ".users"; + public static final String roles = security + ".roles"; + public static final String systemConfiguration = administration + ".systemConfiguration"; + public static final String settings = systemConfiguration + ".settings"; + public static final String plugins = systemConfiguration + ".plugins"; + public static final String templates = systemConfiguration + ".templates"; + public static final String content = administration + ".content"; + public static final String contentProviders = content + ".contentProviders"; + public static final String repositories = content + ".repositories"; + public static final String highAvailability = administration + ".highAvailability"; + public static final String haServers = highAvailability + ".servers"; + public static final String agents = highAvailability + ".agents"; + public static final String affinityGroups = highAvailability + ".affinityGroups"; + public static final String partitionEvents = highAvailability + ".partitionEvents"; + public static final String reports = administration + ".reports"; + public static final String resourceVersionInventoryReport = reports + ".resourceVersionInventoryReport"; + public static final String downloads = administration + ".downloads"; + public static final String license = administration + ".license"; + public static final String administration_AFTER = administration + "_AFTER"; + //debug + public static final String debug_BEFORE = administration_AFTER;//same spot + public static final String debug = menu + ".debug"; + public static final String sqlInterface = debug + ".sqlInterface"; + public static final String jpqlHqlInterface = debug + ".jpqlHqlInterface"; + public static final String hibernate = debug + ".hibernate"; + public static final String administrativeControl = debug + ".administrativeControl"; + public static final String testEmail = debug + ".testEmail"; + public static final String testAgent = debug + ".testAgent"; + public static final String debug_AFTER = debug + "_AFTER"; + //help + public static final String help_BEFORE = debug_AFTER;//same spot + public static final String help = menu + ".help"; + public static final String onlineDocumentation = help + ".onlineDocumentation"; + public static final String openASupportCase = help + ".openASupportCase"; + public static final String about = help + ".about"; + public static final String help_AFTER = help + "_AFTER"; + //refresh + public static final String refresh = menu + ".refresh"; + public static final String refresh_BEFORE = refresh + "_BEFORE"; + public static final String stop = refresh + ".stop"; + public static final String refreshEvery1Minute = refresh + ".refreshEvery1Minute"; + public static final String refreshEvery5Minutes = refresh + ".refreshEvery5Minutes"; + public static final String refreshEvery10Minutes = refresh + ".refreshEvery10Minutes"; + public static final String refresh_AFTER = refresh + "_AFTER"; + //loggedInAs + public static final String loggedInAs_BEFORE = refresh_AFTER;//same spot + public static final String loggedInAs = menu + ".loggedInAs"; + public static final String editDetails = loggedInAs + ".editDetails"; + public static final String changePassword = loggedInAs + ".changePassword"; + public static final String logout = loggedInAs + ".logout"; + public static final String loggedInAs_AFTER = loggedInAs + "_AFTER"; + + public ExtensionPoints() { + } + + public String getMenu() { + return menu; + } + + public String getLogo() { + return logo; + } + + public String getLogoBefore() { + return logo_BEFORE; + } + + public String getLogoAfter() { + return logo_AFTER; + } + + public String getOverviewBefore() { + return overview_BEFORE; + } + + public String getOverview() { + return overview; + } + + public String getSubsystemviews() { + return subsystemViews; + } + + public String getConfigurationchanges() { + return configurationChanges; + } + + public String getSuspectmetrics() { + return suspectMetrics; + } + + public String getOperations() { + return operations; + } + + public String getAlerts() { + return alerts; + } + + public String getAlertdefinitions() { + return alertDefinitions; + } + + public String getAutodiscoveryqueue() { + return autoDiscoveryQueue; + } + + public String getDashboard() { + return dashboard; + } + + public String getOverviewAfter() { + return overview_AFTER; + } + + public String getDebugBefore() { + return debug_BEFORE; + } + + public String getDebug() { + return debug; + } + + public String getSqlinterface() { + return sqlInterface; + } + + public String getJpqlhqlinterface() { + return jpqlHqlInterface; + } + + public String getHibernate() { + return hibernate; + } + + public String getAdministrativecontrol() { + return administrativeControl; + } + + public String getTestemail() { + return testEmail; + } + + public String getTestagent() { + return testAgent; + } + + public String getDebugAfter() { + return debug_AFTER; + } + + public String getResourcesBefore() { + return resources_BEFORE; + } + + public String getResources() { + return resources; + } + + public String getPlatforms() { + return platforms; + } + + public String getServers() { + return servers; + } + + public String getServices() { + return services; + } + + public String getFavoriteresources() { + return favoriteResources; + } + + public String getRecentlyviewedresources() { + return recentlyViewedResources; + } + + public String getSearchresources() { + return searchResources; + } + + public String getResourcesAfter() { + return resources_AFTER; + } + + public String getGroupsBefore() { + return groups_BEFORE; + } + + public String getGroups() { + return groups; + } + + public String getCompatible() { + return compatible; + } + + public String getMixed() { + return mixed; + } + + public String getDefinitions() { + return definitions; + } + + public String getNewgroup() { + return newGroup; + } + + public String getNewgroupdefinition() { + return newGroupDefinition; + } + + public String getFavoritegroups() { + return favoriteGroups; + } + + public String getRecentlyviewedgroups() { + return recentlyViewedGroups; + } + + public String getSearchgroups() { + return searchGroups; + } + + public String getGroupsAfter() { + return groups_AFTER; + } + + public String getAdministrationBefore() { + return administration_BEFORE; + } + + public String getAdministration() { + return administration; + } + + public String getSecurity() { + return security; + } + + public String getUsers() { + return users; + } + + public String getRoles() { + return roles; + } + + public String getSystemconfiguration() { + return systemConfiguration; + } + + public String getSettings() { + return settings; + } + + public String getPlugins() { + return plugins; + } + + public String getTemplates() { + return templates; + } + + public String getContent() { + return content; + } + + public String getContentproviders() { + return contentProviders; + } + + public String getRepositories() { + return repositories; + } + + public String getHighavailability() { + return highAvailability; + } + + public String getHaservers() { + return haServers; + } + + public String getAgents() { + return agents; + } + + public String getAffinitygroups() { + return affinityGroups; + } + + public String getPartitionevents() { + return partitionEvents; + } + + public String getReports() { + return reports; + } + + public String getResourceversioninventoryreport() { + return resourceVersionInventoryReport; + } + + public String getDownloads() { + return downloads; + } + + public String getLicense() { + return license; + } + + public String getAdministrationAfter() { + return administration_AFTER; + } + + public String getHelpBefore() { + return help_BEFORE; + } + + public String getHelp() { + return help; + } + + public String getOnlinedocumentation() { + return onlineDocumentation; + } + + public String getOpenasupportcase() { + return openASupportCase; + } + + public String getAbout() { + return about; + } + + public String getHelpAfter() { + return help_AFTER; + } + + public String getRefreshBefore() { + return refresh_BEFORE; + } + + public String getRefresh() { + return refresh; + } + + public String getStop() { + return stop; + } + + public String getRefreshevery1minute() { + return refreshEvery1Minute; + } + + public String getRefreshevery5minutes() { + return refreshEvery5Minutes; + } + + public String getRefreshevery10minutes() { + return refreshEvery10Minutes; + } + + public String getRefreshAfter() { + return refresh_AFTER; + } + + public String getLoggedinasBefore() { + return loggedInAs_BEFORE; + } + + public String getLoggedinas() { + return loggedInAs; + } + + public String getEditdetails() { + return editDetails; + } + + public String getChangepassword() { + return changePassword; + } + + public String getLogout() { + return logout; + } + + public String getLoggedinasAfter() { + return loggedInAs_AFTER; + } + + //MENU:ExtensionPoints END + + //constants:end +} diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/perspectives/MenuItem.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/perspectives/MenuItem.java index ee7cffe..2ba210e 100644 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/perspectives/MenuItem.java +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/perspectives/MenuItem.java @@ -18,32 +18,43 @@ */ package org.rhq.enterprise.gui.perspectives;
-/** Features for each menu item. +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +/** Features for each menu item. A menu item can be as simple as a logo, + * menu separator bar or as complicated as a root menu item with an arbitrary + * amount of child menuitems. * * @author Simeon Pinder * */ public class MenuItem {
- //constants:begin Extension point map - public static String menu = "menu"; - public static String menu_BEGIN = "menu.BEGIN"; - public static String logo = "menu.logo"; - - public static String overview_BEFORE = "menu.overview_BEFORE"; - public static String overview = "menu.overview"; - - public static String resources_BEFORE = "menu.resources_BEFORE"; - public static String resources = "menu.resources"; - - //constants:end - + //url to icon image private String iconUrl = ""; + //width of icon private int iconWidth = 0; + //height of icon private int iconHeight = 0; + //url to direct user to onclick private String url = ""; + //The label to be displayed for this menu item private String name = ""; + //whether this menu item is to be enabled/visible private boolean rendered = true; + //whether this menuItem represent a menu separator + private boolean isMenuSeparator = false; + //includes N child MenuItem instances + private List<MenuItem> childMenuItems = new ArrayList<MenuItem>(); + //Stores a unique reference to the ExtensionPoint key for this item. + private String extensionKey = ""; + //whether this menuItem(relevant to top menu items only) is aligned from far left + private boolean alignLeft = true; + + //default no args. To satisfy basic bean functionality. + MenuItem() { + }
MenuItem(String iconUrl, String url, String name) { this.iconUrl = iconUrl; @@ -51,6 +62,13 @@ public class MenuItem { this.name = name; }
+ MenuItem(String iconUrl, String url, String name, List<MenuItem> children, String key, HashMap<String, MenuItem> map) { + this(iconUrl, url, name); + children.add(this); + map.put(key, this); + this.extensionKey = key; + } + public String getIconUrl() { return iconUrl; } @@ -98,4 +116,36 @@ public class MenuItem { public void setIconWidth(int iconWidth) { this.iconWidth = iconWidth; } + + public boolean isMenuSeparator() { + return isMenuSeparator; + } + + public void setMenuSeparator(boolean isMenuSeparator) { + this.isMenuSeparator = isMenuSeparator; + } + + public void setChildMenuItems(List<MenuItem> childMenuItems) { + this.childMenuItems = childMenuItems; + } + + public List<MenuItem> getChildMenuItems() { + return childMenuItems; + } + + public String getExtensionKey() { + return extensionKey; + } + + public void setExtensionKey(String extensionKey) { + this.extensionKey = extensionKey; + } + + public boolean isAlignLeft() { + return alignLeft; + } + + public void setAlignLeft(boolean alignLeft) { + this.alignLeft = alignLeft; + } } diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/perspectives/PerspectivesMenuUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/perspectives/PerspectivesMenuUIBean.java index 66560a0..308ad2b 100644 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/perspectives/PerspectivesMenuUIBean.java +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/perspectives/PerspectivesMenuUIBean.java @@ -19,8 +19,10 @@ package org.rhq.enterprise.gui.perspectives;
import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.List; +import java.util.Set;
/** * Bean dynamically provides menu information used by menu.xhtml. This bean should be viewed @@ -31,435 +33,293 @@ import java.util.List; * */ public class PerspectivesMenuUIBean { + + //Stores reference to the root menu item + private MenuItem CoreMenuBar = null; + /* Stores all mapped MenuItem information */ private HashMap<String, MenuItem> menuDefinition = new HashMap<String, MenuItem>();
- /*===== LOGO TO HOME PAGE =====*/ - private MenuItem logo = new MenuItem("/images/JBossLogo_small.png", "", ""); - { - logo.setIconHeight(21); - logo.setIconWidth(37); - menuDefinition.put(MenuItem.logo, logo); - } + // provides MenuItem mapping lookup via bean accessor + private MenuItem extensionPoint = null;
- /*===== OVERVIEW =====*/ - private MenuItem overview = new MenuItem("", "", "Overview"); - { - menuDefinition.put(MenuItem.overview, overview); - } - /*===== Overview.BEFORE extension pt. ============= */ - private MenuItem overviewBefore = new MenuItem("", "", ""); - { - overviewBefore.setRendered(false);//disable to start - menuDefinition.put(MenuItem.overview_BEFORE, overviewBefore); - } + {//initialization block + //Root of core menu + MenuItem menu = new MenuItem(); + menu.setExtensionKey(ExtensionPoints.menu); + CoreMenuBar = menu; + menuDefinition.put(ExtensionPoints.menu, menu);
- private List<MenuItem> overviewBeforeItems = new ArrayList<MenuItem>(); + List<MenuItem> attachPoints = menu.getChildMenuItems();
- /****** Overview > SYSTEM VIEWS ******/ - private MenuItem subsystemViews = new MenuItem("", "", "Subsystem Views"); - private List<MenuItem> subsystemMenuItems = new ArrayList<MenuItem>(); - {//initialization block - //SubsystemView menu items - String[] subsystemCategories = { "Configure", "Monitor_failed", "Operation", "Flag_blue", "Flag_grey" }; - String[] subsystemPages = { "configurationUpdate", "oobHistory", "operationHistory", "alertHistory", - "alertDefinitions" }; - String[] subsystemNames = { "Configuration Changes", "Suspect Metrics", "Operations", "Alerts", - "Alert Definitions" }; - for (int i = 0; i < subsystemPages.length; i++) { - subsystemMenuItems.add(new MenuItem("/images/icons/" + subsystemCategories[i] + "_16.png",//icon url - "/rhq/subsystem/" + subsystemPages[i] + ".xhtml", // menu item url - subsystemNames[i])); //menu item name + /*===== LOGO TO HOME PAGE =====*/ + MenuItem logoBefore = new MenuItem("", "", "", menu.getChildMenuItems(), ExtensionPoints.logo_BEFORE, + menuDefinition); + logoBefore.setRendered(false); + MenuItem logo = new MenuItem("/images/JBossLogo_small.png", "", "", menu.getChildMenuItems(), + ExtensionPoints.logo, menuDefinition); + logo.setIconHeight(21); + logo.setIconWidth(37); + MenuItem logoAfter = new MenuItem("", "", "", menu.getChildMenuItems(), ExtensionPoints.logo_AFTER, + menuDefinition); + logoAfter.setRendered(false); + /*===== OVERVIEW =====*/ + MenuItem overview = new MenuItem("", "", "Overview", menu.getChildMenuItems(), ExtensionPoints.overview, + menuDefinition); + /*===== Overview.BEFORE extension pt. Ignore same as Logo.after ============= */ + /*===== OVERVIEW.AFTER =====*/ + MenuItem overviewAfter = new MenuItem("", "", "", menu.getChildMenuItems(), ExtensionPoints.overview_AFTER, + menuDefinition); + overviewAfter.setRendered(false); + + /****** Overview > SYSTEM VIEWS ******/ + MenuItem subsystemViews = new MenuItem("", "", "Subsystem Views", overview.getChildMenuItems(), + ExtensionPoints.subsystemViews, menuDefinition); + List<MenuItem> subsystemMenuItems = new ArrayList<MenuItem>(); + { + //SubsystemView menu items + String[] imageNames = { "Configure", "Monitor_failed", "Operation", "Flag_blue", "Flag_grey" }; + String[] pageNames = { "configurationUpdate", "oobHistory", "operationHistory", "alertHistory", + "alertDefinitions" }; + String[] menuNames = { "Configuration Changes", "Suspect Metrics", "Operations", "Alerts", + "Alert Definitions" }; + for (int i = 0; i < imageNames.length; i++) { + String extKey = null; + String name = menuNames[i]; + if (name.indexOf("Configuration") > -1) { + extKey = ExtensionPoints.configurationChanges; + } + if (name.indexOf("Suspect") > -1) { + extKey = ExtensionPoints.suspectMetrics; + } + if (name.indexOf("Operations") > -1) { + extKey = ExtensionPoints.operations; + } + if (name.indexOf("Alerts") > -1) { + extKey = ExtensionPoints.alerts; + } + if (name.indexOf("Alert") > -1) { + extKey = ExtensionPoints.alertDefinitions; + } + MenuItem m = new MenuItem("/images/icons/" + imageNames[i] + "_16.png",//icon url + "/rhq/subsystem/" + pageNames[i] + ".xhtml", // menu item url + menuNames[i], subsystemViews.getChildMenuItems(), extKey, menuDefinition); //menu item name + } } - } - /* ***** Overview > AUTO-DISCOVERY QUEUE ***** */ - private MenuItem autoDiscoveryQueue = new MenuItem("", "/rhq/discovery/queue.xhtml", "Auto Discovery Queue");; - - /* ***** Overview > DASHBOARD ***** */ - private MenuItem dashboard = new MenuItem("", "/Dashboard.do", "Dashboard"); - - /* ===== RESOURCES ===== */ - private MenuItem resources = new MenuItem("", "", "Resources"); - - /* Resources: Platform */ - private MenuItem resourcesPlatform = null; - { - resourcesPlatform = new MenuItem("/images/icons/Platform_up_16.png", - "/ResourceHub.do?resourceCategory=PLATFORM", ""); - } - /* Resources: Server */ - private MenuItem resourcesServer = null; - { - resourcesServer = new MenuItem("/images/icons/Server_up_16.png", "/ResourceHub.do?resourceCategory=SERVER", ""); - } - - /* Resources: Service */ - private MenuItem resourcesService = null; - { - resourcesService = new MenuItem("/images/icons/Service_up_16.png", "/ResourceHub.do?resourceCategory=SERVICE", - ""); - } - - private MenuItem resourcesFavorite = new MenuItem("/images/icons/Favorite_16.png", "", "Favorite Resources"); - private MenuItem resourcesRecentlyViewed = new MenuItem("/images/icons/History_16.png", "", - "Recently Viewed Resources"); - //TODO: enable? - private MenuItem resourcesSearch = new MenuItem("/images/icons/History_16.png", "", "Search: "); - - /* ===== GROUPS ===== */ - private MenuItem groups = new MenuItem("", "", "Groups"); - private MenuItem groupsCompatible = new MenuItem("/images/icons/Cluster_up_16.png", - "/GroupHub.do?groupCategory=COMPATIBLE", ""); - private MenuItem groupsMixed = new MenuItem("/images/icons/Group_up_16.png", "/GroupHub.do?groupCategory=MIXED", ""); - private MenuItem groupsDefinitions = new MenuItem("/images/GroupDefinition_16.png", - "/rhq/definition/group/list.xhtml", ""); - private MenuItem groupsNewResource = new MenuItem("", "/resource/group/Inventory.do?mode=new", ""); - private MenuItem groupsNewDefinition = new MenuItem("", "/rhq/definition/group/new.xhtml", ""); - private MenuItem groupsFavorite = new MenuItem("/images/icons/Favorite_16.png", "", "Favorite Groups"); - private MenuItem groupsRecentlyViewed = new MenuItem("/images/icons/History_16.png", "", "Recently Viewed Groups"); - - /* ===== ADMINISTRATION ===== */ - private MenuItem security = new MenuItem("", "", "Security"); - private MenuItem securityUsers = new MenuItem("", "/admin/user/UserAdmin.do?mode=list", "Users"); - private MenuItem securityRoles = new MenuItem("", "/admin/role/RoleAdmin.do?mode=list", "Roles"); - private MenuItem sysconfig = new MenuItem("", "", "System Configuration"); - private MenuItem sysconfigSettings = new MenuItem("", "/admin/config/Config.do?mode=edit", "Settings"); - private MenuItem sysconfigPlugins = new MenuItem("", "/rhq/admin/plugin/plugin-list.xhtml", "Plugins"); - private MenuItem sysconfigTemplates = new MenuItem("", - "/admin/config/EditDefaults.do?mode=monitor&viewMode=all", "Templates"); - private MenuItem content = new MenuItem("", "", "Content"); - private MenuItem contentContentProviders = new MenuItem("", "/rhq/content/listContentProviders.xhtml", - "Content Providers"); - private MenuItem contentRepositories = new MenuItem("", "/rhq/content/listRepos.xhtml", "Repositories"); - private MenuItem ha = new MenuItem("", "", "High Availability"); - private MenuItem haServers = new MenuItem("", "/rhq/ha/listServers.xhtml", "Servers"); - private MenuItem haAgents = new MenuItem("", "/rhq/ha/listAgents.xhtml", "Agents"); - private MenuItem haAffinityGroups = new MenuItem("", "/rhq/ha/listAffinityGroups.xhtml", "Affinity Groups"); - private MenuItem haPartitionEvents = new MenuItem("", "/rhq/ha/listPartitionEvents.xhtml", "Partition Events"); - private MenuItem reports = new MenuItem("", "", "Reports"); - private MenuItem reportsResourceVersion = new MenuItem("", "/rhq/admin/report/resourceInstallReport.xhtml", - "Resource Version Inventory Report"); - private MenuItem downloads = new MenuItem("/images/icons/Save_16.png", "/rhq/admin/downloads.xhtml", "Downloads"); - private MenuItem license = new MenuItem("", "/admin/license/LicenseAdmin.do?mode=view", "License"); - - public List<MenuItem> getSubsystemMenuItems() { - return subsystemMenuItems; - } - - public void setSubsystemMenuItems(List<MenuItem> subsystemMenuItems) { - this.subsystemMenuItems = subsystemMenuItems; - } - - public MenuItem getAutoDiscoveryQueue() { - return autoDiscoveryQueue; - } - - public void setAutoDiscoveryQueue(MenuItem autoDiscoveryQueue) { - this.autoDiscoveryQueue = autoDiscoveryQueue; - } - - public MenuItem getDashboard() { - return dashboard; - } - - public void setDashboard(MenuItem dashboard) { - this.dashboard = dashboard; - } - - public MenuItem getResourcesPlatform() { - return resourcesPlatform; - } - - public void setResourcesPlatform(MenuItem resourcesPlatform) { - this.resourcesPlatform = resourcesPlatform; - } - - public MenuItem getResourcesServer() { - return resourcesServer; - } - - public void setResourcesServer(MenuItem resourcesServer) { - this.resourcesServer = resourcesServer; - } - - public MenuItem getResourcesService() { - return resourcesService; - } - - public void setResourcesService(MenuItem resourcesService) { - this.resourcesService = resourcesService; - } - - public MenuItem getGroups() { - return groups; - } - - public void setGroups(MenuItem groups) { - this.groups = groups; - } - - public MenuItem getGroupsCompatible() { - return groupsCompatible; - } - - public void setGroupsCompatible(MenuItem groupsCompatible) { - this.groupsCompatible = groupsCompatible; - } - - public MenuItem getGroupsMixed() { - return groupsMixed; - } - - public void setGroupsMixed(MenuItem groupsMixed) { - this.groupsMixed = groupsMixed; - } - - public MenuItem getGroupsDefinitions() { - return groupsDefinitions; - } - - public void setGroupsDefinitions(MenuItem groupsDefinitions) { - this.groupsDefinitions = groupsDefinitions; - } - - public MenuItem getGroupsNewResource() { - return groupsNewResource; - } - - public void setGroupsNewResource(MenuItem groupsNewResource) { - this.groupsNewResource = groupsNewResource; - } - - public MenuItem getGroupsNewDefinition() { - return groupsNewDefinition; - } - - public void setGroupsNewDefinition(MenuItem groupsNewDefinition) { - this.groupsNewDefinition = groupsNewDefinition; - } - - public MenuItem getLogo() { - return logo; - } - - public void setLogo(MenuItem logo) { - this.logo = logo; - } - - public MenuItem getOverview() { - return overview; - } - - public void setOverview(MenuItem overview) { - this.overview = overview; - } - - public MenuItem getSubsystemViews() { - return subsystemViews; - } - - public void setSubsystemViews(MenuItem subsystemViews) { - this.subsystemViews = subsystemViews; - } - - public MenuItem getResources() { - return resources; - } - - public void setResources(MenuItem resources) { - this.resources = resources; - } - - public MenuItem getResourcesFavorite() { - return resourcesFavorite; - } - - public void setResourcesFavorite(MenuItem resourcesFavorite) { - this.resourcesFavorite = resourcesFavorite; - } - - public MenuItem getResourcesRecentlyViewed() { - return resourcesRecentlyViewed; - } - - public void setResourcesRecentlyViewed(MenuItem resourcesRecentlyViewed) { - this.resourcesRecentlyViewed = resourcesRecentlyViewed; - } - - public MenuItem getGroupsFavorite() { - return groupsFavorite; - } - - public void setGroupsFavorite(MenuItem groupsFavorite) { - this.groupsFavorite = groupsFavorite; - } - - public MenuItem getGroupsRecentlyViewed() { - return groupsRecentlyViewed; - } - - public void setGroupsRecentlyViewed(MenuItem groupsRecentlyViewed) { - this.groupsRecentlyViewed = groupsRecentlyViewed; - } - - public MenuItem getResourcesSearch() { - return resourcesSearch; - } - - public void setResourcesSearch(MenuItem resourcesSearch) { - this.resourcesSearch = resourcesSearch; - } - - public MenuItem getSecurity() { - return security; - } - - public void setSecurity(MenuItem security) { - this.security = security; - } - - public MenuItem getSecurityUsers() { - return securityUsers; - } - - public void setSecurityUsers(MenuItem securityUsers) { - this.securityUsers = securityUsers; - } - - public MenuItem getSecurityRoles() { - return securityRoles; - } - - public void setSecurityRoles(MenuItem securityRoles) { - this.securityRoles = securityRoles; - } - - public MenuItem getSysconfig() { - return sysconfig; - } - - public void setSysconfig(MenuItem sysconfig) { - this.sysconfig = sysconfig; - } - - public MenuItem getSysconfigSettings() { - return sysconfigSettings; - } - - public void setSysconfigSettings(MenuItem sysconfigSettings) { - this.sysconfigSettings = sysconfigSettings; - } - - public MenuItem getSysconfigPlugins() { - return sysconfigPlugins; - } - - public void setSysconfigPlugins(MenuItem sysconfigPlugins) { - this.sysconfigPlugins = sysconfigPlugins; - } - - public MenuItem getSysconfigTemplates() { - return sysconfigTemplates; - } - - public void setSysconfigTemplates(MenuItem sysconfigTemplates) { - this.sysconfigTemplates = sysconfigTemplates; - } - - public MenuItem getContent() { - return content; - } - - public void setContent(MenuItem content) { - this.content = content; - } - - public MenuItem getContentContentProviders() { - return contentContentProviders; - } - - public void setContentContentProviders(MenuItem contentContentProviders) { - this.contentContentProviders = contentContentProviders; - } - - public MenuItem getContentRepositories() { - return contentRepositories; - } - - public void setContentRepositories(MenuItem contentRepositories) { - this.contentRepositories = contentRepositories; - } - - public MenuItem getHa() { - return ha; - } - - public void setHa(MenuItem ha) { - this.ha = ha; - } - - public MenuItem getHaServers() { - return haServers; - } - - public void setHaServers(MenuItem haServers) { - this.haServers = haServers; - } - - public MenuItem getHaAgents() { - return haAgents; - } - - public void setHaAgents(MenuItem haAgents) { - this.haAgents = haAgents; - } - - public MenuItem getHaAffinityGroups() { - return haAffinityGroups; - } - - public void setHaAffinityGroups(MenuItem haAffinityGroups) { - this.haAffinityGroups = haAffinityGroups; - } - - public MenuItem getHaPartitionEvents() { - return haPartitionEvents; - } - - public void setHaPartitionEvents(MenuItem haPartitionEvents) { - this.haPartitionEvents = haPartitionEvents; - } - - public MenuItem getReports() { - return reports; - } - - public void setReports(MenuItem reports) { - this.reports = reports; - } - - public MenuItem getReportsResourceVersion() { - return reportsResourceVersion; - } - - public void setReportsResourceVersion(MenuItem reportsResourceVersion) { - this.reportsResourceVersion = reportsResourceVersion; - } - - public MenuItem getDownloads() { - return downloads; - } - - public void setDownloads(MenuItem downloads) { - this.downloads = downloads; - } - - public MenuItem getLicense() { - return license; - } - - public void setLicense(MenuItem license) { - this.license = license; + /* ***** Overview > AUTO-DISCOVERY QUEUE ***** */ + MenuItem autoDiscoveryQueue = new MenuItem("", "/rhq/discovery/queue.xhtml", "Auto Discovery Queue", overview + .getChildMenuItems(), ExtensionPoints.autoDiscoveryQueue, menuDefinition); + + /* ***** Overview > DASHBOARD ***** */ + MenuItem dashboard = new MenuItem("", "/Dashboard.do", "Dashboard", overview.getChildMenuItems(), + ExtensionPoints.dashboard, menuDefinition); + + /* ===== RESOURCES ===== */ + MenuItem resources = new MenuItem("", "", "Resources", menu.getChildMenuItems(), ExtensionPoints.resources, + menuDefinition); + /*===== RESOURCES.BEFORE extension pt. Ignore same as Overvie.after ============= */ + /*===== Resources.AFTER =====*/ + MenuItem resourcesAfter = new MenuItem("", "", "", menu.getChildMenuItems(), ExtensionPoints.resources_AFTER, + menuDefinition); + resourcesAfter.setRendered(false); + + /* Resources: Platform */ + MenuItem resourcesPlatform = new MenuItem("/images/icons/Platform_up_16.png", + "/ResourceHub.do?resourceCategory=PLATFORM", "", resources.getChildMenuItems(), ExtensionPoints.platforms, + menuDefinition); + /* Resources: Server */ + MenuItem resourcesServer = new MenuItem("/images/icons/Server_up_16.png", + "/ResourceHub.do?resourceCategory=SERVER", "", resources.getChildMenuItems(), ExtensionPoints.servers, + menuDefinition); + /* Resources: Service */ + MenuItem resourcesService = new MenuItem("/images/icons/Service_up_16.png", + "/ResourceHub.do?resourceCategory=SERVICE", "", resources.getChildMenuItems(), ExtensionPoints.services, + menuDefinition); + // Menu bar separator + MenuItem separator = new MenuItem("", "", ""); + separator.setMenuSeparator(true); + resources.getChildMenuItems().add(separator); + /* Resources: Favorites */ + MenuItem resourcesFavorite = new MenuItem("/images/icons/Favorite_16.png", "", "Favorite Resources", resources + .getChildMenuItems(), ExtensionPoints.favoriteResources, menuDefinition); + /* Resources: Recently Viewed */ + MenuItem resourcesRecentlyViewed = new MenuItem("/images/icons/History_16.png", "", + "Recently Viewed Resources", resources.getChildMenuItems(), ExtensionPoints.recentlyViewedResources, + menuDefinition); + //ADD Menu bar separator + resources.getChildMenuItems().add(separator); + /* Resources: Search */ + MenuItem resourcesSearch = new MenuItem("", "", "Search: ", resources.getChildMenuItems(), + ExtensionPoints.searchResources, menuDefinition); + + /* ===== GROUPS ===== */ + MenuItem groups = new MenuItem("", "", "Groups", menu.getChildMenuItems(), ExtensionPoints.groups, + menuDefinition); + /*===== Groups.BEFORE extension pt. Ignore same as Overvie.after ============= */ + /*===== Groups.AFTER =====*/ + MenuItem groupsAfter = new MenuItem("", "", "", menu.getChildMenuItems(), ExtensionPoints.groups_AFTER, + menuDefinition); + groupsAfter.setRendered(false); + /* GROUPS: Compatible */ + MenuItem groupsCompatible = new MenuItem("/images/icons/Cluster_up_16.png", + "/GroupHub.do?groupCategory=COMPATIBLE", "", groups.getChildMenuItems(), ExtensionPoints.compatible, + menuDefinition); + /* GROUPS: Mixed */ + MenuItem groupsMixed = new MenuItem("/images/icons/Group_up_16.png", "/GroupHub.do?groupCategory=MIXED", "", + groups.getChildMenuItems(), ExtensionPoints.mixed, menuDefinition); + /* GROUPS: Group Definitions */ + MenuItem groupsDefinitions = new MenuItem("/images/GroupDefinition_16.png", "/rhq/definition/group/list.xhtml", + "", groups.getChildMenuItems(), ExtensionPoints.definitions, menuDefinition); + /* GROUPS: New Group */ + MenuItem groupsNewResource = new MenuItem("", "/resource/group/Inventory.do?mode=new", "", groups + .getChildMenuItems(), ExtensionPoints.newGroup, menuDefinition); + /* GROUPS: New Group Definition */ + MenuItem groupsNewDefinition = new MenuItem("", "/rhq/definition/group/new.xhtml", "", groups + .getChildMenuItems(), ExtensionPoints.newGroupDefinition, menuDefinition); + // Menu bar separator + groups.getChildMenuItems().add(separator); + + /* GROUPS: Favorites */ + MenuItem groupsFavorite = new MenuItem("/images/icons/Favorite_16.png", "", "Favorite Groups", groups + .getChildMenuItems(), ExtensionPoints.favoriteGroups, menuDefinition); + /* GROUPS: Recently Viewed */ + MenuItem groupsRecentlyViewed = new MenuItem("/images/icons/History_16.png", "", "Recently Viewed Groups", + groups.getChildMenuItems(), ExtensionPoints.recentlyViewedGroups, menuDefinition); + // Menu bar separator + groups.getChildMenuItems().add(separator); + /* GROUPS: Recently Viewed */ + MenuItem groupsSearch = new MenuItem("", "", "Search", groups.getChildMenuItems(), + ExtensionPoints.searchGroups, menuDefinition); + + /* ===== ADMINISTRATION ===== */ + MenuItem administration = new MenuItem("", "", "Administration", menu.getChildMenuItems(), + ExtensionPoints.administration, menuDefinition); + /*===== ADMINISTRATION.BEFORE extension pt. Ignore same as Groups.after ============= */ + /*===== ADMINISTRATION.AFTER =====*/ + MenuItem administrationAfter = new MenuItem("", "", "", menu.getChildMenuItems(), + ExtensionPoints.administration_AFTER, menuDefinition); + administrationAfter.setRendered(false); + MenuItem security = new MenuItem("", "", "Security", administration.getChildMenuItems(), + ExtensionPoints.security, menuDefinition); + MenuItem securityUsers = new MenuItem("", "/admin/user/UserAdmin.do?mode=list", "Users", security + .getChildMenuItems(), ExtensionPoints.users, menuDefinition); + MenuItem securityRoles = new MenuItem("", "/admin/role/RoleAdmin.do?mode=list", "Roles", security + .getChildMenuItems(), ExtensionPoints.roles, menuDefinition); + MenuItem sysconfig = new MenuItem("", "", "System Configuration", administration.getChildMenuItems(), + ExtensionPoints.systemConfiguration, menuDefinition); + MenuItem sysconfigSettings = new MenuItem("", "/admin/config/Config.do?mode=edit", "Settings", sysconfig + .getChildMenuItems(), ExtensionPoints.settings, menuDefinition); + MenuItem sysconfigPlugins = new MenuItem("", "/rhq/admin/plugin/plugin-list.xhtml", "Plugins", sysconfig + .getChildMenuItems(), ExtensionPoints.plugins, menuDefinition); + MenuItem sysconfigTemplates = new MenuItem("", "/admin/config/EditDefaults.do?mode=monitor&viewMode=all", + "Templates", sysconfig.getChildMenuItems(), ExtensionPoints.templates, menuDefinition); + MenuItem content = new MenuItem("", "", "Content", administration.getChildMenuItems(), ExtensionPoints.content, + menuDefinition); + MenuItem contentContentProviders = new MenuItem("", "/rhq/content/listContentProviders.xhtml", + "Content Providers", content.getChildMenuItems(), ExtensionPoints.contentProviders, menuDefinition); + MenuItem contentRepositories = new MenuItem("", "/rhq/content/listRepos.xhtml", "Repositories", content + .getChildMenuItems(), ExtensionPoints.repositories, menuDefinition); + MenuItem ha = new MenuItem("", "", "High Availability", administration.getChildMenuItems(), + ExtensionPoints.highAvailability, menuDefinition); + MenuItem haServers = new MenuItem("", "/rhq/ha/listServers.xhtml", "Servers", ha.getChildMenuItems(), + ExtensionPoints.haServers, menuDefinition); + MenuItem haAgents = new MenuItem("", "/rhq/ha/listAgents.xhtml", "Agents", ha.getChildMenuItems(), + ExtensionPoints.agents, menuDefinition); + MenuItem haAffinityGroups = new MenuItem("", "/rhq/ha/listAffinityGroups.xhtml", "Affinity Groups", ha + .getChildMenuItems(), ExtensionPoints.affinityGroups, menuDefinition); + MenuItem haPartitionEvents = new MenuItem("", "/rhq/ha/listPartitionEvents.xhtml", "Partition Events", ha + .getChildMenuItems(), ExtensionPoints.partitionEvents, menuDefinition); + MenuItem reports = new MenuItem("", "", "Reports", administration.getChildMenuItems(), ExtensionPoints.reports, + menuDefinition); + MenuItem reportsResourceVersion = new MenuItem("", "/rhq/admin/report/resourceInstallReport.xhtml", + "Resource Version Inventory Report", reports.getChildMenuItems(), + ExtensionPoints.resourceVersionInventoryReport, menuDefinition); + MenuItem downloads = new MenuItem("/images/icons/Save_16.png", "/rhq/admin/downloads.xhtml", "Downloads", + administration.getChildMenuItems(), ExtensionPoints.downloads, menuDefinition); + MenuItem license = new MenuItem("", "/admin/license/LicenseAdmin.do?mode=view", "License", administration + .getChildMenuItems(), ExtensionPoints.license, menuDefinition); + + //* ------------- DEBUG ------------------- *// + /*===== DEBUG.BEFORE extension pt. Ignore same as Administration.after ============= */ + MenuItem debug = new MenuItem("", "", "Debug", menu.getChildMenuItems(), ExtensionPoints.debug, menuDefinition); + MenuItem sqlInterface = new MenuItem("", "/admin/test/sql.jsp", "SQL Interface", debug.getChildMenuItems(), + ExtensionPoints.sqlInterface, menuDefinition); + MenuItem jpqlHibernateInterface = new MenuItem("", "/admin/test/hibernate.jsp", "JPQL/HQL Interface", debug + .getChildMenuItems(), ExtensionPoints.jpqlHqlInterface, menuDefinition); + MenuItem hibernate = new MenuItem("", "/admin/test/browser.jsp", "Hibernate Entity Browser", debug + .getChildMenuItems(), ExtensionPoints.hibernate, menuDefinition); + MenuItem administrativeControl = new MenuItem("", "/admin/test/control.jsp", "Administrative Control", debug + .getChildMenuItems(), ExtensionPoints.administrativeControl, menuDefinition); + MenuItem testEmail = new MenuItem("", "/admin/test/email.jsp", "Test Email Configuration", debug + .getChildMenuItems(), ExtensionPoints.testEmail, menuDefinition); + MenuItem testAgent = new MenuItem("", "/admin/test/agent.jsp", "Test Agent Communications", debug + .getChildMenuItems(), ExtensionPoints.testAgent, menuDefinition); + /*===== DEBUG.AFTER =====*/ + MenuItem debugAfter = new MenuItem("", "", "", menu.getChildMenuItems(), ExtensionPoints.debug_AFTER, + menuDefinition); + debugAfter.setRendered(false); + + //* ------------- HELP ------------------- *// + /*===== HELP.BEFORE extension pt. Ignore same as Administration.after ============= */ + MenuItem help = new MenuItem("", "", "Help", attachPoints, ExtensionPoints.help, menuDefinition); + /*===== HELP.AFTER =====*/ + MenuItem helpAfter = new MenuItem("", "", "", attachPoints, ExtensionPoints.help_AFTER, menuDefinition); + helpAfter.setRendered(false); + MenuItem onlineDoc = new MenuItem("", "http://www.redhat.com/docs/en-US/JBoss_ON/", "Online Documentation", + help.getChildMenuItems(), ExtensionPoints.help, menuDefinition); + MenuItem support = new MenuItem("", "https://support.redhat.com/jbossnetwork/restricted/addCase.html", + "Open a Support Case", help.getChildMenuItems(), ExtensionPoints.openASupportCase, menuDefinition); + // Menu bar separator + help.getChildMenuItems().add(separator); + MenuItem about = new MenuItem("/images/icons/availability_grey_16.png", "", "", help.getChildMenuItems(), + ExtensionPoints.about, menuDefinition); + + //* ------------- REFRESH ------------------- *// + /*===== REFRESH.BEFORE extension pt. ============= */ + MenuItem refreshBefore = new MenuItem("", "", "", menu.getChildMenuItems(), ExtensionPoints.refresh_BEFORE, + menuDefinition); + refreshBefore.setRendered(false); + refreshBefore.setAlignLeft(false); + MenuItem refresh = new MenuItem("", "", "", attachPoints, ExtensionPoints.refresh, menuDefinition); + refresh.setAlignLeft(false); + /*===== HELP.AFTER =====*/ + MenuItem refreshAfter = new MenuItem("", "", "", attachPoints, ExtensionPoints.refresh_AFTER, menuDefinition); + refreshAfter.setRendered(false); + refreshAfter.setAlignLeft(false); + MenuItem stop = new MenuItem("", "", "Stop", refresh.getChildMenuItems(), ExtensionPoints.stop, menuDefinition); + MenuItem refresh1 = new MenuItem("", "", "Refresh every 1 minute", refresh.getChildMenuItems(), + ExtensionPoints.refreshEvery1Minute, menuDefinition); + MenuItem refresh5 = new MenuItem("", "", "Refresh every 5 minutes", refresh.getChildMenuItems(), + ExtensionPoints.refreshEvery5Minutes, menuDefinition); + MenuItem refresh10 = new MenuItem("", "", "Refresh every 10 minutes", refresh.getChildMenuItems(), + ExtensionPoints.refreshEvery10Minutes, menuDefinition); + + //* ------------- IS LOGGED IN ------------------- *// + /*===== IS LOGGED IN.BEFORE extension pt. Ignore same as refresh.after ============= */ + MenuItem loggedIn = new MenuItem("", "", "", attachPoints, ExtensionPoints.loggedInAs, menuDefinition); + loggedIn.setAlignLeft(false); + /*===== IS LOGGED IN.AFTER =====*/ + MenuItem loggedInAfter = new MenuItem("", "", "", attachPoints, ExtensionPoints.loggedInAs_AFTER, + menuDefinition); + loggedInAfter.setRendered(false); + loggedInAfter.setAlignLeft(false); + MenuItem edit = new MenuItem("", "", "Edit Details", loggedIn.getChildMenuItems(), ExtensionPoints.stop, + menuDefinition); + MenuItem change = new MenuItem("", "", "Change Password", loggedIn.getChildMenuItems(), + ExtensionPoints.refreshEvery1Minute, menuDefinition); + // Menu bar separator + loggedIn.getChildMenuItems().add(separator); + MenuItem logout = new MenuItem("", "/Logout.do", "Logout", loggedIn.getChildMenuItems(), + ExtensionPoints.refreshEvery5Minutes, menuDefinition); + + } + + public MenuItem getCoreMenuBar() { + return CoreMenuBar; + } + + public void setCoreMenuBar(MenuItem coreMenuBar) { + CoreMenuBar = coreMenuBar; }
public HashMap<String, MenuItem> getMenuDefinition() { @@ -470,19 +330,35 @@ public class PerspectivesMenuUIBean { this.menuDefinition = menuDefinition; }
- public MenuItem getOverviewBefore() { - return overviewBefore; - } - - public void setOverviewBefore(MenuItem overviewBefore) { - this.overviewBefore = overviewBefore; - } - - public List<MenuItem> getOverviewBeforeItems() { - return overviewBeforeItems; + public static void main(String[] args) { + PerspectivesMenuUIBean bean = new PerspectivesMenuUIBean(); + // System.out.println("Bean:" + bean); + MenuItem coreMenu = bean.getCoreMenuBar(); + HashMap<String, MenuItem> definition = bean.getMenuDefinition(); + //iterate over the coreMenu recursively + recurse(coreMenu, "(TOP)"); + //iterate over the map and display the values + Set<String> keys = definition.keySet(); + ArrayList<String> list = new ArrayList<String>(keys); + Collections.sort(list); + System.out.println("\n Key listing [" + keys.size() + " item(s)] \n"); + for (String key : list) { + System.out.println("KEY:" + key + "=" + definition.get(key)); + } }
- public void setOverviewBeforeItems(List<MenuItem> overviewBeforeItems) { - this.overviewBeforeItems = overviewBeforeItems; + private static void recurse(MenuItem menu, String prefix) { + if ((menu != null)) { + //base case: leaf + if (menu.getChildMenuItems().size() == 0) { + System.out.println(prefix + "#" + menu.getName() + ":" + menu.getExtensionKey() + ":"); + } else { + System.out.println(prefix + "[DIR-(" + menu.getChildMenuItems().size() + ")]" + menu.getName() + ":" + + menu.getExtensionKey() + ":"); + for (MenuItem child : menu.getChildMenuItems()) { + recurse(child, prefix + "\t"); + } + } + } } } diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-managed-beans/perspectives-beans.xml b/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-managed-beans/perspectives-beans.xml index 53c0d31..a8ab990 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-managed-beans/perspectives-beans.xml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-managed-beans/perspectives-beans.xml @@ -10,5 +10,10 @@ <managed-bean-class>org.rhq.enterprise.gui.perspectives.PerspectivesMenuUIBean</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean> - + <managed-bean> + <managed-bean-name>ExtensionPoints</managed-bean-name> + <managed-bean-class>org.rhq.enterprise.gui.perspectives.ExtensionPoints</managed-bean-class> + <managed-bean-scope>request</managed-bean-scope> + </managed-bean> + </faces-config> \ No newline at end of file diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/common/menu/menu.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/common/menu/menu.xhtml index 5a7e438..3beaf09 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/common/menu/menu.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/common/menu/menu.xhtml @@ -14,579 +14,456 @@
<f:loadBundle basename="ApplicationResources" var="msg" />
- - <rich:toolBar styleClass="topMenu"> - <rich:toolBarGroup location="left"> - - ui:remove===== LOGO TO HOME PAGE =====</ui:remove> - - <h:outputLink value="/"> - <h:graphicImage value="#{PerspectivesMenuUIBean.logo.iconUrl}" - width="#{PerspectivesMenuUIBean.logo.iconWidth}" - height="#{PerspectivesMenuUIBean.logo.iconHeight}" - rendered="#{PerspectivesMenuUIBean.logo.rendered}" /> - </h:outputLink> - - ui:remove===== OVERVIEW.BEFORE =====</ui:remove> - <c:if test="#{PerspectivesMenuUIBean.overviewBefore.rendered}"> - rich:dropDownMenu - <f:facet name="label"> - <h:panelGroup> - <h:outputText - value="#{PerspectivesMenuUIBean.overviewBefore.name}" - rendered="#{PerspectivesMenuUIBean.overviewBefore.rendered}" /> - </h:panelGroup> + <rich:toolBar styleClass="topMenu"> + <rich:toolBarGroup location="left"> + + ui:remove===== If the component is enabled i.e. rendered==true =====</ui:remove> + <c:if test="#{PerspectivesMenuUIBean.coreMenuBar.rendered}"> + ui:remove===== If CoreMenu UI hasn't been disabled =====</ui:remove> + ui:remove===== Iterate through children[Top Menu Items] =====</ui:remove> + <c:forEach var="top" + items="#{PerspectivesMenuUIBean.coreMenuBar.childMenuItems}"> + <c:if test="#{top.rendered and top.alignLeft}"> + ui:remove===== LOGO TO HOME PAGE or other top-level-image menu item =====</ui:remove> + <c:if test="#{ExtensionPoints.logo == top.extensionKey or 'top-level-image' == top.extensionKey}"> + <h:outputLink value="/"> + <h:graphicImage value="#{top.iconUrl}" + width="#{top.iconWidth}" + height="#{top.iconHeight}" + rendered="#{top.rendered}" /> + </h:outputLink> + </c:if> + ui:remove===== DEBUG top-level menu item =====</ui:remove> + <c:if test="#{ExtensionPoints.debug == top.extensionKey}"> + <rich:dropDownMenu rendered="#{GlobalPermissionsUIBean.superuser and + GlobalPermissionsUIBean.debugMode}"> + <f:facet name="label"> + <h:panelGroup> + <h:outputText value="#{top.name}"/> + </h:panelGroup> + </f:facet> + <c:forEach var="child" + items="#{top.childMenuItems}"> + <rich:menuItem submitMode="none" + icon="#{child.iconUrl}" + width="#{child.iconWidth}" height="#{child.iconHeight}" + onclick="window.open('#{child.url}')" + target="blank_"> + <h:outputText value="#{child.name}"/> + </rich:menuItem> + </c:forEach> + </rich:dropDownMenu> + </c:if> + <c:if test="#{ExtensionPoints.logo != top.extensionKey and ExtensionPoints.debug != top.extensionKey}"> + rich:dropDownMenu + <f:facet name="label"> + <h:panelGroup> + <c:choose> + ui:remove= logic for administration =</ui:remove> + <c:when test="${ExtensionPoints.administration == top.extensionKey}"> + <h:outputText value="#{msg['admin.admin.AdministrationTitle']}"/> + </c:when> + ui:remove= logic for help =</ui:remove> + <c:when test="${ExtensionPoints.help == top.extensionKey}"> + <h:outputText value="#{msg['header.help.link']}"/> + </c:when> + <c:otherwise> + <h:outputText value="#{top.name}"/> + </c:otherwise> + </c:choose> + </h:panelGroup> </f:facet> - <c:forEach var="item" - items="#{PerspectivesMenuUIBean.overviewBeforeItems}"> - <rich:menuItem submitMode="none" icon="#{item.iconUrl}" - width="#{item.iconWidth}" height="#{item.iconHeight}" - rendered="#{item.rendered}" - onclick="window.location = '#{item.url}'"> - <h:outputText value="#{item.name}" /> - </rich:menuItem> + ui:remove Now process the children MenuItems if they exist </ui:remove> + + <c:forEach var="child" + items="#{top.childMenuItems}"> + <c:if test="#{child.rendered}"> + <c:choose> + <c:when test="${child.childMenuItems.size > 0}"> + <rich:menuGroup value="#{child.name}"> + <c:forEach var="grandchild" + items="#{child.childMenuItems}"> + <rich:menuItem submitMode="none" icon="#{grandchild.iconUrl}" + width="#{grandchild.iconWidth}" height="#{grandchild.iconHeight}" + onclick="window.location = '#{grandchild.url}'"> + <h:outputText value="#{grandchild.name}" /> + </rich:menuItem> + </c:forEach> + </rich:menuGroup> + </c:when> + <c:otherwise> + <c:choose> + ui:remove= logic for platforms =</ui:remove> + <c:when test="${ExtensionPoints.platforms == child.extensionKey}"> + <rich:menuItem submitMode="none" icon="#{child.iconUrl}" + width="#{child.iconWidth}" height="#{child.iconHeight}" + onclick="window.location = '#{child.url}'"> + <h:outputText value="#{msg['resource.hub.filter.platform']}"/> + </rich:menuItem> + </c:when> + ui:remove= logic for servers =</ui:remove> + <c:when test="${ExtensionPoints.servers == child.extensionKey}"> + <rich:menuItem submitMode="none" icon="#{child.iconUrl}" + width="#{child.iconWidth}" height="#{child.iconHeight}" + onclick="window.location = '#{child.url}'"> + <h:outputText value="#{msg['resource.hub.filter.server']}"/> + </rich:menuItem> + </c:when> + ui:remove= logic for services =</ui:remove> + <c:when test="${ExtensionPoints.services == child.extensionKey}"> + <rich:menuItem submitMode="none" icon="#{child.iconUrl}" + width="#{child.iconWidth}" height="#{child.iconHeight}" + onclick="window.location = '#{child.url}'"> + <h:outputText value="#{msg['resource.hub.filter.service']}"/> + </rich:menuItem> + </c:when> + <c:when test="#{child.menuSeparator}"> + rich:menuSeparator/ + </c:when> + <c:when test="${ExtensionPoints.favoriteresources == child.extensionKey}"> + <rich:menuGroup value="#{child.name}" icon="#{child.iconUrl}" + width="#{child.iconWidth}" height="#{child.iconHeight}"> + <c:forEach var="resource" items="#{UserPreferencesUIBean.resourceFavorites}"> + <rich:menuItem submitMode="none" + icon="/images/icons/#{resource.resourceType.category}_up_16.png" + onclick="window.location = '#{onf:getDefaultResourceTabURL()}?id=#{resource.id}'"> + <h:outputText value="#{resource.name}"/> + </rich:menuItem> + </c:forEach> + </rich:menuGroup> + </c:when> + <c:when test="${ExtensionPoints.recentlyviewedresources == child.extensionKey}"> + ui:remove***** Resources > Recently Viewed *****</ui:remove> + <rich:menuGroup value="#{child.name}" icon="#{child.iconUrl}" + width="#{child.iconWidth}" height="#{child.iconHeight}"> + <c:forEach var="visit" items="#{UserPreferencesUIBean.recentVisits}"> + <c:if test="#{visit.kind == 'PLATFORM' or visit.kind == 'SERVER' or visit.kind == 'SERVICE'}"> + <rich:menuItem submitMode="none" + icon="/images/icons/#{visit.kind.displayName}_up_16.png" + onclick="window.location = '#{onf:getDefaultResourceTabURL()}?id=#{visit.id}'"> + <h:outputText value="#{visit.name}"/> + </rich:menuItem> + </c:if> + </c:forEach> + </rich:menuGroup> + </c:when> + <c:when test="${ExtensionPoints.searchresources == child.extensionKey}"> + ui:remove***** Resources > SEARCH *****</ui:remove> + <rich:menuItem submitMode="none" disabled="true" iconDisabled="/images/icons/Search_16.png"> + <h:outputText value="Search: " style="color: black;"/> + <h:panelGroup> + <h:inputText id="selectedResource" style="width: 250px;" immediate="true" + onkeypress="return ignoreEnterKey(event);" /> + <rich:suggestionbox id="resourceSelectBox" for="selectedResource" tokens=",[]" + ajaxSingle="true" immediate="true" + suggestionAction="#{ResourceSelectUIBean.autocomplete}" + var="result" data="foo" fetchValue="#{result.resource.id}" + nothingLabel="No matching resources found" + style="background-color: #cccccc;" + onselect="document.location.href='#{onf:getDefaultResourceTabURL()}?id=' + #{rich:element('selectedResource')}.value" + usingSuggestObjects="false" width="700" height="400"> + <h:column> + <f:facet name="header">Avail</f:facet> + <h:graphicImage + value="/images/icons/availability_#{result.availability == 'UP' ? 'green' : 'red'}_16.png"/> + </h:column> + <h:column> + <f:facet name="header">Resource</f:facet> + <h:outputText value="#{result.resource.name}"/> + </h:column> + <h:column> + <f:facet name="header">Parent</f:facet> + <h:outputText value="#{result.parent.name}"/> + </h:column> + </rich:suggestionbox> + </h:panelGroup> + </rich:menuItem> + </c:when> + <c:when test="${ExtensionPoints.mixed == child.extensionKey or + ExtensionPoints.compatible == child.extensionKey or + ExtensionPoints.definitions == child.extensionKey}"> + ui:remove***** Groups > COMPATIBLE GROUPS *****</ui:remove> + ui:remove***** Groups > MIXED GROUPS *****</ui:remove> + ui:remove***** Groups > GROUP DEFINITIONS *****</ui:remove> + <rich:menuItem submitMode="none" icon="#{child.iconUrl}" + width="#{child.iconWidth}" height="#{child.iconHeight}" + onclick="window.location = '#{child.url}'"> + <c:choose> + <c:when test="#{ExtensionPoints.compatible == child.extensionKey}"> + <h:outputText value="#{msg['resource.hub.filter.compatibleGroups']}"/> + </c:when> + <c:when test="#{ExtensionPoints.mixed == child.extensionKey}"> + <h:outputText value="#{msg['resource.hub.filter.mixedGroups']}"/> + </c:when> + <c:when test="#{ExtensionPoints.definitions == child.extensionKey}"> + <h:outputText value="#{msg['resource.hub.filter.groupDefinitions']}"/> + </c:when> + </c:choose> + </rich:menuItem> + </c:when> + <c:when test="#{ExtensionPoints.newgroup == child.extensionKey}"> + ui:remove***** Groups > NEW RESOURCE GROUP *****</ui:remove> + <rich:menuSeparator rendered="#{GlobalPermissionsUIBean.inventory}"/> + <rich:menuItem submitMode="none" onclick="window.location = '#{child.url}'" + rendered="#{GlobalPermissionsUIBean.inventory}"> + <h:outputText value="#{msg['resource.hub.NewGroupLink']}"/> + </rich:menuItem> + </c:when> + <c:when test="#{ExtensionPoints.newgroupdefinition == child.extensionKey}"> + ui:remove***** Groups > NEW GROUP DEFINITIONS *****</ui:remove> + <rich:menuItem submitMode="none" onclick="window.location = '#{child.url}'" + rendered="#{GlobalPermissionsUIBean.inventory}"> + <h:outputText value="#{msg['resource.hub.NewGroupDefinitionLink']}"/> + </rich:menuItem> + </c:when> + <c:when test="#{ExtensionPoints.favoritegroups == child.extensionKey}"> + ui:remove***** Groups > FAVORITE GROUPS *****</ui:remove> + <rich:menuGroup value="#{child.name}" icon="#{child.iconUrl}"> + <c:forEach var="group" items="#{UserPreferencesUIBean.groupFavorites}"> + <rich:menuItem submitMode="none" + icon="/images/icons/#{group.groupCategory == 'MIXED' ? 'Group' : 'Cluster'}_up_16.png" + onclick="window.location = '/rhq/group/inventory/view.xhtml?groupId=#{group.id}'"> + <h:outputText value="#{group.name}"/> + </rich:menuItem> + </c:forEach> + </rich:menuGroup> + </c:when> + <c:when test="${ExtensionPoints.recentlyviewedgroups == child.extensionKey}"> + ui:remove***** Groups > RECENTLY VIEWED *****</ui:remove> + <rich:menuGroup value="#{child.name}" icon="#{child.iconUrl}"> + <c:forEach var="visit" items="#{UserPreferencesUIBean.recentVisits}"> + <c:if test="#{visit.kind == 'COMPATIBLE_GROUP' or visit.kind == 'MIXED_GROUP'}"> + <rich:menuItem submitMode="none" + icon="/images/icons/#{visit.kind == 'COMPATIBLE_GROUP' ? 'Cluster' : 'Group'}_up_16.png" + onclick="window.location = '/rhq/group/inventory/view.xhtml?groupId=#{visit.id}'"> + <h:outputText value="#{visit.name}"/> + </rich:menuItem> + </c:if> + </c:forEach> + </rich:menuGroup> + </c:when> + <c:when test="${ExtensionPoints.searchgroups == child.extensionKey}"> + ui:remove***** Groups > SEARCH *****</ui:remove> + <rich:menuItem submitMode="none" disabled="true" iconDisabled="/images/icons/Search_16.png"> + <h:outputText value="Search: " style="color: black;"/> + <h:panelGroup> + <h:inputText id="selectedGroup" style="width: 250px;" immediate="true" + onkeypress="return ignoreEnterKey(event);" /> + <rich:suggestionbox id="groupSelectBox" for="selectedGroup" tokens=",[]" + ajaxSingle="true" immediate="true" + suggestionAction="#{ResourceGroupSelectUIBean.autocomplete}" + var="result" data="foo" fetchValue="#{result.groupQueryString}" + nothingLabel="No matching groups found" + style="background-color: #cccccc;" + onselect="document.location.href='/rhq/group/inventory/view.xhtml?' + #{rich:element('selectedGroup')}.value" + usingSuggestObjects="false" width="700" height="400"> + <h:column> + <f:facet name="header">Avail</f:facet> + <h:graphicImage value="/images/icons/availability_green_16.png" rendered="#{result.implicitUp > 0 and result.implicitDown == 0}"/> + <h:graphicImage value="/images/icons/availability_red_16.png" rendered="#{result.implicitUp == 0 and result.implicitDown > 0}"/> + <h:graphicImage value="/images/icons/availability_yellow_16.png" rendered="#{result.implicitUp > 0 and result.implicitDown > 0}"/> + <h:graphicImage value="/images/icons/availability_grey_16.png" rendered="#{result.implicitUp == 0 and result.implicitDown == 0}"/> + </h:column> + <h:column> + <f:facet name="header">Group</f:facet> + <h:outputText value="#{result.resourceGroup.name}"/> + </h:column> + <h:column> + <f:facet name="header">Category</f:facet> + <h:outputText value="#{result.category.name}" rendered="#{result.category.name == 'MIXED'}"/> + <h:outputText value="#{result.resourceGroup.resourceType.name}" rendered="#{result.category.name == 'COMPATIBLE'}"/> + </h:column> + </rich:suggestionbox> + </h:panelGroup> + </rich:menuItem> + </c:when> + <c:when test="#{ExtensionPoints.about == child.extensionKey}"> + ui:remove***** Help > ABOUT *****</ui:remove> + <rich:menuItem submitMode="none" id="aboutLink" icon="#{child.iconUrl}" + width="#{child.iconWidth}" height="#{child.iconHeight}"> + <h:outputText value="#{msg['header.about.link']}"/> + <rich:componentControl for="aboutPanel" attachTo="aboutLink" operation="show" event="onclick"/> + </rich:menuItem> + </c:when> + <c:otherwise> + <rich:menuItem submitMode="none" icon="#{child.iconUrl}" + width="#{child.iconWidth}" height="#{child.iconHeight}" + onclick="window.location = '#{child.url}'"> + <h:outputText value="#{child.name}" /> + </rich:menuItem> + </c:otherwise> + </c:choose> + </c:otherwise> + </c:choose> + </c:if> </c:forEach> - </rich:dropDownMenu> - </c:if> - ui:remove===== OVERVIEW =====</ui:remove> - - rich:dropDownMenu - <f:facet name="label"> - <h:panelGroup> - <h:outputText value="#{PerspectivesMenuUIBean.overview.name}" - rendered="#{PerspectivesMenuUIBean.overview.rendered}" /> - </h:panelGroup> - </f:facet> - - ui:remove***** Overview > SYSTEM VIEWS *****</ui:remove> - rich:menuGroup - value="#{PerspectivesMenuUIBean.subsystemViews.name}" - <c:forEach var="menu" - items="#{PerspectivesMenuUIBean.subsystemMenuItems}"> - <rich:menuItem submitMode="none" icon="#{menu.iconUrl}" - onclick="window.location = '#{menu.url}'"> - <h:outputText value="#{menu.name}" /> - </rich:menuItem> - </c:forEach> - </rich:menuGroup> - - ui:remove***** Overview > AUTO-DISCOVERY QUEUE *****</ui:remove> - <rich:menuItem submitMode="none" - onclick="window.location = '#{PerspectivesMenuUIBean.autoDiscoveryQueue.url}'"> - <h:outputText - value="#{PerspectivesMenuUIBean.autoDiscoveryQueue.name}" /> - </rich:menuItem> - - ui:remove***** Overview > DASHBOARD *****</ui:remove> - <rich:menuItem submitMode="none" - onclick="window.location = '#{PerspectivesMenuUIBean.dashboard.url}'"> - <h:outputText value="#{PerspectivesMenuUIBean.dashboard.name}" /> - </rich:menuItem> - </rich:dropDownMenu> - - ui:remove===== RESOURCES =====</ui:remove> - - <rich:dropDownMenu id="resourcesMenu"> - <f:facet name="label"> - <h:panelGroup> - <h:outputText value="#{PerspectivesMenuUIBean.resources.name}" /> - </h:panelGroup> - </f:facet> - - ui:remove***** Resources > PLATFORMS *****</ui:remove> - <rich:menuItem submitMode="none" - icon="#{PerspectivesMenuUIBean.resourcesPlatform.iconUrl}" - onclick="window.location = '#{PerspectivesMenuUIBean.resourcesPlatform.url}'"> - <h:outputText value="#{msg['resource.hub.filter.platform']}" /> - </rich:menuItem> - - ui:remove***** Resources > SERVERS *****</ui:remove> - <rich:menuItem submitMode="none" - icon="#{PerspectivesMenuUIBean.resourcesServer.iconUrl}" - onclick="window.location = '#{PerspectivesMenuUIBean.resourcesServer.url}'"> - <h:outputText value="#{msg['resource.hub.filter.server']}" /> - </rich:menuItem> - - ui:remove***** Resources > SERVICES *****</ui:remove> - <rich:menuItem submitMode="none" - icon="#{PerspectivesMenuUIBean.resourcesService.iconUrl}" - onclick="window.location = '#{PerspectivesMenuUIBean.resourcesService.url}'"> - <h:outputText value="#{msg['resource.hub.filter.service']}" /> - </rich:menuItem> - - ui:remove***** Resources > FAVORITE RESOURCES *****</ui:remove> - rich:menuGroup - value="#{PerspectivesMenuUIBean.resourcesFavorite.name}" - icon="#{PerspectivesMenuUIBean.resourcesFavorite.iconUrl}" - <c:forEach var="resource" - items="#{UserPreferencesUIBean.resourceFavorites}"> - <rich:menuItem submitMode="none" - icon="/images/icons/#{resource.resourceType.category}_up_16.png" - onclick="window.location = '#{onf:getDefaultResourceTabURL()}?id=#{resource.id}'"> - <h:outputText value="#{resource.name}" /> - </rich:menuItem> - </c:forEach> - </rich:menuGroup> - - ui:remove***** Resources > RECENTLY VIEWED *****</ui:remove> - rich:menuGroup - value="#{PerspectivesMenuUIBean.resourcesRecentlyViewed.name}" - icon="#{PerspectivesMenuUIBean.resourcesRecentlyViewed.iconUrl}" - <c:forEach var="visit" - items="#{UserPreferencesUIBean.recentVisits}"> - <c:if - test="#{visit.kind == 'PLATFORM' or visit.kind == 'SERVER' or visit.kind == 'SERVICE'}"> - <rich:menuItem submitMode="none" - icon="/images/icons/#{visit.kind.displayName}_up_16.png" - onclick="window.location = '#{onf:getDefaultResourceTabURL()}?id=#{visit.id}'"> - <h:outputText value="#{visit.name}" /> - </rich:menuItem> - </c:if> - </c:forEach> - </rich:menuGroup> - - <rich:menuSeparator /> - - ui:remove***** Resources > SEARCH *****</ui:remove> - <rich:menuItem submitMode="none" disabled="true" - iconDisabled="/images/icons/Search_16.png"> - <h:outputText value="Search: " style="color: black;" /> - <h:panelGroup> - <h:inputText id="selectedResource" style="width: 250px;" - immediate="true" onkeypress="return ignoreEnterKey(event);" /> - <rich:suggestionbox id="resourceSelectBox" for="selectedResource" - tokens=",[]" ajaxSingle="true" immediate="true" - suggestionAction="#{ResourceSelectUIBean.autocomplete}" - var="result" data="foo" fetchValue="#{result.resource.id}" - nothingLabel="No matching resources found" - style="background-color: #cccccc;" - onselect="document.location.href='#{onf:getDefaultResourceTabURL()}?id=' + #{rich:element('selectedResource')}.value" - usingSuggestObjects="false" width="700" height="400"> - <h:column> - <f:facet name="header">Avail</f:facet> - <h:graphicImage - value="/images/icons/availability_#{result.availability == 'UP' ? 'green' : 'red'}_16.png" /> - </h:column> - <h:column> - <f:facet name="header">Resource</f:facet> - <h:outputText value="#{result.resource.name}" /> - </h:column> - <h:column> - <f:facet name="header">Parent</f:facet> - <h:outputText value="#{result.parent.name}" /> - </h:column> - </rich:suggestionbox> - </h:panelGroup> - </rich:menuItem> - </rich:dropDownMenu> - - ui:remove===== GROUPS =====</ui:remove> - - <rich:dropDownMenu id="groupsMenu"> - <f:facet name="label"> - <h:panelGroup> - <h:outputText value="#{PerspectivesMenuUIBean.groups.name}"/> - </h:panelGroup> - </f:facet> - - ui:remove***** Groups > COMPATIBLE GROUPS *****</ui:remove> - <rich:menuItem submitMode="none" - icon="#{PerspectivesMenuUIBean.groupsCompatible.iconUrl}" - onclick="window.location = '#{PerspectivesMenuUIBean.groupsCompatible.url}'"> - <h:outputText - value="#{msg['resource.hub.filter.compatibleGroups']}" /> - </rich:menuItem> - - ui:remove***** Groups > MIXED GROUPS *****</ui:remove> - <rich:menuItem submitMode="none" - icon="#{PerspectivesMenuUIBean.groupsMixed.iconUrl}" - onclick="window.location = '#{PerspectivesMenuUIBean.groupsMixed.url}'"> - <h:outputText value="#{msg['resource.hub.filter.mixedGroups']}" /> - </rich:menuItem> - - ui:remove***** Groups > GROUP DEFINITIONS *****</ui:remove> - <rich:menuItem submitMode="none" - icon="#{PerspectivesMenuUIBean.groupsDefinitions.iconUrl}" - onclick="window.location = '#{PerspectivesMenuUIBean.groupsDefinitions.url}'"> - <h:outputText - value="#{msg['resource.hub.filter.groupDefinitions']}" /> - </rich:menuItem> - - <rich:menuSeparator rendered="#{GlobalPermissionsUIBean.inventory}" /> - - ui:remove***** Groups > NEW RESOURCE GROUP *****</ui:remove> - <rich:menuItem submitMode="none" - onclick="window.location = '#{PerspectivesMenuUIBean.groupsNewResource.url}'" - rendered="#{GlobalPermissionsUIBean.inventory}"> - <h:outputText value="#{msg['resource.hub.NewGroupLink']}" /> - </rich:menuItem> - - ui:remove***** Groups > NEW GROUP DEFINITIONS *****</ui:remove> - <rich:menuItem submitMode="none" - onclick="window.location = '#{PerspectivesMenuUIBean.groupsNewDefinition.url}'" - rendered="#{GlobalPermissionsUIBean.inventory}"> - <h:outputText - value="#{msg['resource.hub.NewGroupDefinitionLink']}" /> - </rich:menuItem> - - <rich:menuSeparator /> - - ui:remove***** Groups > FAVORITE GROUPS *****</ui:remove> - rich:menuGroup - value="#{PerspectivesMenuUIBean.groupsFavorite.name}" - icon="#{PerspectivesMenuUIBean.groupsFavorite.iconUrl}" - <c:forEach var="group" - items="#{UserPreferencesUIBean.groupFavorites}"> - <rich:menuItem submitMode="none" - icon="/images/icons/#{group.groupCategory == 'MIXED' ? 'Group' : 'Cluster'}_up_16.png" - onclick="window.location = '/rhq/group/inventory/view.xhtml?groupId=#{group.id}'"> - <h:outputText value="#{group.name}" /> - </rich:menuItem> - </c:forEach> - </rich:menuGroup> - - ui:remove***** Groups > RECENTLY VIEWED *****</ui:remove> - rich:menuGroup - value="#{PerspectivesMenuUIBean.groupsRecentlyViewed.name}" - icon="#{PerspectivesMenuUIBean.groupsRecentlyViewed.iconUrl}" - <c:forEach var="visit" - items="#{UserPreferencesUIBean.recentVisits}"> - <c:if - test="#{visit.kind == 'COMPATIBLE_GROUP' or visit.kind == 'MIXED_GROUP'}"> - <rich:menuItem submitMode="none" - icon="/images/icons/#{visit.kind == 'COMPATIBLE_GROUP' ? 'Cluster' : 'Group'}_up_16.png" - onclick="window.location = '/rhq/group/inventory/view.xhtml?groupId=#{visit.id}'"> - <h:outputText value="#{visit.name}" /> - </rich:menuItem> - </c:if> - </c:forEach> - </rich:menuGroup> - - <rich:menuSeparator /> - - ui:remove***** Groups > SEARCH *****</ui:remove> - <rich:menuItem submitMode="none" disabled="true" - iconDisabled="/images/icons/Search_16.png"> - <h:outputText value="Search: " style="color: black;" /> - <h:panelGroup> - <h:inputText id="selectedGroup" style="width: 250px;" - immediate="true" onkeypress="return ignoreEnterKey(event);" /> - <rich:suggestionbox id="groupSelectBox" for="selectedGroup" - tokens=",[]" ajaxSingle="true" immediate="true" - suggestionAction="#{ResourceGroupSelectUIBean.autocomplete}" - var="result" data="foo" fetchValue="#{result.groupQueryString}" - nothingLabel="No matching groups found" - style="background-color: #cccccc;" - onselect="document.location.href='/rhq/group/inventory/view.xhtml?' + #{rich:element('selectedGroup')}.value" - usingSuggestObjects="false" width="700" height="400"> - <h:column> - <f:facet name="header">Avail</f:facet> - <h:graphicImage value="/images/icons/availability_green_16.png" - rendered="#{result.implicitUp > 0 and result.implicitDown == 0}" /> - <h:graphicImage value="/images/icons/availability_red_16.png" - rendered="#{result.implicitUp == 0 and result.implicitDown > 0}" /> - <h:graphicImage - value="/images/icons/availability_yellow_16.png" - rendered="#{result.implicitUp > 0 and result.implicitDown > 0}" /> - <h:graphicImage value="/images/icons/availability_grey_16.png" - rendered="#{result.implicitUp == 0 and result.implicitDown == 0}" /> - </h:column> - <h:column> - <f:facet name="header">Group</f:facet> - <h:outputText value="#{result.resourceGroup.name}" /> - </h:column> - <h:column> - <f:facet name="header">Category</f:facet> - <h:outputText value="#{result.category.name}" - rendered="#{result.category.name == 'MIXED'}" /> - <h:outputText value="#{result.resourceGroup.resourceType.name}" - rendered="#{result.category.name == 'COMPATIBLE'}" /> - </h:column> - </rich:suggestionbox> - </h:panelGroup> - </rich:menuItem> - - </rich:dropDownMenu> - - ui:remove===== ADMINISTRATION =====</ui:remove> - - rich:dropDownMenu - <f:facet name="label"> - <h:panelGroup> - <h:outputText value="#{msg['admin.admin.AdministrationTitle']}" /> - </h:panelGroup> - </f:facet> - - ui:remove***** Administration > SECURITY *****</ui:remove> - <rich:menuGroup value="Security"> - <rich:menuItem submitMode="none" - onclick="window.location = '/admin/user/UserAdmin.do?mode=list'"> - <h:outputText value="Users" /> - </rich:menuItem> - <rich:menuItem submitMode="none" - onclick="window.location = '/admin/role/RoleAdmin.do?mode=list'"> - <h:outputText value="Roles" /> - </rich:menuItem> - </rich:menuGroup> - - ui:remove***** Administration > SYSTEM CONFIGURATION *****</ui:remove> - <rich:menuGroup value="System Configuration" - rendered="#{GlobalPermissionsUIBean.settings || GlobalPermissionsUIBean.inventory}"> - <rich:menuItem submitMode="none" - onclick="window.location = '/admin/config/Config.do?mode=edit'" - rendered="#{GlobalPermissionsUIBean.settings}"> - <h:outputText value="Settings" /> - </rich:menuItem> - <rich:menuItem submitMode="none" - onclick="window.location = '/rhq/admin/plugin/plugin-list.xhtml'" - rendered="#{GlobalPermissionsUIBean.settings}"> - <h:outputText value="Plugins" /> - </rich:menuItem> - <rich:menuItem submitMode="none" - onclick="window.location = '/admin/config/EditDefaults.do?mode=monitor&viewMode=all'" - rendered="#{GlobalPermissionsUIBean.inventory}"> - <h:outputText value="Templates" /> - </rich:menuItem> - </rich:menuGroup> - - ui:remove***** Administration > CONTENT *****</ui:remove> - <rich:menuGroup value="Content" - rendered="#{GlobalPermissionsUIBean.inventory}"> - <rich:menuItem submitMode="none" - onclick="window.location = '/rhq/content/listContentProviders.xhtml'"> - <h:outputText value="Content Providers" /> - </rich:menuItem> - <rich:menuItem submitMode="none" - onclick="window.location = '/rhq/content/listRepos.xhtml'"> - <h:outputText value="Repositories" /> - </rich:menuItem> - </rich:menuGroup> - - ui:remove***** Administration > HIGH AVAILABILITY *****</ui:remove> - <rich:menuGroup value="High Availability" - rendered="#{GlobalPermissionsUIBean.inventory}"> - <rich:menuItem submitMode="none" - onclick="window.location = '/rhq/ha/listServers.xhtml'"> - <h:outputText value="Servers" /> - </rich:menuItem> - <rich:menuItem submitMode="none" - onclick="window.location = '/rhq/ha/listAgents.xhtml'"> - <h:outputText value="Agents" /> - </rich:menuItem> - <rich:menuItem submitMode="none" - onclick="window.location = '/rhq/ha/listAffinityGroups.xhtml'"> - <h:outputText value="Affinity Groups" /> - </rich:menuItem> - <rich:menuItem submitMode="none" - onclick="window.location = '/rhq/ha/listPartitionEvents.xhtml'"> - <h:outputText value="Partition Events" /> - </rich:menuItem> - </rich:menuGroup> - - - - <rich:menuGroup value="Reports"> - <rich:menuItem submitMode="none" - onclick="window.location = '/rhq/admin/report/resourceInstallReport.xhtml'"> - <h:outputText value="Resource Version Inventory Report" /> - </rich:menuItem> - - </rich:menuGroup> - - <rich:menuItem submitMode="none" icon="/images/icons/Save_16.png" - onclick="window.location = '/rhq/admin/downloads.xhtml'"> - <h:outputText value="Downloads" /> - </rich:menuItem> - - - <rich:menuItem submitMode="none" - onclick="window.location = '/admin/license/LicenseAdmin.do?mode=view'" - rendered="#{GlobalPermissionsUIBean.settings}"> - <h:outputText value="License" /> - </rich:menuItem> - </rich:dropDownMenu> - - ui:remove===== DEBUG =====</ui:remove> - - <rich:dropDownMenu - rendered="#{GlobalPermissionsUIBean.superuser and - GlobalPermissionsUIBean.debugMode}"> - <f:facet name="label"> - <h:panelGroup> - <h:outputText value="Debug" /> - </h:panelGroup> - </f:facet> - - <rich:menuItem submitMode="none" - onclick="window.open('/admin/test/sql.jsp')" target="blank_"> - <h:outputText value="SQL Interface" /> - </rich:menuItem> - <rich:menuItem submitMode="none" - onclick="window.open('/admin/test/hibernate.jsp')" target="blank_"> - <h:outputText value="JPQL/HQL Interface" /> - </rich:menuItem> - <rich:menuItem submitMode="none" - onclick="window.open('/admin/test/browser.jsp')" target="blank_"> - <h:outputText value="Hibernate Entity Browser" /> - </rich:menuItem> - <rich:menuItem submitMode="none" - onclick="window.open('/admin/test/control.jsp')" target="blank_"> - <h:outputText value="Administrative Control" /> - </rich:menuItem> - <rich:menuItem submitMode="none" - onclick="window.open('/admin/test/email.jsp')" target="blank_"> - <h:outputText value="Test Email Configuration" /> - </rich:menuItem> - <rich:menuItem submitMode="none" - onclick="window.open('/admin/test/agent.jsp')" target="blank_"> - <h:outputText value="Test Agent Communications" /> - </rich:menuItem> - </rich:dropDownMenu> - - ui:remove===== HELP =====</ui:remove> - - rich:dropDownMenu - <f:facet name="label"> - <h:panelGroup> - <h:outputText value="#{msg['header.help.link']}" /> - </h:panelGroup> - </f:facet> - - ui:remove***** Help > DOCUMENTATION *****</ui:remove> - <rich:menuItem submitMode="none" - onclick="window.open('http://www.redhat.com/docs/en-US/JBoss_ON/')" - target="blank_"> - <h:outputText value="Online Documentation" /> - </rich:menuItem> - - ui:remove***** Help > SUPPORT CASE *****</ui:remove> - <rich:menuItem submitMode="none" - onclick="window.open('https://support.redhat.com/jbossnetwork/restricted/addCase.html')" - target="blank_"> - <h:outputText value="Open a Support Case" /> - </rich:menuItem> - - <rich:menuSeparator /> - - ui:remove***** Help > ABOUT *****</ui:remove> - <rich:menuItem submitMode="none" id="aboutLink" - icon="/images/icons/availability_grey_16.png"> - <h:outputText value="#{msg['header.about.link']}" /> - <rich:componentControl for="aboutPanel" attachTo="aboutLink" - operation="show" event="onclick" /> - </rich:menuItem> - </rich:dropDownMenu> - </rich:toolBarGroup> - - - <rich:toolBarGroup location="right"> - - <a4j:status id="commonStatus" layout="block" - startStyle=" filter:alpha(opacity=85); -moz-opacity: 0.85; opacity: 0.85; vertical-align: middle;"> - <f:facet name="start"> - <img src="/images/ajax-loader.gif" alt="" - style="vertical-align: middle;" /> - <span style="vertical-align: middle;">Loading...</span> - </f:facet> - </a4j:status> - - - - - - <rich:dropDownMenu rendered="#{request.method == 'GET'}"> - <f:facet name="label"> - <h:panelGroup> - <h:graphicImage value="/images/refreshRunning.gif" - rendered="#{UserPreferencesUIBean.pageRefresh != 0}" /> - <h:graphicImage value="/images/refreshStopped.gif" - rendered="#{UserPreferencesUIBean.pageRefresh == 0}" /> - <span id="refreshTimeLeft" style="width: 0px;"><h:outputText - value="#{UserPreferencesUIBean.pageRefresh}" - rendered="#{UserPreferencesUIBean.pageRefresh != 0}" /></span> - - </h:panelGroup> - </f:facet> - - ui:remove***** Logged in as > EDIT DETAILS *****</ui:remove> - - - - <rich:menuItem submitMode="none" - onclick="updatePageRefresh('#{request.getAttribute('javax.servlet.forward.request_uri')}', 0)"> - <h:outputText value="Stop" /> - <f:facet name="icon"> - <h:graphicImage - value="/images/#{UserPreferencesUIBean.pageRefresh == 0 ? 'check.png' : 'spacer.gif'}" - width="16" height="16" /> - </f:facet> - </rich:menuItem> - <rich:menuItem submitMode="none" - onclick="updatePageRefresh('#{request.getAttribute('javax.servlet.forward.request_uri')}',60)"> - <h:outputText value="Refresh every 1 minute" /> - <f:facet name="icon"> - <h:graphicImage - value="/images/#{UserPreferencesUIBean.pageRefresh == 60 ? 'check.png' : 'spacer.gif'}" - width="16" height="16" /> - </f:facet> - </rich:menuItem> - <rich:menuItem submitMode="none" - onclick="updatePageRefresh('#{request.getAttribute('javax.servlet.forward.request_uri')}',300)"> - <h:outputText value="Refresh every 5 minutes" /> - <f:facet name="icon"> - <h:graphicImage - value="/images/#{UserPreferencesUIBean.pageRefresh == 300 ? 'check.png' : 'spacer.gif'}" - width="16" height="16" /> - </f:facet> - </rich:menuItem> - <rich:menuItem submitMode="none" - onclick="updatePageRefresh('#{request.getAttribute('javax.servlet.forward.request_uri')}',600)"> - <h:outputText value="Refresh every 10 minutes" /> - <f:facet name="icon"> - <h:graphicImage - value="/images/#{UserPreferencesUIBean.pageRefresh == 600 ? 'check.png' : 'spacer.gif'}" - width="16" height="16" /> - </f:facet> - </rich:menuItem> - - </rich:dropDownMenu> - - ui:remove===== LOGGED IN AS =====</ui:remove> - - - rich:dropDownMenu - <f:facet name="label"> - <h:panelGroup> - <h:outputText - value="Logged in as #{UserPreferencesUIBean.subject.name}" /> - </h:panelGroup> - </f:facet> - - ui:remove***** Logged in as > EDIT DETAILS *****</ui:remove> - <rich:menuItem submitMode="none" - onclick="window.location = '/admin/user/UserAdmin.do?mode=edit&u=#{UserPreferencesUIBean.subject.id}'"> - <h:outputText value="Edit Details" /> - </rich:menuItem> - - ui:remove***** Logged in as > CHANGE PASSWORD *****</ui:remove> - <rich:menuItem submitMode="none" - onclick="window.location = '/admin/user/UserAdmin.do?mode=editPass&u=#{UserPreferencesUIBean.subject.id}'"> - <h:outputText value="Change Password" /> - </rich:menuItem> - - <rich:menuSeparator /> - - ui:remove***** Logged in as > LOGOUT *****</ui:remove> - <rich:menuItem submitMode="none" - onclick="window.location = '/Logout.do'"> - <h:outputText value="Logout" /> - </rich:menuItem> - </rich:dropDownMenu> - - </rich:toolBarGroup> - </rich:toolBar> - + </c:if> + </c:if> + </c:forEach> + </c:if> + </rich:toolBarGroup> + + ui:remove===== Display CoreMenu right aligned components =====</ui:remove> + <rich:toolBarGroup location="right"> + <a4j:status id="commonStatus" layout="block" + startStyle=" filter:alpha(opacity=85); -moz-opacity: 0.85; opacity: 0.85; vertical-align: middle;"> + <f:facet name="start"> + <img src="/images/ajax-loader.gif" alt="" style="vertical-align:middle;"/> <span + style="vertical-align: middle;">Loading...</span> + </f:facet> + </a4j:status> + + <c:if test="#{PerspectivesMenuUIBean.coreMenuBar.rendered}"> + ui:remove===== If CoreMenu UI hasn't been disabled =====</ui:remove> + ui:remove===== Iterate through children[Top Menu Items - RIGHT ALIGNED] =====</ui:remove> + <c:forEach var="top" + items="#{PerspectivesMenuUIBean.coreMenuBar.childMenuItems}"> + <c:if test="#{top.rendered and top.alignLeft == false}"> + + ui:remove===== Refresh item =====</ui:remove> + <c:if test="#{ExtensionPoints.refresh == top.extensionKey}"> + <rich:dropDownMenu rendered="#{request.method == 'GET'}"> + <f:facet name="label"> + <h:panelGroup> + <h:graphicImage value="/images/refreshRunning.gif" rendered="#{UserPreferencesUIBean.pageRefresh != 0}"/> + <h:graphicImage value="/images/refreshStopped.gif" rendered="#{UserPreferencesUIBean.pageRefresh == 0}"/> + <span id="refreshTimeLeft" style="width: 0px;"><h:outputText value="#{UserPreferencesUIBean.pageRefresh}" rendered="#{UserPreferencesUIBean.pageRefresh != 0}"/></span> + </h:panelGroup> + </f:facet> + <rich:menuItem submitMode="none" onclick="updatePageRefresh('#{request.getAttribute('javax.servlet.forward.request_uri')}', 0)"> + <h:outputText value="Stop"/> + <f:facet name="icon"> + <h:graphicImage value="/images/#{UserPreferencesUIBean.pageRefresh == 0 ? 'check.png' : 'spacer.gif'}" width="16" height="16"/> + </f:facet> + </rich:menuItem> + <rich:menuItem submitMode="none" onclick="updatePageRefresh('#{request.getAttribute('javax.servlet.forward.request_uri')}',60)"> + <h:outputText value="Refresh every 1 minute"/> + <f:facet name="icon"> + <h:graphicImage value="/images/#{UserPreferencesUIBean.pageRefresh == 60 ? 'check.png' : 'spacer.gif'}" width="16" height="16"/> + </f:facet> + </rich:menuItem> + <rich:menuItem submitMode="none" onclick="updatePageRefresh('#{request.getAttribute('javax.servlet.forward.request_uri')}',300)"> + <h:outputText value="Refresh every 5 minutes"/> + <f:facet name="icon"> + <h:graphicImage value="/images/#{UserPreferencesUIBean.pageRefresh == 300 ? 'check.png' : 'spacer.gif'}" width="16" height="16"/> + </f:facet> + </rich:menuItem> + <rich:menuItem submitMode="none" onclick="updatePageRefresh('#{request.getAttribute('javax.servlet.forward.request_uri')}',600)"> + <h:outputText value="Refresh every 10 minutes"/> + <f:facet name="icon"> + <h:graphicImage value="/images/#{UserPreferencesUIBean.pageRefresh == 600 ? 'check.png' : 'spacer.gif'}" width="16" height="16"/> + </f:facet> + </rich:menuItem> + </rich:dropDownMenu> + </c:if> + ui:remove===== LoggedInAs item =====</ui:remove> + <c:if test="#{ExtensionPoints.loggedinas == top.extensionKey}"> + rich:dropDownMenu + <f:facet name="label"> + <h:panelGroup> + <h:outputText value="Logged in as #{UserPreferencesUIBean.subject.name}"/> + </h:panelGroup> + </f:facet> + ui:remove Now process the children MenuItems if they exist </ui:remove> + <c:forEach var="child" + items="#{top.childMenuItems}"> + <c:if test="#{child.rendered}"> + <c:choose> + <c:when test="${child.childMenuItems.size > 0}"> + <rich:menuGroup value="#{child.name}"> + <c:forEach var="grandchild" + items="#{child.childMenuItems}"> + <c:choose> + <c:when test="#{grandchild.menuSeparator}"> + rich:menuSeparator/ + </c:when> + <c:otherwise> + <rich:menuItem submitMode="none" icon="#{grandchild.iconUrl}" + width="#{grandchild.iconWidth}" height="#{grandchild.iconHeight}" + onclick="window.location = '#{grandchild.url}'"> + <h:outputText value="#{grandchild.name}" /> + </rich:menuItem> + </c:otherwise> + </c:choose> + </c:forEach> + </rich:menuGroup> + </c:when> + <c:otherwise> + <c:choose> + <c:when test="#{child.menuSeparator}"> + rich:menuSeparator/ + </c:when> + <c:otherwise> + <rich:menuItem submitMode="none" icon="#{child.iconUrl}" + width="#{child.iconWidth}" height="#{child.iconHeight}" + onclick="window.location = '#{child.url}'"> + <h:outputText value="#{child.name}" /> + </rich:menuItem> + </c:otherwise> + </c:choose> + </c:otherwise> + </c:choose> + </c:if> + </c:forEach> + </rich:dropDownMenu> + </c:if> + <c:if test="#{ExtensionPoints.loggedinas != top.extensionKey and ExtensionPoints.refresh != top.extensionKey}"> + rich:dropDownMenu + <f:facet name="label"> + <h:panelGroup> + <h:outputText value="#{top.name}"/> + </h:panelGroup> + </f:facet> + ui:remove Now process the children MenuItems if they exist </ui:remove> + <c:forEach var="child" + items="#{top.childMenuItems}"> + <c:if test="#{child.rendered}"> + <c:choose> + <c:when test="${child.childMenuItems.size > 0}"> + <rich:menuGroup value="#{child.name}"> + <c:forEach var="grandchild" + items="#{child.childMenuItems}"> + <c:choose> + <c:when test="#{grandchild.menuSeparator}"> + rich:menuSeparator/ + </c:when> + <c:otherwise> + <rich:menuItem submitMode="none" icon="#{grandchild.iconUrl}" + width="#{grandchild.iconWidth}" height="#{grandchild.iconHeight}" + onclick="window.location = '#{grandchild.url}'"> + <h:outputText value="#{grandchild.name}" /> + </rich:menuItem> + </c:otherwise> + </c:choose> + </c:forEach> + </rich:menuGroup> + </c:when> + <c:otherwise> + <c:choose> + <c:when test="#{child.menuSeparator}"> + rich:menuSeparator/ + </c:when> + <c:otherwise> + <rich:menuItem submitMode="none" icon="#{child.iconUrl}" + width="#{child.iconWidth}" height="#{child.iconHeight}" + onclick="window.location = '#{child.url}'"> + <h:outputText value="#{child.name}" /> + </rich:menuItem> + </c:otherwise> + </c:choose> + </c:otherwise> + </c:choose> + </c:if> + </c:forEach> + </rich:dropDownMenu> + </c:if> + </c:if> + </c:forEach> + </c:if> + </rich:toolBarGroup> + </rich:toolBar> + <rich:modalPanel id="aboutPanel" resizeable="false" width="320" height="250"> <f:facet name="header">
commit 6a2d6ad8f26ce5249c6a09320728a016e9b60935 Merge: a3a2d66... b470482... Author: Adam Young ayoung@redhat.com Date: Wed Nov 25 14:36:41 2009 -0500
Merge branch 'raw-config' of ssh://git.fedorahosted.org/git/rhq/rhq into raw-config
commit b47048248bb4550fe78d0ccef319080e264d4079 Author: John Sanda john@localhost.localdomain Date: Wed Nov 25 14:35:34 2009 -0500
Updating runtime dependencies
diff --git a/modules/plugins/raw-config-test/pom.xml b/modules/plugins/raw-config-test/pom.xml index a55bfbc..60eef55 100644 --- a/modules/plugins/raw-config-test/pom.xml +++ b/modules/plugins/raw-config-test/pom.xml @@ -75,6 +75,16 @@ <version>1.6.4</version> </artifactItem> <artifactItem> + <groupId>org.apache.ant</groupId> + <artifactId>ant</artifactId> + <version>1.7.1</version> + </artifactItem> + <artifactItem> + <groupId>org.apache.ant</groupId> + <artifactId>ant-launcher</artifactId> + <version>1.7.1</version> + </artifactItem> + <artifactItem> <groupId>commons-configuration</groupId> <artifactId>commons-configuration</artifactId> <version>1.6</version>
commit 2ce39c2280d2a87a3d70a229883d68a086f896bb Author: Jay Shaughnessy jshaughn@redhat.com Date: Wed Nov 25 13:55:33 2009 -0500
Work to expose coreMenu extension point via perspective manager
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveException.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveException.java new file mode 100644 index 0000000..b238b44 --- /dev/null +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveException.java @@ -0,0 +1,40 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2008 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.perspective; + +public class PerspectiveException extends Exception { + + private static final long serialVersionUID = 1L; + + public PerspectiveException() { + } + + public PerspectiveException(String message) { + super(message); + } + + public PerspectiveException(Throwable cause) { + super(cause); + } + + public PerspectiveException(String message, Throwable cause) { + super(message, cause); + } + +} diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveManagerBean.java index 0dce72a..c33120b 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveManagerBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveManagerBean.java @@ -18,9 +18,65 @@ */ package org.rhq.enterprise.server.perspective;
+import java.util.List; + +import javax.ejb.EJB; import javax.ejb.Stateless; +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.rhq.core.domain.auth.Subject; +import org.rhq.enterprise.server.RHQConstants; +import org.rhq.enterprise.server.auth.SubjectManagerLocal;
@Stateless // @WebService(endpointInterface = "org.rhq.enterprise.server.perspective.PerspectiveManagerRemote") public class PerspectiveManagerBean implements PerspectiveManagerLocal, PerspectiveManagerRemote { + + private final Log log = LogFactory.getLog(PerspectiveManagerBean.class); + + @PersistenceContext(unitName = RHQConstants.PERSISTENCE_UNIT_NAME) + private EntityManager entityManager; + + @EJB + private SubjectManagerLocal subjectManager; + + /* (non-Javadoc) + * @see org.rhq.enterprise.server.perspective.PerspectiveManagerLocal#getCoreMenu(org.rhq.core.domain.auth.Subject) + */ + @Override + public List<MenuItem> getCoreMenu(Subject subject) throws PerspectiveException { + List<MenuItem> coreMenu = null; + + try { + coreMenu = PerspectiveManagerHelper.getPluginMetadataManager().getCoreMenu(); + } catch (Exception e) { + throw new PerspectiveException("Failed to get Core Menu.", e); + } + + // TODO: Apply Activators here + + // TODO: Cache session:menu map here + + // TODO: remove this debug code + // printMenu(coreMenu, ""); + + return coreMenu; + } + + // TODO: remove this debug code + @SuppressWarnings("unused") + private void printMenu(List<MenuItem> menu, String indent) { + if (null == menu) + return; + + for (MenuItem menuItem : menu) { + System.out.println(indent + menuItem.getItem().getName()); + printMenu(menuItem.getChildren(), indent + ".."); + } + } + } \ No newline at end of file diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveManagerHelper.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveManagerHelper.java new file mode 100644 index 0000000..94c2d19 --- /dev/null +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveManagerHelper.java @@ -0,0 +1,42 @@ +package org.rhq.enterprise.server.perspective; + +import org.rhq.enterprise.server.plugin.pc.MasterServerPluginContainer; +import org.rhq.enterprise.server.plugin.pc.ServerPluginServiceManagement; +import org.rhq.enterprise.server.plugin.pc.perspective.PerspectiveServerPluginContainer; +import org.rhq.enterprise.server.plugin.pc.perspective.PerspectiveServerPluginManager; +import org.rhq.enterprise.server.plugin.pc.perspective.metadata.PerspectivePluginMetadataManager; +import org.rhq.enterprise.server.util.LookupUtil; + +public class PerspectiveManagerHelper { + + public static PerspectiveServerPluginContainer getPluginContainer() throws Exception { + PerspectiveServerPluginContainer pc = null; + + try { + ServerPluginServiceManagement mbean = LookupUtil.getServerPluginService(); + if (!mbean.isMasterPluginContainerStarted()) { + throw new IllegalStateException("The master plugin container is not started!"); + } + + MasterServerPluginContainer master = mbean.getMasterPluginContainer(); + pc = master.getPluginContainer(PerspectiveServerPluginContainer.class); + } catch (IllegalStateException ise) { + throw ise; + } catch (Exception e) { + throw new Exception("Cannot obtain the Perspective plugin container", e); + } + + if (pc == null) { + throw new Exception("Perspective plugin container is null!"); + } + + return pc; + } + + public static PerspectivePluginMetadataManager getPluginMetadataManager() throws Exception { + PerspectiveServerPluginManager manager = (PerspectiveServerPluginManager) getPluginContainer() + .getPluginManager(); + return manager.getMetadataManager(); + } + +} diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveManagerLocal.java index 139ac77..18d46b4 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveManagerLocal.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveManagerLocal.java @@ -18,8 +18,24 @@ */ package org.rhq.enterprise.server.perspective;
+import java.util.List; + import javax.ejb.Local;
+import org.rhq.core.domain.auth.Subject; + @Local public interface PerspectiveManagerLocal { + + /** + * Return the core menu for the specified subject. Depending on their inventory and roles the + * core menu for one subject1 could differ from that of subject2. + * + * Subsequent calls will return the same core menu for the same Subject. In other words, it does + * not change during a user session. + * + * @param subject + * @return + */ + List<MenuItem> getCoreMenu(Subject subject) throws PerspectiveException; } \ No newline at end of file diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/perspective/metadata/PerspectivePluginMetadataManager.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/perspective/metadata/PerspectivePluginMetadataManager.java index 9e86e6d..099e9fe 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/perspective/metadata/PerspectivePluginMetadataManager.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/perspective/metadata/PerspectivePluginMetadataManager.java @@ -186,4 +186,12 @@ public class PerspectivePluginMetadataManager { } return result; } + + /** + * @return the coreMenu + */ + public List<MenuItem> getCoreMenu() { + return coreMenu; + } + }
commit 314f6a3b66b4d4f6120bfc5685670be7f91d8cdc Author: Jay Shaughnessy jshaughn@redhat.com Date: Wed Nov 25 13:54:39 2009 -0500
Add more activator elements, reviewed optional/required settings, beefed up doc annotations. Worked on tab extensions.
diff --git a/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-perspective.xsd b/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-perspective.xsd index 5093db1..9223e1b 100644 --- a/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-perspective.xsd +++ b/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-perspective.xsd @@ -89,6 +89,9 @@ name="globalTask" type="perspective:TaskType"> xs:annotation + xs:documentation + Add a Global Task extension. + </xs:documentation> xs:appinfo <jaxb:class name="PerspectiveGlobalTaskElement" /> @@ -100,6 +103,9 @@ name="resourceTask" type="perspective:TaskType"> xs:annotation + xs:documentation + Add a Resource Task extension. + </xs:documentation> xs:appinfo <jaxb:class name="PerspectiveResourceTaskElement" /> @@ -126,12 +132,15 @@ maxOccurs="unbounded"> xs:annotation xs:documentation - Activate task only if the user has resources of the specified type in inventory. + Activate the extension only if the user has resources of the specified type in + inventory. Activated only if the user has the required permissions. At least one resource - activator required for - resource tasks. Activated for resources only if specified trait - conditions are also met. + activator + required for + resource task extensions. Activated for resources only if specified trait + conditions are + also met. </xs:documentation> </xs:annotation> </xs:element> @@ -141,7 +150,7 @@ maxOccurs="unbounded"> xs:annotation xs:documentation - Activate task only if the user has the required global permissions. + Activate the extension only if the user has the required global permissions. </xs:documentation> </xs:annotation> </xs:element> @@ -150,7 +159,8 @@ minOccurs="0" maxOccurs="1"> xs:annotation - xs:documentationOptional additional help text for the task.</xs:documentation> + xs:documentationVerbose display help text for the task extension. Displayed on request. + </xs:documentation> </xs:annotation> </xs:element> </xs:sequence> @@ -160,20 +170,19 @@ use="required"> xs:annotation xs:documentation - The task name. Unique within names defined by the perspective. Used for - display if - displayName not provided. - </xs:documentation> + Internal name for the task extension. Unique within extension names defined by the + perspective. + </xs:documentation> </xs:annotation> </xs:attribute> <xs:attribute name="displayName" type="perspective:DisplayNameType" - use="optional"> + use="required"> xs:annotation xs:documentation - The name used for display, if provided. - </xs:documentation> + The display name for the task extension. + </xs:documentation> </xs:annotation> </xs:attribute> <xs:attribute @@ -182,17 +191,17 @@ use="required"> xs:annotation xs:documentation - The task description displayed for the task. - </xs:documentation> + The display description for the task extension. + </xs:documentation> </xs:annotation> </xs:attribute> <xs:attribute name="url" type="xs:anyURI" - use="optional"> + use="required"> xs:annotation xs:documentation - The request URL for the task. Typically kicks off a wizard or similar workflow. + The request URL for the task extension. Typically kicks off a wizard or similar workflow. </xs:documentation> </xs:annotation> </xs:attribute> @@ -202,9 +211,9 @@ use="optional"> xs:annotation xs:documentation - Optional task category. Tasks for the same category will be grouped together. - Categories - are not predefined. + The display category for the task extension (optional). Tasks with the same category will + be grouped + together in the task pane. </xs:documentation> </xs:annotation> </xs:attribute> @@ -225,9 +234,7 @@ type="perspective:MenuItemType"> xs:annotation xs:documentation - Add or Remove a menu item in an existing menu extension point. Additions can specify - positioning as - well as a recursive structure, defineing a tree of MenuItems. + Add, Replace or Remove a menuItem extension for an existing menu extension point. </xs:documentation> xs:appinfo <jaxb:class @@ -241,14 +248,37 @@ xs:sequence <xs:element ref="perspective:position" - minOccurs="0" + minOccurs="1" maxOccurs="1"> xs:annotation xs:documentation - Required for root menuItem additions. Position of children is implicit given the - XML - structure. - </xs:documentation> + Required positioning element for the menuItem extension. + </xs:documentation> + </xs:annotation> + </xs:element> + <xs:element + ref="perspective:inventoryActivator" + minOccurs="0" + maxOccurs="unbounded"> + xs:annotation + xs:documentation + Activate the extension only if the user has resources of the specified type in + inventory. + Activated only if the user has the required permissions. Activated for + resources only if + specified trait + conditions are also met. + </xs:documentation> + </xs:annotation> + </xs:element> + <xs:element + ref="perspective:permissionActivator" + minOccurs="0" + maxOccurs="unbounded"> + xs:annotation + xs:documentation + Activate the extension only if the user has the required global permissions. + </xs:documentation> </xs:annotation> </xs:element> </xs:sequence> @@ -259,10 +289,10 @@ default="add"> xs:annotation xs:documentation - Add or remove the menu entry. For removal all but the name attribute are ignored. - Default - is add. - </xs:documentation> + Add, Replace or Remove the menuItem extension. For removal all but the name attribute are + ignored. + Default is add. + </xs:documentation> </xs:annotation> </xs:attribute> <xs:attribute @@ -271,10 +301,9 @@ use="required"> xs:annotation xs:documentation - ExtensionPoint name used for reference by other defined extension points. - Unique within + Internal name for the menuItem extension. Unique within extension names defined by the perspective. - </xs:documentation> + </xs:documentation> </xs:annotation> </xs:attribute> <xs:attribute @@ -283,8 +312,7 @@ use="optional"> xs:annotation xs:documentation - The displayed menu item name. Required for add actions. If empty an icon must be - defined. + The display name for the menuItem extension. If omitted an icon is required. </xs:documentation> </xs:annotation> </xs:attribute> @@ -294,8 +322,8 @@ use="optional"> xs:annotation xs:documentation - Certain menu items utilize special built-in rendering features. - </xs:documentation> + Certain menuItem extensions utilize special built-in rendering features. + </xs:documentation> </xs:annotation> </xs:attribute> <xs:attribute @@ -304,9 +332,11 @@ use="optional"> xs:annotation xs:documentation - The request URL for the menu entry. If not provided the entry is just a placeholder for - MenuItems. - </xs:documentation> + The request URL for the menuItem extension. If omitted it is assumed + the menuItem + exists as + a navigation element to child menuItems. + </xs:documentation> </xs:annotation> </xs:attribute> <xs:attribute @@ -315,9 +345,9 @@ use="optional"> xs:annotation xs:documentation - The request URL for the icon image for this menu item. If not provided then no image is - used. - </xs:documentation> + The request URL for the icon displayed for this menuItem extension. If omitted no image is + displayed. Required if displayName if omitted. + </xs:documentation> </xs:annotation> </xs:attribute> <xs:attribute @@ -333,135 +363,145 @@ </xs:complexType>
<xs:element - name="resourceTab"> + name="resourceTab" + type="perspective:TabType"> xs:annotation + xs:documentation + Add, Replace or Remove a resourceTab extension for a ResourceTab extension point. + </xs:documentation> xs:appinfo <jaxb:class name="PerspectiveResourceTabElement" /> </xs:appinfo> </xs:annotation> - xs:complexType - xs:sequence - <xs:element - ref="perspective:position" - minOccurs="0" - maxOccurs="1"> - xs:annotation - xs:documentation - Required for root menuItem additions. Position of children is implicit given the - XML - structure. - </xs:documentation> - </xs:annotation> - </xs:element> - </xs:sequence> - <xs:attribute - name="name" - type="perspective:NameType" - use="required"> - xs:annotation - xs:documentation - The menu entry name. Unique within menu items defined for the perspective. Displayed - on - screen. - </xs:documentation> - </xs:annotation> - </xs:attribute> - <xs:attribute - name="action" - type="perspective:ActionType" - use="optional" - default="add"> - xs:annotation - xs:documentation - Add or remove the menu entry. Add is the default. - </xs:documentation> - </xs:annotation> - </xs:attribute> - <xs:attribute - name="url" - type="xs:anyURI" - use="optional"> - xs:annotation - xs:documentation - The request URL for the menu entry. If not provided the entry is just a placeholder for - MenuItems. - </xs:documentation> - </xs:annotation> - </xs:attribute> - </xs:complexType> </xs:element>
<xs:element - name="resourceSubTab"> + name="resourceSubTab" + type="perspective:TabType"> xs:annotation + xs:documentation + Add, Replace or Remove a resourceSubTab extension for a ResourceTab extension point. + </xs:documentation> xs:appinfo <jaxb:class name="PerspectiveResourceSubTabElement" /> </xs:appinfo> </xs:annotation> - xs:complexType - xs:sequence - <xs:element - ref="perspective:position" - minOccurs="0" - maxOccurs="1"> - xs:annotation - xs:documentation - Required for root menuItem additions. Position of children is implicit given the - XML - structure. - </xs:documentation> - </xs:annotation> - </xs:element> - </xs:sequence> - <xs:attribute - name="name" - type="perspective:NameType" - use="required"> + </xs:element> + + <xs:complexType + name="TabType"> + xs:sequence + <xs:element + ref="perspective:position" + minOccurs="1" + maxOccurs="1"> xs:annotation xs:documentation - The menu entry name. Unique within menu items defined for the perspective. Displayed - on - screen. + Required positioning element for the Tab or SubTab extension. </xs:documentation> </xs:annotation> - </xs:attribute> - <xs:attribute - name="action" - type="perspective:ActionType" - use="optional" - default="add"> + </xs:element> + <xs:element + ref="perspective:inventoryActivator" + minOccurs="0" + maxOccurs="unbounded"> xs:annotation xs:documentation - Add or remove the menu entry. Add is the default. + Activate the extension only if the user has resources of the specified type in + inventory. + Activated only if the user has the required permissions. Activated for + resources only if + specified trait + conditions are also met. </xs:documentation> </xs:annotation> - </xs:attribute> - <xs:attribute - name="url" - type="xs:anyURI" - use="optional"> + </xs:element> + <xs:element + ref="perspective:permissionActivator" + minOccurs="0" + maxOccurs="unbounded"> xs:annotation xs:documentation - The request URL for the menu entry. If not provided the entry is just a placeholder for - MenuItems. + Activate task only if the user has the required global permissions. </xs:documentation> </xs:annotation> - </xs:attribute> - </xs:complexType> - </xs:element> + </xs:element> + </xs:sequence> + <xs:attribute + name="action" + type="perspective:ActionType" + use="optional" + default="add"> + xs:annotation + xs:documentation + Add, Replace or Remove the tab extension. For removal all but the name attribute are + ignored. Default is add.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute + name="name" + type="perspective:NameType" + use="required"> + xs:annotation + xs:documentation + Internal name for the tab extension. Unique within extension names defined by the + perspective.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute + name="displayName" + type="perspective:DisplayNameType" + use="required"> + xs:annotation + xs:documentation + The display name for the tab extension. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute + name="url" + type="xs:anyURI" + use="required"> + xs:annotation + xs:documentation + The request URL for the tab extension. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute + name="iconUrl" + type="xs:anyURI" + use="optional"> + xs:annotation + xs:documentation + The request URL for the icon displayed for this tab extension. If omitted no image is + displayed. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute + name="iconWidth" + type="xs:int" + use="optional"> + </xs:attribute> + <xs:attribute + name="iconHeight" + type="xs:int" + use="optional"> + </xs:attribute> + </xs:complexType>
<xs:element name="inventoryActivator"> xs:annotation + xs:documentationAn activator specifying inventory conditions that must be satisfied in order for the + extension to be active.</xs:documentation> xs:appinfo <jaxb:class name="InventoryActivatorElement" /> </xs:appinfo> - xs:documentation - Activators must be satisfied for the extension point to be active. - </xs:documentation> </xs:annotation>
xs:complexType @@ -482,9 +522,7 @@ type="xs:string" use="required"> xs:annotation - xs:documentation - Plugin for the specified resource type. - </xs:documentation> + xs:documentationPlugin for the specified resource type.</xs:documentation> </xs:annotation> </xs:attribute> <xs:attribute @@ -492,8 +530,7 @@ type="xs:string" use="required"> xs:annotation - xs:documentation - Resource Type that must be in inventory to activate the extension point. + xs:documentationResource Type that must be in inventory to activate the extension point. </xs:documentation> </xs:annotation> </xs:attribute> @@ -504,11 +541,8 @@ name="permissionActivator" type="perspective:PermissionType"> xs:annotation - xs:documentation - Activators must be satisfied for the extension point to be active. - The specified permission - must be available to the current user session. - </xs:documentation> + xs:documentationAn activator specifying a permission condition that must be satisfied in order for the + extension to be active.</xs:documentation> </xs:annotation> </xs:element>
@@ -516,11 +550,8 @@ name="traitActivator" type="perspective:TraitActivatorType"> xs:annotation - xs:documentation - Activators must be satisfied for the extension point to be active. - The specified permission - must be available to the current user session. - </xs:documentation> + xs:documentationAn activator specifying a resource trait conditions that must be satisfied in order for the + extension to be active.</xs:documentation> </xs:annotation> </xs:element>
@@ -531,9 +562,7 @@ type="xs:string" use="required"> xs:annotation - xs:documentation - The trait being tested for activation. - </xs:documentation> + xs:documentationThe trait being tested for activation.</xs:documentation> </xs:annotation> </xs:attribute> <xs:attribute @@ -541,10 +570,7 @@ type="xs:string" use="required"> xs:annotation - xs:documentation - The value of the trait. By default this is a 'contains' test. For equality, set strict to - true. - </xs:documentation> + xs:documentationThe value of the trait. By default, a case insensitive 'contains' test.</xs:documentation> </xs:annotation> </xs:attribute> <xs:attribute @@ -553,8 +579,7 @@ use="optional" default="false"> xs:annotation - xs:documentation - If true perform equality test. If false (default) perform a contains test. + xs:documentationIf true perform equality test. If false (default) perform a contains test. </xs:documentation> </xs:annotation> </xs:attribute> @@ -564,8 +589,7 @@ use="optional" default="false"> xs:annotation - xs:documentation - If true perform a case sensitive test. If false (default) test is sase insensitive. + xs:documentationIf true perform a case sensitive test. If false (default) test is case insensitive. </xs:documentation> </xs:annotation> </xs:attribute> @@ -575,6 +599,8 @@ name="position" type="perspective:PositionType"> xs:annotation + xs:documentationSpecifies positioning for an extension. Often relative to an existing extension. + </xs:documentation> xs:appinfo <jaxb:class name="PerspectivePositionElement" /> @@ -589,9 +615,7 @@ type="perspective:ExtensionPointNameType" use="required"> xs:annotation - xs:documentation - The extension point (a menu, resource tab bar, etc) where the insertion is occuring. - </xs:documentation> + xs:documentationThe extension point for which the extension is being positioned.</xs:documentation> </xs:annotation> </xs:attribute> <xs:attribute @@ -599,12 +623,8 @@ type="perspective:NameType" use="optional"> xs:annotation - xs:documentation - Position relatively against this name. Required for before/after positioning. - The name is - context specific, it could be a - menu entry name, a menu item name, tab name, subTab name, etc. - </xs:documentation> + xs:documentationPosition relatively against this extension name. Required for all placement relative to + another extension.</xs:documentation> </xs:annotation> </xs:attribute> <xs:attribute @@ -617,6 +637,10 @@ type="xs:boolean" use="optional" default="false"> + xs:annotation + xs:documentationIf true generate a break prior to this extension. Typically used for menuItem extensions, + ignored when breaks are nonsensical.</xs:documentation> + </xs:annotation> </xs:attribute> </xs:complexType>
@@ -624,8 +648,9 @@ name="ActionType"> xs:annotation xs:documentation - Add : Add new or Replaces existing + Add : Add new Remove : Removes existing + Replace : Replace existing </xs:documentation> </xs:annotation> <xs:restriction @@ -634,6 +659,8 @@ value="add"></xs:enumeration> <xs:enumeration value="remove"></xs:enumeration> + <xs:enumeration + value="replace"></xs:enumeration> </xs:restriction> </xs:simpleType>
@@ -764,5 +791,4 @@ </xs:restriction> </xs:simpleType>
- </xs:schema>
commit 9f95406ea4af3a31c1635eaa5d401aa05ad1e652 Author: John Sanda john@localhost.localdomain Date: Wed Nov 25 13:54:02 2009 -0500
[US 6] Updating raw config test plugin to support update operation for Raw Server
diff --git a/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/RawServer.groovy b/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/RawServer.groovy index c71f0fb..9acbbd8 100644 --- a/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/RawServer.groovy +++ b/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/RawServer.groovy @@ -6,6 +6,7 @@ import org.rhq.core.domain.configuration.Configuration import org.rhq.core.domain.configuration.RawConfiguration import org.rhq.core.domain.measurement.AvailabilityType import org.rhq.core.pluginapi.inventory.ResourceContext +import groovy.util.AntBuilder
class RawServer implements ResourceComponent, ResourceConfigurationFacet {
@@ -13,7 +14,11 @@ class RawServer implements ResourceComponent, ResourceConfigurationFacet {
File rawConfig1
+ def ant = new AntBuilder() + void start(ResourceContext context) { + ant = new AntBuilder() + rawConfigDir = new File("${System.getProperty('java.io.tmpdir')}/raw-config-test") rawConfig1 = new File(rawConfigDir, "raw-test-1.txt")
@@ -67,6 +72,12 @@ class RawServer implements ResourceComponent, ResourceConfigurationFacet { }
void persistRawConfiguration(RawConfiguration rawConfiguration) { + ant.copy(file: rawConfiguration.path, tofile: "${rawConfiguration.path}.orig") + ant.delete(file: rawConfiguration.path) + + def file = new File(rawConfiguration.path) + file.createNewFile() + file << rawConfiguration.contents }
void validateStructuredConfiguration(Configuration configuration) { diff --git a/modules/plugins/raw-config-test/src/test/groovy/org/rhq/plugins/test/rawconfig/RawServerTest.groovy b/modules/plugins/raw-config-test/src/test/groovy/org/rhq/plugins/test/rawconfig/RawServerTest.groovy new file mode 100644 index 0000000..ebb84c2 --- /dev/null +++ b/modules/plugins/raw-config-test/src/test/groovy/org/rhq/plugins/test/rawconfig/RawServerTest.groovy @@ -0,0 +1,29 @@ +package org.rhq.plugins.test.rawconfig + +import org.testng.annotations.Test +import org.rhq.core.domain.configuration.RawConfiguration + +class RawServerTest { + + @Test + void testPersistRawConfiguration() { + def rawFileName = "raw-test.txt" + def rawFile = new File(confDir, rawFileName) + + def contents = "hello world" + + rawFile << contents + + def updatedContents = "hello world from red hat" + + def rawConfig = new RawConfiguration(path: rawFile.absolutePath, contents: updatedContents.bytes) + + def rawServer = new RawServer() + rawServer.persistRawConfiguration(rawConfig) + } + + String getConfDir() { + getClass().getResource(".").toURI().path + } + +} \ No newline at end of file
commit 94a2f33e543fed0ce161d65dcb09c00e10519810 Author: Jay Shaughnessy jshaughn@redhat.com Date: Wed Nov 25 13:51:22 2009 -0500
NullPointer protection
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginManager.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginManager.java index 8eb7c70..c747814 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginManager.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginManager.java @@ -284,14 +284,17 @@ public class ServerPluginManager { MasterServerPluginContainerConfiguration masterConfig = masterPC.getConfiguration(); File dataDir = new File(masterConfig.getDataDirectory(), pluginName); File tmpDir = masterConfig.getTemporaryDirectory(); - Configuration plugnConfig; + Configuration pluginConfig = null; List<ScheduledJobDefinition> schedules; try { // TODO: today we have no way in the UI to customize the plugin config values // for now, just use the defaults as defined in the descriptor ConfigurationDefinition configDef = ServerPluginDescriptorMetadataParser .getPluginConfigurationDefinition(pluginDescriptor); - plugnConfig = configDef.getDefaultTemplate().createConfiguration(); + // It is not required that a server plugin define plugin configuration + if (null != configDef) { + pluginConfig = configDef.getDefaultTemplate().createConfiguration(); + }
// TODO: today we have no way in the UI to customize the schedules // for now, just use the defaults as defined in the descriptor @@ -301,7 +304,7 @@ public class ServerPluginManager { throw new RuntimeException(e); }
- context = new ServerPluginContext(env, dataDir, tmpDir, plugnConfig, schedules); + context = new ServerPluginContext(env, dataDir, tmpDir, pluginConfig, schedules); this.pluginContextCache.put(pluginName, context); return context; }
commit a3a2d66d3e662d330a79e75d7fe5b9393bfebd98 Merge: 1668456... 5479efd... Author: Adam Young ayoung@redhat.com Date: Wed Nov 25 12:51:43 2009 -0500
Merge branch 'raw-config' of ssh://git.fedorahosted.org/git/rhq/rhq into raw-config
commit 5479efd69802818f80c0fd27ee52a6a6cd555906 Author: John Sanda john@localhost.localdomain Date: Wed Nov 25 12:46:47 2009 -0500
[US 6] Refactoring ConfigurationManager.updateResourceConfiguration() to support raw config.
Adding an initial unit test for updateResourceConfiguration(). With this commit should be able to handle updates for resources that support structured only via the legacy API or raw only.
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManager.java index dd38c78..2bda0c3 100644 --- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManager.java +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManager.java @@ -115,11 +115,9 @@ public class ConfigurationManager extends AgentService implements ContainerServi public void updateResourceConfiguration(ConfigurationUpdateRequest request) { ConfigurationServerService configurationServerService = getConfigurationServerService();
- ConfigManagement configMgmt = new LegacyConfigManagement(); - configMgmt.setComponentService(componentService); - try { - ResourceType resourceType = getResourceType(request.getResourceId()); + ConfigManagement configMgmt = configMgmtFactory.getStrategy(request.getResourceId()); + ResourceType resourceType = componentService.getResourceType(request.getResourceId());
Runnable runnable = new UpdateResourceConfigurationRunner(configurationServerService, resourceType, configMgmt, request); @@ -311,6 +309,15 @@ public class ConfigurationManager extends AgentService implements ContainerServi }
/** + * This setter is here to provide a test hook + * + * @param threadPool A fake object such as a mock + */ + void setThreadPool(ScheduledExecutorService threadPool) { + this.threadPool = threadPool; + } + + /** * Given a resource ID, this obtains that resource's ConfigurationFacet interface. If it does not support the * configuration facet, an exception is thrown. * diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/UpdateResourceConfigurationRunner.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/UpdateResourceConfigurationRunner.java index 44bd6cd..eb4897b 100644 --- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/UpdateResourceConfigurationRunner.java +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/UpdateResourceConfigurationRunner.java @@ -80,6 +80,26 @@ public class UpdateResourceConfigurationRunner implements Runnable, Callable<Con this.request = request; }
+ ConfigurationUpdateRequest getRequest() { + return request; + } + + ConfigManagement getConfigMgmt() { + return configMgmt; + } + + ResourceType getResourceType() { + return resourceType; + } + + ConfigurationServerService getConfigurationServerService() { + return configurationServerService; + } + + ConfigurationUtilityService getConfigUtilService() { + return configUtilService; + } + void setConfigUtilService(ConfigurationUtilityService service) { configUtilService = service; } @@ -95,13 +115,8 @@ public class UpdateResourceConfigurationRunner implements Runnable, Callable<Con public ConfigurationUpdateResponse call() throws Exception { ConfigurationUpdateResponse response; int requestId = request.getConfigurationUpdateId(); -// ConfigurationUpdateReport report = new ConfigurationUpdateReport(request.getConfiguration()); - ConfigurationUpdateReport report = null; try { -// configurationFacet.updateResourceConfiguration(report); -// report = configMgmt.executeUpdate(request.getResourceId(), request.getConfiguration()); response = new ConfigurationUpdateResponse(requestId, request.getConfiguration(), SUCCESS, null); - try { configMgmt.executeUpdate(request.getResourceId(), request.getConfiguration()); } catch (UpdateInProgressException e) { @@ -112,10 +127,6 @@ public class UpdateResourceConfigurationRunner implements Runnable, Callable<Con response.setErrorMessage(e.getMessage()); }
-// if (response.getStatus() == ConfigurationUpdateStatus.INPROGRESS) { -// response.setErrorMessage("Configuration facet did not indicate success or failure - assuming failure."); -// } - ConfigurationDefinition configurationDefinition = resourceType.getResourceConfigurationDefinition();
// Normalize and validate the config. diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigurationManagerTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigurationManagerTest.java index 200ed40..9b0b910 100644 --- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigurationManagerTest.java +++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigurationManagerTest.java @@ -27,17 +27,26 @@ import static org.testng.Assert.*;
import org.jmock.Expectations; import org.rhq.core.clientapi.agent.PluginContainerException; +import org.rhq.core.clientapi.agent.configuration.ConfigurationUpdateRequest; +import org.rhq.core.clientapi.server.configuration.ConfigurationUpdateResponse; +import org.rhq.core.clientapi.server.configuration.ConfigurationServerService; import org.rhq.core.domain.configuration.Configuration; import org.rhq.core.domain.configuration.RawConfiguration; import org.rhq.core.domain.configuration.PropertySimple; import org.rhq.core.domain.resource.ResourceType; import org.rhq.core.pc.util.ComponentService; import org.rhq.core.pc.util.FacetLockType; +import org.rhq.core.pc.PluginContainerConfiguration; +import org.rhq.core.pc.ServerServices; import org.rhq.core.pluginapi.configuration.ResourceConfigurationFacet; +import org.rhq.test.jmock.PropertyMatcher; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; +import org.hamcrest.Matcher;
import java.util.Set; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.Callable;
public class ConfigurationManagerTest extends ConfigManagementTest {
@@ -317,4 +326,44 @@ public class ConfigurationManagerTest extends ConfigManagementTest { ); }
+ @Test + public void updatingConfigShouldSubmitRunnerToThreadPool() throws Exception { + int configUpdateId = -1; + + Configuration config = new Configuration(); + + ConfigurationUpdateRequest request = new ConfigurationUpdateRequest(configUpdateId, config, resourceId); + + final ScheduledExecutorService threadPool = context.mock(ScheduledExecutorService.class, "threadPool"); + configurationMgr.setThreadPool(threadPool); + + final ConfigManagement configMgmt = context.mock(ConfigManagement.class); + + final ConfigurationServerService configServerService = context.mock(ConfigurationServerService.class); + + PluginContainerConfiguration containerConfig = new PluginContainerConfiguration(); + ServerServices serverServices = new ServerServices(); + serverServices.setConfigurationServerService(configServerService); + + configurationMgr.setConfiguration(containerConfig); + + final UpdateResourceConfigurationRunner updateRunner = new UpdateResourceConfigurationRunner(configServerService, + resourceType, configMgmt, request); + + context.checking(new Expectations() {{ + allowing(componentService).getResourceType(resourceId); will(returnValue(resourceType)); + + atLeast(1).of(configMgmtFactory).getStrategy(resourceId); will(returnValue(configMgmt)); + + oneOf(threadPool).submit((Runnable)with(matchingUpdateRunner(updateRunner))); + }}); + + configurationMgr.updateResourceConfiguration(request); + } + + public static Matcher<UpdateResourceConfigurationRunner> matchingUpdateRunner( + UpdateResourceConfigurationRunner expected) { + return new PropertyMatcher<UpdateResourceConfigurationRunner>(expected); + } + } diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/UpdateResourceConfigurationRunnerTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/UpdateResourceConfigurationRunnerTest.java index f746942..0877668 100644 --- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/UpdateResourceConfigurationRunnerTest.java +++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/UpdateResourceConfigurationRunnerTest.java @@ -48,41 +48,23 @@ import org.testng.annotations.Test;
public class UpdateResourceConfigurationRunnerTest extends ConfigManagementTest {
- ComponentService componentService; - ConfigManagement configMgmt;
- ConfigurationFacet facet; + ConfigurationServerService configServerService; + + ConfigurationUtilityService configUtilService;
@BeforeMethod public void setup() throws Exception { - componentService = context.mock(ComponentService.class); - facet = context.mock(ConfigurationFacet.class); - configMgmt = context.mock(ConfigManagement.class); - - setDefaultExpectations(); - } - - void setDefaultExpectations() throws Exception { - final boolean daemonThread = false; - final boolean onlyIfStarted = true; - - context.checking(new Expectations() {{ - allowing(componentService).getComponent(resourceId, ConfigurationFacet.class, WRITE, FACET_METHOD_TIMEOUT, - daemonThread, onlyIfStarted); - will(returnValue(facet)); - }}); + configServerService = context.mock(ConfigurationServerService.class); + configUtilService = context.mock(ConfigurationUtilityService.class); }
@Test public void successfulUpdateShouldSendSuccessResponseToServer() throws Exception { final Configuration config = createStructuredConfig();
- final ConfigurationServerService configServerService = context.mock(ConfigurationServerService.class); - - final ConfigurationUtilityService configUtilService = context.mock(ConfigurationUtilityService.class); - int configUpdateId = -1;
ConfigurationUpdateRequest updateRequest = new ConfigurationUpdateRequest(configUpdateId, config, resourceId); @@ -103,15 +85,15 @@ public class UpdateResourceConfigurationRunnerTest extends ConfigManagementTest oneOf(configServerService).completeConfigurationUpdate(with(matchingResponse(successResponse))); }});
- updateRunner.call(); + ConfigurationUpdateResponse actualResponse = updateRunner.call(); + + assertConfigurationUpdateResponseMatches(successResponse, actualResponse, "Expected a success response"); }
@Test public void successfulUpdateShouldReturnSuccessResponseInEmbeddedMode() throws Exception { final Configuration config = createStructuredConfig();
- final ConfigurationUtilityService configUtilService = context.mock(ConfigurationUtilityService.class); - int configUpdateId = -1;
ConfigurationUpdateRequest updateRequest = new ConfigurationUpdateRequest(configUpdateId, config, resourceId); @@ -140,10 +122,6 @@ public class UpdateResourceConfigurationRunnerTest extends ConfigManagementTest public void inProgressUpdateShouldSendFailureResponseToServer() throws Exception { final Configuration config = createStructuredConfig();
- final ConfigurationServerService configServerService = context.mock(ConfigurationServerService.class); - - final ConfigurationUtilityService configUtilService = context.mock(ConfigurationUtilityService.class); - int configUpdateId = -1;
ConfigurationUpdateRequest updateRequest = new ConfigurationUpdateRequest(configUpdateId, config, resourceId); @@ -166,14 +144,47 @@ public class UpdateResourceConfigurationRunnerTest extends ConfigManagementTest oneOf(configServerService).completeConfigurationUpdate(with(matchingResponse(failureResponse))); }});
- updateRunner.call(); + ConfigurationUpdateResponse actualResponse = updateRunner.call(); + + assertConfigurationUpdateResponseMatches(failureResponse, actualResponse, "Expected a failure response"); }
@Test - public void failedUpdateShouldReturnFailureResponseInEmbeddedMode() throws Exception { + public void failedUpdateShouldSendFailureResponseToServer() throws Exception { final Configuration config = createStructuredConfig();
- final ConfigurationUtilityService configUtilService = context.mock(ConfigurationUtilityService.class); + final int configUpdateId = -1; + + ConfigurationUpdateRequest updateRequest = new ConfigurationUpdateRequest(configUpdateId, config, resourceId); + + UpdateResourceConfigurationRunner updateRunner = new UpdateResourceConfigurationRunner(configServerService, + resourceType, configMgmt, updateRequest); + updateRunner.setConfigUtilService(configUtilService); + + String errorMsg = "Configuration update failed."; + + final ConfigurationUpdateException exception = new ConfigurationUpdateException(errorMsg); + + final ConfigurationUpdateResponse failureResponse = new ConfigurationUpdateResponse(configUpdateId, config, + FAILURE, errorMsg); + + context.checking(new Expectations() {{ + oneOf(configMgmt).executeUpdate(resourceId, config); will(throwExceptionFromFacet(exception)); + + oneOf(configUtilService).normalizeConfiguration(config, resourceType.getResourceConfigurationDefinition()); + oneOf(configUtilService).validateConfiguration(config, resourceType.getResourceConfigurationDefinition()); + + oneOf(configServerService).completeConfigurationUpdate(with(matchingResponse(failureResponse))); + }}); + + ConfigurationUpdateResponse actualResponse = updateRunner.call(); + + assertConfigurationUpdateResponseMatches(failureResponse, actualResponse, "Expected a failure response"); + } + + @Test + public void failedUpdateShouldReturnFailureResponseInEmbeddedMode() throws Exception { + final Configuration config = createStructuredConfig();
int configUpdateId = -1;
@@ -203,11 +214,9 @@ public class UpdateResourceConfigurationRunnerTest extends ConfigManagementTest }
@Test - public void failureResponseShouldBeSentToServerWhenFacetThrowsAnException() throws Exception { + public void failureResponseShouldBeSentToServerWhenUnexpectedExceptionThrown() throws Exception { final Configuration config = createStructuredConfig();
- final ConfigurationServerService configServerService = context.mock(ConfigurationServerService.class); - int configUpdateId = -1;
ConfigurationUpdateRequest updateRequest = new ConfigurationUpdateRequest(configUpdateId, config, resourceId); @@ -226,11 +235,13 @@ public class UpdateResourceConfigurationRunnerTest extends ConfigManagementTest oneOf(configServerService).completeConfigurationUpdate(with(matchingResponse(failureResponse))); }});
- updateRunner.call(); + ConfigurationUpdateResponse actualResponse = updateRunner.call(); + + assertConfigurationUpdateResponseMatches(failureResponse, actualResponse, "Expected a failure response"); }
@Test - public void failureResponseShouldBeReturnedWhenFacetThrowsAnExceptionInEmbeddedMode() throws Exception { + public void failureResponseShouldBeReturnedWhenUnexpectedExceptionThrownInEmbeddedMode() throws Exception { final Configuration config = createStructuredConfig();
int configUpdateId = -1;
commit 02aebdca267d10a8c0bb3f2f071f3578be42d438 Author: John Sanda john@localhost.localdomain Date: Wed Nov 25 10:00:37 2009 -0500
[US 6] Updating call to RawConfig.deepCopy() to pass a boolean argument
Passing false to deepCopy() which indicates that ids should not be copied. This is consistent with the way it was formerly called in which deepCopy() did not take any arguments and did not copy ids.
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/RawConfigCollection.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/RawConfigCollection.java index dddfc0d..29dbe4b 100644 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/RawConfigCollection.java +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/RawConfigCollection.java @@ -238,7 +238,7 @@ public class RawConfigCollection extends AbstractConfigurationUIBean implements
String original = new String(getCurrent().getContents()); if (!updated.equals(original)) { - getRawConfigDelegate().current = getRawConfigDelegate().current.deepCopy(); + getRawConfigDelegate().current = getRawConfigDelegate().current.deepCopy(false); getRawConfigDelegate().current.setContents(updated.getBytes()); //TODO update other values like MD5 getModified().put(getRawConfigDelegate().current.getPath(), getRawConfigDelegate().current);
commit 89599e406e200a63dc9f82b7e7f0cb715294ccf5 Author: John Sanda john@localhost.localdomain Date: Wed Nov 25 09:44:45 2009 -0500
[US 6] Refactoring UpdateResourceConfigurationRunner to handle ConfigurationUpdateException
Refactoring UpdateResourceConfigurationRunnerTest to use a mock for ConfigManagement instead of a concrete implementation. Concrete implementations will be tested separately.
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/UpdateResourceConfigurationRunner.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/UpdateResourceConfigurationRunner.java index ccdbc20..44bd6cd 100644 --- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/UpdateResourceConfigurationRunner.java +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/UpdateResourceConfigurationRunner.java @@ -107,6 +107,9 @@ public class UpdateResourceConfigurationRunner implements Runnable, Callable<Con } catch (UpdateInProgressException e) { response.setStatus(INPROGRESS); response.setErrorMessage("Configuration facet did not indicate success or failure - assuming failure."); + } catch (ConfigurationUpdateException e) { + response.setStatus(FAILURE); + response.setErrorMessage(e.getMessage()); }
// if (response.getStatus() == ConfigurationUpdateStatus.INPROGRESS) { diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/UpdateResourceConfigurationRunnerTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/UpdateResourceConfigurationRunnerTest.java index 0c87833..f746942 100644 --- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/UpdateResourceConfigurationRunnerTest.java +++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/UpdateResourceConfigurationRunnerTest.java @@ -59,9 +59,8 @@ public class UpdateResourceConfigurationRunnerTest extends ConfigManagementTest componentService = context.mock(ComponentService.class); facet = context.mock(ConfigurationFacet.class);
- configMgmt = new LegacyConfigManagement(); - configMgmt.setComponentService(componentService); - + configMgmt = context.mock(ConfigManagement.class); + setDefaultExpectations(); }
@@ -80,8 +79,6 @@ public class UpdateResourceConfigurationRunnerTest extends ConfigManagementTest public void successfulUpdateShouldSendSuccessResponseToServer() throws Exception { final Configuration config = createStructuredConfig();
- configMgmt = context.mock(ConfigManagement.class); - final ConfigurationServerService configServerService = context.mock(ConfigurationServerService.class);
final ConfigurationUtilityService configUtilService = context.mock(ConfigurationUtilityService.class); @@ -113,8 +110,6 @@ public class UpdateResourceConfigurationRunnerTest extends ConfigManagementTest public void successfulUpdateShouldReturnSuccessResponseInEmbeddedMode() throws Exception { final Configuration config = createStructuredConfig();
- configMgmt = context.mock(ConfigManagement.class); - final ConfigurationUtilityService configUtilService = context.mock(ConfigurationUtilityService.class);
int configUpdateId = -1; @@ -145,8 +140,6 @@ public class UpdateResourceConfigurationRunnerTest extends ConfigManagementTest public void inProgressUpdateShouldSendFailureResponseToServer() throws Exception { final Configuration config = createStructuredConfig();
- configMgmt = context.mock(ConfigManagement.class); - final ConfigurationServerService configServerService = context.mock(ConfigurationServerService.class);
final ConfigurationUtilityService configUtilService = context.mock(ConfigurationUtilityService.class); @@ -180,8 +173,6 @@ public class UpdateResourceConfigurationRunnerTest extends ConfigManagementTest public void failedUpdateShouldReturnFailureResponseInEmbeddedMode() throws Exception { final Configuration config = createStructuredConfig();
- //final ConfigurationFacet facet = context.mock(ConfigurationFacet.class); - final ConfigurationUtilityService configUtilService = context.mock(ConfigurationUtilityService.class);
int configUpdateId = -1; @@ -192,14 +183,15 @@ public class UpdateResourceConfigurationRunnerTest extends ConfigManagementTest configMgmt, updateRequest); updateRunner.setConfigUtilService(configUtilService);
- String errorMsg = "Configuration facet did not indicate success or failure - assuming failure."; + String errorMsg = "Configuration update failed."; + + final ConfigurationUpdateException exception = new ConfigurationUpdateException(errorMsg);
final ConfigurationUpdateResponse failureResponse = new ConfigurationUpdateResponse(configUpdateId, config, FAILURE, errorMsg);
context.checking(new Expectations() {{ - oneOf(facet).updateResourceConfiguration(with(any(ConfigurationUpdateReport.class))); - will(updateReportTo(INPROGRESS)); + oneOf(configMgmt).executeUpdate(resourceId, config); will(throwExceptionFromFacet(exception));
oneOf(configUtilService).normalizeConfiguration(config, resourceType.getResourceConfigurationDefinition()); oneOf(configUtilService).validateConfiguration(config, resourceType.getResourceConfigurationDefinition()); @@ -216,8 +208,6 @@ public class UpdateResourceConfigurationRunnerTest extends ConfigManagementTest
final ConfigurationServerService configServerService = context.mock(ConfigurationServerService.class);
- //final ConfigurationFacet facet = context.mock(ConfigurationFacet.class); - int configUpdateId = -1;
ConfigurationUpdateRequest updateRequest = new ConfigurationUpdateRequest(configUpdateId, config, resourceId); @@ -231,8 +221,7 @@ public class UpdateResourceConfigurationRunnerTest extends ConfigManagementTest exception);
context.checking(new Expectations() {{ - oneOf(facet).updateResourceConfiguration(with(any(ConfigurationUpdateReport.class))); - will(throwExceptionFromFacet(exception)); + oneOf(configMgmt).executeUpdate(resourceId, config); will(throwExceptionFromFacet(exception));
oneOf(configServerService).completeConfigurationUpdate(with(matchingResponse(failureResponse))); }}); @@ -257,7 +246,7 @@ public class UpdateResourceConfigurationRunnerTest extends ConfigManagementTest exception);
context.checking(new Expectations() {{ - oneOf(facet).updateResourceConfiguration(with(any(ConfigurationUpdateReport.class))); + oneOf(configMgmt).executeUpdate(resourceId, config); will(throwExceptionFromFacet(exception)); }});
commit ee3d23efd54deea192fde06e66f7bdf7a57512e0 Author: Heiko W. Rupp pilhuhn@fedorapeople.org Date: Wed Nov 25 12:45:44 2009 +0100
First cut at alert plugin xml schema (#1139)
diff --git a/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-alert.xsd b/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-alert.xsd index 99a3b45..dc4d925 100644 --- a/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-alert.xsd +++ b/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-alert.xsd @@ -2,6 +2,7 @@
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:serverplugin="urn:xmlns:rhq-serverplugin" + xmlns:config="urn:xmlns:rhq-configuration" xmlns:c="urn:xmlns:rhq-configuration" xmlns:alert="urn:xmlns:rhq-serverplugin.alert" targetNamespace="urn:xmlns:rhq-serverplugin.alert" @@ -15,7 +16,7 @@
xs:annotation xs:documentation - Schema for alert server-side plugins. + Schema for alert server-side plug-ins. </xs:documentation> xs:appinfo jaxb:schemaBindings @@ -27,7 +28,7 @@ <xs:element name="alert-plugin" type="alert:AlertPluginDescriptorType" substitutionGroup="serverplugin:server-plugin"> xs:annotation xs:documentation - Defines an alert plugin. This type of plugin allows you to create your own + Defines an alert plug-in. This type of plug-in allows you to create your own alert handlers, enabling you to send alerts to custom endpoints. </xs:documentation> xs:appinfo @@ -39,10 +40,35 @@ xs:complexContent <xs:extension base="serverplugin:ServerPluginDescriptorType"> xs:sequence + <xs:element name="shortName" minOccurs="1" maxOccurs="1"> + xs:annotation + xs:documentation + The short name of this plugin as it will be shown in Headers and drop down boxes + </xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="pluginClass" minOccurs="1" maxOccurs="1"> + xs:annotation + xs:documentation + The name of the class implementing the plugin functionality. This class needs to + implement the org.rhq.enterprise.server.plugin.pc.alert.AlertSender base class + </xs:documentation> + </xs:annotation> + </xs:element> <!-- alert specific schema goes here. note, serverplugin xsd gives you global <plugin-configuration> already --> + <xs:element ref="alert:alert-configuration" minOccurs="0" maxOccurs="1"/> </xs:sequence> </xs:extension> </xs:complexContent> </xs:complexType>
+ <xs:element name="alert-configuration" type="config:configuration"> + xs:annotation + xs:documentation + This section defines the configuration items that are used for individual alert templates. + </xs:documentation> + </xs:annotation> + + </xs:element> + </xs:schema>
commit 2c501cc0a0dc79a3ce4b5eecfec5009259be69f4 Author: Heiko W. Rupp pilhuhn@fedorapeople.org Date: Wed Nov 25 12:41:46 2009 +0100
First cut at AlertSender api. (#1116)
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSender.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSender.java new file mode 100644 index 0000000..6adc6f6 --- /dev/null +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSender.java @@ -0,0 +1,56 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2009 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.plugin.pc.alert; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.rhq.core.domain.alert.Alert; +import org.rhq.core.domain.configuration.Configuration; + +/** + * Abstract base class for all Alert senders. In order to implement your + * AlertSender, you need to at least overwrite #send(). When the AlertSenderManager + * constructs this object, it will inject the preferences for your specific alert sender + * type. + * For each Alert a new instance of your implementation will be called and destroyed + * afterwards. + * + * @author Heiko W. Rupp + * + */ +public abstract class AlertSender { + + private final Log log = LogFactory.getLog(AlertSender.class); + + /** Configuration from the global per plugin type preferences */ + protected Configuration preferences; + + /** Configuration from the per alert definition parameters */ + protected Configuration alertParameters; + + + /** + * This method is called to actually send an alert notification. + * This is where you implement all functionality. + * @param alert the Alert to operate on + * @return result of sending - a ResultState and a message for auditing + */ + public abstract SenderResult send(Alert alert) ; +} diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/ResultState.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/ResultState.java new file mode 100644 index 0000000..8133ba9 --- /dev/null +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/ResultState.java @@ -0,0 +1,29 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2009 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.plugin.pc.alert; + +/** + * State of a SenderResult + * @author Heiko W. Rupp + * @see SenderResult + */ +public enum ResultState { + SUCCESS, + FAILURE; +} diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/SenderResult.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/SenderResult.java new file mode 100644 index 0000000..b5a49a1 --- /dev/null +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/SenderResult.java @@ -0,0 +1,83 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2009 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.plugin.pc.alert; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * The result of sending an alert notification via AlertSender#send() + * @author Heiko W. Rupp + */ +public class SenderResult { + + private String message; + private ResultState state; + + public SenderResult(ResultState state, String message) { + this.message = message; + this.state = state; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public ResultState getState() { + return state; + } + + public void setState(ResultState state) { + this.state = state; + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder(); + sb.append("SenderResult"); + sb.append("{message='").append(message).append('''); + sb.append(", state=").append(state); + sb.append('}'); + return sb.toString(); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + SenderResult that = (SenderResult) o; + + if (message != null ? !message.equals(that.message) : that.message != null) return false; + if (state != that.state) return false; + + return true; + } + + @Override + public int hashCode() { + int result = message != null ? message.hashCode() : 0; + result = 31 * result + (state != null ? state.hashCode() : 0); + return result; + } +}
commit 90a38475a395fa6088bb6b744149c136a9acd961 Author: John Sanda john@localhost.localdomain Date: Tue Nov 24 22:50:24 2009 -0500
[US 6] Refactoring Configuration.deepCopy() to properly handle hibernate proxies.
Refactoring implementors of DeepCopyable to take a boolean flag that indicates whether or not to copy the id field. Unit tests have been updated to reflect the change.
diff --git a/modules/core/domain/src/main/java/META-INF/MANIFEST.MF b/modules/core/domain/src/main/java/META-INF/MANIFEST.MF new file mode 100644 index 0000000..3090f97 --- /dev/null +++ b/modules/core/domain/src/main/java/META-INF/MANIFEST.MF @@ -0,0 +1,4 @@ +Manifest-Version: 1.0 +Class-Path: i18nlog-1.0.9.jar jaxb-api-2.1.jar stax-api-1.0-2.jar acti + vation-1.1.jar rhq-core-util-1.4.0-SNAPSHOT.jar jdom-1.0.jar + diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/Configuration.java b/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/Configuration.java index c5ca304..dcebf96 100644 --- a/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/Configuration.java +++ b/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/Configuration.java @@ -453,64 +453,39 @@ public class Configuration implements Externalizable, Cloneable, AbstractPropert * @return the new copy */ public Configuration deepCopy(boolean keepIds) { - if (!keepIds) { - return deepCopyWithoutProxies(); - } - - Configuration copy; + Configuration copy = new Configuration();
- try { - copy = clone(); - } catch (CloneNotSupportedException e) { - throw new RuntimeException("CloneNotSupported can't happen"); + if (keepIds) { + copy.id = this.id; }
- if (!keepIds) { - copy.id = 0; - - for (Property property : copy.properties.values()) { - clearIds(property); - } - } + copy.notes = this.notes; + copy.version = this.version; + createDeepCopyOfProperties(copy, keepIds); + createDeepCopyOfRawConfigs(copy, keepIds);
return copy; }
- private void clearIds(Property property) { - property.setId(0); - - if (property instanceof PropertyList) { - for (Property childProperty : ((PropertyList) property).getList()) { - clearIds(childProperty); - } - } else if (property instanceof PropertyMap) { - for (Property childProperty : ((PropertyMap) property).getMap().values()) { - clearIds(childProperty); - } - } - - return; - } - public Configuration deepCopyWithoutProxies() { Configuration copy = new Configuration(); copy.notes = this.notes; copy.version = this.version; - createDeepCopyOfProperties(copy); - createDeepCopyOfRawConfigs(copy); + createDeepCopyOfProperties(copy, false); + createDeepCopyOfRawConfigs(copy, false);
return copy; }
- private void createDeepCopyOfRawConfigs(Configuration copy) { + private void createDeepCopyOfRawConfigs(Configuration copy, boolean keepId) { for (RawConfiguration rawConfig : rawConfigurations) { - copy.addRawConfiguration(rawConfig.deepCopy()); + copy.addRawConfiguration(rawConfig.deepCopy(keepId)); } }
- private void createDeepCopyOfProperties(Configuration copy) { + private void createDeepCopyOfProperties(Configuration copy, boolean keepId) { for (Property property : this.properties.values()) { - copy.put(property.deepCopy()); + copy.put(property.deepCopy(keepId)); } }
@@ -661,7 +636,7 @@ public class Configuration implements Externalizable, Cloneable, AbstractPropert private Map<String, Property> createDeepCopyOfMap() { Map<String, Property> copy = new HashMap<String, Property>(); for (Map.Entry<String, Property> entry : this.properties.entrySet()) { - copy.put(entry.getKey(), entry.getValue().deepCopy()); + copy.put(entry.getKey(), entry.getValue().deepCopy(true)); } return copy; } @@ -669,7 +644,7 @@ public class Configuration implements Externalizable, Cloneable, AbstractPropert private Set<RawConfiguration> createDeepCopyOfRawConfigs() { Set<RawConfiguration> copy = new HashSet<RawConfiguration>(); for (RawConfiguration rawConfig : this.rawConfigurations) { - copy.add(rawConfig.deepCopy()); + copy.add(rawConfig.deepCopy(true)); } return copy; } diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/DeepCopyable.java b/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/DeepCopyable.java index e3e56d5..c680b04 100644 --- a/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/DeepCopyable.java +++ b/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/DeepCopyable.java @@ -25,6 +25,6 @@ package org.rhq.core.domain.configuration;
public interface DeepCopyable<T> {
- T deepCopy(); + T deepCopy(boolean keepId);
} diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/Property.java b/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/Property.java index f4494c8..5c1ba79 100644 --- a/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/Property.java +++ b/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/Property.java @@ -127,7 +127,10 @@ public class Property implements Externalizable, DeepCopyable<Property> { public Property() { }
- protected Property(Property original) { + protected Property(Property original, boolean keepId) { + if (keepId) { + this.id = original.id; + } this.errorMessage = original.errorMessage; this.name = original.name; } @@ -284,7 +287,7 @@ public class Property implements Externalizable, DeepCopyable<Property> { return ((this.name != null) ? this.name.hashCode() : 0); }
- public Property deepCopy() { + public Property deepCopy(boolean keepId) { return null; }
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/PropertyList.java b/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/PropertyList.java index aff96b9..c3e26a0 100644 --- a/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/PropertyList.java +++ b/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/PropertyList.java @@ -86,8 +86,8 @@ public class PropertyList extends Property { setName(name); }
- protected PropertyList(PropertyList original) { - super(original); + protected PropertyList(PropertyList original, boolean keepId) { + super(original, keepId); }
/** @@ -212,11 +212,11 @@ public class PropertyList extends Property { return result; }
- public PropertyList deepCopy() { - PropertyList copy = new PropertyList(this); + public PropertyList deepCopy(boolean keepId) { + PropertyList copy = new PropertyList(this, keepId);
for (Property property : list) { - copy.add(property.deepCopy()); + copy.add(property.deepCopy(false)); }
return copy; diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/PropertyMap.java b/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/PropertyMap.java index e901377..e8e15b7 100644 --- a/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/PropertyMap.java +++ b/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/PropertyMap.java @@ -76,8 +76,8 @@ public class PropertyMap extends Property implements AbstractPropertyMap { public PropertyMap() { }
- protected PropertyMap(PropertyMap original) { - super(original); + protected PropertyMap(PropertyMap original, boolean keepId) { + super(original, keepId); }
/** @@ -263,11 +263,11 @@ public class PropertyMap extends Property implements AbstractPropertyMap { return result; }
- public PropertyMap deepCopy() { - PropertyMap copy = new PropertyMap(this); + public PropertyMap deepCopy(boolean keepId) { + PropertyMap copy = new PropertyMap(this, keepId);
for (Property property : map.values()) { - copy.put(property.deepCopy()); + copy.put(property.deepCopy(keepId)); }
return copy; diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/PropertySimple.java b/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/PropertySimple.java index 0824553..04aeb7e 100644 --- a/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/PropertySimple.java +++ b/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/PropertySimple.java @@ -70,8 +70,8 @@ public class PropertySimple extends Property implements Externalizable { override = Boolean.FALSE; }
- protected PropertySimple(PropertySimple original) { - super(original); + protected PropertySimple(PropertySimple original, boolean keepId) { + super(original, keepId); this.override = original.override; this.unmaskedStringValue = original.unmaskedStringValue; this.stringValue = original.stringValue; @@ -85,9 +85,7 @@ public class PropertySimple extends Property implements Externalizable { * @param name * @param value */ - public PropertySimple(@NotNull - String name, @Nullable - Object value) { + public PropertySimple(@NotNull String name, @Nullable Object value) { setName(name); setValue(value); } @@ -98,8 +96,7 @@ public class PropertySimple extends Property implements Externalizable { * * @param value */ - public void setValue(@Nullable - Object value) { + public void setValue(@Nullable Object value) { if (value == null) { stringValue = null; return; @@ -131,8 +128,7 @@ public class PropertySimple extends Property implements Externalizable { * * @param value */ - public void setStringValue(@Nullable - String value) { + public void setStringValue(@Nullable String value) { this.setValue(value); }
@@ -157,8 +153,7 @@ public class PropertySimple extends Property implements Externalizable { * * @param value */ - public void setBooleanValue(@Nullable - Boolean value) { + public void setBooleanValue(@Nullable Boolean value) { this.setValue(value); }
@@ -207,8 +202,7 @@ public class PropertySimple extends Property implements Externalizable { * * @param value */ - public void setIntegerValue(@Nullable - Integer value) { + public void setIntegerValue(@Nullable Integer value) { this.setValue(value); }
@@ -232,8 +226,7 @@ public class PropertySimple extends Property implements Externalizable { * * @param value */ - public void setFloatValue(@Nullable - Float value) { + public void setFloatValue(@Nullable Float value) { this.setValue(value); }
@@ -257,8 +250,7 @@ public class PropertySimple extends Property implements Externalizable { * * @param value */ - public void setDoubleValue(@Nullable - Double value) { + public void setDoubleValue(@Nullable Double value) { this.setValue(value); }
@@ -336,8 +328,8 @@ public class PropertySimple extends Property implements Externalizable { return result; }
- public PropertySimple deepCopy() { - return new PropertySimple(this); + public PropertySimple deepCopy(boolean keepId) { + return new PropertySimple(this, keepId); }
@Override diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/RawConfiguration.java b/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/RawConfiguration.java index 4e1cdc4..1bb27c9 100644 --- a/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/RawConfiguration.java +++ b/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/RawConfiguration.java @@ -240,9 +240,14 @@ public class RawConfiguration implements Serializable, DeepCopyable<RawConfigura .toString(); }
- public RawConfiguration deepCopy() { + public RawConfiguration deepCopy(boolean keepId) { RawConfiguration copy = new RawConfiguration(); + if (keepId) { + copy.id = this.id; + } + copy.path = this.path; + if (this.contents != null) { copy.setContents(this.getContents()); } diff --git a/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/ConfigurationTest.java b/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/ConfigurationTest.java index 5f8ce70..72da7c0 100644 --- a/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/ConfigurationTest.java +++ b/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/ConfigurationTest.java @@ -43,59 +43,107 @@ import java.io.ObjectInputStream; public class ConfigurationTest {
@Test - public void deepCopyWithoutProxiesShouldNotReturnReferenceToOriginalObject() { + public void deepCopyShouldNotReturnReferenceToOriginalObjectWhenKeepingIds() { Configuration original = createConfiguration(); - Configuration copy = original.deepCopyWithoutProxies(); + Configuration copy = original.deepCopy(true);
assertNotSame(copy, original, "Expected a reference to a new Configuration object, not the original object being copied"); }
@Test - public void deepCopyWithoutProxiesShouldCopySimpleFields() { + public void deepCopyShouldNotReturnReferenceToOriginalObjectWhenNotKeepingIds() { Configuration original = createConfiguration(); - Configuration copy = original.deepCopyWithoutProxies(); + Configuration copy = original.deepCopy(false);
+ assertNotSame(copy, original, "Expected a reference to a new Configuration object, not the original object being copied"); + } + + @Test + public void deepCopyShouldCopyAllSimpleFieldsWhenKeepingIds() { + Configuration original = createConfiguration(); + Configuration copy = original.deepCopy(true); + + assertEquals(copy.getId(), original.getId(), "Failed to copy the id property"); assertEquals(copy.getNotes(), original.getNotes(), "Failed to copy the notes property"); assertEquals(copy.getVersion(), original.getVersion(), "Failed to copy version property"); }
@Test - public void deepCopyWithoutProxiesShouldNotCopyIdProperty() { + public void deepCopyShouldNotCopyIdWhenNotKeepingIds() { Configuration original = createConfiguration(); - Configuration copy = original.deepCopyWithoutProxies(); + Configuration copy = original.deepCopy(false);
assertFalse(copy.getId() == original.getId(), "The original id property should not be copied"); + assertEquals(copy.getNotes(), original.getNotes(), "Failed to copy the notes property"); + assertEquals(copy.getVersion(), original.getVersion(), "Failed to copy version property"); + } + + @Test + public void deepCopyShouldCopyPropertiesWhenKeepingIds() { + Configuration original = createConfiguration(); + original.put(new PropertySimple("simpleProperty", "Simple Property")); + + Configuration copy = original.deepCopy(true); + + assertNotSame(copy.getProperties(), original.getProperties(), "The properties property should not refer to the properties in the original object"); + assertEquals(copy.getProperties(), original.getProperties(), "Failed to copy the contents of the properties collection"); }
@Test - public void deepCopyWithoutProxiesShouldCopyProperties() { + public void deepCopyShouldCopyPropertiesWhenNotKeepingIds() { Configuration original = createConfiguration(); original.put(new PropertySimple("simpleProperty", "Simple Property"));
- Configuration copy = original.deepCopyWithoutProxies(); + Configuration copy = original.deepCopy(false);
assertNotSame(copy.getProperties(), original.getProperties(), "The properties property should not refer to the properties in the original object"); assertEquals(copy.getProperties(), original.getProperties(), "Failed to copy the contents of the properties collection"); }
@Test - public void deepCopyWithoutProxiesShouldNotReturnCopyReferenceOfOriginalProperty() { + public void deepCopyShouldNotReturnCopyReferenceOfOriginalPropertyWhenKeepingIds() { Configuration original = createConfiguration(); String propertyName = "simpleProperty"; original.put(new PropertySimple(propertyName, "Simple Property"));
- Configuration copy = original.deepCopyWithoutProxies(); + Configuration copy = original.deepCopy(true);
assertNotSame(copy.get(propertyName), original.get(propertyName), "Expected a refernce to a new property, not the original property being copied"); }
@Test - public void deepCopyWithoutProxiesShouldSetParentReferenceOfCopiedProperties() { + public void deepCopyShouldNotReturnCopyReferenceOfOriginalPropertyWhenNotKeepingIds() { + Configuration original = createConfiguration(); + String propertyName = "simpleProperty"; + original.put(new PropertySimple(propertyName, "Simple Property")); + + Configuration copy = original.deepCopy(false); + + assertNotSame(copy.get(propertyName), original.get(propertyName), "Expected a refernce to a new property, not the original property being copied"); + } + + @Test + public void deepCopyShouldSetParentReferenceOfCopiedPropertiesWhenKeepingIds() { + Configuration original = createConfiguration(); + String propertyName = "simpleProperty"; + original.put(new PropertySimple(propertyName, "Simple Property")); + + Configuration copy = original.deepCopy(true); + + assertSame( + copy.get(propertyName).getConfiguration(), + copy, + "The reference to the parent configuration should point to the newly copied configuration, not the original configuration" + ); + } + + @Test + public void deepCopyShouldSetParentReferenceOfCopiedPropertiesWhenNotKeepingIds() { Configuration original = createConfiguration(); String propertyName = "simpleProperty"; original.put(new PropertySimple(propertyName, "Simple Property"));
- Configuration copy = original.deepCopyWithoutProxies(); + Configuration copy = original.deepCopy(false);
assertSame( copy.get(propertyName).getConfiguration(), @@ -105,11 +153,27 @@ public class ConfigurationTest { }
@Test - public void deepCopyWithoutProxiesShouldCopyRawConfigurations() { + public void deepCopyShouldCopyRawConfigurationsWhenKeepingIds() { Configuration original = createConfiguration(); original.addRawConfiguration(createRawConfiguration("/tmp/foo"));
- Configuration copy = original.deepCopyWithoutProxies(); + Configuration copy = original.deepCopy(true); + + assertNotSame( + copy.getRawConfigurations(), + original.getRawConfigurations(), + "The rawConfigurations property should not refer to the original rawConfigurations of the copied object." + ); + + assertRawConfigurationsEquals(copy.getRawConfigurations(), original.getRawConfigurations(), "Failed to copy rawConfigurations property."); + } + + @Test + public void deepCopyShouldCopyRawConfigurationsWhenNotKeepingIds() { + Configuration original = createConfiguration(); + original.addRawConfiguration(createRawConfiguration("/tmp/foo")); + + Configuration copy = original.deepCopy(false);
assertNotSame( copy.getRawConfigurations(), @@ -128,11 +192,26 @@ public class ConfigurationTest { }
@Test - public void deepCopyWithoutProxiesShouldSetParentReferenceOfCopiedRawConfigurations() { + public void deepCopyShouldSetParentReferenceOfCopiedRawConfigurationsWhenKeepingIds() { + Configuration original = createConfiguration(); + original.addRawConfiguration(createRawConfiguration("/tmp/foo")); + + Configuration copy = original.deepCopy(true); + RawConfiguration copiedRawConfig = getCopiedRawConfiguration(copy); + + assertSame( + copiedRawConfig.getConfiguration(), + copy, + "The reference to the parent configuration should point to the newly copied configuration, not the original configuration." + ); + } + + @Test + public void deepCopyShouldSetParentReferenceOfCopiedRawConfigurationsWhenNotKeepingIds() { Configuration original = createConfiguration(); original.addRawConfiguration(createRawConfiguration("/tmp/foo"));
- Configuration copy = original.deepCopyWithoutProxies(); + Configuration copy = original.deepCopy(false); RawConfiguration copiedRawConfig = getCopiedRawConfiguration(copy);
assertSame( diff --git a/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/PropertyListTest.java b/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/PropertyListTest.java index d298001..56d3887 100644 --- a/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/PropertyListTest.java +++ b/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/PropertyListTest.java @@ -30,41 +30,52 @@ import org.testng.annotations.Test; public class PropertyListTest {
@Test - public void deepCopyShouldCopySimpleFields() { + public void deepCopyShouldCopyAllSimpleFields() { PropertyList original = createPropertyList();
- PropertyList copy = original.deepCopy(); + PropertyList copy = original.deepCopy(true);
assertNotSame(copy, original, "The copy should not reference the original object"); - + + assertEquals(copy.getId(), original.getId(), "Failed to copy the id property"); assertEquals(copy.getName(), original.getName(), "Failed to copy the name property"); assertEquals(copy.getErrorMessage(), original.getErrorMessage(), "Failed to copy the errorMessage property"); }
@Test - public void deepCopyShouldNotCopyIdField() { + public void deepCopyShouldNotCopyIdFieldWhenFlagIsFalse() { PropertyList original = createPropertyList(); - PropertyList copy = original.deepCopy(); + PropertyList copy = original.deepCopy(false);
assertFalse(copy.getId() == original.getId(), "The original id property should not be copied."); + assertEquals(copy.getName(), original.getName(), "Failed to copy the name property"); + assertEquals(copy.getErrorMessage(), original.getErrorMessage(), "Failed to copy the errorMessage property"); + } + + @Test + public void deepCopyShouldNotCopyReferenceOfUnderlyingListWhenIdIncluded() { + PropertyList original = createPropertyList(); + PropertyList copy = original.deepCopy(true); + + assertNotSame(original.getList(), copy.getList(), "The values in the underlying list should be copied, not the variable reference to the list."); }
@Test - public void deepCopyShouldNotCopyReferenceOfUnderlyingList() { + public void deepCopyShouldNotCopyReferenceOfUnderlyingListWhenIdNotIncluded() { PropertyList original = createPropertyList(); - PropertyList copy = original.deepCopy(); + PropertyList copy = original.deepCopy(false);
assertNotSame(original.getList(), copy.getList(), "The values in the underlying list should be copied, not the variable reference to the list."); }
@Test - public void deepCopyShouldCopyProperty() { + public void deepCopyShouldCopyPropertyWhenIdIncluded() { PropertyList original = createPropertyList();
PropertySimple simpleProperty = new PropertySimple("simeplProperty", "Simple Property"); original.add(simpleProperty);
- PropertyList copy = original.deepCopy(); + PropertyList copy = original.deepCopy(true);
assertEquals(copy.getList().size(), original.getList().size(), "Failed to copy simple property contained in original property list");
@@ -72,13 +83,39 @@ public class PropertyListTest { }
@Test - public void deepCopyShouldSetParentOfCopiedProperty() { + public void deepCopyShouldCopyPropertyWhenIdNotIncluded() { + PropertyList original = createPropertyList(); + + PropertySimple simpleProperty = new PropertySimple("simeplProperty", "Simple Property"); + original.add(simpleProperty); + + PropertyList copy = original.deepCopy(false); + + assertEquals(copy.getList().size(), original.getList().size(), "Failed to copy simple property contained in original property list"); + + assertNotSame(copy.getList().get(0), original.getList().get(0), "Properties in the list should be copied by value as opposed to just copying the references"); + } + + @Test + public void deepCopyShouldSetParentOfCopiedPropertyWhenIdIncluded() { + PropertyList original = createPropertyList(); + + PropertySimple simpleProperty = new PropertySimple("simpleProperty", "Simple Property"); + original.add(simpleProperty); + + PropertyList copy = original.deepCopy(true); + + assertSame(copy.getList().get(0).getParentList(), copy, "The parentList property of copied properties should be set to the new PropertyList"); + } + + @Test + public void deepCopyShouldSetParentOfCopiedPropertyWhenIdNotIncluded() { PropertyList original = createPropertyList();
PropertySimple simpleProperty = new PropertySimple("simpleProperty", "Simple Property"); original.add(simpleProperty);
- PropertyList copy = original.deepCopy(); + PropertyList copy = original.deepCopy(false);
assertSame(copy.getList().get(0).getParentList(), copy, "The parentList property of copied properties should be set to the new PropertyList"); } diff --git a/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/PropertyMapTest.java b/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/PropertyMapTest.java index 4a999b6..e73d835 100644 --- a/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/PropertyMapTest.java +++ b/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/PropertyMapTest.java @@ -30,40 +30,55 @@ import org.testng.annotations.Test; public class PropertyMapTest {
@Test - public void deepCopyShouldCopySimpleFields() { + public void deepCopyShouldCopyAllSimpleFields() { PropertyMap original = createPropertyMap(); - PropertyMap copy = original.deepCopy(); + PropertyMap copy = original.deepCopy(true);
assertNotSame(copy, original, "The copy should not reference the original object");
+ assertEquals(copy.getId(), original.getId(), "Failed to copy the id property"); assertEquals(copy.getName(), original.getName(), "Failed to copy the name property"); assertEquals(copy.getErrorMessage(), original.getErrorMessage(), "Failed to copy the errorMessage property"); }
@Test - public void deepCopyShouldNotCopyIdField() { + public void deepCopyShouldNotCopyIdFieldWhenFlagIsFalse() { PropertyMap original = createPropertyMap(); - PropertyMap copy = original.deepCopy(); + PropertyMap copy = original.deepCopy(false); + + assertNotSame(copy, original, "The copy should not reference the original object");
assertFalse(copy.getId() == original.getId(), "The original id property should not be copied."); + assertEquals(copy.getName(), original.getName(), "Failed to copy the name property"); + assertEquals(copy.getErrorMessage(), original.getErrorMessage(), "Failed to copy the errorMessage property"); }
@Test - public void deepCopyShouldNotCopyReferenceOfUnderlyingMap() { + public void deepCopyShouldCopyPropertyWhenIdIncluded() { PropertyMap original = createPropertyMap(); - PropertyMap copy = original.deepCopy();
- assertNotSame(copy.getMap(), original.getMap(), "The values in the underlying map should be copied, not the reference to the map itself"); + PropertySimple simpleProperty = new PropertySimple("simeplProperty", "Simple Property"); + original.put(simpleProperty); + + PropertyMap copy = original.deepCopy(true); + + assertEquals(copy.getMap().size(), original.getMap().size(), "Failed to copy simple property contained in original property map"); + + assertNotSame( + copy.getMap().get(simpleProperty.getName()), + original.getMap().get(simpleProperty.getName()), + "Properties in the map should be copied by value as opposed to just copying the references" + ); }
@Test - public void deepCopyShouldCopyProperty() { + public void deepCopyShouldCopyPropertyWhenIdNotIncluded() { PropertyMap original = createPropertyMap();
PropertySimple simpleProperty = new PropertySimple("simeplProperty", "Simple Property"); original.put(simpleProperty);
- PropertyMap copy = original.deepCopy(); + PropertyMap copy = original.deepCopy(false);
assertEquals(copy.getMap().size(), original.getMap().size(), "Failed to copy simple property contained in original property map");
@@ -75,13 +90,29 @@ public class PropertyMapTest { }
@Test - public void deepCopyShouldSetParentOfCopiedProperty() { + public void deepCopyShouldSetParentOfCopiedPropertyWhenIdIncluded() { + PropertyMap original = createPropertyMap(); + + PropertySimple simpleProperty = new PropertySimple("simpleProperty", "Simple Property"); + original.put(simpleProperty); + + PropertyMap copy = original.deepCopy(true); + + assertSame( + copy.get(simpleProperty.getName()).getParentMap(), + copy, + "The parentMap property of copied properties should be set to the new PropertyMap" + ); + } + + @Test + public void deepCopyShouldSetParentOfCopiedPropertyWhenIdNotIncluded() { PropertyMap original = createPropertyMap();
PropertySimple simpleProperty = new PropertySimple("simpleProperty", "Simple Property"); original.put(simpleProperty);
- PropertyMap copy = original.deepCopy(); + PropertyMap copy = original.deepCopy(false);
assertSame( copy.get(simpleProperty.getName()).getParentMap(), diff --git a/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/PropertySimpleTest.java b/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/PropertySimpleTest.java index c1b76aa..7b49837 100644 --- a/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/PropertySimpleTest.java +++ b/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/PropertySimpleTest.java @@ -30,13 +30,14 @@ import org.testng.annotations.Test; public class PropertySimpleTest {
@Test - public void deepCopyShouldCopySimpleFields() { + public void deepCopyShouldCopyAllSimpleFields() { PropertySimple original = createProperty();
- PropertySimple copy = original.deepCopy(); + PropertySimple copy = original.deepCopy(true);
assertNotSame(copy, original, "The copy should not reference the original object"); - + + assertEquals(copy.getId(), original.getId(), "Failed to copy the id property"); assertEquals(copy.getName(), original.getName(), "Failed to copy the name property"); assertEquals(copy.getErrorMessage(), original.getErrorMessage(), "Failed to copy the errorMessage property"); assertEquals(copy.getOverride(), original.getOverride(), "Failed to copy the override property"); @@ -45,12 +46,17 @@ public class PropertySimpleTest { }
@Test - public void deepCopyShouldNotCopyIdField() { + public void deepCopyShouldNotCopyIdFieldWhenFlagIsFalse() { PropertySimple original = createProperty();
- PropertySimple copy = original.deepCopy(); + PropertySimple copy = original.deepCopy(false);
assertFalse(copy.getId() == original.getId(), "The original id property should not be copied."); + assertEquals(copy.getName(), original.getName(), "Failed to copy the name property"); + assertEquals(copy.getErrorMessage(), original.getErrorMessage(), "Failed to copy the errorMessage property"); + assertEquals(copy.getOverride(), original.getOverride(), "Failed to copy the override property"); + assertEquals(copy.getUnmaskedStringValue(), original.getUnmaskedStringValue(), "Failed to copy the unmaskedStringValue property"); + assertEquals(copy.getStringValue(), original.getStringValue(), "Failed to copy the stringValue property"); }
private PropertySimple createProperty() { diff --git a/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/RawConfigurationTest.java b/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/RawConfigurationTest.java index 2d60ba2..3a373b2 100644 --- a/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/RawConfigurationTest.java +++ b/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/RawConfigurationTest.java @@ -218,45 +218,49 @@ public class RawConfigurationTest { }
@Test - public void deepCopyShouldCopyPath() { + public void deepCopyShouldCopyPathAndIdWhenIdIncluded() { RawConfiguration original = new RawConfiguration(); original.setPath("/tmp/foo"); + original.setId(-1);
- RawConfiguration copy = original.deepCopy(); + RawConfiguration copy = original.deepCopy(true);
+ assertEquals(copy.getId(), copy.getId(), "Failed to copy the id property."); assertEquals(copy.getPath(), original.getPath(), "Failed to copy the path property."); }
@Test - public void deepCopyShouldCopyContents() { + public void deepCopyShouldCopyPathAndIdWhenIdNotIncluded() { RawConfiguration original = new RawConfiguration(); - original.setContents(new byte[] {1, 2, 3, 4, 5}); + original.setPath("/tmp/foo"); + original.setId(-1);
- RawConfiguration copy = original.deepCopy(); + RawConfiguration copy = original.deepCopy(false);
- assertFalse(original.getContents() == copy.getContents(), "The values in the contents array should be copied, not the reference to the original object."); - assertEquals(copy.getContents(), original.getContents(), "Failed to copy contents property."); + assertFalse(copy.getId() == original.getId(), "The original id property should not be copied."); + assertEquals(copy.getPath(), original.getPath(), "Failed to copy the path property."); }
@Test - public void deepCopyShouldNotCopyIdProperty() { + public void deepCopyShouldCopyContentsWhenCopyingId() { RawConfiguration original = new RawConfiguration(); - original.setId(1); + original.setContents(new byte[] {1, 2, 3, 4, 5});
- RawConfiguration copy = original.deepCopy(); + RawConfiguration copy = original.deepCopy(true);
- assertFalse(original.getId() == copy.getId(), "The id property should not be copied."); + assertFalse(original.getContents() == copy.getContents(), "The values in the contents array should be copied, not the reference to the original object."); + assertEquals(copy.getContents(), original.getContents(), "Failed to copy contents property."); }
- private RawConfiguration serializeAndDeserialize(RawConfiguration rawConfig) throws Exception { - ByteArrayOutputStream byteOutputStream = new ByteArrayOutputStream(); - ObjectOutputStream ostream = new ObjectOutputStream(byteOutputStream); - - ostream.writeObject(rawConfig); + @Test + public void deepCopyShouldCopyContentsWhenNotCopyingId() { + RawConfiguration original = new RawConfiguration(); + original.setContents(new byte[] {1, 2, 3, 4, 5});
- ByteArrayInputStream byteInputStream = new ByteArrayInputStream(byteOutputStream.toByteArray()); - ObjectInputStream istream = new ObjectInputStream(byteInputStream); + RawConfiguration copy = original.deepCopy(false);
- return (RawConfiguration) istream.readObject(); + assertFalse(original.getContents() == copy.getContents(), "The values in the contents array should be copied, not the reference to the original object."); + assertEquals(copy.getContents(), original.getContents(), "Failed to copy contents property."); } + }
commit 60ba50a452f0db9c6af51d2e2a86a608813da3e0 Author: Jay Shaughnessy jshaughn@redhat.com Date: Tue Nov 24 15:02:17 2009 -0500
Fix problem due to a failed git merge
diff --git a/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-perspective.xsd b/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-perspective.xsd index 4c48957..5093db1 100644 --- a/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-perspective.xsd +++ b/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-perspective.xsd @@ -120,9 +120,8 @@ </xs:documentation> </xs:annotation> </xs:element> - <xs:element - ref="perspective:resourceActivator" + ref="perspective:inventoryActivator" minOccurs="0" maxOccurs="unbounded"> xs:annotation
commit ac15413eff9e2bacb476139bed54fbacb2648084 Author: John Sanda john@localhost.localdomain Date: Tue Nov 24 14:50:57 2009 -0500
[US 6] Changing return type of ConfigManagement.executeUpdate() to void.
Updating implementing classes with API change. If executeUpdate() returns without throwing an exception it can be assumed that the update completed successfully.
Initial commit for ConfigurationUpdateException and UpdateInProgressException. These exceptions can be thrown when an update is not successful.
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigManagement.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigManagement.java index b6f24b3..3ad0df8 100644 --- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigManagement.java +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigManagement.java @@ -42,7 +42,7 @@ public interface ConfigManagement {
Configuration execute(int resourceId) throws PluginContainerException;
- ConfigurationUpdateReport executeUpdate(int resourceId, Configuration configuration) + void executeUpdate(int resourceId, Configuration configuration) throws PluginContainerException;
} diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigManagementSupport.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigManagementSupport.java index 24fd900..5ab7269 100644 --- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigManagementSupport.java +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigManagementSupport.java @@ -59,6 +59,17 @@ public abstract class ConfigManagementSupport implements ConfigManagement { FACET_METHOD_TIMEOUT, daemonOnly, onlyIfStarted); }
+ protected ResourceConfigurationFacet loadResourceConfigFacetWithWriteLock(int resourceId) + throws PluginContainerException { + + FacetLockType lockType = FacetLockType.WRITE; + boolean daemonThread = (lockType != FacetLockType.WRITE); + boolean onlyIfStarted = true; + + return componentService.getComponent(resourceId, ResourceConfigurationFacet.class, lockType, + FACET_METHOD_TIMEOUT, daemonThread, onlyIfStarted); + } + protected ConfigurationFacet loadConfigurationFacet(int resourceId, FacetLockType lockType) throws PluginContainerException {
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationUpdateException.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationUpdateException.java new file mode 100644 index 0000000..6c107f9 --- /dev/null +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationUpdateException.java @@ -0,0 +1,55 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2008 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, version 2, as + * published by the Free Software Foundation, and/or the GNU Lesser + * General Public License, version 2.1, also as published by the Free + * Software Foundation. + * + * 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 and the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * and the GNU Lesser 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.core.pc.configuration; + +/** + * A plugin can throw this exception to indicate to the container that there was a failure that was handled in some + * way as opposed to an unexpected failure that is not handled. The container will includes the contents of the + * <code>message</code> property in the response that is sent back to the server; whereas with any other exception, the + * entire stack trace will be included in the response that sent back to the server. + * <p/> + * Consider the following scenario to illustrate an appropriate use of this exception. A plugin attempts to apply an + * update, and it receives an error code from an external process indicating that the update failed. The plugin in turn + * could throw a <code>ConfigurationUpdateException</code> including the error code along with other relevant + * information to provide to additional context. That error message, as opposed to the full stack trace, will be + * included in the response that is sent back to the server. + */ +public class ConfigurationUpdateException extends RuntimeException { + + public ConfigurationUpdateException() { + super(); + } + + public ConfigurationUpdateException(String message) { + super(message); + } + + public ConfigurationUpdateException(String message, Throwable cause) { + super(message, cause); + } + + public ConfigurationUpdateException(Throwable cause) { + super(cause); + } +} diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LegacyConfigManagement.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LegacyConfigManagement.java index 85aa6ce..9d9bbbd 100644 --- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LegacyConfigManagement.java +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LegacyConfigManagement.java @@ -75,14 +75,10 @@ public class LegacyConfigManagement extends ConfigManagementSupport { } }
- public ConfigurationUpdateReport executeUpdate(int resourceId, Configuration configuration) + public void executeUpdate(int resourceId, Configuration configuration) throws PluginContainerException { ConfigurationFacet facet = loadConfigurationFacet(resourceId, WRITE); ConfigurationUpdateReport report = new ConfigurationUpdateReport(configuration); - - facet.updateResourceConfiguration(report); - - return report; }
} diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadStructured.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadStructured.java index e978233..5e76590 100644 --- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadStructured.java +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadStructured.java @@ -27,7 +27,6 @@ import org.rhq.core.domain.configuration.Configuration; import org.rhq.core.domain.resource.ResourceType; import org.rhq.core.clientapi.agent.PluginContainerException; import org.rhq.core.pluginapi.configuration.ResourceConfigurationFacet; -import org.rhq.core.pluginapi.configuration.ConfigurationUpdateReport; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory;
@@ -68,8 +67,7 @@ public class LoadStructured extends ConfigManagementSupport { } }
- public ConfigurationUpdateReport executeUpdate(int resourceId, Configuration configuration) + public void executeUpdate(int resourceId, Configuration configuration) throws PluginContainerException { - return null; } } diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadStructuredAndRaw.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadStructuredAndRaw.java index 2ff175f..cbfca94 100644 --- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadStructuredAndRaw.java +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadStructuredAndRaw.java @@ -30,7 +30,6 @@ import org.rhq.core.domain.configuration.RawConfiguration; import org.rhq.core.domain.resource.ResourceType; import org.rhq.core.clientapi.agent.PluginContainerException; import org.rhq.core.pluginapi.configuration.ResourceConfigurationFacet; -import org.rhq.core.pluginapi.configuration.ConfigurationUpdateReport; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory;
@@ -85,8 +84,7 @@ public class LoadStructuredAndRaw extends ConfigManagementSupport { } }
- public ConfigurationUpdateReport executeUpdate(int resourceId, Configuration configuration) - throws PluginContainerException { - return null; + public void executeUpdate(int resourceId, Configuration configuration) + throws PluginContainerException { } } diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/RawConfigManagement.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/RawConfigManagement.java index c3c99f9..4f1ab96 100644 --- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/RawConfigManagement.java +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/RawConfigManagement.java @@ -28,6 +28,7 @@ import org.apache.commons.logging.LogFactory; import org.rhq.core.clientapi.agent.PluginContainerException; import org.rhq.core.domain.configuration.Configuration; import org.rhq.core.domain.configuration.RawConfiguration; +import org.rhq.core.domain.configuration.ConfigurationUpdateStatus; import org.rhq.core.domain.resource.ResourceType; import org.rhq.core.pluginapi.configuration.ResourceConfigurationFacet; import org.rhq.core.pluginapi.configuration.ConfigurationUpdateReport; @@ -60,8 +61,14 @@ public class RawConfigManagement extends ConfigManagementSupport { return config; }
- public ConfigurationUpdateReport executeUpdate(int resourceId, Configuration configuration) + public void executeUpdate(int resourceId, Configuration configuration) throws PluginContainerException { - return null; + + ResourceConfigurationFacet facet = loadResourceConfigFacetWithWriteLock(resourceId); + + for (RawConfiguration rawConfig : configuration.getRawConfigurations()) { + facet.persistRawConfiguration(rawConfig); + } + } } diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/UpdateInProgressException.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/UpdateInProgressException.java new file mode 100644 index 0000000..018d3f9 --- /dev/null +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/UpdateInProgressException.java @@ -0,0 +1,43 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2008 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, version 2, as + * published by the Free Software Foundation, and/or the GNU Lesser + * General Public License, version 2.1, also as published by the Free + * Software Foundation. + * + * 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 and the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * and the GNU Lesser 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.core.pc.configuration; + +public class UpdateInProgressException extends ConfigurationUpdateException { + + public UpdateInProgressException() { + super(); + } + + public UpdateInProgressException(String message) { + super(message); + } + + public UpdateInProgressException(String message, Throwable cause) { + super(message, cause); + } + + public UpdateInProgressException(Throwable cause) { + super(cause); + } +} diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/UpdateResourceConfigurationRunner.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/UpdateResourceConfigurationRunner.java index 163dc8c..ccdbc20 100644 --- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/UpdateResourceConfigurationRunner.java +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/UpdateResourceConfigurationRunner.java @@ -22,6 +22,8 @@ */ package org.rhq.core.pc.configuration;
+import static org.rhq.core.domain.configuration.ConfigurationUpdateStatus.*; + import java.util.List; import java.util.concurrent.Callable;
@@ -97,15 +99,20 @@ public class UpdateResourceConfigurationRunner implements Runnable, Callable<Con ConfigurationUpdateReport report = null; try { // configurationFacet.updateResourceConfiguration(report); - report = configMgmt.executeUpdate(request.getResourceId(), request.getConfiguration()); - - response = new ConfigurationUpdateResponse(requestId, report.getConfiguration(), report.getStatus(), report - .getErrorMessage()); +// report = configMgmt.executeUpdate(request.getResourceId(), request.getConfiguration()); + response = new ConfigurationUpdateResponse(requestId, request.getConfiguration(), SUCCESS, null);
- if (response.getStatus() == ConfigurationUpdateStatus.INPROGRESS) { + try { + configMgmt.executeUpdate(request.getResourceId(), request.getConfiguration()); + } catch (UpdateInProgressException e) { + response.setStatus(INPROGRESS); response.setErrorMessage("Configuration facet did not indicate success or failure - assuming failure."); }
+// if (response.getStatus() == ConfigurationUpdateStatus.INPROGRESS) { +// response.setErrorMessage("Configuration facet did not indicate success or failure - assuming failure."); +// } + ConfigurationDefinition configurationDefinition = resourceType.getResourceConfigurationDefinition();
// Normalize and validate the config. diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigManagementTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigManagementTest.java index cc8e760..57e5183 100644 --- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigManagementTest.java +++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigManagementTest.java @@ -28,6 +28,8 @@ import org.rhq.core.domain.configuration.PropertySimple; import org.rhq.core.domain.configuration.RawConfiguration; import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; import org.rhq.core.domain.resource.ResourceType; +import org.rhq.core.clientapi.server.configuration.ConfigurationUpdateResponse; +import org.rhq.core.pluginapi.configuration.ConfigurationUpdateReport; import org.rhq.test.JMockTest;
import static org.rhq.test.AssertUtils.*; @@ -116,4 +118,14 @@ public class ConfigManagementTest extends JMockTest {
assertEquals(loadedConfig.getNotes(), expectedNotes, "The notes property should be set to a default when it is not already initialized."); } + + void assertConfigurationUpdateResponseMatches(ConfigurationUpdateResponse expected, + ConfigurationUpdateResponse actual, String msg) { + assertPropertiesMatch(expected, actual, msg); + } + + void assertConfigurationUpdateReportMatches(ConfigurationUpdateReport expected, ConfigurationUpdateReport actual, + String msg) { + assertPropertiesMatch(expected, actual, msg); + } } diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/RawConfigManagementTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/RawConfigManagementTest.java index 473ba1c..2d6975c 100644 --- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/RawConfigManagementTest.java +++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/RawConfigManagementTest.java @@ -23,17 +23,20 @@
package org.rhq.core.pc.configuration;
+import static org.rhq.core.domain.configuration.ConfigurationUpdateStatus.SUCCESS; +import static java.util.Collections.EMPTY_SET; + import org.jmock.Expectations; import org.rhq.core.domain.configuration.Configuration; import org.rhq.core.domain.configuration.RawConfiguration; import org.rhq.core.pc.util.ComponentService; import org.rhq.core.pc.util.FacetLockType; import org.rhq.core.pluginapi.configuration.ResourceConfigurationFacet; +import org.rhq.core.pluginapi.configuration.ConfigurationUpdateReport; import static org.testng.Assert.assertNull; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test;
-import static java.util.Collections.EMPTY_SET; import java.util.Set;
public class RawConfigManagementTest extends ConfigManagementTest { @@ -65,7 +68,7 @@ public class RawConfigManagementTest extends ConfigManagementTest { createRawConfiguration("/tmp/bar.txt") );
- addDefaultExpectations(rawConfigs); + addDefaultExpectationsForLoad(rawConfigs);
Configuration loadedConfig = rawConfigMgmt.execute(resourceId);
@@ -77,7 +80,7 @@ public class RawConfigManagementTest extends ConfigManagementTest { final Configuration config = new Configuration(); config.setNotes(null);
- addDefaultExpectations(EMPTY_SET); + addDefaultExpectationsForLoad(EMPTY_SET);
Configuration loadedConfig = rawConfigMgmt.execute(resourceId);
@@ -88,14 +91,14 @@ public class RawConfigManagementTest extends ConfigManagementTest { public void nullShouldBeReturnedWhenRawIsNull() throws Exception { Set<RawConfiguration> rawConfigs = null;
- addDefaultExpectations(rawConfigs); + addDefaultExpectationsForLoad(rawConfigs);
Configuration loadedConfig = rawConfigMgmt.execute(resourceId);
assertNull(loadedConfig, "Expected null to be returned when facet returns null for raw."); }
- private void addDefaultExpectations(final Set<RawConfiguration> rawConfigs) + private void addDefaultExpectationsForLoad(final Set<RawConfiguration> rawConfigs) throws Exception {
context.checking(new Expectations() {{ @@ -113,4 +116,53 @@ public class RawConfigManagementTest extends ConfigManagementTest { }}); }
+ @Test + public void facetShouldBeCalledToUpdateASingleRaw() throws Exception { + final RawConfiguration raw = createRawConfiguration("/tmp/raw.txt"); + + final Configuration config = new Configuration(); + config.addRawConfiguration(raw); + + addDefaultExpectationsForUpdate(); + + context.checking(new Expectations() {{ + oneOf(configFacet).persistRawConfiguration(raw); + }}); + + rawConfigMgmt.executeUpdate(resourceId, config); + } + + @Test + public void facetShouldBeCalledToUpdateMultipleRaws() throws Exception { + final RawConfiguration raw1 = createRawConfiguration("/tmp/raw1.txt"); + final RawConfiguration raw2 = createRawConfiguration("/tmp/raw2.txt"); + + final Configuration config = new Configuration(); + config.addRawConfiguration(raw1); + config.addRawConfiguration(raw2); + + addDefaultExpectationsForUpdate(); + + context.checking(new Expectations() {{ + oneOf(configFacet).persistRawConfiguration(raw1); + oneOf(configFacet).persistRawConfiguration(raw2); + }}); + + rawConfigMgmt.executeUpdate(resourceId, config); + } + + private void addDefaultExpectationsForUpdate() throws Exception { + final boolean isDaemonThread = false; + + context.checking(new Expectations() {{ + atLeast(1).of(componentService).getComponent(resourceId, + ResourceConfigurationFacet.class, + FacetLockType.WRITE, + ConfigManagement.FACET_METHOD_TIMEOUT, + isDaemonThread, + onlyIfStarted); + will(returnValue(configFacet)); + }}); + } + } diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/UpdateResourceConfigurationRunnerTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/UpdateResourceConfigurationRunnerTest.java index 48bf0ae..0c87833 100644 --- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/UpdateResourceConfigurationRunnerTest.java +++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/UpdateResourceConfigurationRunnerTest.java @@ -80,9 +80,9 @@ public class UpdateResourceConfigurationRunnerTest extends ConfigManagementTest public void successfulUpdateShouldSendSuccessResponseToServer() throws Exception { final Configuration config = createStructuredConfig();
- final ConfigurationServerService configServerService = context.mock(ConfigurationServerService.class); + configMgmt = context.mock(ConfigManagement.class);
- //final ConfigurationFacet facet = context.mock(ConfigurationFacet.class); + final ConfigurationServerService configServerService = context.mock(ConfigurationServerService.class);
final ConfigurationUtilityService configUtilService = context.mock(ConfigurationUtilityService.class);
@@ -98,8 +98,7 @@ public class UpdateResourceConfigurationRunnerTest extends ConfigManagementTest SUCCESS, null);
context.checking(new Expectations() {{ - oneOf(facet).updateResourceConfiguration(with(any(ConfigurationUpdateReport.class))); - will(updateReportTo(SUCCESS)); + oneOf(configMgmt).executeUpdate(resourceId, config);
oneOf(configUtilService).normalizeConfiguration(config, resourceType.getResourceConfigurationDefinition()); oneOf(configUtilService).validateConfiguration(config, resourceType.getResourceConfigurationDefinition()); @@ -114,7 +113,7 @@ public class UpdateResourceConfigurationRunnerTest extends ConfigManagementTest public void successfulUpdateShouldReturnSuccessResponseInEmbeddedMode() throws Exception { final Configuration config = createStructuredConfig();
- //final ConfigurationFacet facet = context.mock(ConfigurationFacet.class); + configMgmt = context.mock(ConfigManagement.class);
final ConfigurationUtilityService configUtilService = context.mock(ConfigurationUtilityService.class);
@@ -130,8 +129,7 @@ public class UpdateResourceConfigurationRunnerTest extends ConfigManagementTest SUCCESS, null);
context.checking(new Expectations() {{ - oneOf(facet).updateResourceConfiguration(with(any(ConfigurationUpdateReport.class))); - will(updateReportTo(SUCCESS)); + oneOf(configMgmt).executeUpdate(resourceId, config);
oneOf(configUtilService).normalizeConfiguration(config, resourceType.getResourceConfigurationDefinition()); oneOf(configUtilService).validateConfiguration(config, resourceType.getResourceConfigurationDefinition()); @@ -147,9 +145,9 @@ public class UpdateResourceConfigurationRunnerTest extends ConfigManagementTest public void inProgressUpdateShouldSendFailureResponseToServer() throws Exception { final Configuration config = createStructuredConfig();
- final ConfigurationServerService configServerService = context.mock(ConfigurationServerService.class); + configMgmt = context.mock(ConfigManagement.class);
- //final ConfigurationFacet facet = context.mock(ConfigurationFacet.class); + final ConfigurationServerService configServerService = context.mock(ConfigurationServerService.class);
final ConfigurationUtilityService configUtilService = context.mock(ConfigurationUtilityService.class);
@@ -167,8 +165,7 @@ public class UpdateResourceConfigurationRunnerTest extends ConfigManagementTest FAILURE, errorMsg);
context.checking(new Expectations() {{ - oneOf(facet).updateResourceConfiguration(with(any(ConfigurationUpdateReport.class))); - will(updateReportTo(INPROGRESS)); + oneOf(configMgmt).executeUpdate(resourceId, config); will(throwException(new UpdateInProgressException()));
oneOf(configUtilService).normalizeConfiguration(config, resourceType.getResourceConfigurationDefinition()); oneOf(configUtilService).validateConfiguration(config, resourceType.getResourceConfigurationDefinition()); @@ -269,22 +266,6 @@ public class UpdateResourceConfigurationRunnerTest extends ConfigManagementTest assertConfigurationUpdateResponseMatches(failureResponse, actualResponse, "Expected a failure response"); }
- void assertConfigurationUpdateResponseMatches(ConfigurationUpdateResponse expected, - ConfigurationUpdateResponse actual, String msg) { - assertPropertiesMatch(expected, actual, msg); - } - - boolean propertyEquals(Object expected, Object actual) { - if (expected == null && actual == null) { - return true; - } - - if (expected == null && actual != null) { - return false; - } - return expected.equals(actual); - } - public static Matcher<ConfigurationUpdateResponse> matchingResponse(ConfigurationUpdateResponse expected) { return new PropertyMatcher<ConfigurationUpdateResponse>(expected); }
commit 1668456fce3f4ed2568b863156f5160c98e7ca2f Author: Adam Young ayoung@redhat.com Date: Tue Nov 24 14:50:41 2009 -0500
updated .classpath sources
diff --git a/.classpath b/.classpath index 4ae73a2..158e2f2 100644 --- a/.classpath +++ b/.classpath @@ -155,8 +155,8 @@ <classpathentry exported="true" kind="var" path="M2_REPO/cglib/cglib-nodep/2.1_3/cglib-nodep-2.1_3.jar"/> <classpathentry exported="true" kind="var" path="M2_REPO/commons-logging/commons-logging/1.1/commons-logging-1.1.jar"/> <classpathentry exported="true" kind="var" path="M2_REPO/commons-lang/commons-lang/2.4/commons-lang-2.4.jar"/> - <classpathentry exported="true" kind="var" path="M2_REPO/javax/faces/jsf-api/1.2_12/jsf-api-1.2_12.jar" sourcepath="/M2_REPO/javax/faces/jsf-api/1.2_06/jsf-api-1.2_06-sources.jar"/> - <classpathentry exported="true" kind="var" path="M2_REPO/javax/faces/jsf-impl/1.2_12/jsf-impl-1.2_12.jar" sourcepath="/M2_REPO/javax/faces/jsf-impl/1.2_06/jsf-impl-1.2_06-sources.jar"/> + <classpathentry exported="true" kind="var" path="M2_REPO/javax/faces/jsf-api/1.2_12/jsf-api-1.2_12.jar" sourcepath="/M2_REPO/javax/faces/jsf-api/1.2_12/jsf-api-1.2_12-sources.jar"/> + <classpathentry exported="true" kind="var" path="M2_REPO/javax/faces/jsf-impl/1.2_12/jsf-impl-1.2_12.jar" sourcepath="/M2_REPO/javax/faces/jsf-impl/1.2_12/jsf-impl-1.2_12-sources.jar"/> <classpathentry exported="true" kind="var" path="M2_REPO/javax/el/el-api/1.0/el-api-1.0.jar"/> <classpathentry exported="true" kind="var" path="M2_REPO/com/sun/facelets/jsf-facelets/1.1.14/jsf-facelets-1.1.14.jar" sourcepath="/M2_REPO/com/sun/facelets/jsf-facelets/1.1.13/jsf-facelets-1.1.13-sources.jar"/> <classpathentry exported="true" kind="var" path="M2_REPO/mc4j/org-mc4j-ems/1.2.11/org-mc4j-ems-1.2.11.jar" sourcepath="/M2_REPO/mc4j/org-mc4j-ems/1.2.11/org-mc4j-ems-1.2.11-sources.jar"/> @@ -164,8 +164,8 @@ <classpathentry exported="true" kind="var" path="M2_REPO/javax/mail/mail/1.3.1/mail-1.3.1.jar"/> <classpathentry exported="true" kind="var" path="M2_REPO/commons-fileupload/commons-fileupload/1.2/commons-fileupload-1.2.jar"/> <classpathentry exported="true" kind="var" path="M2_REPO/org/richfaces/framework/richfaces-api/3.3.0.GA/richfaces-api-3.3.0.GA.jar" sourcepath="/M2_REPO/org/richfaces/framework/richfaces-api/3.1.3.GA/richfaces-api-3.1.3.GA-sources.jar"/> - <classpathentry exported="true" kind="var" path="M2_REPO/org/richfaces/framework/richfaces-impl/3.3.0.GA/richfaces-impl-3.3.0.GA.jar" sourcepath="/M2_REPO/org/richfaces/framework/richfaces-impl/3.1.3.GA/richfaces-impl-3.1.3.GA-sources.jar"/> - <classpathentry exported="true" kind="var" path="M2_REPO/org/richfaces/ui/richfaces-ui/3.3.0.GA/richfaces-ui-3.3.0.GA.jar" sourcepath="/M2_REPO/org/richfaces/ui/richfaces-ui/3.1.3.GA/richfaces-ui-3.1.3.GA-sources.jar"/> + <classpathentry exported="true" kind="var" path="M2_REPO/org/richfaces/framework/richfaces-impl/3.3.0.GA/richfaces-impl-3.3.0.GA.jar" sourcepath="/M2_REPO/org/richfaces/framework/richfaces-impl/3.3.0.GA/richfaces-impl-3.3.0.GA-sources.jar"/> + <classpathentry exported="true" kind="var" path="M2_REPO/org/richfaces/ui/richfaces-ui/3.3.0.GA/richfaces-ui-3.3.0.GA.jar" sourcepath="/M2_REPO/org/richfaces/ui/richfaces-ui/3.3.0.GA/richfaces-ui-3.3.0.GA-sources.jar"/> <classpathentry exported="true" kind="var" path="M2_REPO/postgresql/postgresql/8.4-701.jdbc3/postgresql-8.4-701.jdbc3.jar"/> <classpathentry exported="true" kind="var" path="M2_REPO/jboss/jboss-cache/1.4.1.SP9/jboss-cache-1.4.1.SP9.jar"/> <classpathentry exported="true" kind="var" path="M2_REPO/org/hyperic/sigar/1.6.3.82/sigar-1.6.3.82.jar" sourcepath="/M2_REPO/org/hyperic/sigar/1.6.3.82/sigar-1.6.3.82-sources.jar"/>
commit 4ff1b8440d4e0bdbd1a24995d8f03420d2093253 Author: John Sanda john@localhost.localdomain Date: Tue Nov 24 11:14:54 2009 -0500
[US 6] Renaming LoadResourceConfigurationFactory to ConfigManagementFactory
Also renaming implemenators and variables to be consistent.
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigManagementFactory.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigManagementFactory.java new file mode 100644 index 0000000..fc44dcd --- /dev/null +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigManagementFactory.java @@ -0,0 +1,32 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2008 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, version 2, as + * published by the Free Software Foundation, and/or the GNU Lesser + * General Public License, version 2.1, also as published by the Free + * Software Foundation. + * + * 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 and the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * and the GNU Lesser 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.core.pc.configuration; + +import org.rhq.core.clientapi.agent.PluginContainerException; + +public interface ConfigManagementFactory { + + ConfigManagement getStrategy(int resourceId) throws PluginContainerException; + +} diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigManagementFactoryImpl.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigManagementFactoryImpl.java new file mode 100644 index 0000000..66aef29 --- /dev/null +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigManagementFactoryImpl.java @@ -0,0 +1,89 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2008 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, version 2, as + * published by the Free Software Foundation, and/or the GNU Lesser + * General Public License, version 2.1, also as published by the Free + * Software Foundation. + * + * 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 and the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * and the GNU Lesser 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.core.pc.configuration; + +import static org.rhq.core.domain.configuration.definition.ConfigurationFormat.*; + +import org.rhq.core.pc.util.ComponentService; +import org.rhq.core.domain.resource.ResourceType; +import org.rhq.core.clientapi.agent.PluginContainerException; +import org.apache.maven.artifact.versioning.ComparableVersion; + +public class ConfigManagementFactoryImpl implements ConfigManagementFactory { + + private static final ComparableVersion NON_LEGACY_AMPS_VERSION = new ComparableVersion("2.1"); + + private ComponentService componentService; + + private ConfigurationUtilityService configUtilityService = new ConfigurationUtilityServiceImpl(); + + public void setComponentService(ComponentService componentService) { + this.componentService = componentService; + } + + public ConfigManagement getStrategy(int resourceId) throws PluginContainerException { + ConfigManagement loadConfig = createStrategy(resourceId); + initStrategyDependencies(loadConfig); + + return loadConfig; + } + + private void initStrategyDependencies(ConfigManagement loadConfig) { + loadConfig.setComponentService(componentService); + loadConfig.setConfigurationUtilityService(configUtilityService); + } + + private ConfigManagement createStrategy(int resourceId) throws PluginContainerException { + String ampsVersion = componentService.getAmpsVersion(resourceId); + + if (isLegacyVersion(ampsVersion)) { + return new LegacyConfigManagement(); + } + + ResourceType resourceType = componentService.getResourceType(resourceId); + + if (isStructured(resourceType)) { + return new LoadStructured(); + } + + if (isRaw(resourceType)) { + return new RawConfigManagement(); + } + + // else format is both structured and raw + return new LoadStructuredAndRaw(); + } + + private boolean isLegacyVersion(String ampsVersion) { + return new ComparableVersion(ampsVersion).compareTo(NON_LEGACY_AMPS_VERSION) < 0; + } + + private boolean isStructured(ResourceType resourceType) { + return resourceType.getResourceConfigurationDefinition().getConfigurationFormat().equals(STRUCTURED); + } + + private boolean isRaw(ResourceType resourceType) { + return resourceType.getResourceConfigurationDefinition().getConfigurationFormat().equals(RAW); + } +} diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManager.java index 25ae1e7..dd38c78 100644 --- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManager.java +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManager.java @@ -72,7 +72,7 @@ public class ConfigurationManager extends AgentService implements ContainerServi
private ComponentService componentService;
- private LoadResourceConfigurationFactory loadConfigFactory; + private ConfigManagementFactory configMgmtFactory;
public ConfigurationManager() { super(ConfigurationAgentService.class); @@ -108,8 +108,8 @@ public class ConfigurationManager extends AgentService implements ContainerServi this.componentService = componentService; }
- public void setLoadConfigFactory(LoadResourceConfigurationFactory factory) { - loadConfigFactory = factory; + public void setConfigManagementFactory(ConfigManagementFactory factory) { + configMgmtFactory = factory; }
public void updateResourceConfiguration(ConfigurationUpdateRequest request) { @@ -243,7 +243,7 @@ public class ConfigurationManager extends AgentService implements ContainerServi public Configuration loadResourceConfiguration(int resourceId) throws PluginContainerException {
- ConfigManagement loadConfig = loadConfigFactory.getStrategy(resourceId); + ConfigManagement loadConfig = configMgmtFactory.getStrategy(resourceId); Configuration configuration = null;
try { diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManagerInitializer.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManagerInitializer.java index 9208d46..b547e94 100644 --- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManagerInitializer.java +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManagerInitializer.java @@ -31,11 +31,11 @@ public class ConfigurationManagerInitializer { public void initialize(ConfigurationManager manager) { ComponentService componentService = new ComponentServiceImpl();
- LoadResourceConfigurationFactoryImpl factory = new LoadResourceConfigurationFactoryImpl(); + ConfigManagementFactoryImpl factory = new ConfigManagementFactoryImpl(); factory.setComponentService(componentService);
manager.setComponentService(componentService); - manager.setLoadConfigFactory(factory); + manager.setConfigManagementFactory(factory); }
} diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadResourceConfigurationFactory.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadResourceConfigurationFactory.java deleted file mode 100644 index be777be..0000000 --- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadResourceConfigurationFactory.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2008 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, version 2, as - * published by the Free Software Foundation, and/or the GNU Lesser - * General Public License, version 2.1, also as published by the Free - * Software Foundation. - * - * 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 and the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * and the GNU Lesser 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.core.pc.configuration; - -import org.rhq.core.clientapi.agent.PluginContainerException; - -public interface LoadResourceConfigurationFactory { - - ConfigManagement getStrategy(int resourceId) throws PluginContainerException; - -} diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadResourceConfigurationFactoryImpl.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadResourceConfigurationFactoryImpl.java deleted file mode 100644 index ad5ece4..0000000 --- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadResourceConfigurationFactoryImpl.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2008 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, version 2, as - * published by the Free Software Foundation, and/or the GNU Lesser - * General Public License, version 2.1, also as published by the Free - * Software Foundation. - * - * 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 and the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * and the GNU Lesser 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.core.pc.configuration; - -import static org.rhq.core.domain.configuration.definition.ConfigurationFormat.*; - -import org.rhq.core.pc.util.ComponentService; -import org.rhq.core.domain.resource.ResourceType; -import org.rhq.core.clientapi.agent.PluginContainerException; -import org.apache.maven.artifact.versioning.ComparableVersion; - -public class LoadResourceConfigurationFactoryImpl implements LoadResourceConfigurationFactory { - - private static final ComparableVersion NON_LEGACY_AMPS_VERSION = new ComparableVersion("2.1"); - - private ComponentService componentService; - - private ConfigurationUtilityService configUtilityService = new ConfigurationUtilityServiceImpl(); - - public void setComponentService(ComponentService componentService) { - this.componentService = componentService; - } - - public ConfigManagement getStrategy(int resourceId) throws PluginContainerException { - ConfigManagement loadConfig = createStrategy(resourceId); - initStrategyDependencies(loadConfig); - - return loadConfig; - } - - private void initStrategyDependencies(ConfigManagement loadConfig) { - loadConfig.setComponentService(componentService); - loadConfig.setConfigurationUtilityService(configUtilityService); - } - - private ConfigManagement createStrategy(int resourceId) throws PluginContainerException { - String ampsVersion = componentService.getAmpsVersion(resourceId); - - if (isLegacyVersion(ampsVersion)) { - return new LegacyConfigManagement(); - } - - ResourceType resourceType = componentService.getResourceType(resourceId); - - if (isStructured(resourceType)) { - return new LoadStructured(); - } - - if (isRaw(resourceType)) { - return new RawConfigManagement(); - } - - // else format is both structured and raw - return new LoadStructuredAndRaw(); - } - - private boolean isLegacyVersion(String ampsVersion) { - return new ComparableVersion(ampsVersion).compareTo(NON_LEGACY_AMPS_VERSION) < 0; - } - - private boolean isStructured(ResourceType resourceType) { - return resourceType.getResourceConfigurationDefinition().getConfigurationFormat().equals(STRUCTURED); - } - - private boolean isRaw(ResourceType resourceType) { - return resourceType.getResourceConfigurationDefinition().getConfigurationFormat().equals(RAW); - } -} diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigManagementFactoryImplTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigManagementFactoryImplTest.java new file mode 100644 index 0000000..8ea73cf --- /dev/null +++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigManagementFactoryImplTest.java @@ -0,0 +1,273 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2008 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, version 2, as + * published by the Free Software Foundation, and/or the GNU Lesser + * General Public License, version 2.1, also as published by the Free + * Software Foundation. + * + * 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 and the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * and the GNU Lesser 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.core.pc.configuration; + +import static org.testng.Assert.*; + +import org.testng.annotations.Test; +import org.testng.annotations.BeforeMethod; +import org.rhq.core.pc.util.ComponentService; +import org.rhq.core.domain.resource.ResourceType; +import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; +import org.rhq.core.domain.configuration.definition.ConfigurationFormat; +import org.rhq.test.JMockTest; +import org.jmock.Expectations; + +public class ConfigManagementFactoryImplTest extends JMockTest { + + static final String LEGACY_AMPS_VERSION = "2.0"; + + static final String NON_LEGACY_AMPS_VERSION = "2.1"; + + ComponentService componentService; + + int resourceId = -1; + + ConfigManagementFactoryImpl factory; + + @BeforeMethod + public void setup() { + componentService = context.mock(ComponentService.class); + + factory = new ConfigManagementFactoryImpl(); + factory.setComponentService(componentService); + } + + @Test + public void factoryShouldReturnLegacyLoadConfigWhenAmpsVersionIsLessThan2dot1() throws Exception { + context.checking(new Expectations() {{ + allowing(componentService).getAmpsVersion(resourceId); will(returnValue(LEGACY_AMPS_VERSION)); + }}); + + ConfigManagement loadConfig = factory.getStrategy(resourceId); + + assertTrue( + loadConfig instanceof LegacyConfigManagement, + "Expected to get an instance of " + LegacyConfigManagement.class.getSimpleName() + " when the " + + "resource is from a plugin having an ampsVersion less than " + NON_LEGACY_AMPS_VERSION + ); + } + + @Test + public void factoryShouldInitializeLegacyLoadConfigWithComponentService() throws Exception { + context.checking(new Expectations() {{ + allowing(componentService).getAmpsVersion(resourceId); will(returnValue(LEGACY_AMPS_VERSION)); + }}); + + ConfigManagement loadConfig = factory.getStrategy(resourceId); + + assertComponentServiceInitialized(loadConfig); + } + + @Test + public void factoryShouldInitializeLegacyLoadConfigWithConfigurationUtilityService() throws Exception { + context.checking(new Expectations() {{ + allowing(componentService).getAmpsVersion(resourceId); will(returnValue(LEGACY_AMPS_VERSION)); + }}); + + ConfigManagement loadConfig = factory.getStrategy(resourceId); + + assertConfigurationUtilityServiceInitialized(loadConfig); + } + + @Test + public void factoryShouldReturnStructuredLoadConfigWhenAmpsVersionIs2dot1AndFormatIsStructured() throws Exception { + context.checking(new Expectations() {{ + allowing(componentService).getAmpsVersion(resourceId); will(returnValue(NON_LEGACY_AMPS_VERSION)); + + allowing(componentService).getResourceType(resourceId); + will(returnValue(createResourceTypeThatSupportsStructured())); + }}); + + ConfigManagement loadConfig = factory.getStrategy(resourceId); + + assertTrue( + loadConfig instanceof LoadStructured, + "Expected to get an instance of " + LoadStructured.class.getSimpleName() + + "when resource is from a plugin having an ampsversion >= " + NON_LEGACY_AMPS_VERSION + " and the resource " + + "configuration format is structured." + ); + } + + @Test + public void factoryShouldInitializeLoadStructuredWithComponentService() throws Exception { + context.checking(new Expectations() {{ + allowing(componentService).getAmpsVersion(resourceId); will(returnValue(NON_LEGACY_AMPS_VERSION)); + + allowing(componentService).getResourceType(resourceId); + will(returnValue(createResourceTypeThatSupportsStructured())); + }}); + + ConfigManagement loadConfig = factory.getStrategy(resourceId); + + assertComponentServiceInitialized(loadConfig); + } + + @Test + public void factoryShouldInitializeLoadStructuredWithConfigurationUtilityService() throws Exception { + context.checking(new Expectations() {{ + allowing(componentService).getAmpsVersion(resourceId); will(returnValue(NON_LEGACY_AMPS_VERSION)); + + allowing(componentService).getResourceType(resourceId); + will(returnValue(createResourceTypeThatSupportsStructured())); + }}); + + ConfigManagement loadConfig = factory.getStrategy(resourceId); + + assertConfigurationUtilityServiceInitialized(loadConfig); + } + + @Test + public void factoryShouldReturnLoadRawWhenAmpsVersionIs2dot1AndFormatIsRaw() throws Exception { + context.checking(new Expectations() {{ + allowing(componentService).getAmpsVersion(resourceId); will(returnValue(NON_LEGACY_AMPS_VERSION)); + + allowing(componentService).getResourceType(resourceId); + will(returnValue(createResourceTypeThatSupportsRaw())); + }}); + + ConfigManagement loadConfig = factory.getStrategy(resourceId); + + assertTrue( + loadConfig instanceof RawConfigManagement, + "Expected to get an instance of " + RawConfigManagement.class.getSimpleName() + " when " + + "resource is from a plugin having an ampsversion >= " + NON_LEGACY_AMPS_VERSION + " and the resource " + + "configuration format is raw." + ); + } + + @Test + public void factoryShouldInitializeLoadRawWithComponentService() throws Exception { + context.checking(new Expectations() {{ + allowing(componentService).getAmpsVersion(resourceId); will(returnValue(NON_LEGACY_AMPS_VERSION)); + + allowing(componentService).getResourceType(resourceId); + will(returnValue(createResourceTypeThatSupportsStructured())); + }}); + + ConfigManagement loadConfig = factory.getStrategy(resourceId); + + assertComponentServiceInitialized(loadConfig); + } + + @Test + public void factoryShouldInitializeLoadRawWithConfigurationUtilityService() throws Exception { + context.checking(new Expectations() {{ + allowing(componentService).getAmpsVersion(resourceId); will(returnValue(NON_LEGACY_AMPS_VERSION)); + + allowing(componentService).getResourceType(resourceId); + will(returnValue(createResourceTypeThatSupportsStructured())); + }}); + + ConfigManagement loadConfig = factory.getStrategy(resourceId); + + assertConfigurationUtilityServiceInitialized(loadConfig); + } + + @Test + public void factoryShouldReturnLoadStructuredAndRawWhenAmpsVersionIs2dot1AndFormatIsBoth() throws Exception { + context.checking(new Expectations() {{ + allowing(componentService).getAmpsVersion(resourceId); will(returnValue(NON_LEGACY_AMPS_VERSION)); + + allowing(componentService).getResourceType(resourceId); + will(returnValue(createResourceTypeThatSupportsStructuredAndRaw())); + }}); + + ConfigManagement loadConfig = factory.getStrategy(resourceId); + + assertTrue( + loadConfig instanceof LoadStructuredAndRaw, + "Expected to get an instance of" + LoadStructuredAndRaw.class.getSimpleName() + + " when resource is from a plugin having an ampsVersion >= " + NON_LEGACY_AMPS_VERSION + " and the " + + "resource configuration format is both (structured and raw)." + ); + } + + @Test + public void factoryShouldInitializeLoadStructuredAndRawWithComponentService() throws Exception { + context.checking(new Expectations() {{ + allowing(componentService).getAmpsVersion(resourceId); will(returnValue(NON_LEGACY_AMPS_VERSION)); + + allowing(componentService).getResourceType(resourceId); + will(returnValue(createResourceTypeThatSupportsStructured())); + }}); + + ConfigManagement loadConfig = factory.getStrategy(resourceId); + + assertComponentServiceInitialized(loadConfig); + } + + @Test + public void factoryShouldInitializeLoadStructuredAndRawWithConfigurationUtilityService() throws Exception { + context.checking(new Expectations() {{ + allowing(componentService).getAmpsVersion(resourceId); will(returnValue(NON_LEGACY_AMPS_VERSION)); + + allowing(componentService).getResourceType(resourceId); + will(returnValue(createResourceTypeThatSupportsStructured())); + }}); + + ConfigManagement loadConfig = factory.getStrategy(resourceId); + + assertConfigurationUtilityServiceInitialized(loadConfig); + } + + void assertComponentServiceInitialized(ConfigManagement loadConfig) { + assertNotNull(loadConfig.getComponentService(), "The factory must initialize the componentService " + + "property of the loadConfig object."); + } + + void assertConfigurationUtilityServiceInitialized(ConfigManagement loadConfig) { + assertNotNull(loadConfig.getConfigurationUtilityService(), "The factory must initialize the " + + "configurationUtilityService property of the loadConfig object."); + } + + ResourceType createResourceType() { + ResourceType resourceType = new ResourceType(); + resourceType.setResourceConfigurationDefinition(new ConfigurationDefinition("test_config", "Test Configuration")); + + return resourceType; + } + + ResourceType createResourceTypeThatSupportsStructured() { + ResourceType resourceType = createResourceType(); + resourceType.getResourceConfigurationDefinition().setConfigurationFormat(ConfigurationFormat.STRUCTURED); + + return resourceType; + } + + ResourceType createResourceTypeThatSupportsRaw() { + ResourceType resourceType = createResourceType(); + resourceType.getResourceConfigurationDefinition().setConfigurationFormat(ConfigurationFormat.RAW); + + return resourceType; + } + + ResourceType createResourceTypeThatSupportsStructuredAndRaw() { + ResourceType resourceType = createResourceType(); + resourceType.getResourceConfigurationDefinition().setConfigurationFormat(ConfigurationFormat.STRUCTURED_AND_RAW); + + return resourceType; + } + +} diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigurationManagerTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigurationManagerTest.java index 747f29e..200ed40 100644 --- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigurationManagerTest.java +++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigurationManagerTest.java @@ -49,7 +49,7 @@ public class ConfigurationManagerTest extends ConfigManagementTest {
boolean FROM_RAW = false;
- LoadResourceConfigurationFactory loadConfigFactory; + ConfigManagementFactory configMgmtFactory;
ComponentService componentService;
@@ -57,12 +57,12 @@ public class ConfigurationManagerTest extends ConfigManagementTest {
@BeforeMethod public void setup() { - loadConfigFactory = context.mock(LoadResourceConfigurationFactory.class); + configMgmtFactory = context.mock(ConfigManagementFactory.class);
componentService = context.mock(ComponentService.class);
configurationMgr = new ConfigurationManager(); - configurationMgr.setLoadConfigFactory(loadConfigFactory); + configurationMgr.setConfigManagementFactory(configMgmtFactory); configurationMgr.setComponentService(componentService); }
@@ -73,7 +73,7 @@ public class ConfigurationManagerTest extends ConfigManagementTest { final ConfigManagement loadConfig = context.mock(ConfigManagement.class);
context.checking(new Expectations() {{ - atLeast(1).of(loadConfigFactory).getStrategy(resourceId); will(returnValue(loadConfig)); + atLeast(1).of(configMgmtFactory).getStrategy(resourceId); will(returnValue(loadConfig));
atLeast(1).of(loadConfig).execute(resourceId); will(returnValue(expectedConfig)); }}); @@ -88,7 +88,7 @@ public class ConfigurationManagerTest extends ConfigManagementTest { final ConfigManagement loadConfig = context.mock(ConfigManagement.class);
context.checking(new Expectations() {{ - atLeast(1).of(loadConfigFactory).getStrategy(resourceId); will(returnValue(loadConfig)); + atLeast(1).of(configMgmtFactory).getStrategy(resourceId); will(returnValue(loadConfig));
atLeast(1).of(loadConfig).execute(resourceId); will(returnValue(null));
@@ -105,7 +105,7 @@ public class ConfigurationManagerTest extends ConfigManagementTest { context.checking(new Expectations() {{ allowing(componentService).getResourceType(resourceId); will(returnValue(resourceType));
- atLeast(1).of(loadConfigFactory).getStrategy(resourceId); will(returnValue(loadConfig)); + atLeast(1).of(configMgmtFactory).getStrategy(resourceId); will(returnValue(loadConfig));
atLeast(1).of(loadConfig).execute(resourceId); will(throwException(new RuntimeException())); }}); diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadResourceConfigurationFactoryImplTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadResourceConfigurationFactoryImplTest.java deleted file mode 100644 index f22c4c1..0000000 --- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadResourceConfigurationFactoryImplTest.java +++ /dev/null @@ -1,273 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2008 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, version 2, as - * published by the Free Software Foundation, and/or the GNU Lesser - * General Public License, version 2.1, also as published by the Free - * Software Foundation. - * - * 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 and the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * and the GNU Lesser 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.core.pc.configuration; - -import static org.testng.Assert.*; - -import org.testng.annotations.Test; -import org.testng.annotations.BeforeMethod; -import org.rhq.core.pc.util.ComponentService; -import org.rhq.core.domain.resource.ResourceType; -import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; -import org.rhq.core.domain.configuration.definition.ConfigurationFormat; -import org.rhq.test.JMockTest; -import org.jmock.Expectations; - -public class LoadResourceConfigurationFactoryImplTest extends JMockTest { - - static final String LEGACY_AMPS_VERSION = "2.0"; - - static final String NON_LEGACY_AMPS_VERSION = "2.1"; - - ComponentService componentService; - - int resourceId = -1; - - LoadResourceConfigurationFactoryImpl factory; - - @BeforeMethod - public void setup() { - componentService = context.mock(ComponentService.class); - - factory = new LoadResourceConfigurationFactoryImpl(); - factory.setComponentService(componentService); - } - - @Test - public void factoryShouldReturnLegacyLoadConfigWhenAmpsVersionIsLessThan2dot1() throws Exception { - context.checking(new Expectations() {{ - allowing(componentService).getAmpsVersion(resourceId); will(returnValue(LEGACY_AMPS_VERSION)); - }}); - - ConfigManagement loadConfig = factory.getStrategy(resourceId); - - assertTrue( - loadConfig instanceof LegacyConfigManagement, - "Expected to get an instance of " + LegacyConfigManagement.class.getSimpleName() + " when the " + - "resource is from a plugin having an ampsVersion less than " + NON_LEGACY_AMPS_VERSION - ); - } - - @Test - public void factoryShouldInitializeLegacyLoadConfigWithComponentService() throws Exception { - context.checking(new Expectations() {{ - allowing(componentService).getAmpsVersion(resourceId); will(returnValue(LEGACY_AMPS_VERSION)); - }}); - - ConfigManagement loadConfig = factory.getStrategy(resourceId); - - assertComponentServiceInitialized(loadConfig); - } - - @Test - public void factoryShouldInitializeLegacyLoadConfigWithConfigurationUtilityService() throws Exception { - context.checking(new Expectations() {{ - allowing(componentService).getAmpsVersion(resourceId); will(returnValue(LEGACY_AMPS_VERSION)); - }}); - - ConfigManagement loadConfig = factory.getStrategy(resourceId); - - assertConfigurationUtilityServiceInitialized(loadConfig); - } - - @Test - public void factoryShouldReturnStructuredLoadConfigWhenAmpsVersionIs2dot1AndFormatIsStructured() throws Exception { - context.checking(new Expectations() {{ - allowing(componentService).getAmpsVersion(resourceId); will(returnValue(NON_LEGACY_AMPS_VERSION)); - - allowing(componentService).getResourceType(resourceId); - will(returnValue(createResourceTypeThatSupportsStructured())); - }}); - - ConfigManagement loadConfig = factory.getStrategy(resourceId); - - assertTrue( - loadConfig instanceof LoadStructured, - "Expected to get an instance of " + LoadStructured.class.getSimpleName() + - "when resource is from a plugin having an ampsversion >= " + NON_LEGACY_AMPS_VERSION + " and the resource " + - "configuration format is structured." - ); - } - - @Test - public void factoryShouldInitializeLoadStructuredWithComponentService() throws Exception { - context.checking(new Expectations() {{ - allowing(componentService).getAmpsVersion(resourceId); will(returnValue(NON_LEGACY_AMPS_VERSION)); - - allowing(componentService).getResourceType(resourceId); - will(returnValue(createResourceTypeThatSupportsStructured())); - }}); - - ConfigManagement loadConfig = factory.getStrategy(resourceId); - - assertComponentServiceInitialized(loadConfig); - } - - @Test - public void factoryShouldInitializeLoadStructuredWithConfigurationUtilityService() throws Exception { - context.checking(new Expectations() {{ - allowing(componentService).getAmpsVersion(resourceId); will(returnValue(NON_LEGACY_AMPS_VERSION)); - - allowing(componentService).getResourceType(resourceId); - will(returnValue(createResourceTypeThatSupportsStructured())); - }}); - - ConfigManagement loadConfig = factory.getStrategy(resourceId); - - assertConfigurationUtilityServiceInitialized(loadConfig); - } - - @Test - public void factoryShouldReturnLoadRawWhenAmpsVersionIs2dot1AndFormatIsRaw() throws Exception { - context.checking(new Expectations() {{ - allowing(componentService).getAmpsVersion(resourceId); will(returnValue(NON_LEGACY_AMPS_VERSION)); - - allowing(componentService).getResourceType(resourceId); - will(returnValue(createResourceTypeThatSupportsRaw())); - }}); - - ConfigManagement loadConfig = factory.getStrategy(resourceId); - - assertTrue( - loadConfig instanceof RawConfigManagement, - "Expected to get an instance of " + RawConfigManagement.class.getSimpleName() + " when " + - "resource is from a plugin having an ampsversion >= " + NON_LEGACY_AMPS_VERSION + " and the resource " + - "configuration format is raw." - ); - } - - @Test - public void factoryShouldInitializeLoadRawWithComponentService() throws Exception { - context.checking(new Expectations() {{ - allowing(componentService).getAmpsVersion(resourceId); will(returnValue(NON_LEGACY_AMPS_VERSION)); - - allowing(componentService).getResourceType(resourceId); - will(returnValue(createResourceTypeThatSupportsStructured())); - }}); - - ConfigManagement loadConfig = factory.getStrategy(resourceId); - - assertComponentServiceInitialized(loadConfig); - } - - @Test - public void factoryShouldInitializeLoadRawWithConfigurationUtilityService() throws Exception { - context.checking(new Expectations() {{ - allowing(componentService).getAmpsVersion(resourceId); will(returnValue(NON_LEGACY_AMPS_VERSION)); - - allowing(componentService).getResourceType(resourceId); - will(returnValue(createResourceTypeThatSupportsStructured())); - }}); - - ConfigManagement loadConfig = factory.getStrategy(resourceId); - - assertConfigurationUtilityServiceInitialized(loadConfig); - } - - @Test - public void factoryShouldReturnLoadStructuredAndRawWhenAmpsVersionIs2dot1AndFormatIsBoth() throws Exception { - context.checking(new Expectations() {{ - allowing(componentService).getAmpsVersion(resourceId); will(returnValue(NON_LEGACY_AMPS_VERSION)); - - allowing(componentService).getResourceType(resourceId); - will(returnValue(createResourceTypeThatSupportsStructuredAndRaw())); - }}); - - ConfigManagement loadConfig = factory.getStrategy(resourceId); - - assertTrue( - loadConfig instanceof LoadStructuredAndRaw, - "Expected to get an instance of" + LoadStructuredAndRaw.class.getSimpleName() + - " when resource is from a plugin having an ampsVersion >= " + NON_LEGACY_AMPS_VERSION + " and the " + - "resource configuration format is both (structured and raw)." - ); - } - - @Test - public void factoryShouldInitializeLoadStructuredAndRawWithComponentService() throws Exception { - context.checking(new Expectations() {{ - allowing(componentService).getAmpsVersion(resourceId); will(returnValue(NON_LEGACY_AMPS_VERSION)); - - allowing(componentService).getResourceType(resourceId); - will(returnValue(createResourceTypeThatSupportsStructured())); - }}); - - ConfigManagement loadConfig = factory.getStrategy(resourceId); - - assertComponentServiceInitialized(loadConfig); - } - - @Test - public void factoryShouldInitializeLoadStructuredAndRawWithConfigurationUtilityService() throws Exception { - context.checking(new Expectations() {{ - allowing(componentService).getAmpsVersion(resourceId); will(returnValue(NON_LEGACY_AMPS_VERSION)); - - allowing(componentService).getResourceType(resourceId); - will(returnValue(createResourceTypeThatSupportsStructured())); - }}); - - ConfigManagement loadConfig = factory.getStrategy(resourceId); - - assertConfigurationUtilityServiceInitialized(loadConfig); - } - - void assertComponentServiceInitialized(ConfigManagement loadConfig) { - assertNotNull(loadConfig.getComponentService(), "The factory must initialize the componentService " + - "property of the loadConfig object."); - } - - void assertConfigurationUtilityServiceInitialized(ConfigManagement loadConfig) { - assertNotNull(loadConfig.getConfigurationUtilityService(), "The factory must initialize the " + - "configurationUtilityService property of the loadConfig object."); - } - - ResourceType createResourceType() { - ResourceType resourceType = new ResourceType(); - resourceType.setResourceConfigurationDefinition(new ConfigurationDefinition("test_config", "Test Configuration")); - - return resourceType; - } - - ResourceType createResourceTypeThatSupportsStructured() { - ResourceType resourceType = createResourceType(); - resourceType.getResourceConfigurationDefinition().setConfigurationFormat(ConfigurationFormat.STRUCTURED); - - return resourceType; - } - - ResourceType createResourceTypeThatSupportsRaw() { - ResourceType resourceType = createResourceType(); - resourceType.getResourceConfigurationDefinition().setConfigurationFormat(ConfigurationFormat.RAW); - - return resourceType; - } - - ResourceType createResourceTypeThatSupportsStructuredAndRaw() { - ResourceType resourceType = createResourceType(); - resourceType.getResourceConfigurationDefinition().setConfigurationFormat(ConfigurationFormat.STRUCTURED_AND_RAW); - - return resourceType; - } - -}
commit b6390b22dbd28be0688566e3034bb5f4a0b1d840 Merge: ef77c4a... 3755cc5... Author: Jay Shaughnessy jshaughn@redhat.com Date: Tue Nov 24 10:00:33 2009 -0500
Merge branch 'linux-config-dev' into linux-config
Conflicts: modules/enterprise/server/plugins/perspectives/core/perspective/src/main/resources/META-INF/rhq-serverplugin.xml modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-perspective.xsd
diff --cc modules/enterprise/server/plugins/perspectives/core/perspective/src/main/resources/META-INF/rhq-serverplugin.xml index 63e1746,fb640ee..1617ef6 --- a/modules/enterprise/server/plugins/perspectives/core/perspective/src/main/resources/META-INF/rhq-serverplugin.xml +++ b/modules/enterprise/server/plugins/perspectives/core/perspective/src/main/resources/META-INF/rhq-serverplugin.xml @@@ -503,4 -503,4 +503,4 @@@
--</perspectivePlugin> ++</perspectivePlugin>
commit 082c3dd41f771708b9b1a6cae52a36b25e2fe59f Author: John Sanda john@localhost.localdomain Date: Tue Nov 24 09:32:38 2009 -0500
[US 6] Starting to refactor UpdateResourceConfigurationRunner for raw config support and lots of refactoring.
Renaming LoadResourceConfiguration to ConfigManagement since the interface now provides operations both for loading and updating configs. Renaming implementors to more logical names.
Refactoring UpdatResourceConfigurationRunner to take an instance of ConfigManagement instead of ConfigurationFacet.
Adding the method assertCollectionEqualsNoOrder() in AssertUtils in the test-utils module. The method implementation is largely delegated to CollectionEqualsChecker has logic to provide a useful error report. It will generate a message that tells you if elements were found in the collection that should not have been there as well as if elements were not found that should have been.
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/BaseLoadConfig.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/BaseLoadConfig.java deleted file mode 100644 index 417bf7f..0000000 --- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/BaseLoadConfig.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2008 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, version 2, as - * published by the Free Software Foundation, and/or the GNU Lesser - * General Public License, version 2.1, also as published by the Free - * Software Foundation. - * - * 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 and the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * and the GNU Lesser 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.core.pc.configuration; - -import org.rhq.core.pc.util.ComponentService; -import org.rhq.core.pc.util.FacetLockType; -import org.rhq.core.pluginapi.configuration.ResourceConfigurationFacet; -import org.rhq.core.clientapi.agent.PluginContainerException; - -public abstract class BaseLoadConfig implements LoadResourceConfiguration { - - protected ComponentService componentService; - - protected ConfigurationUtilityService configUtilityService; - - public ComponentService getComponentService() { - return componentService; - } - - public void setComponentService(ComponentService componentService) { - this.componentService = componentService; - } - - public ConfigurationUtilityService getConfigurationUtilityService() { - return configUtilityService; - } - - public void setConfigurationUtilityService(ConfigurationUtilityService configUtilityService) { - this.configUtilityService = configUtilityService; - } - - protected ResourceConfigurationFacet loadResouceConfiguratonFacet(int resourceId) throws PluginContainerException { - boolean daemonOnly = true; - boolean onlyIfStarted = true; - - return componentService.getComponent(resourceId, ResourceConfigurationFacet.class, FacetLockType.READ, - FACET_METHOD_TIMEOUT, daemonOnly, onlyIfStarted); - } -} diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigManagement.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigManagement.java new file mode 100644 index 0000000..b6f24b3 --- /dev/null +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigManagement.java @@ -0,0 +1,48 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2008 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, version 2, as + * published by the Free Software Foundation, and/or the GNU Lesser + * General Public License, version 2.1, also as published by the Free + * Software Foundation. + * + * 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 and the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * and the GNU Lesser 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.core.pc.configuration; + +import org.rhq.core.pc.util.ComponentService; +import org.rhq.core.domain.configuration.Configuration; +import org.rhq.core.clientapi.agent.PluginContainerException; +import org.rhq.core.pluginapi.configuration.ConfigurationUpdateReport; + +public interface ConfigManagement { + + static final int FACET_METHOD_TIMEOUT = 60 * 1000; // 60 seconds + + ComponentService getComponentService(); + + void setComponentService(ComponentService componentService); + + ConfigurationUtilityService getConfigurationUtilityService(); + + void setConfigurationUtilityService(ConfigurationUtilityService configUtilityService); + + Configuration execute(int resourceId) throws PluginContainerException; + + ConfigurationUpdateReport executeUpdate(int resourceId, Configuration configuration) + throws PluginContainerException; + +} diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigManagementSupport.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigManagementSupport.java new file mode 100644 index 0000000..24fd900 --- /dev/null +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigManagementSupport.java @@ -0,0 +1,71 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2008 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, version 2, as + * published by the Free Software Foundation, and/or the GNU Lesser + * General Public License, version 2.1, also as published by the Free + * Software Foundation. + * + * 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 and the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * and the GNU Lesser 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.core.pc.configuration; + +import org.rhq.core.pc.util.ComponentService; +import org.rhq.core.pc.util.FacetLockType; +import org.rhq.core.pluginapi.configuration.ResourceConfigurationFacet; +import org.rhq.core.pluginapi.configuration.ConfigurationFacet; +import org.rhq.core.clientapi.agent.PluginContainerException; + +public abstract class ConfigManagementSupport implements ConfigManagement { + + protected ComponentService componentService; + + protected ConfigurationUtilityService configUtilityService; + + public ComponentService getComponentService() { + return componentService; + } + + public void setComponentService(ComponentService componentService) { + this.componentService = componentService; + } + + public ConfigurationUtilityService getConfigurationUtilityService() { + return configUtilityService; + } + + public void setConfigurationUtilityService(ConfigurationUtilityService configUtilityService) { + this.configUtilityService = configUtilityService; + } + + protected ResourceConfigurationFacet loadResouceConfiguratonFacet(int resourceId) throws PluginContainerException { + boolean daemonOnly = true; + boolean onlyIfStarted = true; + + return componentService.getComponent(resourceId, ResourceConfigurationFacet.class, FacetLockType.READ, + FACET_METHOD_TIMEOUT, daemonOnly, onlyIfStarted); + } + + protected ConfigurationFacet loadConfigurationFacet(int resourceId, FacetLockType lockType) + throws PluginContainerException { + + boolean daemonThread = (lockType != FacetLockType.WRITE); + boolean onlyIfStarted = true; + + return componentService.getComponent(resourceId, ConfigurationFacet.class, lockType, FACET_METHOD_TIMEOUT, + daemonThread, onlyIfStarted); + } +} diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManager.java index 8bfbfb3..25ae1e7 100644 --- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManager.java +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManager.java @@ -22,7 +22,6 @@ */ package org.rhq.core.pc.configuration;
-import java.util.List; import java.util.Set; import java.util.Queue; import java.util.LinkedList; @@ -35,13 +34,11 @@ import org.apache.maven.artifact.versioning.ComparableVersion; import org.rhq.core.clientapi.agent.PluginContainerException; import org.rhq.core.clientapi.agent.configuration.ConfigurationAgentService; import org.rhq.core.clientapi.agent.configuration.ConfigurationUpdateRequest; -import org.rhq.core.clientapi.agent.configuration.ConfigurationUtility; import org.rhq.core.clientapi.server.configuration.ConfigurationServerService; import org.rhq.core.clientapi.server.configuration.ConfigurationUpdateResponse; import org.rhq.core.domain.configuration.Configuration; import org.rhq.core.domain.configuration.RawConfiguration; import org.rhq.core.domain.configuration.Property; -import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; import org.rhq.core.domain.resource.ResourceType; import org.rhq.core.pc.ContainerService; import org.rhq.core.pc.PluginContainerConfiguration; @@ -53,7 +50,6 @@ import org.rhq.core.pc.util.FacetLockType; import org.rhq.core.pc.util.LoggingThreadFactory; import org.rhq.core.pluginapi.configuration.ConfigurationFacet; import org.rhq.core.pluginapi.configuration.ResourceConfigurationFacet; -import org.rhq.core.util.exception.WrappedRemotingException;
/** * Manages configuration of all resources across all plugins. @@ -119,12 +115,14 @@ public class ConfigurationManager extends AgentService implements ContainerServi public void updateResourceConfiguration(ConfigurationUpdateRequest request) { ConfigurationServerService configurationServerService = getConfigurationServerService();
+ ConfigManagement configMgmt = new LegacyConfigManagement(); + configMgmt.setComponentService(componentService); + try { ResourceType resourceType = getResourceType(request.getResourceId()); - ConfigurationFacet configurationFacet = getConfigurationFacet(request.getResourceId(), FacetLockType.WRITE);
Runnable runnable = new UpdateResourceConfigurationRunner(configurationServerService, resourceType, - configurationFacet, request); + configMgmt, request); getThreadPool().submit(runnable); } catch (PluginContainerException e) { log.error("Failed to submit config update task. Cause: " + e); @@ -149,12 +147,14 @@ public class ConfigurationManager extends AgentService implements ContainerServi try { ConfigurationServerService configurationServerService = getConfigurationServerService(); ResourceType resourceType = getResourceType(request.getResourceId()); - ConfigurationFacet configurationFacet = getConfigurationFacet(request.getResourceId(), FacetLockType.WRITE); + + ConfigManagement configMgmt = new LegacyConfigManagement(); + configMgmt.setComponentService(componentService);
Callable<ConfigurationUpdateResponse> runner;
runner = new UpdateResourceConfigurationRunner(configurationServerService, resourceType, - configurationFacet, request); + configMgmt, request);
response = getThreadPool().submit(runner).get(); } catch (Exception e) { @@ -243,7 +243,7 @@ public class ConfigurationManager extends AgentService implements ContainerServi public Configuration loadResourceConfiguration(int resourceId) throws PluginContainerException {
- LoadResourceConfiguration loadConfig = loadConfigFactory.getStrategy(resourceId); + ConfigManagement loadConfig = loadConfigFactory.getStrategy(resourceId); Configuration configuration = null;
try { diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LegacyConfigManagement.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LegacyConfigManagement.java new file mode 100644 index 0000000..85aa6ce --- /dev/null +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LegacyConfigManagement.java @@ -0,0 +1,88 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2008 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, version 2, as + * published by the Free Software Foundation, and/or the GNU Lesser + * General Public License, version 2.1, also as published by the Free + * Software Foundation. + * + * 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 and the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * and the GNU Lesser 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.core.pc.configuration; + +import static org.rhq.core.pc.util.FacetLockType.*; +import org.rhq.core.pc.util.FacetLockType; + +import org.rhq.core.clientapi.agent.PluginContainerException; +import org.rhq.core.clientapi.agent.configuration.ConfigurationUtility; +import org.rhq.core.domain.configuration.Configuration; +import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; +import org.rhq.core.domain.resource.ResourceType; +import org.rhq.core.pluginapi.configuration.ConfigurationFacet; +import org.rhq.core.pluginapi.configuration.ConfigurationUpdateReport; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.util.List; + +public class LegacyConfigManagement extends ConfigManagementSupport { + + private static final Log log = LogFactory.getLog(LegacyConfigManagement.class); + + public Configuration execute(int resourceId) throws PluginContainerException { + Configuration configuration = loadConfigFromFacet(resourceId, READ); + ResourceType resourceType = componentService.getResourceType(resourceId); + + // If the plugin didn't already set the notes field, set it to something useful. + if (configuration.getNotes() == null) { + configuration.setNotes("Resource config for " + resourceType.getName() + " Resource w/ id " + resourceId); + } + + ConfigurationDefinition configurationDefinition = resourceType.getResourceConfigurationDefinition(); + + // Normalize and validate the config. + ConfigurationUtility.normalizeConfiguration(configuration, configurationDefinition); + List<String> errorMessages = ConfigurationUtility.validateConfiguration(configuration, + configurationDefinition); + for (String errorMessage : errorMessages) { + log.warn("Plugin Error: Invalid " + resourceType.getName() + " Resource configuration returned by " + + resourceType.getPlugin() + " plugin - " + errorMessage); + } + + return configuration; + } + + private Configuration loadConfigFromFacet(int resourceId, FacetLockType lockType) throws PluginContainerException { + ConfigurationFacet configFacet = loadConfigurationFacet(resourceId, lockType); + + try { + return configFacet.loadResourceConfiguration(); + } catch (Exception e) { + throw new PluginContainerException(e); + } + } + + public ConfigurationUpdateReport executeUpdate(int resourceId, Configuration configuration) + throws PluginContainerException { + ConfigurationFacet facet = loadConfigurationFacet(resourceId, WRITE); + ConfigurationUpdateReport report = new ConfigurationUpdateReport(configuration); + + facet.updateResourceConfiguration(report); + + return report; + } + +} diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LegacyLoadConfig.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LegacyLoadConfig.java deleted file mode 100644 index b987ddf..0000000 --- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LegacyLoadConfig.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2008 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, version 2, as - * published by the Free Software Foundation, and/or the GNU Lesser - * General Public License, version 2.1, also as published by the Free - * Software Foundation. - * - * 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 and the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * and the GNU Lesser 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.core.pc.configuration; - -import org.rhq.core.clientapi.agent.PluginContainerException; -import org.rhq.core.clientapi.agent.configuration.ConfigurationUtility; -import org.rhq.core.domain.configuration.Configuration; -import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; -import org.rhq.core.domain.resource.ResourceType; -import org.rhq.core.pc.util.FacetLockType; -import org.rhq.core.pluginapi.configuration.ConfigurationFacet; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import java.util.List; - -public class LegacyLoadConfig extends BaseLoadConfig { - - private static final Log log = LogFactory.getLog(LegacyLoadConfig.class); - - public Configuration execute(int resourceId) throws PluginContainerException { - Configuration configuration = loadConfigFromFacet(resourceId); - ResourceType resourceType = componentService.getResourceType(resourceId); - - // If the plugin didn't already set the notes field, set it to something useful. - if (configuration.getNotes() == null) { - configuration.setNotes("Resource config for " + resourceType.getName() + " Resource w/ id " + resourceId); - } - - ConfigurationDefinition configurationDefinition = resourceType.getResourceConfigurationDefinition(); - - // Normalize and validate the config. - ConfigurationUtility.normalizeConfiguration(configuration, configurationDefinition); - List<String> errorMessages = ConfigurationUtility.validateConfiguration(configuration, - configurationDefinition); - for (String errorMessage : errorMessages) { - log.warn("Plugin Error: Invalid " + resourceType.getName() + " Resource configuration returned by " - + resourceType.getPlugin() + " plugin - " + errorMessage); - } - - return configuration; - } - - private Configuration loadConfigFromFacet(int resourceId) throws PluginContainerException { - FacetLockType lockType = FacetLockType.READ; - boolean daemonThread = (lockType != FacetLockType.WRITE); - boolean onlyIfStarted = true; - - ConfigurationFacet configFacet = componentService.getComponent(resourceId, ConfigurationFacet.class, - lockType, FACET_METHOD_TIMEOUT, daemonThread, onlyIfStarted); - - Configuration configuration = null; - try { - return configFacet.loadResourceConfiguration(); - } catch (Exception e) { - throw new PluginContainerException(e); - } - } - -} diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadRaw.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadRaw.java deleted file mode 100644 index debfa45..0000000 --- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadRaw.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2008 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, version 2, as - * published by the Free Software Foundation, and/or the GNU Lesser - * General Public License, version 2.1, also as published by the Free - * Software Foundation. - * - * 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 and the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * and the GNU Lesser 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.core.pc.configuration; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.rhq.core.clientapi.agent.PluginContainerException; -import org.rhq.core.domain.configuration.Configuration; -import org.rhq.core.domain.configuration.RawConfiguration; -import org.rhq.core.domain.resource.ResourceType; -import org.rhq.core.pluginapi.configuration.ResourceConfigurationFacet; - -import java.util.Set; - -public class LoadRaw extends BaseLoadConfig { - - private final Log log = LogFactory.getLog(LoadRaw.class); - - public Configuration execute(int resourceId) throws PluginContainerException { - ResourceConfigurationFacet facet = loadResouceConfiguratonFacet(resourceId); - - Set<RawConfiguration> rawConfigs = facet.loadRawConfigurations(); - - if (rawConfigs == null) { - return null; - } - - Configuration config = new Configuration(); - for (RawConfiguration rawConfig : rawConfigs) { - config.addRawConfiguration(rawConfig); - } - - if (config.getNotes() == null) { - ResourceType resourceType = componentService.getResourceType(resourceId); - config.setNotes("Resource config for " + resourceType.getName() + " Resource w/ id " + resourceId); - } - - return config; - } - -} diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadResourceConfiguration.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadResourceConfiguration.java deleted file mode 100644 index 60133c7..0000000 --- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadResourceConfiguration.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2008 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, version 2, as - * published by the Free Software Foundation, and/or the GNU Lesser - * General Public License, version 2.1, also as published by the Free - * Software Foundation. - * - * 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 and the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * and the GNU Lesser 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.core.pc.configuration; - -import org.rhq.core.pc.util.ComponentService; -import org.rhq.core.domain.configuration.Configuration; -import org.rhq.core.clientapi.agent.PluginContainerException; - -public interface LoadResourceConfiguration { - - static final int FACET_METHOD_TIMEOUT = 60 * 1000; // 60 seconds - - ComponentService getComponentService(); - - void setComponentService(ComponentService componentService); - - ConfigurationUtilityService getConfigurationUtilityService(); - - void setConfigurationUtilityService(ConfigurationUtilityService configUtilityService); - - Configuration execute(int resourceId) throws PluginContainerException; - -} diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadResourceConfigurationFactory.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadResourceConfigurationFactory.java index 5bd04ed..be777be 100644 --- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadResourceConfigurationFactory.java +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadResourceConfigurationFactory.java @@ -27,6 +27,6 @@ import org.rhq.core.clientapi.agent.PluginContainerException;
public interface LoadResourceConfigurationFactory {
- LoadResourceConfiguration getStrategy(int resourceId) throws PluginContainerException; + ConfigManagement getStrategy(int resourceId) throws PluginContainerException;
} diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadResourceConfigurationFactoryImpl.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadResourceConfigurationFactoryImpl.java index e2b1e86..ad5ece4 100644 --- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadResourceConfigurationFactoryImpl.java +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadResourceConfigurationFactoryImpl.java @@ -42,23 +42,23 @@ public class LoadResourceConfigurationFactoryImpl implements LoadResourceConfigu this.componentService = componentService; }
- public LoadResourceConfiguration getStrategy(int resourceId) throws PluginContainerException { - LoadResourceConfiguration loadConfig = createStrategy(resourceId); + public ConfigManagement getStrategy(int resourceId) throws PluginContainerException { + ConfigManagement loadConfig = createStrategy(resourceId); initStrategyDependencies(loadConfig);
return loadConfig; }
- private void initStrategyDependencies(LoadResourceConfiguration loadConfig) { + private void initStrategyDependencies(ConfigManagement loadConfig) { loadConfig.setComponentService(componentService); loadConfig.setConfigurationUtilityService(configUtilityService); }
- private LoadResourceConfiguration createStrategy(int resourceId) throws PluginContainerException { + private ConfigManagement createStrategy(int resourceId) throws PluginContainerException { String ampsVersion = componentService.getAmpsVersion(resourceId);
if (isLegacyVersion(ampsVersion)) { - return new LegacyLoadConfig(); + return new LegacyConfigManagement(); }
ResourceType resourceType = componentService.getResourceType(resourceId); @@ -68,7 +68,7 @@ public class LoadResourceConfigurationFactoryImpl implements LoadResourceConfigu }
if (isRaw(resourceType)) { - return new LoadRaw(); + return new RawConfigManagement(); }
// else format is both structured and raw diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadStructured.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadStructured.java index 7d29270..e978233 100644 --- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadStructured.java +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadStructured.java @@ -27,12 +27,13 @@ import org.rhq.core.domain.configuration.Configuration; import org.rhq.core.domain.resource.ResourceType; import org.rhq.core.clientapi.agent.PluginContainerException; import org.rhq.core.pluginapi.configuration.ResourceConfigurationFacet; +import org.rhq.core.pluginapi.configuration.ConfigurationUpdateReport; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory;
import java.util.List;
-public class LoadStructured extends BaseLoadConfig { +public class LoadStructured extends ConfigManagementSupport {
private final Log log = LogFactory.getLog(LoadStructured.class);
@@ -66,4 +67,9 @@ public class LoadStructured extends BaseLoadConfig { + resourceType.getPlugin() + " plugin - " + errorMessage); } } + + public ConfigurationUpdateReport executeUpdate(int resourceId, Configuration configuration) + throws PluginContainerException { + return null; + } } diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadStructuredAndRaw.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadStructuredAndRaw.java index c139ae5..2ff175f 100644 --- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadStructuredAndRaw.java +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadStructuredAndRaw.java @@ -30,13 +30,14 @@ import org.rhq.core.domain.configuration.RawConfiguration; import org.rhq.core.domain.resource.ResourceType; import org.rhq.core.clientapi.agent.PluginContainerException; import org.rhq.core.pluginapi.configuration.ResourceConfigurationFacet; +import org.rhq.core.pluginapi.configuration.ConfigurationUpdateReport; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory;
import java.util.List; import java.util.Set;
-public class LoadStructuredAndRaw extends BaseLoadConfig { +public class LoadStructuredAndRaw extends ConfigManagementSupport {
private final Log log = LogFactory.getLog(LoadStructuredAndRaw.class);
@@ -83,4 +84,9 @@ public class LoadStructuredAndRaw extends BaseLoadConfig { + resourceType.getPlugin() + " plugin - " + errorMessage); } } + + public ConfigurationUpdateReport executeUpdate(int resourceId, Configuration configuration) + throws PluginContainerException { + return null; + } } diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/RawConfigManagement.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/RawConfigManagement.java new file mode 100644 index 0000000..c3c99f9 --- /dev/null +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/RawConfigManagement.java @@ -0,0 +1,67 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2008 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, version 2, as + * published by the Free Software Foundation, and/or the GNU Lesser + * General Public License, version 2.1, also as published by the Free + * Software Foundation. + * + * 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 and the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * and the GNU Lesser 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.core.pc.configuration; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.rhq.core.clientapi.agent.PluginContainerException; +import org.rhq.core.domain.configuration.Configuration; +import org.rhq.core.domain.configuration.RawConfiguration; +import org.rhq.core.domain.resource.ResourceType; +import org.rhq.core.pluginapi.configuration.ResourceConfigurationFacet; +import org.rhq.core.pluginapi.configuration.ConfigurationUpdateReport; + +import java.util.Set; + +public class RawConfigManagement extends ConfigManagementSupport { + + private final Log log = LogFactory.getLog(RawConfigManagement.class); + + public Configuration execute(int resourceId) throws PluginContainerException { + ResourceConfigurationFacet facet = loadResouceConfiguratonFacet(resourceId); + + Set<RawConfiguration> rawConfigs = facet.loadRawConfigurations(); + + if (rawConfigs == null) { + return null; + } + + Configuration config = new Configuration(); + for (RawConfiguration rawConfig : rawConfigs) { + config.addRawConfiguration(rawConfig); + } + + if (config.getNotes() == null) { + ResourceType resourceType = componentService.getResourceType(resourceId); + config.setNotes("Resource config for " + resourceType.getName() + " Resource w/ id " + resourceId); + } + + return config; + } + + public ConfigurationUpdateReport executeUpdate(int resourceId, Configuration configuration) + throws PluginContainerException { + return null; + } +} diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/UpdateResourceConfigurationRunner.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/UpdateResourceConfigurationRunner.java index c93485b..163dc8c 100644 --- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/UpdateResourceConfigurationRunner.java +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/UpdateResourceConfigurationRunner.java @@ -29,7 +29,6 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory;
import org.rhq.core.clientapi.agent.configuration.ConfigurationUpdateRequest; -import org.rhq.core.clientapi.agent.configuration.ConfigurationUtility; import org.rhq.core.clientapi.server.configuration.ConfigurationServerService; import org.rhq.core.clientapi.server.configuration.ConfigurationUpdateResponse; import org.rhq.core.domain.configuration.ConfigurationUpdateStatus; @@ -51,6 +50,8 @@ public class UpdateResourceConfigurationRunner implements Runnable, Callable<Con */ private ConfigurationUpdateRequest request;
+ private ConfigManagement configMgmt; + /** * The resource component's facet that will perform the actual re-configuration of the resource. */ @@ -70,10 +71,10 @@ public class UpdateResourceConfigurationRunner implements Runnable, Callable<Con private ConfigurationUtilityService configUtilService = new ConfigurationUtilityServiceImpl();
public UpdateResourceConfigurationRunner(ConfigurationServerService configurationServerService, ResourceType type, - ConfigurationFacet facet, ConfigurationUpdateRequest request) { + ConfigManagement configMgmt, ConfigurationUpdateRequest request) { this.configurationServerService = configurationServerService; // may be null this.resourceType = type; - this.configurationFacet = facet; + this.configMgmt = configMgmt; this.request = request; }
@@ -92,10 +93,12 @@ public class UpdateResourceConfigurationRunner implements Runnable, Callable<Con public ConfigurationUpdateResponse call() throws Exception { ConfigurationUpdateResponse response; int requestId = request.getConfigurationUpdateId(); - ConfigurationUpdateReport report = new ConfigurationUpdateReport(request.getConfiguration()); +// ConfigurationUpdateReport report = new ConfigurationUpdateReport(request.getConfiguration()); + ConfigurationUpdateReport report = null; try { - configurationFacet.updateResourceConfiguration(report); - +// configurationFacet.updateResourceConfiguration(report); + report = configMgmt.executeUpdate(request.getResourceId(), request.getConfiguration()); + response = new ConfigurationUpdateResponse(requestId, report.getConfiguration(), report.getStatus(), report .getErrorMessage());
@@ -123,7 +126,7 @@ public class UpdateResourceConfigurationRunner implements Runnable, Callable<Con } catch (Throwable t) { log.error("Plugin Error: Exception thrown while updating Resource configuration for " + resourceType.getName() + " Resource with id [" + request.getResourceId() + "].", t); - response = new ConfigurationUpdateResponse(requestId, report.getConfiguration(), t); + response = new ConfigurationUpdateResponse(requestId, request.getConfiguration(), t); }
if (this.configurationServerService != null) { @@ -132,4 +135,4 @@ public class UpdateResourceConfigurationRunner implements Runnable, Callable<Con
return response; } -} \ No newline at end of file +} diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigManagementTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigManagementTest.java index cf6e9e9..cc8e760 100644 --- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigManagementTest.java +++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigManagementTest.java @@ -29,6 +29,8 @@ import org.rhq.core.domain.configuration.RawConfiguration; import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; import org.rhq.core.domain.resource.ResourceType; import org.rhq.test.JMockTest; + +import static org.rhq.test.AssertUtils.*; import static org.testng.Assert.assertEquals;
import java.util.HashSet; @@ -83,19 +85,30 @@ public class ConfigManagementTest extends JMockTest { }
void assertRawsLoaded(Set<RawConfiguration> expectedRaws, Configuration actualConfig) { - assertEquals( - actualConfig.getRawConfigurations(), + assertCollectionEqualsNoOrder( expectedRaws, + actualConfig.getRawConfigurations(), "The raw configs were not loaded correctly." ); +// assertEquals( +// actualConfig.getRawConfigurations(), +// expectedRaws, +// "The raw configs were not loaded correctly." +// ); }
void assertStructuredLoaded(Configuration expectedConfig, Configuration actualConfig) { - assertEquals( - actualConfig.getAllProperties(), - expectedConfig.getAllProperties(), + assertCollectionEqualsNoOrder( + expectedConfig.getProperties(), + actualConfig.getProperties(), "The structured configuration was not loaded correctly." ); + +// assertEquals( +// actualConfig.getAllProperties(), +// expectedConfig.getAllProperties(), +// "The structured configuration was not loaded correctly." +// ); }
void assertNotesSetToDefault(Configuration loadedConfig) { diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigurationManagerTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigurationManagerTest.java index 3e0bd7f..747f29e 100644 --- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigurationManagerTest.java +++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigurationManagerTest.java @@ -1,143 +1,320 @@ - /* - * RHQ Management Platform - * Copyright (C) 2005-2008 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, version 2, as - * published by the Free Software Foundation, and/or the GNU Lesser - * General Public License, version 2.1, also as published by the Free - * Software Foundation. - * - * 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 and the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * and the GNU Lesser 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. - */ +/* + * RHQ Management Platform + * Copyright (C) 2005-2008 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, version 2, as + * published by the Free Software Foundation, and/or the GNU Lesser + * General Public License, version 2.1, also as published by the Free + * Software Foundation. + * + * 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 and the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * and the GNU Lesser 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.core.pc.configuration;
-import org.testng.annotations.AfterMethod; -import org.testng.annotations.BeforeMethod; -import org.testng.annotations.Test; +import static org.testng.Assert.*;
+import org.jmock.Expectations; import org.rhq.core.clientapi.agent.PluginContainerException; -import org.rhq.core.clientapi.agent.configuration.ConfigurationUpdateRequest; -import org.rhq.core.clientapi.server.configuration.ConfigurationServerService; -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.RawConfiguration; +import org.rhq.core.domain.configuration.PropertySimple; import org.rhq.core.domain.resource.ResourceType; -import org.rhq.core.pc.PluginContainerConfiguration; -import org.rhq.core.pc.ServerServices; +import org.rhq.core.pc.util.ComponentService; import org.rhq.core.pc.util.FacetLockType; -import org.rhq.core.pluginapi.configuration.ConfigurationFacet; -import org.rhq.core.pluginapi.configuration.ConfigurationUpdateReport; +import org.rhq.core.pluginapi.configuration.ResourceConfigurationFacet; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test;
-/** - * ConfigurationManager Tester. - * - * @author mspritzler - * - * @since 1.0 - * @created June 14, 2007 - */ -public class ConfigurationManagerTest { - private ConfigurationManager manager; +import java.util.Set; + +public class ConfigurationManagerTest extends ConfigManagementTest { + + static final String LEGACY_AMPS_VERSION = "2.0"; + + static final String NON_LEGACY_AMPS_VERSION = "2.1"; + + boolean FROM_STRUCTURED = true; + + boolean FROM_RAW = false; + + LoadResourceConfigurationFactory loadConfigFactory; + + ComponentService componentService; + + ConfigurationManager configurationMgr;
@BeforeMethod - public void setUp() { - // create a plugin container config that contains our mock server service so the manager uses it - ServerServices serverServices = new ServerServices(); - serverServices.setConfigurationServerService(new MockConfigurationServerService()); - PluginContainerConfiguration pcConfig = new PluginContainerConfiguration(); - pcConfig.setServerServices(serverServices); - - // create our mock manager and initialize it - manager = new MockConfigurationManager(); - manager.setConfiguration(pcConfig); - manager.initialize(); - } + public void setup() { + loadConfigFactory = context.mock(LoadResourceConfigurationFactory.class);
- @AfterMethod - public void tearDown() { - manager.shutdown(); + componentService = context.mock(ComponentService.class); + + configurationMgr = new ConfigurationManager(); + configurationMgr.setLoadConfigFactory(loadConfigFactory); + configurationMgr.setComponentService(componentService); }
@Test - public void testUpdateResourceConfiguration() { - //TODO: Test goes here... + public void straegyShouldBeCalledToLoadConfig() throws Exception { + final Configuration expectedConfig = new Configuration(); + + final ConfigManagement loadConfig = context.mock(ConfigManagement.class); + + context.checking(new Expectations() {{ + atLeast(1).of(loadConfigFactory).getStrategy(resourceId); will(returnValue(loadConfig)); + + atLeast(1).of(loadConfig).execute(resourceId); will(returnValue(expectedConfig)); + }}); + + Configuration actualConfig = configurationMgr.loadResourceConfiguration(resourceId); + + assertNotNull(actualConfig, "Expected a non-null " + Configuration.class.getSimpleName() + " to be returned."); + } + + @Test(expectedExceptions = {PluginContainerException.class}) + public void exceptionShouldBeThrownIfConfigIsNull() throws Exception { + final ConfigManagement loadConfig = context.mock(ConfigManagement.class); + + context.checking(new Expectations() {{ + atLeast(1).of(loadConfigFactory).getStrategy(resourceId); will(returnValue(loadConfig)); + + atLeast(1).of(loadConfig).execute(resourceId); will(returnValue(null)); + + allowing(componentService).getResourceType(resourceId); will(returnValue(new ResourceType())); + }}); + + configurationMgr.loadResourceConfiguration(resourceId); + } + + @Test(expectedExceptions = {PluginContainerException.class}) + public void exceptionShouldBeThrownWhenStrategyThrowsAnException() throws Exception { + final ConfigManagement loadConfig = context.mock(ConfigManagement.class); + + context.checking(new Expectations() {{ + allowing(componentService).getResourceType(resourceId); will(returnValue(resourceType)); + + atLeast(1).of(loadConfigFactory).getStrategy(resourceId); will(returnValue(loadConfig)); + + atLeast(1).of(loadConfig).execute(resourceId); will(throwException(new RuntimeException())); + }}); + + configurationMgr.loadResourceConfiguration(resourceId); }
@Test - public void testExecuteUpdateResourceConfigurationImmediatelySuccess() { - Configuration configuration = new Configuration(); - ConfigurationUpdateRequest request = new ConfigurationUpdateRequest(1, configuration, 1); - try { - ConfigurationUpdateResponse response = manager.executeUpdateResourceConfigurationImmediately(request); - assert response.getStatus().equals(ConfigurationUpdateStatus.SUCCESS); - } catch (PluginContainerException e) { - e.printStackTrace(); - assert false : "PluginContainerException has been caught: " + e; - } + public void mergingStucturedIntoRawShouldUpdateLatestRawConfigs() throws Exception { + final Configuration config = new Configuration(); + config.addRawConfiguration(createRawConfiguration("/tmp/raw0.txt")); + + final RawConfiguration raw1 = createRawConfiguration("/tmp/raw1.txt"); + config.addRawConfiguration(raw1); + + final RawConfiguration raw2 = createRawConfiguration("/tmp/raw2.txt"); + + final Set<RawConfiguration> latestRaws = toSet(raw1, raw2); + + final RawConfiguration mergedRaw1 = createRawConfiguration("/tmp/raw1.txt"); + final RawConfiguration mergedRaw2 = createRawConfiguration("/tmp/raw2.txt"); + + final ResourceConfigurationFacet facet = context.mock(ResourceConfigurationFacet.class); + + context.checking(new Expectations() {{ + allowing(componentService).getResourceType(resourceId); will(returnValue(resourceType)); + + atLeast(1).of(componentService).getComponent(resourceId, + ResourceConfigurationFacet.class, + FacetLockType.READ, + ConfigManagement.FACET_METHOD_TIMEOUT, + daemonThread, + onlyIfStarted); + will(returnValue(facet)); + + atLeast(1).of(facet).loadRawConfigurations(); will(returnValue(latestRaws)); + + oneOf(facet).mergeRawConfiguration(config, raw1); will(returnValue(mergedRaw1)); + oneOf(facet).mergeRawConfiguration(config, raw2); will(returnValue(mergedRaw2)); + }}); + + Configuration mergedConfig = configurationMgr.merge(config, resourceId, FROM_STRUCTURED); + + Configuration expectedConfig = new Configuration(); + expectedConfig.addRawConfiguration(mergedRaw1); + expectedConfig.addRawConfiguration(mergedRaw2); + + assertStructuredMergedIntoRaws(mergedConfig, expectedConfig, "Failed to update existing raw configs"); }
@Test - public void testExecuteUpdateResourceConfigurationImmediatelyFailure() { - Configuration configuration = new Configuration(); - ConfigurationUpdateRequest request = new ConfigurationUpdateRequest(2, configuration, 1); - try { - ConfigurationUpdateResponse response = manager.executeUpdateResourceConfigurationImmediately(request); - assert response.getStatus().equals(ConfigurationUpdateStatus.FAILURE); - } catch (PluginContainerException e) { - e.printStackTrace(); - assert false : "PluginContainerException has been caught: " + e; - } + public void mergingStructuredIntoRawShouldIgnoreNulls() throws Exception { + final Configuration config = new Configuration(); + + final RawConfiguration originalRaw = createRawConfiguration("/tmp/raw.txt"); + config.addRawConfiguration(originalRaw); + + final Set<RawConfiguration> latestRaws = toSet(originalRaw); + + final ResourceConfigurationFacet facet = context.mock(ResourceConfigurationFacet.class); + + context.checking(new Expectations() {{ + allowing(componentService).getResourceType(resourceId); will(returnValue(resourceType)); + + atLeast(1).of(componentService).getComponent(resourceId, + ResourceConfigurationFacet.class, + FacetLockType.READ, + ConfigManagement.FACET_METHOD_TIMEOUT, + daemonThread, + onlyIfStarted); + will(returnValue(facet)); + + atLeast(1).of(facet).loadRawConfigurations(); will(returnValue(latestRaws)); + + oneOf(facet).mergeRawConfiguration(config, originalRaw); will(returnValue(null)); + }}); + + Configuration mergedConfig = configurationMgr.merge(config, resourceId, FROM_STRUCTURED); + + Configuration expectedConfig = new Configuration(); + expectedConfig.addRawConfiguration(originalRaw); + + assertStructuredMergedIntoRaws(mergedConfig, expectedConfig, "cannot merge into a null raw."); }
- //@Test - public void testLoadResourceConfiguration() { - //TODO: Test goes here... + @Test + public void mergingStructuredIntoRawShouldDoNothingIfRawsAreNull() throws Exception { + RawConfiguration raw = createRawConfiguration("/tmp/foo.txt"); + + final Configuration config = new Configuration(); + config.addRawConfiguration(raw); + + final ResourceConfigurationFacet facet = context.mock(ResourceConfigurationFacet.class); + + context.checking(new Expectations() {{ + allowing(componentService).getResourceType(resourceId); will(returnValue(resourceType)); + + atLeast(1).of(componentService).getComponent(resourceId, + ResourceConfigurationFacet.class, + FacetLockType.READ, + ConfigManagement.FACET_METHOD_TIMEOUT, + daemonThread, + onlyIfStarted); + will(returnValue(facet)); + + atLeast(1).of(facet).loadRawConfigurations(); will(returnValue(null)); + }}); + + Configuration mergedConfig = configurationMgr.merge(config, resourceId, FROM_STRUCTURED); + + Configuration expectedConfig = new Configuration(); + expectedConfig.addRawConfiguration(raw); + + assertStructuredMergedIntoRaws( + mergedConfig, + expectedConfig, + "Expected raw configs should not be modified when the facet does not return any raw configs." + ); }
- private class MockConfigurationManager extends ConfigurationManager { - @Override - protected ConfigurationFacet getConfigurationFacet(int resourceId, FacetLockType lockType) { - return new MockConfigurationFacet(); - } + void assertStructuredMergedIntoRaws(Configuration actual, Configuration expected, String msg) { + Set<RawConfiguration> actualRaws = actual.getRawConfigurations(); + Set<RawConfiguration> expectedRaws = expected.getRawConfigurations();
- @Override - protected ResourceType getResourceType(int resourceId) { - return new ResourceType(); + assertEquals( + actualRaws.size(), + expectedRaws.size(), + "Merging structured into raws failed, got back the wrong number of raws. -- " + msg + ); + for (RawConfiguration expectedRaw : expectedRaws) { + assertTrue( + actualRaws.contains(expectedRaw), + "Merging structured into raws failed, failed to find to find raw config [" + expectedRaw + "] -- " + msg + ); } }
- private class MockConfigurationServerService implements ConfigurationServerService { - public void completeConfigurationUpdate(ConfigurationUpdateResponse response) { - if (response.getConfigurationUpdateId() == 1) { - response.setStatus(ConfigurationUpdateStatus.SUCCESS); - } else { - response.setStatus(ConfigurationUpdateStatus.FAILURE); - } - } + @Test + public void mergingRawsIntoStructuredShouldUpdateLatestStructuredConfig() throws Exception { + final Configuration config = new Configuration(); + config.put(new PropertySimple("x", "0")); + config.put(new PropertySimple("z", "3"));
- public void persistUpdatedResourceConfiguration(int resourceId, Configuration resourceConfiguration) { - } + final RawConfiguration raw1 = createRawConfiguration("/tmp/foo.txt"); + config.addRawConfiguration(raw1); + + final RawConfiguration raw2 = createRawConfiguration("/tmp/bar.txt"); + config.addRawConfiguration(raw2); + + final Configuration latestStructured = new Configuration(); + latestStructured.put(new PropertySimple("x", "1")); + latestStructured.put(new PropertySimple("y", "1")); + + final ResourceConfigurationFacet facet = context.mock(ResourceConfigurationFacet.class); + + context.checking(new Expectations() {{ + allowing(componentService).getResourceType(resourceId); will(returnValue(resourceType)); + + atLeast(1).of(componentService).getComponent(resourceId, + ResourceConfigurationFacet.class, + FacetLockType.READ, + ConfigManagement.FACET_METHOD_TIMEOUT, + daemonThread, + onlyIfStarted); + will(returnValue(facet)); + + atLeast(1).of(facet).loadStructuredConfiguration(); will(returnValue(latestStructured));
+ oneOf(facet).mergeStructuredConfiguration(raw1, config); + oneOf(facet).mergeStructuredConfiguration(raw2, config); + }}); + + Configuration mergedConfig = configurationMgr.merge(config, resourceId, FROM_RAW); + + assertEquals( + mergedConfig.getAllProperties(), + latestStructured.getAllProperties(), + "Failed to merged raw into structured." + ); }
- private class MockConfigurationFacet implements ConfigurationFacet { - public Configuration loadResourceConfiguration() { - return null; - } + @Test + public void mergingRawsIntoStructuredShouldIgnoreNull() throws Exception { + Configuration config = new Configuration(); + config.addRawConfiguration(createRawConfiguration("/tmp/foo.txt"));
- public void updateResourceConfiguration(ConfigurationUpdateReport report) { - Configuration config = report.getConfiguration(); - } + final ResourceConfigurationFacet facet = context.mock(ResourceConfigurationFacet.class); + + context.checking(new Expectations() {{ + allowing(componentService).getResourceType(resourceId); will(returnValue(resourceType)); + + atLeast(1).of(componentService).getComponent(resourceId, + ResourceConfigurationFacet.class, + FacetLockType.READ, + ConfigManagement.FACET_METHOD_TIMEOUT, + daemonThread, + onlyIfStarted); + will(returnValue(facet)); + + atLeast(1).of(facet).loadStructuredConfiguration(); will(returnValue(null)); + }}); + + Configuration mergedConfig = configurationMgr.merge(config, resourceId, FROM_RAW); + + assertEquals( + mergedConfig, + config, + "Structured config should not be modified when the facet does not return a structured config." + ); } -} \ No newline at end of file + +} diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigurationManagerUnitTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigurationManagerUnitTest.java deleted file mode 100644 index 01aa641..0000000 --- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigurationManagerUnitTest.java +++ /dev/null @@ -1,320 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2008 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, version 2, as - * published by the Free Software Foundation, and/or the GNU Lesser - * General Public License, version 2.1, also as published by the Free - * Software Foundation. - * - * 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 and the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * and the GNU Lesser 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.core.pc.configuration; - -import static org.testng.Assert.*; - -import org.jmock.Expectations; -import org.rhq.core.clientapi.agent.PluginContainerException; -import org.rhq.core.domain.configuration.Configuration; -import org.rhq.core.domain.configuration.RawConfiguration; -import org.rhq.core.domain.configuration.PropertySimple; -import org.rhq.core.domain.resource.ResourceType; -import org.rhq.core.pc.util.ComponentService; -import org.rhq.core.pc.util.FacetLockType; -import org.rhq.core.pluginapi.configuration.ResourceConfigurationFacet; -import org.testng.annotations.BeforeMethod; -import org.testng.annotations.Test; - -import java.util.Set; - -public class ConfigurationManagerUnitTest extends ConfigManagementTest { - - static final String LEGACY_AMPS_VERSION = "2.0"; - - static final String NON_LEGACY_AMPS_VERSION = "2.1"; - - boolean FROM_STRUCTURED = true; - - boolean FROM_RAW = false; - - LoadResourceConfigurationFactory loadConfigFactory; - - ComponentService componentService; - - ConfigurationManager configurationMgr; - - @BeforeMethod - public void setup() { - loadConfigFactory = context.mock(LoadResourceConfigurationFactory.class); - - componentService = context.mock(ComponentService.class); - - configurationMgr = new ConfigurationManager(); - configurationMgr.setLoadConfigFactory(loadConfigFactory); - configurationMgr.setComponentService(componentService); - } - - @Test - public void straegyShouldBeCalledToLoadConfig() throws Exception { - final Configuration expectedConfig = new Configuration(); - - final LoadResourceConfiguration loadConfig = context.mock(LoadResourceConfiguration.class); - - context.checking(new Expectations() {{ - atLeast(1).of(loadConfigFactory).getStrategy(resourceId); will(returnValue(loadConfig)); - - atLeast(1).of(loadConfig).execute(resourceId); will(returnValue(expectedConfig)); - }}); - - Configuration actualConfig = configurationMgr.loadResourceConfiguration(resourceId); - - assertNotNull(actualConfig, "Expected a non-null " + Configuration.class.getSimpleName() + " to be returned."); - } - - @Test(expectedExceptions = {PluginContainerException.class}) - public void exceptionShouldBeThrownIfConfigIsNull() throws Exception { - final LoadResourceConfiguration loadConfig = context.mock(LoadResourceConfiguration.class); - - context.checking(new Expectations() {{ - atLeast(1).of(loadConfigFactory).getStrategy(resourceId); will(returnValue(loadConfig)); - - atLeast(1).of(loadConfig).execute(resourceId); will(returnValue(null)); - - allowing(componentService).getResourceType(resourceId); will(returnValue(new ResourceType())); - }}); - - configurationMgr.loadResourceConfiguration(resourceId); - } - - @Test(expectedExceptions = {PluginContainerException.class}) - public void exceptionShouldBeThrownWhenStrategyThrowsAnException() throws Exception { - final LoadResourceConfiguration loadConfig = context.mock(LoadResourceConfiguration.class); - - context.checking(new Expectations() {{ - allowing(componentService).getResourceType(resourceId); will(returnValue(resourceType)); - - atLeast(1).of(loadConfigFactory).getStrategy(resourceId); will(returnValue(loadConfig)); - - atLeast(1).of(loadConfig).execute(resourceId); will(throwException(new RuntimeException())); - }}); - - configurationMgr.loadResourceConfiguration(resourceId); - } - - @Test - public void mergingStucturedIntoRawShouldUpdateLatestRawConfigs() throws Exception { - final Configuration config = new Configuration(); - config.addRawConfiguration(createRawConfiguration("/tmp/raw0.txt")); - - final RawConfiguration raw1 = createRawConfiguration("/tmp/raw1.txt"); - config.addRawConfiguration(raw1); - - final RawConfiguration raw2 = createRawConfiguration("/tmp/raw2.txt"); - - final Set<RawConfiguration> latestRaws = toSet(raw1, raw2); - - final RawConfiguration mergedRaw1 = createRawConfiguration("/tmp/raw1.txt"); - final RawConfiguration mergedRaw2 = createRawConfiguration("/tmp/raw2.txt"); - - final ResourceConfigurationFacet facet = context.mock(ResourceConfigurationFacet.class); - - context.checking(new Expectations() {{ - allowing(componentService).getResourceType(resourceId); will(returnValue(resourceType)); - - atLeast(1).of(componentService).getComponent(resourceId, - ResourceConfigurationFacet.class, - FacetLockType.READ, - LoadResourceConfiguration.FACET_METHOD_TIMEOUT, - daemonThread, - onlyIfStarted); - will(returnValue(facet)); - - atLeast(1).of(facet).loadRawConfigurations(); will(returnValue(latestRaws)); - - oneOf(facet).mergeRawConfiguration(config, raw1); will(returnValue(mergedRaw1)); - oneOf(facet).mergeRawConfiguration(config, raw2); will(returnValue(mergedRaw2)); - }}); - - Configuration mergedConfig = configurationMgr.merge(config, resourceId, FROM_STRUCTURED); - - Configuration expectedConfig = new Configuration(); - expectedConfig.addRawConfiguration(mergedRaw1); - expectedConfig.addRawConfiguration(mergedRaw2); - - assertStructuredMergedIntoRaws(mergedConfig, expectedConfig, "Failed to update existing raw configs"); - } - - @Test - public void mergingStructuredIntoRawShouldIgnoreNulls() throws Exception { - final Configuration config = new Configuration(); - - final RawConfiguration originalRaw = createRawConfiguration("/tmp/raw.txt"); - config.addRawConfiguration(originalRaw); - - final Set<RawConfiguration> latestRaws = toSet(originalRaw); - - final ResourceConfigurationFacet facet = context.mock(ResourceConfigurationFacet.class); - - context.checking(new Expectations() {{ - allowing(componentService).getResourceType(resourceId); will(returnValue(resourceType)); - - atLeast(1).of(componentService).getComponent(resourceId, - ResourceConfigurationFacet.class, - FacetLockType.READ, - LoadResourceConfiguration.FACET_METHOD_TIMEOUT, - daemonThread, - onlyIfStarted); - will(returnValue(facet)); - - atLeast(1).of(facet).loadRawConfigurations(); will(returnValue(latestRaws)); - - oneOf(facet).mergeRawConfiguration(config, originalRaw); will(returnValue(null)); - }}); - - Configuration mergedConfig = configurationMgr.merge(config, resourceId, FROM_STRUCTURED); - - Configuration expectedConfig = new Configuration(); - expectedConfig.addRawConfiguration(originalRaw); - - assertStructuredMergedIntoRaws(mergedConfig, expectedConfig, "cannot merge into a null raw."); - } - - @Test - public void mergingStructuredIntoRawShouldDoNothingIfRawsAreNull() throws Exception { - RawConfiguration raw = createRawConfiguration("/tmp/foo.txt"); - - final Configuration config = new Configuration(); - config.addRawConfiguration(raw); - - final ResourceConfigurationFacet facet = context.mock(ResourceConfigurationFacet.class); - - context.checking(new Expectations() {{ - allowing(componentService).getResourceType(resourceId); will(returnValue(resourceType)); - - atLeast(1).of(componentService).getComponent(resourceId, - ResourceConfigurationFacet.class, - FacetLockType.READ, - LoadResourceConfiguration.FACET_METHOD_TIMEOUT, - daemonThread, - onlyIfStarted); - will(returnValue(facet)); - - atLeast(1).of(facet).loadRawConfigurations(); will(returnValue(null)); - }}); - - Configuration mergedConfig = configurationMgr.merge(config, resourceId, FROM_STRUCTURED); - - Configuration expectedConfig = new Configuration(); - expectedConfig.addRawConfiguration(raw); - - assertStructuredMergedIntoRaws( - mergedConfig, - expectedConfig, - "Expected raw configs should not be modified when the facet does not return any raw configs." - ); - } - - void assertStructuredMergedIntoRaws(Configuration actual, Configuration expected, String msg) { - Set<RawConfiguration> actualRaws = actual.getRawConfigurations(); - Set<RawConfiguration> expectedRaws = expected.getRawConfigurations(); - - assertEquals( - actualRaws.size(), - expectedRaws.size(), - "Merging structured into raws failed, got back the wrong number of raws. -- " + msg - ); - for (RawConfiguration expectedRaw : expectedRaws) { - assertTrue( - actualRaws.contains(expectedRaw), - "Merging structured into raws failed, failed to find to find raw config [" + expectedRaw + "] -- " + msg - ); - } - } - - @Test - public void mergingRawsIntoStructuredShouldUpdateLatestStructuredConfig() throws Exception { - final Configuration config = new Configuration(); - config.put(new PropertySimple("x", "0")); - config.put(new PropertySimple("z", "3")); - - final RawConfiguration raw1 = createRawConfiguration("/tmp/foo.txt"); - config.addRawConfiguration(raw1); - - final RawConfiguration raw2 = createRawConfiguration("/tmp/bar.txt"); - config.addRawConfiguration(raw2); - - final Configuration latestStructured = new Configuration(); - latestStructured.put(new PropertySimple("x", "1")); - latestStructured.put(new PropertySimple("y", "1")); - - final ResourceConfigurationFacet facet = context.mock(ResourceConfigurationFacet.class); - - context.checking(new Expectations() {{ - allowing(componentService).getResourceType(resourceId); will(returnValue(resourceType)); - - atLeast(1).of(componentService).getComponent(resourceId, - ResourceConfigurationFacet.class, - FacetLockType.READ, - LoadResourceConfiguration.FACET_METHOD_TIMEOUT, - daemonThread, - onlyIfStarted); - will(returnValue(facet)); - - atLeast(1).of(facet).loadStructuredConfiguration(); will(returnValue(latestStructured)); - - oneOf(facet).mergeStructuredConfiguration(raw1, config); - oneOf(facet).mergeStructuredConfiguration(raw2, config); - }}); - - Configuration mergedConfig = configurationMgr.merge(config, resourceId, FROM_RAW); - - assertEquals( - mergedConfig.getAllProperties(), - latestStructured.getAllProperties(), - "Failed to merged raw into structured." - ); - } - - @Test - public void mergingRawsIntoStructuredShouldIgnoreNull() throws Exception { - Configuration config = new Configuration(); - config.addRawConfiguration(createRawConfiguration("/tmp/foo.txt")); - - final ResourceConfigurationFacet facet = context.mock(ResourceConfigurationFacet.class); - - context.checking(new Expectations() {{ - allowing(componentService).getResourceType(resourceId); will(returnValue(resourceType)); - - atLeast(1).of(componentService).getComponent(resourceId, - ResourceConfigurationFacet.class, - FacetLockType.READ, - LoadResourceConfiguration.FACET_METHOD_TIMEOUT, - daemonThread, - onlyIfStarted); - will(returnValue(facet)); - - atLeast(1).of(facet).loadStructuredConfiguration(); will(returnValue(null)); - }}); - - Configuration mergedConfig = configurationMgr.merge(config, resourceId, FROM_RAW); - - assertEquals( - mergedConfig, - config, - "Structured config should not be modified when the facet does not return a structured config." - ); - } - -} diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadRawTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadRawTest.java deleted file mode 100644 index f466801..0000000 --- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadRawTest.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2008 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, version 2, as - * published by the Free Software Foundation, and/or the GNU Lesser - * General Public License, version 2.1, also as published by the Free - * Software Foundation. - * - * 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 and the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * and the GNU Lesser 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.core.pc.configuration; - -import org.jmock.Expectations; -import org.rhq.core.domain.configuration.Configuration; -import org.rhq.core.domain.configuration.RawConfiguration; -import org.rhq.core.pc.util.ComponentService; -import org.rhq.core.pc.util.FacetLockType; -import org.rhq.core.pluginapi.configuration.ResourceConfigurationFacet; -import static org.testng.Assert.assertNull; -import org.testng.annotations.BeforeMethod; -import org.testng.annotations.Test; - -import static java.util.Collections.EMPTY_SET; -import java.util.Set; - -public class LoadRawTest extends ConfigManagementTest { - - ComponentService componentService; - - ConfigurationUtilityService configUtilityService; - - ResourceConfigurationFacet configFacet; - - LoadRaw loadRaw; - - @BeforeMethod - public void setup() { - componentService = context.mock(ComponentService.class); - configUtilityService = context.mock(ConfigurationUtilityService.class); - - configFacet = context.mock(ResourceConfigurationFacet.class); - - loadRaw = new LoadRaw(); - loadRaw.setComponentService(componentService); - loadRaw.setConfigurationUtilityService(configUtilityService); - } - - @Test - public void rawConfigsShouldGetLoaded() throws Exception { - Set<RawConfiguration> rawConfigs = toSet( - createRawConfiguration("/tmp/foo.txt"), - createRawConfiguration("/tmp/bar.txt") - ); - - addDefaultExpectations(rawConfigs); - - Configuration loadedConfig = loadRaw.execute(resourceId); - - assertRawsLoaded(rawConfigs, loadedConfig); - } - - @Test - public void theConfigNotesShouldGetSet() throws Exception { - final Configuration config = new Configuration(); - config.setNotes(null); - - addDefaultExpectations(EMPTY_SET); - - Configuration loadedConfig = loadRaw.execute(resourceId); - - assertNotesSetToDefault(loadedConfig); - } - - @Test - public void nullShouldBeReturnedWhenRawIsNull() throws Exception { - Set<RawConfiguration> rawConfigs = null; - - addDefaultExpectations(rawConfigs); - - Configuration loadedConfig = loadRaw.execute(resourceId); - - assertNull(loadedConfig, "Expected null to be returned when facet returns null for raw."); - } - - private void addDefaultExpectations(final Set<RawConfiguration> rawConfigs) - throws Exception { - - context.checking(new Expectations() {{ - atLeast(1).of(componentService).getComponent(resourceId, - ResourceConfigurationFacet.class, - FacetLockType.READ, - LoadResourceConfiguration.FACET_METHOD_TIMEOUT, - daemonThread, - onlyIfStarted); - will(returnValue(configFacet)); - - atLeast(1).of(configFacet).loadRawConfigurations(); will(returnValue(rawConfigs)); - - allowing(componentService).getResourceType(resourceId); will(returnValue(resourceType)); - }}); - } - -} diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadResourceConfigurationFactoryImplTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadResourceConfigurationFactoryImplTest.java index ef028d2..f22c4c1 100644 --- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadResourceConfigurationFactoryImplTest.java +++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadResourceConfigurationFactoryImplTest.java @@ -60,11 +60,11 @@ public class LoadResourceConfigurationFactoryImplTest extends JMockTest { allowing(componentService).getAmpsVersion(resourceId); will(returnValue(LEGACY_AMPS_VERSION)); }});
- LoadResourceConfiguration loadConfig = factory.getStrategy(resourceId); + ConfigManagement loadConfig = factory.getStrategy(resourceId);
assertTrue( - loadConfig instanceof LegacyLoadConfig, - "Expected to get an instance of " + LegacyLoadConfig.class.getSimpleName() + " when the " + + loadConfig instanceof LegacyConfigManagement, + "Expected to get an instance of " + LegacyConfigManagement.class.getSimpleName() + " when the " + "resource is from a plugin having an ampsVersion less than " + NON_LEGACY_AMPS_VERSION ); } @@ -75,7 +75,7 @@ public class LoadResourceConfigurationFactoryImplTest extends JMockTest { allowing(componentService).getAmpsVersion(resourceId); will(returnValue(LEGACY_AMPS_VERSION)); }});
- LoadResourceConfiguration loadConfig = factory.getStrategy(resourceId); + ConfigManagement loadConfig = factory.getStrategy(resourceId);
assertComponentServiceInitialized(loadConfig); } @@ -86,7 +86,7 @@ public class LoadResourceConfigurationFactoryImplTest extends JMockTest { allowing(componentService).getAmpsVersion(resourceId); will(returnValue(LEGACY_AMPS_VERSION)); }});
- LoadResourceConfiguration loadConfig = factory.getStrategy(resourceId); + ConfigManagement loadConfig = factory.getStrategy(resourceId);
assertConfigurationUtilityServiceInitialized(loadConfig); } @@ -100,7 +100,7 @@ public class LoadResourceConfigurationFactoryImplTest extends JMockTest { will(returnValue(createResourceTypeThatSupportsStructured())); }});
- LoadResourceConfiguration loadConfig = factory.getStrategy(resourceId); + ConfigManagement loadConfig = factory.getStrategy(resourceId);
assertTrue( loadConfig instanceof LoadStructured, @@ -119,7 +119,7 @@ public class LoadResourceConfigurationFactoryImplTest extends JMockTest { will(returnValue(createResourceTypeThatSupportsStructured())); }});
- LoadResourceConfiguration loadConfig = factory.getStrategy(resourceId); + ConfigManagement loadConfig = factory.getStrategy(resourceId);
assertComponentServiceInitialized(loadConfig); } @@ -133,7 +133,7 @@ public class LoadResourceConfigurationFactoryImplTest extends JMockTest { will(returnValue(createResourceTypeThatSupportsStructured())); }});
- LoadResourceConfiguration loadConfig = factory.getStrategy(resourceId); + ConfigManagement loadConfig = factory.getStrategy(resourceId);
assertConfigurationUtilityServiceInitialized(loadConfig); } @@ -147,11 +147,11 @@ public class LoadResourceConfigurationFactoryImplTest extends JMockTest { will(returnValue(createResourceTypeThatSupportsRaw())); }});
- LoadResourceConfiguration loadConfig = factory.getStrategy(resourceId); + ConfigManagement loadConfig = factory.getStrategy(resourceId);
assertTrue( - loadConfig instanceof LoadRaw, - "Expected to get an instance of " + LoadRaw.class.getSimpleName() + " when " + + loadConfig instanceof RawConfigManagement, + "Expected to get an instance of " + RawConfigManagement.class.getSimpleName() + " when " + "resource is from a plugin having an ampsversion >= " + NON_LEGACY_AMPS_VERSION + " and the resource " + "configuration format is raw." ); @@ -166,7 +166,7 @@ public class LoadResourceConfigurationFactoryImplTest extends JMockTest { will(returnValue(createResourceTypeThatSupportsStructured())); }});
- LoadResourceConfiguration loadConfig = factory.getStrategy(resourceId); + ConfigManagement loadConfig = factory.getStrategy(resourceId);
assertComponentServiceInitialized(loadConfig); } @@ -180,7 +180,7 @@ public class LoadResourceConfigurationFactoryImplTest extends JMockTest { will(returnValue(createResourceTypeThatSupportsStructured())); }});
- LoadResourceConfiguration loadConfig = factory.getStrategy(resourceId); + ConfigManagement loadConfig = factory.getStrategy(resourceId);
assertConfigurationUtilityServiceInitialized(loadConfig); } @@ -194,7 +194,7 @@ public class LoadResourceConfigurationFactoryImplTest extends JMockTest { will(returnValue(createResourceTypeThatSupportsStructuredAndRaw())); }});
- LoadResourceConfiguration loadConfig = factory.getStrategy(resourceId); + ConfigManagement loadConfig = factory.getStrategy(resourceId);
assertTrue( loadConfig instanceof LoadStructuredAndRaw, @@ -213,7 +213,7 @@ public class LoadResourceConfigurationFactoryImplTest extends JMockTest { will(returnValue(createResourceTypeThatSupportsStructured())); }});
- LoadResourceConfiguration loadConfig = factory.getStrategy(resourceId); + ConfigManagement loadConfig = factory.getStrategy(resourceId);
assertComponentServiceInitialized(loadConfig); } @@ -227,17 +227,17 @@ public class LoadResourceConfigurationFactoryImplTest extends JMockTest { will(returnValue(createResourceTypeThatSupportsStructured())); }});
- LoadResourceConfiguration loadConfig = factory.getStrategy(resourceId); + ConfigManagement loadConfig = factory.getStrategy(resourceId);
assertConfigurationUtilityServiceInitialized(loadConfig); }
- void assertComponentServiceInitialized(LoadResourceConfiguration loadConfig) { + void assertComponentServiceInitialized(ConfigManagement loadConfig) { assertNotNull(loadConfig.getComponentService(), "The factory must initialize the componentService " + "property of the loadConfig object."); }
- void assertConfigurationUtilityServiceInitialized(LoadResourceConfiguration loadConfig) { + void assertConfigurationUtilityServiceInitialized(ConfigManagement loadConfig) { assertNotNull(loadConfig.getConfigurationUtilityService(), "The factory must initialize the " + "configurationUtilityService property of the loadConfig object."); } diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadStructuredAndRawTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadStructuredAndRawTest.java index 824c05f..e275f82 100644 --- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadStructuredAndRawTest.java +++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadStructuredAndRawTest.java @@ -145,7 +145,7 @@ public class LoadStructuredAndRawTest extends ConfigManagementTest { atLeast(1).of(componentService).getComponent(resourceId, ResourceConfigurationFacet.class, FacetLockType.READ, - LoadResourceConfiguration.FACET_METHOD_TIMEOUT, + ConfigManagement.FACET_METHOD_TIMEOUT, daemonThread, onlyIfStarted); will(returnValue(configFacet)); @@ -169,7 +169,7 @@ public class LoadStructuredAndRawTest extends ConfigManagementTest { atLeast(1).of(componentService).getComponent(resourceId, ResourceConfigurationFacet.class, FacetLockType.READ, - LoadResourceConfiguration.FACET_METHOD_TIMEOUT, + ConfigManagement.FACET_METHOD_TIMEOUT, daemonThread, onlyIfStarted); will(returnValue(configFacet)); diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadStructuredTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadStructuredTest.java index 59677c9..3941afd 100644 --- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadStructuredTest.java +++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadStructuredTest.java @@ -88,7 +88,7 @@ public class LoadStructuredTest extends ConfigManagementTest { atLeast(1).of(componentService).getComponent(resourceId, ResourceConfigurationFacet.class, FacetLockType.READ, - LoadResourceConfiguration.FACET_METHOD_TIMEOUT, + ConfigManagement.FACET_METHOD_TIMEOUT, daemonThread, onlyIfStarted); will(returnValue(configFacet)); @@ -108,7 +108,7 @@ public class LoadStructuredTest extends ConfigManagementTest { atLeast(1).of(componentService).getComponent(resourceId, ResourceConfigurationFacet.class, FacetLockType.READ, - LoadResourceConfiguration.FACET_METHOD_TIMEOUT, + ConfigManagement.FACET_METHOD_TIMEOUT, daemonThread, onlyIfStarted); will(returnValue(configFacet)); diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/RawConfigManagementTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/RawConfigManagementTest.java new file mode 100644 index 0000000..473ba1c --- /dev/null +++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/RawConfigManagementTest.java @@ -0,0 +1,116 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2008 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, version 2, as + * published by the Free Software Foundation, and/or the GNU Lesser + * General Public License, version 2.1, also as published by the Free + * Software Foundation. + * + * 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 and the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * and the GNU Lesser 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.core.pc.configuration; + +import org.jmock.Expectations; +import org.rhq.core.domain.configuration.Configuration; +import org.rhq.core.domain.configuration.RawConfiguration; +import org.rhq.core.pc.util.ComponentService; +import org.rhq.core.pc.util.FacetLockType; +import org.rhq.core.pluginapi.configuration.ResourceConfigurationFacet; +import static org.testng.Assert.assertNull; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import static java.util.Collections.EMPTY_SET; +import java.util.Set; + +public class RawConfigManagementTest extends ConfigManagementTest { + + ComponentService componentService; + + ConfigurationUtilityService configUtilityService; + + ResourceConfigurationFacet configFacet; + + RawConfigManagement rawConfigMgmt; + + @BeforeMethod + public void setup() { + componentService = context.mock(ComponentService.class); + configUtilityService = context.mock(ConfigurationUtilityService.class); + + configFacet = context.mock(ResourceConfigurationFacet.class); + + rawConfigMgmt = new RawConfigManagement(); + rawConfigMgmt.setComponentService(componentService); + rawConfigMgmt.setConfigurationUtilityService(configUtilityService); + } + + @Test + public void rawConfigsShouldGetLoaded() throws Exception { + Set<RawConfiguration> rawConfigs = toSet( + createRawConfiguration("/tmp/foo.txt"), + createRawConfiguration("/tmp/bar.txt") + ); + + addDefaultExpectations(rawConfigs); + + Configuration loadedConfig = rawConfigMgmt.execute(resourceId); + + assertRawsLoaded(rawConfigs, loadedConfig); + } + + @Test + public void theConfigNotesShouldGetSet() throws Exception { + final Configuration config = new Configuration(); + config.setNotes(null); + + addDefaultExpectations(EMPTY_SET); + + Configuration loadedConfig = rawConfigMgmt.execute(resourceId); + + assertNotesSetToDefault(loadedConfig); + } + + @Test + public void nullShouldBeReturnedWhenRawIsNull() throws Exception { + Set<RawConfiguration> rawConfigs = null; + + addDefaultExpectations(rawConfigs); + + Configuration loadedConfig = rawConfigMgmt.execute(resourceId); + + assertNull(loadedConfig, "Expected null to be returned when facet returns null for raw."); + } + + private void addDefaultExpectations(final Set<RawConfiguration> rawConfigs) + throws Exception { + + context.checking(new Expectations() {{ + atLeast(1).of(componentService).getComponent(resourceId, + ResourceConfigurationFacet.class, + FacetLockType.READ, + ConfigManagement.FACET_METHOD_TIMEOUT, + daemonThread, + onlyIfStarted); + will(returnValue(configFacet)); + + atLeast(1).of(configFacet).loadRawConfigurations(); will(returnValue(rawConfigs)); + + allowing(componentService).getResourceType(resourceId); will(returnValue(resourceType)); + }}); + } + +} diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/UpdateResourceConfigurationRunnerTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/UpdateResourceConfigurationRunnerTest.java index 272d22e..48bf0ae 100644 --- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/UpdateResourceConfigurationRunnerTest.java +++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/UpdateResourceConfigurationRunnerTest.java @@ -23,33 +23,66 @@
package org.rhq.core.pc.configuration;
-import static org.rhq.core.domain.configuration.ConfigurationUpdateStatus.*; -import static org.rhq.test.AssertUtils.*; -import org.rhq.test.jmock.PropertyMatcher; - -import org.testng.annotations.Test; +import org.hamcrest.Description; +import org.hamcrest.Matcher; +import org.jmock.Expectations; +import org.jmock.api.Action; +import org.jmock.api.Invocation; +import org.rhq.core.clientapi.agent.configuration.ConfigurationUpdateRequest; import org.rhq.core.clientapi.server.configuration.ConfigurationServerService; import org.rhq.core.clientapi.server.configuration.ConfigurationUpdateResponse; -import org.rhq.core.clientapi.agent.configuration.ConfigurationUpdateRequest; import org.rhq.core.domain.configuration.Configuration; import org.rhq.core.domain.configuration.ConfigurationUpdateStatus; +import static org.rhq.core.domain.configuration.ConfigurationUpdateStatus.FAILURE; +import static org.rhq.core.domain.configuration.ConfigurationUpdateStatus.INPROGRESS; +import static org.rhq.core.domain.configuration.ConfigurationUpdateStatus.SUCCESS; +import org.rhq.core.pc.util.ComponentService; +import static org.rhq.core.pc.configuration.ConfigManagement.FACET_METHOD_TIMEOUT; +import static org.rhq.core.pc.util.FacetLockType.WRITE; import org.rhq.core.pluginapi.configuration.ConfigurationFacet; import org.rhq.core.pluginapi.configuration.ConfigurationUpdateReport; -import org.jmock.Expectations; -import org.jmock.api.Action; -import org.jmock.api.Invocation; -import org.hamcrest.Description; -import org.hamcrest.Matcher; +import static org.rhq.test.AssertUtils.assertPropertiesMatch; +import org.rhq.test.jmock.PropertyMatcher; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test;
public class UpdateResourceConfigurationRunnerTest extends ConfigManagementTest {
+ ComponentService componentService; + + ConfigManagement configMgmt; + + ConfigurationFacet facet; + + @BeforeMethod + public void setup() throws Exception { + componentService = context.mock(ComponentService.class); + facet = context.mock(ConfigurationFacet.class); + + configMgmt = new LegacyConfigManagement(); + configMgmt.setComponentService(componentService); + + setDefaultExpectations(); + } + + void setDefaultExpectations() throws Exception { + final boolean daemonThread = false; + final boolean onlyIfStarted = true; + + context.checking(new Expectations() {{ + allowing(componentService).getComponent(resourceId, ConfigurationFacet.class, WRITE, FACET_METHOD_TIMEOUT, + daemonThread, onlyIfStarted); + will(returnValue(facet)); + }}); + } + @Test public void successfulUpdateShouldSendSuccessResponseToServer() throws Exception { final Configuration config = createStructuredConfig();
final ConfigurationServerService configServerService = context.mock(ConfigurationServerService.class);
- final ConfigurationFacet facet = context.mock(ConfigurationFacet.class); + //final ConfigurationFacet facet = context.mock(ConfigurationFacet.class);
final ConfigurationUtilityService configUtilService = context.mock(ConfigurationUtilityService.class);
@@ -58,7 +91,7 @@ public class UpdateResourceConfigurationRunnerTest extends ConfigManagementTest ConfigurationUpdateRequest updateRequest = new ConfigurationUpdateRequest(configUpdateId, config, resourceId);
UpdateResourceConfigurationRunner updateRunner = new UpdateResourceConfigurationRunner(configServerService, - resourceType, facet, updateRequest); + resourceType, configMgmt, updateRequest); updateRunner.setConfigUtilService(configUtilService);
final ConfigurationUpdateResponse successResponse = new ConfigurationUpdateResponse(configUpdateId, null, @@ -81,7 +114,7 @@ public class UpdateResourceConfigurationRunnerTest extends ConfigManagementTest public void successfulUpdateShouldReturnSuccessResponseInEmbeddedMode() throws Exception { final Configuration config = createStructuredConfig();
- final ConfigurationFacet facet = context.mock(ConfigurationFacet.class); + //final ConfigurationFacet facet = context.mock(ConfigurationFacet.class);
final ConfigurationUtilityService configUtilService = context.mock(ConfigurationUtilityService.class);
@@ -90,7 +123,7 @@ public class UpdateResourceConfigurationRunnerTest extends ConfigManagementTest ConfigurationUpdateRequest updateRequest = new ConfigurationUpdateRequest(configUpdateId, config, resourceId);
UpdateResourceConfigurationRunner updateRunner = new UpdateResourceConfigurationRunner(null, resourceType, - facet, updateRequest); + configMgmt, updateRequest); updateRunner.setConfigUtilService(configUtilService);
final ConfigurationUpdateResponse successResponse = new ConfigurationUpdateResponse(configUpdateId, null, @@ -116,7 +149,7 @@ public class UpdateResourceConfigurationRunnerTest extends ConfigManagementTest
final ConfigurationServerService configServerService = context.mock(ConfigurationServerService.class);
- final ConfigurationFacet facet = context.mock(ConfigurationFacet.class); + //final ConfigurationFacet facet = context.mock(ConfigurationFacet.class);
final ConfigurationUtilityService configUtilService = context.mock(ConfigurationUtilityService.class);
@@ -125,7 +158,7 @@ public class UpdateResourceConfigurationRunnerTest extends ConfigManagementTest ConfigurationUpdateRequest updateRequest = new ConfigurationUpdateRequest(configUpdateId, config, resourceId);
UpdateResourceConfigurationRunner updateRunner = new UpdateResourceConfigurationRunner(configServerService, - resourceType, facet, updateRequest); + resourceType, configMgmt, updateRequest); updateRunner.setConfigUtilService(configUtilService);
String errorMsg = "Configuration facet did not indicate success or failure - assuming failure."; @@ -150,7 +183,7 @@ public class UpdateResourceConfigurationRunnerTest extends ConfigManagementTest public void failedUpdateShouldReturnFailureResponseInEmbeddedMode() throws Exception { final Configuration config = createStructuredConfig();
- final ConfigurationFacet facet = context.mock(ConfigurationFacet.class); + //final ConfigurationFacet facet = context.mock(ConfigurationFacet.class);
final ConfigurationUtilityService configUtilService = context.mock(ConfigurationUtilityService.class);
@@ -159,7 +192,7 @@ public class UpdateResourceConfigurationRunnerTest extends ConfigManagementTest ConfigurationUpdateRequest updateRequest = new ConfigurationUpdateRequest(configUpdateId, config, resourceId);
UpdateResourceConfigurationRunner updateRunner = new UpdateResourceConfigurationRunner(null, resourceType, - facet, updateRequest); + configMgmt, updateRequest); updateRunner.setConfigUtilService(configUtilService);
String errorMsg = "Configuration facet did not indicate success or failure - assuming failure."; @@ -186,14 +219,14 @@ public class UpdateResourceConfigurationRunnerTest extends ConfigManagementTest
final ConfigurationServerService configServerService = context.mock(ConfigurationServerService.class);
- final ConfigurationFacet facet = context.mock(ConfigurationFacet.class); + //final ConfigurationFacet facet = context.mock(ConfigurationFacet.class);
int configUpdateId = -1;
ConfigurationUpdateRequest updateRequest = new ConfigurationUpdateRequest(configUpdateId, config, resourceId);
UpdateResourceConfigurationRunner updateRunner = new UpdateResourceConfigurationRunner(configServerService, - resourceType, facet, updateRequest); + resourceType, configMgmt, updateRequest);
final NullPointerException exception = new NullPointerException("Unexpected error during update");
@@ -214,14 +247,12 @@ public class UpdateResourceConfigurationRunnerTest extends ConfigManagementTest public void failureResponseShouldBeReturnedWhenFacetThrowsAnExceptionInEmbeddedMode() throws Exception { final Configuration config = createStructuredConfig();
- final ConfigurationFacet facet = context.mock(ConfigurationFacet.class); - int configUpdateId = -1;
ConfigurationUpdateRequest updateRequest = new ConfigurationUpdateRequest(configUpdateId, config, resourceId);
UpdateResourceConfigurationRunner updateRunner = new UpdateResourceConfigurationRunner(null, resourceType, - facet, updateRequest); + configMgmt, updateRequest);
final NullPointerException exception = new NullPointerException("Unexpected error during update");
diff --git a/modules/test-utils/src/main/java/org/rhq/test/AssertUtils.java b/modules/test-utils/src/main/java/org/rhq/test/AssertUtils.java index 03581eb..b9bf46d 100644 --- a/modules/test-utils/src/main/java/org/rhq/test/AssertUtils.java +++ b/modules/test-utils/src/main/java/org/rhq/test/AssertUtils.java @@ -25,6 +25,8 @@ package org.rhq.test;
import static org.testng.Assert.*;
+import java.util.Collection; + public class AssertUtils {
/** @@ -47,4 +49,23 @@ public class AssertUtils { assertTrue(result.isMatch(), msg + " -- " + result.getDetails()); }
+ /** + * Verifies that two collections are equal, according to the definition of <code>equals()</code> of the contained + * elements. Order is ignored as well as the runtime type of the collections. + * + * @param expected The expected collection to compare against + * @param actual The actual collection to compare against + * @param msg An error message + * @param <T> The type of the elements in the collections + */ + public static <T> void assertCollectionEqualsNoOrder(Collection<T> expected, Collection<T> actual, String msg) { + CollectionEqualsChecker<T> checker = new CollectionEqualsChecker<T>(); + checker.setExpected(expected); + checker.setActual(actual); + + EqualsResult result = checker.execute(); + + assertTrue(result.isEqual(), msg + " -- " + result.getDetails()); + } + } diff --git a/modules/test-utils/src/main/java/org/rhq/test/CollectionEqualsChecker.java b/modules/test-utils/src/main/java/org/rhq/test/CollectionEqualsChecker.java new file mode 100644 index 0000000..20539da --- /dev/null +++ b/modules/test-utils/src/main/java/org/rhq/test/CollectionEqualsChecker.java @@ -0,0 +1,91 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2008 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, version 2, as + * published by the Free Software Foundation, and/or the GNU Lesser + * General Public License, version 2.1, also as published by the Free + * Software Foundation. + * + * 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 and the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * and the GNU Lesser 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.test; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +public class CollectionEqualsChecker<T> { + + private Collection<T> expected; + + private Collection<T> actual; + + public void setExpected(Collection<T> expected) { + this.expected = expected; + } + + public void setActual(Collection<T> actual) { + this.actual = actual; + } + + public EqualsResult execute() { + boolean isMatch = true; + StringBuilder details = new StringBuilder(); + + if (expected.size() != actual.size()) { + isMatch = false; + details.append("Expected " + expected.size() + " elements but found " + actual.size() + " elements\n"); + } + + List<T> elementsThatShouldBePresent = findMissingElements(expected, actual); + if (!elementsThatShouldBePresent.isEmpty()) { + isMatch = false; + details.append("Expected to find the following elements:\n\t" + + toString(elementsThatShouldBePresent) + "\n\n"); + } + + List<T> elementsThatShouldNotBePresent = findMissingElements(actual, expected); + if (!elementsThatShouldNotBePresent.isEmpty()) { + isMatch = false; + details.append("Did not expect to find the following elements:\n\t" + + toString(elementsThatShouldNotBePresent) + "\n\n"); + } + + return new EqualsResult(isMatch, details.toString()); + } + + private List<T> findMissingElements(Collection<T> elementsToSearchFor, Collection<T> elementsToSearch) { + List<T> missingElements = new ArrayList<T>(); + for (T element : elementsToSearchFor) { + if (!elementsToSearch.contains(element)) { + missingElements.add(element); + } + } + return missingElements; + } + + private String toString(List<T> list) { + StringBuilder buffer = new StringBuilder("["); + for (T element : list) { + buffer.append(element.toString() + ", "); + } + buffer.delete(buffer.length() - 2, buffer.length()); + buffer.append("]"); + + return buffer.toString(); + } + +} diff --git a/modules/test-utils/src/main/java/org/rhq/test/EqualsResult.java b/modules/test-utils/src/main/java/org/rhq/test/EqualsResult.java new file mode 100644 index 0000000..a485efc --- /dev/null +++ b/modules/test-utils/src/main/java/org/rhq/test/EqualsResult.java @@ -0,0 +1,44 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2008 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, version 2, as + * published by the Free Software Foundation, and/or the GNU Lesser + * General Public License, version 2.1, also as published by the Free + * Software Foundation. + * + * 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 and the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * and the GNU Lesser 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.test; + +public class EqualsResult { + + private boolean isEqual; + + private String details; + + public EqualsResult(boolean equals, String details) { + isEqual = equals; + this.details = details; + } + + public boolean isEqual() { + return isEqual; + } + + public String getDetails() { + return details; + } +}
commit 3755cc5f1d58c2bf3b26102c2bd8d642f82f74c0 Author: Jay Shaughnessy jshaughn@redhat.com Date: Tue Nov 24 09:29:05 2009 -0500
files removed
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/perspective/ExtensionPoint.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/perspective/ExtensionPoint.java new file mode 100644 index 0000000..8f7bc47 --- /dev/null +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/perspective/ExtensionPoint.java @@ -0,0 +1,12 @@ +package org.rhq.enterprise.server.perspective; + + +/** + * Immutable class representing a single perspective extension point. + * + * @author jshaughnessy + * + */ +public enum ExtensionPoint { + coreMenu, taskPane; +} diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/perspective/MenuItem.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/perspective/MenuItem.java new file mode 100644 index 0000000..8284b5e --- /dev/null +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/perspective/MenuItem.java @@ -0,0 +1,37 @@ +package org.rhq.enterprise.server.perspective; + +import java.util.List; + +import org.rhq.enterprise.server.xmlschema.generated.serverplugin.perspective.MenuItemType; + +public class MenuItem { + + private MenuItemType item; + private List<MenuItem> children; + + public MenuItem(MenuItemType item) { + super(); + this.item = item; + } + + /** + * @return the children + */ + public List<MenuItem> getChildren() { + return children; + } + + /** + * @param children the children to set + */ + public void setChildren(List<MenuItem> children) { + this.children = children; + } + + /** + * @return the item + */ + public MenuItemType getItem() { + return item; + } +}
commit 960c732c54ab56a00674dbd7bc612ab186c659db Author: Jay Shaughnessy jshaughn@redhat.com Date: Tue Nov 24 09:27:02 2009 -0500
Descriptor processing to make definitions available to the server/gui code.
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/perspective/PerspectiveServerPluginManager.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/perspective/PerspectiveServerPluginManager.java index ed9408a..ee0fef1 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/perspective/PerspectiveServerPluginManager.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/perspective/PerspectiveServerPluginManager.java @@ -34,6 +34,8 @@ import javax.naming.InitialContext; import org.rhq.core.util.file.FileUtil; import org.rhq.enterprise.server.plugin.pc.ServerPluginEnvironment; import org.rhq.enterprise.server.plugin.pc.ServerPluginManager; +import org.rhq.enterprise.server.plugin.pc.perspective.metadata.PerspectivePluginMetadataManager; +import org.rhq.enterprise.server.xmlschema.generated.serverplugin.perspective.PerspectivePluginDescriptorType;
/** * This loads in all perspective server plugins that can be found. You can obtain a loaded plugin's @@ -44,10 +46,34 @@ import org.rhq.enterprise.server.plugin.pc.ServerPluginManager; */ public class PerspectiveServerPluginManager extends ServerPluginManager {
+ private PerspectivePluginMetadataManager metadataManager; + public PerspectiveServerPluginManager(PerspectiveServerPluginContainer pc) { super(pc); }
+ @Override + public void initialize() throws Exception { + super.initialize(); + this.metadataManager = new PerspectivePluginMetadataManager(); + } + + @Override + public void shutdown() { + super.shutdown(); + this.metadataManager = null; + } + + /** + * An object that can be used to process and store all metadata from all perspective plugins. This object will contain all the + * metadata found in all loaded perspective plugins. + * + * @return object to retrieve plugin metadata from + */ + public PerspectivePluginMetadataManager getMetadataManager() { + return this.metadataManager; + } + /* At load-time ensure that any WAR files packaged with the server plugin are deployed to the RHQ * Server. Note, perspective apps are logically deployed along-side, not inside the rhq.ear (although physically * under the default/work). They should have access to the same shared components. @@ -58,6 +84,9 @@ public class PerspectiveServerPluginManager extends ServerPluginManager { public synchronized void loadPlugin(ServerPluginEnvironment env) throws Exception { super.loadPlugin(env);
+ // merge this perspective into any previously loaded perspective definitions + this.metadataManager.loadPlugin((PerspectivePluginDescriptorType) env.getPluginDescriptor()); + String name = null; try { JarFile plugin = new JarFile(env.getPluginUrl().getFile()); @@ -118,6 +147,27 @@ public class PerspectiveServerPluginManager extends ServerPluginManager { return destFile; }
+ /** + * All of the plugins have been loaded, so now let the metadata manager sort through the definitions. + * + * @see org.rhq.enterprise.server.plugin.pc.ServerPluginManager#startPlugins() + */ + @Override + public synchronized void startPlugins() { + super.startPlugins(); + + this.metadataManager.start(); + } + + /* (non-Javadoc) + * @see org.rhq.enterprise.server.plugin.pc.ServerPluginManager#stopPlugins() + */ + @Override + public synchronized void stopPlugins() { + // TODO Auto-generated method stub + super.stopPlugins(); + } + /* At unload-time ensure that any WAR files packaged with the server plugin are un-deployed on * the RHQ Server. * @@ -139,6 +189,8 @@ public class PerspectiveServerPluginManager extends ServerPluginManager { getLog().error("Failed to deploy " + env.getPluginName() + "#" + name, e); }
+ this.metadataManager.unloadPlugin((PerspectivePluginDescriptorType) env.getPluginDescriptor()); + super.unloadPlugin(env); }
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/perspective/metadata/PerspectivePluginMetadataManager.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/perspective/metadata/PerspectivePluginMetadataManager.java new file mode 100644 index 0000000..9e86e6d --- /dev/null +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/perspective/metadata/PerspectivePluginMetadataManager.java @@ -0,0 +1,189 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2009 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.plugin.pc.perspective.metadata; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.rhq.enterprise.server.perspective.ExtensionPoint; +import org.rhq.enterprise.server.perspective.MenuItem; +import org.rhq.enterprise.server.xmlschema.generated.serverplugin.perspective.MenuItemType; +import org.rhq.enterprise.server.xmlschema.generated.serverplugin.perspective.PerspectivePluginDescriptorType; +import org.rhq.enterprise.server.xmlschema.generated.serverplugin.perspective.PlacementType; +import org.rhq.enterprise.server.xmlschema.generated.serverplugin.perspective.PositionType; +import org.rhq.enterprise.server.xmlschema.generated.serverplugin.perspective.TaskType; + +/** + * This loads in all deployed perspective server plugins and maintains the complete set of + * {@link #getMetadataManager() metadata} found in all plugin descriptors. Individual plugin + * metadata is irrelevant and not retrievable. The union of the perpective definitions is + * maintained and made available. Conflict resolution rules are applied as needed for + * clashing perspective definitions. + * + * Activators are not processed here, they use session-time information. This is performed at + * plugin-load-time. + * + * @author Jay Shaughnessy + */ + +public class PerspectivePluginMetadataManager { + private final String CORE_PERSPECTIVE_NAME = "CorePerspective"; + + private Log log = LogFactory.getLog(PerspectivePluginMetadataManager.class); + + //private static PerspectivePluginMetadataManager manager = new PerspectivePluginMetadataManager(); + + private Map<String, PerspectivePluginDescriptorType> loadedPlugins = new HashMap<String, PerspectivePluginDescriptorType>(); + + private boolean isStarted = false; + private List<TaskType> globalTasks = null; + private List<TaskType> resourceTasks = null; + private List<MenuItem> coreMenu = null; + + public PerspectivePluginMetadataManager() { + } + + /** + * Transforms the pluginDescriptor into domain object form and stores those objects. + * + * @param descriptor the descriptor to transform + * + * @return void + */ + public synchronized void loadPlugin(PerspectivePluginDescriptorType descriptor) { + loadedPlugins.put(descriptor.getName(), descriptor); + } + + public synchronized void unloadPlugin(PerspectivePluginDescriptorType descriptor) { + loadedPlugins.remove(descriptor.getName()); + } + + public synchronized void start() { + if (isStarted) + return; + + // always process the core perspective first as other perspectives may reference its definitions + processCorePerspective(); + + isStarted = true; + } + + private void processCorePerspective() { + PerspectivePluginDescriptorType cp = loadedPlugins.get(CORE_PERSPECTIVE_NAME); + + if (null == cp) { + throw new IllegalStateException("Core perspective must be loaded. Invalid startup. Load: " + + CORE_PERSPECTIVE_NAME); + } + + globalTasks = cp.getGlobalTask(); + resourceTasks = cp.getResourceTask(); + + // Setup core menus + if (null == this.coreMenu) { + this.coreMenu = new ArrayList<MenuItem>(); + } + for (MenuItemType menuItemDef : cp.getMenuItem()) { + PositionType position = menuItemDef.getPosition(); + if (ExtensionPoint.coreMenu == ExtensionPoint.valueOf(position.getExtensionPoint())) { + addToMenu(this.coreMenu, menuItemDef); + } else { + throw new IllegalArgumentException("Unknown Extension Point defined in menuItem [" + + menuItemDef.getName() + "] : " + position.getExtensionPoint()); + } + } + + // TODO: remove this debug code + //printMenu(this.coreMenu, ""); + } + + // TODO: remove this debug code + @SuppressWarnings("unused") + private void printMenu(List<MenuItem> menu, String indent) { + if (null == menu) + return; + + for (MenuItem menuItem : menu) { + System.out.println(indent + menuItem.getItem().getName()); + printMenu(menuItem.getChildren(), indent + " "); + } + } + + private void addToMenu(List<MenuItem> menu, MenuItemType menuItemDef) { + + PositionType position = menuItemDef.getPosition(); + List<MenuItem> containingMenu = getContainingMenu(menu, menuItemDef); + MenuItem menuItem = new MenuItem(menuItemDef); + + if (PlacementType.START == position.getPlacement()) { + containingMenu.add(0, menuItem); + } else if (PlacementType.END == position.getPlacement()) { + containingMenu.add(menuItem); + } else { + int index = getMenuItemIndex(containingMenu, position.getName()); + if (-1 == index) { + throw new IllegalArgumentException("Invalid position defined for menuItem [" + menuItemDef.getName() + + "]. Referenced menuItem not found : " + position.getName() + + ". Make sure supporting menus are defined for the menuItem."); + } + + containingMenu.add((PlacementType.AFTER == position.getPlacement() ? ++index : --index), menuItem); + } + } + + private List<MenuItem> getContainingMenu(List<MenuItem> menu, MenuItemType menuItemDef) { + String name = menuItemDef.getName(); + String[] nameTokens = (null != name) ? name.split("\.") : new String[0]; + List<MenuItem> result = menu; + + for (int i = 0; (i + 1 < nameTokens.length); ++i) { + int index = this.getMenuItemIndex(result, nameTokens[i]); + if (-1 == index) { + throw new IllegalArgumentException("Invalid position defined for menuItem [" + menuItemDef.getName() + + "]. No containing menu found for : " + name + + ". Make sure supporting menus are defined for the menuItem."); + } + MenuItem menuItem = result.get(index); + result = menuItem.getChildren(); + if (null == result) { + result = new ArrayList<MenuItem>(); + menuItem.setChildren(result); + } + } + + return result; + } + + private int getMenuItemIndex(List<MenuItem> menu, String name) { + int result = -1; + + for (int i = 0, size = menu.size(); (i < size); ++i) { + if (menu.get(i).getItem().getName().endsWith(name)) { + result = i; + break; + } + } + return result; + } +} diff --git a/modules/enterprise/server/plugins/perspectives/core/perspective/src/main/resources/META-INF/rhq-serverplugin.xml b/modules/enterprise/server/plugins/perspectives/core/perspective/src/main/resources/META-INF/rhq-serverplugin.xml index 63e1746..fb640ee 100644 --- a/modules/enterprise/server/plugins/perspectives/core/perspective/src/main/resources/META-INF/rhq-serverplugin.xml +++ b/modules/enterprise/server/plugins/perspectives/core/perspective/src/main/resources/META-INF/rhq-serverplugin.xml @@ -119,7 +119,7 @@ url="/ResourceHub.do?resourceCategory=SERVICE"> <position extensionPoint="coreMenu" - name="resources.platforms" + name="resources.servers" placement="after" /> </menuItem> <menuItem diff --git a/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-perspective.xsd b/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-perspective.xsd index 0ddd9b5..4c48957 100644 --- a/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-perspective.xsd +++ b/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-perspective.xsd @@ -111,15 +111,39 @@ name="TaskType"> xs:sequence <xs:element - name="NewElement" - type="xs:string"> + ref="perspective:extensionPoint" + minOccurs="0" + maxOccurs="unbounded"> + xs:annotation + xs:documentation + Limit task to the designated task pane extension points. Otherwise, all. + </xs:documentation> + </xs:annotation> </xs:element> + <xs:element - ref="perspective:extensionPoint" - minOccurs="1" + ref="perspective:resourceActivator" + minOccurs="0" maxOccurs="unbounded"> xs:annotation - xs:documentationA task pane extension point for which this task is presented.</xs:documentation> + xs:documentation + Activate task only if the user has resources of the specified type in inventory. + Activated + only if the user has the required permissions. At least one resource + activator required for + resource tasks. Activated for resources only if specified trait + conditions are also met. + </xs:documentation> + </xs:annotation> + </xs:element> + <xs:element + ref="perspective:permissionActivator" + minOccurs="0" + maxOccurs="unbounded"> + xs:annotation + xs:documentation + Activate task only if the user has the required global permissions. + </xs:documentation> </xs:annotation> </xs:element> <xs:element @@ -198,7 +222,8 @@ </xs:element>
<xs:element - name="menuItem"> + name="menuItem" + type="perspective:MenuItemType"> xs:annotation xs:documentation Add or Remove a menu item in an existing menu extension point. Additions can specify @@ -210,100 +235,103 @@ name="PerspectiveMenuItemElement" /> </xs:appinfo> </xs:annotation> - xs:complexType - xs:sequence - <xs:element - ref="perspective:position" - minOccurs="0" - maxOccurs="1"> - xs:annotation - xs:documentation - Required for root menuItem additions. Position of children is implicit given the - XML - structure. - </xs:documentation> - </xs:annotation> - </xs:element> - </xs:sequence> - <xs:attribute - name="action" - type="perspective:ActionType" - use="optional" - default="add"> + </xs:element> + + <xs:complexType + name="MenuItemType"> + xs:sequence + <xs:element + ref="perspective:position" + minOccurs="0" + maxOccurs="1"> xs:annotation xs:documentation - Add or remove the menu entry. For removal all but the name attribute are ignored. - Default is add. - </xs:documentation> + Required for root menuItem additions. Position of children is implicit given the + XML + structure. + </xs:documentation> </xs:annotation> - </xs:attribute> - <xs:attribute - name="name" - type="perspective:NameType" - use="required"> - xs:annotation - xs:documentation - ExtensionPoint name used for reference by other defined extension points. - Unique within - perspective. + </xs:element> + </xs:sequence> + <xs:attribute + name="action" + type="perspective:ActionType" + use="optional" + default="add"> + xs:annotation + xs:documentation + Add or remove the menu entry. For removal all but the name attribute are ignored. + Default + is add. </xs:documentation> - </xs:annotation> - </xs:attribute> - <xs:attribute - name="displayName" - type="perspective:DisplayNameType" - use="optional"> - xs:annotation - xs:documentation - The displayed menu item name. Required for add actions. If empty an icon must be - defined. + </xs:annotation> + </xs:attribute> + <xs:attribute + name="name" + type="perspective:NameType" + use="required"> + xs:annotation + xs:documentation + ExtensionPoint name used for reference by other defined extension points. + Unique within + perspective. </xs:documentation> - </xs:annotation> - </xs:attribute> - <xs:attribute - name="feature" - type="perspective:MenuItemFeatureType" - use="optional"> - xs:annotation - xs:documentation - Certain menu items utilize special built-in rendering features. + </xs:annotation> + </xs:attribute> + <xs:attribute + name="displayName" + type="perspective:DisplayNameType" + use="optional"> + xs:annotation + xs:documentation + The displayed menu item name. Required for add actions. If empty an icon must be + defined. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute + name="feature" + type="perspective:MenuItemFeatureType" + use="optional"> + xs:annotation + xs:documentation + Certain menu items utilize special built-in rendering features. </xs:documentation> - </xs:annotation> - </xs:attribute> - <xs:attribute - name="url" - type="xs:anyURI" - use="optional"> - xs:annotation - xs:documentation - The request URL for the menu entry. If not provided the entry is just a placeholder for - MenuItems. + </xs:annotation> + </xs:attribute> + <xs:attribute + name="url" + type="xs:anyURI" + use="optional"> + xs:annotation + xs:documentation + The request URL for the menu entry. If not provided the entry is just a placeholder for + MenuItems. </xs:documentation> - </xs:annotation> - </xs:attribute> - <xs:attribute - name="iconUrl" - type="xs:anyURI" - use="optional"> - xs:annotation - xs:documentation - The request URL for the icon image for this menu item. If not provided then no image is - used. + </xs:annotation> + </xs:attribute> + <xs:attribute + name="iconUrl" + type="xs:anyURI" + use="optional"> + xs:annotation + xs:documentation + The request URL for the icon image for this menu item. If not provided then no image is + used. </xs:documentation> - </xs:annotation> - </xs:attribute> - <xs:attribute - name="iconWidth" - type="xs:int" - use="optional"> - </xs:attribute> - <xs:attribute - name="iconHeight" - type="xs:int" - use="optional"> - </xs:attribute> - </xs:complexType> - </xs:element> + </xs:annotation> + </xs:attribute> + <xs:attribute + name="iconWidth" + type="xs:int" + use="optional"> + </xs:attribute> + <xs:attribute + name="iconHeight" + type="xs:int" + use="optional"> + </xs:attribute> + </xs:complexType>
<xs:element name="resourceTab"> @@ -436,6 +464,7 @@ Activators must be satisfied for the extension point to be active. </xs:documentation> </xs:annotation> + xs:complexType xs:sequence <xs:element
commit eb6a0254d10500c154e64beca5bba9aafa7b5c8a Merge: ad07de6... 91cf9cc... Author: Adam Young ayoung@redhat.com Date: Tue Nov 24 08:46:37 2009 -0500
Merge branch 'raw-config' of ssh://git.fedorahosted.org/git/rhq/rhq into raw-config
commit 91cf9cc20ab0058bb6fabe6dc60e0f729e5beb01 Author: John Sanda john@localhost.localdomain Date: Mon Nov 23 13:47:21 2009 -0500
[US 6] Adding Javadocs
diff --git a/modules/test-utils/src/main/java/org/rhq/test/AssertUtils.java b/modules/test-utils/src/main/java/org/rhq/test/AssertUtils.java index bde72ba..03581eb 100644 --- a/modules/test-utils/src/main/java/org/rhq/test/AssertUtils.java +++ b/modules/test-utils/src/main/java/org/rhq/test/AssertUtils.java @@ -27,6 +27,16 @@ import static org.testng.Assert.*;
public class AssertUtils {
+ /** + * Verifies that all public, accessible properties of the two objects are equal. This method might be used when you + * want to compare two objects without using their <code>equals()</code> methods or when do not implement <code> + * equals()</code>. + * + * @param expected The expected object to compare against + * @param actual The actual object to be compared + * @param msg An error message + * @param <T> The type of the objects to be compared + */ public static <T> void assertPropertiesMatch(T expected, T actual, String msg) { PropertyMatcher<T> matcher = new PropertyMatcher<T>(); matcher.setExpected(expected); diff --git a/modules/test-utils/src/main/java/org/rhq/test/jmock/PropertyMatcher.java b/modules/test-utils/src/main/java/org/rhq/test/jmock/PropertyMatcher.java index 3be7e2d..4a46adc 100644 --- a/modules/test-utils/src/main/java/org/rhq/test/jmock/PropertyMatcher.java +++ b/modules/test-utils/src/main/java/org/rhq/test/jmock/PropertyMatcher.java @@ -27,6 +27,11 @@ import org.hamcrest.TypeSafeMatcher; import org.hamcrest.Description; import org.rhq.test.MatchResult;
+/** + * A JMock custom matcher that matches based on the public, accessible properties of an object. + * + * @param <T> The type of the object to match. + */ public class PropertyMatcher<T> extends TypeSafeMatcher<T> {
private T expected;
commit a89ac8b47d650b67df4a1446018f107ddaa1b3b9 Author: John Sanda john@localhost.localdomain Date: Mon Nov 23 13:28:30 2009 -0500
[US 6] Refactoring common test classes into test-utils module.
Moving JMockTest into test-utils so that it can be resued across different modules.
Initial commit for AssertUtils which for now contains only a single method, assertPropertyMatches(). This method compare all accessible properties of two objects. Internally, that method is implemented by org.rhq.test.PropertyMathcher.
Initial commit for org.rhq.test.jmock.PropertyMatcher. This is a custom JMock matcher that performs matching based on the accessible properties of an object.
diff --git a/modules/core/plugin-container/pom.xml b/modules/core/plugin-container/pom.xml index 90b481b..6285a42 100644 --- a/modules/core/plugin-container/pom.xml +++ b/modules/core/plugin-container/pom.xml @@ -96,9 +96,9 @@ </dependency>
<dependency> - <groupId>org.jmock</groupId> - <artifactId>jmock</artifactId> - <version>2.5.1</version> + <groupId>${groupId}</groupId> + <artifactId>test-utils</artifactId> + <version>${version}</version> <scope>test</scope> </dependency>
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigManagementTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigManagementTest.java index afed6b6..cf6e9e9 100644 --- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigManagementTest.java +++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigManagementTest.java @@ -28,6 +28,7 @@ import org.rhq.core.domain.configuration.PropertySimple; import org.rhq.core.domain.configuration.RawConfiguration; import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; import org.rhq.core.domain.resource.ResourceType; +import org.rhq.test.JMockTest; import static org.testng.Assert.assertEquals;
import java.util.HashSet; diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigurationUpdateResponseMatcher.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigurationUpdateResponseMatcher.java deleted file mode 100644 index 74bca9b..0000000 --- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigurationUpdateResponseMatcher.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2008 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, version 2, as - * published by the Free Software Foundation, and/or the GNU Lesser - * General Public License, version 2.1, also as published by the Free - * Software Foundation. - * - * 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 and the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * and the GNU Lesser 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.core.pc.configuration; - -import org.hamcrest.Description; -import org.hamcrest.Matcher; -import org.hamcrest.TypeSafeMatcher; -import org.rhq.core.clientapi.server.configuration.ConfigurationUpdateResponse; - -public class ConfigurationUpdateResponseMatcher extends TypeSafeMatcher<ConfigurationUpdateResponse> { - - public static Matcher<ConfigurationUpdateResponse> matchingResponse(ConfigurationUpdateResponse expected) { - return new ConfigurationUpdateResponseMatcher(expected); - } - - private ConfigurationUpdateResponse expected; - - public ConfigurationUpdateResponseMatcher(ConfigurationUpdateResponse response) { - expected = response; - } - - public boolean matchesSafely(ConfigurationUpdateResponse actual) { - return propertyEquals(expected.getConfiguration(), actual.getConfiguration()) && - propertyEquals(expected.getConfigurationUpdateId(), actual.getConfigurationUpdateId()) && - propertyEquals(expected.getErrorMessage(), actual.getErrorMessage()) && - propertyEquals(expected.getStatus(), actual.getStatus()); - } - - private boolean propertyEquals(Object expected, Object actual) { - if (expected == null && actual == null) { - return true; - } - - if (expected == null && actual != null) { - return false; - } - return expected.equals(actual); - } - - public void describeTo(Description description) { - description.appendText(expected.toString()); - } -} diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/JMockTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/JMockTest.java deleted file mode 100644 index e6e9422..0000000 --- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/JMockTest.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2008 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, version 2, as - * published by the Free Software Foundation, and/or the GNU Lesser - * General Public License, version 2.1, also as published by the Free - * Software Foundation. - * - * 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 and the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * and the GNU Lesser 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.core.pc.configuration; - -import org.jmock.Mockery; -import org.testng.IHookCallBack; -import org.testng.IHookable; -import org.testng.ITestResult; -import org.testng.annotations.BeforeMethod; - -public class JMockTest implements IHookable { - - protected Mockery context; - - @BeforeMethod - void initContext() { - context = new Mockery(); - } - - public void run(IHookCallBack iHookCallBack, ITestResult iTestResult) { - iHookCallBack.runTestMethod(iTestResult); - try { - context.assertIsSatisfied(); - } - catch (Throwable t) { - iTestResult.setStatus(ITestResult.FAILURE); - iTestResult.setThrowable(t); - } - } -} diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadResourceConfigurationFactoryImplTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadResourceConfigurationFactoryImplTest.java index 6913b87..ef028d2 100644 --- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadResourceConfigurationFactoryImplTest.java +++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadResourceConfigurationFactoryImplTest.java @@ -31,6 +31,7 @@ import org.rhq.core.pc.util.ComponentService; import org.rhq.core.domain.resource.ResourceType; import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; import org.rhq.core.domain.configuration.definition.ConfigurationFormat; +import org.rhq.test.JMockTest; import org.jmock.Expectations;
public class LoadResourceConfigurationFactoryImplTest extends JMockTest { diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/UpdateResourceConfigurationRunnerTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/UpdateResourceConfigurationRunnerTest.java index 10bc6d1..272d22e 100644 --- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/UpdateResourceConfigurationRunnerTest.java +++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/UpdateResourceConfigurationRunnerTest.java @@ -23,9 +23,9 @@
package org.rhq.core.pc.configuration;
-import static org.rhq.core.pc.configuration.ConfigurationUpdateResponseMatcher.*; import static org.rhq.core.domain.configuration.ConfigurationUpdateStatus.*; -import static org.testng.Assert.*; +import static org.rhq.test.AssertUtils.*; +import org.rhq.test.jmock.PropertyMatcher;
import org.testng.annotations.Test; import org.rhq.core.clientapi.server.configuration.ConfigurationServerService; @@ -39,6 +39,7 @@ import org.jmock.Expectations; import org.jmock.api.Action; import org.jmock.api.Invocation; import org.hamcrest.Description; +import org.hamcrest.Matcher;
public class UpdateResourceConfigurationRunnerTest extends ConfigManagementTest {
@@ -239,35 +240,7 @@ public class UpdateResourceConfigurationRunnerTest extends ConfigManagementTest
void assertConfigurationUpdateResponseMatches(ConfigurationUpdateResponse expected, ConfigurationUpdateResponse actual, String msg) { - boolean matches = true; - StringBuilder errors = new StringBuilder(msg + " -- " + ConfigurationUpdateResponse.class.getSimpleName() + - " objects do not match:\n"); - - if (!propertyEquals(expected.getConfigurationUpdateId(), actual.getConfigurationUpdateId())) { - matches = false; - errors.append("expected.configurationUpdateId = " + expected.getConfigurationUpdateId() + "\n"); - errors.append("actual.configurationUpdateId = " + actual.getConfigurationUpdateId() + "\n\n"); - } - - if (!propertyEquals(expected.getConfiguration(), actual.getConfiguration())) { - matches = false; - errors.append("expected.configuration = " + expected.getConfiguration() + "\n"); - errors.append("actual.configuration = " + actual.getConfiguration() + "\n\n"); - } - - if (!propertyEquals(expected.getErrorMessage(), actual.getErrorMessage())) { - matches = false; - errors.append("expected.errorMessage = " + expected.getErrorMessage() + "\n"); - errors.append("actual.errorMessage = " + actual.getErrorMessage() + "\n\n"); - } - - if (!propertyEquals(expected.getStatus(), actual.getStatus())) { - matches = false; - errors.append("expected.status = " + expected.getStatus() + "\n"); - errors.append("actual.status = " + actual.getStatus() + "\n\n"); - } - - assertTrue(matches, errors.toString()); + assertPropertiesMatch(expected, actual, msg); }
boolean propertyEquals(Object expected, Object actual) { @@ -281,6 +254,10 @@ public class UpdateResourceConfigurationRunnerTest extends ConfigManagementTest return expected.equals(actual); }
+ public static Matcher<ConfigurationUpdateResponse> matchingResponse(ConfigurationUpdateResponse expected) { + return new PropertyMatcher<ConfigurationUpdateResponse>(expected); + } + public static Action updateReportTo(ConfigurationUpdateStatus status) { return new UpdateResourceConfigurationAction(status); } diff --git a/modules/pom.xml b/modules/pom.xml index b8edc96..9954974 100644 --- a/modules/pom.xml +++ b/modules/pom.xml @@ -1,3 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion> @@ -81,4 +82,7 @@
</profiles>
-</project> + <modules> + <module>test-utils</module> + </modules> +</project> \ No newline at end of file diff --git a/modules/test-utils/pom.xml b/modules/test-utils/pom.xml new file mode 100644 index 0000000..50453bd --- /dev/null +++ b/modules/test-utils/pom.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance%22%3E + <modelVersion>4.0.0</modelVersion> + <parent> + <artifactId>rhq-modules-parent</artifactId> + <groupId>org.rhq</groupId> + <version>1.4.0-SNAPSHOT</version> + </parent> + <artifactId>test-utils</artifactId> + <name>RHQ Test Utils</name> + + <dependencies> + <dependency> + <groupId>org.testng</groupId> + <artifactId>testng</artifactId> + <version>5.9</version> + <scope>compile</scope> + <classifier>jdk15</classifier> + </dependency> + <dependency> + <groupId>org.jmock</groupId> + <artifactId>jmock</artifactId> + <version>2.5.1</version> + </dependency> + <dependency> + <groupId>commons-beanutils</groupId> + <artifactId>commons-beanutils</artifactId> + <version>1.8.2</version> + </dependency> + </dependencies> +</project> diff --git a/modules/test-utils/src/main/java/org/rhq/test/AssertUtils.java b/modules/test-utils/src/main/java/org/rhq/test/AssertUtils.java new file mode 100644 index 0000000..bde72ba --- /dev/null +++ b/modules/test-utils/src/main/java/org/rhq/test/AssertUtils.java @@ -0,0 +1,40 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2008 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, version 2, as + * published by the Free Software Foundation, and/or the GNU Lesser + * General Public License, version 2.1, also as published by the Free + * Software Foundation. + * + * 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 and the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * and the GNU Lesser 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.test; + +import static org.testng.Assert.*; + +public class AssertUtils { + + public static <T> void assertPropertiesMatch(T expected, T actual, String msg) { + PropertyMatcher<T> matcher = new PropertyMatcher<T>(); + matcher.setExpected(expected); + matcher.setActual(actual); + + MatchResult result = matcher.execute(); + + assertTrue(result.isMatch(), msg + " -- " + result.getDetails()); + } + +} diff --git a/modules/test-utils/src/main/java/org/rhq/test/JMockTest.java b/modules/test-utils/src/main/java/org/rhq/test/JMockTest.java new file mode 100644 index 0000000..f3add4e --- /dev/null +++ b/modules/test-utils/src/main/java/org/rhq/test/JMockTest.java @@ -0,0 +1,51 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2008 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, version 2, as + * published by the Free Software Foundation, and/or the GNU Lesser + * General Public License, version 2.1, also as published by the Free + * Software Foundation. + * + * 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 and the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * and the GNU Lesser 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.test; + +import org.jmock.Mockery; +import org.testng.IHookCallBack; +import org.testng.IHookable; +import org.testng.ITestResult; +import org.testng.annotations.BeforeMethod; + +public class JMockTest implements IHookable { + + protected Mockery context; + + @BeforeMethod + public void initContext() { + context = new Mockery(); + } + + public void run(IHookCallBack iHookCallBack, ITestResult iTestResult) { + iHookCallBack.runTestMethod(iTestResult); + try { + context.assertIsSatisfied(); + } + catch (Throwable t) { + iTestResult.setStatus(ITestResult.FAILURE); + iTestResult.setThrowable(t); + } + } +} diff --git a/modules/test-utils/src/main/java/org/rhq/test/MatchResult.java b/modules/test-utils/src/main/java/org/rhq/test/MatchResult.java new file mode 100644 index 0000000..a68d956 --- /dev/null +++ b/modules/test-utils/src/main/java/org/rhq/test/MatchResult.java @@ -0,0 +1,44 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2008 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, version 2, as + * published by the Free Software Foundation, and/or the GNU Lesser + * General Public License, version 2.1, also as published by the Free + * Software Foundation. + * + * 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 and the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * and the GNU Lesser 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.test; + +public class MatchResult { + + private boolean isMatch; + + private String details; + + public MatchResult(boolean isMatch, String details) { + this.isMatch = isMatch; + this.details = details; + } + + public boolean isMatch() { + return isMatch; + } + + public String getDetails() { + return details; + } +} diff --git a/modules/test-utils/src/main/java/org/rhq/test/PropertyMatchException.java b/modules/test-utils/src/main/java/org/rhq/test/PropertyMatchException.java new file mode 100644 index 0000000..6acc3d9 --- /dev/null +++ b/modules/test-utils/src/main/java/org/rhq/test/PropertyMatchException.java @@ -0,0 +1,43 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2008 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, version 2, as + * published by the Free Software Foundation, and/or the GNU Lesser + * General Public License, version 2.1, also as published by the Free + * Software Foundation. + * + * 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 and the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * and the GNU Lesser 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.test; + +public class PropertyMatchException extends RuntimeException { + + public PropertyMatchException() { + super(); + } + + public PropertyMatchException(String message) { + super(message); + } + + public PropertyMatchException(String message, Throwable cause) { + super(message, cause); + } + + public PropertyMatchException(Throwable cause) { + super(cause); + } +} diff --git a/modules/test-utils/src/main/java/org/rhq/test/PropertyMatcher.java b/modules/test-utils/src/main/java/org/rhq/test/PropertyMatcher.java new file mode 100644 index 0000000..6352be5 --- /dev/null +++ b/modules/test-utils/src/main/java/org/rhq/test/PropertyMatcher.java @@ -0,0 +1,88 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2008 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, version 2, as + * published by the Free Software Foundation, and/or the GNU Lesser + * General Public License, version 2.1, also as published by the Free + * Software Foundation. + * + * 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 and the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * and the GNU Lesser 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.test; + +import org.apache.commons.beanutils.PropertyUtils; + +import java.util.Map; +import java.lang.reflect.InvocationTargetException; + +public class PropertyMatcher<T> { + + private T expected; + + private T actual; + + public void setExpected(T expected) { + this.expected = expected; + } + + public void setActual(T actual) { + this.actual = actual; + } + + public MatchResult execute() { + try { + Map<String, ?> expectedProps = PropertyUtils.describe(expected); + Map<String, ?> actualProps = PropertyUtils.describe(actual); + + boolean isMatch = true; + StringBuilder details = new StringBuilder(expected.getClass().getSimpleName() + + " objects do not match:\n"); + + for (String name : expectedProps.keySet()) { + Object expectedValue = expectedProps.get(name); + Object actualValue = actualProps.get(name); + + if (!propertyEquals(expectedValue, actualValue)) { + isMatch = false; + details.append("expected." + name + " = " + expectedValue + "\n"); + details.append("actual." + name + " = " + actualValue + "\n\n"); + } + } + + return new MatchResult(isMatch, details.toString()); + } + catch (IllegalAccessException e) { + throw new PropertyMatchException(e); + } + catch (InvocationTargetException e) { + throw new PropertyMatchException(e); + } + catch (NoSuchMethodException e) { + throw new PropertyMatchException(e); + } + } + + private boolean propertyEquals(Object expected, Object actual) { + if (expected == null && actual == null) { + return true; + } + + if (expected == null && actual != null) { + return false; + } + return expected.equals(actual); + } +} diff --git a/modules/test-utils/src/main/java/org/rhq/test/jmock/PropertyMatcher.java b/modules/test-utils/src/main/java/org/rhq/test/jmock/PropertyMatcher.java new file mode 100644 index 0000000..3be7e2d --- /dev/null +++ b/modules/test-utils/src/main/java/org/rhq/test/jmock/PropertyMatcher.java @@ -0,0 +1,51 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2008 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, version 2, as + * published by the Free Software Foundation, and/or the GNU Lesser + * General Public License, version 2.1, also as published by the Free + * Software Foundation. + * + * 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 and the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * and the GNU Lesser 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.test.jmock; + +import org.hamcrest.TypeSafeMatcher; +import org.hamcrest.Description; +import org.rhq.test.MatchResult; + +public class PropertyMatcher<T> extends TypeSafeMatcher<T> { + + private T expected; + + public PropertyMatcher(T expected) { + this.expected = expected; + } + + public boolean matchesSafely(T actual) { + org.rhq.test.PropertyMatcher<T> matcher = new org.rhq.test.PropertyMatcher<T>(); + matcher.setExpected(expected); + matcher.setActual(actual); + + MatchResult result = matcher.execute(); + + return result.isMatch(); + } + + public void describeTo(Description description) { + description.appendText(expected.toString()); + } +}
commit ad07de61361d0ceccd92362c57afc057269144a3 Merge: 14a2d52... 641c329... Author: Adam Young ayoung@redhat.com Date: Mon Nov 23 12:35:41 2009 -0500
Merge branch 'raw-config' of ssh://git.fedorahosted.org/git/rhq/rhq into raw-config
commit 14a2d521c890662426ccf14af01f83bb12627a39 Author: Adam Young ayoung@redhat.com Date: Mon Nov 23 11:28:00 2009 -0500
Made navigation for the edit buttons universal: wroks no matter where clicked. Used for the view-raw.xhtml.
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-navigation/configuration-navigation.xml b/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-navigation/configuration-navigation.xml index fc93ea8..5668f17 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-navigation/configuration-navigation.xml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-navigation/configuration-navigation.xml @@ -6,7 +6,6 @@
<navigation-rule>
- <from-view-id>/rhq/resource/configuration/view.xhtml</from-view-id>
<navigation-case> <from-action>#{ExistingResourceConfigurationUIBean.editConfiguration}</from-action>
commit 641c32987ac120c4f4e2a891c048c7528d5b466f Merge: a89b22a... 89f7276... Author: John Sanda john@localhost.localdomain Date: Mon Nov 23 11:22:56 2009 -0500
Merge branch 'raw-config' of ssh://git.fedorahosted.org/git/rhq/rhq into raw-config
commit a89b22aa59250277e59cc7fc0871f6d6f94b47db Author: John Sanda john@localhost.localdomain Date: Mon Nov 23 11:19:57 2009 -0500
[US 6] Adding unit tests for embedded mode
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/UpdateResourceConfigurationRunnerTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/UpdateResourceConfigurationRunnerTest.java index 392130b..10bc6d1 100644 --- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/UpdateResourceConfigurationRunnerTest.java +++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/UpdateResourceConfigurationRunnerTest.java @@ -25,6 +25,7 @@ package org.rhq.core.pc.configuration;
import static org.rhq.core.pc.configuration.ConfigurationUpdateResponseMatcher.*; import static org.rhq.core.domain.configuration.ConfigurationUpdateStatus.*; +import static org.testng.Assert.*;
import org.testng.annotations.Test; import org.rhq.core.clientapi.server.configuration.ConfigurationServerService; @@ -76,6 +77,39 @@ public class UpdateResourceConfigurationRunnerTest extends ConfigManagementTest }
@Test + public void successfulUpdateShouldReturnSuccessResponseInEmbeddedMode() throws Exception { + final Configuration config = createStructuredConfig(); + + final ConfigurationFacet facet = context.mock(ConfigurationFacet.class); + + final ConfigurationUtilityService configUtilService = context.mock(ConfigurationUtilityService.class); + + int configUpdateId = -1; + + ConfigurationUpdateRequest updateRequest = new ConfigurationUpdateRequest(configUpdateId, config, resourceId); + + UpdateResourceConfigurationRunner updateRunner = new UpdateResourceConfigurationRunner(null, resourceType, + facet, updateRequest); + updateRunner.setConfigUtilService(configUtilService); + + final ConfigurationUpdateResponse successResponse = new ConfigurationUpdateResponse(configUpdateId, null, + SUCCESS, null); + + context.checking(new Expectations() {{ + oneOf(facet).updateResourceConfiguration(with(any(ConfigurationUpdateReport.class))); + will(updateReportTo(SUCCESS)); + + oneOf(configUtilService).normalizeConfiguration(config, resourceType.getResourceConfigurationDefinition()); + oneOf(configUtilService).validateConfiguration(config, resourceType.getResourceConfigurationDefinition()); + + }}); + + ConfigurationUpdateResponse actualResponse = updateRunner.call(); + + assertConfigurationUpdateResponseMatches(successResponse, actualResponse, "Expected a success response"); + } + + @Test public void inProgressUpdateShouldSendFailureResponseToServer() throws Exception { final Configuration config = createStructuredConfig();
@@ -112,6 +146,40 @@ public class UpdateResourceConfigurationRunnerTest extends ConfigManagementTest }
@Test + public void failedUpdateShouldReturnFailureResponseInEmbeddedMode() throws Exception { + final Configuration config = createStructuredConfig(); + + final ConfigurationFacet facet = context.mock(ConfigurationFacet.class); + + final ConfigurationUtilityService configUtilService = context.mock(ConfigurationUtilityService.class); + + int configUpdateId = -1; + + ConfigurationUpdateRequest updateRequest = new ConfigurationUpdateRequest(configUpdateId, config, resourceId); + + UpdateResourceConfigurationRunner updateRunner = new UpdateResourceConfigurationRunner(null, resourceType, + facet, updateRequest); + updateRunner.setConfigUtilService(configUtilService); + + String errorMsg = "Configuration facet did not indicate success or failure - assuming failure."; + + final ConfigurationUpdateResponse failureResponse = new ConfigurationUpdateResponse(configUpdateId, config, + FAILURE, errorMsg); + + context.checking(new Expectations() {{ + oneOf(facet).updateResourceConfiguration(with(any(ConfigurationUpdateReport.class))); + will(updateReportTo(INPROGRESS)); + + oneOf(configUtilService).normalizeConfiguration(config, resourceType.getResourceConfigurationDefinition()); + oneOf(configUtilService).validateConfiguration(config, resourceType.getResourceConfigurationDefinition()); + }}); + + ConfigurationUpdateResponse actualResponse = updateRunner.call(); + + assertConfigurationUpdateResponseMatches(failureResponse, actualResponse, "Expected a failure response"); + } + + @Test public void failureResponseShouldBeSentToServerWhenFacetThrowsAnException() throws Exception { final Configuration config = createStructuredConfig();
@@ -138,7 +206,79 @@ public class UpdateResourceConfigurationRunnerTest extends ConfigManagementTest oneOf(configServerService).completeConfigurationUpdate(with(matchingResponse(failureResponse))); }});
- updateRunner.call(); + updateRunner.call(); + } + + @Test + public void failureResponseShouldBeReturnedWhenFacetThrowsAnExceptionInEmbeddedMode() throws Exception { + final Configuration config = createStructuredConfig(); + + final ConfigurationFacet facet = context.mock(ConfigurationFacet.class); + + int configUpdateId = -1; + + ConfigurationUpdateRequest updateRequest = new ConfigurationUpdateRequest(configUpdateId, config, resourceId); + + UpdateResourceConfigurationRunner updateRunner = new UpdateResourceConfigurationRunner(null, resourceType, + facet, updateRequest); + + final NullPointerException exception = new NullPointerException("Unexpected error during update"); + + final ConfigurationUpdateResponse failureResponse = new ConfigurationUpdateResponse(configUpdateId, config, + exception); + + context.checking(new Expectations() {{ + oneOf(facet).updateResourceConfiguration(with(any(ConfigurationUpdateReport.class))); + will(throwExceptionFromFacet(exception)); + }}); + + ConfigurationUpdateResponse actualResponse = updateRunner.call(); + + assertConfigurationUpdateResponseMatches(failureResponse, actualResponse, "Expected a failure response"); + } + + void assertConfigurationUpdateResponseMatches(ConfigurationUpdateResponse expected, + ConfigurationUpdateResponse actual, String msg) { + boolean matches = true; + StringBuilder errors = new StringBuilder(msg + " -- " + ConfigurationUpdateResponse.class.getSimpleName() + + " objects do not match:\n"); + + if (!propertyEquals(expected.getConfigurationUpdateId(), actual.getConfigurationUpdateId())) { + matches = false; + errors.append("expected.configurationUpdateId = " + expected.getConfigurationUpdateId() + "\n"); + errors.append("actual.configurationUpdateId = " + actual.getConfigurationUpdateId() + "\n\n"); + } + + if (!propertyEquals(expected.getConfiguration(), actual.getConfiguration())) { + matches = false; + errors.append("expected.configuration = " + expected.getConfiguration() + "\n"); + errors.append("actual.configuration = " + actual.getConfiguration() + "\n\n"); + } + + if (!propertyEquals(expected.getErrorMessage(), actual.getErrorMessage())) { + matches = false; + errors.append("expected.errorMessage = " + expected.getErrorMessage() + "\n"); + errors.append("actual.errorMessage = " + actual.getErrorMessage() + "\n\n"); + } + + if (!propertyEquals(expected.getStatus(), actual.getStatus())) { + matches = false; + errors.append("expected.status = " + expected.getStatus() + "\n"); + errors.append("actual.status = " + actual.getStatus() + "\n\n"); + } + + assertTrue(matches, errors.toString()); + } + + boolean propertyEquals(Object expected, Object actual) { + if (expected == null && actual == null) { + return true; + } + + if (expected == null && actual != null) { + return false; + } + return expected.equals(actual); }
public static Action updateReportTo(ConfigurationUpdateStatus status) {
commit 89f727616b9c90290f948c0de30abc8dbdadbc39 Author: Adam Young ayoung@redhat.com Date: Mon Nov 23 11:16:08 2009 -0500
Made links to structured conditional of structred being supported
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view-raw.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view-raw.xhtml index 5f919f3..65ac139 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view-raw.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view-raw.xhtml @@ -33,32 +33,34 @@ } </script> - <h:outputText value="#{messages.youareviewingraw}" /> - <h:outputText value=" #{messages.switch2}" /> - <h:outputLink value="view.xhtml"> - <s:conversationId /> + <h:outputText value="#{messages.youareviewingraw}" /> + <h:panelGroup rendered="#{rawConfigCollection.structuredSupported}"> + <h:outputText value=" #{messages.switch2}" /> + <h:outputLink value="view.xhtml"> + <s:conversationId /> <f:param name="id" value="#{ResourceUIBean.id}" /> <h:outputText value=" #{messages.structured}" /> - </h:outputLink> + </h:outputLink> + </h:panelGroup> + + <h:form id="viewResourceConfigurationForm"> + <!-- TODO remove the id version --> + <input type="hidden" name="id" value="#{ResourceUIBean.id}"/> - <h:form id="viewResourceConfigurationForm"> - <!-- TODO remove the id version --> - <input type="hidden" name="id" value="#{ResourceUIBean.id}"/> - - - <h:panelGrid columns="2" styleClass="buttons-table" columnClasses="button-cell" + <h:panelGrid columns="2" styleClass="buttons-table" columnClasses="button-cell" rendered="#{ExistingResourceConfigurationUIBean.configuration != null and !ExistingResourceConfigurationUIBean.updateInProgress}"> - <h:commandButton value="#{messages.editstructured}" action="#{ExistingResourceConfigurationUIBean.editConfiguration}" + + <h:commandButton value="#{messages.editstructured}" action="#{ExistingResourceConfigurationUIBean.editConfiguration}" title="Edit this Configuration" styleClass="buttonmed" rendered="${ResourceUIBean.permissions.configure and rawConfigCollection.structuredSupported and !ExistingResourceConfigurationUIBean.updateInProgress}" /> <h:commandButton value="#{messages.editraw}" action="#{ExistingResourceConfigurationUIBean.editRawConfiguration}" title="Advanced Mode Edit of Raw Configuration Files" styleClass="buttonmed" rendered="${ResourceUIBean.permissions.configure and rawConfigCollection.rawSupported and !ExistingResourceConfigurationUIBean.updateInProgress}" /> - </h:panelGrid> + </h:panelGrid> - </h:form> + </h:form> <table class="summary-props-table" style=""> <tr>
commit ef77c4af198f1deca1f869bbd880b7c9a948a613 Author: Jay Shaughnessy jshaughn@redhat.com Date: Mon Nov 23 10:28:37 2009 -0500
more perspective descriptor schema tweaks
diff --git a/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-perspective.xsd b/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-perspective.xsd index b6fabfd..0ddd9b5 100644 --- a/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-perspective.xsd +++ b/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-perspective.xsd @@ -228,7 +228,8 @@ <xs:attribute name="action" type="perspective:ActionType" - use="optional"> + use="optional" + default="add"> xs:annotation xs:documentation Add or remove the menu entry. For removal all but the name attribute are ignored. @@ -342,7 +343,8 @@ <xs:attribute name="action" type="perspective:ActionType" - use="optional"> + use="optional" + default="add"> xs:annotation xs:documentation Add or remove the menu entry. Add is the default. @@ -401,7 +403,8 @@ <xs:attribute name="action" type="perspective:ActionType" - use="optional"> + use="optional" + default="add"> xs:annotation xs:documentation Add or remove the menu entry. Add is the default. @@ -581,6 +584,12 @@ type="perspective:PlacementType" use="required"> </xs:attribute> + <xs:attribute + name="break" + type="xs:boolean" + use="optional" + default="false"> + </xs:attribute> </xs:complexType>
<xs:simpleType @@ -616,7 +625,7 @@ <xs:restriction base="xs:string"> <xs:minLength - value="1" /> + value="0" /> <xs:maxLength value="128" /> </xs:restriction>
commit c60357c442440143a537a703a0d11b993d644f07 Author: Jay Shaughnessy jshaughn@redhat.com Date: Mon Nov 23 10:27:30 2009 -0500
Add core perspective to rhq.ear
diff --git a/modules/enterprise/server/ear/pom.xml b/modules/enterprise/server/ear/pom.xml index 4e40aae..02e4f91 100644 --- a/modules/enterprise/server/ear/pom.xml +++ b/modules/enterprise/server/ear/pom.xml @@ -411,6 +411,12 @@ <version>${project.version}</version> </artifactItem>
+ <artifactItem> + <groupId>org.rhq</groupId> + <artifactId>rhq-core-perspective</artifactId> + <version>${project.version}</version> + </artifactItem> + <!-- Temporary Sample Perspective --> <artifactItem> <groupId>org.rhq</groupId>
commit 29c7c2e62bc7cbb75ac92ae1af173968477d81fb Author: Jay Shaughnessy jshaughn@redhat.com Date: Mon Nov 23 10:26:42 2009 -0500
conforming to schema change
diff --git a/etc/samples/perspectives/sample-perspective/perspective/src/main/resources/META-INF/rhq-serverplugin.xml b/etc/samples/perspectives/sample-perspective/perspective/src/main/resources/META-INF/rhq-serverplugin.xml index 490ae03..36430f3 100644 --- a/etc/samples/perspectives/sample-perspective/perspective/src/main/resources/META-INF/rhq-serverplugin.xml +++ b/etc/samples/perspectives/sample-perspective/perspective/src/main/resources/META-INF/rhq-serverplugin.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8" ?>
-<perspective-plugin +<perspectivePlugin apiVersion="1.0" version="1.0" description="A Sample Perspective Utilizing Every Extension Point and Filter" @@ -11,4 +11,4 @@ xmlns:serverplugin="urn:xmlns:rhq-serverplugin" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance%22%3E
-</perspective-plugin> \ No newline at end of file +</perspectivePlugin> \ No newline at end of file
commit 996b0c7f09dcdc85f3964d3442d8b54c5f4d3bf0 Author: Jay Shaughnessy jshaughn@redhat.com Date: Fri Nov 20 22:23:28 2009 -0500
Add Core perspective to build
diff --git a/modules/enterprise/server/plugins/pom.xml b/modules/enterprise/server/plugins/pom.xml index a3331db..dc2c402 100644 --- a/modules/enterprise/server/plugins/pom.xml +++ b/modules/enterprise/server/plugins/pom.xml @@ -39,6 +39,7 @@ <module>yum</module> <module>url</module> <module>rhnhosted</module> + <module>perspectives/core</module> <!-- temporary sample perspective plugin --> <module>../../../../etc/samples/perspectives/sample-perspective</module> </modules>
commit 90bc40f44690b85ece0a86502fcf2cde9d57e624 Author: Jay Shaughnessy jshaughn@redhat.com Date: Fri Nov 20 22:22:51 2009 -0500
New Core Perspective defining CoreUI extensions
diff --git a/modules/enterprise/server/plugins/perspectives/core/perspective/pom.xml b/modules/enterprise/server/plugins/perspectives/core/perspective/pom.xml new file mode 100644 index 0000000..e8dfec7 --- /dev/null +++ b/modules/enterprise/server/plugins/perspectives/core/perspective/pom.xml @@ -0,0 +1,62 @@ +<?xml version="1.0"?> + +<project + xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd%22%3E + + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.rhq</groupId> + <artifactId>rhq-parent</artifactId> + <version>1.4.0-SNAPSHOT</version> + </parent> + + <groupId>org.rhq</groupId> + <artifactId>rhq-core-perspective</artifactId> + <packaging>jar</packaging> + + <name>RHQ Core Perspective</name> + <description>A Perspective defining Core UI Elements</description> + + <properties> + <rhq.version>1.4.0-SNAPSHOT</rhq.version> + </properties> + + <dependencies> + + <!-- Below are the core modules that are required dependencies of all server plugins --> + <dependency> + <groupId>org.rhq</groupId> + <artifactId>rhq-enterprise-server</artifactId> + <version>${rhq.version}</version> + <scope>provided</scope> <!-- provided by the server/plugin-container --> + </dependency> + + <!-- uncomment the one of the three logging systems your plugin uses: log4j, commons-logging or i18nlog --> + <!-- all three are provided to your plugin by the server/plugin-container --> + <!-- + <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.14</version> + <scope>provided</scope> </dependency> + --> + + <!-- + <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.1</version> + <scope>provided</scope> </dependency> + --> + + <!-- + <dependency> <groupId>i18nlog</groupId> <artifactId>i18nlog</artifactId> <version>1.0.9</version> </dependency> + --> + + <!-- Define any third-party dependencies your plugin has here. --> + <!-- + <dependency> <groupId>group-id-of-dependency-goes-here</groupId> + <artifactId>artifact-id-of-dependency-goes-here</artifactId> <version>version-of-dependency-goes-here</version> + </dependency> + --> + + </dependencies> + +</project> diff --git a/modules/enterprise/server/plugins/perspectives/core/perspective/src/main/resources/META-INF/rhq-serverplugin.xml b/modules/enterprise/server/plugins/perspectives/core/perspective/src/main/resources/META-INF/rhq-serverplugin.xml new file mode 100644 index 0000000..63e1746 --- /dev/null +++ b/modules/enterprise/server/plugins/perspectives/core/perspective/src/main/resources/META-INF/rhq-serverplugin.xml @@ -0,0 +1,506 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<perspectivePlugin + version="1.0" + apiVersion="2.0" + description="The Core Perspective defining Core UI Elements" + displayName="Core Perspective" + name="CorePerspective" + package="org.rhq.perspective.core" + xmlns="urn:xmlns:rhq-serverplugin.perspective" + xmlns:serverplugin="urn:xmlns:rhq-serverplugin" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance%22%3E + + <!-- Core Menu --> + <menuItem + name="logo" + displayName="" + url="/" + iconUrl="/images/JBossLogo_small.png"> + <position + extensionPoint="coreMenu" + placement="start" /> + </menuItem> + <menuItem + name="overview" + displayName="Overview"> + <position + extensionPoint="coreMenu" + name="logo" + placement="after" /> + </menuItem> + <menuItem + name="resources" + displayName="Resources"> + <position + extensionPoint="coreMenu" + name="overview" + placement="after" /> + </menuItem> + <menuItem + name="groups" + displayName="Groups"> + <position + extensionPoint="coreMenu" + name="resources" + placement="after" /> + </menuItem> + <menuItem + name="administration" + displayName="Administration"> + <position + extensionPoint="coreMenu" + name="groups" + placement="after" /> + </menuItem> + <menuItem + name="help" + displayName="Help"> + <position + extensionPoint="coreMenu" + name="administration" + placement="after" /> + </menuItem> + + + <!-- Core Menu: Overview --> + <menuItem + name="overview.subsystemViews" + displayName="Subsystem Views"> + <position + extensionPoint="coreMenu" + name="overview" + placement="start" /> + </menuItem> + <menuItem + name="overview.autoDiscoveryQueue" + displayName="Auto Discovery Queue" + url="/rhq/discovery/queue.xhtml"> + <position + extensionPoint="coreMenu" + name="overview.subsystemViews" + placement="after" /> + </menuItem> + <menuItem + name="overview.dashboard" + displayName="Dashboard" + url="/Dashboard.do"> + <position + extensionPoint="coreMenu" + name="overview.autoDiscoveryQueue" + placement="after" /> + </menuItem> + + <!-- Core Menu: Resources --> + <menuItem + name="resources.platforms" + displayName="Platforms" + iconUrl="/images/icons/Platform_up_16.png" + url="/ResourceHub.do?resourceCategory=PLATFORM"> + <position + extensionPoint="coreMenu" + name="resources" + placement="start" /> + </menuItem> + <menuItem + name="resources.servers" + displayName="Servers" + iconUrl="/images/icons/Server_up_16.png" + url="/ResourceHub.do?resourceCategory=SERVER"> + <position + extensionPoint="coreMenu" + name="resources.platforms" + placement="after" /> + </menuItem> + <menuItem + name="resources.services" + displayName="Services" + iconUrl="/images/icons/Service_up_16.png" + url="/ResourceHub.do?resourceCategory=SERVICE"> + <position + extensionPoint="coreMenu" + name="resources.platforms" + placement="after" /> + </menuItem> + <menuItem + name="resources.favoriteResources" + displayName="Favorite Resources" + feature="resourceFavorites" + iconUrl="/images/icons/Favorite_16.png"> + <position + extensionPoint="coreMenu" + name="resources.services" + placement="after" /> + </menuItem> + <menuItem + name="resources.recentlyViewedResources" + displayName="Recently Viewed Resources" + feature="resourceRecentlyViewed" + iconUrl="/images/icons/History_16.png"> + <position + extensionPoint="coreMenu" + name="resources.favoriteResources" + placement="after" /> + </menuItem> + <menuItem + name="resources.search" + displayName="Search:" + feature="resourceSearch" + iconUrl="/images/icons/Search_16.png"> + <position + extensionPoint="coreMenu" + name="resources.recentlyViewedResources" + placement="after" + break="true" /> + </menuItem> + + <!-- Core Menu: Groups --> + <menuItem + name="groups.compatibleGroups" + displayName="Compatible Groups" + iconUrl="images/icons/Cluster_up_16.png" + url="/GroupHub.do?groupCategory=COMPATIBLE"> + <position + extensionPoint="coreMenu" + name="groups" + placement="start" /> + </menuItem> + <menuItem + name="groups.mixedGroups" + displayName="Mixed Groups" + iconUrl="/images/icons/Group_up_16.png" + url="/GroupHub.do?groupCategory=MIXED"> + <position + extensionPoint="coreMenu" + name="groups.compatibleGroups" + placement="after" /> + </menuItem> + <menuItem + name="groups.groupDefinitions" + displayName="Group Definitions" + iconUrl="/images/GroupDefinition_16.png" + url="/rhq/definition/group/list.xhtml"> + <position + extensionPoint="coreMenu" + name="groups.mixedGroups" + placement="after" /> + </menuItem> + <menuItem + name="groups.newGroup" + displayName="New Group" + url="/resource/group/Inventory.do?mode=new"> + <position + extensionPoint="coreMenu" + name="groups.groupDefinitions" + placement="after" + break="true" /> + </menuItem> + <menuItem + name="groups.newGroupDefinition" + displayName="New Group Definition" + url="/rhq/definition/group/new.xhtml"> + <position + extensionPoint="coreMenu" + name="groups.newGroup" + placement="after" /> + </menuItem> + <menuItem + name="groups.favoriteGroups" + displayName="Favorite Groups" + feature="groupFavorites" + iconUrl="/images/icons/Favorite_16.png"> + <position + extensionPoint="coreMenu" + name="groups.newGroupDefinition" + placement="after" + break="true" /> + </menuItem> + <menuItem + name="groups.recentlyViewedGroups" + displayName="Recently Viewed Groups" + feature="groupRecentlyViewed" + iconUrl="/images/icons/History_16.png"> + <position + extensionPoint="coreMenu" + name="groups.favoriteGroups" + placement="after" /> + </menuItem> + <menuItem + name="groups.search" + displayName="Search:" + feature="groupSearch" + iconUrl="/images/icons/Search_16.png"> + <position + extensionPoint="coreMenu" + name="groups.recentlyViewedGroups" + placement="after" + break="true" /> + </menuItem> + + <!-- Core Menu: Administration --> + <menuItem + name="administration.security" + displayName="Security"> + <position + extensionPoint="coreMenu" + name="administration" + placement="start" /> + </menuItem> + <menuItem + name="administration.systemConfiguration" + displayName="systemConfiguration"> + <position + extensionPoint="coreMenu" + name="administration.security" + placement="after" /> + </menuItem> + <menuItem + name="administration.content" + displayName="Content"> + <position + extensionPoint="coreMenu" + name="administration.systemConfiguration" + placement="after" /> + </menuItem> + <menuItem + name="administration.highAvailability" + displayName="High Availability"> + <position + extensionPoint="coreMenu" + name="administration.content" + placement="after" /> + </menuItem> + <menuItem + name="administration.reports" + displayName="Reports"> + <position + extensionPoint="coreMenu" + name="administration.highAvailability" + placement="after" /> + </menuItem> + <menuItem + name="administration.download" + displayName="Download" + iconUrl="/images/icons/Save_16.png" + url="/rhq/admin/downloads.xhtml"> + <position + extensionPoint="coreMenu" + name="administration.reports" + placement="after" /> + </menuItem> + <menuItem + name="administration.license" + displayName="License" + url="/admin/license/LicenseAdmin.do?mode=view"> + <position + extensionPoint="coreMenu" + name="administration.download" + placement="after" /> + </menuItem> + + <!-- Core Menu: Help --> + <menuItem + name="help.onlineDocumentation" + displayName="Online Documentation" + feature="newWindow" + url="http://www.redhat.com/docs/en-US/JBoss_ON/%22%3E + <position + extensionPoint="coreMenu" + name="help" + placement="start" /> + </menuItem> + <menuItem + name="help.openASupportCase" + displayName="Open a Support Case" + feature="newWindow" + url="https://support.redhat.com/jbossnetwork/restricted/addCase.html%22%3E + <position + extensionPoint="coreMenu" + name="help.onlineDocumentation" + placement="after" /> + </menuItem> + <menuItem + name="help.about" + displayName="About" + feature="aboutBox" + iconUrl="/images/icons/availability_grey_16.png"> + <position + extensionPoint="coreMenu" + name="help.openASupportCase" + placement="after" + break="true" /> + </menuItem> + + <!-- Core Menu: Overview.Subsystem Views --> + <menuItem + name="overview.subsystemViews.configurationChanges" + displayName="Configuration Changes" + iconUrl="/images/icons/Configure_16.png" + url="/rhq/subsystem/configurationUpdate.xhtml"> + <position + extensionPoint="coreMenu" + name="overview.subsystemViews" + placement="start" /> + </menuItem> + <menuItem + name="overview.subsystemViews.suspectMetrics" + displayName="suspectMetrics" + iconUrl="/images/icons/Monitor_failed_16.png" + url="/rhq/subsystem/oobHistory.xhtml"> + <position + extensionPoint="coreMenu" + name="overview.subsystemViews.configurationChanges" + placement="after" /> + </menuItem> + <menuItem + name="overview.subsystemViews.operations" + displayName="Operations" + iconUrl="/images/icons/Operation_16.png" + url="/rhq/subsystem/operationHistory.xhtml"> + <position + extensionPoint="coreMenu" + name="overview.subsystemViews.suspectMetrics" + placement="after" /> + </menuItem> + <menuItem + name="overview.subsystemViews.alerts" + displayName="Alerts" + iconUrl="/images/icons/Flag_blue_16.png" + url="/rhq/subsystem/alertHistory.xhtml"> + <position + extensionPoint="coreMenu" + name="overview.subsystemViews.operations" + placement="after" /> + </menuItem> + <menuItem + name="overview.subsystemViews.alertDefinitions" + displayName="Alert Definitions" + iconUrl="/images/icons/Flag_blue_16.png" + url="/rhq/subsystem/alertDefinitions.xhtml"> + <position + extensionPoint="coreMenu" + name="overview.subsystemViews.alerts" + placement="after" /> + </menuItem> + + <!-- Core Menu: Administration.Security --> + <menuItem + name="administration.security.users" + displayName="Users" + url="/admin/user/UserAdmin.do?mode=list"> + <position + extensionPoint="coreMenu" + name="administration.security" + placement="start" /> + </menuItem> + <menuItem + name="administration.security.roles" + displayName="Roles" + url="/admin/role/RoleAdmin.do?mode=list"> + <position + extensionPoint="coreMenu" + name="administration.security.users" + placement="after" /> + </menuItem> + + <!-- Core Menu: administration.systemConfiguration --> + <menuItem + name="administration.systemConfiguration.settings" + displayName="Settings" + url="/admin/config/Config.do?mode=edit"> + <position + extensionPoint="coreMenu" + name="administration.systemConfiguration" + placement="start" /> + </menuItem> + <menuItem + name="administration.systemConfiguration.plugins" + displayName="Plugins" + url="/rhq/admin/plugin/plugin-list.xhtml"> + <position + extensionPoint="coreMenu" + name="administration.systemConfiguration.settings" + placement="after" /> + </menuItem> + <menuItem + name="administration.systemConfiguration.templates" + displayName="Templates" + url="/admin/config/EditDefaults.do?mode=monitor&viewMode=all"> + <position + extensionPoint="coreMenu" + name="administration.systemConfiguration.plugins" + placement="after" /> + </menuItem> + + <!-- Core Menu: administration.content --> + <menuItem + name="administration.content.contentProviders" + displayName="Content Providers" + url="/rhq/content/listContentProviders.xhtml"> + <position + extensionPoint="coreMenu" + name="administration.content" + placement="start" /> + </menuItem> + <menuItem + name="administration.content.repositories" + displayName="Repositories" + url="/rhq/content/listRepos.xhtml"> + <position + extensionPoint="coreMenu" + name="administration.content.contentProviders" + placement="after" /> + </menuItem> + + <!-- Core Menu: administration.highAvailability --> + <menuItem + name="administration.highAvailability.servers" + displayName="Servers" + url="/rhq/ha/listServers.xhtml"> + <position + extensionPoint="coreMenu" + name="administration.highAvailability" + placement="start" /> + </menuItem> + <menuItem + name="administration.highAvailability.agents" + displayName="Agents" + url="/rhq/ha/listAgents.xhtml"> + <position + extensionPoint="coreMenu" + name="administration.highAvailability.servers" + placement="after" /> + </menuItem> + <menuItem + name="administration.highAvailability.affinityGroups" + displayName="Affinity Groups" + url="/rhq/ha/listAffinityGroups.xhtml"> + <position + extensionPoint="coreMenu" + name="administration.highAvailability.agents" + placement="after" /> + </menuItem> + <menuItem + name="administration.highAvailability.paritionEvents" + displayName="Partition Events" + url="/rhq/ha/listPartitionEvents.xhtml"> + <position + extensionPoint="coreMenu" + name="administration.highAvailability.affinityGroups" + placement="after" /> + </menuItem> + + <!-- Core Menu: administration.reports --> + <menuItem + name="administration.reports.resourceVersionInventoryReport" + displayName="Servers" + url="/rhq/admin/report/resourceInstallReport.xhtml"> + <position + extensionPoint="coreMenu" + name="administration.reports" + placement="start" /> + </menuItem> + + + +</perspectivePlugin> \ No newline at end of file diff --git a/modules/enterprise/server/plugins/perspectives/core/pom.xml b/modules/enterprise/server/plugins/perspectives/core/pom.xml new file mode 100644 index 0000000..01ce0b1 --- /dev/null +++ b/modules/enterprise/server/plugins/perspectives/core/pom.xml @@ -0,0 +1,44 @@ +<project + xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd%22%3E + + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.rhq</groupId> + <artifactId>rhq-parent</artifactId> + <version>1.4.0-SNAPSHOT</version> + </parent> + + <groupId>org.rhq</groupId> + <artifactId>rhq-core-perspective-parent</artifactId> + <packaging>pom</packaging> + + <name>RHQ Core Perspective Parent</name> + <description>parent POM for modules comprising the RHQ Core Perspective</description> + + <scm> + <connection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/modules/enterprise/plugins/perspectives/core</connection> + <developerConnection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/modules/enterprise/plugins/perspectives/core/</developerConnection> + </scm> + + <properties> + <scm.module.path>modules/enterprise/plugins/perspectives/core/</scm.module.path> + </properties> + + <profiles> + + <profile> + <id>default</id> + <activation> + <activeByDefault>true</activeByDefault> + </activation> + <modules> + <module>perspective</module> + </modules> + </profile> + + </profiles> + +</project> \ No newline at end of file
commit 3da3d63d13bb70ce9319a22449845e8e03c095eb Author: Jay Shaughnessy jshaughn@redhat.com Date: Fri Nov 20 22:21:01 2009 -0500
Under Construction - Perspective Descriptor
diff --git a/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-perspective.xsd b/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-perspective.xsd index ce586b7..b6fabfd 100644 --- a/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-perspective.xsd +++ b/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-perspective.xsd @@ -1,48 +1,731 @@ <?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
-<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" - xmlns:config="urn:xmlns:rhq-configuration" - xmlns:serverplugin="urn:xmlns:rhq-serverplugin" - xmlns:perspective="urn:xmlns:rhq-serverplugin.perspective" - targetNamespace="urn:xmlns:rhq-serverplugin.perspective" - elementFormDefault="qualified" - jaxb:version="2.0" - xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" blockDefault=""> - - <xs:import namespace="urn:xmlns:rhq-serverplugin" schemaLocation="rhq-serverplugin.xsd" /> - - xs:annotation - xs:documentation - Schema for a Perspective Descriptor. Perspective are deployed as Server Plugins. - </xs:documentation> - xs:appinfo - jaxb:schemaBindings - <jaxb:package name="org.rhq.enterprise.server.xmlschema.generated.serverplugin.perspective" /> - </jaxb:schemaBindings> - </xs:appinfo> - </xs:annotation> - - <xs:element name="perspective-plugin" type="perspective:PerspectivePluginDescriptorType" substitutionGroup="serverplugin:server-plugin"> - xs:annotation - xs:documentation - Defines a Perspective plugin. A Perspective is deployed as a Server Plugin. - The Server Plugin Container (SPC) handles simple lifecycle management for - the deployed plugins (e.g. start, stop). The plugin is otherwise standalone - and can do everything it needs to do without additional help from the SPC. +<xs:schema + xmlns:xs="http://www.w3.org/2001/XMLSchema" + xmlns:config="urn:xmlns:rhq-configuration" + xmlns:serverplugin="urn:xmlns:rhq-serverplugin" + xmlns:perspective="urn:xmlns:rhq-serverplugin.perspective" + targetNamespace="urn:xmlns:rhq-serverplugin.perspective" + elementFormDefault="qualified" + jaxb:version="2.0" + xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" + blockDefault=""> + + <xs:include + schemaLocation=""></xs:include> + <xs:import + namespace="urn:xmlns:rhq-serverplugin" + schemaLocation="rhq-serverplugin.xsd" /> + + xs:annotation + xs:documentation + Schema for a Perspective Descriptor. Perspective are deployed as Server Plugins. + </xs:documentation> + xs:appinfo + jaxb:schemaBindings + <jaxb:package + name="org.rhq.enterprise.server.xmlschema.generated.serverplugin.perspective" /> + </jaxb:schemaBindings> + </xs:appinfo> + </xs:annotation> + + <xs:element + name="perspectivePlugin" + type="perspective:PerspectivePluginDescriptorType" + substitutionGroup="serverplugin:server-plugin"> + xs:annotation + xs:documentation + Defines a Perspective plugin. A Perspective is deployed as a Server Plugin. + The Server Plugin + Container (SPC) handles simple lifecycle management for + the deployed plugins (e.g. start, stop). The plugin + is otherwise standalone + and can do everything it needs to do without additional help from the SPC. + </xs:documentation> + xs:appinfo + <jaxb:class + name="PerspectivePluginElement" /> + </xs:appinfo> + </xs:annotation> + </xs:element> + + <xs:complexType + name="PerspectivePluginDescriptorType"> + xs:complexContent + <xs:extension + base="serverplugin:ServerPluginDescriptorType"> + xs:sequence + <xs:element + ref="perspective:globalTask" + minOccurs="0" + maxOccurs="unbounded"> + </xs:element> + <xs:element + ref="perspective:resourceTask" + minOccurs="0" + maxOccurs="unbounded"> + </xs:element> + <xs:element + ref="perspective:menuItem" + minOccurs="0" + maxOccurs="unbounded"> + </xs:element> + <xs:element + ref="perspective:resourceTab" + minOccurs="0" + maxOccurs="unbounded"> + </xs:element> + <xs:element + ref="perspective:resourceSubTab" + minOccurs="0" + maxOccurs="unbounded"> + </xs:element> + </xs:sequence> + </xs:extension> + </xs:complexContent> + </xs:complexType> + + <xs:element + name="globalTask" + type="perspective:TaskType"> + xs:annotation + xs:appinfo + <jaxb:class + name="PerspectiveGlobalTaskElement" /> + </xs:appinfo> + </xs:annotation> + </xs:element> + + <xs:element + name="resourceTask" + type="perspective:TaskType"> + xs:annotation + xs:appinfo + <jaxb:class + name="PerspectiveResourceTaskElement" /> + </xs:appinfo> + </xs:annotation> + </xs:element> + + <xs:complexType + name="TaskType"> + xs:sequence + <xs:element + name="NewElement" + type="xs:string"> + </xs:element> + <xs:element + ref="perspective:extensionPoint" + minOccurs="1" + maxOccurs="unbounded"> + xs:annotation + xs:documentationA task pane extension point for which this task is presented.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element + ref="perspective:helpText" + minOccurs="0" + maxOccurs="1"> + xs:annotation + xs:documentationOptional additional help text for the task.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + <xs:attribute + name="name" + type="perspective:NameType" + use="required"> + xs:annotation + xs:documentation + The task name. Unique within names defined by the perspective. Used for + display if + displayName not provided. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute + name="displayName" + type="perspective:DisplayNameType" + use="optional"> + xs:annotation + xs:documentation + The name used for display, if provided. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute + name="description" + type="perspective:DescriptionType" + use="required"> + xs:annotation + xs:documentation + The task description displayed for the task. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute + name="url" + type="xs:anyURI" + use="optional"> + xs:annotation + xs:documentation + The request URL for the task. Typically kicks off a wizard or similar workflow. </xs:documentation> - xs:appinfo - <jaxb:class name="PerspectivePluginElement" /> - </xs:appinfo> - </xs:annotation> - </xs:element> - <xs:complexType name="PerspectivePluginDescriptorType"> - xs:complexContent - <xs:extension base="serverplugin:ServerPluginDescriptorType"> - xs:sequence - <!--...put specific perspective schema definitions here...--> - </xs:sequence> - </xs:extension> - </xs:complexContent> - </xs:complexType> + </xs:annotation> + </xs:attribute> + <xs:attribute + name="category" + type="xs:string" + use="optional"> + xs:annotation + xs:documentation + Optional task category. Tasks for the same category will be grouped together. + Categories + are not predefined. + </xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:complexType> + + <xs:element + name="extensionPoint" + type="perspective:ExtensionPointNameType"> + </xs:element> + + <xs:element + name="helpText" + type="perspective:HelpTextType"> + </xs:element> + + <xs:element + name="menuItem"> + xs:annotation + xs:documentation + Add or Remove a menu item in an existing menu extension point. Additions can specify + positioning as + well as a recursive structure, defineing a tree of MenuItems. + </xs:documentation> + xs:appinfo + <jaxb:class + name="PerspectiveMenuItemElement" /> + </xs:appinfo> + </xs:annotation> + xs:complexType + xs:sequence + <xs:element + ref="perspective:position" + minOccurs="0" + maxOccurs="1"> + xs:annotation + xs:documentation + Required for root menuItem additions. Position of children is implicit given the + XML + structure. + </xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + <xs:attribute + name="action" + type="perspective:ActionType" + use="optional"> + xs:annotation + xs:documentation + Add or remove the menu entry. For removal all but the name attribute are ignored. + Default is add. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute + name="name" + type="perspective:NameType" + use="required"> + xs:annotation + xs:documentation + ExtensionPoint name used for reference by other defined extension points. + Unique within + perspective. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute + name="displayName" + type="perspective:DisplayNameType" + use="optional"> + xs:annotation + xs:documentation + The displayed menu item name. Required for add actions. If empty an icon must be + defined. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute + name="feature" + type="perspective:MenuItemFeatureType" + use="optional"> + xs:annotation + xs:documentation + Certain menu items utilize special built-in rendering features. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute + name="url" + type="xs:anyURI" + use="optional"> + xs:annotation + xs:documentation + The request URL for the menu entry. If not provided the entry is just a placeholder for + MenuItems. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute + name="iconUrl" + type="xs:anyURI" + use="optional"> + xs:annotation + xs:documentation + The request URL for the icon image for this menu item. If not provided then no image is + used. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute + name="iconWidth" + type="xs:int" + use="optional"> + </xs:attribute> + <xs:attribute + name="iconHeight" + type="xs:int" + use="optional"> + </xs:attribute> + </xs:complexType> + </xs:element> + + <xs:element + name="resourceTab"> + xs:annotation + xs:appinfo + <jaxb:class + name="PerspectiveResourceTabElement" /> + </xs:appinfo> + </xs:annotation> + xs:complexType + xs:sequence + <xs:element + ref="perspective:position" + minOccurs="0" + maxOccurs="1"> + xs:annotation + xs:documentation + Required for root menuItem additions. Position of children is implicit given the + XML + structure. + </xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + <xs:attribute + name="name" + type="perspective:NameType" + use="required"> + xs:annotation + xs:documentation + The menu entry name. Unique within menu items defined for the perspective. Displayed + on + screen. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute + name="action" + type="perspective:ActionType" + use="optional"> + xs:annotation + xs:documentation + Add or remove the menu entry. Add is the default. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute + name="url" + type="xs:anyURI" + use="optional"> + xs:annotation + xs:documentation + The request URL for the menu entry. If not provided the entry is just a placeholder for + MenuItems. + </xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:complexType> + </xs:element> + + <xs:element + name="resourceSubTab"> + xs:annotation + xs:appinfo + <jaxb:class + name="PerspectiveResourceSubTabElement" /> + </xs:appinfo> + </xs:annotation> + xs:complexType + xs:sequence + <xs:element + ref="perspective:position" + minOccurs="0" + maxOccurs="1"> + xs:annotation + xs:documentation + Required for root menuItem additions. Position of children is implicit given the + XML + structure. + </xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + <xs:attribute + name="name" + type="perspective:NameType" + use="required"> + xs:annotation + xs:documentation + The menu entry name. Unique within menu items defined for the perspective. Displayed + on + screen. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute + name="action" + type="perspective:ActionType" + use="optional"> + xs:annotation + xs:documentation + Add or remove the menu entry. Add is the default. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute + name="url" + type="xs:anyURI" + use="optional"> + xs:annotation + xs:documentation + The request URL for the menu entry. If not provided the entry is just a placeholder for + MenuItems. + </xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:complexType> + </xs:element> + + <xs:element + name="inventoryActivator"> + xs:annotation + xs:appinfo + <jaxb:class + name="InventoryActivatorElement" /> + </xs:appinfo> + xs:documentation + Activators must be satisfied for the extension point to be active. + </xs:documentation> + </xs:annotation> + xs:complexType + xs:sequence + <xs:element + ref="perspective:permissionActivator" + minOccurs="0" + maxOccurs="unbounded"> + </xs:element> + <xs:element + ref="perspective:traitActivator" + minOccurs="0" + maxOccurs="unbounded"> + </xs:element> + </xs:sequence> + <xs:attribute + name="plugin" + type="xs:string" + use="required"> + xs:annotation + xs:documentation + Plugin for the specified resource type. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute + name="resourceType" + type="xs:string" + use="required"> + xs:annotation + xs:documentation + Resource Type that must be in inventory to activate the extension point. + </xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:complexType> + </xs:element> + + <xs:element + name="permissionActivator" + type="perspective:PermissionType"> + xs:annotation + xs:documentation + Activators must be satisfied for the extension point to be active. + The specified permission + must be available to the current user session. + </xs:documentation> + </xs:annotation> + </xs:element> + + <xs:element + name="traitActivator" + type="perspective:TraitActivatorType"> + xs:annotation + xs:documentation + Activators must be satisfied for the extension point to be active. + The specified permission + must be available to the current user session. + </xs:documentation> + </xs:annotation> + </xs:element> + + <xs:complexType + name="TraitActivatorType"> + <xs:attribute + name="trait" + type="xs:string" + use="required"> + xs:annotation + xs:documentation + The trait being tested for activation. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute + name="value" + type="xs:string" + use="required"> + xs:annotation + xs:documentation + The value of the trait. By default this is a 'contains' test. For equality, set strict to + true. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute + name="isEquals" + type="xs:boolean" + use="optional" + default="false"> + xs:annotation + xs:documentation + If true perform equality test. If false (default) perform a contains test. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute + name="isCaseSensitive" + type="xs:boolean" + use="optional" + default="false"> + xs:annotation + xs:documentation + If true perform a case sensitive test. If false (default) test is sase insensitive. + </xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:complexType> + + <xs:element + name="position" + type="perspective:PositionType"> + xs:annotation + xs:appinfo + <jaxb:class + name="PerspectivePositionElement" /> + </xs:appinfo> + </xs:annotation> + </xs:element> + + <xs:complexType + name="PositionType"> + <xs:attribute + name="extensionPoint" + type="perspective:ExtensionPointNameType" + use="required"> + xs:annotation + xs:documentation + The extension point (a menu, resource tab bar, etc) where the insertion is occuring. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute + name="name" + type="perspective:NameType" + use="optional"> + xs:annotation + xs:documentation + Position relatively against this name. Required for before/after positioning. + The name is + context specific, it could be a + menu entry name, a menu item name, tab name, subTab name, etc. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute + name="placement" + type="perspective:PlacementType" + use="required"> + </xs:attribute> + </xs:complexType> + + <xs:simpleType + name="ActionType"> + xs:annotation + xs:documentation + Add : Add new or Replaces existing + Remove : Removes existing + </xs:documentation> + </xs:annotation> + <xs:restriction + base="xs:string"> + <xs:enumeration + value="add"></xs:enumeration> + <xs:enumeration + value="remove"></xs:enumeration> + </xs:restriction> + </xs:simpleType> + + <xs:simpleType + name="DescriptionType"> + <xs:restriction + base="xs:string"> + <xs:minLength + value="1" /> + <xs:maxLength + value="512" /> + </xs:restriction> + </xs:simpleType> + + <xs:simpleType + name="DisplayNameType"> + <xs:restriction + base="xs:string"> + <xs:minLength + value="1" /> + <xs:maxLength + value="128" /> + </xs:restriction> + </xs:simpleType> + + <xs:simpleType + name="ExtensionPointNameType"> + <xs:restriction + base="xs:string"> + <xs:minLength + value="1" /> + <xs:maxLength + value="128" /> + </xs:restriction> + </xs:simpleType> + + <xs:simpleType + name="HelpTextType"> + <xs:restriction + base="xs:string"> + <xs:minLength + value="1" /> + <xs:maxLength + value="1024" /> + </xs:restriction> + </xs:simpleType> + + <xs:simpleType + name="MenuItemFeatureType"> + <xs:restriction + base="xs:string"> + <xs:enumeration + value="aboutBox"></xs:enumeration> + <xs:enumeration + value="groupFavorites"></xs:enumeration> + <xs:enumeration + value="groupRecentlyViewed"></xs:enumeration> + <xs:enumeration + value="groupSearch"></xs:enumeration> + <xs:enumeration + value="resourceFavorites"></xs:enumeration> + <xs:enumeration + value="resourceRecentlyViewed"></xs:enumeration> + <xs:enumeration + value="resourceSearch"></xs:enumeration> + <xs:enumeration + value="newWindow"></xs:enumeration> + <xs:enumeration + value="resourceSearch"></xs:enumeration> + </xs:restriction> + </xs:simpleType> + + <xs:simpleType + name="NameType"> + <xs:restriction + base="xs:string"> + <xs:minLength + value="1" /> + <xs:maxLength + value="64" /> + </xs:restriction> + </xs:simpleType> + + <xs:simpleType + name="PermissionType"> + <xs:restriction + base="xs:string"> + <xs:enumeration + value="MANAGE_INVENTORY"></xs:enumeration> + <xs:enumeration + value="MANAGE_SECURITY"></xs:enumeration> + <xs:enumeration + value="MANAGE_SETTINGS"></xs:enumeration> + + <xs:enumeration + value="CONFIGURE"></xs:enumeration> + <xs:enumeration + value="CONTROL"></xs:enumeration> + <xs:enumeration + value="CREATE_CHILD_RESOURCE"></xs:enumeration> + <xs:enumeration + value="DELETE_RESOURCE"></xs:enumeration> + <xs:enumeration + value="MANAGE_ALERTS"></xs:enumeration> + <xs:enumeration + value="MANAGE_CONTENT"></xs:enumeration> + <xs:enumeration + value="MANAGE_MEASUREMENTS"></xs:enumeration> + <xs:enumeration + value="MODIFY_RESOURCE"></xs:enumeration> + <xs:enumeration + value="VIEW_RESOURCE"></xs:enumeration> + </xs:restriction> + </xs:simpleType> + + <xs:simpleType + name="PlacementType"> + <xs:restriction + base="xs:string"> + <xs:enumeration + value="before"></xs:enumeration> + <xs:enumeration + value="after"></xs:enumeration> + <xs:enumeration + value="start"></xs:enumeration> + <xs:enumeration + value="end"></xs:enumeration> + </xs:restriction> + </xs:simpleType> +
</xs:schema> diff --git a/modules/enterprise/server/xml-schemas/src/test/resources/test-serverplugin-perspective.xml b/modules/enterprise/server/xml-schemas/src/test/resources/test-serverplugin-perspective.xml index f39a1b6..ac01d06 100644 --- a/modules/enterprise/server/xml-schemas/src/test/resources/test-serverplugin-perspective.xml +++ b/modules/enterprise/server/xml-schemas/src/test/resources/test-serverplugin-perspective.xml @@ -1,15 +1,14 @@ <?xml version="1.0" encoding="UTF-8"?>
-<perspective-plugin +<perspectivePlugin apiVersion="1.0" version="1.0" description="A Sample Perspective Utilizing Every Extension Point and Filter" displayName="Sample Perspective" name="SamplePerspective" package="org.rhq.perspective.sample" - pluginLifecycleListener="perspectivePluginLifecycleListener" xmlns="urn:xmlns:rhq-serverplugin.perspective" xmlns:serverplugin="urn:xmlns:rhq-serverplugin" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance%22%3E
-</perspective-plugin> +</perspectivePlugin>
commit 246c743e9d836ca0bede72fb0adf09f8881a834c Author: Jay Shaughnessy jshaughn@redhat.com Date: Mon Nov 16 09:10:34 2009 -0500
Obsolete stuff from old perspctives investigation.
diff --git a/modules/enterprise/server/jar/src/main/resources/perspectives/admin.xml b/modules/enterprise/server/jar/src/main/resources/perspectives/admin.xml deleted file mode 100644 index eb29b5a..0000000 --- a/modules/enterprise/server/jar/src/main/resources/perspectives/admin.xml +++ /dev/null @@ -1,5 +0,0 @@ -<perspective name="admin" path="/admin" - description="platform administration tasks" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xmlns="urn:xmlns:rhq-perspective"> -</perspective> \ No newline at end of file diff --git a/modules/enterprise/server/jar/src/main/resources/perspectives/content.xml b/modules/enterprise/server/jar/src/main/resources/perspectives/content.xml deleted file mode 100644 index ec9d159..0000000 --- a/modules/enterprise/server/jar/src/main/resources/perspectives/content.xml +++ /dev/null @@ -1,29 +0,0 @@ -<perspective name="content" path="/pulp" - description="advanced software content management" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xmlns="urn:xmlns:rhq-perspective"> - <task name="repo create" path="/pulp/repos/create" - description="Create Repo"> - <pathmatches>/pulp/repos</pathmatches> - <pathmatches>/pulp/repos/create</pathmatches> - <pathmatches>/pulp/repos/create_confirm</pathmatches> - <pathmatches>/pulp/repos/create*</pathmatches> - </task> - <task name="repo add package" - path="/pulp/repos/add_package?cid={0}" - description="Add Content to this Repo" context="repo"> - <pathmatches>/pulp/repos/details/*</pathmatches> - </task> - <task name="repo clone" path="/pulp/repos/clone" - description="Clone A Repo"> - <pathmatches>/pulp/repos/*</pathmatches> - </task> - <task name="repo clone existing" path="/pulp/repos/clone?cid={0}" - description="Clone this Repo" context="repo"> - <pathmatches>/pulp/repos/*</pathmatches> - </task> - <task name="repo delete" path="/pulp/repos/delete" - description="Delete A repo"> - <pathmatches>/pulp/repos/*</pathmatches> - </task> -</perspective> \ No newline at end of file diff --git a/modules/enterprise/server/jar/src/main/resources/perspectives/middleware.xml b/modules/enterprise/server/jar/src/main/resources/perspectives/middleware.xml deleted file mode 100644 index 0d0c9e8..0000000 --- a/modules/enterprise/server/jar/src/main/resources/perspectives/middleware.xml +++ /dev/null @@ -1,5 +0,0 @@ -<perspective name="middleware" path="/middleware" - description="manage middleware applications" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xmlns="urn:xmlns:rhq-perspective"> -</perspective> diff --git a/modules/enterprise/server/jar/src/main/resources/perspectives/root.xml b/modules/enterprise/server/jar/src/main/resources/perspectives/root.xml deleted file mode 100644 index e222b25..0000000 --- a/modules/enterprise/server/jar/src/main/resources/perspectives/root.xml +++ /dev/null @@ -1,5 +0,0 @@ -<perspective name="root" path="/" - description="start here" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xmlns="urn:xmlns:rhq-perspective"> -</perspective> \ No newline at end of file
commit ce32637f2997a499b9bbe9e2629c658d9dcb8e31 Author: Jay Shaughnessy jshaughn@redhat.com Date: Mon Nov 23 10:28:37 2009 -0500
more perspective descriptor schema tweaks
diff --git a/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-perspective.xsd b/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-perspective.xsd index b6fabfd..0ddd9b5 100644 --- a/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-perspective.xsd +++ b/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-perspective.xsd @@ -228,7 +228,8 @@ <xs:attribute name="action" type="perspective:ActionType" - use="optional"> + use="optional" + default="add"> xs:annotation xs:documentation Add or remove the menu entry. For removal all but the name attribute are ignored. @@ -342,7 +343,8 @@ <xs:attribute name="action" type="perspective:ActionType" - use="optional"> + use="optional" + default="add"> xs:annotation xs:documentation Add or remove the menu entry. Add is the default. @@ -401,7 +403,8 @@ <xs:attribute name="action" type="perspective:ActionType" - use="optional"> + use="optional" + default="add"> xs:annotation xs:documentation Add or remove the menu entry. Add is the default. @@ -581,6 +584,12 @@ type="perspective:PlacementType" use="required"> </xs:attribute> + <xs:attribute + name="break" + type="xs:boolean" + use="optional" + default="false"> + </xs:attribute> </xs:complexType>
<xs:simpleType @@ -616,7 +625,7 @@ <xs:restriction base="xs:string"> <xs:minLength - value="1" /> + value="0" /> <xs:maxLength value="128" /> </xs:restriction>
commit bcaecd83a38c03d4cf98f1a287b96778c49162af Author: Jay Shaughnessy jshaughn@redhat.com Date: Mon Nov 23 10:27:30 2009 -0500
Add core perspective to rhq.ear
diff --git a/modules/enterprise/server/ear/pom.xml b/modules/enterprise/server/ear/pom.xml index ac874e9..dfce882 100644 --- a/modules/enterprise/server/ear/pom.xml +++ b/modules/enterprise/server/ear/pom.xml @@ -399,6 +399,12 @@ <version>${project.version}</version> </artifactItem>
+ <artifactItem> + <groupId>org.rhq</groupId> + <artifactId>rhq-core-perspective</artifactId> + <version>${project.version}</version> + </artifactItem> + <!-- Temporary Sample Perspective --> <artifactItem> <groupId>org.rhq</groupId>
commit 3a7d95f1bd0790c2a549255b11cd170afedfed48 Author: Jay Shaughnessy jshaughn@redhat.com Date: Mon Nov 23 10:26:42 2009 -0500
conforming to schema change
diff --git a/etc/samples/perspectives/sample-perspective/perspective/src/main/resources/META-INF/rhq-serverplugin.xml b/etc/samples/perspectives/sample-perspective/perspective/src/main/resources/META-INF/rhq-serverplugin.xml index 490ae03..36430f3 100644 --- a/etc/samples/perspectives/sample-perspective/perspective/src/main/resources/META-INF/rhq-serverplugin.xml +++ b/etc/samples/perspectives/sample-perspective/perspective/src/main/resources/META-INF/rhq-serverplugin.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8" ?>
-<perspective-plugin +<perspectivePlugin apiVersion="1.0" version="1.0" description="A Sample Perspective Utilizing Every Extension Point and Filter" @@ -11,4 +11,4 @@ xmlns:serverplugin="urn:xmlns:rhq-serverplugin" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance%22%3E
-</perspective-plugin> \ No newline at end of file +</perspectivePlugin> \ No newline at end of file
commit 85e904f544bf0e1d4b4bdf818f51757c3a7fd363 Merge: 5d70557... 866e687... Author: John Sanda john@localhost.localdomain Date: Mon Nov 23 09:44:38 2009 -0500
Merge branch 'raw-config' of ssh://git.fedorahosted.org/git/rhq/rhq into raw-config
commit 5d70557ee7d45a3caffb31e626e6318045336240 Author: John Sanda john@localhost.localdomain Date: Mon Nov 23 09:40:07 2009 -0500
[US 6] Adding unit tests for existing resource configuration update code
Initial commit for ConfigurationUpdateResponseMatcher. Getting UpdateResourceConfigurationRunner under test has been a bit cumbersome because the collaborators that it calls (ConfigurationFacet and ConfigurationServerService) produce side effects on the arguments that they receive instead of returning values.
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationUpdateService.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationUpdateService.java deleted file mode 100644 index bdafc4b..0000000 --- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationUpdateService.java +++ /dev/null @@ -1,8 +0,0 @@ -package org.rhq.core.pc.configuration; - -/** - * Created by IntelliJ IDEA. User: john Date: Nov 12, 2009 Time: 4:37:07 PM To change this template use File | Settings - * | File Templates. - */ -public interface ConfigurationUpdateService { -} diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/UpdateLegacyConfig.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/UpdateLegacyConfig.java deleted file mode 100644 index 4039310..0000000 --- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/UpdateLegacyConfig.java +++ /dev/null @@ -1,8 +0,0 @@ -package org.rhq.core.pc.configuration; - -/** - * Created by IntelliJ IDEA. User: john Date: Nov 12, 2009 Time: 4:33:27 PM To change this template use File | Settings - * | File Templates. - */ -public interface UpdateLegacyConfig { -} diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/UpdateResourceConfigurationRunner.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/UpdateResourceConfigurationRunner.java index fbb84e3..c93485b 100644 --- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/UpdateResourceConfigurationRunner.java +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/UpdateResourceConfigurationRunner.java @@ -1,25 +1,25 @@ /* - * RHQ Management Platform - * Copyright (C) 2005-2008 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, version 2, as - * published by the Free Software Foundation, and/or the GNU Lesser - * General Public License, version 2.1, also as published by the Free - * Software Foundation. - * - * 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 and the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * and the GNU Lesser 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. - */ + * RHQ Management Platform + * Copyright (C) 2005-2008 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, version 2, as + * published by the Free Software Foundation, and/or the GNU Lesser + * General Public License, version 2.1, also as published by the Free + * Software Foundation. + * + * 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 and the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * and the GNU Lesser 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.core.pc.configuration;
import java.util.List; @@ -67,6 +67,8 @@ public class UpdateResourceConfigurationRunner implements Runnable, Callable<Con */ private ConfigurationServerService configurationServerService;
+ private ConfigurationUtilityService configUtilService = new ConfigurationUtilityServiceImpl(); + public UpdateResourceConfigurationRunner(ConfigurationServerService configurationServerService, ResourceType type, ConfigurationFacet facet, ConfigurationUpdateRequest request) { this.configurationServerService = configurationServerService; // may be null @@ -75,6 +77,10 @@ public class UpdateResourceConfigurationRunner implements Runnable, Callable<Con this.request = request; }
+ void setConfigUtilService(ConfigurationUtilityService service) { + configUtilService = service; + } + public void run() { try { call(); @@ -100,8 +106,8 @@ public class UpdateResourceConfigurationRunner implements Runnable, Callable<Con ConfigurationDefinition configurationDefinition = resourceType.getResourceConfigurationDefinition();
// Normalize and validate the config. - ConfigurationUtility.normalizeConfiguration(response.getConfiguration(), configurationDefinition); - List<String> errorMessages = ConfigurationUtility.validateConfiguration(response.getConfiguration(), + configUtilService.normalizeConfiguration(response.getConfiguration(), configurationDefinition); + List<String> errorMessages = configUtilService.validateConfiguration(response.getConfiguration(), configurationDefinition); for (String errorMessage : errorMessages) { log.warn("Plugin Error: Invalid " + resourceType.getName() + " Resource configuration returned by " diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigurationUpdateResponseMatcher.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigurationUpdateResponseMatcher.java new file mode 100644 index 0000000..74bca9b --- /dev/null +++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigurationUpdateResponseMatcher.java @@ -0,0 +1,64 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2008 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, version 2, as + * published by the Free Software Foundation, and/or the GNU Lesser + * General Public License, version 2.1, also as published by the Free + * Software Foundation. + * + * 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 and the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * and the GNU Lesser 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.core.pc.configuration; + +import org.hamcrest.Description; +import org.hamcrest.Matcher; +import org.hamcrest.TypeSafeMatcher; +import org.rhq.core.clientapi.server.configuration.ConfigurationUpdateResponse; + +public class ConfigurationUpdateResponseMatcher extends TypeSafeMatcher<ConfigurationUpdateResponse> { + + public static Matcher<ConfigurationUpdateResponse> matchingResponse(ConfigurationUpdateResponse expected) { + return new ConfigurationUpdateResponseMatcher(expected); + } + + private ConfigurationUpdateResponse expected; + + public ConfigurationUpdateResponseMatcher(ConfigurationUpdateResponse response) { + expected = response; + } + + public boolean matchesSafely(ConfigurationUpdateResponse actual) { + return propertyEquals(expected.getConfiguration(), actual.getConfiguration()) && + propertyEquals(expected.getConfigurationUpdateId(), actual.getConfigurationUpdateId()) && + propertyEquals(expected.getErrorMessage(), actual.getErrorMessage()) && + propertyEquals(expected.getStatus(), actual.getStatus()); + } + + private boolean propertyEquals(Object expected, Object actual) { + if (expected == null && actual == null) { + return true; + } + + if (expected == null && actual != null) { + return false; + } + return expected.equals(actual); + } + + public void describeTo(Description description) { + description.appendText(expected.toString()); + } +} diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/JMockTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/JMockTest.java index 4f95f42..e6e9422 100644 --- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/JMockTest.java +++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/JMockTest.java @@ -23,11 +23,11 @@
package org.rhq.core.pc.configuration;
-import org.testng.IHookable; +import org.jmock.Mockery; import org.testng.IHookCallBack; +import org.testng.IHookable; import org.testng.ITestResult; import org.testng.annotations.BeforeMethod; -import org.jmock.Mockery;
public class JMockTest implements IHookable {
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/UpdateResourceConfigurationRunnerTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/UpdateResourceConfigurationRunnerTest.java new file mode 100644 index 0000000..392130b --- /dev/null +++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/UpdateResourceConfigurationRunnerTest.java @@ -0,0 +1,187 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2008 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, version 2, as + * published by the Free Software Foundation, and/or the GNU Lesser + * General Public License, version 2.1, also as published by the Free + * Software Foundation. + * + * 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 and the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * and the GNU Lesser 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.core.pc.configuration; + +import static org.rhq.core.pc.configuration.ConfigurationUpdateResponseMatcher.*; +import static org.rhq.core.domain.configuration.ConfigurationUpdateStatus.*; + +import org.testng.annotations.Test; +import org.rhq.core.clientapi.server.configuration.ConfigurationServerService; +import org.rhq.core.clientapi.server.configuration.ConfigurationUpdateResponse; +import org.rhq.core.clientapi.agent.configuration.ConfigurationUpdateRequest; +import org.rhq.core.domain.configuration.Configuration; +import org.rhq.core.domain.configuration.ConfigurationUpdateStatus; +import org.rhq.core.pluginapi.configuration.ConfigurationFacet; +import org.rhq.core.pluginapi.configuration.ConfigurationUpdateReport; +import org.jmock.Expectations; +import org.jmock.api.Action; +import org.jmock.api.Invocation; +import org.hamcrest.Description; + +public class UpdateResourceConfigurationRunnerTest extends ConfigManagementTest { + + @Test + public void successfulUpdateShouldSendSuccessResponseToServer() throws Exception { + final Configuration config = createStructuredConfig(); + + final ConfigurationServerService configServerService = context.mock(ConfigurationServerService.class); + + final ConfigurationFacet facet = context.mock(ConfigurationFacet.class); + + final ConfigurationUtilityService configUtilService = context.mock(ConfigurationUtilityService.class); + + int configUpdateId = -1; + + ConfigurationUpdateRequest updateRequest = new ConfigurationUpdateRequest(configUpdateId, config, resourceId); + + UpdateResourceConfigurationRunner updateRunner = new UpdateResourceConfigurationRunner(configServerService, + resourceType, facet, updateRequest); + updateRunner.setConfigUtilService(configUtilService); + + final ConfigurationUpdateResponse successResponse = new ConfigurationUpdateResponse(configUpdateId, null, + SUCCESS, null); + + context.checking(new Expectations() {{ + oneOf(facet).updateResourceConfiguration(with(any(ConfigurationUpdateReport.class))); + will(updateReportTo(SUCCESS)); + + oneOf(configUtilService).normalizeConfiguration(config, resourceType.getResourceConfigurationDefinition()); + oneOf(configUtilService).validateConfiguration(config, resourceType.getResourceConfigurationDefinition()); + + oneOf(configServerService).completeConfigurationUpdate(with(matchingResponse(successResponse))); + }}); + + updateRunner.call(); + } + + @Test + public void inProgressUpdateShouldSendFailureResponseToServer() throws Exception { + final Configuration config = createStructuredConfig(); + + final ConfigurationServerService configServerService = context.mock(ConfigurationServerService.class); + + final ConfigurationFacet facet = context.mock(ConfigurationFacet.class); + + final ConfigurationUtilityService configUtilService = context.mock(ConfigurationUtilityService.class); + + int configUpdateId = -1; + + ConfigurationUpdateRequest updateRequest = new ConfigurationUpdateRequest(configUpdateId, config, resourceId); + + UpdateResourceConfigurationRunner updateRunner = new UpdateResourceConfigurationRunner(configServerService, + resourceType, facet, updateRequest); + updateRunner.setConfigUtilService(configUtilService); + + String errorMsg = "Configuration facet did not indicate success or failure - assuming failure."; + + final ConfigurationUpdateResponse failureResponse = new ConfigurationUpdateResponse(configUpdateId, config, + FAILURE, errorMsg); + + context.checking(new Expectations() {{ + oneOf(facet).updateResourceConfiguration(with(any(ConfigurationUpdateReport.class))); + will(updateReportTo(INPROGRESS)); + + oneOf(configUtilService).normalizeConfiguration(config, resourceType.getResourceConfigurationDefinition()); + oneOf(configUtilService).validateConfiguration(config, resourceType.getResourceConfigurationDefinition()); + + oneOf(configServerService).completeConfigurationUpdate(with(matchingResponse(failureResponse))); + }}); + + updateRunner.call(); + } + + @Test + public void failureResponseShouldBeSentToServerWhenFacetThrowsAnException() throws Exception { + final Configuration config = createStructuredConfig(); + + final ConfigurationServerService configServerService = context.mock(ConfigurationServerService.class); + + final ConfigurationFacet facet = context.mock(ConfigurationFacet.class); + + int configUpdateId = -1; + + ConfigurationUpdateRequest updateRequest = new ConfigurationUpdateRequest(configUpdateId, config, resourceId); + + UpdateResourceConfigurationRunner updateRunner = new UpdateResourceConfigurationRunner(configServerService, + resourceType, facet, updateRequest); + + final NullPointerException exception = new NullPointerException("Unexpected error during update"); + + final ConfigurationUpdateResponse failureResponse = new ConfigurationUpdateResponse(configUpdateId, config, + exception); + + context.checking(new Expectations() {{ + oneOf(facet).updateResourceConfiguration(with(any(ConfigurationUpdateReport.class))); + will(throwExceptionFromFacet(exception)); + + oneOf(configServerService).completeConfigurationUpdate(with(matchingResponse(failureResponse))); + }}); + + updateRunner.call(); + } + + public static Action updateReportTo(ConfigurationUpdateStatus status) { + return new UpdateResourceConfigurationAction(status); + } + + public static Action throwExceptionFromFacet(Throwable t) { + return new ThrowFacetExceptionAction(t); + } + + static class UpdateResourceConfigurationAction implements Action { + ConfigurationUpdateStatus status; + + public UpdateResourceConfigurationAction(ConfigurationUpdateStatus status) { + this.status = status; + } + + public void describeTo(Description description) { + description.appendText("Updating status of " + ConfigurationUpdateReport.class.getSimpleName() + " to " + + status); + } + + public Object invoke(Invocation invocation) throws Throwable { + ConfigurationUpdateReport report = (ConfigurationUpdateReport) invocation.getParameter(0); + report.setStatus(status); + return null; + } + } + + static class ThrowFacetExceptionAction implements Action { + Throwable throwable; + + public ThrowFacetExceptionAction(Throwable t) { + throwable = t; + } + + public void describeTo(Description description) { + description.appendText("throws <" + throwable.getClass().getName() + ">: " + throwable.getMessage()); + } + + public Object invoke(Invocation invocation) throws Throwable { + throw throwable; + } + } + +}
commit f55fdc2662c75544f370a4e8d37ab6ce8ed2dd0d Author: Jay Shaughnessy jshaughn@redhat.com Date: Fri Nov 20 22:23:28 2009 -0500
Add Core perspective to build
diff --git a/modules/enterprise/server/plugins/pom.xml b/modules/enterprise/server/plugins/pom.xml index a3331db..dc2c402 100644 --- a/modules/enterprise/server/plugins/pom.xml +++ b/modules/enterprise/server/plugins/pom.xml @@ -39,6 +39,7 @@ <module>yum</module> <module>url</module> <module>rhnhosted</module> + <module>perspectives/core</module> <!-- temporary sample perspective plugin --> <module>../../../../etc/samples/perspectives/sample-perspective</module> </modules>
commit 8cab3e9ae416eac6ef3c4abc3c9917eb7bb9edc0 Author: Jay Shaughnessy jshaughn@redhat.com Date: Fri Nov 20 22:22:51 2009 -0500
New Core Perspective defining CoreUI extensions
diff --git a/modules/enterprise/server/plugins/perspectives/core/perspective/pom.xml b/modules/enterprise/server/plugins/perspectives/core/perspective/pom.xml new file mode 100644 index 0000000..e8dfec7 --- /dev/null +++ b/modules/enterprise/server/plugins/perspectives/core/perspective/pom.xml @@ -0,0 +1,62 @@ +<?xml version="1.0"?> + +<project + xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd%22%3E + + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.rhq</groupId> + <artifactId>rhq-parent</artifactId> + <version>1.4.0-SNAPSHOT</version> + </parent> + + <groupId>org.rhq</groupId> + <artifactId>rhq-core-perspective</artifactId> + <packaging>jar</packaging> + + <name>RHQ Core Perspective</name> + <description>A Perspective defining Core UI Elements</description> + + <properties> + <rhq.version>1.4.0-SNAPSHOT</rhq.version> + </properties> + + <dependencies> + + <!-- Below are the core modules that are required dependencies of all server plugins --> + <dependency> + <groupId>org.rhq</groupId> + <artifactId>rhq-enterprise-server</artifactId> + <version>${rhq.version}</version> + <scope>provided</scope> <!-- provided by the server/plugin-container --> + </dependency> + + <!-- uncomment the one of the three logging systems your plugin uses: log4j, commons-logging or i18nlog --> + <!-- all three are provided to your plugin by the server/plugin-container --> + <!-- + <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.14</version> + <scope>provided</scope> </dependency> + --> + + <!-- + <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.1</version> + <scope>provided</scope> </dependency> + --> + + <!-- + <dependency> <groupId>i18nlog</groupId> <artifactId>i18nlog</artifactId> <version>1.0.9</version> </dependency> + --> + + <!-- Define any third-party dependencies your plugin has here. --> + <!-- + <dependency> <groupId>group-id-of-dependency-goes-here</groupId> + <artifactId>artifact-id-of-dependency-goes-here</artifactId> <version>version-of-dependency-goes-here</version> + </dependency> + --> + + </dependencies> + +</project> diff --git a/modules/enterprise/server/plugins/perspectives/core/perspective/src/main/resources/META-INF/rhq-serverplugin.xml b/modules/enterprise/server/plugins/perspectives/core/perspective/src/main/resources/META-INF/rhq-serverplugin.xml new file mode 100644 index 0000000..63e1746 --- /dev/null +++ b/modules/enterprise/server/plugins/perspectives/core/perspective/src/main/resources/META-INF/rhq-serverplugin.xml @@ -0,0 +1,506 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<perspectivePlugin + version="1.0" + apiVersion="2.0" + description="The Core Perspective defining Core UI Elements" + displayName="Core Perspective" + name="CorePerspective" + package="org.rhq.perspective.core" + xmlns="urn:xmlns:rhq-serverplugin.perspective" + xmlns:serverplugin="urn:xmlns:rhq-serverplugin" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance%22%3E + + <!-- Core Menu --> + <menuItem + name="logo" + displayName="" + url="/" + iconUrl="/images/JBossLogo_small.png"> + <position + extensionPoint="coreMenu" + placement="start" /> + </menuItem> + <menuItem + name="overview" + displayName="Overview"> + <position + extensionPoint="coreMenu" + name="logo" + placement="after" /> + </menuItem> + <menuItem + name="resources" + displayName="Resources"> + <position + extensionPoint="coreMenu" + name="overview" + placement="after" /> + </menuItem> + <menuItem + name="groups" + displayName="Groups"> + <position + extensionPoint="coreMenu" + name="resources" + placement="after" /> + </menuItem> + <menuItem + name="administration" + displayName="Administration"> + <position + extensionPoint="coreMenu" + name="groups" + placement="after" /> + </menuItem> + <menuItem + name="help" + displayName="Help"> + <position + extensionPoint="coreMenu" + name="administration" + placement="after" /> + </menuItem> + + + <!-- Core Menu: Overview --> + <menuItem + name="overview.subsystemViews" + displayName="Subsystem Views"> + <position + extensionPoint="coreMenu" + name="overview" + placement="start" /> + </menuItem> + <menuItem + name="overview.autoDiscoveryQueue" + displayName="Auto Discovery Queue" + url="/rhq/discovery/queue.xhtml"> + <position + extensionPoint="coreMenu" + name="overview.subsystemViews" + placement="after" /> + </menuItem> + <menuItem + name="overview.dashboard" + displayName="Dashboard" + url="/Dashboard.do"> + <position + extensionPoint="coreMenu" + name="overview.autoDiscoveryQueue" + placement="after" /> + </menuItem> + + <!-- Core Menu: Resources --> + <menuItem + name="resources.platforms" + displayName="Platforms" + iconUrl="/images/icons/Platform_up_16.png" + url="/ResourceHub.do?resourceCategory=PLATFORM"> + <position + extensionPoint="coreMenu" + name="resources" + placement="start" /> + </menuItem> + <menuItem + name="resources.servers" + displayName="Servers" + iconUrl="/images/icons/Server_up_16.png" + url="/ResourceHub.do?resourceCategory=SERVER"> + <position + extensionPoint="coreMenu" + name="resources.platforms" + placement="after" /> + </menuItem> + <menuItem + name="resources.services" + displayName="Services" + iconUrl="/images/icons/Service_up_16.png" + url="/ResourceHub.do?resourceCategory=SERVICE"> + <position + extensionPoint="coreMenu" + name="resources.platforms" + placement="after" /> + </menuItem> + <menuItem + name="resources.favoriteResources" + displayName="Favorite Resources" + feature="resourceFavorites" + iconUrl="/images/icons/Favorite_16.png"> + <position + extensionPoint="coreMenu" + name="resources.services" + placement="after" /> + </menuItem> + <menuItem + name="resources.recentlyViewedResources" + displayName="Recently Viewed Resources" + feature="resourceRecentlyViewed" + iconUrl="/images/icons/History_16.png"> + <position + extensionPoint="coreMenu" + name="resources.favoriteResources" + placement="after" /> + </menuItem> + <menuItem + name="resources.search" + displayName="Search:" + feature="resourceSearch" + iconUrl="/images/icons/Search_16.png"> + <position + extensionPoint="coreMenu" + name="resources.recentlyViewedResources" + placement="after" + break="true" /> + </menuItem> + + <!-- Core Menu: Groups --> + <menuItem + name="groups.compatibleGroups" + displayName="Compatible Groups" + iconUrl="images/icons/Cluster_up_16.png" + url="/GroupHub.do?groupCategory=COMPATIBLE"> + <position + extensionPoint="coreMenu" + name="groups" + placement="start" /> + </menuItem> + <menuItem + name="groups.mixedGroups" + displayName="Mixed Groups" + iconUrl="/images/icons/Group_up_16.png" + url="/GroupHub.do?groupCategory=MIXED"> + <position + extensionPoint="coreMenu" + name="groups.compatibleGroups" + placement="after" /> + </menuItem> + <menuItem + name="groups.groupDefinitions" + displayName="Group Definitions" + iconUrl="/images/GroupDefinition_16.png" + url="/rhq/definition/group/list.xhtml"> + <position + extensionPoint="coreMenu" + name="groups.mixedGroups" + placement="after" /> + </menuItem> + <menuItem + name="groups.newGroup" + displayName="New Group" + url="/resource/group/Inventory.do?mode=new"> + <position + extensionPoint="coreMenu" + name="groups.groupDefinitions" + placement="after" + break="true" /> + </menuItem> + <menuItem + name="groups.newGroupDefinition" + displayName="New Group Definition" + url="/rhq/definition/group/new.xhtml"> + <position + extensionPoint="coreMenu" + name="groups.newGroup" + placement="after" /> + </menuItem> + <menuItem + name="groups.favoriteGroups" + displayName="Favorite Groups" + feature="groupFavorites" + iconUrl="/images/icons/Favorite_16.png"> + <position + extensionPoint="coreMenu" + name="groups.newGroupDefinition" + placement="after" + break="true" /> + </menuItem> + <menuItem + name="groups.recentlyViewedGroups" + displayName="Recently Viewed Groups" + feature="groupRecentlyViewed" + iconUrl="/images/icons/History_16.png"> + <position + extensionPoint="coreMenu" + name="groups.favoriteGroups" + placement="after" /> + </menuItem> + <menuItem + name="groups.search" + displayName="Search:" + feature="groupSearch" + iconUrl="/images/icons/Search_16.png"> + <position + extensionPoint="coreMenu" + name="groups.recentlyViewedGroups" + placement="after" + break="true" /> + </menuItem> + + <!-- Core Menu: Administration --> + <menuItem + name="administration.security" + displayName="Security"> + <position + extensionPoint="coreMenu" + name="administration" + placement="start" /> + </menuItem> + <menuItem + name="administration.systemConfiguration" + displayName="systemConfiguration"> + <position + extensionPoint="coreMenu" + name="administration.security" + placement="after" /> + </menuItem> + <menuItem + name="administration.content" + displayName="Content"> + <position + extensionPoint="coreMenu" + name="administration.systemConfiguration" + placement="after" /> + </menuItem> + <menuItem + name="administration.highAvailability" + displayName="High Availability"> + <position + extensionPoint="coreMenu" + name="administration.content" + placement="after" /> + </menuItem> + <menuItem + name="administration.reports" + displayName="Reports"> + <position + extensionPoint="coreMenu" + name="administration.highAvailability" + placement="after" /> + </menuItem> + <menuItem + name="administration.download" + displayName="Download" + iconUrl="/images/icons/Save_16.png" + url="/rhq/admin/downloads.xhtml"> + <position + extensionPoint="coreMenu" + name="administration.reports" + placement="after" /> + </menuItem> + <menuItem + name="administration.license" + displayName="License" + url="/admin/license/LicenseAdmin.do?mode=view"> + <position + extensionPoint="coreMenu" + name="administration.download" + placement="after" /> + </menuItem> + + <!-- Core Menu: Help --> + <menuItem + name="help.onlineDocumentation" + displayName="Online Documentation" + feature="newWindow" + url="http://www.redhat.com/docs/en-US/JBoss_ON/%22%3E + <position + extensionPoint="coreMenu" + name="help" + placement="start" /> + </menuItem> + <menuItem + name="help.openASupportCase" + displayName="Open a Support Case" + feature="newWindow" + url="https://support.redhat.com/jbossnetwork/restricted/addCase.html%22%3E + <position + extensionPoint="coreMenu" + name="help.onlineDocumentation" + placement="after" /> + </menuItem> + <menuItem + name="help.about" + displayName="About" + feature="aboutBox" + iconUrl="/images/icons/availability_grey_16.png"> + <position + extensionPoint="coreMenu" + name="help.openASupportCase" + placement="after" + break="true" /> + </menuItem> + + <!-- Core Menu: Overview.Subsystem Views --> + <menuItem + name="overview.subsystemViews.configurationChanges" + displayName="Configuration Changes" + iconUrl="/images/icons/Configure_16.png" + url="/rhq/subsystem/configurationUpdate.xhtml"> + <position + extensionPoint="coreMenu" + name="overview.subsystemViews" + placement="start" /> + </menuItem> + <menuItem + name="overview.subsystemViews.suspectMetrics" + displayName="suspectMetrics" + iconUrl="/images/icons/Monitor_failed_16.png" + url="/rhq/subsystem/oobHistory.xhtml"> + <position + extensionPoint="coreMenu" + name="overview.subsystemViews.configurationChanges" + placement="after" /> + </menuItem> + <menuItem + name="overview.subsystemViews.operations" + displayName="Operations" + iconUrl="/images/icons/Operation_16.png" + url="/rhq/subsystem/operationHistory.xhtml"> + <position + extensionPoint="coreMenu" + name="overview.subsystemViews.suspectMetrics" + placement="after" /> + </menuItem> + <menuItem + name="overview.subsystemViews.alerts" + displayName="Alerts" + iconUrl="/images/icons/Flag_blue_16.png" + url="/rhq/subsystem/alertHistory.xhtml"> + <position + extensionPoint="coreMenu" + name="overview.subsystemViews.operations" + placement="after" /> + </menuItem> + <menuItem + name="overview.subsystemViews.alertDefinitions" + displayName="Alert Definitions" + iconUrl="/images/icons/Flag_blue_16.png" + url="/rhq/subsystem/alertDefinitions.xhtml"> + <position + extensionPoint="coreMenu" + name="overview.subsystemViews.alerts" + placement="after" /> + </menuItem> + + <!-- Core Menu: Administration.Security --> + <menuItem + name="administration.security.users" + displayName="Users" + url="/admin/user/UserAdmin.do?mode=list"> + <position + extensionPoint="coreMenu" + name="administration.security" + placement="start" /> + </menuItem> + <menuItem + name="administration.security.roles" + displayName="Roles" + url="/admin/role/RoleAdmin.do?mode=list"> + <position + extensionPoint="coreMenu" + name="administration.security.users" + placement="after" /> + </menuItem> + + <!-- Core Menu: administration.systemConfiguration --> + <menuItem + name="administration.systemConfiguration.settings" + displayName="Settings" + url="/admin/config/Config.do?mode=edit"> + <position + extensionPoint="coreMenu" + name="administration.systemConfiguration" + placement="start" /> + </menuItem> + <menuItem + name="administration.systemConfiguration.plugins" + displayName="Plugins" + url="/rhq/admin/plugin/plugin-list.xhtml"> + <position + extensionPoint="coreMenu" + name="administration.systemConfiguration.settings" + placement="after" /> + </menuItem> + <menuItem + name="administration.systemConfiguration.templates" + displayName="Templates" + url="/admin/config/EditDefaults.do?mode=monitor&viewMode=all"> + <position + extensionPoint="coreMenu" + name="administration.systemConfiguration.plugins" + placement="after" /> + </menuItem> + + <!-- Core Menu: administration.content --> + <menuItem + name="administration.content.contentProviders" + displayName="Content Providers" + url="/rhq/content/listContentProviders.xhtml"> + <position + extensionPoint="coreMenu" + name="administration.content" + placement="start" /> + </menuItem> + <menuItem + name="administration.content.repositories" + displayName="Repositories" + url="/rhq/content/listRepos.xhtml"> + <position + extensionPoint="coreMenu" + name="administration.content.contentProviders" + placement="after" /> + </menuItem> + + <!-- Core Menu: administration.highAvailability --> + <menuItem + name="administration.highAvailability.servers" + displayName="Servers" + url="/rhq/ha/listServers.xhtml"> + <position + extensionPoint="coreMenu" + name="administration.highAvailability" + placement="start" /> + </menuItem> + <menuItem + name="administration.highAvailability.agents" + displayName="Agents" + url="/rhq/ha/listAgents.xhtml"> + <position + extensionPoint="coreMenu" + name="administration.highAvailability.servers" + placement="after" /> + </menuItem> + <menuItem + name="administration.highAvailability.affinityGroups" + displayName="Affinity Groups" + url="/rhq/ha/listAffinityGroups.xhtml"> + <position + extensionPoint="coreMenu" + name="administration.highAvailability.agents" + placement="after" /> + </menuItem> + <menuItem + name="administration.highAvailability.paritionEvents" + displayName="Partition Events" + url="/rhq/ha/listPartitionEvents.xhtml"> + <position + extensionPoint="coreMenu" + name="administration.highAvailability.affinityGroups" + placement="after" /> + </menuItem> + + <!-- Core Menu: administration.reports --> + <menuItem + name="administration.reports.resourceVersionInventoryReport" + displayName="Servers" + url="/rhq/admin/report/resourceInstallReport.xhtml"> + <position + extensionPoint="coreMenu" + name="administration.reports" + placement="start" /> + </menuItem> + + + +</perspectivePlugin> \ No newline at end of file diff --git a/modules/enterprise/server/plugins/perspectives/core/pom.xml b/modules/enterprise/server/plugins/perspectives/core/pom.xml new file mode 100644 index 0000000..01ce0b1 --- /dev/null +++ b/modules/enterprise/server/plugins/perspectives/core/pom.xml @@ -0,0 +1,44 @@ +<project + xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd%22%3E + + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.rhq</groupId> + <artifactId>rhq-parent</artifactId> + <version>1.4.0-SNAPSHOT</version> + </parent> + + <groupId>org.rhq</groupId> + <artifactId>rhq-core-perspective-parent</artifactId> + <packaging>pom</packaging> + + <name>RHQ Core Perspective Parent</name> + <description>parent POM for modules comprising the RHQ Core Perspective</description> + + <scm> + <connection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/modules/enterprise/plugins/perspectives/core</connection> + <developerConnection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/modules/enterprise/plugins/perspectives/core/</developerConnection> + </scm> + + <properties> + <scm.module.path>modules/enterprise/plugins/perspectives/core/</scm.module.path> + </properties> + + <profiles> + + <profile> + <id>default</id> + <activation> + <activeByDefault>true</activeByDefault> + </activation> + <modules> + <module>perspective</module> + </modules> + </profile> + + </profiles> + +</project> \ No newline at end of file
commit 5868ff69cc004122739a493551bda21f1dc5fa1d Author: Jay Shaughnessy jshaughn@redhat.com Date: Fri Nov 20 22:21:01 2009 -0500
Under Construction - Perspective Descriptor
diff --git a/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-perspective.xsd b/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-perspective.xsd index ce586b7..b6fabfd 100644 --- a/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-perspective.xsd +++ b/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-perspective.xsd @@ -1,48 +1,731 @@ <?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
-<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" - xmlns:config="urn:xmlns:rhq-configuration" - xmlns:serverplugin="urn:xmlns:rhq-serverplugin" - xmlns:perspective="urn:xmlns:rhq-serverplugin.perspective" - targetNamespace="urn:xmlns:rhq-serverplugin.perspective" - elementFormDefault="qualified" - jaxb:version="2.0" - xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" blockDefault=""> - - <xs:import namespace="urn:xmlns:rhq-serverplugin" schemaLocation="rhq-serverplugin.xsd" /> - - xs:annotation - xs:documentation - Schema for a Perspective Descriptor. Perspective are deployed as Server Plugins. - </xs:documentation> - xs:appinfo - jaxb:schemaBindings - <jaxb:package name="org.rhq.enterprise.server.xmlschema.generated.serverplugin.perspective" /> - </jaxb:schemaBindings> - </xs:appinfo> - </xs:annotation> - - <xs:element name="perspective-plugin" type="perspective:PerspectivePluginDescriptorType" substitutionGroup="serverplugin:server-plugin"> - xs:annotation - xs:documentation - Defines a Perspective plugin. A Perspective is deployed as a Server Plugin. - The Server Plugin Container (SPC) handles simple lifecycle management for - the deployed plugins (e.g. start, stop). The plugin is otherwise standalone - and can do everything it needs to do without additional help from the SPC. +<xs:schema + xmlns:xs="http://www.w3.org/2001/XMLSchema" + xmlns:config="urn:xmlns:rhq-configuration" + xmlns:serverplugin="urn:xmlns:rhq-serverplugin" + xmlns:perspective="urn:xmlns:rhq-serverplugin.perspective" + targetNamespace="urn:xmlns:rhq-serverplugin.perspective" + elementFormDefault="qualified" + jaxb:version="2.0" + xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" + blockDefault=""> + + <xs:include + schemaLocation=""></xs:include> + <xs:import + namespace="urn:xmlns:rhq-serverplugin" + schemaLocation="rhq-serverplugin.xsd" /> + + xs:annotation + xs:documentation + Schema for a Perspective Descriptor. Perspective are deployed as Server Plugins. + </xs:documentation> + xs:appinfo + jaxb:schemaBindings + <jaxb:package + name="org.rhq.enterprise.server.xmlschema.generated.serverplugin.perspective" /> + </jaxb:schemaBindings> + </xs:appinfo> + </xs:annotation> + + <xs:element + name="perspectivePlugin" + type="perspective:PerspectivePluginDescriptorType" + substitutionGroup="serverplugin:server-plugin"> + xs:annotation + xs:documentation + Defines a Perspective plugin. A Perspective is deployed as a Server Plugin. + The Server Plugin + Container (SPC) handles simple lifecycle management for + the deployed plugins (e.g. start, stop). The plugin + is otherwise standalone + and can do everything it needs to do without additional help from the SPC. + </xs:documentation> + xs:appinfo + <jaxb:class + name="PerspectivePluginElement" /> + </xs:appinfo> + </xs:annotation> + </xs:element> + + <xs:complexType + name="PerspectivePluginDescriptorType"> + xs:complexContent + <xs:extension + base="serverplugin:ServerPluginDescriptorType"> + xs:sequence + <xs:element + ref="perspective:globalTask" + minOccurs="0" + maxOccurs="unbounded"> + </xs:element> + <xs:element + ref="perspective:resourceTask" + minOccurs="0" + maxOccurs="unbounded"> + </xs:element> + <xs:element + ref="perspective:menuItem" + minOccurs="0" + maxOccurs="unbounded"> + </xs:element> + <xs:element + ref="perspective:resourceTab" + minOccurs="0" + maxOccurs="unbounded"> + </xs:element> + <xs:element + ref="perspective:resourceSubTab" + minOccurs="0" + maxOccurs="unbounded"> + </xs:element> + </xs:sequence> + </xs:extension> + </xs:complexContent> + </xs:complexType> + + <xs:element + name="globalTask" + type="perspective:TaskType"> + xs:annotation + xs:appinfo + <jaxb:class + name="PerspectiveGlobalTaskElement" /> + </xs:appinfo> + </xs:annotation> + </xs:element> + + <xs:element + name="resourceTask" + type="perspective:TaskType"> + xs:annotation + xs:appinfo + <jaxb:class + name="PerspectiveResourceTaskElement" /> + </xs:appinfo> + </xs:annotation> + </xs:element> + + <xs:complexType + name="TaskType"> + xs:sequence + <xs:element + name="NewElement" + type="xs:string"> + </xs:element> + <xs:element + ref="perspective:extensionPoint" + minOccurs="1" + maxOccurs="unbounded"> + xs:annotation + xs:documentationA task pane extension point for which this task is presented.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element + ref="perspective:helpText" + minOccurs="0" + maxOccurs="1"> + xs:annotation + xs:documentationOptional additional help text for the task.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + <xs:attribute + name="name" + type="perspective:NameType" + use="required"> + xs:annotation + xs:documentation + The task name. Unique within names defined by the perspective. Used for + display if + displayName not provided. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute + name="displayName" + type="perspective:DisplayNameType" + use="optional"> + xs:annotation + xs:documentation + The name used for display, if provided. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute + name="description" + type="perspective:DescriptionType" + use="required"> + xs:annotation + xs:documentation + The task description displayed for the task. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute + name="url" + type="xs:anyURI" + use="optional"> + xs:annotation + xs:documentation + The request URL for the task. Typically kicks off a wizard or similar workflow. </xs:documentation> - xs:appinfo - <jaxb:class name="PerspectivePluginElement" /> - </xs:appinfo> - </xs:annotation> - </xs:element> - <xs:complexType name="PerspectivePluginDescriptorType"> - xs:complexContent - <xs:extension base="serverplugin:ServerPluginDescriptorType"> - xs:sequence - <!--...put specific perspective schema definitions here...--> - </xs:sequence> - </xs:extension> - </xs:complexContent> - </xs:complexType> + </xs:annotation> + </xs:attribute> + <xs:attribute + name="category" + type="xs:string" + use="optional"> + xs:annotation + xs:documentation + Optional task category. Tasks for the same category will be grouped together. + Categories + are not predefined. + </xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:complexType> + + <xs:element + name="extensionPoint" + type="perspective:ExtensionPointNameType"> + </xs:element> + + <xs:element + name="helpText" + type="perspective:HelpTextType"> + </xs:element> + + <xs:element + name="menuItem"> + xs:annotation + xs:documentation + Add or Remove a menu item in an existing menu extension point. Additions can specify + positioning as + well as a recursive structure, defineing a tree of MenuItems. + </xs:documentation> + xs:appinfo + <jaxb:class + name="PerspectiveMenuItemElement" /> + </xs:appinfo> + </xs:annotation> + xs:complexType + xs:sequence + <xs:element + ref="perspective:position" + minOccurs="0" + maxOccurs="1"> + xs:annotation + xs:documentation + Required for root menuItem additions. Position of children is implicit given the + XML + structure. + </xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + <xs:attribute + name="action" + type="perspective:ActionType" + use="optional"> + xs:annotation + xs:documentation + Add or remove the menu entry. For removal all but the name attribute are ignored. + Default is add. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute + name="name" + type="perspective:NameType" + use="required"> + xs:annotation + xs:documentation + ExtensionPoint name used for reference by other defined extension points. + Unique within + perspective. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute + name="displayName" + type="perspective:DisplayNameType" + use="optional"> + xs:annotation + xs:documentation + The displayed menu item name. Required for add actions. If empty an icon must be + defined. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute + name="feature" + type="perspective:MenuItemFeatureType" + use="optional"> + xs:annotation + xs:documentation + Certain menu items utilize special built-in rendering features. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute + name="url" + type="xs:anyURI" + use="optional"> + xs:annotation + xs:documentation + The request URL for the menu entry. If not provided the entry is just a placeholder for + MenuItems. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute + name="iconUrl" + type="xs:anyURI" + use="optional"> + xs:annotation + xs:documentation + The request URL for the icon image for this menu item. If not provided then no image is + used. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute + name="iconWidth" + type="xs:int" + use="optional"> + </xs:attribute> + <xs:attribute + name="iconHeight" + type="xs:int" + use="optional"> + </xs:attribute> + </xs:complexType> + </xs:element> + + <xs:element + name="resourceTab"> + xs:annotation + xs:appinfo + <jaxb:class + name="PerspectiveResourceTabElement" /> + </xs:appinfo> + </xs:annotation> + xs:complexType + xs:sequence + <xs:element + ref="perspective:position" + minOccurs="0" + maxOccurs="1"> + xs:annotation + xs:documentation + Required for root menuItem additions. Position of children is implicit given the + XML + structure. + </xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + <xs:attribute + name="name" + type="perspective:NameType" + use="required"> + xs:annotation + xs:documentation + The menu entry name. Unique within menu items defined for the perspective. Displayed + on + screen. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute + name="action" + type="perspective:ActionType" + use="optional"> + xs:annotation + xs:documentation + Add or remove the menu entry. Add is the default. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute + name="url" + type="xs:anyURI" + use="optional"> + xs:annotation + xs:documentation + The request URL for the menu entry. If not provided the entry is just a placeholder for + MenuItems. + </xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:complexType> + </xs:element> + + <xs:element + name="resourceSubTab"> + xs:annotation + xs:appinfo + <jaxb:class + name="PerspectiveResourceSubTabElement" /> + </xs:appinfo> + </xs:annotation> + xs:complexType + xs:sequence + <xs:element + ref="perspective:position" + minOccurs="0" + maxOccurs="1"> + xs:annotation + xs:documentation + Required for root menuItem additions. Position of children is implicit given the + XML + structure. + </xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + <xs:attribute + name="name" + type="perspective:NameType" + use="required"> + xs:annotation + xs:documentation + The menu entry name. Unique within menu items defined for the perspective. Displayed + on + screen. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute + name="action" + type="perspective:ActionType" + use="optional"> + xs:annotation + xs:documentation + Add or remove the menu entry. Add is the default. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute + name="url" + type="xs:anyURI" + use="optional"> + xs:annotation + xs:documentation + The request URL for the menu entry. If not provided the entry is just a placeholder for + MenuItems. + </xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:complexType> + </xs:element> + + <xs:element + name="inventoryActivator"> + xs:annotation + xs:appinfo + <jaxb:class + name="InventoryActivatorElement" /> + </xs:appinfo> + xs:documentation + Activators must be satisfied for the extension point to be active. + </xs:documentation> + </xs:annotation> + xs:complexType + xs:sequence + <xs:element + ref="perspective:permissionActivator" + minOccurs="0" + maxOccurs="unbounded"> + </xs:element> + <xs:element + ref="perspective:traitActivator" + minOccurs="0" + maxOccurs="unbounded"> + </xs:element> + </xs:sequence> + <xs:attribute + name="plugin" + type="xs:string" + use="required"> + xs:annotation + xs:documentation + Plugin for the specified resource type. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute + name="resourceType" + type="xs:string" + use="required"> + xs:annotation + xs:documentation + Resource Type that must be in inventory to activate the extension point. + </xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:complexType> + </xs:element> + + <xs:element + name="permissionActivator" + type="perspective:PermissionType"> + xs:annotation + xs:documentation + Activators must be satisfied for the extension point to be active. + The specified permission + must be available to the current user session. + </xs:documentation> + </xs:annotation> + </xs:element> + + <xs:element + name="traitActivator" + type="perspective:TraitActivatorType"> + xs:annotation + xs:documentation + Activators must be satisfied for the extension point to be active. + The specified permission + must be available to the current user session. + </xs:documentation> + </xs:annotation> + </xs:element> + + <xs:complexType + name="TraitActivatorType"> + <xs:attribute + name="trait" + type="xs:string" + use="required"> + xs:annotation + xs:documentation + The trait being tested for activation. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute + name="value" + type="xs:string" + use="required"> + xs:annotation + xs:documentation + The value of the trait. By default this is a 'contains' test. For equality, set strict to + true. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute + name="isEquals" + type="xs:boolean" + use="optional" + default="false"> + xs:annotation + xs:documentation + If true perform equality test. If false (default) perform a contains test. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute + name="isCaseSensitive" + type="xs:boolean" + use="optional" + default="false"> + xs:annotation + xs:documentation + If true perform a case sensitive test. If false (default) test is sase insensitive. + </xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:complexType> + + <xs:element + name="position" + type="perspective:PositionType"> + xs:annotation + xs:appinfo + <jaxb:class + name="PerspectivePositionElement" /> + </xs:appinfo> + </xs:annotation> + </xs:element> + + <xs:complexType + name="PositionType"> + <xs:attribute + name="extensionPoint" + type="perspective:ExtensionPointNameType" + use="required"> + xs:annotation + xs:documentation + The extension point (a menu, resource tab bar, etc) where the insertion is occuring. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute + name="name" + type="perspective:NameType" + use="optional"> + xs:annotation + xs:documentation + Position relatively against this name. Required for before/after positioning. + The name is + context specific, it could be a + menu entry name, a menu item name, tab name, subTab name, etc. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute + name="placement" + type="perspective:PlacementType" + use="required"> + </xs:attribute> + </xs:complexType> + + <xs:simpleType + name="ActionType"> + xs:annotation + xs:documentation + Add : Add new or Replaces existing + Remove : Removes existing + </xs:documentation> + </xs:annotation> + <xs:restriction + base="xs:string"> + <xs:enumeration + value="add"></xs:enumeration> + <xs:enumeration + value="remove"></xs:enumeration> + </xs:restriction> + </xs:simpleType> + + <xs:simpleType + name="DescriptionType"> + <xs:restriction + base="xs:string"> + <xs:minLength + value="1" /> + <xs:maxLength + value="512" /> + </xs:restriction> + </xs:simpleType> + + <xs:simpleType + name="DisplayNameType"> + <xs:restriction + base="xs:string"> + <xs:minLength + value="1" /> + <xs:maxLength + value="128" /> + </xs:restriction> + </xs:simpleType> + + <xs:simpleType + name="ExtensionPointNameType"> + <xs:restriction + base="xs:string"> + <xs:minLength + value="1" /> + <xs:maxLength + value="128" /> + </xs:restriction> + </xs:simpleType> + + <xs:simpleType + name="HelpTextType"> + <xs:restriction + base="xs:string"> + <xs:minLength + value="1" /> + <xs:maxLength + value="1024" /> + </xs:restriction> + </xs:simpleType> + + <xs:simpleType + name="MenuItemFeatureType"> + <xs:restriction + base="xs:string"> + <xs:enumeration + value="aboutBox"></xs:enumeration> + <xs:enumeration + value="groupFavorites"></xs:enumeration> + <xs:enumeration + value="groupRecentlyViewed"></xs:enumeration> + <xs:enumeration + value="groupSearch"></xs:enumeration> + <xs:enumeration + value="resourceFavorites"></xs:enumeration> + <xs:enumeration + value="resourceRecentlyViewed"></xs:enumeration> + <xs:enumeration + value="resourceSearch"></xs:enumeration> + <xs:enumeration + value="newWindow"></xs:enumeration> + <xs:enumeration + value="resourceSearch"></xs:enumeration> + </xs:restriction> + </xs:simpleType> + + <xs:simpleType + name="NameType"> + <xs:restriction + base="xs:string"> + <xs:minLength + value="1" /> + <xs:maxLength + value="64" /> + </xs:restriction> + </xs:simpleType> + + <xs:simpleType + name="PermissionType"> + <xs:restriction + base="xs:string"> + <xs:enumeration + value="MANAGE_INVENTORY"></xs:enumeration> + <xs:enumeration + value="MANAGE_SECURITY"></xs:enumeration> + <xs:enumeration + value="MANAGE_SETTINGS"></xs:enumeration> + + <xs:enumeration + value="CONFIGURE"></xs:enumeration> + <xs:enumeration + value="CONTROL"></xs:enumeration> + <xs:enumeration + value="CREATE_CHILD_RESOURCE"></xs:enumeration> + <xs:enumeration + value="DELETE_RESOURCE"></xs:enumeration> + <xs:enumeration + value="MANAGE_ALERTS"></xs:enumeration> + <xs:enumeration + value="MANAGE_CONTENT"></xs:enumeration> + <xs:enumeration + value="MANAGE_MEASUREMENTS"></xs:enumeration> + <xs:enumeration + value="MODIFY_RESOURCE"></xs:enumeration> + <xs:enumeration + value="VIEW_RESOURCE"></xs:enumeration> + </xs:restriction> + </xs:simpleType> + + <xs:simpleType + name="PlacementType"> + <xs:restriction + base="xs:string"> + <xs:enumeration + value="before"></xs:enumeration> + <xs:enumeration + value="after"></xs:enumeration> + <xs:enumeration + value="start"></xs:enumeration> + <xs:enumeration + value="end"></xs:enumeration> + </xs:restriction> + </xs:simpleType> +
</xs:schema> diff --git a/modules/enterprise/server/xml-schemas/src/test/resources/test-serverplugin-perspective.xml b/modules/enterprise/server/xml-schemas/src/test/resources/test-serverplugin-perspective.xml index f39a1b6..ac01d06 100644 --- a/modules/enterprise/server/xml-schemas/src/test/resources/test-serverplugin-perspective.xml +++ b/modules/enterprise/server/xml-schemas/src/test/resources/test-serverplugin-perspective.xml @@ -1,15 +1,14 @@ <?xml version="1.0" encoding="UTF-8"?>
-<perspective-plugin +<perspectivePlugin apiVersion="1.0" version="1.0" description="A Sample Perspective Utilizing Every Extension Point and Filter" displayName="Sample Perspective" name="SamplePerspective" package="org.rhq.perspective.sample" - pluginLifecycleListener="perspectivePluginLifecycleListener" xmlns="urn:xmlns:rhq-serverplugin.perspective" xmlns:serverplugin="urn:xmlns:rhq-serverplugin" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance%22%3E
-</perspective-plugin> +</perspectivePlugin>
commit 866e687cd9b4cb4380b0f9d28ef21c8f2b979a2b Author: Adam Young ayoung@redhat.com Date: Fri Nov 20 17:00:14 2009 -0500
Added guards around the navigation links between raw and structured
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit-raw.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit-raw.xhtml index 2c60ff9..4bbb24f 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit-raw.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit-raw.xhtml @@ -35,13 +35,14 @@ <a4j:form id="editResourceConfigurationForm"> <h:outputText value="#{messages.youareviewingraw}" /> - <h:outputText value=" #{messages.switch2}" /> - <h:commandLink action="#{rawConfigCollection.switchTostructured}"> + <h:panelGroup rendered="#{rawConfigCollection.structuredSupported}"> + <h:outputText value=" #{messages.switch2}" /> + <h:commandLink action="#{rawConfigCollection.switchTostructured}"> <s:conversationId /> <f:param name="id" value="#{ResourceUIBean.id}" /> <h:outputText value=" #{messages.structured}" /> </h:commandLink> - + </h:panelGroup> <table class="summary-props-table" style=""> <input type="hidden" name="id" value="#{ResourceUIBean.id}" /> diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit.xhtml index 6d3de6f..b28ade4 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit.xhtml @@ -28,9 +28,11 @@ THIS TEXT WILL BE REMOVED.
<input type="hidden" name="id" value="#{ResourceUIBean.id}"/>
+ <h:outputText value="#{messages.youareviewingstructured}" /> + <h:panelGroup rendered="#{rawConfigCollection.rawSupported}" > - You are viewing this in structured mode. Switch to - <h:commandLink action="#{rawConfigCollection.switchToraw}" rendered="#{rawConfigCollection.rawSupported}"> + <h:outputText value=" #{messages.switch2}" /> + <h:commandLink action="#{rawConfigCollection.switchToraw}" > <f:param name="conversationId" value="#{conversation.id}"/> <f:param name="id" value="#{ResourceUIBean.id}"/> <h:outputText value=" files mode"/> diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view-raw.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view-raw.xhtml index 4b137aa..5f919f3 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view-raw.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view-raw.xhtml @@ -41,6 +41,25 @@ <h:outputText value=" #{messages.structured}" /> </h:outputLink> + + <h:form id="viewResourceConfigurationForm"> + <!-- TODO remove the id version --> + <input type="hidden" name="id" value="#{ResourceUIBean.id}"/> + + + <h:panelGrid columns="2" styleClass="buttons-table" columnClasses="button-cell" + rendered="#{ExistingResourceConfigurationUIBean.configuration != null and !ExistingResourceConfigurationUIBean.updateInProgress}"> + <h:commandButton value="#{messages.editstructured}" action="#{ExistingResourceConfigurationUIBean.editConfiguration}" + title="Edit this Configuration" styleClass="buttonmed" + rendered="${ResourceUIBean.permissions.configure and rawConfigCollection.structuredSupported and !ExistingResourceConfigurationUIBean.updateInProgress}" /> + <h:commandButton value="#{messages.editraw}" action="#{ExistingResourceConfigurationUIBean.editRawConfiguration}" + title="Advanced Mode Edit of Raw Configuration Files" styleClass="buttonmed" + rendered="${ResourceUIBean.permissions.configure and rawConfigCollection.rawSupported and !ExistingResourceConfigurationUIBean.updateInProgress}" /> + </h:panelGrid> + + + </h:form> + <table class="summary-props-table" style=""> <tr> <td bgcolor="#a4b2b9" width="25%" valign="top">Files diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml index 08dd098..dd2eded 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml @@ -11,6 +11,7 @@ xmlns:c="http://java.sun.com/jstl/core" xmlns:onc="http://jboss.org/on/component%22%3E
+ THIS TEXT WILL BE REMOVED.
<ui:composition template="/rhq/resource/layout/main.xhtml"> @@ -27,21 +28,20 @@ THIS TEXT WILL BE REMOVED. <b>${msg['note']}</b> ${msg['resource.config.Current.updateInProgress']} </h:panelGroup>
- - <h:outputText value="#{messages.youareviewingstructured}" /> - <h:outputLink value="view-raw.xhtml"> - <f:param name="id" value="#{ResourceUIBean.id}" /> - <h:outputText value=" #{messages.raw}" /> - </h:outputLink> - + <h:outputText value="#{messages.youareviewingstructured}" /> + <h:panelGroup rendered="#{rawConfigCollection.rawSupported}" > + <h:outputText value=" #{messages.switch2}" /> + <h:outputLink value="view-raw.xhtml"> + <f:param name="id" value="#{ResourceUIBean.id}" /> + <h:outputText value=" #{messages.raw}" /> + </h:outputLink> + </h:panelGroup>
<h:outputText value=" #{messages.nopermissionedit}" rendered="#{!ResourceUIBean.permissions.configure}"/>
<h:form id="viewResourceConfigurationForm"> <!-- TODO remove the id version --> <input type="hidden" name="id" value="#{ResourceUIBean.id}"/> - <input type="hidden" name="id" value="#{ResourceUIBean.id}"/> -
<h:panelGrid columns="2" styleClass="buttons-table" columnClasses="button-cell" rendered="#{ExistingResourceConfigurationUIBean.configuration != null and !ExistingResourceConfigurationUIBean.updateInProgress}">
commit 33bd499db4212a65d1d3d96cc8df73e473d242ad Author: Adam Young ayoung@redhat.com Date: Fri Nov 20 16:24:32 2009 -0500
Fixes for bugs https://bugzilla.redhat.com/show_bug.cgi?id=537141 and https://bugzilla.redhat.com/show_bug.cgi?id=537086
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/classes/messages.properties b/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/classes/messages.properties index 331de61..06d7c32 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/classes/messages.properties +++ b/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/classes/messages.properties @@ -32,3 +32,4 @@ upload=Upload save=save download=Download nopermissionedit=You do not have permission to edit this resource's configuration +uploadcomplete=Back \ No newline at end of file diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/upload.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/upload.xhtml index c159adb..1ebde85 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/upload.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/upload.xhtml @@ -32,13 +32,15 @@ noDuplicate="true" immediateUpload="true" autoclear="false" - allowFlash="false" > + allowFlash="false" + maxRequestSize="100000" + > <a4j:support event="onuploadcomplete" action="#{rawConfigCollection.upload}" /> </rich:fileUpload> </h:form> </h:panelGrid> <h:outputLink value="edit-raw.xhtml" action="toEditRaw" > - <h:outputText value=" Upload Complete" /> + <h:outputText value="#{messages.uploadcomplete}" /> <f:param name="id" value="#{rawConfigCollection.resourceId}" /> </h:outputLink> </rich:panel>
commit 58fa8060bf833e05ce6bcdc9846f744744a555c7 Author: Lukas Krejci lkrejci@redhat.com Date: Fri Nov 20 16:14:28 2009 +0100
Make sure the start() and stop() methods are run only once in the whole suite. Because both of the tests inherit from the AbstractAugeasConfigurationComponentTest that defines the @BeforeSuite and @AfterSuite methods, those we run twice causing weird and wonderful issues.
diff --git a/modules/plugins/cron/src/test/java/org/rhq/plugins/cron/test/CronComponentTest.java b/modules/plugins/cron/src/test/java/org/rhq/plugins/cron/test/CronComponentTest.java index 7aee6e1..6eb844e 100644 --- a/modules/plugins/cron/src/test/java/org/rhq/plugins/cron/test/CronComponentTest.java +++ b/modules/plugins/cron/src/test/java/org/rhq/plugins/cron/test/CronComponentTest.java @@ -1,11 +1,3 @@ -package org.rhq.plugins.cron.test; -import org.rhq.core.domain.configuration.Configuration; -import org.rhq.core.domain.configuration.PropertyList; -import org.rhq.core.domain.configuration.PropertyMap; -import org.rhq.core.domain.configuration.PropertySimple; -import org.rhq.plugins.augeas.AugeasConfigurationComponent; -import org.rhq.plugins.augeas.test.AbstractAugeasConfigurationComponentTest; - /* * RHQ Management Platform * Copyright (C) 2005-2009 Red Hat, Inc. @@ -29,6 +21,18 @@ import org.rhq.plugins.augeas.test.AbstractAugeasConfigurationComponentTest; * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
+package org.rhq.plugins.cron.test; + +import org.testng.annotations.AfterSuite; +import org.testng.annotations.BeforeSuite; + +import org.rhq.core.domain.configuration.Configuration; +import org.rhq.core.domain.configuration.PropertyList; +import org.rhq.core.domain.configuration.PropertyMap; +import org.rhq.core.domain.configuration.PropertySimple; +import org.rhq.plugins.augeas.AugeasConfigurationComponent; +import org.rhq.plugins.augeas.test.AbstractAugeasConfigurationComponentTest; + /** * Tests for cron component. * @@ -36,13 +40,16 @@ import org.rhq.plugins.augeas.test.AbstractAugeasConfigurationComponentTest; */ public class CronComponentTest extends AbstractAugeasConfigurationComponentTest {
+ public static final String INCLUDE_GLOBS = "/etc/crontab|/etc/cron.d/another-crontab"; + public static final String CRON_COMPONENT_START_TEST_GROUP = "cron-component-start"; + @Override protected void tweakDefaultPluginConfig(Configuration defaultPluginConfig) { super.tweakDefaultPluginConfig(defaultPluginConfig); //the base cannot support the /etc/cron.d/* glob pattern because it reads stuff from the classloader resource stream //that doesn't support searching (or does it?) //so we have to update the include globs to include only concrete file paths - defaultPluginConfig.put(new PropertySimple(AugeasConfigurationComponent.INCLUDE_GLOBS_PROP, "/etc/crontab|/etc/cron.d/another-crontab")); + defaultPluginConfig.put(new PropertySimple(AugeasConfigurationComponent.INCLUDE_GLOBS_PROP, INCLUDE_GLOBS)); }
@Override diff --git a/modules/plugins/cron/src/test/java/org/rhq/plugins/cron/test/CronTabComponentTest.java b/modules/plugins/cron/src/test/java/org/rhq/plugins/cron/test/CronTabComponentTest.java index 1e9811d..d217810 100644 --- a/modules/plugins/cron/src/test/java/org/rhq/plugins/cron/test/CronTabComponentTest.java +++ b/modules/plugins/cron/src/test/java/org/rhq/plugins/cron/test/CronTabComponentTest.java @@ -23,6 +23,7 @@
package org.rhq.plugins.cron.test;
+import java.io.IOException; import java.util.Set;
import org.rhq.core.domain.configuration.Configuration; @@ -43,8 +44,26 @@ import org.rhq.plugins.augeas.test.AbstractAugeasConfigurationComponentTest; public class CronTabComponentTest extends AbstractAugeasConfigurationComponentTest {
@Override + public void start() { + //do nothing.. + //this method is intentionally not annotated with @BeforeSuite as its parent, so + //that it actually isn't run.. we need to run the @BeforeSuite only once and that + //is done in the CronComponentTest + } + + @Override + public void stop() { + //do nothing.. the cron component test will take care of teardown + //as with start() method, this is intentionally not annotated... + } + + public void resetConfigFiles() throws IOException { + //make this a non-test method so that only the one on the cron component gets executed. + } + + @Override protected Resource getResource() { - //let's pick the "another-crontab file + //let's pick the "another-crontab" file InventoryManager inventoryManager = PluginContainer.getInstance().getInventoryManager(); ResourceType resourceType = getResourceType(); Set<Resource> resources = inventoryManager.getResourcesWithType(resourceType);
commit 9c17623b3a538354695b872497aea85573680af1 Author: Lukas Krejci lkrejci@redhat.com Date: Fri Nov 20 16:12:31 2009 +0100
Fixed the resource key generation regression introduced in the last update of this class.
diff --git a/modules/plugins/cron/src/main/java/org/rhq/plugins/cron/CronTabDiscoveryComponent.java b/modules/plugins/cron/src/main/java/org/rhq/plugins/cron/CronTabDiscoveryComponent.java index b486fd2..71137e1 100644 --- a/modules/plugins/cron/src/main/java/org/rhq/plugins/cron/CronTabDiscoveryComponent.java +++ b/modules/plugins/cron/src/main/java/org/rhq/plugins/cron/CronTabDiscoveryComponent.java @@ -65,7 +65,7 @@ public class CronTabDiscoveryComponent implements ResourceDiscoveryComponent<Cro
ResourceType resourceType = context.getResourceType();
- int pathUnderRootStartIdx = rootPath.endsWith(File.pathSeparator) ? rootPath.length() - 1 : rootPath.length(); + int pathUnderRootStartIdx = rootPath.endsWith(File.separator) ? rootPath.length() - 1 : rootPath.length();
for (File f : files) { String resourceKey = f.getAbsolutePath().substring(pathUnderRootStartIdx);
commit 04ecf133ed821ec67acb7c0ae18e78deb91cb7fd Merge: 682e561... e6472fc... Author: Partha Aji paji@redhat.com Date: Thu Nov 19 21:28:31 2009 -0500
Merge branch 'master' into linux-config
Fixed merge conflicts Conflicts: modules/enterprise/gui/portal-war/src/main/webapp/rhq/layout/main-layout.xhtml modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginManager.java
diff --cc etc/samples/perspectives/sample-perspective/app/pom.xml index acf9d67,0000000..4857117 mode 100644,000000..100644 --- a/etc/samples/perspectives/sample-perspective/app/pom.xml +++ b/etc/samples/perspectives/sample-perspective/app/pom.xml @@@ -1,143 -1,0 +1,143 @@@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.rhq</groupId> + <artifactId>rhq-parent</artifactId> + <version>1.4.0-SNAPSHOT</version> + </parent> + + <groupId>org.rhq</groupId> + <artifactId>rhq-sample-perspective-war</artifactId> + <packaging>war</packaging> + + <name>RHQ Sample Perspective War</name> + + <scm> + <connection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/etc/samples/sample-perspective/app/</connection> + <developerConnection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/etc/samples/sample-perspective/app/</developerConnection> + </scm> + + <properties> + <scm.module.path>modules/enterprise/gui/perspectives/sample-perspective-war/</scm.module.path> + <war.dir>${basedir}/target/${final.name}</war.dir> + </properties> + + <dependencies> + + </dependencies> + + <build> + <finalName>rhq-sample-perspective</finalName> + + <plugins> + + <plugin> + <artifactId>maven-war-plugin</artifactId> + <configuration> + <archive> + <manifest> + <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries> + <addDefaultImplementationEntries>true</addDefaultImplementationEntries> + </manifest> + <manifestEntries> + <Build-Number>${buildNumber}</Build-Number> + </manifestEntries> + </archive> + <webResources> + <resource> + <filtering>true</filtering> + <directory>${basedir}/src/main/webapp</directory> + <includes> + <include>**/*.properties</include> + </includes> + </resource> + </webResources> + </configuration> + </plugin> + + </plugins> + + </build> + + <profiles> + + <profile> + <id>dev</id> + + <properties> - <rhq.rootDir>../../../..</rhq.rootDir> ++ <rhq.rootDir>../../../../..</rhq.rootDir> + <rhq.containerDir>${rhq.rootDir}/${rhq.defaultDevContainerPath}</rhq.containerDir> + <rhq.deploymentName>${project.build.finalName}.war</rhq.deploymentName> + <rhq.deploymentDir>${rhq.containerDir}/jbossas/server/default/deploy/${rhq.deploymentName}</rhq.deploymentDir> + </properties> + + <build> + <plugins> + + <plugin> + <artifactId>maven-antrun-plugin</artifactId> + <version>1.1</version> + <executions> + + <execution> + <id>deploy-classes</id> + <phase>compile</phase> + <configuration> + <tasks> + <property name="classes.dir" location="${rhq.deploymentDir}/WEB-INF/classes" /> + <echo>*** Copying updated files from target/classes to ${classes.dir}...</echo> + <copy todir="${classes.dir}" failonerror="false" verbose="${rhq.verbose}"> + <fileset dir="target/classes" /> + </copy> + </tasks> + </configuration> + <goals> + <goal>run</goal> + </goals> + </execution> + + <execution> + <id>deploy</id> + <phase>package</phase> + <configuration> + <tasks> + <property name="deployment.dir" location="${rhq.deploymentDir}" /> + <echo>*** Copying updated files from target${file.separator}${project.build.finalName}${file.separator} to ${deployment.dir}${file.separator}...</echo> + <copy todir="${deployment.dir}" verbose="${rhq.verbose}"> + <fileset dir="${basedir}/target/${project.build.finalName}" /> + </copy> + <delete dir="${deployment.dir}.rej" /> <!-- need to remove any residual backups --> + </tasks> + </configuration> + <goals> + <goal>run</goal> + </goals> + </execution> + + <execution> + <id>undeploy</id> + <phase>clean</phase> + <configuration> + <tasks> + <property name="deployment.dir" location="${rhq.deploymentDir}" /> + <echo>*** Deleting ${deployment.dir}${file.separator}...</echo> + <delete dir="${deployment.dir}" /> + </tasks> + </configuration> + <goals> + <goal>run</goal> + </goals> + </execution> + + </executions> + </plugin> + + </plugins> + </build> + </profile> + + </profiles> + - </project> ++</project> diff --cc modules/enterprise/gui/portal-war/src/main/webapp/rhq/layout/main-layout.xhtml index bd4a0d1,339a4ea..6359d7e --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/layout/main-layout.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/layout/main-layout.xhtml @@@ -29,7 -29,14 +29,6 @@@ <script type="text/javascript" src="/js/formValues.js"></script> <script type="text/javascript" src="/js/rhq.js"></script> <script type="text/javascript" src="/js/popup.js"></script> - - <script type="text/javascript" src="/js/iframeSSI.js"> - /*********************************************** - * IFrame SSI script II- © Dynamic Drive DHTML code library (http://www.dynamicdrive.com) - * Visit DynamicDrive.com for hundreds of original DHTML scripts - * This notice must stay intact for legal use - ***********************************************/ - </script> - <link href="/css/theme/default.css" rel="stylesheet" type="text/css"/> <link href="/css/theme/alphacube.css" rel="stylesheet" type="text/css"/> <link href="/css/theme/debug.css" rel="stylesheet" type="text/css"/> diff --cc modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginManager.java index d2401e6,a0cca3f..8eb7c70 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginManager.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginManager.java @@@ -296,34 -284,26 +284,24 @@@ public class ServerPluginManager MasterServerPluginContainerConfiguration masterConfig = masterPC.getConfiguration(); File dataDir = new File(masterConfig.getDataDirectory(), pluginName); File tmpDir = masterConfig.getTemporaryDirectory(); -- - // TODO: today we have no way in the UI to customize the plugin config values - // for now, just use the defaults as defined in the descriptor - Configuration config = null; + Configuration plugnConfig; + List<ScheduledJobDefinition> schedules; - try { - ConfigurationDefinition configDef = ConfigurationMetadataParser.parse(pluginName, pluginDescriptor - .getPluginConfiguration()); - - config = (null == configDef) ? null : configDef.getDefaultTemplate().createConfiguration(); - } catch (InvalidPluginDescriptorException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + // TODO: today we have no way in the UI to customize the plugin config values + // for now, just use the defaults as defined in the descriptor + ConfigurationDefinition configDef = ServerPluginDescriptorMetadataParser + .getPluginConfigurationDefinition(pluginDescriptor); + plugnConfig = configDef.getDefaultTemplate().createConfiguration(); + + // TODO: today we have no way in the UI to customize the schedules + // for now, just use the defaults as defined in the descriptor + schedules = ServerPluginDescriptorMetadataParser.getScheduledJobs(pluginDescriptor); + } catch (Exception e) { + // TODO need proper exception handling + throw new RuntimeException(e); }
- Schedule schedule = null; - if (pluginDescriptor.getLifecycleListener() != null) { - ScheduleType scheduleType = pluginDescriptor.getLifecycleListener().getSchedule(); - if (scheduleType != null) { - boolean concurrent = scheduleType.isConcurrent(); - if (scheduleType.getPeriod() != null) { - schedule = new PeriodicSchedule(concurrent, scheduleType.getPeriod().longValue()); - } else { - schedule = new CronSchedule(concurrent, scheduleType.getCron()); - } - } - } - - context = new ServerPluginContext(env, dataDir, tmpDir, config, schedule); + context = new ServerPluginContext(env, dataDir, tmpDir, plugnConfig, schedules); this.pluginContextCache.put(pluginName, context); return context; } diff --cc modules/enterprise/server/xml-schemas/src/test/java/org/rhq/enterprise/server/xmlschema/ServerPluginDescriptorUtilTest.java index 419bfe2,f38a541..f7fb990 --- a/modules/enterprise/server/xml-schemas/src/test/java/org/rhq/enterprise/server/xmlschema/ServerPluginDescriptorUtilTest.java +++ b/modules/enterprise/server/xml-schemas/src/test/java/org/rhq/enterprise/server/xmlschema/ServerPluginDescriptorUtilTest.java @@@ -96,31 -128,22 +129,36 @@@ public class ServerPluginDescriptorUtil assert descriptor.getDescription().equals("alert plugin wotgorilla?"); assert descriptor.getPackage().equals("org.alert.package.name.here");
- LifecycleListenerType lifecycleListener = descriptor.getLifecycleListener(); - ScheduleType schedule = lifecycleListener.getSchedule(); - assert lifecycleListener.getClazz().equals("alertPluginLifecycleListener"); - assert schedule.getCron() == null; - assert schedule.getPeriod().longValue() == 1000L; + ServerPluginComponentType pluginComponent = descriptor.getPluginComponent(); + assert pluginComponent.getClazz().equals("alertPluginComponent"); + + assert descriptor.getScheduledJobs() == null; + assert ServerPluginDescriptorMetadataParser.getScheduledJobs(descriptor).size() == 0; + + ConfigurationDescriptor configDescriptor = descriptor.getPluginConfiguration(); + assert configDescriptor != null; + assert configDescriptor.getConfigurationProperty().get(0).getValue().getName().equals("alertprop1");
- ConfigurationDescriptor config = descriptor.getPluginConfiguration(); + ConfigurationDefinition config; + config = ServerPluginDescriptorMetadataParser.getPluginConfigurationDefinition(descriptor); assert config != null; - assert config.getConfigurationProperty().get(0).getValue().getName().equals("alertprop1"); + assert config.getPropertyDefinitionSimple("alertprop1") != null; }
+ public void testPerspectivePluginDescriptor() throws Exception { + String testXml = "test-serverplugin-perspective.xml"; + ServerPluginDescriptorType data = parseTestXml(testXml); + assert data instanceof PerspectivePluginDescriptorType; + PerspectivePluginDescriptorType descriptor = (PerspectivePluginDescriptorType) data; + + assert descriptor.getApiVersion().equals("1.0"); + assert descriptor.getVersion().equals("1.0"); + assert descriptor.getName().equals("SamplePerspective"); + assert descriptor.getDisplayName().equals("Sample Perspective"); + assert descriptor.getDescription().equals("A Sample Perspective Utilizing Every Extension Point and Filter"); + assert descriptor.getPackage().equals("org.rhq.perspective.sample"); + } + private ServerPluginDescriptorType parseTestXml(String testXml) throws Exception { Unmarshaller unmarshaller = ServerPluginDescriptorUtil.getServerPluginDescriptorUnmarshaller(); URL url = this.getClass().getClassLoader().getResource(testXml);
commit 96877c1a384aca86837aa2ce2cf7bcc3e456cabd Merge: 0bc3968... 5bb22f0... Author: Adam Young ayoung@redhat.com Date: Wed Nov 18 21:05:50 2009 -0500
Merge branch 'raw-config' of ssh://git.fedorahosted.org/git/rhq/rhq into raw-config
commit 0bc39682fa705d34b8421cf0df7d98dae86c3261 Author: Adam Young ayoung@redhat.com Date: Wed Nov 18 21:04:27 2009 -0500
Using css class and i18n support for the submit buttons
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/classes/messages.properties b/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/classes/messages.properties index 7c1514f..331de61 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/classes/messages.properties +++ b/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/classes/messages.properties @@ -26,6 +26,7 @@ files = List of files currentfile = Current File uncommitted = file has uncommitted changes discard=Discard Changes +commit=Commit Changes fullscreen=Full Screen upload=Upload save=save diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit-raw.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit-raw.xhtml index 860fb2c..2c60ff9 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit-raw.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit-raw.xhtml @@ -64,10 +64,14 @@ </h:panelGroup> <div>______________________________________</div> <div>* <h:outputText value="#{messages.uncommitted}" /></div> - <a4j:commandButton action="#{rawConfigCollection.commit}" - value="commit changes" reRender="changedFiles" /> <a4j:commandButton - action="#{rawConfigCollection.discard}" value="#{messages.discard}" - reRender="changedFiles" /></td> + <h:panelGrid columns="2" styleClass="buttons-table" columnClasses="button-cell"> + <a4j:commandButton action="#{rawConfigCollection.commit}" + value="#{messages.commit}" reRender="changedFiles" styleClass="buttonmed"/> + <a4j:commandButton + action="#{rawConfigCollection.discard}" value="#{messages.discard}" + reRender="changedFiles" styleClass="buttonmed"/> + </h:panelGrid> + </td> <td> <div> <h:outputText value="#{messages.currentfile}" />
commit 5bb22f04d2bf6c3e3eb33d6fb16c37d59489deb8 Author: John Sanda john@localhost.localdomain Date: Wed Nov 18 15:26:00 2009 -0500
[US 4] Adding javadocs
diff --git a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/configuration/ConfigurationAgentService.java b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/configuration/ConfigurationAgentService.java index ecd499b..32a3dd4 100644 --- a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/configuration/ConfigurationAgentService.java +++ b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/configuration/ConfigurationAgentService.java @@ -79,6 +79,23 @@ public interface ConfigurationAgentService { */ Configuration loadResourceConfiguration(int resourceId) throws PluginContainerException;
+ /** + * If the <code>fromStructured</code> flag is <code>true</code>, then the structured configuration (i.e., <code> + * Configuration.properties</code>) is merged into the latest raw configurations returned from the plugin. The + * Configuration object returned will consist of the structured configuration along with the merged raw + * configurations. If <code>fromStructured</code> is <code>false</code>, then the raw configurations (i.e., <code> + * Configuration.rawConfigurations</code>) is merged into the latest structured configurations returned from the + * plugin. The returned Configuration will then consist of the raw configuration along with the merged structured + * configuration. + * + * @param configuration The Configuration with the changes to be merged + * @param resourceId The id of the resource to which the configuration belongs + * @param fromStructured A flag that if <code>true</code> indicates the merge should be from structured to raw, + * otherwise merge from raw to structured. + * @return The <strong>merged</strong> configuration, where a merge consists of a refresh of the side being merged + * followed by the values of the side merging from being applied to the side being merged into. + * @throws PluginContainerException if a runtime or plugin error occurs. + */ Configuration merge(Configuration configuration, int resourceId, boolean fromStructured) throws PluginContainerException; } \ No newline at end of file diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManager.java index 923ad4e..8bfbfb3 100644 --- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManager.java +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManager.java @@ -167,6 +167,8 @@ public class ConfigurationManager extends AgentService implements ContainerServi public Configuration merge(Configuration configuration, int resourceId, boolean fromStructured) throws PluginContainerException {
+ // TODO Throw an exception if the resource does not support structured and raw + boolean daemonOnly = true; boolean onlyIfStarted = true;
commit 682e56123054e559d035cfea8fa1d947efccc600 Author: Shannon Hughes shughes@fred.hughes.lan Date: Wed Nov 18 15:06:49 2009 -0500
adding postfix and aliases plugins to the packaging ear
diff --git a/modules/enterprise/server/ear/pom.xml b/modules/enterprise/server/ear/pom.xml index ac874e9..4e40aae 100644 --- a/modules/enterprise/server/ear/pom.xml +++ b/modules/enterprise/server/ear/pom.xml @@ -229,6 +229,12 @@
<artifactItem> <groupId>org.rhq</groupId> + <artifactId>rhq-aliases-plugin</artifactId> + <version>${project.version}</version> + </artifactItem> + + <artifactItem> + <groupId>org.rhq</groupId> <artifactId>rhq-apache-plugin</artifactId> <version>${project.version}</version> </artifactItem> @@ -326,6 +332,12 @@
<artifactItem> <groupId>org.rhq</groupId> + <artifactId>rhq-postfix-plugin</artifactId> + <version>${project.version}</version> + </artifactItem> + + <artifactItem> + <groupId>org.rhq</groupId> <artifactId>rhq-postgres-plugin</artifactId> <version>${project.version}</version> </artifactItem> diff --git a/modules/plugins/JBossOSGi/jopr-jbossOsgi-plugin.iml b/modules/plugins/JBossOSGi/jopr-jbossOsgi-plugin.iml index 82347c1..cf034d5 100644 --- a/modules/plugins/JBossOSGi/jopr-jbossOsgi-plugin.iml +++ b/modules/plugins/JBossOSGi/jopr-jbossOsgi-plugin.iml @@ -3,6 +3,7 @@ <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_5" inherit-compiler-output="false"> <output url="file://$MODULE_DIR$/target/classes" /> <output-test url="file://$MODULE_DIR$/target/test-classes" /> + <exclude-output /> <content url="file://$MODULE_DIR$"> <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/src/main/resources" isTestSource="false" /> @@ -11,32 +12,14 @@ <orderEntry type="inheritedJdk" /> <orderEntry type="sourceFolder" forTests="false" /> <orderEntry type="library" exported="" name="Maven: commons-logging:commons-logging:1.1" level="project" /> - <orderEntry type="library" name="Maven: log4j:log4j:1.2.14" level="project" /> + <orderEntry type="library" exported="" name="Maven: log4j:log4j:1.2.12" level="project" /> <orderEntry type="library" exported="" name="Maven: logkit:logkit:1.0.1" level="project" /> <orderEntry type="library" exported="" name="Maven: avalon-framework:avalon-framework:4.1.3" level="project" /> <orderEntry type="library" exported="" name="Maven: javax.servlet:servlet-api:2.3" level="project" /> - <orderEntry type="library" exported="" name="Maven: i18nlog:i18nlog:1.0.9" level="project" /> - <orderEntry type="library" name="Maven: javax.xml.bind:jaxb-api:2.1" level="project" /> - <orderEntry type="library" name="Maven: javax.xml.stream:stax-api:1.0-2" level="project" /> - <orderEntry type="library" exported="" name="Maven: javax.activation:activation:1.1.1" level="project" /> - <orderEntry type="library" name="Maven: org.testng:testng:jdk15:5.7" level="project" /> - <orderEntry type="library" exported="" name="Maven: junit:junit:3.8.1" level="project" /> - <orderEntry type="library" name="Maven: org.jetbrains:annotations:7.0.2" level="project" /> - <orderEntry type="module" module-name="rhq-core-domain" /> - <orderEntry type="module" module-name="rhq-core-util" /> - <orderEntry type="library" name="Maven: jdom:jdom:1.0" level="project" /> - <orderEntry type="module" module-name="rhq-core-plugin-api" /> - <orderEntry type="module" module-name="rhq-core-native-system" /> - <orderEntry type="library" name="Maven: org.hyperic:sigar:1.6.0.14" level="project" /> - <orderEntry type="library" name="Maven: com.sun.xml.bind:jaxb-impl:2.1.6" level="project" /> - <orderEntry type="module" module-name="rhq-core-plugin-container" /> - <orderEntry type="module" module-name="rhq-core-comm-api" /> - <orderEntry type="module" module-name="rhq-core-client-api" /> - <orderEntry type="library" name="Maven: javax.persistence:persistence-api:1.0" level="project" /> - <orderEntry type="library" name="Maven: jboss.jboss-embeddable-ejb3:hibernate-all:1.0.0.Alpha9" level="project" /> - <orderEntry type="module" module-name="rhq-jmx-plugin" /> - <orderEntry type="library" name="Maven: mc4j:org-mc4j-ems:1.2.6" level="project" /> - <orderEntry type="library" name="Maven: com.sun:tools:1.4.2" level="project" /> + <orderEntry type="library" name="Maven: org.rhq:rhq-core-domain:${rhq.version}" level="project" /> + <orderEntry type="library" name="Maven: org.rhq:rhq-core-plugin-api:${rhq.version}" level="project" /> + <orderEntry type="library" name="Maven: org.rhq:rhq-core-native-system:${rhq.version}" level="project" /> + <orderEntry type="library" name="Maven: org.rhq:rhq-jmx-plugin:${rhq.version}" level="project" /> <orderEntry type="library" exported="" name="Maven: org.osgi:org.osgi.core:r4v41" level="project" /> <orderEntry type="library" exported="" name="Maven: org.osgi:org.osgi.compendium:r4v41" level="project" /> <orderEntry type="library" exported="" name="Maven: org.jboss.osgi:jboss-osgi-spi:1.0.0.Beta1" level="project" /> @@ -58,6 +41,7 @@ <orderEntry type="library" exported="" name="Maven: apache-xerces:xml-apis:2.9.1" level="project" /> <orderEntry type="library" exported="" name="Maven: apache-xerces:xercesImpl:2.9.1" level="project" /> <orderEntry type="library" exported="" name="Maven: wutka-dtdparser:dtdparser121:1.2.1" level="project" /> + <orderEntry type="library" exported="" name="Maven: javax.activation:activation:1.1.1" level="project" /> <orderEntry type="library" exported="" name="Maven: org.jboss.integration:jboss-classloading-spi:5.0.3.GA" level="project" /> <orderEntry type="library" exported="" name="Maven: org.jboss.logging:jboss-logging-spi:2.0.5.GA" level="project" /> <orderEntry type="library" exported="" name="Maven: org.jboss.cl:jboss-classloading:2.0.3.GA" level="project" /> @@ -69,6 +53,7 @@ <orderEntry type="library" exported="" name="Maven: org.jboss.deployers:jboss-deployers-client:2.0.5.GA" level="project" /> <orderEntry type="library" exported="" name="Maven: org.jboss.deployers:jboss-deployers-impl:2.0.5.GA" level="project" /> <orderEntry type="library" exported="" name="Maven: javassist:javassist:3.9.0.GA" level="project" /> + <orderEntry type="library" exported="" name="Maven: junit:junit:4.4" level="project" /> </component> </module>
commit 4be561283fb03fcd6dbbfb437e9adf163eef0fc2 Author: John Sanda john@localhost.localdomain Date: Wed Nov 18 14:25:16 2009 -0500
[US 4] Fixing bugs in the merge() method that resulted in returning the configuration unmodified.
In addition to returning the updated configuration, the merge() method has been updated to "refresh" the side being merged into. If for example, we are merging from structured to raw, ConfigurationManager first loads the raw configs from config facet, and replaces Configuration.rawConfigurations with those loaded raw configs. Then the structured is merged into the raws. The same is done going from raw to structured.
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManager.java index c5af995..923ad4e 100644 --- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManager.java +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManager.java @@ -22,14 +22,11 @@ */ package org.rhq.core.pc.configuration;
-import java.util.LinkedList; -import java.util.Queue; +import java.util.List; import java.util.Set; -import java.util.concurrent.Callable; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ScheduledThreadPoolExecutor; -import java.util.concurrent.TimeUnit; +import java.util.Queue; +import java.util.LinkedList; +import java.util.concurrent.*;
import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -38,21 +35,25 @@ import org.apache.maven.artifact.versioning.ComparableVersion; import org.rhq.core.clientapi.agent.PluginContainerException; import org.rhq.core.clientapi.agent.configuration.ConfigurationAgentService; import org.rhq.core.clientapi.agent.configuration.ConfigurationUpdateRequest; +import org.rhq.core.clientapi.agent.configuration.ConfigurationUtility; import org.rhq.core.clientapi.server.configuration.ConfigurationServerService; import org.rhq.core.clientapi.server.configuration.ConfigurationUpdateResponse; import org.rhq.core.domain.configuration.Configuration; import org.rhq.core.domain.configuration.RawConfiguration; +import org.rhq.core.domain.configuration.Property; +import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; import org.rhq.core.domain.resource.ResourceType; import org.rhq.core.pc.ContainerService; -import org.rhq.core.pc.PluginContainer; import org.rhq.core.pc.PluginContainerConfiguration; -import org.rhq.core.pc.agent.AgentService; +import org.rhq.core.pc.PluginContainer; import org.rhq.core.pc.util.ComponentService; +import org.rhq.core.pc.agent.AgentService; import org.rhq.core.pc.util.ComponentUtil; import org.rhq.core.pc.util.FacetLockType; import org.rhq.core.pc.util.LoggingThreadFactory; import org.rhq.core.pluginapi.configuration.ConfigurationFacet; import org.rhq.core.pluginapi.configuration.ResourceConfigurationFacet; +import org.rhq.core.util.exception.WrappedRemotingException;
/** * Manages configuration of all resources across all plugins. @@ -85,14 +86,17 @@ public class ConfigurationManager extends AgentService implements ContainerServi LoggingThreadFactory threadFactory = new LoggingThreadFactory(SENDER_THREAD_POOL_NAME, true); threadPool = new ScheduledThreadPoolExecutor(1, threadFactory);
- ConfigurationCheckExecutor configurationChecker = new ConfigurationCheckExecutor(this, - getConfigurationServerService(), PluginContainer.getInstance().getInventoryManager()); + ConfigurationCheckExecutor configurationChecker = + new ConfigurationCheckExecutor(this, getConfigurationServerService(), + PluginContainer.getInstance().getInventoryManager());
if (pluginContainerConfiguration.getConfigurationDiscoveryPeriod() > 0 - && pluginContainerConfiguration.isInsideAgent()) { - threadPool.scheduleAtFixedRate(configurationChecker, pluginContainerConfiguration - .getConfigurationDiscoveryInitialDelay(), pluginContainerConfiguration - .getConfigurationDiscoveryPeriod(), TimeUnit.SECONDS); + && pluginContainerConfiguration.isInsideAgent()) { + threadPool.scheduleAtFixedRate( + configurationChecker, + pluginContainerConfiguration.getConfigurationDiscoveryInitialDelay(), + pluginContainerConfiguration.getConfigurationDiscoveryPeriod(), + TimeUnit.SECONDS); } }
@@ -171,7 +175,8 @@ public class ConfigurationManager extends AgentService implements ContainerServi
if (fromStructured) { mergedStructuredIntoRaws(configuration, facet); - } else { + } + else { mergeRawsIntoStructured(configuration, facet); }
@@ -179,17 +184,36 @@ public class ConfigurationManager extends AgentService implements ContainerServi }
private void mergeRawsIntoStructured(Configuration configuration, ResourceConfigurationFacet facet) { - for (RawConfiguration rawConfig : configuration.getRawConfigurations()) { - facet.mergeStructuredConfiguration(rawConfig, configuration); + Configuration structuredConfig = facet.loadStructuredConfiguration(); + + if (structuredConfig != null) { + prepareConfigForMergeIntoStructured(configuration, structuredConfig); + + for (RawConfiguration rawConfig : configuration.getRawConfigurations()) { + structuredConfig.addRawConfiguration(rawConfig); + facet.mergeStructuredConfiguration(rawConfig, configuration); + } + } + } + + private void prepareConfigForMergeIntoStructured(Configuration config, Configuration latestStructured) { + config.getAllProperties().clear(); + for (Property property : latestStructured.getProperties()) { + config.put(property); } }
private void mergedStructuredIntoRaws(Configuration configuration, ResourceConfigurationFacet facet) { - Set<RawConfiguration> rawConfigs = configuration.getRawConfigurations();//facet.loadRawConfigurations(); + Set<RawConfiguration> rawConfigs = facet.loadRawConfigurations(); + if (rawConfigs == null) { return; } + + prepareConfigForMergeIntoRaws(configuration, rawConfigs); + Queue<RawConfiguration> queue = new LinkedList<RawConfiguration>(rawConfigs); + while (!queue.isEmpty()) { RawConfiguration originalRaw = queue.poll(); RawConfiguration mergedRaw = facet.mergeRawConfiguration(configuration, originalRaw); @@ -200,13 +224,22 @@ public class ConfigurationManager extends AgentService implements ContainerServi } }
- private void updateRawConfig(Configuration configuration, RawConfiguration originalRaw, RawConfiguration mergedRaw) { + private void prepareConfigForMergeIntoRaws(Configuration config, Set<RawConfiguration> latestRaws) { + config.getRawConfigurations().clear(); + for (RawConfiguration raw : latestRaws) { + config.addRawConfiguration(raw); + } + } + + private void updateRawConfig(Configuration configuration, RawConfiguration originalRaw, + RawConfiguration mergedRaw) {
configuration.removeRawConfiguration(originalRaw); configuration.addRawConfiguration(mergedRaw); }
- public Configuration loadResourceConfiguration(int resourceId) throws PluginContainerException { + public Configuration loadResourceConfiguration(int resourceId) + throws PluginContainerException {
LoadResourceConfiguration loadConfig = loadConfigFactory.getStrategy(resourceId); Configuration configuration = null; @@ -227,43 +260,43 @@ public class ConfigurationManager extends AgentService implements ContainerServi private String createErrorMsg(int resourceId, String msg) throws PluginContainerException { ResourceType resourceType = componentService.getResourceType(resourceId);
- return "Plugin Error: Resource Component for [" + resourceType.getName() + "] Resource with id [" + resourceId - + "]: " + msg; + return "Plugin Error: Resource Component for [" + resourceType.getName() + "] Resource with id [" + + resourceId + "]: " + msg; }
- // public Configuration loadResourceConfiguration(int resourceId) throws PluginContainerException { - // ResourceType resourceType = getResourceType(resourceId); - // ConfigurationFacet configComponent = getConfigurationFacet(resourceId, FacetLockType.READ); - // try { - // Configuration configuration = configComponent.loadResourceConfiguration(); - // if (configuration == null) { - // throw new PluginContainerException("Plugin Error: Resource Component for [" + resourceType.getName() - // + "] Resource with id [" + resourceId + "] returned a null Configuration."); - // } - // - // // If the plugin didn't already set the notes field, set it to something useful. - // if (configuration.getNotes() == null) { - // configuration.setNotes("Resource config for " + resourceType.getName() + " Resource w/ id " + resourceId); - // } - // - // ConfigurationDefinition configurationDefinition = resourceType.getResourceConfigurationDefinition(); - // - // // Normalize and validate the config. - // ConfigurationUtility.normalizeConfiguration(configuration, configurationDefinition); - // List<String> errorMessages = ConfigurationUtility.validateConfiguration(configuration, - // configurationDefinition); - // for (String errorMessage : errorMessages) { - // log.warn("Plugin Error: Invalid " + resourceType.getName() + " Resource configuration returned by " - // + resourceType.getPlugin() + " plugin - " + errorMessage); - // } - // - // return configuration; - // } catch (Throwable t) { - // //noinspection ThrowableInstanceNeverThrown - // throw new PluginContainerException("Cannot load Resource configuration for [" + resourceId + "]", - // new WrappedRemotingException(t)); - // } - // } +// public Configuration loadResourceConfiguration(int resourceId) throws PluginContainerException { +// ResourceType resourceType = getResourceType(resourceId); +// ConfigurationFacet configComponent = getConfigurationFacet(resourceId, FacetLockType.READ); +// try { +// Configuration configuration = configComponent.loadResourceConfiguration(); +// if (configuration == null) { +// throw new PluginContainerException("Plugin Error: Resource Component for [" + resourceType.getName() +// + "] Resource with id [" + resourceId + "] returned a null Configuration."); +// } +// +// // If the plugin didn't already set the notes field, set it to something useful. +// if (configuration.getNotes() == null) { +// configuration.setNotes("Resource config for " + resourceType.getName() + " Resource w/ id " + resourceId); +// } +// +// ConfigurationDefinition configurationDefinition = resourceType.getResourceConfigurationDefinition(); +// +// // Normalize and validate the config. +// ConfigurationUtility.normalizeConfiguration(configuration, configurationDefinition); +// List<String> errorMessages = ConfigurationUtility.validateConfiguration(configuration, +// configurationDefinition); +// for (String errorMessage : errorMessages) { +// log.warn("Plugin Error: Invalid " + resourceType.getName() + " Resource configuration returned by " +// + resourceType.getPlugin() + " plugin - " + errorMessage); +// } +// +// return configuration; +// } catch (Throwable t) { +// //noinspection ThrowableInstanceNeverThrown +// throw new PluginContainerException("Cannot load Resource configuration for [" + resourceId + "]", +// new WrappedRemotingException(t)); +// } +// }
/** * Returns a thread pool that this object will use when asychronously executing configuration operations on a @@ -288,8 +321,7 @@ public class ConfigurationManager extends AgentService implements ContainerServi protected ConfigurationFacet getConfigurationFacet(int resourceId, FacetLockType lockType) throws PluginContainerException { boolean daemonThread = (lockType != FacetLockType.WRITE); - return ComponentUtil.getComponent(resourceId, ConfigurationFacet.class, lockType, FACET_METHOD_TIMEOUT, - daemonThread, true); + return ComponentUtil.getComponent(resourceId, ConfigurationFacet.class, lockType, FACET_METHOD_TIMEOUT, daemonThread, true); }
/** @@ -318,4 +350,4 @@ public class ConfigurationManager extends AgentService implements ContainerServi
return null; } -} \ No newline at end of file +} diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigurationManagerUnitTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigurationManagerUnitTest.java index d86410d..01aa641 100644 --- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigurationManagerUnitTest.java +++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigurationManagerUnitTest.java @@ -30,7 +30,6 @@ import org.rhq.core.clientapi.agent.PluginContainerException; import org.rhq.core.domain.configuration.Configuration; import org.rhq.core.domain.configuration.RawConfiguration; import org.rhq.core.domain.configuration.PropertySimple; -import org.rhq.core.domain.configuration.PropertyList; import org.rhq.core.domain.resource.ResourceType; import org.rhq.core.pc.util.ComponentService; import org.rhq.core.pc.util.FacetLockType; @@ -115,21 +114,19 @@ public class ConfigurationManagerUnitTest extends ConfigManagementTest { }
@Test - public void mergingStucturedIntoRawShouldUpdateConfigWithModifiedRaws() throws Exception { + public void mergingStucturedIntoRawShouldUpdateLatestRawConfigs() throws Exception { final Configuration config = new Configuration(); + config.addRawConfiguration(createRawConfiguration("/tmp/raw0.txt"));
- final RawConfiguration originalRaw1 = createRawConfiguration("/tmp/raw1.txt"); - config.addRawConfiguration(originalRaw1); + final RawConfiguration raw1 = createRawConfiguration("/tmp/raw1.txt"); + config.addRawConfiguration(raw1);
- final RawConfiguration originalRaw2 = createRawConfiguration("/tmp/raw2.txt"); - config.addRawConfiguration(originalRaw2); + final RawConfiguration raw2 = createRawConfiguration("/tmp/raw2.txt");
- final RawConfiguration originalRaw3 = createRawConfiguration("/tmp/raw3.txt"); - config.addRawConfiguration(originalRaw3); + final Set<RawConfiguration> latestRaws = toSet(raw1, raw2);
final RawConfiguration mergedRaw1 = createRawConfiguration("/tmp/raw1.txt"); final RawConfiguration mergedRaw2 = createRawConfiguration("/tmp/raw2.txt"); - final RawConfiguration mergedRaw3 = createRawConfiguration("/tmp/raw3.txt");
final ResourceConfigurationFacet facet = context.mock(ResourceConfigurationFacet.class);
@@ -144,11 +141,10 @@ public class ConfigurationManagerUnitTest extends ConfigManagementTest { onlyIfStarted); will(returnValue(facet));
- atLeast(1).of(facet).loadRawConfigurations(); will(returnValue(config.getRawConfigurations())); + atLeast(1).of(facet).loadRawConfigurations(); will(returnValue(latestRaws));
- oneOf(facet).mergeRawConfiguration(config, originalRaw1); will(returnValue(mergedRaw1)); - oneOf(facet).mergeRawConfiguration(config, originalRaw2); will(returnValue(mergedRaw2)); - oneOf(facet).mergeRawConfiguration(config, originalRaw3); will(returnValue(mergedRaw3)); + oneOf(facet).mergeRawConfiguration(config, raw1); will(returnValue(mergedRaw1)); + oneOf(facet).mergeRawConfiguration(config, raw2); will(returnValue(mergedRaw2)); }});
Configuration mergedConfig = configurationMgr.merge(config, resourceId, FROM_STRUCTURED); @@ -156,7 +152,6 @@ public class ConfigurationManagerUnitTest extends ConfigManagementTest { Configuration expectedConfig = new Configuration(); expectedConfig.addRawConfiguration(mergedRaw1); expectedConfig.addRawConfiguration(mergedRaw2); - expectedConfig.addRawConfiguration(mergedRaw3);
assertStructuredMergedIntoRaws(mergedConfig, expectedConfig, "Failed to update existing raw configs"); } @@ -168,6 +163,8 @@ public class ConfigurationManagerUnitTest extends ConfigManagementTest { final RawConfiguration originalRaw = createRawConfiguration("/tmp/raw.txt"); config.addRawConfiguration(originalRaw);
+ final Set<RawConfiguration> latestRaws = toSet(originalRaw); + final ResourceConfigurationFacet facet = context.mock(ResourceConfigurationFacet.class);
context.checking(new Expectations() {{ @@ -181,7 +178,7 @@ public class ConfigurationManagerUnitTest extends ConfigManagementTest { onlyIfStarted); will(returnValue(facet));
- atLeast(1).of(facet).loadRawConfigurations(); will(returnValue(config.getRawConfigurations())); + atLeast(1).of(facet).loadRawConfigurations(); will(returnValue(latestRaws));
oneOf(facet).mergeRawConfiguration(config, originalRaw); will(returnValue(null)); }}); @@ -247,8 +244,10 @@ public class ConfigurationManagerUnitTest extends ConfigManagementTest { }
@Test - public void mergingRawsIntoStructuredShouldUpdateConfigWithModifedStructured() throws Exception { - Configuration config = new Configuration(); + public void mergingRawsIntoStructuredShouldUpdateLatestStructuredConfig() throws Exception { + final Configuration config = new Configuration(); + config.put(new PropertySimple("x", "0")); + config.put(new PropertySimple("z", "3"));
final RawConfiguration raw1 = createRawConfiguration("/tmp/foo.txt"); config.addRawConfiguration(raw1); @@ -256,7 +255,9 @@ public class ConfigurationManagerUnitTest extends ConfigManagementTest { final RawConfiguration raw2 = createRawConfiguration("/tmp/bar.txt"); config.addRawConfiguration(raw2);
- final Configuration structured = new Configuration(); + final Configuration latestStructured = new Configuration(); + latestStructured.put(new PropertySimple("x", "1")); + latestStructured.put(new PropertySimple("y", "1"));
final ResourceConfigurationFacet facet = context.mock(ResourceConfigurationFacet.class);
@@ -271,17 +272,17 @@ public class ConfigurationManagerUnitTest extends ConfigManagementTest { onlyIfStarted); will(returnValue(facet));
- atLeast(1).of(facet).loadStructuredConfiguration(); will(returnValue(structured)); + atLeast(1).of(facet).loadStructuredConfiguration(); will(returnValue(latestStructured));
- oneOf(facet).mergeStructuredConfiguration(raw1, structured); - oneOf(facet).mergeStructuredConfiguration(raw2, structured); + oneOf(facet).mergeStructuredConfiguration(raw1, config); + oneOf(facet).mergeStructuredConfiguration(raw2, config); }});
Configuration mergedConfig = configurationMgr.merge(config, resourceId, FROM_RAW);
assertEquals( mergedConfig.getAllProperties(), - structured.getAllProperties(), + latestStructured.getAllProperties(), "Failed to merged raw into structured." ); } diff --git a/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/LegacyServer.groovy b/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/LegacyServer.groovy new file mode 100644 index 0000000..e779d10 --- /dev/null +++ b/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/LegacyServer.groovy @@ -0,0 +1,12 @@ +package org.rhq.plugins.test.rawconfig +/** + * Created by IntelliJ IDEA. + * User: john + * Date: Nov 17, 2009 + * Time: 12:35:30 AM + * To change this template use File | Settings | File Templates. + */ + +public class LegacyServer { + +} \ No newline at end of file
commit c84c7f5f29b7ca51558593dbfa641b42b3aaca50 Author: Lukas Krejci lkrejci@redhat.com Date: Wed Nov 18 18:25:47 2009 +0100
unit tests for cron plugin
diff --git a/modules/plugins/cron/pom.xml b/modules/plugins/cron/pom.xml index 5992726..af77bc8 100644 --- a/modules/plugins/cron/pom.xml +++ b/modules/plugins/cron/pom.xml @@ -67,6 +67,7 @@ <copy toDir="target/itest/plugins" flatten="true"> <fileset dir="${settings.localRepository}/"> <include name="org/rhq/rhq-platform-plugin/${project.version}/rhq-platform-plugin-${project.version}.jar" /> + <include name="org/rhq/rhq-augeas-plugin/${project.version}/rhq-augeas-plugin-${project.version}.jar" /> </fileset> <fileset dir="${project.build.directory}"> <include name="${project.artifactId}-${project.version}.jar" /> diff --git a/modules/plugins/cron/src/test/java/org/rhq/plugins/cron/test/CronComponentTest.java b/modules/plugins/cron/src/test/java/org/rhq/plugins/cron/test/CronComponentTest.java new file mode 100644 index 0000000..7aee6e1 --- /dev/null +++ b/modules/plugins/cron/src/test/java/org/rhq/plugins/cron/test/CronComponentTest.java @@ -0,0 +1,109 @@ +package org.rhq.plugins.cron.test; +import org.rhq.core.domain.configuration.Configuration; +import org.rhq.core.domain.configuration.PropertyList; +import org.rhq.core.domain.configuration.PropertyMap; +import org.rhq.core.domain.configuration.PropertySimple; +import org.rhq.plugins.augeas.AugeasConfigurationComponent; +import org.rhq.plugins.augeas.test.AbstractAugeasConfigurationComponentTest; + +/* + * RHQ Management Platform + * Copyright (C) 2005-2009 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, version 2, as + * published by the Free Software Foundation, and/or the GNU Lesser + * General Public License, version 2.1, also as published by the Free + * Software Foundation. + * + * 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 and the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * and the GNU Lesser 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. + */ + +/** + * Tests for cron component. + * + * @author Lukas Krejci + */ +public class CronComponentTest extends AbstractAugeasConfigurationComponentTest { + + @Override + protected void tweakDefaultPluginConfig(Configuration defaultPluginConfig) { + super.tweakDefaultPluginConfig(defaultPluginConfig); + //the base cannot support the /etc/cron.d/* glob pattern because it reads stuff from the classloader resource stream + //that doesn't support searching (or does it?) + //so we have to update the include globs to include only concrete file paths + defaultPluginConfig.put(new PropertySimple(AugeasConfigurationComponent.INCLUDE_GLOBS_PROP, "/etc/crontab|/etc/cron.d/another-crontab")); + } + + @Override + protected Configuration getExpectedResourceConfig() { + Configuration config = new Configuration(); + + PropertyList hourlyJobs = new PropertyList("hourlyJobs"); + config.put(hourlyJobs); + + PropertyList dailyJobs = new PropertyList("dailyJobs"); + config.put(dailyJobs); + + PropertyList weeklyJobs = new PropertyList("weeklyJobs"); + config.put(weeklyJobs); + + PropertyList monthlyJobs = new PropertyList("monthlyJobs"); + config.put(monthlyJobs); + + PropertyList yearlyJobs = new PropertyList("yearlyJobs"); + config.put(yearlyJobs); + + PropertyMap yearlyJob = new PropertyMap("."); + yearlyJob.put(new PropertySimple("time/minute", "0")); + yearlyJob.put(new PropertySimple("time/hour", "0")); + yearlyJob.put(new PropertySimple("time/dayofmonth", "1")); + yearlyJob.put(new PropertySimple("time/month", "1")); + yearlyJob.put(new PropertySimple("time/dayofweek", "*")); + yearlyJob.put(new PropertySimple("user", "root")); + yearlyJob.put(new PropertySimple(".", "echo "tmp"")); + yearlyJob.put(new PropertySimple("crontab", "/etc/crontab")); + yearlyJobs.add(yearlyJob); + + PropertyMap dailyJob = new PropertyMap("."); + dailyJob.put(new PropertySimple("time/minute", "1")); + dailyJob.put(new PropertySimple("time/hour", "0")); + dailyJob.put(new PropertySimple("time/dayofmonth", "*")); + dailyJob.put(new PropertySimple("time/month", "*")); + dailyJob.put(new PropertySimple("time/dayofweek", "*")); + dailyJob.put(new PropertySimple("user", "root")); + dailyJob.put(new PropertySimple(".", "echo "tmp"")); + dailyJob.put(new PropertySimple("crontab", "/etc/cron.d/another-crontab")); + dailyJobs.add(dailyJob); + + return config; + } + + @Override + protected String getPluginName() { + return "Cron"; + } + + @Override + protected String getResourceTypeName() { + return "Cron"; + } + + @Override + protected Configuration getUpdatedResourceConfig() { + //This component doesn't support updates. + return getExpectedResourceConfig(); + } + + //TODO add createChildResource tests +} diff --git a/modules/plugins/cron/src/test/java/org/rhq/plugins/cron/test/CronTabComponentTest.java b/modules/plugins/cron/src/test/java/org/rhq/plugins/cron/test/CronTabComponentTest.java new file mode 100644 index 0000000..1e9811d --- /dev/null +++ b/modules/plugins/cron/src/test/java/org/rhq/plugins/cron/test/CronTabComponentTest.java @@ -0,0 +1,132 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2009 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, version 2, as + * published by the Free Software Foundation, and/or the GNU Lesser + * General Public License, version 2.1, also as published by the Free + * Software Foundation. + * + * 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 and the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * and the GNU Lesser 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.plugins.cron.test; + +import java.util.Set; + +import org.rhq.core.domain.configuration.Configuration; +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.resource.Resource; +import org.rhq.core.domain.resource.ResourceType; +import org.rhq.core.pc.PluginContainer; +import org.rhq.core.pc.inventory.InventoryManager; +import org.rhq.plugins.augeas.test.AbstractAugeasConfigurationComponentTest; + +/** + * + * + * @author Lukas Krejci + */ +public class CronTabComponentTest extends AbstractAugeasConfigurationComponentTest { + + @Override + protected Resource getResource() { + //let's pick the "another-crontab file + InventoryManager inventoryManager = PluginContainer.getInstance().getInventoryManager(); + ResourceType resourceType = getResourceType(); + Set<Resource> resources = inventoryManager.getResourcesWithType(resourceType); + + for(Resource res : resources) { + if ("/etc/cron.d/another-crontab".equals(res.getResourceKey())) { + return res; + } + } + return null; + } + + @Override + protected Configuration getExpectedResourceConfig() { + Configuration config = new Configuration(); + + PropertyList envVars = new PropertyList("environmentSettings"); + config.put(envVars); + + PropertyList entries = new PropertyList("entries"); + config.put(entries); + + PropertyMap envVar = new PropertyMap("var"); + envVar.put(new PropertySimple("name", "SHELLVAR")); + envVar.put(new PropertySimple("value", "value")); + envVars.add(envVar); + + PropertyMap entry = new PropertyMap("entry"); + entry.put(new PropertySimple("time/minute", "1")); + entry.put(new PropertySimple("time/hour", "0")); + entry.put(new PropertySimple("time/dayofmonth", "*")); + entry.put(new PropertySimple("time/month", "*")); + entry.put(new PropertySimple("time/dayofweek", "*")); + entry.put(new PropertySimple("user", "root")); + entry.put(new PropertySimple(".", "echo "tmp"")); + entries.add(entry); + + return config; + } + + @Override + protected String getPluginName() { + return "Cron"; + } + + @Override + protected String getResourceTypeName() { + return "Cron Tab"; + } + + @Override + protected Configuration getUpdatedResourceConfig() { + Configuration config = getExpectedResourceConfig(); + + //update the envVar and add a new one + PropertyList envVars = config.getList("environmentSettings"); + PropertyMap existingVar = (PropertyMap) envVars.getList().get(0); + existingVar.put(new PropertySimple("name", "SHELLVARUPDATED")); + existingVar.put(new PropertySimple("value", "updated_value")); + + PropertyMap newVar = new PropertyMap("var"); + newVar.put(new PropertySimple("name", "SHELLVARNEW")); + newVar.put(new PropertySimple("value", "value")); + envVars.add(newVar); + + + //update existing and add a new entry + PropertyList entries = config.getList("entries"); + PropertyMap existingEntry = (PropertyMap) entries.getList().get(0); + existingEntry.put(new PropertySimple("time/minute", "2")); + + PropertyMap newEntry = new PropertyMap("entry"); + newEntry.put(new PropertySimple("time/minute", "1")); + newEntry.put(new PropertySimple("time/hour", "0")); + newEntry.put(new PropertySimple("time/dayofmonth", "*")); + newEntry.put(new PropertySimple("time/month", "*")); + newEntry.put(new PropertySimple("time/dayofweek", "*")); + newEntry.put(new PropertySimple("user", "foo")); + newEntry.put(new PropertySimple(".", "echo "tmp"")); + entries.add(newEntry); + + return config; + } + +} diff --git a/modules/plugins/cron/src/test/resources/etc/cron.d/another-crontab b/modules/plugins/cron/src/test/resources/etc/cron.d/another-crontab new file mode 100644 index 0000000..27b1d1f --- /dev/null +++ b/modules/plugins/cron/src/test/resources/etc/cron.d/another-crontab @@ -0,0 +1,4 @@ +#another crontab file loaded from under cron.d +SHELLVAR=value + +1 0 * * * root echo "tmp" diff --git a/modules/plugins/cron/src/test/resources/etc/crontab b/modules/plugins/cron/src/test/resources/etc/crontab new file mode 100644 index 0000000..73be4d2 --- /dev/null +++ b/modules/plugins/cron/src/test/resources/etc/crontab @@ -0,0 +1,2 @@ +#a testing crontab file +0 0 1 1 * root echo "tmp"
commit 227aebcc3d90031b452db47c4a8d1a105f4e6754 Author: Lukas Krejci lkrejci@redhat.com Date: Wed Nov 18 18:25:21 2009 +0100
Correctly handling the augeas root path.
diff --git a/modules/plugins/cron/src/main/java/org/rhq/plugins/cron/CronTabComponent.java b/modules/plugins/cron/src/main/java/org/rhq/plugins/cron/CronTabComponent.java index 954605f..e0fbebf 100644 --- a/modules/plugins/cron/src/main/java/org/rhq/plugins/cron/CronTabComponent.java +++ b/modules/plugins/cron/src/main/java/org/rhq/plugins/cron/CronTabComponent.java @@ -59,8 +59,10 @@ public class CronTabComponent extends AugeasConfigurationComponent<CronComponent private String rootPath;
public void start(ResourceContext<CronComponent> context) throws InvalidPluginConfigurationException, Exception { - crontabFile = new File(context.getResourceKey()); - rootPath = AugeasNode.SEPARATOR + "files" + crontabFile.getAbsolutePath(); + String augeasRootPath = context.getPluginConfiguration().getSimpleValue(AugeasConfigurationComponent.AUGEAS_ROOT_PATH_PROP, AugeasConfigurationComponent.DEFAULT_AUGEAS_ROOT_PATH); + + crontabFile = new File(augeasRootPath, context.getResourceKey()); + rootPath = AugeasNode.SEPARATOR + "files" + context.getResourceKey(); super.start(context); }
diff --git a/modules/plugins/cron/src/main/java/org/rhq/plugins/cron/CronTabDiscoveryComponent.java b/modules/plugins/cron/src/main/java/org/rhq/plugins/cron/CronTabDiscoveryComponent.java index fca42db..b486fd2 100644 --- a/modules/plugins/cron/src/main/java/org/rhq/plugins/cron/CronTabDiscoveryComponent.java +++ b/modules/plugins/cron/src/main/java/org/rhq/plugins/cron/CronTabDiscoveryComponent.java @@ -30,6 +30,7 @@ import java.util.List; import java.util.Set;
import org.rhq.core.domain.configuration.Configuration; +import org.rhq.core.domain.configuration.PropertySimple; import org.rhq.core.domain.resource.ResourceType; import org.rhq.core.pluginapi.inventory.DiscoveredResourceDetails; import org.rhq.core.pluginapi.inventory.InvalidPluginConfigurationException; @@ -56,19 +57,22 @@ public class CronTabDiscoveryComponent implements ResourceDiscoveryComponent<Cro List<String> excludes = AugeasConfigurationDiscoveryComponent.getGlobList( cronConfiguration.getSimple(AugeasConfigurationComponent.EXCLUDE_GLOBS_PROP));
- List<File> files = Glob.matchAll(new File(AugeasConfigurationComponent.DEFAULT_AUGEAS_ROOT_PATH), includes); + String rootPath = cronConfiguration.getSimpleValue(AugeasConfigurationComponent.AUGEAS_ROOT_PATH_PROP, AugeasConfigurationComponent.DEFAULT_AUGEAS_ROOT_PATH); + List<File> files = Glob.matchAll(new File(rootPath), includes); Glob.excludeAll(files, excludes);
HashSet<DiscoveredResourceDetails> results = new HashSet<DiscoveredResourceDetails>();
ResourceType resourceType = context.getResourceType();
+ int pathUnderRootStartIdx = rootPath.endsWith(File.pathSeparator) ? rootPath.length() - 1 : rootPath.length(); + for (File f : files) { - String resourceKey = f.getAbsolutePath(); + String resourceKey = f.getAbsolutePath().substring(pathUnderRootStartIdx); Configuration defaultConfiguration = context.getDefaultPluginConfiguration(); defaultConfiguration.put(AugeasConfigurationDiscoveryComponent.getGlobList( AugeasConfigurationComponent.INCLUDE_GLOBS_PROP, Collections.singletonList(resourceKey))); - + defaultConfiguration.put(new PropertySimple(AugeasConfigurationComponent.AUGEAS_ROOT_PATH_PROP, rootPath)); DiscoveredResourceDetails result = new DiscoveredResourceDetails(resourceType, resourceKey, resourceKey, null, null, defaultConfiguration, null); results.add(result);
commit 26b1a355ccb1dc12a8b62f667f31ce499305ef67 Author: Lukas Krejci lkrejci@redhat.com Date: Wed Nov 18 18:23:39 2009 +0100
Making CronComponent implicitly fail on config update because it is designed as readonly.
diff --git a/modules/plugins/cron/src/main/java/org/rhq/plugins/cron/CronComponent.java b/modules/plugins/cron/src/main/java/org/rhq/plugins/cron/CronComponent.java index 2cc5f8a..8ef5b19 100644 --- a/modules/plugins/cron/src/main/java/org/rhq/plugins/cron/CronComponent.java +++ b/modules/plugins/cron/src/main/java/org/rhq/plugins/cron/CronComponent.java @@ -26,6 +26,7 @@ import net.augeas.Augeas; import net.augeas.AugeasException;
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; @@ -34,6 +35,7 @@ import org.rhq.core.domain.configuration.definition.PropertyDefinition; import org.rhq.core.domain.configuration.definition.PropertyDefinitionList; import org.rhq.core.domain.configuration.definition.PropertyDefinitionSimple; import org.rhq.core.domain.resource.CreateResourceStatus; +import org.rhq.core.pluginapi.configuration.ConfigurationUpdateReport; import org.rhq.core.pluginapi.inventory.CreateChildResourceFacet; import org.rhq.core.pluginapi.inventory.CreateResourceReport; import org.rhq.plugins.augeas.AugeasConfigurationComponent; @@ -91,6 +93,12 @@ public class CronComponent extends AugeasConfigurationComponent<PlatformComponen }
@Override + public void updateResourceConfiguration(ConfigurationUpdateReport report) { + report.setErrorMessage("This is a readonly view of cron tabs. Update isn't supported."); + report.setStatus(ConfigurationUpdateStatus.FAILURE); + } + + @Override protected String getAugeasPathRelativeToParent(PropertyDefinition propDef, AugeasNode parentNode, Augeas augeas) { String name = propDef.getName(); if (CRONTAB_PROP.equals(name)) {
commit 8e0ae4c640bcd3d9841d41f48fe08d2e4dfdd72d Author: Adam Young ayoung@redhat.com Date: Tue Nov 17 21:01:31 2009 -0500
Corrected color for file list
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit-raw.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit-raw.xhtml index c15712d..860fb2c 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit-raw.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit-raw.xhtml @@ -46,7 +46,7 @@ <input type="hidden" name="id" value="#{ResourceUIBean.id}" /> <tr> - <td bgcolor="lightblue" width="25%" valign="top"> + <td bgcolor="#a4b2b9" width="25%" valign="top"> <h:outputText value="#{messages.files}" /> <div>______________________________________</div> diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view-raw.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view-raw.xhtml index ae6a1e8..4b137aa 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view-raw.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view-raw.xhtml @@ -43,7 +43,7 @@ <table class="summary-props-table" style=""> <tr> - <td bgcolor="lightblue" width="25%" valign="top">Files + <td bgcolor="#a4b2b9" width="25%" valign="top">Files <h:panelGroup id="changedFiles" layout="vertical"> <h:form> <input type="hidden" name="id" value="#{ResourceUIBean.id}" />
commit 301a9da0580fb40f3972c093e229c36398735412 Author: Adam Young ayoung@redhat.com Date: Tue Nov 17 20:06:13 2009 -0500
Merge fixed
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManager.java index 9cc1a9d..c5af995 100644 --- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManager.java +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManager.java @@ -22,11 +22,14 @@ */ package org.rhq.core.pc.configuration;
-import java.util.List; -import java.util.Set; -import java.util.Queue; import java.util.LinkedList; -import java.util.concurrent.*; +import java.util.Queue; +import java.util.Set; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.TimeUnit;
import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -35,24 +38,21 @@ import org.apache.maven.artifact.versioning.ComparableVersion; import org.rhq.core.clientapi.agent.PluginContainerException; import org.rhq.core.clientapi.agent.configuration.ConfigurationAgentService; import org.rhq.core.clientapi.agent.configuration.ConfigurationUpdateRequest; -import org.rhq.core.clientapi.agent.configuration.ConfigurationUtility; import org.rhq.core.clientapi.server.configuration.ConfigurationServerService; import org.rhq.core.clientapi.server.configuration.ConfigurationUpdateResponse; import org.rhq.core.domain.configuration.Configuration; import org.rhq.core.domain.configuration.RawConfiguration; -import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; import org.rhq.core.domain.resource.ResourceType; import org.rhq.core.pc.ContainerService; -import org.rhq.core.pc.PluginContainerConfiguration; import org.rhq.core.pc.PluginContainer; -import org.rhq.core.pc.util.ComponentService; +import org.rhq.core.pc.PluginContainerConfiguration; import org.rhq.core.pc.agent.AgentService; +import org.rhq.core.pc.util.ComponentService; import org.rhq.core.pc.util.ComponentUtil; import org.rhq.core.pc.util.FacetLockType; import org.rhq.core.pc.util.LoggingThreadFactory; import org.rhq.core.pluginapi.configuration.ConfigurationFacet; import org.rhq.core.pluginapi.configuration.ResourceConfigurationFacet; -import org.rhq.core.util.exception.WrappedRemotingException;
/** * Manages configuration of all resources across all plugins. @@ -85,17 +85,14 @@ public class ConfigurationManager extends AgentService implements ContainerServi LoggingThreadFactory threadFactory = new LoggingThreadFactory(SENDER_THREAD_POOL_NAME, true); threadPool = new ScheduledThreadPoolExecutor(1, threadFactory);
- ConfigurationCheckExecutor configurationChecker = - new ConfigurationCheckExecutor(this, getConfigurationServerService(), - PluginContainer.getInstance().getInventoryManager()); + ConfigurationCheckExecutor configurationChecker = new ConfigurationCheckExecutor(this, + getConfigurationServerService(), PluginContainer.getInstance().getInventoryManager());
if (pluginContainerConfiguration.getConfigurationDiscoveryPeriod() > 0 - && pluginContainerConfiguration.isInsideAgent()) { - threadPool.scheduleAtFixedRate( - configurationChecker, - pluginContainerConfiguration.getConfigurationDiscoveryInitialDelay(), - pluginContainerConfiguration.getConfigurationDiscoveryPeriod(), - TimeUnit.SECONDS); + && pluginContainerConfiguration.isInsideAgent()) { + threadPool.scheduleAtFixedRate(configurationChecker, pluginContainerConfiguration + .getConfigurationDiscoveryInitialDelay(), pluginContainerConfiguration + .getConfigurationDiscoveryPeriod(), TimeUnit.SECONDS); } }
@@ -174,8 +171,7 @@ public class ConfigurationManager extends AgentService implements ContainerServi
if (fromStructured) { mergedStructuredIntoRaws(configuration, facet); - } - else { + } else { mergeRawsIntoStructured(configuration, facet); }
@@ -183,24 +179,17 @@ public class ConfigurationManager extends AgentService implements ContainerServi }
private void mergeRawsIntoStructured(Configuration configuration, ResourceConfigurationFacet facet) { - Configuration structuredConfig = facet.loadStructuredConfiguration(); - - if (structuredConfig != null) { - for (RawConfiguration rawConfig : configuration.getRawConfigurations()) { - facet.mergeStructuredConfiguration(rawConfig, structuredConfig); - } + for (RawConfiguration rawConfig : configuration.getRawConfigurations()) { + facet.mergeStructuredConfiguration(rawConfig, configuration); } }
private void mergedStructuredIntoRaws(Configuration configuration, ResourceConfigurationFacet facet) { - Set<RawConfiguration> rawConfigs = facet.loadRawConfigurations(); - + Set<RawConfiguration> rawConfigs = configuration.getRawConfigurations();//facet.loadRawConfigurations(); if (rawConfigs == null) { return; } - Queue<RawConfiguration> queue = new LinkedList<RawConfiguration>(rawConfigs); - while (!queue.isEmpty()) { RawConfiguration originalRaw = queue.poll(); RawConfiguration mergedRaw = facet.mergeRawConfiguration(configuration, originalRaw); @@ -211,15 +200,13 @@ public class ConfigurationManager extends AgentService implements ContainerServi } }
- private void updateRawConfig(Configuration configuration, RawConfiguration originalRaw, - RawConfiguration mergedRaw) { + private void updateRawConfig(Configuration configuration, RawConfiguration originalRaw, RawConfiguration mergedRaw) {
configuration.removeRawConfiguration(originalRaw); configuration.addRawConfiguration(mergedRaw); }
- public Configuration loadResourceConfiguration(int resourceId) - throws PluginContainerException { + public Configuration loadResourceConfiguration(int resourceId) throws PluginContainerException {
LoadResourceConfiguration loadConfig = loadConfigFactory.getStrategy(resourceId); Configuration configuration = null; @@ -227,7 +214,7 @@ public class ConfigurationManager extends AgentService implements ContainerServi try { configuration = loadConfig.execute(resourceId); } catch (Throwable t) { - throw new PluginContainerException(createErrorMsg(resourceId, "An exception was thrown."), t); + throw new PluginContainerException(createErrorMsg(resourceId, "An exception was thrown."), t); }
if (configuration == null) { @@ -240,43 +227,43 @@ public class ConfigurationManager extends AgentService implements ContainerServi private String createErrorMsg(int resourceId, String msg) throws PluginContainerException { ResourceType resourceType = componentService.getResourceType(resourceId);
- return "Plugin Error: Resource Component for [" + resourceType.getName() + "] Resource with id [" + - resourceId + "]: " + msg; + return "Plugin Error: Resource Component for [" + resourceType.getName() + "] Resource with id [" + resourceId + + "]: " + msg; }
-// public Configuration loadResourceConfiguration(int resourceId) throws PluginContainerException { -// ResourceType resourceType = getResourceType(resourceId); -// ConfigurationFacet configComponent = getConfigurationFacet(resourceId, FacetLockType.READ); -// try { -// Configuration configuration = configComponent.loadResourceConfiguration(); -// if (configuration == null) { -// throw new PluginContainerException("Plugin Error: Resource Component for [" + resourceType.getName() -// + "] Resource with id [" + resourceId + "] returned a null Configuration."); -// } -// -// // If the plugin didn't already set the notes field, set it to something useful. -// if (configuration.getNotes() == null) { -// configuration.setNotes("Resource config for " + resourceType.getName() + " Resource w/ id " + resourceId); -// } -// -// ConfigurationDefinition configurationDefinition = resourceType.getResourceConfigurationDefinition(); -// -// // Normalize and validate the config. -// ConfigurationUtility.normalizeConfiguration(configuration, configurationDefinition); -// List<String> errorMessages = ConfigurationUtility.validateConfiguration(configuration, -// configurationDefinition); -// for (String errorMessage : errorMessages) { -// log.warn("Plugin Error: Invalid " + resourceType.getName() + " Resource configuration returned by " -// + resourceType.getPlugin() + " plugin - " + errorMessage); -// } -// -// return configuration; -// } catch (Throwable t) { -// //noinspection ThrowableInstanceNeverThrown -// throw new PluginContainerException("Cannot load Resource configuration for [" + resourceId + "]", -// new WrappedRemotingException(t)); -// } -// } + // public Configuration loadResourceConfiguration(int resourceId) throws PluginContainerException { + // ResourceType resourceType = getResourceType(resourceId); + // ConfigurationFacet configComponent = getConfigurationFacet(resourceId, FacetLockType.READ); + // try { + // Configuration configuration = configComponent.loadResourceConfiguration(); + // if (configuration == null) { + // throw new PluginContainerException("Plugin Error: Resource Component for [" + resourceType.getName() + // + "] Resource with id [" + resourceId + "] returned a null Configuration."); + // } + // + // // If the plugin didn't already set the notes field, set it to something useful. + // if (configuration.getNotes() == null) { + // configuration.setNotes("Resource config for " + resourceType.getName() + " Resource w/ id " + resourceId); + // } + // + // ConfigurationDefinition configurationDefinition = resourceType.getResourceConfigurationDefinition(); + // + // // Normalize and validate the config. + // ConfigurationUtility.normalizeConfiguration(configuration, configurationDefinition); + // List<String> errorMessages = ConfigurationUtility.validateConfiguration(configuration, + // configurationDefinition); + // for (String errorMessage : errorMessages) { + // log.warn("Plugin Error: Invalid " + resourceType.getName() + " Resource configuration returned by " + // + resourceType.getPlugin() + " plugin - " + errorMessage); + // } + // + // return configuration; + // } catch (Throwable t) { + // //noinspection ThrowableInstanceNeverThrown + // throw new PluginContainerException("Cannot load Resource configuration for [" + resourceId + "]", + // new WrappedRemotingException(t)); + // } + // }
/** * Returns a thread pool that this object will use when asychronously executing configuration operations on a @@ -301,7 +288,8 @@ public class ConfigurationManager extends AgentService implements ContainerServi protected ConfigurationFacet getConfigurationFacet(int resourceId, FacetLockType lockType) throws PluginContainerException { boolean daemonThread = (lockType != FacetLockType.WRITE); - return ComponentUtil.getComponent(resourceId, ConfigurationFacet.class, lockType, FACET_METHOD_TIMEOUT, daemonThread, true); + return ComponentUtil.getComponent(resourceId, ConfigurationFacet.class, lockType, FACET_METHOD_TIMEOUT, + daemonThread, true); }
/** diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/RawConfigCollection.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/RawConfigCollection.java index b12bf20..dddfc0d 100644 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/RawConfigCollection.java +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/RawConfigCollection.java @@ -66,6 +66,9 @@ public class RawConfigCollection extends AbstractConfigurationUIBean implements private Configuration getMergedConfiguration() { for (RawConfiguration raw : getRawConfigDelegate().modified.values()) { getRaws().put(raw.getPath(), raw); + log.error("Just merged in raw path =[" + raw.getPath() + "]"); + log.error(" file =[" + new String(raw.getContents()) + "]"); + } getConfiguration().getRawConfigurations().clear(); getConfiguration().getRawConfigurations().addAll(getRaws().values()); @@ -287,20 +290,38 @@ public class RawConfigCollection extends AbstractConfigurationUIBean implements
public String switchToraw() { log.error("switch2raw called"); + dumpProperties(getConfiguration(), log); Configuration configuration = LookupUtil.getConfigurationManager().translateResourceConfiguration( EnterpriseFacesContextUtility.getSubject(), getResourceId(), getMergedConfiguration(), true); + log.error("switch2raw post merge"); + dumpProperties(getConfiguration(), log);
getRawConfigDelegate().setConfiguration(configuration); - getRawConfigDelegate().setRaws(null); + for (RawConfiguration raw : configuration.getRawConfigurations()) { + getRawConfigDelegate().getRaws().put(raw.getPath(), raw); + } getRawConfigDelegate().current = null; + getRawConfigDelegate().setConfiguration(configuration); + getRawConfigDelegateMap().put(getResourceId(), getRawConfigDelegate());
return "/rhq/resource/configuration/edit-raw.xhtml?currentResourceId=" + getResourceId(); }
+ void dumpProperties(Configuration conf, Log log) { + for (String key : conf.getAllProperties().keySet()) { + log.error("property=" + conf.getAllProperties().get(key)); + } + } + public String switchTostructured() { log.error("switch2structured called"); + + dumpProperties(getConfiguration(), log); Configuration configuration = LookupUtil.getConfigurationManager().translateResourceConfiguration( EnterpriseFacesContextUtility.getSubject(), getResourceId(), getMergedConfiguration(), false); + log.error("switch2structured post merge"); + + dumpProperties(configuration, log);
for (Property property : configuration.getAllProperties().values()) { property.setConfiguration(configuration);
commit ea2d05ef10703777faf3aca210eb2a4ec0b3833a Author: Adam Young ayoung@redhat.com Date: Tue Nov 17 16:07:27 2009 -0500
straightening out the raws collection
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/RawConfigCollection.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/RawConfigCollection.java index 781c390..b12bf20 100644 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/RawConfigCollection.java +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/RawConfigCollection.java @@ -202,14 +202,6 @@ public class RawConfigCollection extends AbstractConfigurationUIBean implements */ @Create public void init() { - /* - ResourceConfigurationUpdate resourceConfigurationUpdate = getConfigurationManager() - .getLatestResourceConfigurationUpdate(EnterpriseFacesContextUtility.getSubject(), - EnterpriseFacesContextUtility.getResource().getResourceType().getId()); - - resourceConfigurationUpdate.getConfiguration().getRawConfigurations(); - getConfigurationManager().translateResourceConfiguration(subject, resourceId, configuration, fromStructured) - */
}
@@ -298,11 +290,10 @@ public class RawConfigCollection extends AbstractConfigurationUIBean implements Configuration configuration = LookupUtil.getConfigurationManager().translateResourceConfiguration( EnterpriseFacesContextUtility.getSubject(), getResourceId(), getMergedConfiguration(), true);
- for (RawConfiguration raw : configuration.getRawConfigurations()) { - getRawConfigDelegate().getRaws().put(raw.getPath(), raw); - getRawConfigDelegate().setConfiguration(configuration); - } + getRawConfigDelegate().setConfiguration(configuration); + getRawConfigDelegate().setRaws(null); getRawConfigDelegate().current = null; + return "/rhq/resource/configuration/edit-raw.xhtml?currentResourceId=" + getResourceId(); }
@@ -320,6 +311,7 @@ public class RawConfigCollection extends AbstractConfigurationUIBean implements getRawConfigDelegate().setConfiguration(configuration); } getRawConfigDelegate().current = null; + getRawConfigDelegate().setConfiguration(configuration);
return "/rhq/resource/configuration/edit.xhtml?currentResourceId=" + getResourceId(); } diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit.xhtml index 0b421cb..6d3de6f 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit.xhtml @@ -38,7 +38,7 @@ THIS TEXT WILL BE REMOVED. </h:panelGroup> <onc:config configurationDefinition="#{ExistingResourceConfigurationUIBean.configurationDefinition}" - configuration="#{rawConfigCollection.configuration}" + configuration="#{ExistingResourceConfigurationUIBean.configuration}" nullConfigurationDefinitionMessage="#{ExistingResourceConfigurationUIBean.nullConfigurationDefinitionMessage}" nullConfigurationMessage="#{ExistingResourceConfigurationUIBean.nullConfigurationMessage}" prevalidate="true"/>
commit 26a1a2fc2e2b9940ef0bcb7c251c3cced7a96be8 Author: John Sanda john@localhost.localdomain Date: Tue Nov 17 00:28:12 2009 -0500
[US 4] Updating ConfigurationManager to better support translating raw to structured
Also updating raw-config-test plugin to support the API change in ResourceConfigurationFacet where the mergeRawConfiguration() returns a RawConfiguration object.
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManager.java index 9eb9ab3..9cc1a9d 100644 --- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManager.java +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManager.java @@ -176,14 +176,22 @@ public class ConfigurationManager extends AgentService implements ContainerServi mergedStructuredIntoRaws(configuration, facet); } else { - for (RawConfiguration rawConfig : configuration.getRawConfigurations()) { - facet.mergeStructuredConfiguration(rawConfig, configuration); - } + mergeRawsIntoStructured(configuration, facet); }
return configuration; }
+ private void mergeRawsIntoStructured(Configuration configuration, ResourceConfigurationFacet facet) { + Configuration structuredConfig = facet.loadStructuredConfiguration(); + + if (structuredConfig != null) { + for (RawConfiguration rawConfig : configuration.getRawConfigurations()) { + facet.mergeStructuredConfiguration(rawConfig, structuredConfig); + } + } + } + private void mergedStructuredIntoRaws(Configuration configuration, ResourceConfigurationFacet facet) { Set<RawConfiguration> rawConfigs = facet.loadRawConfigurations();
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigManagementTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigManagementTest.java new file mode 100644 index 0000000..afed6b6 --- /dev/null +++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigManagementTest.java @@ -0,0 +1,105 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2008 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, version 2, as + * published by the Free Software Foundation, and/or the GNU Lesser + * General Public License, version 2.1, also as published by the Free + * Software Foundation. + * + * 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 and the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * and the GNU Lesser 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.core.pc.configuration; + +import org.rhq.core.domain.configuration.Configuration; +import org.rhq.core.domain.configuration.PropertySimple; +import org.rhq.core.domain.configuration.RawConfiguration; +import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; +import org.rhq.core.domain.resource.ResourceType; +import static org.testng.Assert.assertEquals; + +import java.util.HashSet; +import java.util.Random; +import java.util.Set; + +public class ConfigManagementTest extends JMockTest { + + Random random = new Random(); + + ResourceType resourceType = new ResourceType(); + int resourceId = -1; + boolean daemonThread = true; + boolean onlyIfStarted = true; + + Configuration createStructuredConfig() { + Configuration config = new Configuration(); + config.put(new PropertySimple("x", "1")); + config.put(new PropertySimple("y", "2")); + + return config; + } + + Set<RawConfiguration> toSet(RawConfiguration... rawConfigs) { + Set<RawConfiguration> rawConfigSet = new HashSet<RawConfiguration>(); + for (RawConfiguration rawConfig : rawConfigs) { + rawConfigSet.add(rawConfig); + } + return rawConfigSet; + } + + RawConfiguration createRawConfiguration(String path) { + RawConfiguration rawConfig = new RawConfiguration(); + rawConfig.setContents(randomBytes()); + rawConfig.setPath(path); + + return rawConfig; + } + + byte[] randomBytes() { + byte[] bytes = new byte[10]; + random.nextBytes(bytes); + + return bytes; + } + + ConfigurationDefinition getResourceConfigDefinition() { + if (resourceType.getResourceConfigurationDefinition() == null) { + resourceType.setResourceConfigurationDefinition(new ConfigurationDefinition("", "")); + } + return resourceType.getResourceConfigurationDefinition(); + } + + void assertRawsLoaded(Set<RawConfiguration> expectedRaws, Configuration actualConfig) { + assertEquals( + actualConfig.getRawConfigurations(), + expectedRaws, + "The raw configs were not loaded correctly." + ); + } + + void assertStructuredLoaded(Configuration expectedConfig, Configuration actualConfig) { + assertEquals( + actualConfig.getAllProperties(), + expectedConfig.getAllProperties(), + "The structured configuration was not loaded correctly." + ); + } + + void assertNotesSetToDefault(Configuration loadedConfig) { + String expectedNotes = "Resource config for " + resourceType.getName() + " Resource w/ id " + resourceId; + + assertEquals(loadedConfig.getNotes(), expectedNotes, "The notes property should be set to a default when it is not already initialized."); + } +} diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigurationManagerUnitTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigurationManagerUnitTest.java index bf8a8ce..d86410d 100644 --- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigurationManagerUnitTest.java +++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigurationManagerUnitTest.java @@ -24,26 +24,23 @@ package org.rhq.core.pc.configuration;
import static org.testng.Assert.*; -import static java.util.Collections.EMPTY_SET;
import org.jmock.Expectations; -import org.jmock.Sequence; import org.rhq.core.clientapi.agent.PluginContainerException; import org.rhq.core.domain.configuration.Configuration; import org.rhq.core.domain.configuration.RawConfiguration; +import org.rhq.core.domain.configuration.PropertySimple; +import org.rhq.core.domain.configuration.PropertyList; import org.rhq.core.domain.resource.ResourceType; import org.rhq.core.pc.util.ComponentService; import org.rhq.core.pc.util.FacetLockType; import org.rhq.core.pluginapi.configuration.ResourceConfigurationFacet; -import org.rhq.core.pluginapi.configuration.ConfigurationFacet; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test;
-import java.util.Random; import java.util.Set; -import java.util.HashSet;
-public class ConfigurationManagerUnitTest extends LoadConfigTest { +public class ConfigurationManagerUnitTest extends ConfigManagementTest {
static final String LEGACY_AMPS_VERSION = "2.0";
@@ -156,9 +153,12 @@ public class ConfigurationManagerUnitTest extends LoadConfigTest {
Configuration mergedConfig = configurationMgr.merge(config, resourceId, FROM_STRUCTURED);
- Set<RawConfiguration> mergedRaws = toSet(mergedRaw1, mergedRaw2, mergedRaw3); + Configuration expectedConfig = new Configuration(); + expectedConfig.addRawConfiguration(mergedRaw1); + expectedConfig.addRawConfiguration(mergedRaw2); + expectedConfig.addRawConfiguration(mergedRaw3);
- assertEquals(mergedConfig.getRawConfigurations(), mergedRaws, "Failed to merge structured into raws."); + assertStructuredMergedIntoRaws(mergedConfig, expectedConfig, "Failed to update existing raw configs"); }
@Test @@ -188,17 +188,18 @@ public class ConfigurationManagerUnitTest extends LoadConfigTest {
Configuration mergedConfig = configurationMgr.merge(config, resourceId, FROM_STRUCTURED);
- assertEquals( - mergedConfig.getRawConfigurations(), - config.getRawConfigurations(), - "Expected the raw configs to be unmodified when merge operation returns null." - ); + Configuration expectedConfig = new Configuration(); + expectedConfig.addRawConfiguration(originalRaw); + + assertStructuredMergedIntoRaws(mergedConfig, expectedConfig, "cannot merge into a null raw."); }
@Test public void mergingStructuredIntoRawShouldDoNothingIfRawsAreNull() throws Exception { + RawConfiguration raw = createRawConfiguration("/tmp/foo.txt"); + final Configuration config = new Configuration(); - config.addRawConfiguration(createRawConfiguration("/tmp/foo.txt")); + config.addRawConfiguration(raw);
final ResourceConfigurationFacet facet = context.mock(ResourceConfigurationFacet.class);
@@ -218,66 +219,50 @@ public class ConfigurationManagerUnitTest extends LoadConfigTest {
Configuration mergedConfig = configurationMgr.merge(config, resourceId, FROM_STRUCTURED);
- assertEquals( - mergedConfig.getRawConfigurations(), - config.getRawConfigurations(), - "Expected the raw configs to be unmodifed when the facet does not return any raw configs." + Configuration expectedConfig = new Configuration(); + expectedConfig.addRawConfiguration(raw); + + assertStructuredMergedIntoRaws( + mergedConfig, + expectedConfig, + "Expected raw configs should not be modified when the facet does not return any raw configs." ); }
-// @Test -// public void theFacetShouldMergeTheStructuredIntoEachRawWhenFromStructured() throws Exception { -// final RawConfiguration rawConfig1 = createRawConfiguration("/tmp/raw1.txt"); -// final RawConfiguration rawConfig2 = createRawConfiguration("/tmp/raw2.txt"); -// final RawConfiguration rawConfig3 = createRawConfiguration("/tmp/raw3.txt"); -// -// final Set<RawConfiguration> rawConfigs = new HashSet<RawConfiguration>(); -// rawConfigs.add(rawConfig1); -// rawConfigs.add(rawConfig2); -// rawConfigs.add(rawConfig3); -// -// final Configuration configuration = new Configuration(); -// configuration.addRawConfiguration(rawConfig1); -// configuration.addRawConfiguration(rawConfig2); -// configuration.addRawConfiguration(rawConfig3); -// -// final ResourceConfigurationFacet facet = context.mock(ResourceConfigurationFacet.class); -// -// final Sequence merge = context.sequence("merge"); -// -// context.checking(new Expectations(){{ -// atLeast(1).of(componentService).getComponent(resourceId, -// ResourceConfigurationFacet.class, -// FacetLockType.READ, -// LoadResourceConfiguration.FACET_METHOD_TIMEOUT, -// daemonThread, -// onlyIfStarted); -// will(returnValue(facet)); -// -// atLeast(1).of(facet).loadRawConfigurations(); will(returnValue(rawConfigs)); -// -// oneOf(facet).mergeRawConfiguration(configuration, rawConfig1); -// oneOf(facet).mergeRawConfiguration(configuration, rawConfig2); -// oneOf(facet).mergeRawConfiguration(configuration, rawConfig3); -// }}); -// -// Configuration actualConfig = configurationMgr.merge(configuration, resourceId, FROM_STRUCTURED); -// } + void assertStructuredMergedIntoRaws(Configuration actual, Configuration expected, String msg) { + Set<RawConfiguration> actualRaws = actual.getRawConfigurations(); + Set<RawConfiguration> expectedRaws = expected.getRawConfigurations(); + + assertEquals( + actualRaws.size(), + expectedRaws.size(), + "Merging structured into raws failed, got back the wrong number of raws. -- " + msg + ); + for (RawConfiguration expectedRaw : expectedRaws) { + assertTrue( + actualRaws.contains(expectedRaw), + "Merging structured into raws failed, failed to find to find raw config [" + expectedRaw + "] -- " + msg + ); + } + }
@Test - public void theFacetShouldMergeEachRawIntoTheStructuredWhenFromRaw() throws Exception { - final RawConfiguration rawConfig1 = createRawConfiguration("/tmp/raw1.txt"); - final RawConfiguration rawConfig2 = createRawConfiguration("/tmp/raw2.txt"); - final RawConfiguration rawConfig3 = createRawConfiguration("/tmp/raw3.txt"); + public void mergingRawsIntoStructuredShouldUpdateConfigWithModifedStructured() throws Exception { + Configuration config = new Configuration();
- final Configuration configuration = new Configuration(); - configuration.addRawConfiguration(rawConfig1); - configuration.addRawConfiguration(rawConfig2); - configuration.addRawConfiguration(rawConfig3); + final RawConfiguration raw1 = createRawConfiguration("/tmp/foo.txt"); + config.addRawConfiguration(raw1); + + final RawConfiguration raw2 = createRawConfiguration("/tmp/bar.txt"); + config.addRawConfiguration(raw2); + + final Configuration structured = new Configuration();
final ResourceConfigurationFacet facet = context.mock(ResourceConfigurationFacet.class);
- context.checking(new Expectations(){{ + context.checking(new Expectations() {{ + allowing(componentService).getResourceType(resourceId); will(returnValue(resourceType)); + atLeast(1).of(componentService).getComponent(resourceId, ResourceConfigurationFacet.class, FacetLockType.READ, @@ -286,25 +271,49 @@ public class ConfigurationManagerUnitTest extends LoadConfigTest { onlyIfStarted); will(returnValue(facet));
- oneOf(facet).mergeStructuredConfiguration(rawConfig1, configuration); - oneOf(facet).mergeStructuredConfiguration(rawConfig2, configuration); - oneOf(facet).mergeStructuredConfiguration(rawConfig3, configuration); + atLeast(1).of(facet).loadStructuredConfiguration(); will(returnValue(structured)); + + oneOf(facet).mergeStructuredConfiguration(raw1, structured); + oneOf(facet).mergeStructuredConfiguration(raw2, structured); }});
- Configuration actualConfig = configurationMgr.merge(configuration, resourceId, FROM_RAW); + Configuration mergedConfig = configurationMgr.merge(config, resourceId, FROM_RAW);
- assertNotNull(actualConfig, "Expected a non-null " + Configuration.class.getSimpleName() + " to be returned."); + assertEquals( + mergedConfig.getAllProperties(), + structured.getAllProperties(), + "Failed to merged raw into structured." + ); }
-// @Test -// public void theUpdateLegacyConfigCmdShouldBeCalledToUpdateLegacyConfig() throws Exception { -// UpdateLegacyConfig updateLegacyConfig = context.mock(UpdateLegacyConfig.class); -// -// context.checking(new Expectations() {{ -// allowing(componentService).getAmpsVersion(resourceId); will(returnValue(LEGACY_AMPS_VERSION)); -// -// //oneOf() -// }}); -// } + @Test + public void mergingRawsIntoStructuredShouldIgnoreNull() throws Exception { + Configuration config = new Configuration(); + config.addRawConfiguration(createRawConfiguration("/tmp/foo.txt")); + + final ResourceConfigurationFacet facet = context.mock(ResourceConfigurationFacet.class); + + context.checking(new Expectations() {{ + allowing(componentService).getResourceType(resourceId); will(returnValue(resourceType)); + + atLeast(1).of(componentService).getComponent(resourceId, + ResourceConfigurationFacet.class, + FacetLockType.READ, + LoadResourceConfiguration.FACET_METHOD_TIMEOUT, + daemonThread, + onlyIfStarted); + will(returnValue(facet)); + + atLeast(1).of(facet).loadStructuredConfiguration(); will(returnValue(null)); + }}); + + Configuration mergedConfig = configurationMgr.merge(config, resourceId, FROM_RAW); + + assertEquals( + mergedConfig, + config, + "Structured config should not be modified when the facet does not return a structured config." + ); + }
} diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadConfigTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadConfigTest.java deleted file mode 100644 index 13e90e5..0000000 --- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadConfigTest.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2008 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, version 2, as - * published by the Free Software Foundation, and/or the GNU Lesser - * General Public License, version 2.1, also as published by the Free - * Software Foundation. - * - * 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 and the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * and the GNU Lesser 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.core.pc.configuration; - -import org.rhq.core.domain.configuration.Configuration; -import org.rhq.core.domain.configuration.PropertySimple; -import org.rhq.core.domain.configuration.RawConfiguration; -import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; -import org.rhq.core.domain.resource.ResourceType; -import static org.testng.Assert.assertEquals; - -import java.util.HashSet; -import java.util.Random; -import java.util.Set; - -public class LoadConfigTest extends JMockTest { - - Random random = new Random(); - - ResourceType resourceType = new ResourceType(); - int resourceId = -1; - boolean daemonThread = true; - boolean onlyIfStarted = true; - - Configuration createStructuredConfig() { - Configuration config = new Configuration(); - config.put(new PropertySimple("x", "1")); - config.put(new PropertySimple("y", "2")); - - return config; - } - - Set<RawConfiguration> toSet(RawConfiguration... rawConfigs) { - Set<RawConfiguration> rawConfigSet = new HashSet<RawConfiguration>(); - for (RawConfiguration rawConfig : rawConfigs) { - rawConfigSet.add(rawConfig); - } - return rawConfigSet; - } - - RawConfiguration createRawConfiguration(String path) { - RawConfiguration rawConfig = new RawConfiguration(); - rawConfig.setContents(randomBytes()); - rawConfig.setPath(path); - - return rawConfig; - } - - byte[] randomBytes() { - byte[] bytes = new byte[10]; - random.nextBytes(bytes); - - return bytes; - } - - ConfigurationDefinition getResourceConfigDefinition() { - if (resourceType.getResourceConfigurationDefinition() == null) { - resourceType.setResourceConfigurationDefinition(new ConfigurationDefinition("", "")); - } - return resourceType.getResourceConfigurationDefinition(); - } - - void assertRawsLoaded(Set<RawConfiguration> expectedRaws, Configuration actualConfig) { - assertEquals( - actualConfig.getRawConfigurations(), - expectedRaws, - "The raw configs were not loaded correctly." - ); - } - - void assertStructuredLoaded(Configuration expectedConfig, Configuration actualConfig) { - assertEquals( - actualConfig.getAllProperties(), - expectedConfig.getAllProperties(), - "The structured configuration was not loaded correctly." - ); - } - - void assertNotesSetToDefault(Configuration loadedConfig) { - String expectedNotes = "Resource config for " + resourceType.getName() + " Resource w/ id " + resourceId; - - assertEquals(loadedConfig.getNotes(), expectedNotes, "The notes property should be set to a default when it is not already initialized."); - } -} diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadRawTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadRawTest.java index dd2429f..f466801 100644 --- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadRawTest.java +++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadRawTest.java @@ -36,7 +36,7 @@ import org.testng.annotations.Test; import static java.util.Collections.EMPTY_SET; import java.util.Set;
-public class LoadRawTest extends LoadConfigTest { +public class LoadRawTest extends ConfigManagementTest {
ComponentService componentService;
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadStructuredAndRawTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadStructuredAndRawTest.java index 1374dec..824c05f 100644 --- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadStructuredAndRawTest.java +++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadStructuredAndRawTest.java @@ -37,13 +37,10 @@ import org.rhq.core.domain.resource.ResourceType; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; import org.jmock.Expectations; -import org.jmock.Sequence;
-import java.util.Random; import java.util.Set; -import java.util.HashSet;
-public class LoadStructuredAndRawTest extends LoadConfigTest { +public class LoadStructuredAndRawTest extends ConfigManagementTest {
ComponentService componentService;
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadStructuredTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadStructuredTest.java index 47d4f12..59677c9 100644 --- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadStructuredTest.java +++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadStructuredTest.java @@ -33,7 +33,7 @@ import static org.testng.Assert.assertNull; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test;
-public class LoadStructuredTest extends LoadConfigTest { +public class LoadStructuredTest extends ConfigManagementTest {
ComponentService componentService;
diff --git a/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/RawServer.groovy b/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/RawServer.groovy index 9eafc98..c71f0fb 100644 --- a/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/RawServer.groovy +++ b/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/RawServer.groovy @@ -56,7 +56,8 @@ class RawServer implements ResourceComponent, ResourceConfigurationFacet { return rawConfigs }
- void mergeRawConfiguration(Configuration from, RawConfiguration to) { + RawConfiguration mergeRawConfiguration(Configuration from, RawConfiguration to) { + null }
void mergeStructuredConfiguration(RawConfiguration from, Configuration to) { diff --git a/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/StructuredAndRawServer.groovy b/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/StructuredAndRawServer.groovy index e645510..43b421d 100644 --- a/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/StructuredAndRawServer.groovy +++ b/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/StructuredAndRawServer.groovy @@ -98,7 +98,7 @@ class StructuredAndRawServer implements ResourceComponent, ResourceConfiguration return rawConfigs }
- void mergeRawConfiguration(Configuration configuration, RawConfiguration rawConfiguration) { + RawConfiguration mergeRawConfiguration(Configuration configuration, RawConfiguration rawConfiguration) { def rawPropertiesConfig = loadRawPropertiesConfiguration(rawConfiguration) def propertyNames = getPropertyNames(rawConfiguration)
@@ -107,17 +107,11 @@ class StructuredAndRawServer implements ResourceComponent, ResourceConfiguration rawPropertiesConfig.setProperty(propertyName, property.stringValue) }
-// def x = configuration.get("x") -// def y = configuration.get("y") -// def z = configuration.get("z") -// -// rawPropertiesConfig.setProperty("x", x.stringValue) -// rawPropertiesConfig.setProperty("y", y.stringValue) -// rawPropertiesConfig.setProperty("z", z.stringValue) - def stream = new ByteArrayOutputStream() rawPropertiesConfig.save(stream) - rawConfiguration.contents = stream.toByteArray() + rawConfiguration.contents = stream.toByteArray() + + return rawConfiguration }
def loadRawPropertiesConfiguration(rawConfig) { @@ -133,10 +127,6 @@ class StructuredAndRawServer implements ResourceComponent, ResourceConfiguration def propertyNames = getPropertyNames(rawConfiguration)
propertyNames.each { name -> configuration.put(new PropertySimple(name, rawPropertiesConfig.getString(name))) } - -// configuration.put(new PropertySimple("x", rawPropertiesConfig.getString("x"))) -// configuration.put(new PropertySimple("y", rawPropertiesConfig.getString("y"))) -// configuration.put(new PropertySimple("z", rawPropertiesConfig.getString("z"))) }
def getPropertyNames(rawConfig) { diff --git a/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/StructuredServer.groovy b/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/StructuredServer.groovy index 02dae03..61ad25e 100644 --- a/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/StructuredServer.groovy +++ b/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/StructuredServer.groovy @@ -62,7 +62,8 @@ class StructuredServer implements ResourceComponent, ResourceConfigurationFacet null }
- void mergeRawConfiguration(Configuration from, RawConfiguration to) { + RawConfiguration mergeRawConfiguration(Configuration from, RawConfiguration to) { + null }
void mergeStructuredConfiguration(RawConfiguration from, Configuration to) {
commit 005d581cf355b576b7a96843e51b2b376f357644 Author: John Sanda john@localhost.localdomain Date: Mon Nov 16 21:16:25 2009 -0500
[US 4] Updating plugin container code for translating from structured to raw.
Correcting ResourceConfigurationFacet so that the mergeRawConfiguration() operation returns a RawConfiguration object.
Modifying the code in ConfigurationManager to first load the raw configs and then use those for the merge operations. Updating and adding tests to handle the different scenarios such as
* raw is modified, in which case it should be replaced * null is returned from merged, in which case nothing should change * no raws are returned, in which case nothing should change
diff --git a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/configuration/ResourceConfigurationFacet.java b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/configuration/ResourceConfigurationFacet.java index 0c49cfd..4a14c67 100644 --- a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/configuration/ResourceConfigurationFacet.java +++ b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/configuration/ResourceConfigurationFacet.java @@ -34,7 +34,7 @@ public interface ResourceConfigurationFacet {
Set<RawConfiguration> loadRawConfigurations();
- void mergeRawConfiguration(Configuration from, RawConfiguration to); + RawConfiguration mergeRawConfiguration(Configuration from, RawConfiguration to);
void mergeStructuredConfiguration(RawConfiguration from, Configuration to);
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManager.java index ef0584b..9eb9ab3 100644 --- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManager.java +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManager.java @@ -23,6 +23,9 @@ package org.rhq.core.pc.configuration;
import java.util.List; +import java.util.Set; +import java.util.Queue; +import java.util.LinkedList; import java.util.concurrent.*;
import org.apache.commons.logging.Log; @@ -170,9 +173,7 @@ public class ConfigurationManager extends AgentService implements ContainerServi FacetLockType.READ, FACET_METHOD_TIMEOUT, daemonOnly, onlyIfStarted);
if (fromStructured) { - for (RawConfiguration rawConfig : configuration.getRawConfigurations()) { - facet.mergeRawConfiguration(configuration, rawConfig); - } + mergedStructuredIntoRaws(configuration, facet); } else { for (RawConfiguration rawConfig : configuration.getRawConfigurations()) { @@ -183,21 +184,58 @@ public class ConfigurationManager extends AgentService implements ContainerServi return configuration; }
+ private void mergedStructuredIntoRaws(Configuration configuration, ResourceConfigurationFacet facet) { + Set<RawConfiguration> rawConfigs = facet.loadRawConfigurations(); + + if (rawConfigs == null) { + return; + } + + Queue<RawConfiguration> queue = new LinkedList<RawConfiguration>(rawConfigs); + + while (!queue.isEmpty()) { + RawConfiguration originalRaw = queue.poll(); + RawConfiguration mergedRaw = facet.mergeRawConfiguration(configuration, originalRaw); + + if (mergedRaw != null) { + updateRawConfig(configuration, originalRaw, mergedRaw); + } + } + } + + private void updateRawConfig(Configuration configuration, RawConfiguration originalRaw, + RawConfiguration mergedRaw) { + + configuration.removeRawConfiguration(originalRaw); + configuration.addRawConfiguration(mergedRaw); + } + public Configuration loadResourceConfiguration(int resourceId) throws PluginContainerException {
LoadResourceConfiguration loadConfig = loadConfigFactory.getStrategy(resourceId); - Configuration configuration = loadConfig.execute(resourceId); + Configuration configuration = null; + + try { + configuration = loadConfig.execute(resourceId); + } catch (Throwable t) { + throw new PluginContainerException(createErrorMsg(resourceId, "An exception was thrown."), t); + }
if (configuration == null) { - ResourceType resourceType = componentService.getResourceType(resourceId); - throw new PluginContainerException("Plugin Error: Resource Component for [" + resourceType.getName() - + "] Resource with id [" + resourceId + "] returned a null Configuration."); + throw new PluginContainerException(createErrorMsg(resourceId, "returned a null Configuration.")); }
return configuration; }
+ private String createErrorMsg(int resourceId, String msg) throws PluginContainerException { + ResourceType resourceType = componentService.getResourceType(resourceId); + + return "Plugin Error: Resource Component for [" + resourceType.getName() + "] Resource with id [" + + resourceId + "]: " + msg; + } + // public Configuration loadResourceConfiguration(int resourceId) throws PluginContainerException { // ResourceType resourceType = getResourceType(resourceId); // ConfigurationFacet configComponent = getConfigurationFacet(resourceId, FacetLockType.READ); diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigurationManagerUnitTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigurationManagerUnitTest.java index 902f163..bf8a8ce 100644 --- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigurationManagerUnitTest.java +++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigurationManagerUnitTest.java @@ -24,6 +24,7 @@ package org.rhq.core.pc.configuration;
import static org.testng.Assert.*; +import static java.util.Collections.EMPTY_SET;
import org.jmock.Expectations; import org.jmock.Sequence; @@ -39,8 +40,10 @@ import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test;
import java.util.Random; +import java.util.Set; +import java.util.HashSet;
-public class ConfigurationManagerUnitTest extends JMockTest { +public class ConfigurationManagerUnitTest extends LoadConfigTest {
static final String LEGACY_AMPS_VERSION = "2.0";
@@ -50,20 +53,12 @@ public class ConfigurationManagerUnitTest extends JMockTest {
boolean FROM_RAW = false;
- int resourceId = -1; - - boolean daemonThread = true; - - boolean onlyIfStarted = true; - LoadResourceConfigurationFactory loadConfigFactory;
ComponentService componentService;
ConfigurationManager configurationMgr;
- Random random; - @BeforeMethod public void setup() { loadConfigFactory = context.mock(LoadResourceConfigurationFactory.class); @@ -73,72 +68,77 @@ public class ConfigurationManagerUnitTest extends JMockTest { configurationMgr = new ConfigurationManager(); configurationMgr.setLoadConfigFactory(loadConfigFactory); configurationMgr.setComponentService(componentService); - - random = new Random(); }
@Test - public void factoryShouldBeCalledToGetStrategy() throws Exception { + public void straegyShouldBeCalledToLoadConfig() throws Exception { + final Configuration expectedConfig = new Configuration(); + final LoadResourceConfiguration loadConfig = context.mock(LoadResourceConfiguration.class); - + context.checking(new Expectations() {{ atLeast(1).of(loadConfigFactory).getStrategy(resourceId); will(returnValue(loadConfig));
- allowing(loadConfig).execute(resourceId); will(returnValue(new Configuration())); + atLeast(1).of(loadConfig).execute(resourceId); will(returnValue(expectedConfig)); }});
- configurationMgr.loadResourceConfiguration(resourceId); - } + Configuration actualConfig = configurationMgr.loadResourceConfiguration(resourceId);
- @Test - public void strategyShouldBeCalledToLoadConfig() throws Exception { - final Configuration expectedConfig = new Configuration(); + assertNotNull(actualConfig, "Expected a non-null " + Configuration.class.getSimpleName() + " to be returned."); + }
+ @Test(expectedExceptions = {PluginContainerException.class}) + public void exceptionShouldBeThrownIfConfigIsNull() throws Exception { final LoadResourceConfiguration loadConfig = context.mock(LoadResourceConfiguration.class);
context.checking(new Expectations() {{ - allowing(loadConfigFactory).getStrategy(resourceId); will(returnValue(loadConfig)); + atLeast(1).of(loadConfigFactory).getStrategy(resourceId); will(returnValue(loadConfig));
- atLeast(1).of(loadConfig).execute(resourceId); - will(returnValue(expectedConfig)); - }}); + atLeast(1).of(loadConfig).execute(resourceId); will(returnValue(null));
- Configuration actualConfig = configurationMgr.loadResourceConfiguration(resourceId); + allowing(componentService).getResourceType(resourceId); will(returnValue(new ResourceType())); + }});
- assertSame(actualConfig, expectedConfig, "Expected the configuration from the loadConfig object to be returned."); + configurationMgr.loadResourceConfiguration(resourceId); }
@Test(expectedExceptions = {PluginContainerException.class}) - public void exceptionShouldBeThrownIfConfigIsNull() throws Exception { + public void exceptionShouldBeThrownWhenStrategyThrowsAnException() throws Exception { final LoadResourceConfiguration loadConfig = context.mock(LoadResourceConfiguration.class);
context.checking(new Expectations() {{ - allowing(loadConfigFactory).getStrategy(resourceId); will(returnValue(loadConfig)); + allowing(componentService).getResourceType(resourceId); will(returnValue(resourceType));
- allowing(loadConfig).execute(resourceId); will(returnValue(null)); + atLeast(1).of(loadConfigFactory).getStrategy(resourceId); will(returnValue(loadConfig));
- allowing(componentService).getResourceType(resourceId); will(returnValue(new ResourceType())); + atLeast(1).of(loadConfig).execute(resourceId); will(throwException(new RuntimeException())); }});
configurationMgr.loadResourceConfiguration(resourceId); }
@Test - public void theFacetShouldMergeTheStructuredIntoEachRawWhenFromStructured() throws Exception { - final RawConfiguration rawConfig1 = createRawConfiguration("/tmp/raw1.txt"); - final RawConfiguration rawConfig2 = createRawConfiguration("/tmp/raw2.txt"); - final RawConfiguration rawConfig3 = createRawConfiguration("/tmp/raw3.txt"); + public void mergingStucturedIntoRawShouldUpdateConfigWithModifiedRaws() throws Exception { + final Configuration config = new Configuration();
- final Configuration configuration = new Configuration(); - configuration.addRawConfiguration(rawConfig1); - configuration.addRawConfiguration(rawConfig2); - configuration.addRawConfiguration(rawConfig3); + final RawConfiguration originalRaw1 = createRawConfiguration("/tmp/raw1.txt"); + config.addRawConfiguration(originalRaw1); + + final RawConfiguration originalRaw2 = createRawConfiguration("/tmp/raw2.txt"); + config.addRawConfiguration(originalRaw2); + + final RawConfiguration originalRaw3 = createRawConfiguration("/tmp/raw3.txt"); + config.addRawConfiguration(originalRaw3); + + final RawConfiguration mergedRaw1 = createRawConfiguration("/tmp/raw1.txt"); + final RawConfiguration mergedRaw2 = createRawConfiguration("/tmp/raw2.txt"); + final RawConfiguration mergedRaw3 = createRawConfiguration("/tmp/raw3.txt");
final ResourceConfigurationFacet facet = context.mock(ResourceConfigurationFacet.class);
- final Sequence sequence = context.sequence("merge"); + context.checking(new Expectations() {{ + allowing(componentService).getResourceType(resourceId); will(returnValue(resourceType));
- context.checking(new Expectations(){{ atLeast(1).of(componentService).getComponent(resourceId, ResourceConfigurationFacet.class, FacetLockType.READ, @@ -147,19 +147,124 @@ public class ConfigurationManagerUnitTest extends JMockTest { onlyIfStarted); will(returnValue(facet));
-// atLeast(1).of(facet).load + atLeast(1).of(facet).loadRawConfigurations(); will(returnValue(config.getRawConfigurations()));
- oneOf(facet).mergeRawConfiguration(configuration, rawConfig1); - oneOf(facet).mergeRawConfiguration(configuration, rawConfig2); - oneOf(facet).mergeRawConfiguration(configuration, rawConfig3); + oneOf(facet).mergeRawConfiguration(config, originalRaw1); will(returnValue(mergedRaw1)); + oneOf(facet).mergeRawConfiguration(config, originalRaw2); will(returnValue(mergedRaw2)); + oneOf(facet).mergeRawConfiguration(config, originalRaw3); will(returnValue(mergedRaw3)); }});
- Configuration actualConfig = configurationMgr.merge(configuration, resourceId, FROM_STRUCTURED); + Configuration mergedConfig = configurationMgr.merge(config, resourceId, FROM_STRUCTURED);
- assertNotNull(actualConfig, "Expected a non-null " + Configuration.class.getSimpleName() + " to be returned."); + Set<RawConfiguration> mergedRaws = toSet(mergedRaw1, mergedRaw2, mergedRaw3); + + assertEquals(mergedConfig.getRawConfigurations(), mergedRaws, "Failed to merge structured into raws."); + } + + @Test + public void mergingStructuredIntoRawShouldIgnoreNulls() throws Exception { + final Configuration config = new Configuration(); + + final RawConfiguration originalRaw = createRawConfiguration("/tmp/raw.txt"); + config.addRawConfiguration(originalRaw); + + final ResourceConfigurationFacet facet = context.mock(ResourceConfigurationFacet.class); + + context.checking(new Expectations() {{ + allowing(componentService).getResourceType(resourceId); will(returnValue(resourceType)); + + atLeast(1).of(componentService).getComponent(resourceId, + ResourceConfigurationFacet.class, + FacetLockType.READ, + LoadResourceConfiguration.FACET_METHOD_TIMEOUT, + daemonThread, + onlyIfStarted); + will(returnValue(facet)); + + atLeast(1).of(facet).loadRawConfigurations(); will(returnValue(config.getRawConfigurations())); + + oneOf(facet).mergeRawConfiguration(config, originalRaw); will(returnValue(null)); + }}); + + Configuration mergedConfig = configurationMgr.merge(config, resourceId, FROM_STRUCTURED); + + assertEquals( + mergedConfig.getRawConfigurations(), + config.getRawConfigurations(), + "Expected the raw configs to be unmodified when merge operation returns null." + ); }
@Test + public void mergingStructuredIntoRawShouldDoNothingIfRawsAreNull() throws Exception { + final Configuration config = new Configuration(); + config.addRawConfiguration(createRawConfiguration("/tmp/foo.txt")); + + final ResourceConfigurationFacet facet = context.mock(ResourceConfigurationFacet.class); + + context.checking(new Expectations() {{ + allowing(componentService).getResourceType(resourceId); will(returnValue(resourceType)); + + atLeast(1).of(componentService).getComponent(resourceId, + ResourceConfigurationFacet.class, + FacetLockType.READ, + LoadResourceConfiguration.FACET_METHOD_TIMEOUT, + daemonThread, + onlyIfStarted); + will(returnValue(facet)); + + atLeast(1).of(facet).loadRawConfigurations(); will(returnValue(null)); + }}); + + Configuration mergedConfig = configurationMgr.merge(config, resourceId, FROM_STRUCTURED); + + assertEquals( + mergedConfig.getRawConfigurations(), + config.getRawConfigurations(), + "Expected the raw configs to be unmodifed when the facet does not return any raw configs." + ); + } + +// @Test +// public void theFacetShouldMergeTheStructuredIntoEachRawWhenFromStructured() throws Exception { +// final RawConfiguration rawConfig1 = createRawConfiguration("/tmp/raw1.txt"); +// final RawConfiguration rawConfig2 = createRawConfiguration("/tmp/raw2.txt"); +// final RawConfiguration rawConfig3 = createRawConfiguration("/tmp/raw3.txt"); +// +// final Set<RawConfiguration> rawConfigs = new HashSet<RawConfiguration>(); +// rawConfigs.add(rawConfig1); +// rawConfigs.add(rawConfig2); +// rawConfigs.add(rawConfig3); +// +// final Configuration configuration = new Configuration(); +// configuration.addRawConfiguration(rawConfig1); +// configuration.addRawConfiguration(rawConfig2); +// configuration.addRawConfiguration(rawConfig3); +// +// final ResourceConfigurationFacet facet = context.mock(ResourceConfigurationFacet.class); +// +// final Sequence merge = context.sequence("merge"); +// +// context.checking(new Expectations(){{ +// atLeast(1).of(componentService).getComponent(resourceId, +// ResourceConfigurationFacet.class, +// FacetLockType.READ, +// LoadResourceConfiguration.FACET_METHOD_TIMEOUT, +// daemonThread, +// onlyIfStarted); +// will(returnValue(facet)); +// +// atLeast(1).of(facet).loadRawConfigurations(); will(returnValue(rawConfigs)); +// +// oneOf(facet).mergeRawConfiguration(configuration, rawConfig1); +// oneOf(facet).mergeRawConfiguration(configuration, rawConfig2); +// oneOf(facet).mergeRawConfiguration(configuration, rawConfig3); +// }}); +// +// Configuration actualConfig = configurationMgr.merge(configuration, resourceId, FROM_STRUCTURED); +// } + + @Test public void theFacetShouldMergeEachRawIntoTheStructuredWhenFromRaw() throws Exception { final RawConfiguration rawConfig1 = createRawConfiguration("/tmp/raw1.txt"); final RawConfiguration rawConfig2 = createRawConfiguration("/tmp/raw2.txt"); @@ -202,19 +307,4 @@ public class ConfigurationManagerUnitTest extends JMockTest { // }}); // }
- RawConfiguration createRawConfiguration(String path) { - RawConfiguration rawConfig = new RawConfiguration(); - rawConfig.setContents(randomBytes()); - rawConfig.setPath(path); - - return rawConfig; - } - - byte[] randomBytes() { - byte[] bytes = new byte[10]; - random.nextBytes(bytes); - - return bytes; - } - } diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/TranslationNotSupportedException.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/TranslationNotSupportedException.java new file mode 100644 index 0000000..4525aa0 --- /dev/null +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/TranslationNotSupportedException.java @@ -0,0 +1,45 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2008 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, version 2, as + * published by the Free Software Foundation, and/or the GNU Lesser + * General Public License, version 2.1, also as published by the Free + * Software Foundation. + * + * 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 and the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * and the GNU Lesser 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.enterprise.server.configuration; + +public class TranslationNotSupportedException extends Exception { + + private static final long serialVersionUID = 1L; + + public TranslationNotSupportedException() { + super(); + } + + public TranslationNotSupportedException(String message) { + super(message); + } + + public TranslationNotSupportedException(String message, Throwable cause) { + super(message, cause); + } + + public TranslationNotSupportedException(Throwable cause) { + super(cause); + } +}
commit 79a65f1730fdce4bfe4f2ba9a3b6b970a96a94f6 Author: Adam Young ayoung@redhat.com Date: Mon Nov 16 15:36:47 2009 -0500
Minor tweak to perform translation
diff --git a/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/StructuredAndRawServer.groovy b/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/StructuredAndRawServer.groovy index 0f2b53f..e645510 100644 --- a/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/StructuredAndRawServer.groovy +++ b/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/StructuredAndRawServer.groovy @@ -140,17 +140,17 @@ class StructuredAndRawServer implements ResourceComponent, ResourceConfiguration }
def getPropertyNames(rawConfig) { - if (rawConfig == rawConfig1) { + if (rawConfig.getPath() == rawConfig1.getPath()) { return ["x", "y", "z"] } - else if (rawConfig == rawConfig2) { + else if (rawConfig.getPath() == rawConfig2.getPath()) { return ["username", "password"] } - else if (rawConfig == rawConfig3) { + else if (rawConfig.getPath() == rawConfig3.getPath()) { return ["rhq.server.hostname", "rhq.server.port"] } else { - throw new RuntimeException("$rawConfig is not a recongnized raw config file") + throw new RuntimeException("$rawConfig.getPath() is not a recongnized raw config file") } }
commit 3ef362d4eafb9de6bf156e530a37de32c0a7b170 Author: Adam Young ayoung@redhat.com Date: Mon Nov 16 13:39:55 2009 -0500
Made the view pages use a non-edited version of the RawConfigDelegate.
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/MockSupport.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/MockSupport.java deleted file mode 100644 index 78c7f83..0000000 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/MockSupport.java +++ /dev/null @@ -1,45 +0,0 @@ -package org.rhq.enterprise.gui.configuration.resource; - -import org.rhq.core.domain.configuration.RawConfiguration; - -public class MockSupport { - - public static void populateRawsMock(RawConfigCollection rawConfigCollection) { - String[] files = { "/etc/mock/file1", "/etc/mock/file2", "/etc/mock/file3", "/etc/mock/me/will/you", - "/etc/mock/turtle/soup", "/etc/mock/mysmock/iclean/yourclock" }; - - String[] filesContents = { - "GALLIA est omnis divisa in partes tres, quarum unam incolunt Belgae, \naliam Aquitani, tertiam qui ipsorum lingua Celtae, \n" - + "nostra Galli appellantur. \nHi omnes lingua, institutis, legibus inter se differunt. \n", - "I've seen all good people \n turn their heads each day \n So Satisfied\n I'm on my way", - "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor \nincididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis\n nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\n Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu\n fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in \nculpa qui officia deserunt mollit anim id est laborum.", - "It was on a dreary night of November that I beheld the accomplishment of my toils. With an anxiety that " - + "almost amounted to agony, I collected the instruments of life around me, that I might infuse a spark of being " - + "into the lifeless thing that lay at my feet. It was already one in the morning; the rain pattered dismally " - + "against the panes, and my candle was nearly burnt out, when, by the glimmer of the half-extinguished light, " - + "I saw the dull yellow eye of the creature open; it breathed hard, and a convulsive motion agitated its limbs.\n\n" - + "How can I describe my emotions at this catastrophe, or how delineate the wretch whom with such infinite pains and " - + "care I had endeavoured to form? His limbs were in proportion, and I had selected his features as beautiful. " - + "Beautiful! Great God! His yellow skin scarcely covered the work of muscles and arteries beneath; his hair was " - + "of a lustrous black, and flowing; his teeth of a pearly whiteness; but these luxuriances only formed a more " - + "horrid contrast with his watery eyes, that seemed almost of the same colour as the dun-white sockets in which " - + "they were set, his shrivelled complexion and straight black lips. ", - ""The time has come," the Walrus said,\n" + "To talk of many things:\n" - + "Of shoes--and ships--and sealing-wax--\n" + "Of cabbages--and kings--\n" - + "And why the sea is boiling hot--\n" + "And whether pigs have wings.", - "My grandfather's clock\n" + "Was too large for the shelf,\n" + "So it stood ninety years on the floor;\n" - + "It was taller by half\n" + "Than the old man himself,\n" - + "Though it weighed not a pennyweight more.\n" + "It was bought on the morn\n" - + "Of the day that he was born,\n" + "It was always his treasure and pride;" + "But it stopped short\n" - + "Never to go again,\n" + "When the old man died." }; - int i = 0; - for (String file : files) { - RawConfiguration raw = new RawConfiguration(); - raw.setPath(file); - raw.setContents((filesContents[i++]).getBytes()); - rawConfigCollection.getRawConfigDelegate().raws.put(file, raw); - } - - } - -} diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/RawConfigCollection.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/RawConfigCollection.java index e5c0153..781c390 100644 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/RawConfigCollection.java +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/RawConfigCollection.java @@ -4,7 +4,6 @@ import java.io.File; import java.io.FileReader; import java.io.IOException; import java.io.Serializable; -import java.util.Collection; import java.util.Iterator; import java.util.TreeMap;
@@ -20,14 +19,13 @@ import org.jboss.seam.annotations.Name; import org.jboss.seam.annotations.Scope;
import org.rhq.core.domain.auth.Subject; -import org.rhq.core.domain.configuration.AbstractResourceConfigurationUpdate; import org.rhq.core.domain.configuration.Configuration; +import org.rhq.core.domain.configuration.Property; import org.rhq.core.domain.configuration.RawConfiguration; import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; import org.rhq.core.domain.configuration.definition.ConfigurationFormat; import org.rhq.enterprise.gui.configuration.AbstractConfigurationUIBean; import org.rhq.enterprise.gui.util.EnterpriseFacesContextUtility; -import org.rhq.enterprise.server.configuration.ConfigurationManagerLocal; import org.rhq.enterprise.server.util.LookupUtil;
@Name("rawConfigCollection") @@ -45,14 +43,6 @@ public class RawConfigCollection extends AbstractConfigurationUIBean implements TODO It should be set to false prior to check in*/ private static final boolean useMock = false;
- /** - * These values are transient due to the need to save and restore the view. - * We can always fetch them again. - */ - transient private ConfigurationManagerLocal configurationManager; - - transient private Configuration configuration = null; - private final Log log = LogFactory.getLog(RawConfigCollection.class); private Integer resourceId = null;
@@ -65,7 +55,8 @@ public class RawConfigCollection extends AbstractConfigurationUIBean implements public String commit() {
Subject subject = EnterpriseFacesContextUtility.getSubject(); - getConfigurationManager().updateResourceConfiguration(subject, getResourceId(), getMergedConfiguration()); + LookupUtil.getConfigurationManager().updateResourceConfiguration(subject, getResourceId(), + getMergedConfiguration());
nullify();
@@ -114,21 +105,14 @@ public class RawConfigCollection extends AbstractConfigurationUIBean implements }
public Configuration getConfiguration() { - if (null == configuration) { - Subject subject = EnterpriseFacesContextUtility.getSubject(); - AbstractResourceConfigurationUpdate configurationUpdate = this.getConfigurationManager() - .getLatestResourceConfigurationUpdate(subject, getRawConfigDelegate().resourceId); - configuration = (configurationUpdate != null) ? configurationUpdate.getConfiguration() : null; - } - - return configuration; + return getRawConfigDelegate().getConfiguration(); }
//TODO Sync this up with the baseclass public ConfigurationDefinition getConfigurationDefinition() { if (null == getRawConfigDelegate().configurationDefinition) {
- getRawConfigDelegate().configurationDefinition = getConfigurationManager() + getRawConfigDelegate().configurationDefinition = LookupUtil.getConfigurationManager() .getResourceConfigurationDefinitionForResourceType(EnterpriseFacesContextUtility.getSubject(), EnterpriseFacesContextUtility.getResource().getResourceType().getId()); } @@ -141,13 +125,6 @@ public class RawConfigCollection extends AbstractConfigurationUIBean implements return getConfigurationDefinition().getConfigurationFormat(); }
- ConfigurationManagerLocal getConfigurationManager() { - if (null == configurationManager) { - configurationManager = LookupUtil.getConfigurationManager(); - } - return configurationManager; - } - public RawConfiguration getCurrent() { if (null == getRawConfigDelegate().current) { Iterator<RawConfiguration> iterator = getRaws().values().iterator(); @@ -201,15 +178,7 @@ public class RawConfigCollection extends AbstractConfigurationUIBean implements }
public TreeMap<String, RawConfiguration> getRaws() { - if (null == getRawConfigDelegate().raws) { - getRawConfigDelegate().raws = new TreeMap<String, RawConfiguration>(); - if (useMock) { - MockSupport.populateRawsMock(this); - } else { - populateRaws(this); - } - } - return getRawConfigDelegate().raws; + return getRawConfigDelegate().getRaws(); }
/** @@ -261,16 +230,6 @@ public class RawConfigCollection extends AbstractConfigurationUIBean implements setRawConfigDelegate(null); }
- void populateRaws(RawConfigCollection rawConfigCollection) { - Collection<RawConfiguration> rawConfigurations = rawConfigCollection.getConfigurationManager() - .getLatestResourceConfigurationUpdate(EnterpriseFacesContextUtility.getSubject(), getResourceId()) - .getConfiguration().getRawConfigurations(); - - for (RawConfiguration raw : rawConfigurations) { - rawConfigCollection.getRawConfigDelegate().raws.put(raw.getPath(), raw); - } - } - /** * Indicates which of the raw configuration files is currently selected. * @param s @@ -336,11 +295,12 @@ public class RawConfigCollection extends AbstractConfigurationUIBean implements
public String switchToraw() { log.error("switch2raw called"); - configuration = getConfigurationManager().translateResourceConfiguration( + Configuration configuration = LookupUtil.getConfigurationManager().translateResourceConfiguration( EnterpriseFacesContextUtility.getSubject(), getResourceId(), getMergedConfiguration(), true);
for (RawConfiguration raw : configuration.getRawConfigurations()) { - getRawConfigDelegate().raws.put(raw.getPath(), raw); + getRawConfigDelegate().getRaws().put(raw.getPath(), raw); + getRawConfigDelegate().setConfiguration(configuration); } getRawConfigDelegate().current = null; return "/rhq/resource/configuration/edit-raw.xhtml?currentResourceId=" + getResourceId(); @@ -348,11 +308,16 @@ public class RawConfigCollection extends AbstractConfigurationUIBean implements
public String switchTostructured() { log.error("switch2structured called"); - configuration = getConfigurationManager().translateResourceConfiguration( + Configuration configuration = LookupUtil.getConfigurationManager().translateResourceConfiguration( EnterpriseFacesContextUtility.getSubject(), getResourceId(), getMergedConfiguration(), false);
+ for (Property property : configuration.getAllProperties().values()) { + property.setConfiguration(configuration); + } + for (RawConfiguration raw : configuration.getRawConfigurations()) { - getRawConfigDelegate().raws.put(raw.getPath(), raw); + getRawConfigDelegate().getRaws().put(raw.getPath(), raw); + getRawConfigDelegate().setConfiguration(configuration); } getRawConfigDelegate().current = null;
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/RawConfigDelegate.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/RawConfigDelegate.java index b7083af..d049f35 100644 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/RawConfigDelegate.java +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/RawConfigDelegate.java @@ -20,27 +20,81 @@ package org.rhq.enterprise.gui.configuration.resource;
import java.io.Serializable; +import java.util.Collection; import java.util.TreeMap;
+import org.rhq.core.domain.auth.Subject; +import org.rhq.core.domain.configuration.AbstractResourceConfigurationUpdate; +import org.rhq.core.domain.configuration.Configuration; import org.rhq.core.domain.configuration.RawConfiguration; import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; +import org.rhq.enterprise.gui.util.EnterpriseFacesContextUtility; +import org.rhq.enterprise.server.util.LookupUtil;
public class RawConfigDelegate implements Serializable {
+ void populateRaws() { + Collection<RawConfiguration> rawConfigurations = LookupUtil.getConfigurationManager() + .getLatestResourceConfigurationUpdate(EnterpriseFacesContextUtility.getSubject(), resourceId) + .getConfiguration().getRawConfigurations(); + + for (RawConfiguration raw : rawConfigurations) { + raws.put(raw.getPath(), raw); + } + } + public RawConfigDelegate(int resourceId) { super(); this.resourceId = resourceId; }
+ public void setRaws(TreeMap<String, RawConfiguration> raws) { + this.raws = raws; + } + + public TreeMap<String, RawConfiguration> getRaws() { + + if (null == raws) { + raws = new TreeMap<String, RawConfiguration>(); + populateRaws(); + } + + return raws; + } + + public void setConfiguration(Configuration configuration) { + this.configuration = configuration; + } + + public Configuration getConfiguration() { + if (null == configuration) { + + Subject subject = EnterpriseFacesContextUtility.getSubject(); + int resourceId = EnterpriseFacesContextUtility.getResource().getId(); + AbstractResourceConfigurationUpdate configurationUpdate = LookupUtil.getConfigurationManager() + .getLatestResourceConfigurationUpdate(subject, resourceId); + Configuration configuration = (configurationUpdate != null) ? configurationUpdate.getConfiguration() : null; + if (configuration != null) { + //ConfigurationMaskingUtility.maskConfiguration(configuration, getConfigurationDefinition()); + } + + return configuration; + + } + return configuration; + } + /** * */ private static final long serialVersionUID = -9058700205958371765L; + int resourceId = 0; String selectedPath; - TreeMap<String, RawConfiguration> raws; + private TreeMap<String, RawConfiguration> raws; TreeMap<String, RawConfiguration> modified = new TreeMap<String, RawConfiguration>(); RawConfiguration current = null; ConfigurationDefinition configurationDefinition = null; + private Configuration configuration;
} \ No newline at end of file diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/RawConfigViewer.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/RawConfigViewer.java new file mode 100644 index 0000000..d794c37 --- /dev/null +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/RawConfigViewer.java @@ -0,0 +1,69 @@ +package org.rhq.enterprise.gui.configuration.resource; + +import java.util.Iterator; +import java.util.TreeMap; + +import org.jboss.seam.ScopeType; +import org.jboss.seam.annotations.Name; +import org.jboss.seam.annotations.Scope; + +import org.rhq.core.domain.configuration.RawConfiguration; +import org.rhq.enterprise.gui.util.EnterpriseFacesContextUtility; + +@Name("RawConfigViewer") +@Scope(ScopeType.SESSION) +public class RawConfigViewer { + + RawConfigDelegate rawConfigDelegate; + + int getResourceId() { + int resourceId = EnterpriseFacesContextUtility.getResource().getId(); + return resourceId; + } + + public RawConfigDelegate getRawConfigDelegate() { + if (null == rawConfigDelegate || (getResourceId() != rawConfigDelegate.resourceId)) { + rawConfigDelegate = new RawConfigDelegate(getResourceId()); + } + return rawConfigDelegate; + } + + public TreeMap<String, RawConfiguration> getRaws() { + return getRawConfigDelegate().getRaws(); + } + + public void setCurrentPath(String path) { + RawConfiguration raw = getRaws().get(path); + if (null != raw) { + getRawConfigDelegate().current = raw; + } + } + + public String getCurrentContents() { + return new String(getCurrent().getContents()); + } + + public Object[] getPaths() { + return getRaws().keySet().toArray(); + } + + public void select(String s) { + getRawConfigDelegate().selectedPath = s; + setCurrentPath(getRawConfigDelegate().selectedPath); + } + + public RawConfiguration getCurrent() { + if (null == getRawConfigDelegate().current) { + Iterator<RawConfiguration> iterator = getRaws().values().iterator(); + if (iterator.hasNext()) { + getRawConfigDelegate().current = iterator.next(); + } else { + getRawConfigDelegate().current = new RawConfiguration(); + getRawConfigDelegate().current.setPath("/dev/null"); + getRawConfigDelegate().current.setContents("".getBytes()); + } + } + return getRawConfigDelegate().current; + } + +} diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit.xhtml index da2f99a..0b421cb 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit.xhtml @@ -27,15 +27,18 @@ THIS TEXT WILL BE REMOVED.
<input type="hidden" name="id" value="#{ResourceUIBean.id}"/> + + <h:panelGroup rendered="#{rawConfigCollection.rawSupported}" > You are viewing this in structured mode. Switch to - <h:commandLink action="#{rawConfigCollection.switchToraw}"> + <h:commandLink action="#{rawConfigCollection.switchToraw}" rendered="#{rawConfigCollection.rawSupported}"> <f:param name="conversationId" value="#{conversation.id}"/> <f:param name="id" value="#{ResourceUIBean.id}"/> <h:outputText value=" files mode"/> </h:commandLink> - + </h:panelGroup> + <onc:config configurationDefinition="#{ExistingResourceConfigurationUIBean.configurationDefinition}" - configuration="#{ExistingResourceConfigurationUIBean.configuration}" + configuration="#{rawConfigCollection.configuration}" nullConfigurationDefinitionMessage="#{ExistingResourceConfigurationUIBean.nullConfigurationDefinitionMessage}" nullConfigurationMessage="#{ExistingResourceConfigurationUIBean.nullConfigurationMessage}" prevalidate="true"/> diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view-raw-full.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view-raw-full.xhtml index 4caa2ac..3867b7b 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view-raw-full.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view-raw-full.xhtml @@ -11,7 +11,7 @@ xmlns:s="http://jboss.com/products/seam/taglib%22%3E
<ui:composition template="/rhq/layout/main.xhtml"> -<ui:param name="pageTitle" value="Upload Configuration File"/> +<ui:param name="pageTitle" value="TODO Internationalize this"/>
<ui:define name="breadcrumbs" > <h:outputLink value="view-raw.xhtml" action="navigateToUpload" > @@ -26,7 +26,7 @@ <h:form id="editResourceConfigurationForm" > <input type="hidden" name="id" value="#{ResourceUIBean.id}" /> <div> -<pre><h:outputText value="#{rawConfigCollection.currentContents}" /></pre> +<pre><h:outputText value="#{RawConfigViewer.currentContents}" /></pre> </div> </h:form> </ui:define> diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view-raw.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view-raw.xhtml index a3092f3..ae6a1e8 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view-raw.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view-raw.xhtml @@ -47,16 +47,15 @@ <h:panelGroup id="changedFiles" layout="vertical"> <h:form> <input type="hidden" name="id" value="#{ResourceUIBean.id}" /> - <ui:repeat value="#{rawConfigCollection.paths}" var="path"> + <ui:repeat value="#{RawConfigViewer.paths}" var="path"> <div> - <h:outputText value="*" rendered="#{rawConfigCollection.isModified(path) }" /> <h:commandLink - action="#{rawConfigCollection.select(path)}" + action="#{RawConfigViewer.select(path)}" value="#{path}" - rendered="#{path != rawConfigCollection.current.path}"> + rendered="#{path != RawConfigViewer.current.path}"> <f:param name="currentPath" value="#{path}" /> </h:commandLink> - <h:outputText value="#{path}" rendered="#{path == rawConfigCollection.current.path}" /> + <h:outputText value="#{path}" rendered="#{path == RawConfigViewer.current.path}" /> </div> </ui:repeat> </h:form> @@ -66,7 +65,7 @@ </td> <td> <div> - Current File: <h:outputText value="#{rawConfigCollection.current.path}" + Current File: <h:outputText value="#{RawConfigViewer.current.path}" styleClass="outhello" /> </div> <h:outputLink value="view-raw-full.xhtml" action="navigateToUpload" > @@ -79,7 +78,7 @@ <f:param name="id" value="#{ResourceUIBean.id}" /> </s:link> <div> - <pre><h:outputText value="#{rawConfigCollection.currentContents}" /></pre> + <pre><h:outputText value="#{RawConfigViewer.currentContents}" /></pre> </div> </td> </tr> diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml index dd4631e..08dd098 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml @@ -55,7 +55,7 @@ THIS TEXT WILL BE REMOVED. </h:panelGrid>
<onc:config configurationDefinition="#{ExistingResourceConfigurationUIBean.configurationDefinition}" - configuration="#{rawConfigCollection.configuration}" + configuration="#{ExistingResourceConfigurationUIBean.configuration}" accessMapActionExpression="#{ExistingResourceConfigurationUIBean.accessMap}" readOnly="true" nullConfigurationDefinitionMessage="#{ExistingResourceConfigurationUIBean.nullConfigurationDefinitionMessage}"
commit 28dd3c299d4f163cb50da28fcd15b1f73b834a05 Merge: 5a0c922... 1dec3d8... Author: Jay Shaughnessy jshaughn@redhat.com Date: Mon Nov 16 09:16:48 2009 -0500
Merge branch 'linux-config' into linux-config-dev
commit 5a0c922a1416fc9cf2d62629df37e32032526b80 Author: Jay Shaughnessy jshaughn@redhat.com Date: Mon Nov 16 09:10:34 2009 -0500
Obsolete stuff from old perspctives investigation.
diff --git a/modules/enterprise/server/jar/src/main/resources/perspectives/admin.xml b/modules/enterprise/server/jar/src/main/resources/perspectives/admin.xml deleted file mode 100644 index eb29b5a..0000000 --- a/modules/enterprise/server/jar/src/main/resources/perspectives/admin.xml +++ /dev/null @@ -1,5 +0,0 @@ -<perspective name="admin" path="/admin" - description="platform administration tasks" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xmlns="urn:xmlns:rhq-perspective"> -</perspective> \ No newline at end of file diff --git a/modules/enterprise/server/jar/src/main/resources/perspectives/content.xml b/modules/enterprise/server/jar/src/main/resources/perspectives/content.xml deleted file mode 100644 index ec9d159..0000000 --- a/modules/enterprise/server/jar/src/main/resources/perspectives/content.xml +++ /dev/null @@ -1,29 +0,0 @@ -<perspective name="content" path="/pulp" - description="advanced software content management" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xmlns="urn:xmlns:rhq-perspective"> - <task name="repo create" path="/pulp/repos/create" - description="Create Repo"> - <pathmatches>/pulp/repos</pathmatches> - <pathmatches>/pulp/repos/create</pathmatches> - <pathmatches>/pulp/repos/create_confirm</pathmatches> - <pathmatches>/pulp/repos/create*</pathmatches> - </task> - <task name="repo add package" - path="/pulp/repos/add_package?cid={0}" - description="Add Content to this Repo" context="repo"> - <pathmatches>/pulp/repos/details/*</pathmatches> - </task> - <task name="repo clone" path="/pulp/repos/clone" - description="Clone A Repo"> - <pathmatches>/pulp/repos/*</pathmatches> - </task> - <task name="repo clone existing" path="/pulp/repos/clone?cid={0}" - description="Clone this Repo" context="repo"> - <pathmatches>/pulp/repos/*</pathmatches> - </task> - <task name="repo delete" path="/pulp/repos/delete" - description="Delete A repo"> - <pathmatches>/pulp/repos/*</pathmatches> - </task> -</perspective> \ No newline at end of file diff --git a/modules/enterprise/server/jar/src/main/resources/perspectives/middleware.xml b/modules/enterprise/server/jar/src/main/resources/perspectives/middleware.xml deleted file mode 100644 index 0d0c9e8..0000000 --- a/modules/enterprise/server/jar/src/main/resources/perspectives/middleware.xml +++ /dev/null @@ -1,5 +0,0 @@ -<perspective name="middleware" path="/middleware" - description="manage middleware applications" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xmlns="urn:xmlns:rhq-perspective"> -</perspective> diff --git a/modules/enterprise/server/jar/src/main/resources/perspectives/root.xml b/modules/enterprise/server/jar/src/main/resources/perspectives/root.xml deleted file mode 100644 index e222b25..0000000 --- a/modules/enterprise/server/jar/src/main/resources/perspectives/root.xml +++ /dev/null @@ -1,5 +0,0 @@ -<perspective name="root" path="/" - description="start here" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xmlns="urn:xmlns:rhq-perspective"> -</perspective> \ No newline at end of file
commit b8e319fbde14b3182b336357c45cd221ee5b735f Author: John Sanda john@localhost.localdomain Date: Mon Nov 16 07:00:04 2009 -0500
Adding unit tests for serialization code.
diff --git a/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/ConfigurationTest.java b/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/ConfigurationTest.java index ae44996..5f8ce70 100644 --- a/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/ConfigurationTest.java +++ b/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/ConfigurationTest.java @@ -363,6 +363,24 @@ public class ConfigurationTest { public void agentSerializationShouldCopyId() throws Exception { ExternalizableStrategy.setStrategy(ExternalizableStrategy.Subsystem.AGENT);
+ assertIdFieldSerialized(); + } + + @Test + public void reflectiveSerializationShouldNotCopyId() throws Exception { + ExternalizableStrategy.setStrategy(ExternalizableStrategy.Subsystem.REFLECTIVE_SERIALIZATION); + + assertIdFieldSerialized(); + } + + @Test + public void remoteAPISerializationShouldCopyId() throws Exception { + ExternalizableStrategy.setStrategy(ExternalizableStrategy.Subsystem.REMOTEAPI); + + assertIdFieldSerialized(); + } + + private void assertIdFieldSerialized() throws Exception { int id = -1;
Configuration config = new Configuration(); @@ -377,6 +395,24 @@ public class ConfigurationTest { public void agentSerializationShouldCopyPropertiesMap() throws Exception { ExternalizableStrategy.setStrategy(ExternalizableStrategy.Subsystem.AGENT);
+ assertPropertiesFieldIsSerialized(); + } + + @Test + public void reflectiveSerializationShouldCopyPropertiesMap() throws Exception { + ExternalizableStrategy.setStrategy(ExternalizableStrategy.Subsystem.REFLECTIVE_SERIALIZATION); + + assertPropertiesFieldIsSerialized(); + } + + @Test + public void remoteAPISerializationShouldCopyPropertiesMap() throws Exception { + ExternalizableStrategy.setStrategy(ExternalizableStrategy.Subsystem.REMOTEAPI); + + assertPropertiesFieldIsSerialized(); + } + + private void assertPropertiesFieldIsSerialized() throws Exception { Configuration config = new Configuration(); config.put(new PropertySimple("x", "1"));
@@ -389,6 +425,25 @@ public class ConfigurationTest { public void agentSerializationShouldCopyNotes() throws Exception { ExternalizableStrategy.setStrategy(ExternalizableStrategy.Subsystem.AGENT);
+ assertNotesFieldSerialized(); + } + + @Test + public void reflectiveSerializationShouldCopyNotes() throws Exception { + ExternalizableStrategy.setStrategy(ExternalizableStrategy.Subsystem.REFLECTIVE_SERIALIZATION); + + assertNotesFieldSerialized(); + } + + @Test + public void remoteAPISerializationShouldCopyNotes() throws Exception { + ExternalizableStrategy.setStrategy(ExternalizableStrategy.Subsystem.REMOTEAPI); + + assertNotesFieldSerialized(); + } + + private void assertNotesFieldSerialized() throws Exception { + Configuration config = new Configuration(); config.setNotes("notes");
@@ -401,6 +456,24 @@ public class ConfigurationTest { public void agentSerializationShouldCopyVersion() throws Exception { ExternalizableStrategy.setStrategy(ExternalizableStrategy.Subsystem.AGENT);
+ assertVersionFieldIsSerialized(); + } + + @Test + public void reflectiveSerializationShouldCopyVersion() throws Exception { + ExternalizableStrategy.setStrategy(ExternalizableStrategy.Subsystem.REFLECTIVE_SERIALIZATION); + + assertVersionFieldIsSerialized(); + } + + @Test + public void remoteAPISerializationShouldCopyVersion() throws Exception { + ExternalizableStrategy.setStrategy(ExternalizableStrategy.Subsystem.REMOTEAPI); + + assertVersionFieldIsSerialized(); + } + + private void assertVersionFieldIsSerialized() throws Exception { Configuration config = new Configuration(); config.setVersion(1L);
@@ -417,6 +490,24 @@ public class ConfigurationTest { public void agentSerializationShouldCopyModifiedTime() throws Exception { ExternalizableStrategy.setStrategy(ExternalizableStrategy.Subsystem.AGENT);
+ assertModifiedTimeIsSerialized(); + } + + @Test + public void reflectiveSerializationShouldCopyModifiedTime() throws Exception { + ExternalizableStrategy.setStrategy(ExternalizableStrategy.Subsystem.REFLECTIVE_SERIALIZATION); + + assertModifiedTimeIsSerialized(); + } + + @Test + public void remoteAPISerializationShouldCopyModifiedTime() throws Exception { + ExternalizableStrategy.setStrategy(ExternalizableStrategy.Subsystem.REMOTEAPI); + + assertModifiedTimeIsSerialized(); + } + + private void assertModifiedTimeIsSerialized() throws Exception { Configuration config = new Configuration(); updateModifiedTime(config);
@@ -434,6 +525,24 @@ public class ConfigurationTest { public void agentSerializationShouldCopyCreatedTime() throws Exception { ExternalizableStrategy.setStrategy(ExternalizableStrategy.Subsystem.AGENT);
+ assertCreatedTimeIsSerialized(); + } + + @Test + public void reflectiveSerializationShouldCopyCreatedTime() throws Exception { + ExternalizableStrategy.setStrategy(ExternalizableStrategy.Subsystem.REFLECTIVE_SERIALIZATION); + + assertCreatedTimeIsSerialized(); + } + + @Test + public void remoteAPISerializationShouldCopyCreatedTime() throws Exception { + ExternalizableStrategy.setStrategy(ExternalizableStrategy.Subsystem.REMOTEAPI); + + assertCreatedTimeIsSerialized(); + } + + private void assertCreatedTimeIsSerialized() throws Exception { Configuration config = new Configuration(); updateCreatedTime(config);
@@ -450,6 +559,24 @@ public class ConfigurationTest { public void agentSerializationShouldCopyRawConfigurations() throws Exception { ExternalizableStrategy.setStrategy(ExternalizableStrategy.Subsystem.AGENT);
+ assertRawConfigurationsIsSerialized(); + } + + @Test + public void reflectiveSerializationShouldCopyRawConfigurations() throws Exception { + ExternalizableStrategy.setStrategy(ExternalizableStrategy.Subsystem.REFLECTIVE_SERIALIZATION); + + assertRawConfigurationsIsSerialized(); + } + + @Test + public void remoteAPISerializationShouldCopyRawConfigurations() throws Exception { + ExternalizableStrategy.setStrategy(ExternalizableStrategy.Subsystem.REMOTEAPI); + + assertRawConfigurationsIsSerialized(); + } + + private void assertRawConfigurationsIsSerialized() throws Exception { Configuration config = new Configuration(); config.addRawConfiguration(createRawConfiguration("/tmp/foo.txt")); config.addRawConfiguration(createRawConfiguration("/tmp/bar.txt")); @@ -482,5 +609,5 @@ public class ConfigurationTest {
return (Configuration) istream.readObject(); } - + }
commit 51175dac99758c9a6b7ca31af6e99a0f953bb1f5 Merge: 39922c0... c32d9ab... Author: John Sanda john@localhost.localdomain Date: Mon Nov 16 00:14:20 2009 -0500
Merge branch 'raw-config' of ssh://git.fedorahosted.org/git/rhq/rhq into raw-config
commit 39922c025303351df271780aaba517f584554899 Author: John Sanda john@localhost.localdomain Date: Mon Nov 16 00:13:08 2009 -0500
Updating Structured and Raw Server to handle 3 config files and fixing the confiurationFormat attribute of Structured Server so that it is 'structured' instead of 'both'
diff --git a/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/StructuredAndRawServer.groovy b/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/StructuredAndRawServer.groovy index 267cc5a..0f2b53f 100644 --- a/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/StructuredAndRawServer.groovy +++ b/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/StructuredAndRawServer.groovy @@ -15,28 +15,38 @@ class StructuredAndRawServer implements ResourceComponent, ResourceConfiguration
File rawConfig1
+ File rawConfig2 + + File rawConfig3 + void start(ResourceContext context) { rawConfigDir = new File("${System.getProperty('java.io.tmpdir')}/raw-config-test") rawConfig1 = new File(rawConfigDir, "structured-and-raw-test-1.txt") + rawConfig2 = new File(rawConfigDir, "structured-and-raw-test-2.txt") + rawConfig3 = new File(rawConfigDir, "structured-and-raw-test-3.txt")
createRawConfigDir() - createConfigFile() + createConfigFile(rawConfig1, ["x": "1", "y": "2", "z": "3"]) + createConfigFile(rawConfig2, ["username": "rhqadmin", "password": "rhqadmin"]) + createConfigFile(rawConfig3, ["rhq.server.hostname": "localhost", "rhq.server.port": "7080"]) }
def createRawConfigDir() { rawConfigDir.mkdirs() }
- def createConfigFile() { - if (rawConfig1.exists()) { + def createConfigFile(File rawConfig, Map properties) { + if (rawConfig.exists()) { return null }
- def properties = ["x": 1, "y": 2, "z": "3"] + addProperties(rawConfig, properties) + }
- rawConfig1.createNewFile() - rawConfig1.withWriter { writer -> - properties.each { key, value -> writer.writeLine("${key}=${value}") } + def addProperties(File rawConfig, Map properties) { + rawConfig.createNewFile() + rawConfig.withWriter {writer -> + properties.each {key, value -> writer.writeLine("${key}=${value}") } } }
@@ -48,33 +58,62 @@ class StructuredAndRawServer implements ResourceComponent, ResourceConfiguration }
Configuration loadStructuredConfiguration() { - def propertiesConfig = new PropertiesConfiguration(rawConfig1) def config = new Configuration()
+ loadStructuredForRawConfig1(config) + loadStructuredForRawConfig2(config) + loadStructuredForRawConfig3(config) + + return config + } + + def loadStructuredForRawConfig1(Configuration config) { + def propertiesConfig = new PropertiesConfiguration(rawConfig1) + config.put(new PropertySimple("x", propertiesConfig.getString("x"))) config.put(new PropertySimple("y", propertiesConfig.getString("y"))) config.put(new PropertySimple("z", propertiesConfig.getString("z"))) + }
- return config + def loadStructuredForRawConfig2(Configuration config) { + def propertiesConfig = new PropertiesConfiguration(rawConfig2) + + config.put(new PropertySimple("username", propertiesConfig.getString("username"))) + config.put(new PropertySimple("password", propertiesConfig.getString("password"))) + } + + def loadStructuredForRawConfig3(Configuration config) { + def propertiesConfig = new PropertiesConfiguration(rawConfig3) + + config.put(new PropertySimple("rhq.server.hostname", propertiesConfig.getString("rhq.server.hostname"))) + config.put(new PropertySimple("rhq.server.port", propertiesConfig.getString("rhq.server.port"))) }
Set<RawConfiguration> loadRawConfigurations() { def rawConfigs = new HashSet<RawConfiguration>() rawConfigs.add(new RawConfiguration(path: rawConfig1.absolutePath, contents: rawConfig1.readBytes())) + rawConfigs.add(new RawConfiguration(path: rawConfig2.absolutePath, contents: rawConfig2.readBytes())) + rawConfigs.add(new RawConfiguration(path: rawConfig3.absolutePath, contents: rawConfig3.readBytes()))
return rawConfigs }
void mergeRawConfiguration(Configuration configuration, RawConfiguration rawConfiguration) { def rawPropertiesConfig = loadRawPropertiesConfiguration(rawConfiguration) + def propertyNames = getPropertyNames(rawConfiguration)
- def x = configuration.get("x") - def y = configuration.get("y") - def z = configuration.get("z") + propertyNames.each { propertyName -> + def property = configuration.get(propertyName) + rawPropertiesConfig.setProperty(propertyName, property.stringValue) + }
- rawPropertiesConfig.setProperty("x", x.stringValue) - rawPropertiesConfig.setProperty("y", y.stringValue) - rawPropertiesConfig.setProperty("z", z.stringValue) +// def x = configuration.get("x") +// def y = configuration.get("y") +// def z = configuration.get("z") +// +// rawPropertiesConfig.setProperty("x", x.stringValue) +// rawPropertiesConfig.setProperty("y", y.stringValue) +// rawPropertiesConfig.setProperty("z", z.stringValue)
def stream = new ByteArrayOutputStream() rawPropertiesConfig.save(stream) @@ -91,10 +130,28 @@ class StructuredAndRawServer implements ResourceComponent, ResourceConfiguration
void mergeStructuredConfiguration(RawConfiguration rawConfiguration, Configuration configuration) { def rawPropertiesConfig = loadRawPropertiesConfiguration(rawConfiguration) + def propertyNames = getPropertyNames(rawConfiguration) + + propertyNames.each { name -> configuration.put(new PropertySimple(name, rawPropertiesConfig.getString(name))) }
- configuration.put(new PropertySimple("x", rawPropertiesConfig.getString("x"))) - configuration.put(new PropertySimple("y", rawPropertiesConfig.getString("y"))) - configuration.put(new PropertySimple("z", rawPropertiesConfig.getString("z"))) +// configuration.put(new PropertySimple("x", rawPropertiesConfig.getString("x"))) +// configuration.put(new PropertySimple("y", rawPropertiesConfig.getString("y"))) +// configuration.put(new PropertySimple("z", rawPropertiesConfig.getString("z"))) + } + + def getPropertyNames(rawConfig) { + if (rawConfig == rawConfig1) { + return ["x", "y", "z"] + } + else if (rawConfig == rawConfig2) { + return ["username", "password"] + } + else if (rawConfig == rawConfig3) { + return ["rhq.server.hostname", "rhq.server.port"] + } + else { + throw new RuntimeException("$rawConfig is not a recongnized raw config file") + } }
void validateRawConfiguration(RawConfiguration rawConfig) { diff --git a/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/StructuredServer.groovy b/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/StructuredServer.groovy index 8ec3391..02dae03 100644 --- a/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/StructuredServer.groovy +++ b/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/StructuredServer.groovy @@ -51,9 +51,9 @@ class StructuredServer implements ResourceComponent, ResourceConfigurationFacet def propertiesConfig = new PropertiesConfiguration(rawConfig1) def config = new Configuration()
- config.put(new PropertySimple("x", propertiesConfig.getString("x"))) - config.put(new PropertySimple("y", propertiesConfig.getString("y"))) - config.put(new PropertySimple("z", propertiesConfig.getString("z"))) + config.put(new PropertySimple("foo", propertiesConfig.getString("foo"))) + config.put(new PropertySimple("bar", propertiesConfig.getString("bar"))) + config.put(new PropertySimple("bam", propertiesConfig.getString("bam")))
return config } diff --git a/modules/plugins/raw-config-test/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/raw-config-test/src/main/resources/META-INF/rhq-plugin.xml index e63dfe4..897e4f3 100644 --- a/modules/plugins/raw-config-test/src/main/resources/META-INF/rhq-plugin.xml +++ b/modules/plugins/raw-config-test/src/main/resources/META-INF/rhq-plugin.xml @@ -18,6 +18,10 @@ <c:simple-property name="x"/> <c:simple-property name="y"/> <c:simple-property name="z"/> + <c:simple-property name="username"/> + <c:simple-property name="password"/> + <c:simple-property name="rhq.server.hostname"/> + <c:simple-property name="rhq.server.port"/> </resource-configuration> </server>
@@ -32,7 +36,7 @@ class="StructuredServer" discovery="StructuredDiscoveryComponent" description="A fake server component that supports structured configuration"> - <resource-configuration configurationFormat="both"> + <resource-configuration configurationFormat="structured"> <c:simple-property name="foo"/> <c:simple-property name="bar"/> <c:simple-property name="bam"/>
commit c32d9ab84b7f1f20e46b95aac748c3cf34b19b99 Merge: 244912f... 9e7a1df... Author: Adam Young ayoung@redhat.com Date: Sun Nov 15 18:47:11 2009 -0500
Merge branch 'raw-config' of ssh://git.fedorahosted.org/git/rhq/rhq into raw-config
commit 9e7a1dfc6ccefdf8255ae965fa4001eaed3ee702 Author: John Sanda john@localhost.localdomain Date: Sun Nov 15 09:36:05 2009 -0500
Adding a resource type to test plugin that supports only structured config
diff --git a/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/StructuredDiscoveryComponent.groovy b/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/StructuredDiscoveryComponent.groovy new file mode 100644 index 0000000..f6fa79b --- /dev/null +++ b/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/StructuredDiscoveryComponent.groovy @@ -0,0 +1,24 @@ +package org.rhq.plugins.test.rawconfig + +import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent +import org.rhq.core.pluginapi.inventory.DiscoveredResourceDetails +import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext + +class StructuredDiscoveryComponent implements ResourceDiscoveryComponent { + + Set<DiscoveredResourceDetails> discoverResources(ResourceDiscoveryContext context) { + def details = new HashSet() + + details << new DiscoveredResourceDetails(context.resourceType, + "1", + "Structured Server", + "1.0", + "A fake server component for testing structured config", + context.defaultPluginConfiguration, + null) + + return details + } + + +} diff --git a/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/StructuredServer.groovy b/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/StructuredServer.groovy new file mode 100644 index 0000000..8ec3391 --- /dev/null +++ b/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/StructuredServer.groovy @@ -0,0 +1,83 @@ +package org.rhq.plugins.test.rawconfig + +import org.rhq.core.pluginapi.configuration.ResourceConfigurationFacet +import org.rhq.core.pluginapi.inventory.ResourceComponent +import org.rhq.core.pluginapi.inventory.ResourceContext +import org.rhq.core.domain.measurement.AvailabilityType +import org.rhq.core.domain.configuration.PropertySimple +import org.rhq.core.domain.configuration.Configuration +import org.apache.commons.configuration.PropertiesConfiguration +import org.rhq.core.domain.configuration.RawConfiguration + +class StructuredServer implements ResourceComponent, ResourceConfigurationFacet { + + File rawConfigDir + + File rawConfig1 + + void start(ResourceContext context) { + rawConfigDir = new File("${System.getProperty('java.io.tmpdir')}/raw-config-test") + rawConfig1 = new File(rawConfigDir, "structured-test-1.txt") + + createRawConfigDir() + createConfigFile() + } + + def createRawConfigDir() { + rawConfigDir.mkdirs() + } + + def createConfigFile() { + if (rawConfig1.exists()) { + return null + } + + def properties = ["foo": "1", "bar": "2", "bam": "3"] + + rawConfig1.createNewFile() + rawConfig1.withWriter { writer -> + properties.each { key, value -> writer.writeLine("${key}=${value}") } + } + } + + void stop() { + } + + AvailabilityType getAvailability() { + AvailabilityType.UP + } + + Configuration loadStructuredConfiguration() { + def propertiesConfig = new PropertiesConfiguration(rawConfig1) + def config = new Configuration() + + config.put(new PropertySimple("x", propertiesConfig.getString("x"))) + config.put(new PropertySimple("y", propertiesConfig.getString("y"))) + config.put(new PropertySimple("z", propertiesConfig.getString("z"))) + + return config + } + + Set<RawConfiguration> loadRawConfigurations() { + null + } + + void mergeRawConfiguration(Configuration from, RawConfiguration to) { + } + + void mergeStructuredConfiguration(RawConfiguration from, Configuration to) { + } + + void persistStructuredConfiguration(Configuration configuration) { + } + + void persistRawConfiguration(RawConfiguration rawConfiguration) { + } + + void validateStructuredConfiguration(Configuration configuration) { + } + + void validateRawConfiguration(RawConfiguration rawConfiguration) { + } + +} diff --git a/modules/plugins/raw-config-test/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/raw-config-test/src/main/resources/META-INF/rhq-plugin.xml index 0e41b79..e63dfe4 100644 --- a/modules/plugins/raw-config-test/src/main/resources/META-INF/rhq-plugin.xml +++ b/modules/plugins/raw-config-test/src/main/resources/META-INF/rhq-plugin.xml @@ -27,4 +27,15 @@ description="A fake server component that supports raw configuration"> <resource-configuration configurationFormat="raw"/> </server> + + <server name="Structured Server" + class="StructuredServer" + discovery="StructuredDiscoveryComponent" + description="A fake server component that supports structured configuration"> + <resource-configuration configurationFormat="both"> + <c:simple-property name="foo"/> + <c:simple-property name="bar"/> + <c:simple-property name="bam"/> + </resource-configuration> + </server> </plugin> \ No newline at end of file
commit 1486cf554f593c49c3a9682cfbd26ec21afaa5df Author: John Sanda john@localhost.localdomain Date: Sat Nov 14 23:00:32 2009 -0500
Updating plugin descriptor parsing code to not require child elements of the config when the format is raw.
The plugin parsing code previously threw an exception if a resource type in the plugin descriptor declared <resource-configuration/> without any child elements. Those children correspond to structured configuration. For a resource type that supports only raw, there is no need to specify any child elements. The parsing code has been updated to support this.
Updating raw-config-test plugin with a second resource type that supports only raw configuration which is how I discovered the parsing behavior.
diff --git a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/metadata/ConfigurationMetadataParser.java b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/metadata/ConfigurationMetadataParser.java index 88ba6c6..de68ca6 100644 --- a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/metadata/ConfigurationMetadataParser.java +++ b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/metadata/ConfigurationMetadataParser.java @@ -22,6 +22,8 @@ */ package org.rhq.core.clientapi.agent.metadata;
+import static org.rhq.core.domain.configuration.definition.ConfigurationFormat.RAW; + import java.util.ArrayList; import java.util.HashSet; import java.util.List; @@ -78,6 +80,10 @@ public class ConfigurationMetadataParser { descriptor.getNotes()); configurationDefinition.setConfigurationFormat(getConfigurationFormat(descriptor));
+ if (configurationDefinition.getConfigurationFormat() == RAW) { + return configurationDefinition; + } + for (ConfigurationTemplateDescriptor templateDescriptor : descriptor.getTemplate()) { configurationDefinition.putTemplate(parseTemplate(templateDescriptor)); } diff --git a/modules/core/client-api/src/test/groovy/org/rhq/core/clientapi/agent/metadata/PluginMetadataParserTest.groovy b/modules/core/client-api/src/test/groovy/org/rhq/core/clientapi/agent/metadata/PluginMetadataParserTest.groovy index b43671f..e5bf3c5 100644 --- a/modules/core/client-api/src/test/groovy/org/rhq/core/clientapi/agent/metadata/PluginMetadataParserTest.groovy +++ b/modules/core/client-api/src/test/groovy/org/rhq/core/clientapi/agent/metadata/PluginMetadataParserTest.groovy @@ -351,6 +351,29 @@ class PluginMetadataParserTest { ) }
+ @Test + void rawResourceConfigurationShouldNotHaveToSpecifyAnyStructuredConfig() { + def pluginDescriptor = toPluginDescriptor( + """ + <plugin name="TestServer" displayName="Test Server" package="org.rhq.plugins.test" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns="urn:xmlns:rhq-plugin" + xmlns:c="urn:xmlns:rhq-configuration"> + <server name="testServer" + class="TestServer" + discovery="TestServerDiscoveryComponent"> + <resource-configuration configurationFormat="raw"/> + </server> + </plugin> + """ + ) + + def parsersByPlugin = [:] + + def parser = new PluginMetadataParser(pluginDescriptor, parsersByPlugin) + + } + static PluginDescriptor toPluginDescriptor(String string) { JAXBContext jaxbContext = JAXBContext.newInstance(DescriptorPackages.PC_PLUGIN) URL pluginSchemaURL = PluginMetadataParser.class.getClassLoader().getResource("rhq-plugin.xsd") diff --git a/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/RawConfigDiscoveryComponent.groovy b/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/RawConfigDiscoveryComponent.groovy deleted file mode 100644 index 2c006fa..0000000 --- a/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/RawConfigDiscoveryComponent.groovy +++ /dev/null @@ -1,23 +0,0 @@ -package org.rhq.plugins.test.rawconfig - -import org.rhq.core.pluginapi.inventory.DiscoveredResourceDetails -import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent -import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext - -class RawConfigDiscoveryComponent implements ResourceDiscoveryComponent { - - Set<DiscoveredResourceDetails> discoverResources(ResourceDiscoveryContext context) { - def details = new HashSet() - - details << new DiscoveredResourceDetails(context.resourceType, - "1", - "Raw Config Server", - "1.0", - "A fake server component for testing raw config", - context.defaultPluginConfiguration, - null) - - return details - } - -} \ No newline at end of file diff --git a/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/RawConfigServer.groovy b/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/RawConfigServer.groovy deleted file mode 100644 index ae908e3..0000000 --- a/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/RawConfigServer.groovy +++ /dev/null @@ -1,112 +0,0 @@ -package org.rhq.plugins.test.rawconfig - -import org.rhq.core.pluginapi.inventory.ResourceComponent -import org.rhq.core.pluginapi.inventory.ResourceContext -import org.rhq.core.domain.measurement.AvailabilityType -import org.rhq.core.pluginapi.configuration.ResourceConfigurationFacet -import org.rhq.core.domain.configuration.Configuration -import org.rhq.core.domain.configuration.RawConfiguration -import org.rhq.core.domain.configuration.PropertySimple -import org.apache.commons.configuration.PropertiesConfiguration - -class RawConfigServer implements ResourceComponent, ResourceConfigurationFacet { - - File rawConfigDir - - File rawConfig1 - - void start(ResourceContext context) { - rawConfigDir = new File("${System.getProperty('java.io.tmpdir')}/raw-config-test") - rawConfig1 = new File(rawConfigDir, "rawconfig-test-1.txt") - - createRawConfigDir() - createConfigFile() - } - - def createRawConfigDir() { - rawConfigDir.mkdirs() - } - - def createConfigFile() { - if (rawConfig1.exists()) { - return null - } - - def properties = ["x": 1, "y": 2, "z": "3"] - - rawConfig1.createNewFile() - rawConfig1.withWriter { writer -> - properties.each { key, value -> writer.writeLine("${key}=${value}") } - } - } - - void stop() { - } - - AvailabilityType getAvailability() { - AvailabilityType.UP - } - - Configuration loadStructuredConfiguration() { - def propertiesConfig = new PropertiesConfiguration(rawConfig1) - def config = new Configuration() - - config.put(new PropertySimple("x", propertiesConfig.getString("x"))) - config.put(new PropertySimple("y", propertiesConfig.getString("y"))) - config.put(new PropertySimple("z", propertiesConfig.getString("z"))) - - return config - } - - Set<RawConfiguration> loadRawConfigurations() { - def rawConfigs = new HashSet<RawConfiguration>() - rawConfigs.add(new RawConfiguration(path: rawConfig1.absolutePath, contents: rawConfig1.readBytes())) - - return rawConfigs - } - - void mergeRawConfiguration(Configuration configuration, RawConfiguration rawConfiguration) { - def rawPropertiesConfig = loadRawPropertiesConfiguration(rawConfiguration) - - def x = configuration.get("x") - def y = configuration.get("y") - def z = configuration.get("z") - - rawPropertiesConfig.setProperty("x", x.stringValue) - rawPropertiesConfig.setProperty("y", y.stringValue) - rawPropertiesConfig.setProperty("z", z.stringValue) - - def stream = new ByteArrayOutputStream() - rawPropertiesConfig.save(stream) - rawConfiguration.contents = stream.toByteArray() - } - - def loadRawPropertiesConfiguration(rawConfig) { - def stream = new ByteArrayInputStream(rawConfig.contents) - def rawPropertiesConfig = new PropertiesConfiguration() - rawPropertiesConfig.load(stream) - - return rawPropertiesConfig - } - - void mergeStructuredConfiguration(RawConfiguration rawConfiguration, Configuration configuration) { - def rawPropertiesConfig = loadRawPropertiesConfiguration(rawConfiguration) - - configuration.put(new PropertySimple("x", rawPropertiesConfig.getString("x"))) - configuration.put(new PropertySimple("y", rawPropertiesConfig.getString("y"))) - configuration.put(new PropertySimple("z", rawPropertiesConfig.getString("z"))) - } - - void validateRawConfiguration(RawConfiguration rawConfig) { - } - - void validateStructuredConfiguration(Configuration config) { - } - - void persistStructuredConfiguration(Configuration config) { - } - - void persistRawConfiguration(RawConfiguration rawConfig) { - } - -} \ No newline at end of file diff --git a/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/RawDiscoveryComponent.groovy b/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/RawDiscoveryComponent.groovy new file mode 100644 index 0000000..70d57f7 --- /dev/null +++ b/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/RawDiscoveryComponent.groovy @@ -0,0 +1,22 @@ +package org.rhq.plugins.test.rawconfig + +import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent +import org.rhq.core.pluginapi.inventory.DiscoveredResourceDetails +import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext + +class RawDiscoveryComponent implements ResourceDiscoveryComponent { + + Set<DiscoveredResourceDetails> discoverResources(ResourceDiscoveryContext context) { + def details = new HashSet() + + details << new DiscoveredResourceDetails(context.resourceType, + "1", + "Raw Server", + "1.0", + "A fake server component for testing raw config", + context.defaultPluginConfiguration, + null) + } + + +} diff --git a/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/RawServer.groovy b/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/RawServer.groovy new file mode 100644 index 0000000..9eafc98 --- /dev/null +++ b/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/RawServer.groovy @@ -0,0 +1,77 @@ +package org.rhq.plugins.test.rawconfig + +import org.rhq.core.pluginapi.inventory.ResourceComponent +import org.rhq.core.pluginapi.configuration.ResourceConfigurationFacet +import org.rhq.core.domain.configuration.Configuration +import org.rhq.core.domain.configuration.RawConfiguration +import org.rhq.core.domain.measurement.AvailabilityType +import org.rhq.core.pluginapi.inventory.ResourceContext + +class RawServer implements ResourceComponent, ResourceConfigurationFacet { + + File rawConfigDir + + File rawConfig1 + + void start(ResourceContext context) { + rawConfigDir = new File("${System.getProperty('java.io.tmpdir')}/raw-config-test") + rawConfig1 = new File(rawConfigDir, "raw-test-1.txt") + + createRawConfigDir() + createConfigFile() + } + + def createRawConfigDir() { + rawConfigDir.mkdirs() + } + + def createConfigFile() { + if (rawConfig1.exists()) { + return null + } + + def properties = ["a": 1, "b": 2, "c": "3"] + + rawConfig1.createNewFile() + rawConfig1.withWriter { writer -> + properties.each { key, value -> writer.writeLine("${key}=${value}") } + } + } + + void stop() { + } + + AvailabilityType getAvailability() { + AvailabilityType.UP + } + + Configuration loadStructuredConfiguration() { + null + } + + Set<RawConfiguration> loadRawConfigurations() { + def rawConfigs = new HashSet() + rawConfigs.add(new RawConfiguration(path: rawConfig1.absolutePath, contents: rawConfig1.readBytes())) + + return rawConfigs + } + + void mergeRawConfiguration(Configuration from, RawConfiguration to) { + } + + void mergeStructuredConfiguration(RawConfiguration from, Configuration to) { + } + + void persistStructuredConfiguration(Configuration configuration) { + } + + void persistRawConfiguration(RawConfiguration rawConfiguration) { + } + + void validateStructuredConfiguration(Configuration configuration) { + } + + void validateRawConfiguration(RawConfiguration rawConfiguration) { + } + +} diff --git a/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/StructuredAndRawDiscoveryComponent.groovy b/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/StructuredAndRawDiscoveryComponent.groovy new file mode 100644 index 0000000..7472952 --- /dev/null +++ b/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/StructuredAndRawDiscoveryComponent.groovy @@ -0,0 +1,23 @@ +package org.rhq.plugins.test.rawconfig + +import org.rhq.core.pluginapi.inventory.DiscoveredResourceDetails +import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent +import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext + +class StructuredAndRawDiscoveryComponent implements ResourceDiscoveryComponent { + + Set<DiscoveredResourceDetails> discoverResources(ResourceDiscoveryContext context) { + def details = new HashSet() + + details << new DiscoveredResourceDetails(context.resourceType, + "1", + "Structured and Raw Server", + "1.0", + "A fake server component for testing structured and raw config", + context.defaultPluginConfiguration, + null) + + return details + } + +} \ No newline at end of file diff --git a/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/StructuredAndRawServer.groovy b/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/StructuredAndRawServer.groovy new file mode 100644 index 0000000..267cc5a --- /dev/null +++ b/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/StructuredAndRawServer.groovy @@ -0,0 +1,112 @@ +package org.rhq.plugins.test.rawconfig + +import org.rhq.core.pluginapi.inventory.ResourceComponent +import org.rhq.core.pluginapi.inventory.ResourceContext +import org.rhq.core.domain.measurement.AvailabilityType +import org.rhq.core.pluginapi.configuration.ResourceConfigurationFacet +import org.rhq.core.domain.configuration.Configuration +import org.rhq.core.domain.configuration.RawConfiguration +import org.rhq.core.domain.configuration.PropertySimple +import org.apache.commons.configuration.PropertiesConfiguration + +class StructuredAndRawServer implements ResourceComponent, ResourceConfigurationFacet { + + File rawConfigDir + + File rawConfig1 + + void start(ResourceContext context) { + rawConfigDir = new File("${System.getProperty('java.io.tmpdir')}/raw-config-test") + rawConfig1 = new File(rawConfigDir, "structured-and-raw-test-1.txt") + + createRawConfigDir() + createConfigFile() + } + + def createRawConfigDir() { + rawConfigDir.mkdirs() + } + + def createConfigFile() { + if (rawConfig1.exists()) { + return null + } + + def properties = ["x": 1, "y": 2, "z": "3"] + + rawConfig1.createNewFile() + rawConfig1.withWriter { writer -> + properties.each { key, value -> writer.writeLine("${key}=${value}") } + } + } + + void stop() { + } + + AvailabilityType getAvailability() { + AvailabilityType.UP + } + + Configuration loadStructuredConfiguration() { + def propertiesConfig = new PropertiesConfiguration(rawConfig1) + def config = new Configuration() + + config.put(new PropertySimple("x", propertiesConfig.getString("x"))) + config.put(new PropertySimple("y", propertiesConfig.getString("y"))) + config.put(new PropertySimple("z", propertiesConfig.getString("z"))) + + return config + } + + Set<RawConfiguration> loadRawConfigurations() { + def rawConfigs = new HashSet<RawConfiguration>() + rawConfigs.add(new RawConfiguration(path: rawConfig1.absolutePath, contents: rawConfig1.readBytes())) + + return rawConfigs + } + + void mergeRawConfiguration(Configuration configuration, RawConfiguration rawConfiguration) { + def rawPropertiesConfig = loadRawPropertiesConfiguration(rawConfiguration) + + def x = configuration.get("x") + def y = configuration.get("y") + def z = configuration.get("z") + + rawPropertiesConfig.setProperty("x", x.stringValue) + rawPropertiesConfig.setProperty("y", y.stringValue) + rawPropertiesConfig.setProperty("z", z.stringValue) + + def stream = new ByteArrayOutputStream() + rawPropertiesConfig.save(stream) + rawConfiguration.contents = stream.toByteArray() + } + + def loadRawPropertiesConfiguration(rawConfig) { + def stream = new ByteArrayInputStream(rawConfig.contents) + def rawPropertiesConfig = new PropertiesConfiguration() + rawPropertiesConfig.load(stream) + + return rawPropertiesConfig + } + + void mergeStructuredConfiguration(RawConfiguration rawConfiguration, Configuration configuration) { + def rawPropertiesConfig = loadRawPropertiesConfiguration(rawConfiguration) + + configuration.put(new PropertySimple("x", rawPropertiesConfig.getString("x"))) + configuration.put(new PropertySimple("y", rawPropertiesConfig.getString("y"))) + configuration.put(new PropertySimple("z", rawPropertiesConfig.getString("z"))) + } + + void validateRawConfiguration(RawConfiguration rawConfig) { + } + + void validateStructuredConfiguration(Configuration config) { + } + + void persistStructuredConfiguration(Configuration config) { + } + + void persistRawConfiguration(RawConfiguration rawConfig) { + } + +} \ No newline at end of file diff --git a/modules/plugins/raw-config-test/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/raw-config-test/src/main/resources/META-INF/rhq-plugin.xml index f7169fe..0e41b79 100644 --- a/modules/plugins/raw-config-test/src/main/resources/META-INF/rhq-plugin.xml +++ b/modules/plugins/raw-config-test/src/main/resources/META-INF/rhq-plugin.xml @@ -10,9 +10,9 @@ xmlns="urn:xmlns:rhq-plugin" xmlns:c="urn:xmlns:rhq-configuration">
- <server name="Raw Config Server" - class="RawConfigServer" - discovery="RawConfigDiscoveryComponent" + <server name="Structured and Raw Server" + class="StructuredAndRawServer" + discovery="StructuredAndRawDiscoveryComponent" description="A fake server component that supports both structured and raw configuration"> <resource-configuration configurationFormat="both"> <c:simple-property name="x"/> @@ -20,4 +20,11 @@ <c:simple-property name="z"/> </resource-configuration> </server> + + <server name="Raw Server" + class="RawServer" + discovery="RawDiscoveryComponent" + description="A fake server component that supports raw configuration"> + <resource-configuration configurationFormat="raw"/> + </server> </plugin> \ No newline at end of file
commit 2445accc0c62c3cf8094a71dffcd43bc6f99c582 Author: John Sanda john@localhost.localdomain Date: Sat Nov 14 17:31:57 2009 -0500
Updating .gitignore for IntelliJ 9
diff --git a/.gitignore b/.gitignore index 21d58ab..8def9cb 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,8 @@ logs *.iml *.ipr *.iws +.idea +.idea/* dev-container modules/dev-container dev-agent
commit 1cfabfface4be109220d937c4fbc30988b7d25ee Author: John Sanda john@localhost.localdomain Date: Sat Nov 14 07:20:02 2009 -0500
Updating plugin with facet API changes for the load methods
diff --git a/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/RawConfigServer.groovy b/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/RawConfigServer.groovy index 6b591e4..ae908e3 100644 --- a/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/RawConfigServer.groovy +++ b/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/RawConfigServer.groovy @@ -48,16 +48,23 @@ class RawConfigServer implements ResourceComponent, ResourceConfigurationFacet { }
Configuration loadStructuredConfiguration() { - return loadRawConfigurations() - } + def propertiesConfig = new PropertiesConfiguration(rawConfig1) + def config = new Configuration()
- Configuration loadRawConfigurations() { - Configuration config = new Configuration() - config.addRawConfiguration(new RawConfiguration(path: rawConfig1.absolutePath, contents: rawConfig1.readBytes())) + config.put(new PropertySimple("x", propertiesConfig.getString("x"))) + config.put(new PropertySimple("y", propertiesConfig.getString("y"))) + config.put(new PropertySimple("z", propertiesConfig.getString("z")))
return config }
+ Set<RawConfiguration> loadRawConfigurations() { + def rawConfigs = new HashSet<RawConfiguration>() + rawConfigs.add(new RawConfiguration(path: rawConfig1.absolutePath, contents: rawConfig1.readBytes())) + + return rawConfigs + } + void mergeRawConfiguration(Configuration configuration, RawConfiguration rawConfiguration) { def rawPropertiesConfig = loadRawPropertiesConfiguration(rawConfiguration)
@@ -90,4 +97,16 @@ class RawConfigServer implements ResourceComponent, ResourceConfigurationFacet { configuration.put(new PropertySimple("z", rawPropertiesConfig.getString("z"))) }
+ void validateRawConfiguration(RawConfiguration rawConfig) { + } + + void validateStructuredConfiguration(Configuration config) { + } + + void persistStructuredConfiguration(Configuration config) { + } + + void persistRawConfiguration(RawConfiguration rawConfig) { + } + } \ No newline at end of file
commit 244912fd6f3a04092886e871964424534e8c10d3 Author: Adam Young ayoung@redhat.com Date: Fri Nov 13 23:33:21 2009 -0500
Changes made in structured visible in raw
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ExistingResourceConfigurationUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ExistingResourceConfigurationUIBean.java index e717ed5..846b867 100644 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ExistingResourceConfigurationUIBean.java +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ExistingResourceConfigurationUIBean.java @@ -22,7 +22,11 @@ import javax.faces.application.FacesMessage;
import org.jetbrains.annotations.Nullable;
-import org.rhq.core.domain.auth.Subject; +import org.jboss.seam.ScopeType; +import org.jboss.seam.annotations.In; +import org.jboss.seam.annotations.Name; +import org.jboss.seam.annotations.Scope; + import org.rhq.core.domain.configuration.AbstractResourceConfigurationUpdate; import org.rhq.core.domain.configuration.Configuration; import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; @@ -36,6 +40,8 @@ import org.rhq.enterprise.server.util.LookupUtil; /** * @author Ian Springer */ +@Name(value = "ExistingResourceConfigurationUIBean") +@Scope(ScopeType.PAGE) public class ExistingResourceConfigurationUIBean extends AbstractConfigurationUIBean { public static final String MANAGED_BEAN_NAME = "ExistingResourceConfigurationUIBean";
@@ -123,6 +129,8 @@ public class ExistingResourceConfigurationUIBean extends AbstractConfigurationUI
@Nullable protected Configuration lookupConfiguration() { + + /* Subject subject = EnterpriseFacesContextUtility.getSubject(); int resourceId = EnterpriseFacesContextUtility.getResource().getId(); AbstractResourceConfigurationUpdate configurationUpdate = this.configurationManager @@ -133,5 +141,21 @@ public class ExistingResourceConfigurationUIBean extends AbstractConfigurationUI }
return configuration; + */ + + return getRawConfigCollection().getConfiguration(); + + } + + @In(create = true, required = true, value = "rawConfigCollection") + RawConfigCollection rawConfigCollection; + + public RawConfigCollection getRawConfigCollection() { + return rawConfigCollection; } + + public void setRawConfigCollection(RawConfigCollection rawConfigCollection) { + this.rawConfigCollection = rawConfigCollection; + } + } \ No newline at end of file diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-managed-beans/configuration-beans.xml b/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-managed-beans/configuration-beans.xml index 1383c31..de0dace 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-managed-beans/configuration-beans.xml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-managed-beans/configuration-beans.xml @@ -4,19 +4,19 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd%22%3E
- <!-- /rhq/resource/configuration/view.xhtml, /rhq/resource/configuration/view-map.xhtml --> + <!-- /rhq/resource/configuration/view.xhtml, /rhq/resource/configuration/view-map.xhtml <managed-bean> <managed-bean-name>ExistingResourceConfigurationViewUIBean</managed-bean-name> <managed-bean-class>org.rhq.enterprise.gui.configuration.resource.ExistingResourceConfigurationUIBean</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> - </managed-bean> + </managed-bean> --> <!-- /rhq/resource/configuration/history.xhtml, /rhq/resource/configuration/edit.xhtml, and - /rhq/resource/configuration/edit-map.xhtml --> + /rhq/resource/configuration/edit-map.xhtml <managed-bean> <managed-bean-name>ExistingResourceConfigurationUIBean</managed-bean-name> <managed-bean-class>org.rhq.enterprise.gui.configuration.resource.ExistingResourceConfigurationUIBean</managed-bean-class> <managed-bean-scope>session</managed-bean-scope> - </managed-bean> + </managed-bean> -->
<!-- /rhq/resource/configuration/add-new-simple.xhtml --> <managed-bean> diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-navigation/configuration-navigation.xml b/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-navigation/configuration-navigation.xml index d1c2f14..fc93ea8 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-navigation/configuration-navigation.xml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-navigation/configuration-navigation.xml @@ -9,13 +9,13 @@ <from-view-id>/rhq/resource/configuration/view.xhtml</from-view-id>
<navigation-case> - <from-action>#{ExistingResourceConfigurationViewUIBean.editConfiguration}</from-action> + <from-action>#{ExistingResourceConfigurationUIBean.editConfiguration}</from-action> <to-view-id>/rhq/resource/configuration/edit.xhtml?id=#{param.id}</to-view-id> <redirect/> </navigation-case>
<navigation-case> - <from-action>#{ExistingResourceConfigurationViewUIBean.editRawConfiguration}</from-action> + <from-action>#{ExistingResourceConfigurationUIBean.editRawConfiguration}</from-action> <to-view-id>/rhq/resource/configuration/edit-raw.xhtml?id=#{param.id}</to-view-id> <redirect/> </navigation-case> diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view-map.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view-map.xhtml index 837fa3a..91ff1cb 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view-map.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view-map.xhtml @@ -27,8 +27,8 @@ THIS TEXT WILL BE REMOVED.
<input type="hidden" name="id" value="#{ResourceUIBean.id}"/>
- <onc:config configurationDefinition="#{ExistingResourceConfigurationViewUIBean.configurationDefinition}" - configuration="#{ExistingResourceConfigurationViewUIBean.configuration}" + <onc:config configurationDefinition="#{ExistingResourceConfigurationUIBean.configurationDefinition}" + configuration="#{ExistingResourceConfigurationUIBean.configuration}" listName="#{param.listName}" listIndex="#{param.listIndex}" readOnly="true" diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml index 638bdb2..dd4631e 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml @@ -23,7 +23,7 @@ THIS TEXT WILL BE REMOVED.
<ui:define name="content">
- <h:panelGroup layout="block" styleClass="InfoBlock" rendered="#{ExistingResourceConfigurationViewUIBean.updateInProgress}"> + <h:panelGroup layout="block" styleClass="InfoBlock" rendered="#{ExistingResourceConfigurationUIBean.updateInProgress}"> <b>${msg['note']}</b> ${msg['resource.config.Current.updateInProgress']} </h:panelGroup>
@@ -44,27 +44,27 @@ THIS TEXT WILL BE REMOVED.
<h:panelGrid columns="2" styleClass="buttons-table" columnClasses="button-cell" - rendered="#{ExistingResourceConfigurationViewUIBean.configuration != null and !ExistingResourceConfigurationViewUIBean.updateInProgress}"> + rendered="#{ExistingResourceConfigurationUIBean.configuration != null and !ExistingResourceConfigurationUIBean.updateInProgress}">
- <h:commandButton value="#{messages.editstructured}" action="#{ExistingResourceConfigurationViewUIBean.editConfiguration}" + <h:commandButton value="#{messages.editstructured}" action="#{ExistingResourceConfigurationUIBean.editConfiguration}" title="Edit this Configuration" styleClass="buttonmed" - rendered="${ResourceUIBean.permissions.configure and rawConfigCollection.structuredSupported and !ExistingResourceConfigurationViewUIBean.updateInProgress}" /> - <h:commandButton value="#{messages.editraw}" action="#{ExistingResourceConfigurationViewUIBean.editRawConfiguration}" + rendered="${ResourceUIBean.permissions.configure and rawConfigCollection.structuredSupported and !ExistingResourceConfigurationUIBean.updateInProgress}" /> + <h:commandButton value="#{messages.editraw}" action="#{ExistingResourceConfigurationUIBean.editRawConfiguration}" title="Advanced Mode Edit of Raw Configuration Files" styleClass="buttonmed" - rendered="${ResourceUIBean.permissions.configure and rawConfigCollection.rawSupported and !ExistingResourceConfigurationViewUIBean.updateInProgress}" /> + rendered="${ResourceUIBean.permissions.configure and rawConfigCollection.rawSupported and !ExistingResourceConfigurationUIBean.updateInProgress}" /> </h:panelGrid>
- <onc:config configurationDefinition="#{ExistingResourceConfigurationViewUIBean.configurationDefinition}" + <onc:config configurationDefinition="#{ExistingResourceConfigurationUIBean.configurationDefinition}" configuration="#{rawConfigCollection.configuration}" - accessMapActionExpression="#{ExistingResourceConfigurationViewUIBean.accessMap}" + accessMapActionExpression="#{ExistingResourceConfigurationUIBean.accessMap}" readOnly="true" - nullConfigurationDefinitionMessage="#{ExistingResourceConfigurationViewUIBean.nullConfigurationDefinitionMessage}" - nullConfigurationMessage="#{ExistingResourceConfigurationViewUIBean.nullConfigurationMessage}" + nullConfigurationDefinitionMessage="#{ExistingResourceConfigurationUIBean.nullConfigurationDefinitionMessage}" + nullConfigurationMessage="#{ExistingResourceConfigurationUIBean.nullConfigurationMessage}" prevalidate="true"/>
</h:form>
- <h:panelGroup layout="block" styleClass="InfoBlock" rendered="#{ExistingResourceConfigurationViewUIBean.updateInProgress}"> + <h:panelGroup layout="block" styleClass="InfoBlock" rendered="#{ExistingResourceConfigurationUIBean.updateInProgress}"> <b>${msg['note']}</b> ${msg['resource.config.Current.updateInProgress']} </h:panelGroup>
commit 3e59ed2e6e4d45b2f26052b483b47408fa5480d7 Author: John Sanda john@localhost.localdomain Date: Fri Nov 13 21:20:46 2009 -0500
[US 2] Finishing the refactoring (for now) of the classes and tests involved with loading resources.
Removing the boolean argument from the loadResourceConfiguration() method in ConfigurationAgentService which ConfigurationManager implements. The other principle change that has been addressed is to ensure both the loadStructured() and loadRaw() methods are called for a resource that supports both.
diff --git a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/configuration/ConfigurationAgentService.java b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/configuration/ConfigurationAgentService.java index a7ccd13..ecd499b 100644 --- a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/configuration/ConfigurationAgentService.java +++ b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/configuration/ConfigurationAgentService.java @@ -79,8 +79,6 @@ public interface ConfigurationAgentService { */ Configuration loadResourceConfiguration(int resourceId) throws PluginContainerException;
- Configuration loadResourceConfiguration(int resourceId, boolean fromStructured) throws PluginContainerException; - Configuration merge(Configuration configuration, int resourceId, boolean fromStructured) throws PluginContainerException; } \ No newline at end of file diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManager.java index a45f514..ef0584b 100644 --- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManager.java +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManager.java @@ -183,11 +183,11 @@ public class ConfigurationManager extends AgentService implements ContainerServi return configuration; }
- public Configuration loadResourceConfiguration(int resourceId, boolean fromStructured) + public Configuration loadResourceConfiguration(int resourceId) throws PluginContainerException {
LoadResourceConfiguration loadConfig = loadConfigFactory.getStrategy(resourceId); - Configuration configuration = loadConfig.execute(resourceId, fromStructured); + Configuration configuration = loadConfig.execute(resourceId);
if (configuration == null) { ResourceType resourceType = componentService.getResourceType(resourceId); @@ -198,39 +198,39 @@ public class ConfigurationManager extends AgentService implements ContainerServi return configuration; }
- public Configuration loadResourceConfiguration(int resourceId) throws PluginContainerException { - ResourceType resourceType = getResourceType(resourceId); - ConfigurationFacet configComponent = getConfigurationFacet(resourceId, FacetLockType.READ); - try { - Configuration configuration = configComponent.loadResourceConfiguration(); - if (configuration == null) { - throw new PluginContainerException("Plugin Error: Resource Component for [" + resourceType.getName() - + "] Resource with id [" + resourceId + "] returned a null Configuration."); - } - - // If the plugin didn't already set the notes field, set it to something useful. - if (configuration.getNotes() == null) { - configuration.setNotes("Resource config for " + resourceType.getName() + " Resource w/ id " + resourceId); - } - - ConfigurationDefinition configurationDefinition = resourceType.getResourceConfigurationDefinition(); - - // Normalize and validate the config. - ConfigurationUtility.normalizeConfiguration(configuration, configurationDefinition); - List<String> errorMessages = ConfigurationUtility.validateConfiguration(configuration, - configurationDefinition); - for (String errorMessage : errorMessages) { - log.warn("Plugin Error: Invalid " + resourceType.getName() + " Resource configuration returned by " - + resourceType.getPlugin() + " plugin - " + errorMessage); - } - - return configuration; - } catch (Throwable t) { - //noinspection ThrowableInstanceNeverThrown - throw new PluginContainerException("Cannot load Resource configuration for [" + resourceId + "]", - new WrappedRemotingException(t)); - } - } +// public Configuration loadResourceConfiguration(int resourceId) throws PluginContainerException { +// ResourceType resourceType = getResourceType(resourceId); +// ConfigurationFacet configComponent = getConfigurationFacet(resourceId, FacetLockType.READ); +// try { +// Configuration configuration = configComponent.loadResourceConfiguration(); +// if (configuration == null) { +// throw new PluginContainerException("Plugin Error: Resource Component for [" + resourceType.getName() +// + "] Resource with id [" + resourceId + "] returned a null Configuration."); +// } +// +// // If the plugin didn't already set the notes field, set it to something useful. +// if (configuration.getNotes() == null) { +// configuration.setNotes("Resource config for " + resourceType.getName() + " Resource w/ id " + resourceId); +// } +// +// ConfigurationDefinition configurationDefinition = resourceType.getResourceConfigurationDefinition(); +// +// // Normalize and validate the config. +// ConfigurationUtility.normalizeConfiguration(configuration, configurationDefinition); +// List<String> errorMessages = ConfigurationUtility.validateConfiguration(configuration, +// configurationDefinition); +// for (String errorMessage : errorMessages) { +// log.warn("Plugin Error: Invalid " + resourceType.getName() + " Resource configuration returned by " +// + resourceType.getPlugin() + " plugin - " + errorMessage); +// } +// +// return configuration; +// } catch (Throwable t) { +// //noinspection ThrowableInstanceNeverThrown +// throw new PluginContainerException("Cannot load Resource configuration for [" + resourceId + "]", +// new WrappedRemotingException(t)); +// } +// }
/** * Returns a thread pool that this object will use when asychronously executing configuration operations on a diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LegacyLoadConfig.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LegacyLoadConfig.java index 23818c1..b987ddf 100644 --- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LegacyLoadConfig.java +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LegacyLoadConfig.java @@ -39,7 +39,7 @@ public class LegacyLoadConfig extends BaseLoadConfig {
private static final Log log = LogFactory.getLog(LegacyLoadConfig.class);
- public Configuration execute(int resourceId, boolean fromStructured) throws PluginContainerException { + public Configuration execute(int resourceId) throws PluginContainerException { Configuration configuration = loadConfigFromFacet(resourceId); ResourceType resourceType = componentService.getResourceType(resourceId);
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadRaw.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadRaw.java index f200036..debfa45 100644 --- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadRaw.java +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadRaw.java @@ -23,22 +23,21 @@
package org.rhq.core.pc.configuration;
+import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.rhq.core.clientapi.agent.PluginContainerException; import org.rhq.core.domain.configuration.Configuration; import org.rhq.core.domain.configuration.RawConfiguration; import org.rhq.core.domain.resource.ResourceType; -import org.rhq.core.clientapi.agent.PluginContainerException; import org.rhq.core.pluginapi.configuration.ResourceConfigurationFacet; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory;
-import java.util.List; import java.util.Set;
public class LoadRaw extends BaseLoadConfig {
private final Log log = LogFactory.getLog(LoadRaw.class);
- public Configuration execute(int resourceId, boolean fromStructured) throws PluginContainerException { + public Configuration execute(int resourceId) throws PluginContainerException { ResourceConfigurationFacet facet = loadResouceConfiguratonFacet(resourceId);
Set<RawConfiguration> rawConfigs = facet.loadRawConfigurations(); diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadResourceConfiguration.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadResourceConfiguration.java index e2e2aa9..60133c7 100644 --- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadResourceConfiguration.java +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadResourceConfiguration.java @@ -39,6 +39,6 @@ public interface LoadResourceConfiguration {
void setConfigurationUtilityService(ConfigurationUtilityService configUtilityService);
- Configuration execute(int resourceId, boolean fromStructured) throws PluginContainerException; + Configuration execute(int resourceId) throws PluginContainerException;
} diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadStructured.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadStructured.java index ecbfb1f..7d29270 100644 --- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadStructured.java +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadStructured.java @@ -36,7 +36,7 @@ public class LoadStructured extends BaseLoadConfig {
private final Log log = LogFactory.getLog(LoadStructured.class);
- public Configuration execute(int resourceId, boolean fromStructured) throws PluginContainerException { + public Configuration execute(int resourceId) throws PluginContainerException { ResourceConfigurationFacet facet = loadResouceConfiguratonFacet(resourceId);
Configuration configuration = facet.loadStructuredConfiguration(); diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadStructuredAndRaw.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadStructuredAndRaw.java index 7371058..c139ae5 100644 --- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadStructuredAndRaw.java +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadStructuredAndRaw.java @@ -40,7 +40,7 @@ public class LoadStructuredAndRaw extends BaseLoadConfig {
private final Log log = LogFactory.getLog(LoadStructuredAndRaw.class);
- public Configuration execute(int resourceId, boolean fromStructured) throws PluginContainerException { + public Configuration execute(int resourceId) throws PluginContainerException { ResourceConfigurationFacet facet = loadResouceConfiguratonFacet(resourceId);
Configuration configuration = facet.loadStructuredConfiguration(); diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigurationManagerUnitTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigurationManagerUnitTest.java index 87988fb..902f163 100644 --- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigurationManagerUnitTest.java +++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigurationManagerUnitTest.java @@ -26,6 +26,7 @@ package org.rhq.core.pc.configuration; import static org.testng.Assert.*;
import org.jmock.Expectations; +import org.jmock.Sequence; import org.rhq.core.clientapi.agent.PluginContainerException; import org.rhq.core.domain.configuration.Configuration; import org.rhq.core.domain.configuration.RawConfiguration; @@ -33,6 +34,7 @@ import org.rhq.core.domain.resource.ResourceType; import org.rhq.core.pc.util.ComponentService; import org.rhq.core.pc.util.FacetLockType; import org.rhq.core.pluginapi.configuration.ResourceConfigurationFacet; +import org.rhq.core.pluginapi.configuration.ConfigurationFacet; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test;
@@ -44,9 +46,9 @@ public class ConfigurationManagerUnitTest extends JMockTest {
static final String NON_LEGACY_AMPS_VERSION = "2.1";
- static final boolean FROM_STRUCTURED = true; + boolean FROM_STRUCTURED = true;
- static final boolean FROM_RAW = false; + boolean FROM_RAW = false;
int resourceId = -1;
@@ -82,10 +84,10 @@ public class ConfigurationManagerUnitTest extends JMockTest { context.checking(new Expectations() {{ atLeast(1).of(loadConfigFactory).getStrategy(resourceId); will(returnValue(loadConfig));
- allowing(loadConfig).execute(resourceId, FROM_STRUCTURED); will(returnValue(new Configuration())); + allowing(loadConfig).execute(resourceId); will(returnValue(new Configuration())); }});
- configurationMgr.loadResourceConfiguration(resourceId, true); + configurationMgr.loadResourceConfiguration(resourceId); }
@Test @@ -97,11 +99,11 @@ public class ConfigurationManagerUnitTest extends JMockTest { context.checking(new Expectations() {{ allowing(loadConfigFactory).getStrategy(resourceId); will(returnValue(loadConfig));
- atLeast(1).of(loadConfig).execute(resourceId, FROM_STRUCTURED); + atLeast(1).of(loadConfig).execute(resourceId); will(returnValue(expectedConfig)); }});
- Configuration actualConfig = configurationMgr.loadResourceConfiguration(resourceId, FROM_STRUCTURED); + Configuration actualConfig = configurationMgr.loadResourceConfiguration(resourceId);
assertSame(actualConfig, expectedConfig, "Expected the configuration from the loadConfig object to be returned."); } @@ -113,12 +115,12 @@ public class ConfigurationManagerUnitTest extends JMockTest { context.checking(new Expectations() {{ allowing(loadConfigFactory).getStrategy(resourceId); will(returnValue(loadConfig));
- allowing(loadConfig).execute(resourceId, FROM_STRUCTURED); will(returnValue(null)); + allowing(loadConfig).execute(resourceId); will(returnValue(null));
allowing(componentService).getResourceType(resourceId); will(returnValue(new ResourceType())); }});
- configurationMgr.loadResourceConfiguration(resourceId, FROM_STRUCTURED); + configurationMgr.loadResourceConfiguration(resourceId); }
@Test @@ -134,6 +136,8 @@ public class ConfigurationManagerUnitTest extends JMockTest {
final ResourceConfigurationFacet facet = context.mock(ResourceConfigurationFacet.class);
+ final Sequence sequence = context.sequence("merge"); + context.checking(new Expectations(){{ atLeast(1).of(componentService).getComponent(resourceId, ResourceConfigurationFacet.class, @@ -143,6 +147,8 @@ public class ConfigurationManagerUnitTest extends JMockTest { onlyIfStarted); will(returnValue(facet));
+// atLeast(1).of(facet).load + oneOf(facet).mergeRawConfiguration(configuration, rawConfig1); oneOf(facet).mergeRawConfiguration(configuration, rawConfig2); oneOf(facet).mergeRawConfiguration(configuration, rawConfig3); @@ -185,6 +191,17 @@ public class ConfigurationManagerUnitTest extends JMockTest { assertNotNull(actualConfig, "Expected a non-null " + Configuration.class.getSimpleName() + " to be returned."); }
+// @Test +// public void theUpdateLegacyConfigCmdShouldBeCalledToUpdateLegacyConfig() throws Exception { +// UpdateLegacyConfig updateLegacyConfig = context.mock(UpdateLegacyConfig.class); +// +// context.checking(new Expectations() {{ +// allowing(componentService).getAmpsVersion(resourceId); will(returnValue(LEGACY_AMPS_VERSION)); +// +// //oneOf() +// }}); +// } + RawConfiguration createRawConfiguration(String path) { RawConfiguration rawConfig = new RawConfiguration(); rawConfig.setContents(randomBytes()); diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadConfigTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadConfigTest.java index 7c25352..13e90e5 100644 --- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadConfigTest.java +++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadConfigTest.java @@ -23,17 +23,16 @@
package org.rhq.core.pc.configuration;
-import static org.testng.Assert.*; - -import org.rhq.core.domain.configuration.RawConfiguration; import org.rhq.core.domain.configuration.Configuration; import org.rhq.core.domain.configuration.PropertySimple; +import org.rhq.core.domain.configuration.RawConfiguration; import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; import org.rhq.core.domain.resource.ResourceType; +import static org.testng.Assert.assertEquals;
-import java.util.Set; import java.util.HashSet; import java.util.Random; +import java.util.Set;
public class LoadConfigTest extends JMockTest {
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadRawTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadRawTest.java index 1976fcf..dd2429f 100644 --- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadRawTest.java +++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadRawTest.java @@ -23,20 +23,17 @@
package org.rhq.core.pc.configuration;
-import static org.testng.Assert.*; -import static java.util.Collections.EMPTY_SET; - +import org.jmock.Expectations; +import org.rhq.core.domain.configuration.Configuration; +import org.rhq.core.domain.configuration.RawConfiguration; import org.rhq.core.pc.util.ComponentService; import org.rhq.core.pc.util.FacetLockType; import org.rhq.core.pluginapi.configuration.ResourceConfigurationFacet; -import org.rhq.core.domain.configuration.Configuration; -import org.rhq.core.domain.configuration.RawConfiguration; -import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; -import org.rhq.core.domain.resource.ResourceType; +import static org.testng.Assert.assertNull; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; -import org.jmock.Expectations;
+import static java.util.Collections.EMPTY_SET; import java.util.Set;
public class LoadRawTest extends LoadConfigTest { @@ -70,7 +67,7 @@ public class LoadRawTest extends LoadConfigTest {
addDefaultExpectations(rawConfigs);
- Configuration loadedConfig = loadRaw.execute(resourceId, false); + Configuration loadedConfig = loadRaw.execute(resourceId);
assertRawsLoaded(rawConfigs, loadedConfig); } @@ -82,7 +79,7 @@ public class LoadRawTest extends LoadConfigTest {
addDefaultExpectations(EMPTY_SET);
- Configuration loadedConfig = loadRaw.execute(resourceId, false); + Configuration loadedConfig = loadRaw.execute(resourceId);
assertNotesSetToDefault(loadedConfig); } @@ -93,7 +90,7 @@ public class LoadRawTest extends LoadConfigTest {
addDefaultExpectations(rawConfigs);
- Configuration loadedConfig = loadRaw.execute(resourceId, false); + Configuration loadedConfig = loadRaw.execute(resourceId);
assertNull(loadedConfig, "Expected null to be returned when facet returns null for raw."); } diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadStructuredAndRawTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadStructuredAndRawTest.java index 5b5068b..1374dec 100644 --- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadStructuredAndRawTest.java +++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadStructuredAndRawTest.java @@ -45,10 +45,6 @@ import java.util.HashSet;
public class LoadStructuredAndRawTest extends LoadConfigTest {
- static final boolean FROM_STRUCTURED = true; - - static final boolean FROM_RAW = false; - ComponentService componentService;
ConfigurationUtilityService configUtilityService; @@ -73,7 +69,7 @@ public class LoadStructuredAndRawTest extends LoadConfigTest { }
@Test - public void rawSConfigshouldGetLoaded() throws Exception { + public void rawConfigshouldGetLoaded() throws Exception { Configuration config = new Configuration();
Set<RawConfiguration> rawConfigs = toSet( @@ -84,7 +80,7 @@ public class LoadStructuredAndRawTest extends LoadConfigTest {
addDefaultExpectations(config, rawConfigs);
- Configuration loadedConfig = loadStructuredAndRaw.execute(resourceId, FROM_STRUCTURED); + Configuration loadedConfig = loadStructuredAndRaw.execute(resourceId);
assertRawsLoaded(rawConfigs, loadedConfig); } @@ -97,7 +93,7 @@ public class LoadStructuredAndRawTest extends LoadConfigTest {
addDefaultExpectations(config, EMPTY_SET);
- Configuration loadedConfig = loadStructuredAndRaw.execute(resourceId, FROM_STRUCTURED); + Configuration loadedConfig = loadStructuredAndRaw.execute(resourceId);
assertStructuredLoaded(config, loadedConfig); } @@ -109,7 +105,7 @@ public class LoadStructuredAndRawTest extends LoadConfigTest {
addDefaultExpectations(config, EMPTY_SET);
- Configuration loadedConfig = loadStructuredAndRaw.execute(resourceId, FROM_STRUCTURED); + Configuration loadedConfig = loadStructuredAndRaw.execute(resourceId);
assertNotesSetToDefault(loadedConfig); } @@ -122,7 +118,7 @@ public class LoadStructuredAndRawTest extends LoadConfigTest {
addDefaultExpectations(config, rawConfigs);
- Configuration loadedConfig = loadStructuredAndRaw.execute(resourceId, FROM_STRUCTURED); + Configuration loadedConfig = loadStructuredAndRaw.execute(resourceId);
Configuration emptyStructured = new Configuration();
@@ -140,7 +136,7 @@ public class LoadStructuredAndRawTest extends LoadConfigTest {
addDefaultExpectations(config, rawConfigs);
- Configuration loadedConfig = loadStructuredAndRaw.execute(resourceId, FROM_STRUCTURED); + Configuration loadedConfig = loadStructuredAndRaw.execute(resourceId);
assertRawsLoaded(EMPTY_SET, loadedConfig); assertStructuredLoaded(config, loadedConfig); @@ -164,7 +160,7 @@ public class LoadStructuredAndRawTest extends LoadConfigTest { oneOf(configFacet).loadRawConfigurations(); will(returnValue(null)); }});
- Configuration loadedConfig = loadStructuredAndRaw.execute(resourceId, FROM_STRUCTURED); + Configuration loadedConfig = loadStructuredAndRaw.execute(resourceId);
assertNull(loadedConfig, "Expected null to be returned when facet returns null for both structured and raw."); } diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadStructuredTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadStructuredTest.java index e3e8148..47d4f12 100644 --- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadStructuredTest.java +++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadStructuredTest.java @@ -23,19 +23,17 @@
package org.rhq.core.pc.configuration;
-import static org.testng.Assert.*; - +import org.jmock.Expectations; +import org.rhq.core.domain.configuration.Configuration; +import org.rhq.core.domain.configuration.PropertySimple; import org.rhq.core.pc.util.ComponentService; import org.rhq.core.pc.util.FacetLockType; import org.rhq.core.pluginapi.configuration.ResourceConfigurationFacet; -import org.rhq.core.domain.configuration.Configuration; -import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; -import org.rhq.core.domain.resource.ResourceType; +import static org.testng.Assert.assertNull; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; -import org.jmock.Expectations;
-public class LoadStructuredTest extends JMockTest { +public class LoadStructuredTest extends LoadConfigTest {
ComponentService componentService;
@@ -43,12 +41,6 @@ public class LoadStructuredTest extends JMockTest {
ResourceConfigurationFacet configFacet;
- int resourceId = -1; - - boolean daemonThread = true; - - boolean onlyIfStarted = true; - LoadStructured loadStructured;
@BeforeMethod @@ -64,158 +56,71 @@ public class LoadStructuredTest extends JMockTest { }
@Test - public void theResourceConfigFacetShouldGetLoaded() throws Exception { - context.checking(new Expectations() {{ - atLeast(1).of(componentService).getComponent(resourceId, - ResourceConfigurationFacet.class, - FacetLockType.READ, - LoadResourceConfiguration.FACET_METHOD_TIMEOUT, - daemonThread, - onlyIfStarted); - will(returnValue(configFacet)); - - ignoring(configFacet); - ignoring(configUtilityService); - }}); - - loadStructured.execute(resourceId, true); - } - - @Test - public void theConfigShouldGetLoadedByTheFacet() throws Exception { - context.checking(new Expectations() {{ - allowing(componentService).getComponent(resourceId, - ResourceConfigurationFacet.class, - FacetLockType.READ, - LoadResourceConfiguration.FACET_METHOD_TIMEOUT, - daemonThread, - onlyIfStarted); - will(returnValue(configFacet)); + public void structuredConfigShouldGetLoaded() throws Exception { + Configuration config = new Configuration(); + config.put(new PropertySimple("x", "1")); + config.put(new PropertySimple("y", "2"));
- atLeast(1).of(configFacet).loadStructuredConfiguration(); + addDefaultExpectations(config);
- ignoring(configUtilityService); - }}); + Configuration loadedConfig = loadStructured.execute(resourceId);
- loadStructured.execute(resourceId, true); + assertStructuredLoaded(config, loadedConfig); }
@Test - public void theConfigNotesShouldGetSetIfItIsNotAlreadySet() throws Exception { - final Configuration configuration = new Configuration(); - - final ResourceType resourceType = new ResourceType(); - resourceType.setName("test resource"); - - context.checking(new Expectations() {{ - allowing(componentService).getComponent(resourceId, - ResourceConfigurationFacet.class, - FacetLockType.READ, - LoadResourceConfiguration.FACET_METHOD_TIMEOUT, - daemonThread, - onlyIfStarted); - will(returnValue(configFacet)); - - allowing(componentService).getResourceType(resourceId); will(returnValue(resourceType)); - - allowing(configFacet).loadStructuredConfiguration(); will(returnValue(configuration)); - - ignoring(configUtilityService); - }}); + public void theConfigNotesShouldGetSet() throws Exception { + final Configuration config = new Configuration(); + config.setNotes(null);
- Configuration loadedConfig = loadStructured.execute(resourceId, true); + addDefaultExpectations(config);
- String expectedNotes = "Resource config for " + resourceType.getName() + " Resource w/ id " + resourceId; + Configuration loadedConfig = loadStructured.execute(resourceId);
- assertEquals(loadedConfig.getNotes(), expectedNotes, "The notes property should be set to a default when it is not already initialized."); + assertNotesSetToDefault(loadedConfig); }
@Test - public void theConfigShouldGetNormalized() throws Exception { - final Configuration configuration = new Configuration(); - - final ResourceType resourceType = new ResourceType(); - resourceType.setResourceConfigurationDefinition(new ConfigurationDefinition("", "")); + public void nullShouldBeReturnedWhenStructuredIsNull() throws Exception { + final Configuration config = null;
context.checking(new Expectations() {{ - allowing(componentService).getComponent(resourceId, - ResourceConfigurationFacet.class, - FacetLockType.READ, - LoadResourceConfiguration.FACET_METHOD_TIMEOUT, - daemonThread, - onlyIfStarted); + atLeast(1).of(componentService).getComponent(resourceId, + ResourceConfigurationFacet.class, + FacetLockType.READ, + LoadResourceConfiguration.FACET_METHOD_TIMEOUT, + daemonThread, + onlyIfStarted); will(returnValue(configFacet));
allowing(componentService).getResourceType(resourceId); will(returnValue(resourceType));
- allowing(configFacet).loadStructuredConfiguration(); will(returnValue(configuration)); - - atLeast(1).of(configUtilityService).normalizeConfiguration(configuration, resourceType.getResourceConfigurationDefinition()); - - allowing(configUtilityService).validateConfiguration(configuration, resourceType.getResourceConfigurationDefinition()); + atLeast(1).of(configFacet).loadStructuredConfiguration(); will(returnValue(null)); }});
- loadStructured.execute(resourceId, true); - } - - @Test - public void theConfigShouldGetValidated() throws Exception { - final Configuration configuration = new Configuration(); - - final ResourceType resourceType = new ResourceType(); - resourceType.setResourceConfigurationDefinition(new ConfigurationDefinition("", "")); - - context.checking(new Expectations() {{ - allowing(componentService).getComponent(resourceId, - ResourceConfigurationFacet.class, - FacetLockType.READ, - LoadResourceConfiguration.FACET_METHOD_TIMEOUT, - daemonThread, - onlyIfStarted); - will(returnValue(configFacet)); - - allowing(componentService).getResourceType(resourceId); will(returnValue(resourceType)); - - allowing(configFacet).loadStructuredConfiguration(); will(returnValue(configuration)); - - allowing(configUtilityService).normalizeConfiguration(configuration, resourceType.getResourceConfigurationDefinition()); - - atLeast(1).of(configUtilityService).validateConfiguration(configuration, resourceType.getResourceConfigurationDefinition()); - }}); + Configuration loadedConfig = loadStructured.execute(resourceId);
- loadStructured.execute(resourceId, true); + assertNull(loadedConfig, "Expected null to be returned when facet returns null for structured."); }
- @Test - public void theConfigReceivedFromTheFacetShouldBeReturned() throws Exception { - final Configuration configuration = new Configuration(); - - final ResourceType resourceType = new ResourceType(); - resourceType.setResourceConfigurationDefinition(new ConfigurationDefinition("", "")); - + private void addDefaultExpectations(final Configuration config) throws Exception { context.checking(new Expectations() {{ - allowing(componentService).getComponent(resourceId, - ResourceConfigurationFacet.class, - FacetLockType.READ, - LoadResourceConfiguration.FACET_METHOD_TIMEOUT, - daemonThread, - onlyIfStarted); + atLeast(1).of(componentService).getComponent(resourceId, + ResourceConfigurationFacet.class, + FacetLockType.READ, + LoadResourceConfiguration.FACET_METHOD_TIMEOUT, + daemonThread, + onlyIfStarted); will(returnValue(configFacet));
allowing(componentService).getResourceType(resourceId); will(returnValue(resourceType));
- allowing(configFacet).loadStructuredConfiguration(); will(returnValue(configuration)); - - ignoring(configUtilityService); - }}); + atLeast(1).of(configFacet).loadStructuredConfiguration(); will(returnValue(config));
- Configuration loadedConfig = loadStructured.execute(resourceId, true); + atLeast(1).of(configUtilityService).normalizeConfiguration(config, getResourceConfigDefinition());
- assertSame( - loadedConfig, - configuration, - "The loadRawConfig should return the configuration it receives from the facet component." - ); + atLeast(1).of(configUtilityService).validateConfiguration(config, getResourceConfigDefinition()); + }}); }
} diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java index 8232256..36f35c0 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java @@ -1337,8 +1337,7 @@ public class ConfigurationManagerBean implements ConfigurationManagerLocal, Conf agentPingedSuccessfully = agentClient.ping(5000L);
if (!pingAgentFirst || agentPingedSuccessfully) { - liveConfig = agentClient.getConfigurationAgentService().loadResourceConfiguration(resource.getId(), - fromStructured); + liveConfig = agentClient.getConfigurationAgentService().loadResourceConfiguration(resource.getId()); if (liveConfig == null) { // This should really never occur - the PC should never return a null, always at least an empty config. log.debug("ConfigurationAgentService.loadResourceConfiguration() returned a null Configuration.");
commit 169af151bf6916357b34b4fe7f58d9df097ee75d Author: John Sanda john@localhost.localdomain Date: Fri Nov 13 17:15:10 2009 -0500
[US 2] Refactor LoadRaw and LoadRawTest
Introducing a base test class, LoadConfigTest which holds custom asserts and other helper methods that are shared across the various load config test classes.
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadRaw.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadRaw.java index 14fe458..f200036 100644 --- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadRaw.java +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadRaw.java @@ -24,6 +24,7 @@ package org.rhq.core.pc.configuration;
import org.rhq.core.domain.configuration.Configuration; +import org.rhq.core.domain.configuration.RawConfiguration; import org.rhq.core.domain.resource.ResourceType; import org.rhq.core.clientapi.agent.PluginContainerException; import org.rhq.core.pluginapi.configuration.ResourceConfigurationFacet; @@ -31,6 +32,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory;
import java.util.List; +import java.util.Set;
public class LoadRaw extends BaseLoadConfig {
@@ -39,32 +41,23 @@ public class LoadRaw extends BaseLoadConfig { public Configuration execute(int resourceId, boolean fromStructured) throws PluginContainerException { ResourceConfigurationFacet facet = loadResouceConfiguratonFacet(resourceId);
- Configuration configuration = facet.loadRawConfigurations(); + Set<RawConfiguration> rawConfigs = facet.loadRawConfigurations();
- if (configuration == null) { + if (rawConfigs == null) { return null; }
- ResourceType resourceType = componentService.getResourceType(resourceId); - - if (configuration.getNotes() == null) { - configuration.setNotes("Resource config for " + resourceType.getName() + " Resource w/ id " + resourceId); + Configuration config = new Configuration(); + for (RawConfiguration rawConfig : rawConfigs) { + config.addRawConfiguration(rawConfig); }
- configUtilityService.normalizeConfiguration(configuration, resourceType.getResourceConfigurationDefinition()); - List<String> errorMsgs = configUtilityService.validateConfiguration(configuration, - resourceType.getResourceConfigurationDefinition()); - - logErrorMsgs(errorMsgs, resourceType); - - return configuration; - } + if (config.getNotes() == null) { + ResourceType resourceType = componentService.getResourceType(resourceId); + config.setNotes("Resource config for " + resourceType.getName() + " Resource w/ id " + resourceId); + }
- private void logErrorMsgs(List<String> errorMsgs, ResourceType resourceType) { - for (String errorMessage : errorMsgs) { - log.warn("Plugin Error: Invalid " + resourceType.getName() + " Resource configuration returned by " - + resourceType.getPlugin() + " plugin - " + errorMessage); - } + return config; }
} diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadConfigTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadConfigTest.java new file mode 100644 index 0000000..7c25352 --- /dev/null +++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadConfigTest.java @@ -0,0 +1,106 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2008 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, version 2, as + * published by the Free Software Foundation, and/or the GNU Lesser + * General Public License, version 2.1, also as published by the Free + * Software Foundation. + * + * 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 and the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * and the GNU Lesser 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.core.pc.configuration; + +import static org.testng.Assert.*; + +import org.rhq.core.domain.configuration.RawConfiguration; +import org.rhq.core.domain.configuration.Configuration; +import org.rhq.core.domain.configuration.PropertySimple; +import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; +import org.rhq.core.domain.resource.ResourceType; + +import java.util.Set; +import java.util.HashSet; +import java.util.Random; + +public class LoadConfigTest extends JMockTest { + + Random random = new Random(); + + ResourceType resourceType = new ResourceType(); + int resourceId = -1; + boolean daemonThread = true; + boolean onlyIfStarted = true; + + Configuration createStructuredConfig() { + Configuration config = new Configuration(); + config.put(new PropertySimple("x", "1")); + config.put(new PropertySimple("y", "2")); + + return config; + } + + Set<RawConfiguration> toSet(RawConfiguration... rawConfigs) { + Set<RawConfiguration> rawConfigSet = new HashSet<RawConfiguration>(); + for (RawConfiguration rawConfig : rawConfigs) { + rawConfigSet.add(rawConfig); + } + return rawConfigSet; + } + + RawConfiguration createRawConfiguration(String path) { + RawConfiguration rawConfig = new RawConfiguration(); + rawConfig.setContents(randomBytes()); + rawConfig.setPath(path); + + return rawConfig; + } + + byte[] randomBytes() { + byte[] bytes = new byte[10]; + random.nextBytes(bytes); + + return bytes; + } + + ConfigurationDefinition getResourceConfigDefinition() { + if (resourceType.getResourceConfigurationDefinition() == null) { + resourceType.setResourceConfigurationDefinition(new ConfigurationDefinition("", "")); + } + return resourceType.getResourceConfigurationDefinition(); + } + + void assertRawsLoaded(Set<RawConfiguration> expectedRaws, Configuration actualConfig) { + assertEquals( + actualConfig.getRawConfigurations(), + expectedRaws, + "The raw configs were not loaded correctly." + ); + } + + void assertStructuredLoaded(Configuration expectedConfig, Configuration actualConfig) { + assertEquals( + actualConfig.getAllProperties(), + expectedConfig.getAllProperties(), + "The structured configuration was not loaded correctly." + ); + } + + void assertNotesSetToDefault(Configuration loadedConfig) { + String expectedNotes = "Resource config for " + resourceType.getName() + " Resource w/ id " + resourceId; + + assertEquals(loadedConfig.getNotes(), expectedNotes, "The notes property should be set to a default when it is not already initialized."); + } +} diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadRawTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadRawTest.java index 1eeb3a9..1976fcf 100644 --- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadRawTest.java +++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadRawTest.java @@ -24,29 +24,27 @@ package org.rhq.core.pc.configuration;
import static org.testng.Assert.*; +import static java.util.Collections.EMPTY_SET;
import org.rhq.core.pc.util.ComponentService; import org.rhq.core.pc.util.FacetLockType; import org.rhq.core.pluginapi.configuration.ResourceConfigurationFacet; import org.rhq.core.domain.configuration.Configuration; +import org.rhq.core.domain.configuration.RawConfiguration; import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; import org.rhq.core.domain.resource.ResourceType; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; import org.jmock.Expectations;
-public class LoadRawTest extends JMockTest { +import java.util.Set; + +public class LoadRawTest extends LoadConfigTest {
ComponentService componentService;
ConfigurationUtilityService configUtilityService;
- int resourceId = -1; - - boolean daemonThread = true; - - boolean onlyIfStarted = true; - ResourceConfigurationFacet configFacet;
LoadRaw loadRaw; @@ -64,158 +62,58 @@ public class LoadRawTest extends JMockTest { }
@Test - public void theResourceConfigFacetShouldGetLoaded() throws Exception { - context.checking(new Expectations() {{ - atLeast(1).of(componentService).getComponent(resourceId, - ResourceConfigurationFacet.class, - FacetLockType.READ, - LoadResourceConfiguration.FACET_METHOD_TIMEOUT, - daemonThread, - onlyIfStarted); - will(returnValue(configFacet)); - - ignoring(configFacet); - ignoring(configUtilityService); - }}); - - loadRaw.execute(resourceId, false); - } - - @Test - public void theConfigShouldGetLoadedByTheFacet() throws Exception { - context.checking(new Expectations() {{ - allowing(componentService).getComponent(resourceId, - ResourceConfigurationFacet.class, - FacetLockType.READ, - LoadResourceConfiguration.FACET_METHOD_TIMEOUT, - daemonThread, - onlyIfStarted); - will(returnValue(configFacet)); + public void rawConfigsShouldGetLoaded() throws Exception { + Set<RawConfiguration> rawConfigs = toSet( + createRawConfiguration("/tmp/foo.txt"), + createRawConfiguration("/tmp/bar.txt") + );
- atLeast(1).of(configFacet).loadRawConfigurations(); + addDefaultExpectations(rawConfigs);
- ignoring(configUtilityService); - }}); + Configuration loadedConfig = loadRaw.execute(resourceId, false);
- loadRaw.execute(resourceId, false); + assertRawsLoaded(rawConfigs, loadedConfig); }
@Test - public void theConfigNotesShouldGetSetIfItIsNotAlreadySet() throws Exception { - final Configuration configuration = new Configuration(); + public void theConfigNotesShouldGetSet() throws Exception { + final Configuration config = new Configuration(); + config.setNotes(null);
- final ResourceType resourceType = new ResourceType(); - resourceType.setName("test resource"); - - context.checking(new Expectations() {{ - allowing(componentService).getComponent(resourceId, - ResourceConfigurationFacet.class, - FacetLockType.READ, - LoadResourceConfiguration.FACET_METHOD_TIMEOUT, - daemonThread, - onlyIfStarted); - will(returnValue(configFacet)); - - allowing(componentService).getResourceType(resourceId); will(returnValue(resourceType)); - - allowing(configFacet).loadRawConfigurations(); will(returnValue(configuration)); - - ignoring(configUtilityService); - }}); + addDefaultExpectations(EMPTY_SET);
Configuration loadedConfig = loadRaw.execute(resourceId, false);
- String expectedNotes = "Resource config for " + resourceType.getName() + " Resource w/ id " + resourceId; - - assertEquals(loadedConfig.getNotes(), expectedNotes, "The notes property should be set to a default when it is not already initialized."); + assertNotesSetToDefault(loadedConfig); }
@Test - public void theConfigShouldGetNormalized() throws Exception { - final Configuration configuration = new Configuration(); - - final ResourceType resourceType = new ResourceType(); - resourceType.setResourceConfigurationDefinition(new ConfigurationDefinition("", "")); + public void nullShouldBeReturnedWhenRawIsNull() throws Exception { + Set<RawConfiguration> rawConfigs = null; + + addDefaultExpectations(rawConfigs);
- context.checking(new Expectations() {{ - allowing(componentService).getComponent(resourceId, - ResourceConfigurationFacet.class, - FacetLockType.READ, - LoadResourceConfiguration.FACET_METHOD_TIMEOUT, - daemonThread, - onlyIfStarted); - will(returnValue(configFacet)); - - allowing(componentService).getResourceType(resourceId); will(returnValue(resourceType)); - - allowing(configFacet).loadRawConfigurations(); will(returnValue(configuration)); - - atLeast(1).of(configUtilityService).normalizeConfiguration(configuration, resourceType.getResourceConfigurationDefinition()); - - allowing(configUtilityService).validateConfiguration(configuration, resourceType.getResourceConfigurationDefinition()); - }}); + Configuration loadedConfig = loadRaw.execute(resourceId, false);
- loadRaw.execute(resourceId, false); + assertNull(loadedConfig, "Expected null to be returned when facet returns null for raw."); }
- @Test - public void theConfigShouldGetValidated() throws Exception { - final Configuration configuration = new Configuration(); - - final ResourceType resourceType = new ResourceType(); - resourceType.setResourceConfigurationDefinition(new ConfigurationDefinition("", "")); + private void addDefaultExpectations(final Set<RawConfiguration> rawConfigs) + throws Exception {
context.checking(new Expectations() {{ - allowing(componentService).getComponent(resourceId, - ResourceConfigurationFacet.class, - FacetLockType.READ, - LoadResourceConfiguration.FACET_METHOD_TIMEOUT, - daemonThread, - onlyIfStarted); + atLeast(1).of(componentService).getComponent(resourceId, + ResourceConfigurationFacet.class, + FacetLockType.READ, + LoadResourceConfiguration.FACET_METHOD_TIMEOUT, + daemonThread, + onlyIfStarted); will(returnValue(configFacet));
- allowing(componentService).getResourceType(resourceId); will(returnValue(resourceType)); - - allowing(configFacet).loadRawConfigurations(); will(returnValue(configuration)); - - allowing(configUtilityService).normalizeConfiguration(configuration, resourceType.getResourceConfigurationDefinition()); - - atLeast(1).of(configUtilityService).validateConfiguration(configuration, resourceType.getResourceConfigurationDefinition()); - }}); - - loadRaw.execute(resourceId, false); - } - - @Test - public void theStrategyShouldReturnTheConfig() throws Exception { - final Configuration configuration = new Configuration(); - - final ResourceType resourceType = new ResourceType(); - resourceType.setResourceConfigurationDefinition(new ConfigurationDefinition("", "")); - - context.checking(new Expectations() {{ - allowing(componentService).getComponent(resourceId, - ResourceConfigurationFacet.class, - FacetLockType.READ, - LoadResourceConfiguration.FACET_METHOD_TIMEOUT, - daemonThread, - onlyIfStarted); - will(returnValue(configFacet)); + atLeast(1).of(configFacet).loadRawConfigurations(); will(returnValue(rawConfigs));
allowing(componentService).getResourceType(resourceId); will(returnValue(resourceType)); - - allowing(configFacet).loadRawConfigurations(); will(returnValue(configuration)); - - ignoring(configUtilityService); }}); - - Configuration loadedConfig = loadRaw.execute(resourceId, false); - - assertSame( - loadedConfig, - configuration, - "The loadRaw commnand should return the configuration it receives from the facet component." - ); }
} diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadStructuredAndRawTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadStructuredAndRawTest.java index c76c37c..5b5068b 100644 --- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadStructuredAndRawTest.java +++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadStructuredAndRawTest.java @@ -43,7 +43,7 @@ import java.util.Random; import java.util.Set; import java.util.HashSet;
-public class LoadStructuredAndRawTest extends JMockTest { +public class LoadStructuredAndRawTest extends LoadConfigTest {
static final boolean FROM_STRUCTURED = true;
@@ -55,18 +55,8 @@ public class LoadStructuredAndRawTest extends JMockTest {
ResourceConfigurationFacet configFacet;
- int resourceId = -1; - - ResourceType resourceType; - - boolean daemonThread = true; - - boolean onlyIfStarted = true; - LoadStructuredAndRaw loadStructuredAndRaw;
- Random random = new Random(); - @BeforeMethod public void setup() { resourceType = new ResourceType(); @@ -83,7 +73,7 @@ public class LoadStructuredAndRawTest extends JMockTest { }
@Test - public void rawSConfigshouldBeLoaded() throws Exception { + public void rawSConfigshouldGetLoaded() throws Exception { Configuration config = new Configuration();
Set<RawConfiguration> rawConfigs = toSet( @@ -100,7 +90,7 @@ public class LoadStructuredAndRawTest extends JMockTest { }
@Test - public void structuredConfigShouldBeLoaded() throws Exception { + public void structuredConfigShouldGetLoaded() throws Exception { Configuration config = new Configuration(); config.put(new PropertySimple("x", "1")); config.put(new PropertySimple("y", "2")); @@ -121,13 +111,7 @@ public class LoadStructuredAndRawTest extends JMockTest {
Configuration loadedConfig = loadStructuredAndRaw.execute(resourceId, FROM_STRUCTURED);
- String expectedNotes = "Resource config for " + resourceType.getName() + " Resource w/ id " + resourceId; - - assertEquals( - loadedConfig.getNotes(), - expectedNotes, - "The notes property should be set to a default when it is not already initialized." - ); + assertNotesSetToDefault(loadedConfig); }
@Test @@ -182,7 +166,7 @@ public class LoadStructuredAndRawTest extends JMockTest {
Configuration loadedConfig = loadStructuredAndRaw.execute(resourceId, FROM_STRUCTURED);
- assertNull(loadedConfig, "Expected null to be returned when both structured and raw are null"); + assertNull(loadedConfig, "Expected null to be returned when facet returns null for both structured and raw."); }
private void addDefaultExpectations(final Configuration config, final Set<RawConfiguration> rawConfigs) @@ -204,58 +188,11 @@ public class LoadStructuredAndRawTest extends JMockTest { oneOf(configFacet).loadRawConfigurations(); will(returnValue(rawConfigs));
atLeast(1).of(configUtilityService).normalizeConfiguration(with(any(Configuration.class)), - with(resourceType.getResourceConfigurationDefinition())); + with(getResourceConfigDefinition()));
atLeast(1).of(configUtilityService).validateConfiguration(with(any(Configuration.class)), - with(resourceType.getResourceConfigurationDefinition())); + with(getResourceConfigDefinition())); }}); }
- void assertRawsLoaded(Set<RawConfiguration> expectedRaws, Configuration actualConfig) { - assertEquals( - actualConfig.getRawConfigurations(), - expectedRaws, - "The raw configs were not loaded correctly." - ); - } - - void assertStructuredLoaded(Configuration expectedConfig, Configuration actualConfig) { - assertEquals( - actualConfig.getAllProperties(), - expectedConfig.getAllProperties(), - "The structured configuration was not loaded correctly." - ); - } - - Configuration createStructuredConfig() { - Configuration config = new Configuration(); - config.put(new PropertySimple("x", "1")); - config.put(new PropertySimple("y", "2")); - - return config; - } - - - Set<RawConfiguration> toSet(RawConfiguration... rawConfigs) { - Set<RawConfiguration> rawConfigSet = new HashSet<RawConfiguration>(); - for (RawConfiguration rawConfig : rawConfigs) { - rawConfigSet.add(rawConfig); - } - return rawConfigSet; - } - - RawConfiguration createRawConfiguration(String path) { - RawConfiguration rawConfig = new RawConfiguration(); - rawConfig.setContents(randomBytes()); - rawConfig.setPath(path); - - return rawConfig; - } - - byte[] randomBytes() { - byte[] bytes = new byte[10]; - random.nextBytes(bytes); - - return bytes; - } }
commit 60063b543a6e06bc227b60469fffead98382479e Author: John Sanda john@localhost.localdomain Date: Fri Nov 13 16:29:15 2009 -0500
[US 2] Fixing signature of loadRawConfigurations() to return Set<RawConfiguration>.
diff --git a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/configuration/ResourceConfigurationFacet.java b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/configuration/ResourceConfigurationFacet.java index 430b353..0c49cfd 100644 --- a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/configuration/ResourceConfigurationFacet.java +++ b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/configuration/ResourceConfigurationFacet.java @@ -32,10 +32,18 @@ public interface ResourceConfigurationFacet {
Configuration loadStructuredConfiguration();
- Configuration loadRawConfigurations(); + Set<RawConfiguration> loadRawConfigurations();
void mergeRawConfiguration(Configuration from, RawConfiguration to);
void mergeStructuredConfiguration(RawConfiguration from, Configuration to);
+ void persistStructuredConfiguration(Configuration configuration); + + void persistRawConfiguration(RawConfiguration rawConfiguration); + + void validateStructuredConfiguration(Configuration configuration); + + void validateRawConfiguration(RawConfiguration rawConfiguration); + }
commit 6c56c7e9c23b279dc5e86f2b82253bb7c8772fbf Author: John Sanda john@localhost.localdomain Date: Fri Nov 13 16:26:29 2009 -0500
[US 2] Refactoring strategy class and tests for loading structured and raw.
I had the API for ResourceConfigurationFacet wrong. loadRawConfigurations() was changed to return a set of the raw configs, and the container needs to call both load methods on the facet. This led to some implementation changes as well as some simplification in the refactoring.
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadStructuredAndRaw.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadStructuredAndRaw.java index de5dd60..7371058 100644 --- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadStructuredAndRaw.java +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadStructuredAndRaw.java @@ -23,6 +23,8 @@
package org.rhq.core.pc.configuration;
+import static java.util.Collections.EMPTY_SET; + import org.rhq.core.domain.configuration.Configuration; import org.rhq.core.domain.configuration.RawConfiguration; import org.rhq.core.domain.resource.ResourceType; @@ -32,6 +34,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory;
import java.util.List; +import java.util.Set;
public class LoadStructuredAndRaw extends BaseLoadConfig {
@@ -40,20 +43,23 @@ public class LoadStructuredAndRaw extends BaseLoadConfig { public Configuration execute(int resourceId, boolean fromStructured) throws PluginContainerException { ResourceConfigurationFacet facet = loadResouceConfiguratonFacet(resourceId);
- Configuration configuration; - if (fromStructured) { - configuration = facet.loadStructuredConfiguration(); - if (configuration == null) { - return null; - } - mergeStructured(configuration, facet); + Configuration configuration = facet.loadStructuredConfiguration(); + Set<RawConfiguration> rawConfigs = facet.loadRawConfigurations(); + + if (configuration == null && rawConfigs == null) { + return null; } - else { - configuration = facet.loadRawConfigurations(); - if (configuration == null) { - return null; - } - mergeRaw(configuration, facet); + + if (configuration == null) { + configuration = new Configuration(); + } + + if (rawConfigs == null) { + rawConfigs = EMPTY_SET; + } + + for (RawConfiguration rawConfig : rawConfigs) { + configuration.addRawConfiguration(rawConfig); }
ResourceType resourceType = componentService.getResourceType(resourceId); @@ -71,18 +77,6 @@ public class LoadStructuredAndRaw extends BaseLoadConfig { return configuration; }
- private void mergeStructured(Configuration configuration, ResourceConfigurationFacet configFacet) { - for (RawConfiguration rawConfig : configuration.getRawConfigurations()) { - configFacet.mergeStructuredConfiguration(rawConfig, configuration); - } - } - - private void mergeRaw(Configuration configuration, ResourceConfigurationFacet configFacet) { - for (RawConfiguration rawConfig : configuration.getRawConfigurations()) { - configFacet.mergeRawConfiguration(configuration, rawConfig); - } - } - private void logErrorMsgs(List<String> errorMsgs, ResourceType resourceType) { for (String errorMessage : errorMsgs) { log.warn("Plugin Error: Invalid " + resourceType.getName() + " Resource configuration returned by " diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadStructuredAndRawTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadStructuredAndRawTest.java index 3821cc1..c76c37c 100644 --- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadStructuredAndRawTest.java +++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadStructuredAndRawTest.java @@ -24,19 +24,24 @@ package org.rhq.core.pc.configuration;
import static org.testng.Assert.*; +import static java.util.Collections.*;
import org.rhq.core.pc.util.ComponentService; import org.rhq.core.pc.util.FacetLockType; import org.rhq.core.pluginapi.configuration.ResourceConfigurationFacet; import org.rhq.core.domain.configuration.Configuration; import org.rhq.core.domain.configuration.RawConfiguration; +import org.rhq.core.domain.configuration.PropertySimple; import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; import org.rhq.core.domain.resource.ResourceType; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; import org.jmock.Expectations; +import org.jmock.Sequence;
import java.util.Random; +import java.util.Set; +import java.util.HashSet;
public class LoadStructuredAndRawTest extends JMockTest {
@@ -52,6 +57,8 @@ public class LoadStructuredAndRawTest extends JMockTest {
int resourceId = -1;
+ ResourceType resourceType; + boolean daemonThread = true;
boolean onlyIfStarted = true; @@ -62,6 +69,9 @@ public class LoadStructuredAndRawTest extends JMockTest {
@BeforeMethod public void setup() { + resourceType = new ResourceType(); + resourceType.setResourceConfigurationDefinition(new ConfigurationDefinition("", "")); + componentService = context.mock(ComponentService.class); configUtilityService = context.mock(ConfigurationUtilityService.class);
@@ -73,175 +83,89 @@ public class LoadStructuredAndRawTest extends JMockTest { }
@Test - public void theResourceConfigFacetShouldGetLoaded() throws Exception { - context.checking(new Expectations() {{ - atLeast(1).of(componentService).getComponent(resourceId, - ResourceConfigurationFacet.class, - FacetLockType.READ, - LoadResourceConfiguration.FACET_METHOD_TIMEOUT, - daemonThread, - onlyIfStarted); - will(returnValue(configFacet)); + public void rawSConfigshouldBeLoaded() throws Exception { + Configuration config = new Configuration();
- allowing(configFacet).loadStructuredConfiguration(); - - ignoring(configUtilityService); - }}); + Set<RawConfiguration> rawConfigs = toSet( + createRawConfiguration("/tmp/foo.txt"), + createRawConfiguration("/tmp/bar.txt") + );
- loadStructuredAndRaw.execute(resourceId, FROM_STRUCTURED); - }
- @Test - public void theStructuredConfigShouldGetLoadedWhenFromStructured() throws Exception { - context.checking(new Expectations() {{ - allowing(componentService).getComponent(resourceId, - ResourceConfigurationFacet.class, - FacetLockType.READ, - LoadResourceConfiguration.FACET_METHOD_TIMEOUT, - daemonThread, - onlyIfStarted); - will(returnValue(configFacet)); - - allowing(configFacet).loadStructuredConfiguration(); + addDefaultExpectations(config, rawConfigs);
- ignoring(configUtilityService); - }}); + Configuration loadedConfig = loadStructuredAndRaw.execute(resourceId, FROM_STRUCTURED);
- loadStructuredAndRaw.execute(resourceId, FROM_STRUCTURED); + assertRawsLoaded(rawConfigs, loadedConfig); }
@Test - public void eachRawConfigShouldBeMergedIntoTheStructuredConfigWhenFromStructured() throws Exception { - final RawConfiguration rawConfig1 = createRawConfiguration("/tmp/foo.txt"); - final RawConfiguration rawConfig2 = createRawConfiguration("/tmp/bar.txt"); - final RawConfiguration rawConfig3 = createRawConfiguration("/tmp/bam.txt"); - - final Configuration configuration = new Configuration(); - configuration.addRawConfiguration(rawConfig1); - configuration.addRawConfiguration(rawConfig2); - configuration.addRawConfiguration(rawConfig3); - - final ResourceType resourceType = new ResourceType(); - - context.checking(new Expectations() {{ - allowing(componentService).getComponent(resourceId, - ResourceConfigurationFacet.class, - FacetLockType.READ, - LoadResourceConfiguration.FACET_METHOD_TIMEOUT, - daemonThread, - onlyIfStarted); - will(returnValue(configFacet)); - - allowing(componentService).getResourceType(resourceId); will(returnValue(resourceType)); + public void structuredConfigShouldBeLoaded() throws Exception { + Configuration config = new Configuration(); + config.put(new PropertySimple("x", "1")); + config.put(new PropertySimple("y", "2"));
- atLeast(1).of(configFacet).loadStructuredConfiguration(); will(returnValue(configuration)); + addDefaultExpectations(config, EMPTY_SET);
- oneOf(configFacet).mergeStructuredConfiguration(rawConfig1, configuration); - oneOf(configFacet).mergeStructuredConfiguration(rawConfig2, configuration); - oneOf(configFacet).mergeStructuredConfiguration(rawConfig3, configuration); - - ignoring(configUtilityService); - }}); + Configuration loadedConfig = loadStructuredAndRaw.execute(resourceId, FROM_STRUCTURED);
- loadStructuredAndRaw.execute(resourceId, FROM_STRUCTURED); + assertStructuredLoaded(config, loadedConfig); }
@Test - public void theRawConfigShouldGetLoadedWhenFromRaw() throws Exception { - context.checking(new Expectations() {{ - allowing(componentService).getComponent(resourceId, - ResourceConfigurationFacet.class, - FacetLockType.READ, - LoadResourceConfiguration.FACET_METHOD_TIMEOUT, - daemonThread, - onlyIfStarted); - will(returnValue(configFacet)); + public void theConfigNotesShouldGetSet() throws Exception { + Configuration config = new Configuration(); + config.setNotes(null);
- allowing(componentService).getResourceType(resourceId); will(returnValue(new ResourceType())); + addDefaultExpectations(config, EMPTY_SET);
- atLeast(1).of(configFacet).loadRawConfigurations(); will(returnValue(new Configuration())); + Configuration loadedConfig = loadStructuredAndRaw.execute(resourceId, FROM_STRUCTURED);
- ignoring(configUtilityService); - }}); + String expectedNotes = "Resource config for " + resourceType.getName() + " Resource w/ id " + resourceId;
- loadStructuredAndRaw.execute(resourceId, FROM_RAW); + assertEquals( + loadedConfig.getNotes(), + expectedNotes, + "The notes property should be set to a default when it is not already initialized." + ); }
@Test - public void theStructuredConfigShouldBeMergedIntoEachRawConfigWhenFromRaw() throws Exception { - final RawConfiguration rawConfig1 = createRawConfiguration("/tmp/foo.txt"); - final RawConfiguration rawConfig2 = createRawConfiguration("/tmp/bar.txt"); - final RawConfiguration rawConfig3 = createRawConfiguration("/tmp/bam.txt"); - - final Configuration configuration = new Configuration(); - configuration.addRawConfiguration(rawConfig1); - configuration.addRawConfiguration(rawConfig2); - configuration.addRawConfiguration(rawConfig3); - - context.checking(new Expectations() {{ - allowing(componentService).getComponent(resourceId, - ResourceConfigurationFacet.class, - FacetLockType.READ, - LoadResourceConfiguration.FACET_METHOD_TIMEOUT, - daemonThread, - onlyIfStarted); - will(returnValue(configFacet)); + public void nullStructuredShouldBeIgnored() throws Exception { + Configuration config = null;
- allowing(componentService).getResourceType(resourceId); will(returnValue(new ResourceType())); + Set<RawConfiguration> rawConfigs = toSet(createRawConfiguration("/tmp/foo.txt"));
- allowing(configFacet).loadRawConfigurations(); will(returnValue(configuration)); + addDefaultExpectations(config, rawConfigs);
- oneOf(configFacet).mergeRawConfiguration(configuration, rawConfig1); - oneOf(configFacet).mergeRawConfiguration(configuration, rawConfig2); - oneOf(configFacet).mergeRawConfiguration(configuration, rawConfig3); + Configuration loadedConfig = loadStructuredAndRaw.execute(resourceId, FROM_STRUCTURED);
- ignoring(configUtilityService); - }}); + Configuration emptyStructured = new Configuration();
- loadStructuredAndRaw.execute(resourceId, FROM_RAW); + assertRawsLoaded(rawConfigs, loadedConfig); + assertStructuredLoaded(emptyStructured, loadedConfig); }
@Test - public void theConfigReceivedFromTheFacetShouldBeReturned() throws Exception { - final Configuration configuration = new Configuration(); + public void nullRawsShouldBeIgnored() throws Exception { + Configuration config = new Configuration(); + config.put(new PropertySimple("x", "1")); + config.put(new PropertySimple("y", "2"));
- final ResourceType resourceType = new ResourceType(); - resourceType.setResourceConfigurationDefinition(new ConfigurationDefinition("", "")); + Set<RawConfiguration> rawConfigs = null;
- context.checking(new Expectations() {{ - allowing(componentService).getComponent(resourceId, - ResourceConfigurationFacet.class, - FacetLockType.READ, - LoadResourceConfiguration.FACET_METHOD_TIMEOUT, - daemonThread, - onlyIfStarted); - will(returnValue(configFacet)); - - allowing(componentService).getResourceType(resourceId); will(returnValue(resourceType)); - - allowing(configFacet).loadStructuredConfiguration(); will(returnValue(configuration)); - - ignoring(configUtilityService); - }}); + addDefaultExpectations(config, rawConfigs);
Configuration loadedConfig = loadStructuredAndRaw.execute(resourceId, FROM_STRUCTURED);
- assertSame( - loadedConfig, - configuration, - "The loadRawConfig should return the configuration it receives from the facet component." - ); + assertRawsLoaded(EMPTY_SET, loadedConfig); + assertStructuredLoaded(config, loadedConfig); }
@Test - public void theConfigNotesShouldGetSetIfItIsNotAlreadySet() throws Exception { - final Configuration configuration = new Configuration(); - - final ResourceType resourceType = new ResourceType(); - resourceType.setName("test resource"); - + public void nullShouldBeReturnedWhenStructuredAndRawAreNull() throws Exception { context.checking(new Expectations() {{ - allowing(componentService).getComponent(resourceId, + atLeast(1).of(componentService).getComponent(resourceId, ResourceConfigurationFacet.class, FacetLockType.READ, LoadResourceConfiguration.FACET_METHOD_TIMEOUT, @@ -251,27 +175,21 @@ public class LoadStructuredAndRawTest extends JMockTest {
allowing(componentService).getResourceType(resourceId); will(returnValue(resourceType));
- allowing(configFacet).loadStructuredConfiguration(); will(returnValue(configuration)); + oneOf(configFacet).loadStructuredConfiguration(); will(returnValue(null));
- ignoring(configUtilityService); + oneOf(configFacet).loadRawConfigurations(); will(returnValue(null)); }});
Configuration loadedConfig = loadStructuredAndRaw.execute(resourceId, FROM_STRUCTURED);
- String expectedNotes = "Resource config for " + resourceType.getName() + " Resource w/ id " + resourceId; - - assertEquals(loadedConfig.getNotes(), expectedNotes, "The notes property should be set to a default when it is not already initialized."); + assertNull(loadedConfig, "Expected null to be returned when both structured and raw are null"); }
- @Test - public void theConfigShouldGetNormalized() throws Exception { - final Configuration configuration = new Configuration(); - - final ResourceType resourceType = new ResourceType(); - resourceType.setResourceConfigurationDefinition(new ConfigurationDefinition("", "")); + private void addDefaultExpectations(final Configuration config, final Set<RawConfiguration> rawConfigs) + throws Exception {
context.checking(new Expectations() {{ - allowing(componentService).getComponent(resourceId, + atLeast(1).of(componentService).getComponent(resourceId, ResourceConfigurationFacet.class, FacetLockType.READ, LoadResourceConfiguration.FACET_METHOD_TIMEOUT, @@ -281,42 +199,49 @@ public class LoadStructuredAndRawTest extends JMockTest {
allowing(componentService).getResourceType(resourceId); will(returnValue(resourceType));
- allowing(configFacet).loadStructuredConfiguration(); will(returnValue(configuration)); + oneOf(configFacet).loadStructuredConfiguration(); will(returnValue(config));
- atLeast(1).of(configUtilityService).normalizeConfiguration(configuration, resourceType.getResourceConfigurationDefinition()); + oneOf(configFacet).loadRawConfigurations(); will(returnValue(rawConfigs));
- allowing(configUtilityService).validateConfiguration(configuration, resourceType.getResourceConfigurationDefinition()); - }}); + atLeast(1).of(configUtilityService).normalizeConfiguration(with(any(Configuration.class)), + with(resourceType.getResourceConfigurationDefinition()));
- loadStructuredAndRaw.execute(resourceId, FROM_STRUCTURED); + atLeast(1).of(configUtilityService).validateConfiguration(with(any(Configuration.class)), + with(resourceType.getResourceConfigurationDefinition())); + }}); }
- @Test - public void theConfigShouldGetValidated() throws Exception { - final Configuration configuration = new Configuration(); - - final ResourceType resourceType = new ResourceType(); - resourceType.setResourceConfigurationDefinition(new ConfigurationDefinition("", "")); - - context.checking(new Expectations() {{ - allowing(componentService).getComponent(resourceId, - ResourceConfigurationFacet.class, - FacetLockType.READ, - LoadResourceConfiguration.FACET_METHOD_TIMEOUT, - daemonThread, - onlyIfStarted); - will(returnValue(configFacet)); + void assertRawsLoaded(Set<RawConfiguration> expectedRaws, Configuration actualConfig) { + assertEquals( + actualConfig.getRawConfigurations(), + expectedRaws, + "The raw configs were not loaded correctly." + ); + }
- allowing(componentService).getResourceType(resourceId); will(returnValue(resourceType)); + void assertStructuredLoaded(Configuration expectedConfig, Configuration actualConfig) { + assertEquals( + actualConfig.getAllProperties(), + expectedConfig.getAllProperties(), + "The structured configuration was not loaded correctly." + ); + }
- allowing(configFacet).loadStructuredConfiguration(); will(returnValue(configuration)); + Configuration createStructuredConfig() { + Configuration config = new Configuration(); + config.put(new PropertySimple("x", "1")); + config.put(new PropertySimple("y", "2"));
- allowing(configUtilityService).normalizeConfiguration(configuration, resourceType.getResourceConfigurationDefinition()); + return config; + }
- atLeast(1).of(configUtilityService).validateConfiguration(configuration, resourceType.getResourceConfigurationDefinition()); - }});
- loadStructuredAndRaw.execute(resourceId, FROM_STRUCTURED); + Set<RawConfiguration> toSet(RawConfiguration... rawConfigs) { + Set<RawConfiguration> rawConfigSet = new HashSet<RawConfiguration>(); + for (RawConfiguration rawConfig : rawConfigs) { + rawConfigSet.add(rawConfig); + } + return rawConfigSet; }
RawConfiguration createRawConfiguration(String path) {
commit 1dec3d88bd71cfad5068ea4d5e4a8bed06e34d5a Author: Simeon Pinder spinder@redhat.com Date: Fri Nov 13 14:49:40 2009 -0500
perspectives dynamic menus changes for MenuUIBean.
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/perspectives/MenuItem.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/perspectives/MenuItem.java new file mode 100644 index 0000000..ee7cffe --- /dev/null +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/perspectives/MenuItem.java @@ -0,0 +1,101 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2008 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.gui.perspectives; + +/** Features for each menu item. + * + * @author Simeon Pinder + * + */ +public class MenuItem { + + //constants:begin Extension point map + public static String menu = "menu"; + public static String menu_BEGIN = "menu.BEGIN"; + public static String logo = "menu.logo"; + + public static String overview_BEFORE = "menu.overview_BEFORE"; + public static String overview = "menu.overview"; + + public static String resources_BEFORE = "menu.resources_BEFORE"; + public static String resources = "menu.resources"; + + //constants:end + + private String iconUrl = ""; + private int iconWidth = 0; + private int iconHeight = 0; + private String url = ""; + private String name = ""; + private boolean rendered = true; + + MenuItem(String iconUrl, String url, String name) { + this.iconUrl = iconUrl; + this.url = url; + this.name = name; + } + + public String getIconUrl() { + return iconUrl; + } + + public void setIconUrl(String iconUrl) { + this.iconUrl = iconUrl; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public boolean isRendered() { + return rendered; + } + + public void setRendered(boolean render) { + this.rendered = render; + } + + public int getIconHeight() { + return iconHeight; + } + + public void setIconHeight(int iconHeight) { + this.iconHeight = iconHeight; + } + + public int getIconWidth() { + return iconWidth; + } + + public void setIconWidth(int iconWidth) { + this.iconWidth = iconWidth; + } +} diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/perspectives/PerspectivesMenuUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/perspectives/PerspectivesMenuUIBean.java new file mode 100644 index 0000000..66560a0 --- /dev/null +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/perspectives/PerspectivesMenuUIBean.java @@ -0,0 +1,488 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2008 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.gui.perspectives; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +/** + * Bean dynamically provides menu information used by menu.xhtml. This bean should be viewed + * concurrently with menu.xhtml and it's designed to provide static or dynamic menu content + * for menu.xhtml. + * + * @author Simeon Pinder + * + */ +public class PerspectivesMenuUIBean { + /* Stores all mapped MenuItem information */ + private HashMap<String, MenuItem> menuDefinition = new HashMap<String, MenuItem>(); + + /*===== LOGO TO HOME PAGE =====*/ + private MenuItem logo = new MenuItem("/images/JBossLogo_small.png", "", ""); + { + logo.setIconHeight(21); + logo.setIconWidth(37); + menuDefinition.put(MenuItem.logo, logo); + } + + /*===== OVERVIEW =====*/ + private MenuItem overview = new MenuItem("", "", "Overview"); + { + menuDefinition.put(MenuItem.overview, overview); + } + /*===== Overview.BEFORE extension pt. ============= */ + private MenuItem overviewBefore = new MenuItem("", "", ""); + { + overviewBefore.setRendered(false);//disable to start + menuDefinition.put(MenuItem.overview_BEFORE, overviewBefore); + } + + private List<MenuItem> overviewBeforeItems = new ArrayList<MenuItem>(); + + /****** Overview > SYSTEM VIEWS ******/ + private MenuItem subsystemViews = new MenuItem("", "", "Subsystem Views"); + private List<MenuItem> subsystemMenuItems = new ArrayList<MenuItem>(); + {//initialization block + //SubsystemView menu items + String[] subsystemCategories = { "Configure", "Monitor_failed", "Operation", "Flag_blue", "Flag_grey" }; + String[] subsystemPages = { "configurationUpdate", "oobHistory", "operationHistory", "alertHistory", + "alertDefinitions" }; + String[] subsystemNames = { "Configuration Changes", "Suspect Metrics", "Operations", "Alerts", + "Alert Definitions" }; + for (int i = 0; i < subsystemPages.length; i++) { + subsystemMenuItems.add(new MenuItem("/images/icons/" + subsystemCategories[i] + "_16.png",//icon url + "/rhq/subsystem/" + subsystemPages[i] + ".xhtml", // menu item url + subsystemNames[i])); //menu item name + } + } + /* ***** Overview > AUTO-DISCOVERY QUEUE ***** */ + private MenuItem autoDiscoveryQueue = new MenuItem("", "/rhq/discovery/queue.xhtml", "Auto Discovery Queue");; + + /* ***** Overview > DASHBOARD ***** */ + private MenuItem dashboard = new MenuItem("", "/Dashboard.do", "Dashboard"); + + /* ===== RESOURCES ===== */ + private MenuItem resources = new MenuItem("", "", "Resources"); + + /* Resources: Platform */ + private MenuItem resourcesPlatform = null; + { + resourcesPlatform = new MenuItem("/images/icons/Platform_up_16.png", + "/ResourceHub.do?resourceCategory=PLATFORM", ""); + } + /* Resources: Server */ + private MenuItem resourcesServer = null; + { + resourcesServer = new MenuItem("/images/icons/Server_up_16.png", "/ResourceHub.do?resourceCategory=SERVER", ""); + } + + /* Resources: Service */ + private MenuItem resourcesService = null; + { + resourcesService = new MenuItem("/images/icons/Service_up_16.png", "/ResourceHub.do?resourceCategory=SERVICE", + ""); + } + + private MenuItem resourcesFavorite = new MenuItem("/images/icons/Favorite_16.png", "", "Favorite Resources"); + private MenuItem resourcesRecentlyViewed = new MenuItem("/images/icons/History_16.png", "", + "Recently Viewed Resources"); + //TODO: enable? + private MenuItem resourcesSearch = new MenuItem("/images/icons/History_16.png", "", "Search: "); + + /* ===== GROUPS ===== */ + private MenuItem groups = new MenuItem("", "", "Groups"); + private MenuItem groupsCompatible = new MenuItem("/images/icons/Cluster_up_16.png", + "/GroupHub.do?groupCategory=COMPATIBLE", ""); + private MenuItem groupsMixed = new MenuItem("/images/icons/Group_up_16.png", "/GroupHub.do?groupCategory=MIXED", ""); + private MenuItem groupsDefinitions = new MenuItem("/images/GroupDefinition_16.png", + "/rhq/definition/group/list.xhtml", ""); + private MenuItem groupsNewResource = new MenuItem("", "/resource/group/Inventory.do?mode=new", ""); + private MenuItem groupsNewDefinition = new MenuItem("", "/rhq/definition/group/new.xhtml", ""); + private MenuItem groupsFavorite = new MenuItem("/images/icons/Favorite_16.png", "", "Favorite Groups"); + private MenuItem groupsRecentlyViewed = new MenuItem("/images/icons/History_16.png", "", "Recently Viewed Groups"); + + /* ===== ADMINISTRATION ===== */ + private MenuItem security = new MenuItem("", "", "Security"); + private MenuItem securityUsers = new MenuItem("", "/admin/user/UserAdmin.do?mode=list", "Users"); + private MenuItem securityRoles = new MenuItem("", "/admin/role/RoleAdmin.do?mode=list", "Roles"); + private MenuItem sysconfig = new MenuItem("", "", "System Configuration"); + private MenuItem sysconfigSettings = new MenuItem("", "/admin/config/Config.do?mode=edit", "Settings"); + private MenuItem sysconfigPlugins = new MenuItem("", "/rhq/admin/plugin/plugin-list.xhtml", "Plugins"); + private MenuItem sysconfigTemplates = new MenuItem("", + "/admin/config/EditDefaults.do?mode=monitor&viewMode=all", "Templates"); + private MenuItem content = new MenuItem("", "", "Content"); + private MenuItem contentContentProviders = new MenuItem("", "/rhq/content/listContentProviders.xhtml", + "Content Providers"); + private MenuItem contentRepositories = new MenuItem("", "/rhq/content/listRepos.xhtml", "Repositories"); + private MenuItem ha = new MenuItem("", "", "High Availability"); + private MenuItem haServers = new MenuItem("", "/rhq/ha/listServers.xhtml", "Servers"); + private MenuItem haAgents = new MenuItem("", "/rhq/ha/listAgents.xhtml", "Agents"); + private MenuItem haAffinityGroups = new MenuItem("", "/rhq/ha/listAffinityGroups.xhtml", "Affinity Groups"); + private MenuItem haPartitionEvents = new MenuItem("", "/rhq/ha/listPartitionEvents.xhtml", "Partition Events"); + private MenuItem reports = new MenuItem("", "", "Reports"); + private MenuItem reportsResourceVersion = new MenuItem("", "/rhq/admin/report/resourceInstallReport.xhtml", + "Resource Version Inventory Report"); + private MenuItem downloads = new MenuItem("/images/icons/Save_16.png", "/rhq/admin/downloads.xhtml", "Downloads"); + private MenuItem license = new MenuItem("", "/admin/license/LicenseAdmin.do?mode=view", "License"); + + public List<MenuItem> getSubsystemMenuItems() { + return subsystemMenuItems; + } + + public void setSubsystemMenuItems(List<MenuItem> subsystemMenuItems) { + this.subsystemMenuItems = subsystemMenuItems; + } + + public MenuItem getAutoDiscoveryQueue() { + return autoDiscoveryQueue; + } + + public void setAutoDiscoveryQueue(MenuItem autoDiscoveryQueue) { + this.autoDiscoveryQueue = autoDiscoveryQueue; + } + + public MenuItem getDashboard() { + return dashboard; + } + + public void setDashboard(MenuItem dashboard) { + this.dashboard = dashboard; + } + + public MenuItem getResourcesPlatform() { + return resourcesPlatform; + } + + public void setResourcesPlatform(MenuItem resourcesPlatform) { + this.resourcesPlatform = resourcesPlatform; + } + + public MenuItem getResourcesServer() { + return resourcesServer; + } + + public void setResourcesServer(MenuItem resourcesServer) { + this.resourcesServer = resourcesServer; + } + + public MenuItem getResourcesService() { + return resourcesService; + } + + public void setResourcesService(MenuItem resourcesService) { + this.resourcesService = resourcesService; + } + + public MenuItem getGroups() { + return groups; + } + + public void setGroups(MenuItem groups) { + this.groups = groups; + } + + public MenuItem getGroupsCompatible() { + return groupsCompatible; + } + + public void setGroupsCompatible(MenuItem groupsCompatible) { + this.groupsCompatible = groupsCompatible; + } + + public MenuItem getGroupsMixed() { + return groupsMixed; + } + + public void setGroupsMixed(MenuItem groupsMixed) { + this.groupsMixed = groupsMixed; + } + + public MenuItem getGroupsDefinitions() { + return groupsDefinitions; + } + + public void setGroupsDefinitions(MenuItem groupsDefinitions) { + this.groupsDefinitions = groupsDefinitions; + } + + public MenuItem getGroupsNewResource() { + return groupsNewResource; + } + + public void setGroupsNewResource(MenuItem groupsNewResource) { + this.groupsNewResource = groupsNewResource; + } + + public MenuItem getGroupsNewDefinition() { + return groupsNewDefinition; + } + + public void setGroupsNewDefinition(MenuItem groupsNewDefinition) { + this.groupsNewDefinition = groupsNewDefinition; + } + + public MenuItem getLogo() { + return logo; + } + + public void setLogo(MenuItem logo) { + this.logo = logo; + } + + public MenuItem getOverview() { + return overview; + } + + public void setOverview(MenuItem overview) { + this.overview = overview; + } + + public MenuItem getSubsystemViews() { + return subsystemViews; + } + + public void setSubsystemViews(MenuItem subsystemViews) { + this.subsystemViews = subsystemViews; + } + + public MenuItem getResources() { + return resources; + } + + public void setResources(MenuItem resources) { + this.resources = resources; + } + + public MenuItem getResourcesFavorite() { + return resourcesFavorite; + } + + public void setResourcesFavorite(MenuItem resourcesFavorite) { + this.resourcesFavorite = resourcesFavorite; + } + + public MenuItem getResourcesRecentlyViewed() { + return resourcesRecentlyViewed; + } + + public void setResourcesRecentlyViewed(MenuItem resourcesRecentlyViewed) { + this.resourcesRecentlyViewed = resourcesRecentlyViewed; + } + + public MenuItem getGroupsFavorite() { + return groupsFavorite; + } + + public void setGroupsFavorite(MenuItem groupsFavorite) { + this.groupsFavorite = groupsFavorite; + } + + public MenuItem getGroupsRecentlyViewed() { + return groupsRecentlyViewed; + } + + public void setGroupsRecentlyViewed(MenuItem groupsRecentlyViewed) { + this.groupsRecentlyViewed = groupsRecentlyViewed; + } + + public MenuItem getResourcesSearch() { + return resourcesSearch; + } + + public void setResourcesSearch(MenuItem resourcesSearch) { + this.resourcesSearch = resourcesSearch; + } + + public MenuItem getSecurity() { + return security; + } + + public void setSecurity(MenuItem security) { + this.security = security; + } + + public MenuItem getSecurityUsers() { + return securityUsers; + } + + public void setSecurityUsers(MenuItem securityUsers) { + this.securityUsers = securityUsers; + } + + public MenuItem getSecurityRoles() { + return securityRoles; + } + + public void setSecurityRoles(MenuItem securityRoles) { + this.securityRoles = securityRoles; + } + + public MenuItem getSysconfig() { + return sysconfig; + } + + public void setSysconfig(MenuItem sysconfig) { + this.sysconfig = sysconfig; + } + + public MenuItem getSysconfigSettings() { + return sysconfigSettings; + } + + public void setSysconfigSettings(MenuItem sysconfigSettings) { + this.sysconfigSettings = sysconfigSettings; + } + + public MenuItem getSysconfigPlugins() { + return sysconfigPlugins; + } + + public void setSysconfigPlugins(MenuItem sysconfigPlugins) { + this.sysconfigPlugins = sysconfigPlugins; + } + + public MenuItem getSysconfigTemplates() { + return sysconfigTemplates; + } + + public void setSysconfigTemplates(MenuItem sysconfigTemplates) { + this.sysconfigTemplates = sysconfigTemplates; + } + + public MenuItem getContent() { + return content; + } + + public void setContent(MenuItem content) { + this.content = content; + } + + public MenuItem getContentContentProviders() { + return contentContentProviders; + } + + public void setContentContentProviders(MenuItem contentContentProviders) { + this.contentContentProviders = contentContentProviders; + } + + public MenuItem getContentRepositories() { + return contentRepositories; + } + + public void setContentRepositories(MenuItem contentRepositories) { + this.contentRepositories = contentRepositories; + } + + public MenuItem getHa() { + return ha; + } + + public void setHa(MenuItem ha) { + this.ha = ha; + } + + public MenuItem getHaServers() { + return haServers; + } + + public void setHaServers(MenuItem haServers) { + this.haServers = haServers; + } + + public MenuItem getHaAgents() { + return haAgents; + } + + public void setHaAgents(MenuItem haAgents) { + this.haAgents = haAgents; + } + + public MenuItem getHaAffinityGroups() { + return haAffinityGroups; + } + + public void setHaAffinityGroups(MenuItem haAffinityGroups) { + this.haAffinityGroups = haAffinityGroups; + } + + public MenuItem getHaPartitionEvents() { + return haPartitionEvents; + } + + public void setHaPartitionEvents(MenuItem haPartitionEvents) { + this.haPartitionEvents = haPartitionEvents; + } + + public MenuItem getReports() { + return reports; + } + + public void setReports(MenuItem reports) { + this.reports = reports; + } + + public MenuItem getReportsResourceVersion() { + return reportsResourceVersion; + } + + public void setReportsResourceVersion(MenuItem reportsResourceVersion) { + this.reportsResourceVersion = reportsResourceVersion; + } + + public MenuItem getDownloads() { + return downloads; + } + + public void setDownloads(MenuItem downloads) { + this.downloads = downloads; + } + + public MenuItem getLicense() { + return license; + } + + public void setLicense(MenuItem license) { + this.license = license; + } + + public HashMap<String, MenuItem> getMenuDefinition() { + return menuDefinition; + } + + public void setMenuDefinition(HashMap<String, MenuItem> menuDefinition) { + this.menuDefinition = menuDefinition; + } + + public MenuItem getOverviewBefore() { + return overviewBefore; + } + + public void setOverviewBefore(MenuItem overviewBefore) { + this.overviewBefore = overviewBefore; + } + + public List<MenuItem> getOverviewBeforeItems() { + return overviewBeforeItems; + } + + public void setOverviewBeforeItems(List<MenuItem> overviewBeforeItems) { + this.overviewBeforeItems = overviewBeforeItems; + } +} diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-managed-beans/perspectives-beans.xml b/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-managed-beans/perspectives-beans.xml new file mode 100644 index 0000000..53c0d31 --- /dev/null +++ b/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-managed-beans/perspectives-beans.xml @@ -0,0 +1,14 @@ +<?xml version="1.0"?> + +<faces-config version="1.2" xmlns="http://java.sun.com/xml/ns/javaee" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd%22%3E + + <!-- /rhq/common/menu/menu.xhtml --> + <managed-bean> + <managed-bean-name>PerspectivesMenuUIBean</managed-bean-name> + <managed-bean-class>org.rhq.enterprise.gui.perspectives.PerspectivesMenuUIBean</managed-bean-class> + <managed-bean-scope>request</managed-bean-scope> + </managed-bean> + +</faces-config> \ No newline at end of file diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/web.xml b/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/web.xml index 0038c7d..d5c1906 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/web.xml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/web.xml @@ -108,6 +108,7 @@ /WEB-INF/jsf-managed-beans/admin-beans.xml, /WEB-INF/jsf-managed-beans/measurement-beans.xml, /WEB-INF/jsf-managed-beans/operation-beans.xml, + /WEB-INF/jsf-managed-beans/perspectives-beans.xml, /WEB-INF/jsf-managed-beans/test-beans.xml,
/WEB-INF/jsf-managed-beans-auto-group/inventory-beans.xml, diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/common/menu/menu.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/common/menu/menu.xhtml index e6b4c33..5a7e438 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/common/menu/menu.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/common/menu/menu.xhtml @@ -1,568 +1,646 @@ <a4j:region renderRegionOnly="true" selfRendered="true" - xmlns="http://www.w3.org/1999/xhtml" - xmlns:h="http://java.sun.com/jsf/html" - xmlns:c="http://java.sun.com/jstl/core" - xmlns:f="http://java.sun.com/jsf/core" - xmlns:onf="http://jboss.org/on/function" - xmlns:ui="http://java.sun.com/jsf/facelets" - xmlns:rich="http://richfaces.ajax4jsf.org/rich" - xmlns:a4j="http://richfaces.org/a4j%22%3E - -<h:form> - -<ui:include src="/rhq/common/ie6/ie6fix.xhtml"/> - -<f:loadBundle basename="ApplicationResources" var="msg"/> - - -<rich:toolBar styleClass="topMenu"> -<rich:toolBarGroup location="left"> - - ui:remove===== LOGO TO HOME PAGE =====</ui:remove> - - <h:outputLink value="/"> - <h:graphicImage value="/images/JBossLogo_small.png"/> - </h:outputLink> - - ui:remove===== OVERVIEW =====</ui:remove> - - rich:dropDownMenu - <f:facet name="label"> - <h:panelGroup> - <h:outputText value="Overview"/> - </h:panelGroup> - </f:facet> - - ui:remove***** Overview > SYSTEM VIEWS *****</ui:remove> - <rich:menuGroup value="Subsystem Views"> - <rich:menuItem submitMode="none" icon="/images/icons/Configure_16.png" - onclick="window.location = '/rhq/subsystem/configurationUpdate.xhtml'">Configuration Changes - </rich:menuItem> - <rich:menuItem submitMode="none" icon="/images/icons/Monitor_failed_16.png" - onclick="window.location = '/rhq/subsystem/oobHistory.xhtml'">Suspect Metrics - </rich:menuItem> - <rich:menuItem submitMode="none" icon="/images/icons/Operation_16.png" - onclick="window.location = '/rhq/subsystem/operationHistory.xhtml'">Operations - </rich:menuItem> - <rich:menuItem submitMode="none" icon="/images/icons/Flag_blue_16.png" - onclick="window.location = '/rhq/subsystem/alertHistory.xhtml'">Alerts - </rich:menuItem> - <rich:menuItem submitMode="none" icon="/images/icons/Flag_grey_16.png" - onclick="window.location = '/rhq/subsystem/alertDefinitions.xhtml'">Alert Definitions - </rich:menuItem> - </rich:menuGroup> - - ui:remove***** Overview > AUTO-DISCOVERY QUEUE *****</ui:remove> - <rich:menuItem submitMode="none" - onclick="window.location = '/rhq/discovery/queue.xhtml'"> - <h:outputText value="Auto Discovery Queue"/> - </rich:menuItem> - - ui:remove***** Overview > DASHBOARD *****</ui:remove> - <rich:menuItem submitMode="none" - onclick="window.location = '/Dashboard.do'"> - <h:outputText value="Dashboard"/> - </rich:menuItem> - - </rich:dropDownMenu> - - ui:remove===== RESOURCES =====</ui:remove> - - <rich:dropDownMenu id="resourcesMenu"> - <f:facet name="label"> - <h:panelGroup> - <h:outputText value="Resources"/> - </h:panelGroup> - </f:facet> - - ui:remove***** Resources > PLATFORMS *****</ui:remove> - <rich:menuItem submitMode="none" icon="/images/icons/Platform_up_16.png" - onclick="window.location = '/ResourceHub.do?resourceCategory=PLATFORM'"> - <h:outputText value="#{msg['resource.hub.filter.platform']}"/> - </rich:menuItem> - - ui:remove***** Resources > SERVERS *****</ui:remove> - <rich:menuItem submitMode="none" icon="/images/icons/Server_up_16.png" - onclick="window.location = '/ResourceHub.do?resourceCategory=SERVER'"> - <h:outputText value="#{msg['resource.hub.filter.server']}"/> - </rich:menuItem> - - ui:remove***** Resources > SERVICES *****</ui:remove> - <rich:menuItem submitMode="none" icon="/images/icons/Service_up_16.png" - onclick="window.location = '/ResourceHub.do?resourceCategory=SERVICE'"> - <h:outputText value="#{msg['resource.hub.filter.service']}"/> - </rich:menuItem> - - rich:menuSeparator/ - - ui:remove***** Resources > FAVORITE RESOURCES *****</ui:remove> - <rich:menuGroup value="Favorite Resources" icon="/images/icons/Favorite_16.png"> - <c:forEach var="resource" items="#{UserPreferencesUIBean.resourceFavorites}"> - <rich:menuItem submitMode="none" - icon="/images/icons/#{resource.resourceType.category}_up_16.png" - onclick="window.location = '#{onf:getDefaultResourceTabURL()}?id=#{resource.id}'"> - <h:outputText value="#{resource.name}"/> - </rich:menuItem> - </c:forEach> - </rich:menuGroup> - - ui:remove***** Resources > RECENTLY VIEWED *****</ui:remove> - <rich:menuGroup value="Recently Viewed Resources" icon="/images/icons/History_16.png"> - <c:forEach var="visit" items="#{UserPreferencesUIBean.recentVisits}"> - <c:if test="#{visit.kind == 'PLATFORM' or visit.kind == 'SERVER' or visit.kind == 'SERVICE'}"> - <rich:menuItem submitMode="none" - icon="/images/icons/#{visit.kind.displayName}_up_16.png" - onclick="window.location = '#{onf:getDefaultResourceTabURL()}?id=#{visit.id}'"> - <h:outputText value="#{visit.name}"/> - </rich:menuItem> + xmlns="http://www.w3.org/1999/xhtml" + xmlns:h="http://java.sun.com/jsf/html" + xmlns:c="http://java.sun.com/jstl/core" + xmlns:f="http://java.sun.com/jsf/core" + xmlns:onf="http://jboss.org/on/function" + xmlns:ui="http://java.sun.com/jsf/facelets" + xmlns:rich="http://richfaces.ajax4jsf.org/rich" + xmlns:a4j="http://richfaces.org/a4j%22%3E + + <h:form> + + <ui:include src="/rhq/common/ie6/ie6fix.xhtml" /> + + <f:loadBundle basename="ApplicationResources" var="msg" /> + + + <rich:toolBar styleClass="topMenu"> + <rich:toolBarGroup location="left"> + + ui:remove===== LOGO TO HOME PAGE =====</ui:remove> + + <h:outputLink value="/"> + <h:graphicImage value="#{PerspectivesMenuUIBean.logo.iconUrl}" + width="#{PerspectivesMenuUIBean.logo.iconWidth}" + height="#{PerspectivesMenuUIBean.logo.iconHeight}" + rendered="#{PerspectivesMenuUIBean.logo.rendered}" /> + </h:outputLink> + + ui:remove===== OVERVIEW.BEFORE =====</ui:remove> + <c:if test="#{PerspectivesMenuUIBean.overviewBefore.rendered}"> + rich:dropDownMenu + <f:facet name="label"> + <h:panelGroup> + <h:outputText + value="#{PerspectivesMenuUIBean.overviewBefore.name}" + rendered="#{PerspectivesMenuUIBean.overviewBefore.rendered}" /> + </h:panelGroup> + </f:facet> + <c:forEach var="item" + items="#{PerspectivesMenuUIBean.overviewBeforeItems}"> + <rich:menuItem submitMode="none" icon="#{item.iconUrl}" + width="#{item.iconWidth}" height="#{item.iconHeight}" + rendered="#{item.rendered}" + onclick="window.location = '#{item.url}'"> + <h:outputText value="#{item.name}" /> + </rich:menuItem> + </c:forEach> + </rich:dropDownMenu> </c:if> - </c:forEach> - </rich:menuGroup> - - rich:menuSeparator/ - - ui:remove***** Resources > SEARCH *****</ui:remove> - <rich:menuItem submitMode="none" disabled="true" iconDisabled="/images/icons/Search_16.png"> - <h:outputText value="Search: " style="color: black;"/> - <h:panelGroup> - <h:inputText id="selectedResource" style="width: 250px;" immediate="true" - onkeypress="return ignoreEnterKey(event);" /> - <rich:suggestionbox id="resourceSelectBox" for="selectedResource" tokens=",[]" - ajaxSingle="true" immediate="true" - suggestionAction="#{ResourceSelectUIBean.autocomplete}" - var="result" data="foo" fetchValue="#{result.resource.id}" - nothingLabel="No matching resources found" - style="background-color: #cccccc;" - onselect="document.location.href='#{onf:getDefaultResourceTabURL()}?id=' + #{rich:element('selectedResource')}.value" - usingSuggestObjects="false" width="700" height="400"> - <h:column> - <f:facet name="header">Avail</f:facet> - <h:graphicImage - value="/images/icons/availability_#{result.availability == 'UP' ? 'green' : 'red'}_16.png"/> - </h:column> - <h:column> - <f:facet name="header">Resource</f:facet> - <h:outputText value="#{result.resource.name}"/> - </h:column> - <h:column> - <f:facet name="header">Parent</f:facet> - <h:outputText value="#{result.parent.name}"/> - </h:column> - </rich:suggestionbox> - </h:panelGroup> - </rich:menuItem> - - </rich:dropDownMenu> - - ui:remove===== GROUPS =====</ui:remove> - - <rich:dropDownMenu id="groupsMenu"> - <f:facet name="label"> - <h:panelGroup> - <h:outputText value="Groups"/> - </h:panelGroup> - </f:facet> - - ui:remove***** Groups > COMPATIBLE GROUPS *****</ui:remove> - <rich:menuItem submitMode="none" icon="/images/icons/Cluster_up_16.png" - onclick="window.location = '/GroupHub.do?groupCategory=COMPATIBLE'"> - <h:outputText value="#{msg['resource.hub.filter.compatibleGroups']}"/> - </rich:menuItem> - - ui:remove***** Groups > MIXED GROUPS *****</ui:remove> - <rich:menuItem submitMode="none" icon="/images/icons/Group_up_16.png" - onclick="window.location = '/GroupHub.do?groupCategory=MIXED'"> - <h:outputText value="#{msg['resource.hub.filter.mixedGroups']}"/> - </rich:menuItem> - - ui:remove***** Groups > GROUP DEFINITIONS *****</ui:remove> - <rich:menuItem submitMode="none" icon="/images/GroupDefinition_16.png" - onclick="window.location = '/rhq/definition/group/list.xhtml'"> - <h:outputText value="#{msg['resource.hub.filter.groupDefinitions']}"/> - </rich:menuItem> - - <rich:menuSeparator rendered="#{GlobalPermissionsUIBean.inventory}"/> - - ui:remove***** Groups > NEW RESOURCE GROUP *****</ui:remove> - <rich:menuItem submitMode="none" onclick="window.location = '/resource/group/Inventory.do?mode=new'" - rendered="#{GlobalPermissionsUIBean.inventory}"> - <h:outputText value="#{msg['resource.hub.NewGroupLink']}"/> - </rich:menuItem> - - ui:remove***** Groups > NEW GROUP DEFINITIONS *****</ui:remove> - <rich:menuItem submitMode="none" onclick="window.location = '/rhq/definition/group/new.xhtml'" - rendered="#{GlobalPermissionsUIBean.inventory}"> - <h:outputText value="#{msg['resource.hub.NewGroupDefinitionLink']}"/> - </rich:menuItem> - - rich:menuSeparator/ - - ui:remove***** Groups > FAVORITE GROUPS *****</ui:remove> - <rich:menuGroup value="Favorite Groups" icon="/images/icons/Favorite_16.png"> - <c:forEach var="group" items="#{UserPreferencesUIBean.groupFavorites}"> - <rich:menuItem submitMode="none" - icon="/images/icons/#{group.groupCategory == 'MIXED' ? 'Group' : 'Cluster'}_up_16.png" - onclick="window.location = '/rhq/group/inventory/view.xhtml?groupId=#{group.id}'"> - <h:outputText value="#{group.name}"/> - </rich:menuItem> - </c:forEach> - </rich:menuGroup> - - ui:remove***** Groups > RECENTLY VIEWED *****</ui:remove> - <rich:menuGroup value="Recently Viewed Groups" icon="/images/icons/History_16.png"> - <c:forEach var="visit" items="#{UserPreferencesUIBean.recentVisits}"> - <c:if test="#{visit.kind == 'COMPATIBLE_GROUP' or visit.kind == 'MIXED_GROUP'}"> - <rich:menuItem submitMode="none" - icon="/images/icons/#{visit.kind == 'COMPATIBLE_GROUP' ? 'Cluster' : 'Group'}_up_16.png" - onclick="window.location = '/rhq/group/inventory/view.xhtml?groupId=#{visit.id}'"> - <h:outputText value="#{visit.name}"/> - </rich:menuItem> - </c:if> - </c:forEach> - </rich:menuGroup> - - rich:menuSeparator/ - - ui:remove***** Groups > SEARCH *****</ui:remove> - <rich:menuItem submitMode="none" disabled="true" iconDisabled="/images/icons/Search_16.png"> - <h:outputText value="Search: " style="color: black;"/> - <h:panelGroup> - <h:inputText id="selectedGroup" style="width: 250px;" immediate="true" - onkeypress="return ignoreEnterKey(event);" /> - <rich:suggestionbox id="groupSelectBox" for="selectedGroup" tokens=",[]" - ajaxSingle="true" immediate="true" - suggestionAction="#{ResourceGroupSelectUIBean.autocomplete}" - var="result" data="foo" fetchValue="#{result.groupQueryString}" - nothingLabel="No matching groups found" - style="background-color: #cccccc;" - onselect="document.location.href='/rhq/group/inventory/view.xhtml?' + #{rich:element('selectedGroup')}.value" - usingSuggestObjects="false" width="700" height="400"> - <h:column> - <f:facet name="header">Avail</f:facet> - <h:graphicImage value="/images/icons/availability_green_16.png" rendered="#{result.implicitUp > 0 and result.implicitDown == 0}"/> - <h:graphicImage value="/images/icons/availability_red_16.png" rendered="#{result.implicitUp == 0 and result.implicitDown > 0}"/> - <h:graphicImage value="/images/icons/availability_yellow_16.png" rendered="#{result.implicitUp > 0 and result.implicitDown > 0}"/> - <h:graphicImage value="/images/icons/availability_grey_16.png" rendered="#{result.implicitUp == 0 and result.implicitDown == 0}"/> - </h:column> - <h:column> - <f:facet name="header">Group</f:facet> - <h:outputText value="#{result.resourceGroup.name}"/> - </h:column> - <h:column> - <f:facet name="header">Category</f:facet> - <h:outputText value="#{result.category.name}" rendered="#{result.category.name == 'MIXED'}"/> - <h:outputText value="#{result.resourceGroup.resourceType.name}" rendered="#{result.category.name == 'COMPATIBLE'}"/> - </h:column> - </rich:suggestionbox> - </h:panelGroup> - </rich:menuItem> - - </rich:dropDownMenu> - - ui:remove===== ADMINISTRATION =====</ui:remove> - - rich:dropDownMenu - <f:facet name="label"> - <h:panelGroup> - <h:outputText value="#{msg['admin.admin.AdministrationTitle']}"/> - </h:panelGroup> - </f:facet> - - ui:remove***** Administration > SECURITY *****</ui:remove> - <rich:menuGroup value="Security"> - <rich:menuItem submitMode="none" onclick="window.location = '/admin/user/UserAdmin.do?mode=list'"> - <h:outputText value="Users"/> - </rich:menuItem> - <rich:menuItem submitMode="none" onclick="window.location = '/admin/role/RoleAdmin.do?mode=list'"> - <h:outputText value="Roles"/> - </rich:menuItem> - </rich:menuGroup> - - ui:remove***** Administration > SYSTEM CONFIGURATION *****</ui:remove> - <rich:menuGroup value="System Configuration" rendered="#{GlobalPermissionsUIBean.settings || GlobalPermissionsUIBean.inventory}"> - <rich:menuItem submitMode="none" onclick="window.location = '/admin/config/Config.do?mode=edit'" - rendered="#{GlobalPermissionsUIBean.settings}"> - <h:outputText value="Settings"/> - </rich:menuItem> - <rich:menuItem submitMode="none" onclick="window.location = '/rhq/admin/plugin/plugin-list.xhtml'" - rendered="#{GlobalPermissionsUIBean.settings}"> - <h:outputText value="Plugins"/> - </rich:menuItem> - <rich:menuItem submitMode="none" onclick="window.location = '/admin/config/EditDefaults.do?mode=monitor&viewMode=all'" - rendered="#{GlobalPermissionsUIBean.inventory}"> - <h:outputText value="Templates"/> - </rich:menuItem> - </rich:menuGroup> - - ui:remove***** Administration > CONTENT *****</ui:remove> - <rich:menuGroup value="Content" rendered="#{GlobalPermissionsUIBean.inventory}"> - <rich:menuItem submitMode="none" onclick="window.location = '/rhq/content/listContentProviders.xhtml'"> - <h:outputText value="Content Providers"/> - </rich:menuItem> - <rich:menuItem submitMode="none" onclick="window.location = '/rhq/content/listRepos.xhtml'"> - <h:outputText value="Repositories"/> - </rich:menuItem> - </rich:menuGroup> - - ui:remove***** Administration > HIGH AVAILABILITY *****</ui:remove> - <rich:menuGroup value="High Availability" rendered="#{GlobalPermissionsUIBean.inventory}"> - <rich:menuItem submitMode="none" onclick="window.location = '/rhq/ha/listServers.xhtml'"> - <h:outputText value="Servers"/> - </rich:menuItem> - <rich:menuItem submitMode="none" onclick="window.location = '/rhq/ha/listAgents.xhtml'"> - <h:outputText value="Agents"/> - </rich:menuItem> - <rich:menuItem submitMode="none" onclick="window.location = '/rhq/ha/listAffinityGroups.xhtml'"> - <h:outputText value="Affinity Groups"/> - </rich:menuItem> - <rich:menuItem submitMode="none" onclick="window.location = '/rhq/ha/listPartitionEvents.xhtml'"> - <h:outputText value="Partition Events"/> - </rich:menuItem> - </rich:menuGroup> - - - - <rich:menuGroup value="Reports"> - <rich:menuItem submitMode="none" onclick="window.location = '/rhq/admin/report/resourceInstallReport.xhtml'"> - <h:outputText value="Resource Version Inventory Report"/> - </rich:menuItem> - - </rich:menuGroup> - - <rich:menuItem submitMode="none" - icon="/images/icons/Save_16.png" - onclick="window.location = '/rhq/admin/downloads.xhtml'"> - <h:outputText value="Downloads"/> - </rich:menuItem> - - - <rich:menuItem submitMode="none" - onclick="window.location = '/admin/license/LicenseAdmin.do?mode=view'" - rendered="#{GlobalPermissionsUIBean.settings}"> - <h:outputText value="License"/> - </rich:menuItem> - </rich:dropDownMenu> - - ui:remove===== DEBUG =====</ui:remove> - - <rich:dropDownMenu rendered="#{GlobalPermissionsUIBean.superuser and + ui:remove===== OVERVIEW =====</ui:remove> + + rich:dropDownMenu + <f:facet name="label"> + <h:panelGroup> + <h:outputText value="#{PerspectivesMenuUIBean.overview.name}" + rendered="#{PerspectivesMenuUIBean.overview.rendered}" /> + </h:panelGroup> + </f:facet> + + ui:remove***** Overview > SYSTEM VIEWS *****</ui:remove> + rich:menuGroup + value="#{PerspectivesMenuUIBean.subsystemViews.name}" + <c:forEach var="menu" + items="#{PerspectivesMenuUIBean.subsystemMenuItems}"> + <rich:menuItem submitMode="none" icon="#{menu.iconUrl}" + onclick="window.location = '#{menu.url}'"> + <h:outputText value="#{menu.name}" /> + </rich:menuItem> + </c:forEach> + </rich:menuGroup> + + ui:remove***** Overview > AUTO-DISCOVERY QUEUE *****</ui:remove> + <rich:menuItem submitMode="none" + onclick="window.location = '#{PerspectivesMenuUIBean.autoDiscoveryQueue.url}'"> + <h:outputText + value="#{PerspectivesMenuUIBean.autoDiscoveryQueue.name}" /> + </rich:menuItem> + + ui:remove***** Overview > DASHBOARD *****</ui:remove> + <rich:menuItem submitMode="none" + onclick="window.location = '#{PerspectivesMenuUIBean.dashboard.url}'"> + <h:outputText value="#{PerspectivesMenuUIBean.dashboard.name}" /> + </rich:menuItem> + </rich:dropDownMenu> + + ui:remove===== RESOURCES =====</ui:remove> + + <rich:dropDownMenu id="resourcesMenu"> + <f:facet name="label"> + <h:panelGroup> + <h:outputText value="#{PerspectivesMenuUIBean.resources.name}" /> + </h:panelGroup> + </f:facet> + + ui:remove***** Resources > PLATFORMS *****</ui:remove> + <rich:menuItem submitMode="none" + icon="#{PerspectivesMenuUIBean.resourcesPlatform.iconUrl}" + onclick="window.location = '#{PerspectivesMenuUIBean.resourcesPlatform.url}'"> + <h:outputText value="#{msg['resource.hub.filter.platform']}" /> + </rich:menuItem> + + ui:remove***** Resources > SERVERS *****</ui:remove> + <rich:menuItem submitMode="none" + icon="#{PerspectivesMenuUIBean.resourcesServer.iconUrl}" + onclick="window.location = '#{PerspectivesMenuUIBean.resourcesServer.url}'"> + <h:outputText value="#{msg['resource.hub.filter.server']}" /> + </rich:menuItem> + + ui:remove***** Resources > SERVICES *****</ui:remove> + <rich:menuItem submitMode="none" + icon="#{PerspectivesMenuUIBean.resourcesService.iconUrl}" + onclick="window.location = '#{PerspectivesMenuUIBean.resourcesService.url}'"> + <h:outputText value="#{msg['resource.hub.filter.service']}" /> + </rich:menuItem> + + ui:remove***** Resources > FAVORITE RESOURCES *****</ui:remove> + rich:menuGroup + value="#{PerspectivesMenuUIBean.resourcesFavorite.name}" + icon="#{PerspectivesMenuUIBean.resourcesFavorite.iconUrl}" + <c:forEach var="resource" + items="#{UserPreferencesUIBean.resourceFavorites}"> + <rich:menuItem submitMode="none" + icon="/images/icons/#{resource.resourceType.category}_up_16.png" + onclick="window.location = '#{onf:getDefaultResourceTabURL()}?id=#{resource.id}'"> + <h:outputText value="#{resource.name}" /> + </rich:menuItem> + </c:forEach> + </rich:menuGroup> + + ui:remove***** Resources > RECENTLY VIEWED *****</ui:remove> + rich:menuGroup + value="#{PerspectivesMenuUIBean.resourcesRecentlyViewed.name}" + icon="#{PerspectivesMenuUIBean.resourcesRecentlyViewed.iconUrl}" + <c:forEach var="visit" + items="#{UserPreferencesUIBean.recentVisits}"> + <c:if + test="#{visit.kind == 'PLATFORM' or visit.kind == 'SERVER' or visit.kind == 'SERVICE'}"> + <rich:menuItem submitMode="none" + icon="/images/icons/#{visit.kind.displayName}_up_16.png" + onclick="window.location = '#{onf:getDefaultResourceTabURL()}?id=#{visit.id}'"> + <h:outputText value="#{visit.name}" /> + </rich:menuItem> + </c:if> + </c:forEach> + </rich:menuGroup> + + <rich:menuSeparator /> + + ui:remove***** Resources > SEARCH *****</ui:remove> + <rich:menuItem submitMode="none" disabled="true" + iconDisabled="/images/icons/Search_16.png"> + <h:outputText value="Search: " style="color: black;" /> + <h:panelGroup> + <h:inputText id="selectedResource" style="width: 250px;" + immediate="true" onkeypress="return ignoreEnterKey(event);" /> + <rich:suggestionbox id="resourceSelectBox" for="selectedResource" + tokens=",[]" ajaxSingle="true" immediate="true" + suggestionAction="#{ResourceSelectUIBean.autocomplete}" + var="result" data="foo" fetchValue="#{result.resource.id}" + nothingLabel="No matching resources found" + style="background-color: #cccccc;" + onselect="document.location.href='#{onf:getDefaultResourceTabURL()}?id=' + #{rich:element('selectedResource')}.value" + usingSuggestObjects="false" width="700" height="400"> + <h:column> + <f:facet name="header">Avail</f:facet> + <h:graphicImage + value="/images/icons/availability_#{result.availability == 'UP' ? 'green' : 'red'}_16.png" /> + </h:column> + <h:column> + <f:facet name="header">Resource</f:facet> + <h:outputText value="#{result.resource.name}" /> + </h:column> + <h:column> + <f:facet name="header">Parent</f:facet> + <h:outputText value="#{result.parent.name}" /> + </h:column> + </rich:suggestionbox> + </h:panelGroup> + </rich:menuItem> + + </rich:dropDownMenu> + + ui:remove===== GROUPS =====</ui:remove> + + <rich:dropDownMenu id="groupsMenu"> + <f:facet name="label"> + <h:panelGroup> + <h:outputText value="#{PerspectivesMenuUIBean.groups.name}"/> + </h:panelGroup> + </f:facet> + + ui:remove***** Groups > COMPATIBLE GROUPS *****</ui:remove> + <rich:menuItem submitMode="none" + icon="#{PerspectivesMenuUIBean.groupsCompatible.iconUrl}" + onclick="window.location = '#{PerspectivesMenuUIBean.groupsCompatible.url}'"> + <h:outputText + value="#{msg['resource.hub.filter.compatibleGroups']}" /> + </rich:menuItem> + + ui:remove***** Groups > MIXED GROUPS *****</ui:remove> + <rich:menuItem submitMode="none" + icon="#{PerspectivesMenuUIBean.groupsMixed.iconUrl}" + onclick="window.location = '#{PerspectivesMenuUIBean.groupsMixed.url}'"> + <h:outputText value="#{msg['resource.hub.filter.mixedGroups']}" /> + </rich:menuItem> + + ui:remove***** Groups > GROUP DEFINITIONS *****</ui:remove> + <rich:menuItem submitMode="none" + icon="#{PerspectivesMenuUIBean.groupsDefinitions.iconUrl}" + onclick="window.location = '#{PerspectivesMenuUIBean.groupsDefinitions.url}'"> + <h:outputText + value="#{msg['resource.hub.filter.groupDefinitions']}" /> + </rich:menuItem> + + <rich:menuSeparator rendered="#{GlobalPermissionsUIBean.inventory}" /> + + ui:remove***** Groups > NEW RESOURCE GROUP *****</ui:remove> + <rich:menuItem submitMode="none" + onclick="window.location = '#{PerspectivesMenuUIBean.groupsNewResource.url}'" + rendered="#{GlobalPermissionsUIBean.inventory}"> + <h:outputText value="#{msg['resource.hub.NewGroupLink']}" /> + </rich:menuItem> + + ui:remove***** Groups > NEW GROUP DEFINITIONS *****</ui:remove> + <rich:menuItem submitMode="none" + onclick="window.location = '#{PerspectivesMenuUIBean.groupsNewDefinition.url}'" + rendered="#{GlobalPermissionsUIBean.inventory}"> + <h:outputText + value="#{msg['resource.hub.NewGroupDefinitionLink']}" /> + </rich:menuItem> + + <rich:menuSeparator /> + + ui:remove***** Groups > FAVORITE GROUPS *****</ui:remove> + rich:menuGroup + value="#{PerspectivesMenuUIBean.groupsFavorite.name}" + icon="#{PerspectivesMenuUIBean.groupsFavorite.iconUrl}" + <c:forEach var="group" + items="#{UserPreferencesUIBean.groupFavorites}"> + <rich:menuItem submitMode="none" + icon="/images/icons/#{group.groupCategory == 'MIXED' ? 'Group' : 'Cluster'}_up_16.png" + onclick="window.location = '/rhq/group/inventory/view.xhtml?groupId=#{group.id}'"> + <h:outputText value="#{group.name}" /> + </rich:menuItem> + </c:forEach> + </rich:menuGroup> + + ui:remove***** Groups > RECENTLY VIEWED *****</ui:remove> + rich:menuGroup + value="#{PerspectivesMenuUIBean.groupsRecentlyViewed.name}" + icon="#{PerspectivesMenuUIBean.groupsRecentlyViewed.iconUrl}" + <c:forEach var="visit" + items="#{UserPreferencesUIBean.recentVisits}"> + <c:if + test="#{visit.kind == 'COMPATIBLE_GROUP' or visit.kind == 'MIXED_GROUP'}"> + <rich:menuItem submitMode="none" + icon="/images/icons/#{visit.kind == 'COMPATIBLE_GROUP' ? 'Cluster' : 'Group'}_up_16.png" + onclick="window.location = '/rhq/group/inventory/view.xhtml?groupId=#{visit.id}'"> + <h:outputText value="#{visit.name}" /> + </rich:menuItem> + </c:if> + </c:forEach> + </rich:menuGroup> + + <rich:menuSeparator /> + + ui:remove***** Groups > SEARCH *****</ui:remove> + <rich:menuItem submitMode="none" disabled="true" + iconDisabled="/images/icons/Search_16.png"> + <h:outputText value="Search: " style="color: black;" /> + <h:panelGroup> + <h:inputText id="selectedGroup" style="width: 250px;" + immediate="true" onkeypress="return ignoreEnterKey(event);" /> + <rich:suggestionbox id="groupSelectBox" for="selectedGroup" + tokens=",[]" ajaxSingle="true" immediate="true" + suggestionAction="#{ResourceGroupSelectUIBean.autocomplete}" + var="result" data="foo" fetchValue="#{result.groupQueryString}" + nothingLabel="No matching groups found" + style="background-color: #cccccc;" + onselect="document.location.href='/rhq/group/inventory/view.xhtml?' + #{rich:element('selectedGroup')}.value" + usingSuggestObjects="false" width="700" height="400"> + <h:column> + <f:facet name="header">Avail</f:facet> + <h:graphicImage value="/images/icons/availability_green_16.png" + rendered="#{result.implicitUp > 0 and result.implicitDown == 0}" /> + <h:graphicImage value="/images/icons/availability_red_16.png" + rendered="#{result.implicitUp == 0 and result.implicitDown > 0}" /> + <h:graphicImage + value="/images/icons/availability_yellow_16.png" + rendered="#{result.implicitUp > 0 and result.implicitDown > 0}" /> + <h:graphicImage value="/images/icons/availability_grey_16.png" + rendered="#{result.implicitUp == 0 and result.implicitDown == 0}" /> + </h:column> + <h:column> + <f:facet name="header">Group</f:facet> + <h:outputText value="#{result.resourceGroup.name}" /> + </h:column> + <h:column> + <f:facet name="header">Category</f:facet> + <h:outputText value="#{result.category.name}" + rendered="#{result.category.name == 'MIXED'}" /> + <h:outputText value="#{result.resourceGroup.resourceType.name}" + rendered="#{result.category.name == 'COMPATIBLE'}" /> + </h:column> + </rich:suggestionbox> + </h:panelGroup> + </rich:menuItem> + + </rich:dropDownMenu> + + ui:remove===== ADMINISTRATION =====</ui:remove> + + rich:dropDownMenu + <f:facet name="label"> + <h:panelGroup> + <h:outputText value="#{msg['admin.admin.AdministrationTitle']}" /> + </h:panelGroup> + </f:facet> + + ui:remove***** Administration > SECURITY *****</ui:remove> + <rich:menuGroup value="Security"> + <rich:menuItem submitMode="none" + onclick="window.location = '/admin/user/UserAdmin.do?mode=list'"> + <h:outputText value="Users" /> + </rich:menuItem> + <rich:menuItem submitMode="none" + onclick="window.location = '/admin/role/RoleAdmin.do?mode=list'"> + <h:outputText value="Roles" /> + </rich:menuItem> + </rich:menuGroup> + + ui:remove***** Administration > SYSTEM CONFIGURATION *****</ui:remove> + <rich:menuGroup value="System Configuration" + rendered="#{GlobalPermissionsUIBean.settings || GlobalPermissionsUIBean.inventory}"> + <rich:menuItem submitMode="none" + onclick="window.location = '/admin/config/Config.do?mode=edit'" + rendered="#{GlobalPermissionsUIBean.settings}"> + <h:outputText value="Settings" /> + </rich:menuItem> + <rich:menuItem submitMode="none" + onclick="window.location = '/rhq/admin/plugin/plugin-list.xhtml'" + rendered="#{GlobalPermissionsUIBean.settings}"> + <h:outputText value="Plugins" /> + </rich:menuItem> + <rich:menuItem submitMode="none" + onclick="window.location = '/admin/config/EditDefaults.do?mode=monitor&viewMode=all'" + rendered="#{GlobalPermissionsUIBean.inventory}"> + <h:outputText value="Templates" /> + </rich:menuItem> + </rich:menuGroup> + + ui:remove***** Administration > CONTENT *****</ui:remove> + <rich:menuGroup value="Content" + rendered="#{GlobalPermissionsUIBean.inventory}"> + <rich:menuItem submitMode="none" + onclick="window.location = '/rhq/content/listContentProviders.xhtml'"> + <h:outputText value="Content Providers" /> + </rich:menuItem> + <rich:menuItem submitMode="none" + onclick="window.location = '/rhq/content/listRepos.xhtml'"> + <h:outputText value="Repositories" /> + </rich:menuItem> + </rich:menuGroup> + + ui:remove***** Administration > HIGH AVAILABILITY *****</ui:remove> + <rich:menuGroup value="High Availability" + rendered="#{GlobalPermissionsUIBean.inventory}"> + <rich:menuItem submitMode="none" + onclick="window.location = '/rhq/ha/listServers.xhtml'"> + <h:outputText value="Servers" /> + </rich:menuItem> + <rich:menuItem submitMode="none" + onclick="window.location = '/rhq/ha/listAgents.xhtml'"> + <h:outputText value="Agents" /> + </rich:menuItem> + <rich:menuItem submitMode="none" + onclick="window.location = '/rhq/ha/listAffinityGroups.xhtml'"> + <h:outputText value="Affinity Groups" /> + </rich:menuItem> + <rich:menuItem submitMode="none" + onclick="window.location = '/rhq/ha/listPartitionEvents.xhtml'"> + <h:outputText value="Partition Events" /> + </rich:menuItem> + </rich:menuGroup> + + + + <rich:menuGroup value="Reports"> + <rich:menuItem submitMode="none" + onclick="window.location = '/rhq/admin/report/resourceInstallReport.xhtml'"> + <h:outputText value="Resource Version Inventory Report" /> + </rich:menuItem> + + </rich:menuGroup> + + <rich:menuItem submitMode="none" icon="/images/icons/Save_16.png" + onclick="window.location = '/rhq/admin/downloads.xhtml'"> + <h:outputText value="Downloads" /> + </rich:menuItem> + + + <rich:menuItem submitMode="none" + onclick="window.location = '/admin/license/LicenseAdmin.do?mode=view'" + rendered="#{GlobalPermissionsUIBean.settings}"> + <h:outputText value="License" /> + </rich:menuItem> + </rich:dropDownMenu> + + ui:remove===== DEBUG =====</ui:remove> + + <rich:dropDownMenu + rendered="#{GlobalPermissionsUIBean.superuser and GlobalPermissionsUIBean.debugMode}"> - <f:facet name="label"> - <h:panelGroup> - <h:outputText value="Debug"/> - </h:panelGroup> - </f:facet> - - <rich:menuItem submitMode="none" - onclick="window.open('/admin/test/sql.jsp')" - target="blank_"> - <h:outputText value="SQL Interface"/> - </rich:menuItem> - <rich:menuItem submitMode="none" - onclick="window.open('/admin/test/hibernate.jsp')" - target="blank_"> - <h:outputText value="JPQL/HQL Interface"/> - </rich:menuItem> - <rich:menuItem submitMode="none" - onclick="window.open('/admin/test/browser.jsp')" - target="blank_"> - <h:outputText value="Hibernate Entity Browser"/> - </rich:menuItem> - <rich:menuItem submitMode="none" - onclick="window.open('/admin/test/control.jsp')" - target="blank_"> - <h:outputText value="Administrative Control"/> - </rich:menuItem> - <rich:menuItem submitMode="none" - onclick="window.open('/admin/test/email.jsp')" - target="blank_"> - <h:outputText value="Test Email Configuration"/> - </rich:menuItem> -v <rich:menuItem submitMode="none" - onclick="window.open('/admin/test/agent.jsp')" - target="blank_"> - <h:outputText value="Test Agent Communications"/> - </rich:menuItem> - </rich:dropDownMenu> - - ui:remove===== HELP =====</ui:remove> - - rich:dropDownMenu - <f:facet name="label"> - <h:panelGroup> - <h:outputText value="#{msg['header.help.link']}"/> - </h:panelGroup> - </f:facet> - - ui:remove***** Help > DOCUMENTATION *****</ui:remove> - <rich:menuItem submitMode="none" - onclick="window.open('http://www.redhat.com/docs/en-US/JBoss_ON/')" - target="blank_"> - <h:outputText value="Online Documentation"/> - </rich:menuItem> - - ui:remove***** Help > SUPPORT CASE *****</ui:remove> - <rich:menuItem submitMode="none" - onclick="window.open('https://support.redhat.com/jbossnetwork/restricted/addCase.html')" - target="blank_"> - <h:outputText value="Open a Support Case"/> - </rich:menuItem> - - rich:menuSeparator/ - - ui:remove***** Help > ABOUT *****</ui:remove> - <rich:menuItem submitMode="none" id="aboutLink" icon="/images/icons/availability_grey_16.png"> - <h:outputText value="#{msg['header.about.link']}"/> - <rich:componentControl for="aboutPanel" attachTo="aboutLink" operation="show" event="onclick"/> - </rich:menuItem> - </rich:dropDownMenu> -</rich:toolBarGroup> - - -<rich:toolBarGroup location="right"> - - <a4j:status id="commonStatus" layout="block" - startStyle=" filter:alpha(opacity=85); -moz-opacity: 0.85; opacity: 0.85; vertical-align: middle;"> - <f:facet name="start"> - <img src="/images/ajax-loader.gif" alt="" style="vertical-align:middle;"/> <span - style="vertical-align: middle;">Loading...</span> - </f:facet> - </a4j:status> - - - - - - <rich:dropDownMenu rendered="#{request.method == 'GET'}"> - <f:facet name="label"> - <h:panelGroup> - <h:graphicImage value="/images/refreshRunning.gif" rendered="#{UserPreferencesUIBean.pageRefresh != 0}"/> - <h:graphicImage value="/images/refreshStopped.gif" rendered="#{UserPreferencesUIBean.pageRefresh == 0}"/> - <span id="refreshTimeLeft" style="width: 0px;"><h:outputText value="#{UserPreferencesUIBean.pageRefresh}" rendered="#{UserPreferencesUIBean.pageRefresh != 0}"/></span> - - </h:panelGroup> - </f:facet> - - ui:remove***** Logged in as > EDIT DETAILS *****</ui:remove> - - - - <rich:menuItem submitMode="none" onclick="updatePageRefresh('#{request.getAttribute('javax.servlet.forward.request_uri')}', 0)"> - <h:outputText value="Stop"/> - <f:facet name="icon"> - <h:graphicImage value="/images/#{UserPreferencesUIBean.pageRefresh == 0 ? 'check.png' : 'spacer.gif'}" width="16" height="16"/> - </f:facet> - </rich:menuItem> - <rich:menuItem submitMode="none" onclick="updatePageRefresh('#{request.getAttribute('javax.servlet.forward.request_uri')}',60)"> - <h:outputText value="Refresh every 1 minute"/> - <f:facet name="icon"> - <h:graphicImage value="/images/#{UserPreferencesUIBean.pageRefresh == 60 ? 'check.png' : 'spacer.gif'}" width="16" height="16"/> - </f:facet> - </rich:menuItem> - <rich:menuItem submitMode="none" onclick="updatePageRefresh('#{request.getAttribute('javax.servlet.forward.request_uri')}',300)"> - <h:outputText value="Refresh every 5 minutes"/> - <f:facet name="icon"> - <h:graphicImage value="/images/#{UserPreferencesUIBean.pageRefresh == 300 ? 'check.png' : 'spacer.gif'}" width="16" height="16"/> - </f:facet> - </rich:menuItem> - <rich:menuItem submitMode="none" onclick="updatePageRefresh('#{request.getAttribute('javax.servlet.forward.request_uri')}',600)"> - <h:outputText value="Refresh every 10 minutes"/> - <f:facet name="icon"> - <h:graphicImage value="/images/#{UserPreferencesUIBean.pageRefresh == 600 ? 'check.png' : 'spacer.gif'}" width="16" height="16"/> - </f:facet> - </rich:menuItem> - - </rich:dropDownMenu> - - ui:remove===== LOGGED IN AS =====</ui:remove> - - - rich:dropDownMenu - <f:facet name="label"> - <h:panelGroup> - <h:outputText value="Logged in as #{UserPreferencesUIBean.subject.name}"/> - </h:panelGroup> - </f:facet> - - ui:remove***** Logged in as > EDIT DETAILS *****</ui:remove> - <rich:menuItem submitMode="none" onclick="window.location = '/admin/user/UserAdmin.do?mode=edit&u=#{UserPreferencesUIBean.subject.id}'"> - <h:outputText value="Edit Details"/> - </rich:menuItem> - - ui:remove***** Logged in as > CHANGE PASSWORD *****</ui:remove> - <rich:menuItem submitMode="none" onclick="window.location = '/admin/user/UserAdmin.do?mode=editPass&u=#{UserPreferencesUIBean.subject.id}'"> - <h:outputText value="Change Password"/> - </rich:menuItem> - - rich:menuSeparator/ - - ui:remove***** Logged in as > LOGOUT *****</ui:remove> - <rich:menuItem submitMode="none" onclick="window.location = '/Logout.do'"> - <h:outputText value="Logout"/> - </rich:menuItem> - </rich:dropDownMenu> - -</rich:toolBarGroup> -</rich:toolBar> - -<rich:modalPanel id="aboutPanel" resizeable="false" width="320" height="250"> - <f:facet name="header"> - <h:panelGroup> - <h:outputText value="#{msg['about.Title']}"/> - </h:panelGroup> - </f:facet> - <f:facet name="controls"> - <h:panelGroup> - <h:graphicImage value="/images/close.png" style="cursor:pointer;" id="hidelink"/> - <rich:componentControl for="aboutPanel" attachTo="hidelink" operation="hide" event="onclick"/> - </h:panelGroup> - </f:facet> - - <p> - <span class="DisplaySubhead"><h:outputText value="#{msg['footer.aboutLink']}"/></span><br/> - <span class="DisplayLabel"><h:outputText - value="#{msg['footer.version']}: #{msg['product.version']}"/></span><br/> - <span class="DisplayLabel"><h:outputText - value="#{msg['footer.buildNumber']}: #{msg['product.buildNumber']}"/></span> - </p> - - <p> - <a href="http://jboss.org/"> - <img src="/images/jboss_logo.png" alt="JBoss Homepage" title="JBoss by Red Hat" height="55" /> - </a> - </p> - - <p> - <f:verbatim><h:outputText value="#{msg['footer.copyright']}"/></f:verbatim> - <h:outputText value="#{msg['about.Copyright.Content']}"/> - </p> - - <p> - <a href="http://jboss.org/jopr"> - <h:graphicImage value="/images/logo_icon.png" style="vertical-align:middle" /> - Jopr Project - </a> - - ui:remove - <!--<h:outputText value="#{msg['about.MoreInfo.Label']}"/><br/>--> - <!-- + <f:facet name="label"> + <h:panelGroup> + <h:outputText value="Debug" /> + </h:panelGroup> + </f:facet> + + <rich:menuItem submitMode="none" + onclick="window.open('/admin/test/sql.jsp')" target="blank_"> + <h:outputText value="SQL Interface" /> + </rich:menuItem> + <rich:menuItem submitMode="none" + onclick="window.open('/admin/test/hibernate.jsp')" target="blank_"> + <h:outputText value="JPQL/HQL Interface" /> + </rich:menuItem> + <rich:menuItem submitMode="none" + onclick="window.open('/admin/test/browser.jsp')" target="blank_"> + <h:outputText value="Hibernate Entity Browser" /> + </rich:menuItem> + <rich:menuItem submitMode="none" + onclick="window.open('/admin/test/control.jsp')" target="blank_"> + <h:outputText value="Administrative Control" /> + </rich:menuItem> + <rich:menuItem submitMode="none" + onclick="window.open('/admin/test/email.jsp')" target="blank_"> + <h:outputText value="Test Email Configuration" /> + </rich:menuItem> + <rich:menuItem submitMode="none" + onclick="window.open('/admin/test/agent.jsp')" target="blank_"> + <h:outputText value="Test Agent Communications" /> + </rich:menuItem> + </rich:dropDownMenu> + + ui:remove===== HELP =====</ui:remove> + + rich:dropDownMenu + <f:facet name="label"> + <h:panelGroup> + <h:outputText value="#{msg['header.help.link']}" /> + </h:panelGroup> + </f:facet> + + ui:remove***** Help > DOCUMENTATION *****</ui:remove> + <rich:menuItem submitMode="none" + onclick="window.open('http://www.redhat.com/docs/en-US/JBoss_ON/')" + target="blank_"> + <h:outputText value="Online Documentation" /> + </rich:menuItem> + + ui:remove***** Help > SUPPORT CASE *****</ui:remove> + <rich:menuItem submitMode="none" + onclick="window.open('https://support.redhat.com/jbossnetwork/restricted/addCase.html')" + target="blank_"> + <h:outputText value="Open a Support Case" /> + </rich:menuItem> + + <rich:menuSeparator /> + + ui:remove***** Help > ABOUT *****</ui:remove> + <rich:menuItem submitMode="none" id="aboutLink" + icon="/images/icons/availability_grey_16.png"> + <h:outputText value="#{msg['header.about.link']}" /> + <rich:componentControl for="aboutPanel" attachTo="aboutLink" + operation="show" event="onclick" /> + </rich:menuItem> + </rich:dropDownMenu> + </rich:toolBarGroup> + + + <rich:toolBarGroup location="right"> + + <a4j:status id="commonStatus" layout="block" + startStyle=" filter:alpha(opacity=85); -moz-opacity: 0.85; opacity: 0.85; vertical-align: middle;"> + <f:facet name="start"> + <img src="/images/ajax-loader.gif" alt="" + style="vertical-align: middle;" /> + <span style="vertical-align: middle;">Loading...</span> + </f:facet> + </a4j:status> + + + + + + <rich:dropDownMenu rendered="#{request.method == 'GET'}"> + <f:facet name="label"> + <h:panelGroup> + <h:graphicImage value="/images/refreshRunning.gif" + rendered="#{UserPreferencesUIBean.pageRefresh != 0}" /> + <h:graphicImage value="/images/refreshStopped.gif" + rendered="#{UserPreferencesUIBean.pageRefresh == 0}" /> + <span id="refreshTimeLeft" style="width: 0px;"><h:outputText + value="#{UserPreferencesUIBean.pageRefresh}" + rendered="#{UserPreferencesUIBean.pageRefresh != 0}" /></span> + + </h:panelGroup> + </f:facet> + + ui:remove***** Logged in as > EDIT DETAILS *****</ui:remove> + + + + <rich:menuItem submitMode="none" + onclick="updatePageRefresh('#{request.getAttribute('javax.servlet.forward.request_uri')}', 0)"> + <h:outputText value="Stop" /> + <f:facet name="icon"> + <h:graphicImage + value="/images/#{UserPreferencesUIBean.pageRefresh == 0 ? 'check.png' : 'spacer.gif'}" + width="16" height="16" /> + </f:facet> + </rich:menuItem> + <rich:menuItem submitMode="none" + onclick="updatePageRefresh('#{request.getAttribute('javax.servlet.forward.request_uri')}',60)"> + <h:outputText value="Refresh every 1 minute" /> + <f:facet name="icon"> + <h:graphicImage + value="/images/#{UserPreferencesUIBean.pageRefresh == 60 ? 'check.png' : 'spacer.gif'}" + width="16" height="16" /> + </f:facet> + </rich:menuItem> + <rich:menuItem submitMode="none" + onclick="updatePageRefresh('#{request.getAttribute('javax.servlet.forward.request_uri')}',300)"> + <h:outputText value="Refresh every 5 minutes" /> + <f:facet name="icon"> + <h:graphicImage + value="/images/#{UserPreferencesUIBean.pageRefresh == 300 ? 'check.png' : 'spacer.gif'}" + width="16" height="16" /> + </f:facet> + </rich:menuItem> + <rich:menuItem submitMode="none" + onclick="updatePageRefresh('#{request.getAttribute('javax.servlet.forward.request_uri')}',600)"> + <h:outputText value="Refresh every 10 minutes" /> + <f:facet name="icon"> + <h:graphicImage + value="/images/#{UserPreferencesUIBean.pageRefresh == 600 ? 'check.png' : 'spacer.gif'}" + width="16" height="16" /> + </f:facet> + </rich:menuItem> + + </rich:dropDownMenu> + + ui:remove===== LOGGED IN AS =====</ui:remove> + + + rich:dropDownMenu + <f:facet name="label"> + <h:panelGroup> + <h:outputText + value="Logged in as #{UserPreferencesUIBean.subject.name}" /> + </h:panelGroup> + </f:facet> + + ui:remove***** Logged in as > EDIT DETAILS *****</ui:remove> + <rich:menuItem submitMode="none" + onclick="window.location = '/admin/user/UserAdmin.do?mode=edit&u=#{UserPreferencesUIBean.subject.id}'"> + <h:outputText value="Edit Details" /> + </rich:menuItem> + + ui:remove***** Logged in as > CHANGE PASSWORD *****</ui:remove> + <rich:menuItem submitMode="none" + onclick="window.location = '/admin/user/UserAdmin.do?mode=editPass&u=#{UserPreferencesUIBean.subject.id}'"> + <h:outputText value="Change Password" /> + </rich:menuItem> + + <rich:menuSeparator /> + + ui:remove***** Logged in as > LOGOUT *****</ui:remove> + <rich:menuItem submitMode="none" + onclick="window.location = '/Logout.do'"> + <h:outputText value="Logout" /> + </rich:menuItem> + </rich:dropDownMenu> + + </rich:toolBarGroup> + </rich:toolBar> + + <rich:modalPanel id="aboutPanel" resizeable="false" width="320" + height="250"> + <f:facet name="header"> + <h:panelGroup> + <h:outputText value="#{msg['about.Title']}" /> + </h:panelGroup> + </f:facet> + <f:facet name="controls"> + <h:panelGroup> + <h:graphicImage value="/images/close.png" style="cursor:pointer;" + id="hidelink" /> + <rich:componentControl for="aboutPanel" attachTo="hidelink" + operation="hide" event="onclick" /> + </h:panelGroup> + </f:facet> + + <p><span class="DisplaySubhead"><h:outputText + value="#{msg['footer.aboutLink']}" /></span><br /> + <span class="DisplayLabel"><h:outputText + value="#{msg['footer.version']}: #{msg['product.version']}" /></span><br /> + <span class="DisplayLabel"><h:outputText + value="#{msg['footer.buildNumber']}: #{msg['product.buildNumber']}" /></span> + </p> + + <p><a href="http://jboss.org/"> <img + src="/images/jboss_logo.png" alt="JBoss Homepage" + title="JBoss by Red Hat" height="55" /> </a></p> + + <p><f:verbatim> + <h:outputText value="#{msg['footer.copyright']}" /> + </f:verbatim> <h:outputText value="#{msg['about.Copyright.Content']}" /></p> + + <p><a href="http://jboss.org/jopr"> <h:graphicImage + value="/images/logo_icon.png" style="vertical-align:middle" /> Jopr + Project </a> ui:remove + <!--<h:outputText value="#{msg['about.MoreInfo.Label']}"/><br/>--> + <!-- <a href='mailto:<h:outputText value="#{msg['about.MoreInfo.LinkSales']}"/>'><h:outputText value="#{msg['about.MoreInfo.LinkSales']}"/></a><br/> <a href='mailto:<h:outputText value="#{msg['about.MoreInfo.LinkSupport']}"/>'><h:outputText value="#{msg['about.MoreInfo.LinkSupport']}"/></a> --> - </ui:remove> - </p> + </ui:remove></p>
- <input type="button" value="Close" onclick="Richfaces.hideModalPanel('aboutPanel');"/> -</rich:modalPanel> + <input type="button" value="Close" + onclick="Richfaces.hideModalPanel('aboutPanel');" /> + </rich:modalPanel>
-</h:form> + </h:form>
-<a4j:region renderRegionOnly="true" selfRendered="true"> + <a4j:region renderRegionOnly="true" selfRendered="true">
- <script type="text/javascript"> + <script type="text/javascript">
function refresh() {
@@ -586,14 +664,15 @@ v <rich:menuItem submitMode="none"
</script>
- a4j:form - <a4j:jsFunction name="updatePageRefresh" status="commonStatus" oncomplete="window.location.href = window.location.href;"> - <a4j:actionparam name="param1" assignTo="#{UserPreferencesUIBean.refreshPath}"/> - <a4j:actionparam name="param2" assignTo="#{UserPreferencesUIBean.pageRefresh}"/> - </a4j:jsFunction> - </a4j:form> -</a4j:region> - + a4j:form + <a4j:jsFunction name="updatePageRefresh" status="commonStatus" + oncomplete="window.location.href = window.location.href;"> + <a4j:actionparam name="param1" + assignTo="#{UserPreferencesUIBean.refreshPath}" /> + <a4j:actionparam name="param2" + assignTo="#{UserPreferencesUIBean.pageRefresh}" /> + </a4j:jsFunction> + </a4j:form> + </a4j:region>
- -</a4j:region> \ No newline at end of file +</a4j:region>
commit d1a2a241b6b03266f6428114ad3a9f7cf0529a24 Merge: 56988b9... 1da8898... Author: Adam Young ayoung@redhat.com Date: Fri Nov 13 12:12:29 2009 -0500
Merge branch 'raw-config' of ssh://git.fedorahosted.org/git/rhq/rhq into raw-config
commit 1da8898bf229d096c24ada94c022e51e2fca43ce Author: John Sanda john@localhost.localdomain Date: Fri Nov 13 12:11:27 2009 -0500
Updating pom to include dependencies in the packaged plugin
diff --git a/modules/plugins/raw-config-test/pom.xml b/modules/plugins/raw-config-test/pom.xml index ee22542..a55bfbc 100644 --- a/modules/plugins/raw-config-test/pom.xml +++ b/modules/plugins/raw-config-test/pom.xml @@ -29,7 +29,7 @@ <dependency> <groupId>commons-configuration</groupId> <artifactId>commons-configuration</artifactId> - <version>1.1</version> + <version>1.6</version> </dependency> </dependencies>
@@ -77,7 +77,32 @@ <artifactItem> <groupId>commons-configuration</groupId> <artifactId>commons-configuration</artifactId> - <version>1.1</version> + <version>1.6</version> + </artifactItem> + <artifactItem> + <groupId>commons-collections</groupId> + <artifactId>commons-collections</artifactId> + <version>3.2.1</version> + </artifactItem> + <artifactItem> + <groupId>commons-lang</groupId> + <artifactId>commons-lang</artifactId> + <version>2.4</version> + </artifactItem> + <artifactItem> + <groupId>commons-logging</groupId> + <artifactId>commons-logging</artifactId> + <version>1.1.1</version> + </artifactItem> + <artifactItem> + <groupId>commons-digester</groupId> + <artifactId>commons-digester</artifactId> + <version>1.8</version> + </artifactItem> + <artifactItem> + <groupId>commons-beanutils</groupId> + <artifactId>commons-beanutils-core</artifactId> + <version>1.8.0</version> </artifactItem> </artifactItems> <outputDirectory>${project.build.outputDirectory}/lib</outputDirectory>
commit 1e103c54d9e6b020fe28448a12a7a459d46735fa Merge: cd1b905... 5bdcb13... Author: Jay Shaughnessy jshaughn@redhat.com Date: Fri Nov 13 10:46:40 2009 -0500
Fixing merge issues
commit 56988b92b5a09a7b10c95e4daa73fd165e4b3c2d Merge: 8fcbc7f... 01eb63f... Author: Adam Young ayoung@redhat.com Date: Fri Nov 13 09:54:16 2009 -0500
Merge branch 'raw-config' of ssh://git.fedorahosted.org/git/rhq/rhq into raw-config
commit cd1b905ef439166be474e10150ee8598e65dc770 Author: Jay Shaughnessy jshaughn@redhat.com Date: Fri Nov 13 09:16:16 2009 -0500
Added the first pass at a PerspectiveServerPluginContainer/manager to handle perspective deployment. Added sample perspective to replace the hardwired sample war used by the current poc "custom" tab in the resource view of the UI. The sample perspective lives under rhq/etc/samples/perspectives and is currently added to the build. It is deployed automatically along with the content plugins. Removed the previous hardwiring of teh sample perspective war.
diff --git a/etc/samples/perspectives/sample-perspective/app/pom.xml b/etc/samples/perspectives/sample-perspective/app/pom.xml new file mode 100644 index 0000000..acf9d67 --- /dev/null +++ b/etc/samples/perspectives/sample-perspective/app/pom.xml @@ -0,0 +1,143 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.rhq</groupId> + <artifactId>rhq-parent</artifactId> + <version>1.4.0-SNAPSHOT</version> + </parent> + + <groupId>org.rhq</groupId> + <artifactId>rhq-sample-perspective-war</artifactId> + <packaging>war</packaging> + + <name>RHQ Sample Perspective War</name> + + <scm> + <connection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/etc/samples/sample-perspective/app/</connection> + <developerConnection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/etc/samples/sample-perspective/app/</developerConnection> + </scm> + + <properties> + <scm.module.path>modules/enterprise/gui/perspectives/sample-perspective-war/</scm.module.path> + <war.dir>${basedir}/target/${final.name}</war.dir> + </properties> + + <dependencies> + + </dependencies> + + <build> + <finalName>rhq-sample-perspective</finalName> + + <plugins> + + <plugin> + <artifactId>maven-war-plugin</artifactId> + <configuration> + <archive> + <manifest> + <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries> + <addDefaultImplementationEntries>true</addDefaultImplementationEntries> + </manifest> + <manifestEntries> + <Build-Number>${buildNumber}</Build-Number> + </manifestEntries> + </archive> + <webResources> + <resource> + <filtering>true</filtering> + <directory>${basedir}/src/main/webapp</directory> + <includes> + <include>**/*.properties</include> + </includes> + </resource> + </webResources> + </configuration> + </plugin> + + </plugins> + + </build> + + <profiles> + + <profile> + <id>dev</id> + + <properties> + <rhq.rootDir>../../../..</rhq.rootDir> + <rhq.containerDir>${rhq.rootDir}/${rhq.defaultDevContainerPath}</rhq.containerDir> + <rhq.deploymentName>${project.build.finalName}.war</rhq.deploymentName> + <rhq.deploymentDir>${rhq.containerDir}/jbossas/server/default/deploy/${rhq.deploymentName}</rhq.deploymentDir> + </properties> + + <build> + <plugins> + + <plugin> + <artifactId>maven-antrun-plugin</artifactId> + <version>1.1</version> + <executions> + + <execution> + <id>deploy-classes</id> + <phase>compile</phase> + <configuration> + <tasks> + <property name="classes.dir" location="${rhq.deploymentDir}/WEB-INF/classes" /> + <echo>*** Copying updated files from target/classes to ${classes.dir}...</echo> + <copy todir="${classes.dir}" failonerror="false" verbose="${rhq.verbose}"> + <fileset dir="target/classes" /> + </copy> + </tasks> + </configuration> + <goals> + <goal>run</goal> + </goals> + </execution> + + <execution> + <id>deploy</id> + <phase>package</phase> + <configuration> + <tasks> + <property name="deployment.dir" location="${rhq.deploymentDir}" /> + <echo>*** Copying updated files from target${file.separator}${project.build.finalName}${file.separator} to ${deployment.dir}${file.separator}...</echo> + <copy todir="${deployment.dir}" verbose="${rhq.verbose}"> + <fileset dir="${basedir}/target/${project.build.finalName}" /> + </copy> + <delete dir="${deployment.dir}.rej" /> <!-- need to remove any residual backups --> + </tasks> + </configuration> + <goals> + <goal>run</goal> + </goals> + </execution> + + <execution> + <id>undeploy</id> + <phase>clean</phase> + <configuration> + <tasks> + <property name="deployment.dir" location="${rhq.deploymentDir}" /> + <echo>*** Deleting ${deployment.dir}${file.separator}...</echo> + <delete dir="${deployment.dir}" /> + </tasks> + </configuration> + <goals> + <goal>run</goal> + </goals> + </execution> + + </executions> + </plugin> + + </plugins> + </build> + </profile> + + </profiles> + +</project> \ No newline at end of file diff --git a/etc/samples/perspectives/sample-perspective/app/src/main/webapp/WEB-INF/web.xml b/etc/samples/perspectives/sample-perspective/app/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000..a1968e1 --- /dev/null +++ b/etc/samples/perspectives/sample-perspective/app/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<!DOCTYPE web-app + PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" + "http://java.sun.com/dtd/web-app_2_3.dtd"> + +<web-app> + <display-name>Welcome to Foo!</display-name> + <welcome-file-list> + <welcome-file>index.html</welcome-file> + </welcome-file-list> +</web-app> diff --git a/etc/samples/perspectives/sample-perspective/app/src/main/webapp/index.html b/etc/samples/perspectives/sample-perspective/app/src/main/webapp/index.html new file mode 100644 index 0000000..8bc586a --- /dev/null +++ b/etc/samples/perspectives/sample-perspective/app/src/main/webapp/index.html @@ -0,0 +1,14 @@ +<script type="text/javascript"> + //document.domain = "redhat.com"; +</script> + +<!-- Force the page to be taller than the height of the browser + to test that a vertical scrollbar is not added to the + enclosing iframe. --> +<div style="padding: 10px; background-color: #DDF; height: 1000px;"> + <h4>It's always good to see something from another perspective.</h4> + + <p>The blue portion of this page is an IFRAME whose content was + loaded from rhq-sample-perspective.war, a WAR deployed to the + RHQ Server, as a sibling of rhq.ear.</p> +</div> diff --git a/etc/samples/perspectives/sample-perspective/perspective/pom.xml b/etc/samples/perspectives/sample-perspective/perspective/pom.xml new file mode 100644 index 0000000..9674697 --- /dev/null +++ b/etc/samples/perspectives/sample-perspective/perspective/pom.xml @@ -0,0 +1,105 @@ +<?xml version="1.0"?> + +<project + xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd%22%3E + + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.rhq</groupId> + <artifactId>rhq-parent</artifactId> + <version>1.4.0-SNAPSHOT</version> + </parent> + + <groupId>org.rhq</groupId> + <artifactId>rhq-sample-perspective</artifactId> + <packaging>jar</packaging> + + <name>RHQ Sample Perspective</name> + <description>A Sample Perspective showing extension points and filters</description> + + <properties> + <rhq.version>1.4.0-SNAPSHOT</rhq.version> + </properties> + + <dependencies> + + <!-- Below are the apps packaged with this perspective plugin --> + <dependency> + <groupId>org.rhq</groupId> + <artifactId>rhq-sample-perspective-war</artifactId> + <version>${rhq.version}</version> + <scope>provided</scope> + <type>war</type> + </dependency> + + <!-- Below are the core modules that are required dependencies of all server plugins --> + <dependency> + <groupId>org.rhq</groupId> + <artifactId>rhq-enterprise-server</artifactId> + <version>${rhq.version}</version> + <scope>provided</scope> <!-- provided by the server/plugin-container --> + </dependency> + + <!-- uncomment the one of the three logging systems your plugin uses: log4j, commons-logging or i18nlog --> + <!-- all three are provided to your plugin by the server/plugin-container --> + <!-- + <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.14</version> + <scope>provided</scope> </dependency> + --> + + <!-- + <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.1</version> + <scope>provided</scope> </dependency> + --> + + <!-- + <dependency> <groupId>i18nlog</groupId> <artifactId>i18nlog</artifactId> <version>1.0.9</version> </dependency> + --> + + <!-- Define any third-party dependencies your plugin has here. --> + <!-- + <dependency> <groupId>group-id-of-dependency-goes-here</groupId> + <artifactId>artifact-id-of-dependency-goes-here</artifactId> <version>version-of-dependency-goes-here</version> + </dependency> + --> + + </dependencies> + + <build> + <finalName>${project.artifactId}</finalName> + + <plugins> + + <plugin> + <artifactId>maven-antrun-plugin</artifactId> + <version>1.1</version> + <executions> + + <execution> + <id>add-war</id> + <phase>verify</phase> + <configuration> + <tasks> + <property + name="classes.dir" + location="${rhq.deploymentDir}/WEB-INF/classes" /> + <jar + update="yes" + destfile="${basedir}/target/${project.build.finalName}.jar" + basedir="${basedir}/../app/target" + includes="*.war" /> + </tasks> + </configuration> + <goals> + <goal>run</goal> + </goals> + </execution> + </executions> + </plugin> + </plugins> + </build> + +</project> diff --git a/etc/samples/perspectives/sample-perspective/perspective/src/main/resources/META-INF/rhq-serverplugin.xml b/etc/samples/perspectives/sample-perspective/perspective/src/main/resources/META-INF/rhq-serverplugin.xml new file mode 100644 index 0000000..490ae03 --- /dev/null +++ b/etc/samples/perspectives/sample-perspective/perspective/src/main/resources/META-INF/rhq-serverplugin.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<perspective-plugin + apiVersion="1.0" + version="1.0" + description="A Sample Perspective Utilizing Every Extension Point and Filter" + displayName="Sample Perspective" + name="SamplePerspective" + package="org.rhq.perspective.sample" + xmlns="urn:xmlns:rhq-serverplugin.perspective" + xmlns:serverplugin="urn:xmlns:rhq-serverplugin" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance%22%3E + +</perspective-plugin> \ No newline at end of file diff --git a/etc/samples/perspectives/sample-perspective/pom.xml b/etc/samples/perspectives/sample-perspective/pom.xml new file mode 100644 index 0000000..50372f1 --- /dev/null +++ b/etc/samples/perspectives/sample-perspective/pom.xml @@ -0,0 +1,45 @@ +<project + xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd%22%3E + + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.rhq</groupId> + <artifactId>rhq-parent</artifactId> + <version>1.4.0-SNAPSHOT</version> + </parent> + + <groupId>org.rhq</groupId> + <artifactId>rhq-sample-perspective-parent</artifactId> + <packaging>pom</packaging> + + <name>RHQ Sample Perspective Parent</name> + <description>parent POM for modules comprising the RHQ Sample Perspective</description> + + <scm> + <connection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/etc/samples/sample-perspective/</connection> + <developerConnection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/etc/samples/sample-perspective/</developerConnection> + </scm> + + <properties> + <scm.module.path>etc/samples/sample-perspective/</scm.module.path> + </properties> + + <profiles> + + <profile> + <id>default</id> + <activation> + <activeByDefault>true</activeByDefault> + </activation> + <modules> + <module>app</module> + <module>perspective</module> + </modules> + </profile> + + </profiles> + +</project> \ No newline at end of file diff --git a/etc/samples/sample-perspective/app/pom.xml b/etc/samples/sample-perspective/app/pom.xml deleted file mode 100644 index acf9d67..0000000 --- a/etc/samples/sample-perspective/app/pom.xml +++ /dev/null @@ -1,143 +0,0 @@ -<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> - - <modelVersion>4.0.0</modelVersion> - - <parent> - <groupId>org.rhq</groupId> - <artifactId>rhq-parent</artifactId> - <version>1.4.0-SNAPSHOT</version> - </parent> - - <groupId>org.rhq</groupId> - <artifactId>rhq-sample-perspective-war</artifactId> - <packaging>war</packaging> - - <name>RHQ Sample Perspective War</name> - - <scm> - <connection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/etc/samples/sample-perspective/app/</connection> - <developerConnection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/etc/samples/sample-perspective/app/</developerConnection> - </scm> - - <properties> - <scm.module.path>modules/enterprise/gui/perspectives/sample-perspective-war/</scm.module.path> - <war.dir>${basedir}/target/${final.name}</war.dir> - </properties> - - <dependencies> - - </dependencies> - - <build> - <finalName>rhq-sample-perspective</finalName> - - <plugins> - - <plugin> - <artifactId>maven-war-plugin</artifactId> - <configuration> - <archive> - <manifest> - <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries> - <addDefaultImplementationEntries>true</addDefaultImplementationEntries> - </manifest> - <manifestEntries> - <Build-Number>${buildNumber}</Build-Number> - </manifestEntries> - </archive> - <webResources> - <resource> - <filtering>true</filtering> - <directory>${basedir}/src/main/webapp</directory> - <includes> - <include>**/*.properties</include> - </includes> - </resource> - </webResources> - </configuration> - </plugin> - - </plugins> - - </build> - - <profiles> - - <profile> - <id>dev</id> - - <properties> - <rhq.rootDir>../../../..</rhq.rootDir> - <rhq.containerDir>${rhq.rootDir}/${rhq.defaultDevContainerPath}</rhq.containerDir> - <rhq.deploymentName>${project.build.finalName}.war</rhq.deploymentName> - <rhq.deploymentDir>${rhq.containerDir}/jbossas/server/default/deploy/${rhq.deploymentName}</rhq.deploymentDir> - </properties> - - <build> - <plugins> - - <plugin> - <artifactId>maven-antrun-plugin</artifactId> - <version>1.1</version> - <executions> - - <execution> - <id>deploy-classes</id> - <phase>compile</phase> - <configuration> - <tasks> - <property name="classes.dir" location="${rhq.deploymentDir}/WEB-INF/classes" /> - <echo>*** Copying updated files from target/classes to ${classes.dir}...</echo> - <copy todir="${classes.dir}" failonerror="false" verbose="${rhq.verbose}"> - <fileset dir="target/classes" /> - </copy> - </tasks> - </configuration> - <goals> - <goal>run</goal> - </goals> - </execution> - - <execution> - <id>deploy</id> - <phase>package</phase> - <configuration> - <tasks> - <property name="deployment.dir" location="${rhq.deploymentDir}" /> - <echo>*** Copying updated files from target${file.separator}${project.build.finalName}${file.separator} to ${deployment.dir}${file.separator}...</echo> - <copy todir="${deployment.dir}" verbose="${rhq.verbose}"> - <fileset dir="${basedir}/target/${project.build.finalName}" /> - </copy> - <delete dir="${deployment.dir}.rej" /> <!-- need to remove any residual backups --> - </tasks> - </configuration> - <goals> - <goal>run</goal> - </goals> - </execution> - - <execution> - <id>undeploy</id> - <phase>clean</phase> - <configuration> - <tasks> - <property name="deployment.dir" location="${rhq.deploymentDir}" /> - <echo>*** Deleting ${deployment.dir}${file.separator}...</echo> - <delete dir="${deployment.dir}" /> - </tasks> - </configuration> - <goals> - <goal>run</goal> - </goals> - </execution> - - </executions> - </plugin> - - </plugins> - </build> - </profile> - - </profiles> - -</project> \ No newline at end of file diff --git a/etc/samples/sample-perspective/app/src/main/webapp/WEB-INF/web.xml b/etc/samples/sample-perspective/app/src/main/webapp/WEB-INF/web.xml deleted file mode 100644 index a1968e1..0000000 --- a/etc/samples/sample-perspective/app/src/main/webapp/WEB-INF/web.xml +++ /dev/null @@ -1,12 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> - -<!DOCTYPE web-app - PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" - "http://java.sun.com/dtd/web-app_2_3.dtd"> - -<web-app> - <display-name>Welcome to Foo!</display-name> - <welcome-file-list> - <welcome-file>index.html</welcome-file> - </welcome-file-list> -</web-app> diff --git a/etc/samples/sample-perspective/app/src/main/webapp/index.html b/etc/samples/sample-perspective/app/src/main/webapp/index.html deleted file mode 100644 index 8bc586a..0000000 --- a/etc/samples/sample-perspective/app/src/main/webapp/index.html +++ /dev/null @@ -1,14 +0,0 @@ -<script type="text/javascript"> - //document.domain = "redhat.com"; -</script> - -<!-- Force the page to be taller than the height of the browser - to test that a vertical scrollbar is not added to the - enclosing iframe. --> -<div style="padding: 10px; background-color: #DDF; height: 1000px;"> - <h4>It's always good to see something from another perspective.</h4> - - <p>The blue portion of this page is an IFRAME whose content was - loaded from rhq-sample-perspective.war, a WAR deployed to the - RHQ Server, as a sibling of rhq.ear.</p> -</div> diff --git a/etc/samples/sample-perspective/perspective/pom.xml b/etc/samples/sample-perspective/perspective/pom.xml deleted file mode 100644 index 9674697..0000000 --- a/etc/samples/sample-perspective/perspective/pom.xml +++ /dev/null @@ -1,105 +0,0 @@ -<?xml version="1.0"?> - -<project - xmlns="http://maven.apache.org/POM/4.0.0" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd%22%3E - - <modelVersion>4.0.0</modelVersion> - - <parent> - <groupId>org.rhq</groupId> - <artifactId>rhq-parent</artifactId> - <version>1.4.0-SNAPSHOT</version> - </parent> - - <groupId>org.rhq</groupId> - <artifactId>rhq-sample-perspective</artifactId> - <packaging>jar</packaging> - - <name>RHQ Sample Perspective</name> - <description>A Sample Perspective showing extension points and filters</description> - - <properties> - <rhq.version>1.4.0-SNAPSHOT</rhq.version> - </properties> - - <dependencies> - - <!-- Below are the apps packaged with this perspective plugin --> - <dependency> - <groupId>org.rhq</groupId> - <artifactId>rhq-sample-perspective-war</artifactId> - <version>${rhq.version}</version> - <scope>provided</scope> - <type>war</type> - </dependency> - - <!-- Below are the core modules that are required dependencies of all server plugins --> - <dependency> - <groupId>org.rhq</groupId> - <artifactId>rhq-enterprise-server</artifactId> - <version>${rhq.version}</version> - <scope>provided</scope> <!-- provided by the server/plugin-container --> - </dependency> - - <!-- uncomment the one of the three logging systems your plugin uses: log4j, commons-logging or i18nlog --> - <!-- all three are provided to your plugin by the server/plugin-container --> - <!-- - <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.14</version> - <scope>provided</scope> </dependency> - --> - - <!-- - <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.1</version> - <scope>provided</scope> </dependency> - --> - - <!-- - <dependency> <groupId>i18nlog</groupId> <artifactId>i18nlog</artifactId> <version>1.0.9</version> </dependency> - --> - - <!-- Define any third-party dependencies your plugin has here. --> - <!-- - <dependency> <groupId>group-id-of-dependency-goes-here</groupId> - <artifactId>artifact-id-of-dependency-goes-here</artifactId> <version>version-of-dependency-goes-here</version> - </dependency> - --> - - </dependencies> - - <build> - <finalName>${project.artifactId}</finalName> - - <plugins> - - <plugin> - <artifactId>maven-antrun-plugin</artifactId> - <version>1.1</version> - <executions> - - <execution> - <id>add-war</id> - <phase>verify</phase> - <configuration> - <tasks> - <property - name="classes.dir" - location="${rhq.deploymentDir}/WEB-INF/classes" /> - <jar - update="yes" - destfile="${basedir}/target/${project.build.finalName}.jar" - basedir="${basedir}/../app/target" - includes="*.war" /> - </tasks> - </configuration> - <goals> - <goal>run</goal> - </goals> - </execution> - </executions> - </plugin> - </plugins> - </build> - -</project> diff --git a/etc/samples/sample-perspective/perspective/src/main/resources/META-INF/rhq-serverplugin.xml b/etc/samples/sample-perspective/perspective/src/main/resources/META-INF/rhq-serverplugin.xml deleted file mode 100644 index 490ae03..0000000 --- a/etc/samples/sample-perspective/perspective/src/main/resources/META-INF/rhq-serverplugin.xml +++ /dev/null @@ -1,14 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> - -<perspective-plugin - apiVersion="1.0" - version="1.0" - description="A Sample Perspective Utilizing Every Extension Point and Filter" - displayName="Sample Perspective" - name="SamplePerspective" - package="org.rhq.perspective.sample" - xmlns="urn:xmlns:rhq-serverplugin.perspective" - xmlns:serverplugin="urn:xmlns:rhq-serverplugin" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance%22%3E - -</perspective-plugin> \ No newline at end of file diff --git a/etc/samples/sample-perspective/pom.xml b/etc/samples/sample-perspective/pom.xml deleted file mode 100644 index 50372f1..0000000 --- a/etc/samples/sample-perspective/pom.xml +++ /dev/null @@ -1,45 +0,0 @@ -<project - xmlns="http://maven.apache.org/POM/4.0.0" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd%22%3E - - <modelVersion>4.0.0</modelVersion> - - <parent> - <groupId>org.rhq</groupId> - <artifactId>rhq-parent</artifactId> - <version>1.4.0-SNAPSHOT</version> - </parent> - - <groupId>org.rhq</groupId> - <artifactId>rhq-sample-perspective-parent</artifactId> - <packaging>pom</packaging> - - <name>RHQ Sample Perspective Parent</name> - <description>parent POM for modules comprising the RHQ Sample Perspective</description> - - <scm> - <connection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/etc/samples/sample-perspective/</connection> - <developerConnection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/etc/samples/sample-perspective/</developerConnection> - </scm> - - <properties> - <scm.module.path>etc/samples/sample-perspective/</scm.module.path> - </properties> - - <profiles> - - <profile> - <id>default</id> - <activation> - <activeByDefault>true</activeByDefault> - </activation> - <modules> - <module>app</module> - <module>perspective</module> - </modules> - </profile> - - </profiles> - -</project> \ No newline at end of file diff --git a/modules/enterprise/gui/perspectives/pom.xml b/modules/enterprise/gui/perspectives/pom.xml deleted file mode 100644 index 3ff4835..0000000 --- a/modules/enterprise/gui/perspectives/pom.xml +++ /dev/null @@ -1,33 +0,0 @@ -<project xmlns="http://maven.apache.org/POM/4.0.0" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd%22%3E - - <modelVersion>4.0.0</modelVersion> - - <parent> - <groupId>org.rhq</groupId> - <artifactId>rhq-parent</artifactId> - <version>1.4.0-SNAPSHOT</version> - </parent> - - <groupId>org.rhq</groupId> - <artifactId>rhq-enterprise-gui-perspectives-parent</artifactId> - <packaging>pom</packaging> - - <name>RHQ Enterprise GUI Perspectives</name> - <description>parent POM for perspective modules for the RHQ enterprise GUI</description> - - <scm> - <connection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/modules/enterprise/gui/perspectives/</connection> - <developerConnection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/modules/enterprise/gui/perspectives/</developerConnection> - </scm> - - <properties> - <scm.module.path>modules/enterprise/gui/perspectives/</scm.module.path> - </properties> - - <modules> - <module>sample-perspective-war</module> - </modules> - -</project> diff --git a/modules/enterprise/gui/perspectives/sample-perspective-war/pom.xml b/modules/enterprise/gui/perspectives/sample-perspective-war/pom.xml deleted file mode 100644 index c653fef..0000000 --- a/modules/enterprise/gui/perspectives/sample-perspective-war/pom.xml +++ /dev/null @@ -1,143 +0,0 @@ -<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> - - <modelVersion>4.0.0</modelVersion> - - <parent> - <groupId>org.rhq</groupId> - <artifactId>rhq-parent</artifactId> - <version>1.4.0-SNAPSHOT</version> - </parent> - - <groupId>org.rhq</groupId> - <artifactId>rhq-sample-perspective</artifactId> - <packaging>war</packaging> - - <name>Sample RHQ Perspective War</name> - - <scm> - <connection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/modules/enterprise/gui/perspectives/sample-perspective-war/</connection> - <developerConnection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/modules/enterprise/gui/perspectives/sample-perspective-war/</developerConnection> - </scm> - - <properties> - <scm.module.path>modules/enterprise/gui/perspectives/sample-perspective-war/</scm.module.path> - <war.dir>${basedir}/target/${final.name}</war.dir> - </properties> - - <dependencies> - - </dependencies> - - <build> - <finalName>${project.artifactId}</finalName> - - <plugins> - - <plugin> - <artifactId>maven-war-plugin</artifactId> - <configuration> - <archive> - <manifest> - <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries> - <addDefaultImplementationEntries>true</addDefaultImplementationEntries> - </manifest> - <manifestEntries> - <Build-Number>${buildNumber}</Build-Number> - </manifestEntries> - </archive> - <webResources> - <resource> - <filtering>true</filtering> - <directory>${basedir}/src/main/webapp</directory> - <includes> - <include>**/*.properties</include> - </includes> - </resource> - </webResources> - </configuration> - </plugin> - - </plugins> - - </build> - - <profiles> - - <profile> - <id>dev</id> - - <properties> - <rhq.rootDir>../../../..</rhq.rootDir> - <rhq.containerDir>${rhq.rootDir}/${rhq.defaultDevContainerPath}</rhq.containerDir> - <rhq.deploymentName>${project.build.finalName}.war</rhq.deploymentName> - <rhq.deploymentDir>${rhq.containerDir}/jbossas/server/default/deploy/${rhq.deploymentName}</rhq.deploymentDir> - </properties> - - <build> - <plugins> - - <plugin> - <artifactId>maven-antrun-plugin</artifactId> - <version>1.1</version> - <executions> - - <execution> - <id>deploy-classes</id> - <phase>compile</phase> - <configuration> - <tasks> - <property name="classes.dir" location="${rhq.deploymentDir}/WEB-INF/classes" /> - <echo>*** Copying updated files from target/classes to ${classes.dir}...</echo> - <copy todir="${classes.dir}" failonerror="false" verbose="${rhq.verbose}"> - <fileset dir="target/classes" /> - </copy> - </tasks> - </configuration> - <goals> - <goal>run</goal> - </goals> - </execution> - - <execution> - <id>deploy</id> - <phase>package</phase> - <configuration> - <tasks> - <property name="deployment.dir" location="${rhq.deploymentDir}" /> - <echo>*** Copying updated files from target${file.separator}${project.build.finalName}${file.separator} to ${deployment.dir}${file.separator}...</echo> - <copy todir="${deployment.dir}" verbose="${rhq.verbose}"> - <fileset dir="${basedir}/target/${project.build.finalName}" /> - </copy> - <delete dir="${deployment.dir}.rej" /> <!-- need to remove any residual backups --> - </tasks> - </configuration> - <goals> - <goal>run</goal> - </goals> - </execution> - - <execution> - <id>undeploy</id> - <phase>clean</phase> - <configuration> - <tasks> - <property name="deployment.dir" location="${rhq.deploymentDir}" /> - <echo>*** Deleting ${deployment.dir}${file.separator}...</echo> - <delete dir="${deployment.dir}" /> - </tasks> - </configuration> - <goals> - <goal>run</goal> - </goals> - </execution> - - </executions> - </plugin> - - </plugins> - </build> - </profile> - - </profiles> - -</project> \ No newline at end of file diff --git a/modules/enterprise/gui/perspectives/sample-perspective-war/src/main/webapp/WEB-INF/web.xml b/modules/enterprise/gui/perspectives/sample-perspective-war/src/main/webapp/WEB-INF/web.xml deleted file mode 100644 index a1968e1..0000000 --- a/modules/enterprise/gui/perspectives/sample-perspective-war/src/main/webapp/WEB-INF/web.xml +++ /dev/null @@ -1,12 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> - -<!DOCTYPE web-app - PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" - "http://java.sun.com/dtd/web-app_2_3.dtd"> - -<web-app> - <display-name>Welcome to Foo!</display-name> - <welcome-file-list> - <welcome-file>index.html</welcome-file> - </welcome-file-list> -</web-app> diff --git a/modules/enterprise/gui/perspectives/sample-perspective-war/src/main/webapp/index.html b/modules/enterprise/gui/perspectives/sample-perspective-war/src/main/webapp/index.html deleted file mode 100644 index 8bc586a..0000000 --- a/modules/enterprise/gui/perspectives/sample-perspective-war/src/main/webapp/index.html +++ /dev/null @@ -1,14 +0,0 @@ -<script type="text/javascript"> - //document.domain = "redhat.com"; -</script> - -<!-- Force the page to be taller than the height of the browser - to test that a vertical scrollbar is not added to the - enclosing iframe. --> -<div style="padding: 10px; background-color: #DDF; height: 1000px;"> - <h4>It's always good to see something from another perspective.</h4> - - <p>The blue portion of this page is an IFRAME whose content was - loaded from rhq-sample-perspective.war, a WAR deployed to the - RHQ Server, as a sibling of rhq.ear.</p> -</div> diff --git a/modules/enterprise/gui/pom.xml b/modules/enterprise/gui/pom.xml index a038122..ea3588d 100644 --- a/modules/enterprise/gui/pom.xml +++ b/modules/enterprise/gui/pom.xml @@ -34,8 +34,7 @@ <modules> <module>portal-war</module> <module>installer-war</module> - <module>webdav-war</module> - <!-- <module>perspectives</module> --> + <module>webdav-war</module> </modules> </profile>
diff --git a/modules/enterprise/server/container/pom.xml b/modules/enterprise/server/container/pom.xml index 8494dd2..a4c6d40 100644 --- a/modules/enterprise/server/container/pom.xml +++ b/modules/enterprise/server/container/pom.xml @@ -45,14 +45,11 @@ <version>${project.version}</version> </dependency>
- <!-- Remove this as we now deploy the sample perspective manually <dependency> <groupId>org.rhq</groupId> <artifactId>rhq-sample-perspective</artifactId> <version>${project.version}</version> - <type>war</type> </dependency> - -->
<!-- 3rd Party Deps -->
diff --git a/modules/enterprise/server/container/src/main/scripts/rhq-container.build.xml b/modules/enterprise/server/container/src/main/scripts/rhq-container.build.xml index f52bc69..4eaa7ec 100644 --- a/modules/enterprise/server/container/src/main/scripts/rhq-container.build.xml +++ b/modules/enterprise/server/container/src/main/scripts/rhq-container.build.xml @@ -400,13 +400,6 @@ </fileset> </move>
- <!-- don't do this now that we have a sample perspective to deploy - <echo>Deploying perspective WARs ...</echo> - <mkdir dir="${jboss.deploy.dir}/rhq-sample-perspective.war" /> - <unwar src="${settings.localRepository}/org/rhq/rhq-sample-perspective/${rhq.version}/rhq-sample-perspective-${rhq.version}.war" - dest="${jboss.deploy.dir}/rhq-sample-perspective.war" /> - --> - </target>
<target name="package-connectors" if="package-connectors"> diff --git a/modules/enterprise/server/ear/pom.xml b/modules/enterprise/server/ear/pom.xml index 7308abb..ac874e9 100644 --- a/modules/enterprise/server/ear/pom.xml +++ b/modules/enterprise/server/ear/pom.xml @@ -399,6 +399,13 @@ <version>${project.version}</version> </artifactItem>
+ <!-- Temporary Sample Perspective --> + <artifactItem> + <groupId>org.rhq</groupId> + <artifactId>rhq-sample-perspective</artifactId> + <version>${project.version}</version> + </artifactItem> + </artifactItems> <outputDirectory>${earDirectory}/rhq-serverplugins</outputDirectory> </configuration> diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginManager.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginManager.java index 70cd665..d2401e6 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginManager.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginManager.java @@ -303,7 +303,8 @@ public class ServerPluginManager { try { ConfigurationDefinition configDef = ConfigurationMetadataParser.parse(pluginName, pluginDescriptor .getPluginConfiguration()); - config = configDef.getDefaultTemplate().createConfiguration(); + + config = (null == configDef) ? null : configDef.getDefaultTemplate().createConfiguration(); } catch (InvalidPluginDescriptorException e) { // TODO Auto-generated catch block e.printStackTrace(); diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/perspective/PerspectiveServerPluginContainer.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/perspective/PerspectiveServerPluginContainer.java index 01f5ced..355e023 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/perspective/PerspectiveServerPluginContainer.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/perspective/PerspectiveServerPluginContainer.java @@ -19,21 +19,9 @@
package org.rhq.enterprise.server.plugin.pc.perspective;
-import java.io.File; -import java.io.InputStream; -import java.util.Collections; -import java.util.jar.JarEntry; -import java.util.jar.JarFile; - -import javax.management.MBeanServerConnection; -import javax.management.ObjectName; -import javax.naming.Context; -import javax.naming.InitialContext; - -import org.rhq.core.util.file.FileUtil; import org.rhq.enterprise.server.plugin.pc.AbstractTypeServerPluginContainer; import org.rhq.enterprise.server.plugin.pc.MasterServerPluginContainer; -import org.rhq.enterprise.server.plugin.pc.ServerPluginEnvironment; +import org.rhq.enterprise.server.plugin.pc.ServerPluginManager; import org.rhq.enterprise.server.plugin.pc.ServerPluginType; import org.rhq.enterprise.server.xmlschema.generated.serverplugin.perspective.PerspectivePluginDescriptorType;
@@ -54,113 +42,9 @@ public class PerspectiveServerPluginContainer extends AbstractTypeServerPluginCo return new ServerPluginType(PerspectivePluginDescriptorType.class); }
- /* At load-time ensure that any WAR files packaged with the server plugin are deployed to the RHQ - * Server. Note, perspective apps are logically deployed along-side, not inside the rhq.ear (although physically - * under the default/work). They should have access to the same shared components. - * - * @see org.rhq.enterprise.server.plugin.pc.AbstractTypeServerPluginContainer#loadPlugin(org.rhq.enterprise.server.plugin.pc.ServerPluginEnvironment) - */ @Override - public synchronized void loadPlugin(ServerPluginEnvironment env) throws Exception { - String name = null; - try { - JarFile plugin = new JarFile(env.getPluginUrl().getFile()); - for (JarEntry entry : Collections.list(plugin.entries())) { - name = entry.getName(); - if (name.toLowerCase().endsWith(".war")) { - deployWar(entry.getName(), plugin.getInputStream(entry)); - } - } - } catch (Exception e) { - getLog().error("Failed to deploy " + env.getPluginName() + "#" + name, e); - } - - super.loadPlugin(env); - } - - private void deployWar(String name, InputStream iStream) { - try { - // Save the war file to a temp area - File tempFile = writeWarToTempFile(name, iStream); - - // get reference to MBean server - Context ic = new InitialContext(); - MBeanServerConnection server = (MBeanServerConnection) ic.lookup("jmx/invoker/RMIAdaptor"); - - // get reference to MainDeployer MBean - ObjectName mainDeployer = new ObjectName("jboss.system:service=MainDeployer"); - - server.invoke(mainDeployer, "deploy", new Object[] { tempFile.getAbsolutePath() }, - new String[] { String.class.getName() }); - } catch (Exception e) { - e.printStackTrace(); - } - } - - private File writeWarToTempFile(String name, InputStream iStream) throws Exception { - - File tempDir = new File(System.getProperty("java.io.tmpdir")); - File tempFile = new File(tempDir.getAbsolutePath(), name); - - // Delete any previous instance of the file - if (tempFile.exists()) { - getLog().debug("Existing temporary file found and will be deleted at: " + tempFile); - tempFile.delete(); - } - - FileUtil.writeFile(iStream, tempFile); - - if (!tempFile.exists()) { - String err = "Temporary file for application update not written to: " + tempFile; - getLog().error(err); - throw new Exception(err); - } - - return tempFile; - } - - /* At unload-time ensure that any WAR files packaged with the server plugin are un-deployed on - * the RHQ Server. - * - * @see org.rhq.enterprise.server.plugin.pc.AbstractTypeServerPluginContainer#unloadPlugin(org.rhq.enterprise.server.plugin.pc.ServerPluginEnvironment) - */ - @Override - public synchronized void unloadPlugin(ServerPluginEnvironment env) throws Exception { - String name = null; - try { - JarFile plugin = new JarFile(env.getPluginUrl().getFile()); - for (JarEntry entry : Collections.list(plugin.entries())) { - name = entry.getName(); - if (name.toLowerCase().endsWith(".war")) { - undeployWar(entry.getName()); - } - } - - } catch (Exception e) { - getLog().error("Failed to deploy " + env.getPluginName() + "#" + name, e); - } - - super.unloadPlugin(env); - } - - private void undeployWar(String name) { - try { - // get reference to MBean server - Context ic = new InitialContext(); - MBeanServerConnection server = (MBeanServerConnection) ic.lookup("jmx/invoker/RMIAdaptor"); - - // get reference to MainDeployer MBean - ObjectName mainDeployer = new ObjectName("jboss.system:service=MainDeployer"); - - Boolean isDeployed = (Boolean) server.invoke(mainDeployer, "isDeployed", new Object[] { name }, - new String[] { String.class.getName() }); - - if (isDeployed) { - server.invoke(mainDeployer, "undeploy", new Object[] { name }, new String[] { String.class.getName() }); - } - } catch (Exception e) { - e.printStackTrace(); - } + protected ServerPluginManager createPluginManager() { + return new PerspectiveServerPluginManager(this); }
} diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/perspective/PerspectiveServerPluginManager.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/perspective/PerspectiveServerPluginManager.java new file mode 100644 index 0000000..ed9408a --- /dev/null +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/perspective/PerspectiveServerPluginManager.java @@ -0,0 +1,167 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2009 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.plugin.pc.perspective; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.util.Collections; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; + +import javax.management.MBeanServerConnection; +import javax.management.ObjectName; +import javax.naming.Context; +import javax.naming.InitialContext; + +import org.rhq.core.util.file.FileUtil; +import org.rhq.enterprise.server.plugin.pc.ServerPluginEnvironment; +import org.rhq.enterprise.server.plugin.pc.ServerPluginManager; + +/** + * This loads in all perspective server plugins that can be found. You can obtain a loaded plugin's + * {@link ServerPluginEnvironment environment}, including its classloader, from this object as well. + * + * @author Jay Shaughnessy + * @author John Mazzitelli + */ +public class PerspectiveServerPluginManager extends ServerPluginManager { + + public PerspectiveServerPluginManager(PerspectiveServerPluginContainer pc) { + super(pc); + } + + /* At load-time ensure that any WAR files packaged with the server plugin are deployed to the RHQ + * Server. Note, perspective apps are logically deployed along-side, not inside the rhq.ear (although physically + * under the default/work). They should have access to the same shared components. + * + * @see org.rhq.enterprise.server.plugin.pc.AbstractTypeServerPluginContainer#loadPlugin(org.rhq.enterprise.server.plugin.pc.ServerPluginEnvironment) + */ + @Override + public synchronized void loadPlugin(ServerPluginEnvironment env) throws Exception { + super.loadPlugin(env); + + String name = null; + try { + JarFile plugin = new JarFile(env.getPluginUrl().getFile()); + for (JarEntry entry : Collections.list(plugin.entries())) { + name = entry.getName(); + if (name.toLowerCase().endsWith(".war")) { + deployWar(env, entry.getName(), plugin.getInputStream(entry)); + } + } + } catch (Exception e) { + getLog().error("Failed to deploy " + env.getPluginName() + "#" + name, e); + } + } + + private void deployWar(ServerPluginEnvironment env, String name, InputStream iStream) { + try { + // Save the war file to the plugins data directory. This survives restarts and will + // act as our deploy directory. + File deployFile = writeWarToFile(getDeployFile(env, name), iStream); + + // get reference to MBean server + Context ic = new InitialContext(); + MBeanServerConnection server = (MBeanServerConnection) ic.lookup("jmx/invoker/RMIAdaptor"); + + // get reference to MainDeployer MBean + ObjectName mainDeployer = new ObjectName("jboss.system:service=MainDeployer"); + + server.invoke(mainDeployer, "deploy", new Object[] { deployFile.getAbsolutePath() }, + new String[] { String.class.getName() }); + + } catch (Exception e) { + e.printStackTrace(); + } + } + + private File getDeployFile(ServerPluginEnvironment env, String name) throws IOException { + File dataDir = getServerPluginContext(env).getDataDirectory(); + dataDir.mkdirs(); + return new File(dataDir, name); + } + + private File writeWarToFile(File destFile, InputStream iStream) throws Exception { + + // Delete any previous instance of the file + if (destFile.exists()) { + getLog().debug("Existing file found and will be deleted at: " + destFile); + destFile.delete(); + } + + FileUtil.writeFile(iStream, destFile); + + if (!destFile.exists()) { + String err = "Temporary file for application update not written to: " + destFile; + getLog().error(err); + throw new Exception(err); + } + + return destFile; + } + + /* At unload-time ensure that any WAR files packaged with the server plugin are un-deployed on + * the RHQ Server. + * + * @see org.rhq.enterprise.server.plugin.pc.AbstractTypeServerPluginContainer#unloadPlugin(org.rhq.enterprise.server.plugin.pc.ServerPluginEnvironment) + */ + @Override + public synchronized void unloadPlugin(ServerPluginEnvironment env) throws Exception { + String name = null; + try { + JarFile plugin = new JarFile(env.getPluginUrl().getFile()); + for (JarEntry entry : Collections.list(plugin.entries())) { + name = entry.getName(); + if (name.toLowerCase().endsWith(".war")) { + undeployWar(getDeployFile(env, entry.getName())); + } + } + + } catch (Exception e) { + getLog().error("Failed to deploy " + env.getPluginName() + "#" + name, e); + } + + super.unloadPlugin(env); + } + + private void undeployWar(File deployFile) { + try { + // get reference to MBean server + Context ic = new InitialContext(); + MBeanServerConnection server = (MBeanServerConnection) ic.lookup("jmx/invoker/RMIAdaptor"); + + // get reference to MainDeployer MBean + ObjectName mainDeployer = new ObjectName("jboss.system:service=MainDeployer"); + + URL fileUrl = deployFile.toURI().toURL(); + + Boolean isDeployed = (Boolean) server.invoke(mainDeployer, "isDeployed", new Object[] { fileUrl }, + new String[] { URL.class.getName() }); + + if (isDeployed) { + server.invoke(mainDeployer, "undeploy", new Object[] { fileUrl }, new String[] { URL.class.getName() }); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + +} \ No newline at end of file diff --git a/modules/enterprise/server/plugins/pom.xml b/modules/enterprise/server/plugins/pom.xml index 960616b..a3331db 100644 --- a/modules/enterprise/server/plugins/pom.xml +++ b/modules/enterprise/server/plugins/pom.xml @@ -39,6 +39,8 @@ <module>yum</module> <module>url</module> <module>rhnhosted</module> + <!-- temporary sample perspective plugin --> + <module>../../../../etc/samples/perspectives/sample-perspective</module> </modules>
</project>
commit 74a0ef71b1dc33f9c6b38718a10d893b2875d84c Author: John Sanda john@localhost.localdomain Date: Fri Nov 13 09:07:56 2009 -0500
Updating RawConfigServer to use commons-configuration for the merge operations
diff --git a/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/RawConfigServer.groovy b/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/RawConfigServer.groovy index 7f5e43e..6b591e4 100644 --- a/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/RawConfigServer.groovy +++ b/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/RawConfigServer.groovy @@ -83,8 +83,11 @@ class RawConfigServer implements ResourceComponent, ResourceConfigurationFacet { }
void mergeStructuredConfiguration(RawConfiguration rawConfiguration, Configuration configuration) { - def buffer = new String(rawConfiguration.contents) - buffer.splitEachLine("=") { tokens -> configuration.put(new PropertySimple(tokens[0], tokens[1])) } + def rawPropertiesConfig = loadRawPropertiesConfiguration(rawConfiguration) + + configuration.put(new PropertySimple("x", rawPropertiesConfig.getString("x"))) + configuration.put(new PropertySimple("y", rawPropertiesConfig.getString("y"))) + configuration.put(new PropertySimple("z", rawPropertiesConfig.getString("z"))) }
} \ No newline at end of file
commit 01eb63ff42575c3a09c4d0dac62c85268f888eab Author: John Sanda john@localhost.localdomain Date: Fri Nov 13 08:53:15 2009 -0500
[US 2] Adding dependency for commons-configuration
diff --git a/modules/plugins/raw-config-test/pom.xml b/modules/plugins/raw-config-test/pom.xml index 3937708..ee22542 100644 --- a/modules/plugins/raw-config-test/pom.xml +++ b/modules/plugins/raw-config-test/pom.xml @@ -25,6 +25,12 @@ <artifactId>groovy-all</artifactId> <version>1.6.4</version> </dependency> + + <dependency> + <groupId>commons-configuration</groupId> + <artifactId>commons-configuration</artifactId> + <version>1.1</version> + </dependency> </dependencies>
<build> @@ -68,6 +74,11 @@ <artifactId>groovy-all</artifactId> <version>1.6.4</version> </artifactItem> + <artifactItem> + <groupId>commons-configuration</groupId> + <artifactId>commons-configuration</artifactId> + <version>1.1</version> + </artifactItem> </artifactItems> <outputDirectory>${project.build.outputDirectory}/lib</outputDirectory> </configuration>
commit 3a07b8ddc64cd60be4eb52ab7f2db1750a207591 Author: John Sanda john@localhost.localdomain Date: Fri Nov 13 08:51:10 2009 -0500
[US 2] Implementing merge operations in raw-config-test plugin
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationUpdateService.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationUpdateService.java new file mode 100644 index 0000000..bdafc4b --- /dev/null +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationUpdateService.java @@ -0,0 +1,8 @@ +package org.rhq.core.pc.configuration; + +/** + * Created by IntelliJ IDEA. User: john Date: Nov 12, 2009 Time: 4:37:07 PM To change this template use File | Settings + * | File Templates. + */ +public interface ConfigurationUpdateService { +} diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/UpdateLegacyConfig.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/UpdateLegacyConfig.java new file mode 100644 index 0000000..4039310 --- /dev/null +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/UpdateLegacyConfig.java @@ -0,0 +1,8 @@ +package org.rhq.core.pc.configuration; + +/** + * Created by IntelliJ IDEA. User: john Date: Nov 12, 2009 Time: 4:33:27 PM To change this template use File | Settings + * | File Templates. + */ +public interface UpdateLegacyConfig { +} diff --git a/modules/core/plugin-container/test-output/Custom suite/classes.html b/modules/core/plugin-container/test-output/Custom suite/classes.html deleted file mode 100644 index 1f89740..0000000 --- a/modules/core/plugin-container/test-output/Custom suite/classes.html +++ /dev/null @@ -1,44 +0,0 @@ -<table border='1'> -<tr> -<th>Class name</th> -<th>Method name</th> -<th>Groups</th> -</tr><tr> -<td>org.rhq.core.pc.plugin.PluginManagerTest</td> -<td> </td><td> </td></tr> -<tr> -<td align='center' colspan='3'>@Test</td> -</tr> -<tr> -<td> </td> -<td>pluginManagerShouldReturnAmpsVersionOfLoadedPluginWhenInEmbeddedMode</td> -<td> </td></tr> -<tr> -<td> </td> -<td>pluginsShouldBeShutdownInCorrectOrder</td> -<td> </td></tr> -<tr> -<td> </td> -<td>pluginsShouldBeLoadedInCorrectOrder</td> -<td> </td></tr> -<tr> -<td> </td> -<td>initializeShouldLoadDiscoveredPlugins</td> -<td> </td></tr> -<tr> -<td align='center' colspan='3'>@BeforeClass</td> -</tr> -<tr> -<td> </td> -<td>initClass</td> -<td> </td></tr> -<tr> -<td align='center' colspan='3'>@BeforeMethod</td> -</tr> -<tr> -<td align='center' colspan='3'>@AfterMethod</td> -</tr> -<tr> -<td align='center' colspan='3'>@AfterClass</td> -</tr> -</table> diff --git a/modules/core/plugin-container/test-output/Custom suite/groups.html b/modules/core/plugin-container/test-output/Custom suite/groups.html deleted file mode 100644 index 199cb3f..0000000 --- a/modules/core/plugin-container/test-output/Custom suite/groups.html +++ /dev/null @@ -1 +0,0 @@ -<h2>Groups used for this test run</h2> \ No newline at end of file diff --git a/modules/core/plugin-container/test-output/Custom suite/index.html b/modules/core/plugin-container/test-output/Custom suite/index.html deleted file mode 100644 index b3a3ad2..0000000 --- a/modules/core/plugin-container/test-output/Custom suite/index.html +++ /dev/null @@ -1,6 +0,0 @@ -<html><head><title>Results for Custom suite</title></head> -<frameset cols="26%,74%"> -<frame src="toc.html" name="navFrame"> -<frame src="main.html" name="mainFrame"> -</frameset> -</html> diff --git a/modules/core/plugin-container/test-output/Custom suite/main.html b/modules/core/plugin-container/test-output/Custom suite/main.html deleted file mode 100644 index 59a5d3f..0000000 --- a/modules/core/plugin-container/test-output/Custom suite/main.html +++ /dev/null @@ -1,2 +0,0 @@ -<html><head><title>Results for Custom suite</title></head> -<body>Select a result on the left-hand pane.</body></html> diff --git a/modules/core/plugin-container/test-output/Custom suite/methods-alphabetical.html b/modules/core/plugin-container/test-output/Custom suite/methods-alphabetical.html deleted file mode 100644 index ba955c2..0000000 --- a/modules/core/plugin-container/test-output/Custom suite/methods-alphabetical.html +++ /dev/null @@ -1,14 +0,0 @@ -<h2>Methods run, sorted chronologically</h2><h3>>> means before, << means after</h3><p/><br/><em>Custom suite</em><p/><small><i>(Hover the method name to see the test class name)</i></small><p/> -<table border="1"> -<tr><th>Time</th><th>Delta (ms)</th><th>Suite<br>configuration</th><th>Test<br>configuration</th><th>Class<br>configuration</th><th>Groups<br>configuration</th><th>Method<br>configuration</th><th>Test<br>method</th><th>Thread</th><th>Instances</th></tr> -<tr bgcolor="df886b"> <td>09/11/09 22:20:05</td> <td>0</td> <td> </td><td> </td><td title=">>org.rhq.core.pc.plugin.PluginManagerTest.initClass()">>>initClass</td> -<td> </td><td> </td><td> </td> <td>main@297529802</td> <td></td> </tr> -<tr bgcolor="df886b"> <td>09/11/09 22:20:13</td> <td>8149</td> <td> </td><td> </td><td> </td><td> </td><td> </td><td title="org.rhq.core.pc.plugin.PluginManagerTest.initializeShouldLoadDiscoveredPlugins()">initializeShouldLoadDiscoveredPlugins</td> - <td>main@297529802</td> <td></td> </tr> -<tr bgcolor="df886b"> <td>09/11/09 22:20:08</td> <td>2929</td> <td> </td><td> </td><td> </td><td> </td><td> </td><td title="org.rhq.core.pc.plugin.PluginManagerTest.pluginManagerShouldReturnAmpsVersionOfLoadedPluginWhenInEmbeddedMode()">pluginManagerShouldReturnAmpsVersionOfLoadedPluginWhenInEmbeddedMode</td> - <td>main@297529802</td> <td></td> </tr> -<tr bgcolor="df886b"> <td>09/11/09 22:20:09</td> <td>3921</td> <td> </td><td> </td><td> </td><td> </td><td> </td><td title="org.rhq.core.pc.plugin.PluginManagerTest.pluginsShouldBeLoadedInCorrectOrder()">pluginsShouldBeLoadedInCorrectOrder</td> - <td>main@297529802</td> <td></td> </tr> -<tr bgcolor="df886b"> <td>09/11/09 22:20:11</td> <td>6022</td> <td> </td><td> </td><td> </td><td> </td><td> </td><td title="org.rhq.core.pc.plugin.PluginManagerTest.pluginsShouldBeShutdownInCorrectOrder()">pluginsShouldBeShutdownInCorrectOrder</td> - <td>main@297529802</td> <td></td> </tr> -</table> diff --git a/modules/core/plugin-container/test-output/Custom suite/methods-not-run.html b/modules/core/plugin-container/test-output/Custom suite/methods-not-run.html deleted file mode 100644 index 54b14cb..0000000 --- a/modules/core/plugin-container/test-output/Custom suite/methods-not-run.html +++ /dev/null @@ -1,2 +0,0 @@ -<h2>Methods that were not run</h2><table> -</table> \ No newline at end of file diff --git a/modules/core/plugin-container/test-output/Custom suite/methods.html b/modules/core/plugin-container/test-output/Custom suite/methods.html deleted file mode 100644 index ca7f75e..0000000 --- a/modules/core/plugin-container/test-output/Custom suite/methods.html +++ /dev/null @@ -1,14 +0,0 @@ -<h2>Methods run, sorted chronologically</h2><h3>>> means before, << means after</h3><p/><br/><em>Custom suite</em><p/><small><i>(Hover the method name to see the test class name)</i></small><p/> -<table border="1"> -<tr><th>Time</th><th>Delta (ms)</th><th>Suite<br>configuration</th><th>Test<br>configuration</th><th>Class<br>configuration</th><th>Groups<br>configuration</th><th>Method<br>configuration</th><th>Test<br>method</th><th>Thread</th><th>Instances</th></tr> -<tr bgcolor="df886b"> <td>09/11/09 22:20:05</td> <td>0</td> <td> </td><td> </td><td title=">>org.rhq.core.pc.plugin.PluginManagerTest.initClass()">>>initClass</td> -<td> </td><td> </td><td> </td> <td>main@297529802</td> <td></td> </tr> -<tr bgcolor="df886b"> <td>09/11/09 22:20:08</td> <td>2929</td> <td> </td><td> </td><td> </td><td> </td><td> </td><td title="org.rhq.core.pc.plugin.PluginManagerTest.pluginManagerShouldReturnAmpsVersionOfLoadedPluginWhenInEmbeddedMode()">pluginManagerShouldReturnAmpsVersionOfLoadedPluginWhenInEmbeddedMode</td> - <td>main@297529802</td> <td></td> </tr> -<tr bgcolor="df886b"> <td>09/11/09 22:20:09</td> <td>3921</td> <td> </td><td> </td><td> </td><td> </td><td> </td><td title="org.rhq.core.pc.plugin.PluginManagerTest.pluginsShouldBeLoadedInCorrectOrder()">pluginsShouldBeLoadedInCorrectOrder</td> - <td>main@297529802</td> <td></td> </tr> -<tr bgcolor="df886b"> <td>09/11/09 22:20:11</td> <td>6022</td> <td> </td><td> </td><td> </td><td> </td><td> </td><td title="org.rhq.core.pc.plugin.PluginManagerTest.pluginsShouldBeShutdownInCorrectOrder()">pluginsShouldBeShutdownInCorrectOrder</td> - <td>main@297529802</td> <td></td> </tr> -<tr bgcolor="df886b"> <td>09/11/09 22:20:13</td> <td>8149</td> <td> </td><td> </td><td> </td><td> </td><td> </td><td title="org.rhq.core.pc.plugin.PluginManagerTest.initializeShouldLoadDiscoveredPlugins()">initializeShouldLoadDiscoveredPlugins</td> - <td>main@297529802</td> <td></td> </tr> -</table> diff --git a/modules/core/plugin-container/test-output/Custom suite/reporter-output.html b/modules/core/plugin-container/test-output/Custom suite/reporter-output.html deleted file mode 100644 index 063bc2e..0000000 --- a/modules/core/plugin-container/test-output/Custom suite/reporter-output.html +++ /dev/null @@ -1 +0,0 @@ -<h2>Reporter output</h2><table></table> \ No newline at end of file diff --git a/modules/core/plugin-container/test-output/Custom suite/rhq.html b/modules/core/plugin-container/test-output/Custom suite/rhq.html deleted file mode 100644 index be43416..0000000 --- a/modules/core/plugin-container/test-output/Custom suite/rhq.html +++ /dev/null @@ -1,98 +0,0 @@ -<html> -<head> -<title>TestNG: rhq</title> -<link href="../testng.css" rel="stylesheet" type="text/css" /> -<link href="../my-testng.css" rel="stylesheet" type="text/css" /> - -<style type="text/css"> -.log { display: none;} -.stack-trace { display: none;} -</style> -<script type="text/javascript"> -<!-- -function flip(e) { - current = e.style.display; - if (current == 'block') { - e.style.display = 'none'; - return 0; - } - else { - e.style.display = 'block'; - return 1; - } -} - -function toggleBox(szDivId, elem, msg1, msg2) -{ - var res = -1; if (document.getElementById) { - res = flip(document.getElementById(szDivId)); - } - else if (document.all) { - // this is the way old msie versions work - res = flip(document.all[szDivId]); - } - if(elem) { - if(res == 0) elem.innerHTML = msg1; else elem.innerHTML = msg2; - } - -} - -function toggleAllBoxes() { - if (document.getElementsByTagName) { - d = document.getElementsByTagName('div'); - for (i = 0; i < d.length; i++) { - if (d[i].className == 'log') { - flip(d[i]); - } - } - } -} - -// --> -</script> - -</head> -<body> -<h2 align='center'>rhq</h2><table border='1' align="center"> -<tr> -<td>Tests passed/Failed/Skipped:</td><td>4/0/0</td> -</tr><tr> -<td>Started on:</td><td>Mon Nov 09 22:20:05 EST 2009</td> -</tr> -<tr><td>Total time:</td><td>9 seconds (9399 ms)</td> -</tr><tr> -<td>Included groups:</td><td></td> -</tr><tr> -<td>Excluded groups:</td><td></td> -</tr> -</table><p/> -<small><i>(Hover the method name to see the test class name)</i></small><p/> -<table width='100%' border='1' class='invocation-passed'> -<tr><td colspan='3' align='center'><b>PASSED TESTS</b></td></tr> -<tr><td><b>Test method</b></td> -<td width="10%"><b>Time (seconds)</b></td> -<td width="30%"><b>Exception</b></td> -</tr> -<tr> -<td title='org.rhq.core.pc.plugin.PluginManagerTest.initializeShouldLoadDiscoveredPlugins()'>initializeShouldLoadDiscoveredPlugins</td> -<td>1</td> -<td></td> -</tr> -<tr> -<td title='org.rhq.core.pc.plugin.PluginManagerTest.pluginManagerShouldReturnAmpsVersionOfLoadedPluginWhenInEmbeddedMode()'>pluginManagerShouldReturnAmpsVersionOfLoadedPluginWhenInEmbeddedMode</td> -<td>1</td> -<td></td> -</tr> -<tr> -<td title='org.rhq.core.pc.plugin.PluginManagerTest.pluginsShouldBeLoadedInCorrectOrder()'>pluginsShouldBeLoadedInCorrectOrder</td> -<td>2</td> -<td></td> -</tr> -<tr> -<td title='org.rhq.core.pc.plugin.PluginManagerTest.pluginsShouldBeShutdownInCorrectOrder()'>pluginsShouldBeShutdownInCorrectOrder</td> -<td>2</td> -<td></td> -</tr> -</table><p> -</body> -</html> \ No newline at end of file diff --git a/modules/core/plugin-container/test-output/Custom suite/rhq.properties b/modules/core/plugin-container/test-output/Custom suite/rhq.properties deleted file mode 100644 index e4769b7..0000000 --- a/modules/core/plugin-container/test-output/Custom suite/rhq.properties +++ /dev/null @@ -1 +0,0 @@ -[SuiteResult rhq] \ No newline at end of file diff --git a/modules/core/plugin-container/test-output/Custom suite/rhq.xml b/modules/core/plugin-container/test-output/Custom suite/rhq.xml deleted file mode 100644 index f1278a6..0000000 --- a/modules/core/plugin-container/test-output/Custom suite/rhq.xml +++ /dev/null @@ -1,8 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<testsuite name="rhq" failures="0" tests="4" time="9.399" errors="0"> - <properties/> - <testcase name="pluginManagerShouldReturnAmpsVersionOfLoadedPluginWhenInEmbeddedMode" time="1.008" classname="org.rhq.core.pc.plugin.PluginManagerTest"/> - <testcase name="pluginsShouldBeLoadedInCorrectOrder" time="2.098" classname="org.rhq.core.pc.plugin.PluginManagerTest"/> - <testcase name="pluginsShouldBeShutdownInCorrectOrder" time="2.124" classname="org.rhq.core.pc.plugin.PluginManagerTest"/> - <testcase name="initializeShouldLoadDiscoveredPlugins" time="1.241" classname="org.rhq.core.pc.plugin.PluginManagerTest"/> -</testsuite> diff --git a/modules/core/plugin-container/test-output/Custom suite/testng-failed.xml b/modules/core/plugin-container/test-output/Custom suite/testng-failed.xml deleted file mode 100644 index eaad574..0000000 --- a/modules/core/plugin-container/test-output/Custom suite/testng-failed.xml +++ /dev/null @@ -1,13 +0,0 @@ -<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd"> -<suite thread-count="5" skipfailedinvocationCounts="false" verbose="1" name="Failed suite [Custom suite]" junit="false" parallel="none" annotations="JDK"> - <test name="rhq(failed)" junit="false" parallel="none" annotations="JDK"> - <classes> - <class name="org.rhq.core.pc.plugin.PluginManagerTest"> - <methods> - <include name="initClass"/> - <include name="pluginManagerShouldReturnAmpsVersionOfLoadedPluginWhenInEnterpriseMode"/> - </methods> - </class> - </classes> - </test> -</suite> diff --git a/modules/core/plugin-container/test-output/Custom suite/testng.xml.html b/modules/core/plugin-container/test-output/Custom suite/testng.xml.html deleted file mode 100644 index a34581d..0000000 --- a/modules/core/plugin-container/test-output/Custom suite/testng.xml.html +++ /dev/null @@ -1 +0,0 @@ -<html><head><title>testng.xml for Custom suite</title></head><body><tt><!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd%22%3E;<br/><suite thread-count="5" skipfailedinvocationCounts="false" verbose="1" name="Custom suite" junit="false" parallel="none" annotations="JDK"><br/> <test verbose="1" name="rhq" junit="false" annotations="JDK"><br/> <classes><br/> <class name="org.rhq.core.pc.plugin.PluginManagerTest"/><br/> </classes><br/> </test><br/></suite><br/></tt></body></html> \ No newline at end of file diff --git a/modules/core/plugin-container/test-output/Custom suite/toc.html b/modules/core/plugin-container/test-output/Custom suite/toc.html deleted file mode 100644 index f6418b2..0000000 --- a/modules/core/plugin-container/test-output/Custom suite/toc.html +++ /dev/null @@ -1,30 +0,0 @@ -<html> -<head> -<title>Results for Custom suite</title> -<link href="../testng.css" rel="stylesheet" type="text/css" /> -<link href="../my-testng.css" rel="stylesheet" type="text/css" /> -</head> -<body> -<h3><p align="center">Results for<br/><em>Custom suite</em></p></h3> -<table border='1' width='100%'> -<tr valign='top'> -<td>1 test</td> -<td><a target='mainFrame' href='classes.html'>1 class</a></td> -<td>4 methods:<br/> - <a target='mainFrame' href='methods.html'>chronological</a><br/> - <a target='mainFrame' href='methods-alphabetical.html'>alphabetical</a><br/> - <a target='mainFrame' href='methods-not-run.html'>not run (0)</a></td> -</tr> -<tr> -<td><a target='mainFrame' href='groups.html'>0 group</a></td> -<td><a target='mainFrame' href='reporter-output.html'>reporter output</a></td> -<td><a target='mainFrame' href='testng.xml.html'>testng.xml</a></td> -</tr></table> -<table width='100%' class='test-passed'> -<tr><td> -<table style='width: 100%'><tr><td valign='top'>rhq (4/0/0)</td><td valign='top' align='right'> - <a href='rhq.html' target='mainFrame'>Results</a> -</td></tr></table> -</td></tr><p/> -</table> -</body></html> \ No newline at end of file diff --git a/modules/core/plugin-container/test-output/emailable-report.html b/modules/core/plugin-container/test-output/emailable-report.html deleted file mode 100644 index ab5162f..0000000 --- a/modules/core/plugin-container/test-output/emailable-report.html +++ /dev/null @@ -1,49 +0,0 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml"> -<head> -<title>TestNG: Unit Test</title> -<style type="text/css"> -table caption,table.info_table,table.param,table.passed,table.failed {margin-bottom:10px;border:1px solid #000099;border-collapse:collapse;empty-cells:show;} -table.info_table td,table.info_table th,table.param td,table.param th,table.passed td,table.passed th,table.failed td,table.failed th { -border:1px solid #000099;padding:.25em .5em .25em .5em -} -table.param th {vertical-align:bottom} -td.numi,th.numi,td.numi_attn { -text-align:right -} -tr.total td {font-weight:bold} -table caption { -text-align:center;font-weight:bold; -} -table.passed tr.stripe td,table tr.passedodd td {background-color: #00AA00;} -table.passed td,table tr.passedeven td {background-color: #33FF33;} -table.passed tr.stripe td,table tr.skippedodd td {background-color: #cccccc;} -table.passed td,table tr.skippedodd td {background-color: #dddddd;} -table.failed tr.stripe td,table tr.failedodd td,table.param td.numi_attn {background-color: #FF3333;} -table.failed td,table tr.failedeven td,table.param tr.stripe td.numi_attn {background-color: #DD0000;} -tr.stripe td,tr.stripe th {background-color: #E6EBF9;} -p.totop {font-size:85%;text-align:center;border-bottom:2px black solid} -div.shootout {padding:2em;border:3px #4854A8 solid} -</style> -</head> -<body> -<table cellspacing=0 cellpadding=0 class="param"> -<tr><th>Test</th><th class="numi">Methods<br/>Passed</th><th class="numi">Scenarios<br/>Passed</th><th class="numi"># skipped</th><th class="numi"># failed</th><th class="numi">Total<br/>Time</th><th class="numi">Included<br/>Groups</th><th class="numi">Excluded<br/>Groups</th></tr> -<tr><td style="text-align:left;padding-right:2em">rhq</td><td class="numi">4</td><td class="numi">4</td><td class="numi">0</td><td class="numi">0</td><td class="numi">9.4 seconds</td><td class="numi"></td><td class="numi"></td></tr> -</table> -<a id="summary"></a> -<table cellspacing=0 cellpadding=0 class="passed"> -<tr><th>Class</th><th>Method</th><th># of<br/>Scenarios</th><th>Time<br/>(Msecs)</th></tr> -<tr><th colspan="4">rhq — passed</th></tr> -<tr class="passedodd"><td rowspan="4">org.rhq.core.pc.plugin.PluginManagerTest<td><a href="#m1"><b>initializeShouldLoadDiscoveredPlugins</b> </a></td><td class="numi">1</td><td class="numi">1241</td></tr><tr class="passedodd"><td><a href="#m2"><b>pluginManagerShouldReturnAmpsVersionOfLoadedPluginWhenInEmbeddedMode</b> </a></td><td class="numi">1</td><td class="numi">1008</td></tr><tr class="passedodd"><td><a href="#m3"><b>pluginsShouldBeLoadedInCorrectOrder</b> </a></td><td class="numi">1</td><td class="numi">2098</td></tr><tr class="passedodd"><td><a href="#m4"><b>pluginsShouldBeShutdownInCorrectOrder</b> </a></td><td class="numi">1</td><td class="numi">2124</td></tr> -</table> -<h1>rhq</h1> -<a id="m1"></a><h2>org.rhq.core.pc.plugin.PluginManagerTest:initializeShouldLoadDiscoveredPlugins</h2> -<p class="totop"><a href="#summary">back to summary</a></p> -<a id="m2"></a><h2>org.rhq.core.pc.plugin.PluginManagerTest:pluginManagerShouldReturnAmpsVersionOfLoadedPluginWhenInEmbeddedMode</h2> -<p class="totop"><a href="#summary">back to summary</a></p> -<a id="m3"></a><h2>org.rhq.core.pc.plugin.PluginManagerTest:pluginsShouldBeLoadedInCorrectOrder</h2> -<p class="totop"><a href="#summary">back to summary</a></p> -<a id="m4"></a><h2>org.rhq.core.pc.plugin.PluginManagerTest:pluginsShouldBeShutdownInCorrectOrder</h2> -<p class="totop"><a href="#summary">back to summary</a></p> -</body></html> diff --git a/modules/core/plugin-container/test-output/index.html b/modules/core/plugin-container/test-output/index.html deleted file mode 100644 index 2b714ba..0000000 --- a/modules/core/plugin-container/test-output/index.html +++ /dev/null @@ -1,9 +0,0 @@ -<html> -<head><title>Test results</title><link href="./testng.css" rel="stylesheet" type="text/css" /> -<link href="./my-testng.css" rel="stylesheet" type="text/css" /> -</head><body> -<h2><p align='center'>Test results</p></h2> -<table border='1' width='100%' class='main-page'><tr><th>Suite</th><th>Passed</th><th>Failed</th><th>Skipped</th><th>testng.xml</th></tr> -<tr align='center' class='invocation-passed'><td><em>Total</em></td><td><em>4</em></td><td><em>0</em></td><td><em>0</em></td><td> </td></tr> -<tr align='center' class='invocation-passed'><td><a href='Custom suite/index.html'>Custom suite</a></td> -<td>4</td><td>0</td><td>0</td><td><a href='Custom suite/testng.xml.html'>Link</a></td></tr></table></body></html> diff --git a/modules/core/plugin-container/test-output/testng-failed.xml b/modules/core/plugin-container/test-output/testng-failed.xml deleted file mode 100644 index eaad574..0000000 --- a/modules/core/plugin-container/test-output/testng-failed.xml +++ /dev/null @@ -1,13 +0,0 @@ -<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd"> -<suite thread-count="5" skipfailedinvocationCounts="false" verbose="1" name="Failed suite [Custom suite]" junit="false" parallel="none" annotations="JDK"> - <test name="rhq(failed)" junit="false" parallel="none" annotations="JDK"> - <classes> - <class name="org.rhq.core.pc.plugin.PluginManagerTest"> - <methods> - <include name="initClass"/> - <include name="pluginManagerShouldReturnAmpsVersionOfLoadedPluginWhenInEnterpriseMode"/> - </methods> - </class> - </classes> - </test> -</suite> diff --git a/modules/core/plugin-container/test-output/testng-results.xml b/modules/core/plugin-container/test-output/testng-results.xml deleted file mode 100644 index 5331e20..0000000 --- a/modules/core/plugin-container/test-output/testng-results.xml +++ /dev/null @@ -1,22 +0,0 @@ -<testng-results> - <reporter-output> - </reporter-output> - <suite name="Custom suite"> - <groups> - </groups> - <test name="rhq"> - <class name="org.rhq.core.pc.plugin.PluginManagerTest"> - <test-method status="PASS" signature="pluginsShouldBeLoadedInCorrectOrder()" name="pluginsShouldBeLoadedInCorrectOrder" duration-ms="2098" started-at="2009-11-09T22:20:09Z" finished-at="2009-11-09T22:20:11Z"> - </test-method> - <test-method status="PASS" signature="initClass()" name="initClass" is-config="true" duration-ms="2907" started-at="2009-11-09T22:20:05Z" finished-at="2009-11-09T22:20:08Z"> - </test-method> - <test-method status="PASS" signature="initializeShouldLoadDiscoveredPlugins()" name="initializeShouldLoadDiscoveredPlugins" duration-ms="1241" started-at="2009-11-09T22:20:13Z" finished-at="2009-11-09T22:20:14Z"> - </test-method> - <test-method status="PASS" signature="pluginManagerShouldReturnAmpsVersionOfLoadedPluginWhenInEmbeddedMode()" name="pluginManagerShouldReturnAmpsVersionOfLoadedPluginWhenInEmbeddedMode" duration-ms="1008" started-at="2009-11-09T22:20:08Z" finished-at="2009-11-09T22:20:09Z"> - </test-method> - <test-method status="PASS" signature="pluginsShouldBeShutdownInCorrectOrder()" name="pluginsShouldBeShutdownInCorrectOrder" duration-ms="2124" started-at="2009-11-09T22:20:11Z" finished-at="2009-11-09T22:20:13Z"> - </test-method> - </class> - </test> - </suite> -</testng-results> diff --git a/modules/core/plugin-container/test-output/testng.css b/modules/core/plugin-container/test-output/testng.css deleted file mode 100644 index 3904800..0000000 --- a/modules/core/plugin-container/test-output/testng.css +++ /dev/null @@ -1,9 +0,0 @@ -.invocation-failed, .test-failed { background-color: #DD0000; } -.invocation-percent, .test-percent { background-color: #006600; } -.invocation-passed, .test-passed { background-color: #00AA00; } -.invocation-skipped, .test-skipped { background-color: #CCCC00; } - -.main-page { - font-size: x-large; -} - diff --git a/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/RawConfigServer.groovy b/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/RawConfigServer.groovy index 1d0d8a6..7f5e43e 100644 --- a/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/RawConfigServer.groovy +++ b/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/RawConfigServer.groovy @@ -7,6 +7,7 @@ import org.rhq.core.pluginapi.configuration.ResourceConfigurationFacet import org.rhq.core.domain.configuration.Configuration import org.rhq.core.domain.configuration.RawConfiguration import org.rhq.core.domain.configuration.PropertySimple +import org.apache.commons.configuration.PropertiesConfiguration
class RawConfigServer implements ResourceComponent, ResourceConfigurationFacet {
@@ -47,9 +48,6 @@ class RawConfigServer implements ResourceComponent, ResourceConfigurationFacet { }
Configuration loadStructuredConfiguration() { -// Configuration config = new Configuration() -// properties.each { key, value -> config.put(new PropertySimple(key, value)) } -// return config return loadRawConfigurations() }
@@ -61,6 +59,27 @@ class RawConfigServer implements ResourceComponent, ResourceConfigurationFacet { }
void mergeRawConfiguration(Configuration configuration, RawConfiguration rawConfiguration) { + def rawPropertiesConfig = loadRawPropertiesConfiguration(rawConfiguration) + + def x = configuration.get("x") + def y = configuration.get("y") + def z = configuration.get("z") + + rawPropertiesConfig.setProperty("x", x.stringValue) + rawPropertiesConfig.setProperty("y", y.stringValue) + rawPropertiesConfig.setProperty("z", z.stringValue) + + def stream = new ByteArrayOutputStream() + rawPropertiesConfig.save(stream) + rawConfiguration.contents = stream.toByteArray() + } + + def loadRawPropertiesConfiguration(rawConfig) { + def stream = new ByteArrayInputStream(rawConfig.contents) + def rawPropertiesConfig = new PropertiesConfiguration() + rawPropertiesConfig.load(stream) + + return rawPropertiesConfig }
void mergeStructuredConfiguration(RawConfiguration rawConfiguration, Configuration configuration) { diff --git a/modules/plugins/raw-config-test/src/test/groovy/org/rhq/plugins/test/rawconfig/RawConfigServerTest.groovy b/modules/plugins/raw-config-test/src/test/groovy/org/rhq/plugins/test/rawconfig/RawConfigServerTest.groovy new file mode 100644 index 0000000..52b9b68 --- /dev/null +++ b/modules/plugins/raw-config-test/src/test/groovy/org/rhq/plugins/test/rawconfig/RawConfigServerTest.groovy @@ -0,0 +1,12 @@ +package org.rhq.plugins.test.rawconfig +/** + * Created by IntelliJ IDEA. + * User: john + * Date: Nov 13, 2009 + * Time: 8:26:14 AM + * To change this template use File | Settings | File Templates. + */ + +public class RawConfigServerTest { + +} \ No newline at end of file
commit 5bdcb136695938739f001ec7956d9c7ec4a4f396 Author: Ian Springer ian.springer@redhat.com Date: Fri Nov 13 00:50:33 2009 -0500
back out usage of iframeSSI.js lib for resizing perseptive iframes, since its license is not compatbile with the GPL
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/js/iframeSSI.js b/modules/enterprise/gui/portal-war/src/main/webapp/js/iframeSSI.js deleted file mode 100644 index 32f26d6..0000000 --- a/modules/enterprise/gui/portal-war/src/main/webapp/js/iframeSSI.js +++ /dev/null @@ -1,77 +0,0 @@ -/*********************************************** -* IFrame SSI script II- © Dynamic Drive DHTML code library (http://www.dynamicdrive.com) -* Visit DynamicDrive.com for hundreds of original DHTML scripts -* This notice must stay intact for legal use -***********************************************/ - -//Input the IDs of the IFRAMES you wish to dynamically resize to match its content height: -//Separate each ID with a comma. Examples: ["myframe1", "myframe2"] or ["myframe"] or [] for none: -var iframeids = ["perspective"]; - -//Should script hide iframe from browsers that don't support this script (non IE5+/NS6+ browsers. Recommended): -var iframehide = "no"; - -var isFirefox = (navigator.userAgent.indexOf("Firefox/") != -1); -// NOTE (ips): Original script had 16px, but 40px was what I needed to make it work on FF 3.5.3. -var extraHeight = isFirefox ? 40 : 0; // extra height in px to add to iframe in Firefox - -function resizeCaller() -{ - var dyniframe = new Array(); - for (i = 0; i < iframeids.length; i++) - { - if (document.getElementById) { - resizeIframe(iframeids[i]); - } - //reveal iframe for lower end browsers? (see var above): - if ((document.all || document.getElementById) && iframehide == "no") - { - var tempobj = document.all ? document.all[iframeids[i]] : document.getElementById(iframeids[i]); - tempobj.style.display = "block"; - } - } -} - -function resizeIframe(frameid) -{ - var currentfr = document.getElementById(frameid); - if (currentfr && !window.opera) - { - currentfr.style.display = "block"; - if (currentfr.contentDocument && currentfr.contentDocument.body.offsetHeight) { // NS6+ syntax - currentfr.height = currentfr.contentDocument.body.offsetHeight + extraHeight; - } else if (currentfr.Document && currentfr.Document.body.scrollHeight) { // IE5+ syntax - currentfr.height = currentfr.Document.body.scrollHeight; - } - if (currentfr.addEventListener) { - currentfr.addEventListener("load", readjustIframe, false); - } else if (currentfr.attachEvent) { - currentfr.detachEvent("onload", readjustIframe); // Bug fix line - currentfr.attachEvent("onload", readjustIframe); - } - } -} - -function readjustIframe(loadevt) -{ - var crossevt = (window.event) ? event : loadevt; - var iframeroot = (crossevt.currentTarget) ? crossevt.currentTarget : crossevt.srcElement; - if (iframeroot) { - resizeIframe(iframeroot.id); - } -} - -function loadintoIframe(iframeid, url) -{ - if (document.getElementById) { - document.getElementById(iframeid).src = url; - } -} - -if (window.addEventListener) { - window.addEventListener("load", resizeCaller, false); -} else if (window.attachEvent) { - window.attachEvent("onload", resizeCaller); -} else { - window.onload = resizeCaller; -} diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/layout/main-layout.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/layout/main-layout.xhtml index eac2995..bd4a0d1 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/layout/main-layout.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/layout/main-layout.xhtml @@ -1,163 +1,156 @@ -<?xml version="1.0"?> - -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" - "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> - -<html xmlns="http://www.w3.org/1999/xhtml" - xmlns:h="http://java.sun.com/jsf/html" - xmlns:f="http://java.sun.com/jsf/core" - xmlns:ui="http://java.sun.com/jsf/facelets" - xmlns:c="http://java.sun.com/jstl/core" - xmlns:a4j="http://richfaces.org/a4j" - xmlns:onc="http://jboss.org/on/component" - xmlns:rich="http://richfaces.ajax4jsf.org/rich%22%3E - -<head> - <title>${msg["product.shortName"]} - #{(!empty pageTitle) ? pageTitle : defaultPageTitle}</title> - - <ui:insert name="metaHeaders"></ui:insert> - - <link rel="stylesheet" type="text/css" media="screen" href="/css/win.css"/> - <link rel="stylesheet" type="text/css" media="screen" href="/css/form-style.css"/> - <link rel="stylesheet" type="text/css" media="screen" href="/css/menu.css"/> - - <script type="text/javascript" src="/js/functions.js"></script> - <script type="text/javascript" src="/js/prototype.js"></script> - <script type="text/javascript" src="/js/window.js"></script> - <script type="text/javascript" src="/js/effects.js"></script> - <!--<script type="text/javascript" src="/js/debug.js"></script>--> - <script type="text/javascript" src="/js/formValues.js"></script> - <script type="text/javascript" src="/js/rhq.js"></script> - <script type="text/javascript" src="/js/popup.js"></script> - <script type="text/javascript" src="/js/iframeSSI.js"> - /*********************************************** - * IFrame SSI script II- © Dynamic Drive DHTML code library (http://www.dynamicdrive.com) - * Visit DynamicDrive.com for hundreds of original DHTML scripts - * This notice must stay intact for legal use - ***********************************************/ - </script> - - <link href="/css/theme/default.css" rel="stylesheet" type="text/css"/> - <link href="/css/theme/alphacube.css" rel="stylesheet" type="text/css"/> - <link href="/css/theme/debug.css" rel="stylesheet" type="text/css"/> - - <link rel="icon" type="image/png" href="/images/favicon.png"/> - <link rel="apple-touch-icon" href="/images/favicon.png"/> - - <!-- Trims up the headers of RF toggle panel headers --> - <style type="text/css"> - .BlockTitle { - padding-top: 3px; - padding-bottom: 3px; - } - HTML, BODY { overflow: hidden; } - </style> - - <link rel="stylesheet" type="text/css" media="screen" href="/css/tabular.css"/> - <link rel="stylesheet" type="text/css" media="screen" href="/css/layout.css"/> - - <script type="text/javascript"> - var imagePath = "/images/"; - </script> - -</head> - -<body bgcolor="#FFFFFF" style="height: 100%;"> - -ui:remove - <!-- Set the content type to "text/html" (overriding the default of "application/xhtml+xml") to force -Firefox and other Gecko-based browsers to render the page in "Almost Standards" (i.e. transitional) mode. --> -</ui:remove> -<f:view contentType="text/html"> - - - <f:loadBundle basename="ApplicationResources" var="msg"/> - - <!-- =================== PAGE HEADER =================== --> - - <script language="javascript" type="text/javascript"> - //this has to be defined before the resize trackers inside - //the PageBody element because they depend on the values - //computed inside this tracker function. - WindowResizeTracker.addListener(function() { - var header = $('PageHeader'); - var borderHeight = 2; //set in the inline style of div PageHeader - - if (Prototype.Browser.IE) { - header.style.height = WindowResizeTracker.currentSizes.windowHeight + 'px'; - } else { - header.style.height = (WindowResizeTracker.currentSizes.windowHeight - borderHeight) + 'px'; - } - header.style.width = WindowResizeTracker.currentSizes.windowWidth + 'px'; - - var body = $('PageBody'); - //27 = menu height (and the top position of PageBody) - body.style.height = (WindowResizeTracker.currentSizes.windowHeight - 27 - borderHeight) + 'px'; - body.style.width = header.style.width; - - document.body.style.height = WindowResizeTracker.currentSizes.windowHeight + 'px'; - }); - </script> - <!-- work around for IE and its broken box model. Without the concrete height value, the nav pane will shrink on hover. --> - <!--[if IE]> - <div id="PageHeader" style="border-bottom: 2px solid #999; position: absolute; top: 0; bottom: 0; left: 0; right: 0; height: 100%"> - <![endif]--> - <!--[if !IE]><!--> - <div id="PageHeader" style="border-bottom: 2px solid #999; position: absolute; top: 0; bottom: 0; left: 0; right: 0;"> - <!--<![endif]--> - - <ui:include src="/rhq/common/menu/menu.xhtml"/> - - <!-- work around for IE and its broken box model. Without the concrete height value, the nav pane will shrink on hover. --> - <!--[if IE]> - <div id="PageBody" style="width: 100%; position: absolute; top: 27px; bottom: 0; height: 100%;"> - <![endif]--> - <!--[if !IE]><!--> - <div id="PageBody" style="width: 100%; position: absolute; top: 27px; bottom: 0;"> - <!--<![endif]--> - <ui:insert name="body-area">Default Page Body</ui:insert> - </div> - - </div> - - - - <!-- =================== BODY =================== --> - - - <div id="about" class="dialog" style="display: none; position: absolute; top: 0; left: 0;"> - <div class="DisplayContent" style="margin: 0;"> - <div style="margin:5px"> - <p class="compact"> - <span class="DisplaySubhead">${msg['footer.aboutLink']}</span><br/> - <span class="DisplayLabel">${msg['footer.version']}: ${msg['product.version']}</span><br/> - <span class="DisplayLabel">${msg['footer.buildNumber']}: ${msg['product.buildNumber']}</span> - </p> - - <p class="compact"> - <f:verbatim>${msg['footer.copyright']}</f:verbatim> ${msg['about.Copyright.Content']} - </p> - - <p class="compact"> - ${msg['about.MoreInfo.Label']}<br/> - <a href="mailto:${msg['about.MoreInfo.LinkSales']}">${msg['about.MoreInfo.LinkSales']}</a><br/> - <a href="mailto:${msg['about.MoreInfo.LinkSupport']}">${msg['about.MoreInfo.LinkSupport']}</a> - </p> - </div> - </div> - </div> - - <!-- work-around to enable us to embed richfaces components inside the onc:simpleTrigger; -without this, the page will throw a javascript error "{blah} is not defined" or -"{yadda} is not a constructor", and the pop-up action will not work --> - <rich:calendar rendered="false"/> - <rich:inputNumberSpinner rendered="false"/> - -</f:view> - -<script type="text/javascript"> - addWindowOnLoadEvent(disableConditionalButtons); -</script> - -</body> -</html> +<?xml version="1.0"?> + +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<html xmlns="http://www.w3.org/1999/xhtml" + xmlns:h="http://java.sun.com/jsf/html" + xmlns:f="http://java.sun.com/jsf/core" + xmlns:ui="http://java.sun.com/jsf/facelets" + xmlns:c="http://java.sun.com/jstl/core" + xmlns:a4j="http://richfaces.org/a4j" + xmlns:onc="http://jboss.org/on/component" + xmlns:rich="http://richfaces.ajax4jsf.org/rich%22%3E + +<head> + <title>${msg["product.shortName"]} - #{(!empty pageTitle) ? pageTitle : defaultPageTitle}</title> + + <ui:insert name="metaHeaders"></ui:insert> + + <link rel="stylesheet" type="text/css" media="screen" href="/css/win.css"/> + <link rel="stylesheet" type="text/css" media="screen" href="/css/form-style.css"/> + <link rel="stylesheet" type="text/css" media="screen" href="/css/menu.css"/> + + <script type="text/javascript" src="/js/functions.js"></script> + <script type="text/javascript" src="/js/prototype.js"></script> + <script type="text/javascript" src="/js/window.js"></script> + <script type="text/javascript" src="/js/effects.js"></script> + <!--<script type="text/javascript" src="/js/debug.js"></script>--> + <script type="text/javascript" src="/js/formValues.js"></script> + <script type="text/javascript" src="/js/rhq.js"></script> + <script type="text/javascript" src="/js/popup.js"></script> + + <link href="/css/theme/default.css" rel="stylesheet" type="text/css"/> + <link href="/css/theme/alphacube.css" rel="stylesheet" type="text/css"/> + <link href="/css/theme/debug.css" rel="stylesheet" type="text/css"/> + + <link rel="icon" type="image/png" href="/images/favicon.png"/> + <link rel="apple-touch-icon" href="/images/favicon.png"/> + + <!-- Trims up the headers of RF toggle panel headers --> + <style type="text/css"> + .BlockTitle { + padding-top: 3px; + padding-bottom: 3px; + } + HTML, BODY { overflow: hidden; } + </style> + + <link rel="stylesheet" type="text/css" media="screen" href="/css/tabular.css"/> + <link rel="stylesheet" type="text/css" media="screen" href="/css/layout.css"/> + + <script type="text/javascript"> + var imagePath = "/images/"; + </script> + +</head> + +<body bgcolor="#FFFFFF" style="height: 100%;"> + +ui:remove + <!-- Set the content type to "text/html" (overriding the default of "application/xhtml+xml") to force +Firefox and other Gecko-based browsers to render the page in "Almost Standards" (i.e. transitional) mode. --> +</ui:remove> +<f:view contentType="text/html"> + + + <f:loadBundle basename="ApplicationResources" var="msg"/> + + <!-- =================== PAGE HEADER =================== --> + + <script language="javascript" type="text/javascript"> + //this has to be defined before the resize trackers inside + //the PageBody element because they depend on the values + //computed inside this tracker function. + WindowResizeTracker.addListener(function() { + var header = $('PageHeader'); + var borderHeight = 2; //set in the inline style of div PageHeader + + if (Prototype.Browser.IE) { + header.style.height = WindowResizeTracker.currentSizes.windowHeight + 'px'; + } else { + header.style.height = (WindowResizeTracker.currentSizes.windowHeight - borderHeight) + 'px'; + } + header.style.width = WindowResizeTracker.currentSizes.windowWidth + 'px'; + + var body = $('PageBody'); + //27 = menu height (and the top position of PageBody) + body.style.height = (WindowResizeTracker.currentSizes.windowHeight - 27 - borderHeight) + 'px'; + body.style.width = header.style.width; + + document.body.style.height = WindowResizeTracker.currentSizes.windowHeight + 'px'; + }); + </script> + <!-- work around for IE and its broken box model. Without the concrete height value, the nav pane will shrink on hover. --> + <!--[if IE]> + <div id="PageHeader" style="border-bottom: 2px solid #999; position: absolute; top: 0; bottom: 0; left: 0; right: 0; height: 100%"> + <![endif]--> + <!--[if !IE]><!--> + <div id="PageHeader" style="border-bottom: 2px solid #999; position: absolute; top: 0; bottom: 0; left: 0; right: 0;"> + <!--<![endif]--> + + <ui:include src="/rhq/common/menu/menu.xhtml"/> + + <!-- work around for IE and its broken box model. Without the concrete height value, the nav pane will shrink on hover. --> + <!--[if IE]> + <div id="PageBody" style="width: 100%; position: absolute; top: 27px; bottom: 0; height: 100%;"> + <![endif]--> + <!--[if !IE]><!--> + <div id="PageBody" style="width: 100%; position: absolute; top: 27px; bottom: 0;"> + <!--<![endif]--> + <ui:insert name="body-area">Default Page Body</ui:insert> + </div> + + </div> + + + + <!-- =================== BODY =================== --> + + + <div id="about" class="dialog" style="display: none; position: absolute; top: 0; left: 0;"> + <div class="DisplayContent" style="margin: 0;"> + <div style="margin:5px"> + <p class="compact"> + <span class="DisplaySubhead">${msg['footer.aboutLink']}</span><br/> + <span class="DisplayLabel">${msg['footer.version']}: ${msg['product.version']}</span><br/> + <span class="DisplayLabel">${msg['footer.buildNumber']}: ${msg['product.buildNumber']}</span> + </p> + + <p class="compact"> + <f:verbatim>${msg['footer.copyright']}</f:verbatim> ${msg['about.Copyright.Content']} + </p> + + <p class="compact"> + ${msg['about.MoreInfo.Label']}<br/> + <a href="mailto:${msg['about.MoreInfo.LinkSales']}">${msg['about.MoreInfo.LinkSales']}</a><br/> + <a href="mailto:${msg['about.MoreInfo.LinkSupport']}">${msg['about.MoreInfo.LinkSupport']}</a> + </p> + </div> + </div> + </div> + + <!-- work-around to enable us to embed richfaces components inside the onc:simpleTrigger; +without this, the page will throw a javascript error "{blah} is not defined" or +"{yadda} is not a constructor", and the pop-up action will not work --> + <rich:calendar rendered="false"/> + <rich:inputNumberSpinner rendered="false"/> + +</f:view> + +<script type="text/javascript"> + addWindowOnLoadEvent(disableConditionalButtons); +</script> + +</body> +</html> diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/perspective/index.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/perspective/index.xhtml index fe32cbd..8034b2d 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/perspective/index.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/perspective/index.xhtml @@ -24,7 +24,7 @@ THIS TEXT WILL BE REMOVED.
<iframe id="perspective" src="/rhq-sample-perspective/" scrolling="no" marginwidth="0" marginheight="0" frameborder="0" - style="overflow: visible; display: none; width: 100%;"> + style="overflow: visible; width: 100%; height: 100%;"> ERROR: Perspective-defined page could not be embedded. Please make sure you're using IE6+ or FF2+. </iframe>
commit 7bae64676f5fc3447b530f011300de9eaeb3d231 Author: Partha Aji paji@redhat.com Date: Thu Nov 12 21:41:52 2009 -0500
Commiting base functionality of an post access file. Unit tests and custom lens to come.
diff --git a/modules/plugins/postfix/src/main/java/org/rhq/plugins/postfix/PostfixAccessComponent.java b/modules/plugins/postfix/src/main/java/org/rhq/plugins/postfix/PostfixAccessComponent.java new file mode 100644 index 0000000..f94dd2b --- /dev/null +++ b/modules/plugins/postfix/src/main/java/org/rhq/plugins/postfix/PostfixAccessComponent.java @@ -0,0 +1,61 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2009 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.plugins.postfix; + +import java.util.List; + +import net.augeas.Augeas; + +import org.rhq.core.domain.configuration.PropertyMap; +import org.rhq.core.domain.configuration.definition.PropertyDefinitionList; +import org.rhq.core.domain.configuration.definition.PropertyDefinitionMap; +import org.rhq.plugins.augeas.AugeasConfigurationComponent; +import org.rhq.plugins.augeas.helper.AugeasNode; +import org.rhq.plugins.augeas.helper.AugeasUtility; + +/** + * @author paji + * + */ +public class PostfixAccessComponent extends AugeasConfigurationComponent { + @Override + protected AugeasNode getNewListMemberNode(AugeasNode listNode, PropertyDefinitionMap listMemberPropDefMap, + int listIndex) { + AugeasNode node = new AugeasNode(listNode, "0" + listIndex); + return node; + } + + protected AugeasNode getExistingChildNodeForListMemberPropertyMap(AugeasNode parentNode, + PropertyDefinitionList propDefList, PropertyMap propMap) { + // First find all child nodes with the same 'pattern' value as the PropertyMap. + Augeas augeas = getAugeas(); + + String nameFilter = parentNode.getPath() + "/*/pattern"; + String canonical = propMap.getSimple("pattern").getStringValue(); + List<String> namePaths = AugeasUtility.matchFilter(augeas, nameFilter, canonical); + + if (namePaths == null || namePaths.isEmpty()) { + return null; + } + + AugeasNode node = new AugeasNode(namePaths.get(0)); + return node.getParent(); + } +} diff --git a/modules/plugins/postfix/src/main/java/org/rhq/plugins/postfix/PostfixAccessDiscoveryComponent.java b/modules/plugins/postfix/src/main/java/org/rhq/plugins/postfix/PostfixAccessDiscoveryComponent.java new file mode 100644 index 0000000..ee1ec3e --- /dev/null +++ b/modules/plugins/postfix/src/main/java/org/rhq/plugins/postfix/PostfixAccessDiscoveryComponent.java @@ -0,0 +1,50 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2009 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.plugins.postfix; + +import java.io.File; +import java.util.HashSet; +import java.util.Set; + +import org.rhq.core.domain.configuration.Configuration; +import org.rhq.core.pluginapi.inventory.DiscoveredResourceDetails; +import org.rhq.core.pluginapi.inventory.InvalidPluginConfigurationException; +import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext; +import org.rhq.plugins.augeas.AugeasConfigurationDiscoveryComponent; + +/** + * @author paji + * + */ +public class PostfixAccessDiscoveryComponent extends AugeasConfigurationDiscoveryComponent<PostfixAccessComponent> { + public Set<DiscoveredResourceDetails> discoverResources( + ResourceDiscoveryContext<PostfixAccessComponent> discoveryContext) throws InvalidPluginConfigurationException, + Exception { + + Set<DiscoveredResourceDetails> details = new HashSet<DiscoveredResourceDetails>(); + if (new File("/etc/postfix/access").exists()) { + Configuration pluginConfig = discoveryContext.getDefaultPluginConfiguration(); + DiscoveredResourceDetails detail = new DiscoveredResourceDetails(discoveryContext.getResourceType(), + "Access", "Access File", null, "Access", pluginConfig, null); + details.add(detail); + } + return details; + } +} diff --git a/modules/plugins/postfix/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/postfix/src/main/resources/META-INF/rhq-plugin.xml index 9954569..268b440 100644 --- a/modules/plugins/postfix/src/main/resources/META-INF/rhq-plugin.xml +++ b/modules/plugins/postfix/src/main/resources/META-INF/rhq-plugin.xml @@ -21,7 +21,7 @@
<c:simple-property name="configurationFilesInclusionPatterns" displayName="File Path" type="file" required="true" readOnly="true" default="/etc/postfix/main.cf" - description="the absolute path of the samba configuration"/> + description="the absolute path of the postfix configuration"/>
<c:simple-property name="resourceConfigurationRootNode" required="true" readOnly="true" default="/files/etc/postfix/main.cf"/> @@ -45,6 +45,34 @@ </c:group> </resource-configuration>
+ <service name="Access" discovery="PostfixAccessDiscoveryComponent" class="PostfixAccessComponent" + description="Access List in the Postfix System"> + <plugin-configuration> + <c:simple-property name="augeasModuleName" displayName="Augeas Module Name" default="Postfix_Access" required="true" readOnly="true" + description="the name of the Augeas module/lens to use for loading and updating this resource's configuration"/> + + <c:simple-property name="configurationFilesInclusionPatterns" displayName="File Path" type="file" required="true" readOnly="true" + default="/etc/postfix/access" + description="the absolute path of the postfix configuration"/> + + <c:simple-property name="resourceConfigurationRootNode" required="true" readOnly="true" + default="/files/etc/postfix/access"/> + </plugin-configuration> + <resource-configuration> + <c:list-property name="." displayName="Entries"> + <c:map-property name="*[pattern]"> + <c:simple-property name="pattern" displayName="Filtering Pattern" type="string" required="true" + description="The filtering pattern. Example Ip address 1.2.3"/> + + <c:simple-property name="action" displayName="Action" type="string" required="true" + description="The action to undergo, for example REJECT/ACCEPT"/> + + <c:simple-property name="parameters" displayName="Arguments" type="string" required="false" + description="These depend on the action selected. For example you may choose to use this to be the message for 'DISCARD' action. "/> + </c:map-property> + </c:list-property> + </resource-configuration> + </service> </server>
</plugin>
commit 66410e4509b632d285262d0adb3ec52be397fb6c Author: Partha Aji paji@redhat.com Date: Thu Nov 12 20:46:07 2009 -0500
Added Postfix unit tests + got the update for the postfix plugin working
diff --git a/.classpath b/.classpath index 1be8e0d..62b5fa7 100644 --- a/.classpath +++ b/.classpath @@ -89,7 +89,8 @@ <classpathentry kind="src" path="modules/plugins/samba/src/test/java"/> <classpathentry kind="src" path="modules/plugins/sudoers/src/main/java"/> <classpathentry kind="src" path="modules/plugins/sudoers/src/test/java"/> - <classpathentry kind="src" path="modules/plugins/postfix/src/main/java"/> + <classpathentry kind="src" path="modules/plugins/postfix/src/main/java"/> + <classpathentry kind="src" path="modules/plugins/postfix/src/test/java"/> <classpathentry kind="src" path="modules/plugins/cron/src/main/java"/> <classpathentry kind="src" path="modules/plugins/hudson/src/main/java"/> <classpathentry kind="src" path="modules/plugins/platform/src/test/java"/> diff --git a/modules/plugins/postfix/src/main/java/org/rhq/plugins/postfix/PostfixServerComponent.java b/modules/plugins/postfix/src/main/java/org/rhq/plugins/postfix/PostfixServerComponent.java index 3154304..7a91c24 100644 --- a/modules/plugins/postfix/src/main/java/org/rhq/plugins/postfix/PostfixServerComponent.java +++ b/modules/plugins/postfix/src/main/java/org/rhq/plugins/postfix/PostfixServerComponent.java @@ -18,13 +18,17 @@ */ package org.rhq.plugins.postfix;
+import net.augeas.Augeas; + import org.rhq.core.domain.configuration.Configuration; +import org.rhq.core.domain.configuration.PropertySimple; +import org.rhq.core.domain.configuration.definition.PropertyDefinitionSimple; +import org.rhq.core.domain.configuration.definition.PropertySimpleType; import org.rhq.core.domain.measurement.AvailabilityType; -import org.rhq.core.domain.resource.ResourceType; import org.rhq.core.pluginapi.configuration.ConfigurationUpdateReport; -import org.rhq.core.pluginapi.inventory.CreateResourceReport; import org.rhq.core.pluginapi.inventory.ResourceContext; import org.rhq.plugins.augeas.AugeasConfigurationComponent; +import org.rhq.plugins.augeas.helper.AugeasNode;
/** * TODO @@ -50,34 +54,54 @@ public class PostfixServerComponent extends AugeasConfigurationComponent { public void updateResourceConfiguration(ConfigurationUpdateReport report) { super.updateResourceConfiguration(report); } -/*
- @Override - public CreateResourceReport createResource(CreateResourceReport reportIn) { - CreateResourceReport report = reportIn; - Configuration config = report.getResourceConfiguration(); - String name = config.getSimple(SambaShareComponent.NAME_RESOURCE_CONFIG_PROP).getStringValue(); - report.setResourceKey(name); - report.setResourceName(name); - return super.createResource(report); - } - @Override - protected String getChildResourceConfigurationRootPath(ResourceType resourceType, Configuration resourceConfig) { - if (resourceType.getName().equals(SambaShareComponent.RESOURCE_TYPE_NAME)) { - String targetName = resourceConfig.getSimple(SambaShareComponent.NAME_RESOURCE_CONFIG_PROP).getStringValue(); - return "/files/etc/samba/smb.conf/target[.='" + targetName + "']"; - } else { - throw new IllegalArgumentException("Unsupported child Resource type: " + resourceType); + protected Object toPropertyValue(PropertyDefinitionSimple propDefSimple, Augeas augeas, AugeasNode node) { + if (propDefSimple.getType().equals(PropertySimpleType.BOOLEAN)) { + return "yes".equals(augeas.get(node.getPath())); } + return super.toPropertyValue(propDefSimple, augeas, node); } + @Override - protected String getChildResourceConfigurationRootLabel(ResourceType resourceType, Configuration resourceConfig) { - if (resourceType.getName().equals(SambaShareComponent.RESOURCE_TYPE_NAME)) { - return resourceConfig.getSimple(SambaShareComponent.NAME_RESOURCE_CONFIG_PROP).getStringValue(); - } else { - throw new IllegalArgumentException("Unsupported child Resource type: " + resourceType); + protected String toNodeValue(Augeas augeas, AugeasNode node, PropertyDefinitionSimple propDefSimple, + PropertySimple propSimple) { + if (propDefSimple.getType().equals(PropertySimpleType.BOOLEAN)) { + if (propSimple.getBooleanValue()) { + return "yes"; + } + return "no"; } + return super.toNodeValue(augeas, node, propDefSimple, propSimple); } -*/ + + /* + + @Override + public CreateResourceReport createResource(CreateResourceReport reportIn) { + CreateResourceReport report = reportIn; + Configuration config = report.getResourceConfiguration(); + String name = config.getSimple(SambaShareComponent.NAME_RESOURCE_CONFIG_PROP).getStringValue(); + report.setResourceKey(name); + report.setResourceName(name); + return super.createResource(report); + } + @Override + protected String getChildResourceConfigurationRootPath(ResourceType resourceType, Configuration resourceConfig) { + if (resourceType.getName().equals(SambaShareComponent.RESOURCE_TYPE_NAME)) { + String targetName = resourceConfig.getSimple(SambaShareComponent.NAME_RESOURCE_CONFIG_PROP).getStringValue(); + return "/files/etc/samba/smb.conf/target[.='" + targetName + "']"; + } else { + throw new IllegalArgumentException("Unsupported child Resource type: " + resourceType); + } + } + @Override + protected String getChildResourceConfigurationRootLabel(ResourceType resourceType, Configuration resourceConfig) { + if (resourceType.getName().equals(SambaShareComponent.RESOURCE_TYPE_NAME)) { + return resourceConfig.getSimple(SambaShareComponent.NAME_RESOURCE_CONFIG_PROP).getStringValue(); + } else { + throw new IllegalArgumentException("Unsupported child Resource type: " + resourceType); + } + } + */
} diff --git a/modules/plugins/postfix/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/postfix/src/main/resources/META-INF/rhq-plugin.xml index 9fce0e1..9954569 100644 --- a/modules/plugins/postfix/src/main/resources/META-INF/rhq-plugin.xml +++ b/modules/plugins/postfix/src/main/resources/META-INF/rhq-plugin.xml @@ -24,7 +24,7 @@ description="the absolute path of the samba configuration"/>
<c:simple-property name="resourceConfigurationRootNode" required="true" readOnly="true" - default="/files/etc/postfix/main.cf/*"/> + default="/files/etc/postfix/main.cf"/> </plugin-configuration>
<resource-configuration> @@ -32,7 +32,7 @@ <c:simple-property displayName="Hostname" name="myhostname" description="Server's fully qualified domain name" required="false"/> <c:simple-property displayName="Origin" name="myorigin" description="Domain used in outgoing mail" required="false"/> <c:simple-property displayName="Networks" name="mynetworks" description="List of clients that can relay mail" required="false"/> - <c:simple-property displayName="Destinations" name="mydestinations" description="Space delimited list of domains for which server will accept delivered. Postfix must be restarted." required="false"/> + <c:simple-property displayName="Destinations" name="mydestination" description="Space delimited list of domains for which server will accept delivered. Postfix must be restarted." required="false"/> <c:simple-property displayName="Interfaces" name="inet_interfaces" description="Network interfaces that Postfix will bind to" required="false"/> <c:simple-property displayName="Banner" name="smtpd_banner" description="SMTP Banner (RFC requires hostname and ESMTP prompt)" default="$myhostname ESMTP" required="true"/> </c:group> diff --git a/modules/plugins/postfix/src/test/java/org/rhq/plugins/postfix/PostfixComponentTest.java b/modules/plugins/postfix/src/test/java/org/rhq/plugins/postfix/PostfixComponentTest.java new file mode 100644 index 0000000..7e28b3b --- /dev/null +++ b/modules/plugins/postfix/src/test/java/org/rhq/plugins/postfix/PostfixComponentTest.java @@ -0,0 +1,87 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2008 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.plugins.postfix; + +import org.rhq.core.domain.configuration.Configuration; +import org.rhq.core.domain.configuration.PropertySimple; +import org.rhq.plugins.augeas.test.AbstractAugeasConfigurationComponentTest; + +/** + * An integration test for {@link PostfixComponent}. + */ +public class PostfixComponentTest extends AbstractAugeasConfigurationComponentTest { + @Override + protected String getPluginName() { + return "Postfix"; + } + + @Override + protected String getResourceTypeName() { + return "Postfix Server"; + } + + @Override + protected Configuration getExpectedResourceConfig() { + + /** + * myhostname = virtual.domain.tld + myorigin = $myhostname + mynetworks = 168.100.189.0/28, 127.0.0.0/8 + mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain, + inet_interfaces = localhost + smtpd_banner = $myhostname ESMTP + disable_vrfy_command = no + smtpd_helo_required = no + smtp_always_send_ehlo = yes + in_flow_delay=100 + local_destination_concurrency_limit = 2 + */ + Configuration config = new Configuration(); + + config.put(new PropertySimple("myhostname", "virtual.domain.tld")); + config.put(new PropertySimple("myorigin", "$myhostname")); + config.put(new PropertySimple("mynetworks", "168.100.189.0/28, 127.0.0.0/8")); + config.put(new PropertySimple("mydestination", "$myhostname, localhost.$mydomain, localhost, $mydomain,")); + config.put(new PropertySimple("inet_interfaces", "localhost")); + config.put(new PropertySimple("smtpd_banner", "$myhostname ESMTP")); + config.put(new PropertySimple("disable_vrfy_command", false)); + config.put(new PropertySimple("smtpd_helo_required", false)); + config.put(new PropertySimple("smtp_always_send_ehlo", true)); + config.put(new PropertySimple("in_flow_delay", 100)); + config.put(new PropertySimple("local_destination_concurrency_limit", 2)); + + return config; + } + + @Override + protected Configuration getUpdatedResourceConfig() { + Configuration config = new Configuration(); + config.put(new PropertySimple("myhostname", "virtual.domain.com")); + config.put(new PropertySimple("myorigin", "$myhostname")); + config.put(new PropertySimple("mynetworks", "168.100.189.0/28")); + config.put(new PropertySimple("inet_interfaces", "$myhostname, localhost.$mydomain, localhost, $mydomain")); + config.put(new PropertySimple("smtpd_banner", "$myhostname ESMTP")); + config.put(new PropertySimple("disable_vrfy_command", false)); + config.put(new PropertySimple("smtpd_helo_required", false)); + config.put(new PropertySimple("smtp_always_send_ehlo", true)); + config.put(new PropertySimple("in_flow_delay", 101)); + config.put(new PropertySimple("local_destination_concurrency_limit", 88)); + return config; + } +} diff --git a/modules/plugins/postfix/src/test/resources/etc/postfix/main.cf b/modules/plugins/postfix/src/test/resources/etc/postfix/main.cf new file mode 100644 index 0000000..3ce38f2 --- /dev/null +++ b/modules/plugins/postfix/src/test/resources/etc/postfix/main.cf @@ -0,0 +1,11 @@ +myhostname = virtual.domain.tld +myorigin = $myhostname +mynetworks = 168.100.189.0/28, 127.0.0.0/8 +mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain, +inet_interfaces = localhost +smtpd_banner = $myhostname ESMTP +disable_vrfy_command = no +smtpd_helo_required = no +smtp_always_send_ehlo = yes +in_flow_delay=100 +local_destination_concurrency_limit = 2 \ No newline at end of file
commit c6b5ab28532d11cc5dbdb604c7332587b1697c04 Merge: a7337d3... bfadc10... Author: Jay Shaughnessy jshaughn@redhat.com Date: Thu Nov 12 16:08:54 2009 -0500
Merge branch 'pc' of ssh://jshaughn@git.fedorahosted.org/git/rhq/rhq.git into linux-config
commit a7337d32a934a164f734bfd73e0a67dcd282e38b Author: Jay Shaughnessy jshaughn@redhat.com Date: Thu Nov 12 16:02:32 2009 -0500
continue to add support for perspective lifecycle mgmt
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/perspective/PerspectiveServerPluginContainer.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/perspective/PerspectiveServerPluginContainer.java index 577b14f..01f5ced 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/perspective/PerspectiveServerPluginContainer.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/perspective/PerspectiveServerPluginContainer.java @@ -55,8 +55,8 @@ public class PerspectiveServerPluginContainer extends AbstractTypeServerPluginCo }
/* At load-time ensure that any WAR files packaged with the server plugin are deployed to the RHQ - * Server. Perspective apps are deployed along-side the rhq.ear and can access the same shared - * components. + * Server. Note, perspective apps are logically deployed along-side, not inside the rhq.ear (although physically + * under the default/work). They should have access to the same shared components. * * @see org.rhq.enterprise.server.plugin.pc.AbstractTypeServerPluginContainer#loadPlugin(org.rhq.enterprise.server.plugin.pc.ServerPluginEnvironment) */ @@ -71,7 +71,6 @@ public class PerspectiveServerPluginContainer extends AbstractTypeServerPluginCo deployWar(entry.getName(), plugin.getInputStream(entry)); } } - } catch (Exception e) { getLog().error("Failed to deploy " + env.getPluginName() + "#" + name, e); } @@ -88,11 +87,11 @@ public class PerspectiveServerPluginContainer extends AbstractTypeServerPluginCo Context ic = new InitialContext(); MBeanServerConnection server = (MBeanServerConnection) ic.lookup("jmx/invoker/RMIAdaptor");
- // get reference to CacheMgmtInterceptor MBean + // get reference to MainDeployer MBean ObjectName mainDeployer = new ObjectName("jboss.system:service=MainDeployer");
- // configure a filter to only receive node created and removed events - server.invoke(mainDeployer, "deploy", new Object[] { tempFile.getAbsolutePath() }, null); + server.invoke(mainDeployer, "deploy", new Object[] { tempFile.getAbsolutePath() }, + new String[] { String.class.getName() }); } catch (Exception e) { e.printStackTrace(); } @@ -101,11 +100,11 @@ public class PerspectiveServerPluginContainer extends AbstractTypeServerPluginCo private File writeWarToTempFile(String name, InputStream iStream) throws Exception {
File tempDir = new File(System.getProperty("java.io.tmpdir")); - File tempFile = new File(tempDir.getAbsolutePath(), name + System.currentTimeMillis()); + File tempFile = new File(tempDir.getAbsolutePath(), name);
- // The temp file shouldn't be there, but check and delete it if it is + // Delete any previous instance of the file if (tempFile.exists()) { - getLog().warn("Existing temporary file found and will be deleted at: " + tempFile); + getLog().debug("Existing temporary file found and will be deleted at: " + tempFile); tempFile.delete(); }
@@ -120,4 +119,48 @@ public class PerspectiveServerPluginContainer extends AbstractTypeServerPluginCo return tempFile; }
+ /* At unload-time ensure that any WAR files packaged with the server plugin are un-deployed on + * the RHQ Server. + * + * @see org.rhq.enterprise.server.plugin.pc.AbstractTypeServerPluginContainer#unloadPlugin(org.rhq.enterprise.server.plugin.pc.ServerPluginEnvironment) + */ + @Override + public synchronized void unloadPlugin(ServerPluginEnvironment env) throws Exception { + String name = null; + try { + JarFile plugin = new JarFile(env.getPluginUrl().getFile()); + for (JarEntry entry : Collections.list(plugin.entries())) { + name = entry.getName(); + if (name.toLowerCase().endsWith(".war")) { + undeployWar(entry.getName()); + } + } + + } catch (Exception e) { + getLog().error("Failed to deploy " + env.getPluginName() + "#" + name, e); + } + + super.unloadPlugin(env); + } + + private void undeployWar(String name) { + try { + // get reference to MBean server + Context ic = new InitialContext(); + MBeanServerConnection server = (MBeanServerConnection) ic.lookup("jmx/invoker/RMIAdaptor"); + + // get reference to MainDeployer MBean + ObjectName mainDeployer = new ObjectName("jboss.system:service=MainDeployer"); + + Boolean isDeployed = (Boolean) server.invoke(mainDeployer, "isDeployed", new Object[] { name }, + new String[] { String.class.getName() }); + + if (isDeployed) { + server.invoke(mainDeployer, "undeploy", new Object[] { name }, new String[] { String.class.getName() }); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + }
commit f7274f5ce7a25d1f1c50113fb71380ce289e6073 Author: Jay Shaughnessy jshaughn@redhat.com Date: Thu Nov 12 16:02:05 2009 -0500
Fix phase for adding war to perspective jar
diff --git a/etc/samples/sample-perspective/perspective/pom.xml b/etc/samples/sample-perspective/perspective/pom.xml index 533a07c..9674697 100644 --- a/etc/samples/sample-perspective/perspective/pom.xml +++ b/etc/samples/sample-perspective/perspective/pom.xml @@ -80,7 +80,7 @@
<execution> <id>add-war</id> - <phase>install</phase> + <phase>verify</phase> <configuration> <tasks> <property
commit 638561d2b3d9a80822b3a3cc534a716aefe94fc0 Author: Jay Shaughnessy jshaughn@redhat.com Date: Wed Nov 11 13:39:18 2009 -0500
Sample Perspective Deployment
diff --git a/modules/enterprise/gui/pom.xml b/modules/enterprise/gui/pom.xml index 40076d8..a038122 100644 --- a/modules/enterprise/gui/pom.xml +++ b/modules/enterprise/gui/pom.xml @@ -35,7 +35,7 @@ <module>portal-war</module> <module>installer-war</module> <module>webdav-war</module> - <module>perspectives</module> + <!-- <module>perspectives</module> --> </modules> </profile>
diff --git a/modules/enterprise/server/container/pom.xml b/modules/enterprise/server/container/pom.xml index a56e6fe..8494dd2 100644 --- a/modules/enterprise/server/container/pom.xml +++ b/modules/enterprise/server/container/pom.xml @@ -45,12 +45,14 @@ <version>${project.version}</version> </dependency>
+ <!-- Remove this as we now deploy the sample perspective manually <dependency> <groupId>org.rhq</groupId> <artifactId>rhq-sample-perspective</artifactId> <version>${project.version}</version> <type>war</type> </dependency> + -->
<!-- 3rd Party Deps -->
diff --git a/modules/enterprise/server/container/src/main/scripts/rhq-container.build.xml b/modules/enterprise/server/container/src/main/scripts/rhq-container.build.xml index ad1e0f6..f52bc69 100644 --- a/modules/enterprise/server/container/src/main/scripts/rhq-container.build.xml +++ b/modules/enterprise/server/container/src/main/scripts/rhq-container.build.xml @@ -400,10 +400,12 @@ </fileset> </move>
+ <!-- don't do this now that we have a sample perspective to deploy <echo>Deploying perspective WARs ...</echo> <mkdir dir="${jboss.deploy.dir}/rhq-sample-perspective.war" /> <unwar src="${settings.localRepository}/org/rhq/rhq-sample-perspective/${rhq.version}/rhq-sample-perspective-${rhq.version}.war" dest="${jboss.deploy.dir}/rhq-sample-perspective.war" /> + -->
</target>
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/perspective/PerspectiveServerPluginContainer.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/perspective/PerspectiveServerPluginContainer.java index e6929cc..577b14f 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/perspective/PerspectiveServerPluginContainer.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/perspective/PerspectiveServerPluginContainer.java @@ -19,14 +19,28 @@
package org.rhq.enterprise.server.plugin.pc.perspective;
+import java.io.File; +import java.io.InputStream; +import java.util.Collections; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; + +import javax.management.MBeanServerConnection; +import javax.management.ObjectName; +import javax.naming.Context; +import javax.naming.InitialContext; + +import org.rhq.core.util.file.FileUtil; import org.rhq.enterprise.server.plugin.pc.AbstractTypeServerPluginContainer; import org.rhq.enterprise.server.plugin.pc.MasterServerPluginContainer; +import org.rhq.enterprise.server.plugin.pc.ServerPluginEnvironment; import org.rhq.enterprise.server.plugin.pc.ServerPluginType; import org.rhq.enterprise.server.xmlschema.generated.serverplugin.perspective.PerspectivePluginDescriptorType;
/** - * Manages perspective plugins. + * Manages perspective server plugins. * + * @author Jay Shaughnessy * @author John Mazzitelli */ public class PerspectiveServerPluginContainer extends AbstractTypeServerPluginContainer { @@ -39,4 +53,71 @@ public class PerspectiveServerPluginContainer extends AbstractTypeServerPluginCo public ServerPluginType getSupportedServerPluginType() { return new ServerPluginType(PerspectivePluginDescriptorType.class); } + + /* At load-time ensure that any WAR files packaged with the server plugin are deployed to the RHQ + * Server. Perspective apps are deployed along-side the rhq.ear and can access the same shared + * components. + * + * @see org.rhq.enterprise.server.plugin.pc.AbstractTypeServerPluginContainer#loadPlugin(org.rhq.enterprise.server.plugin.pc.ServerPluginEnvironment) + */ + @Override + public synchronized void loadPlugin(ServerPluginEnvironment env) throws Exception { + String name = null; + try { + JarFile plugin = new JarFile(env.getPluginUrl().getFile()); + for (JarEntry entry : Collections.list(plugin.entries())) { + name = entry.getName(); + if (name.toLowerCase().endsWith(".war")) { + deployWar(entry.getName(), plugin.getInputStream(entry)); + } + } + + } catch (Exception e) { + getLog().error("Failed to deploy " + env.getPluginName() + "#" + name, e); + } + + super.loadPlugin(env); + } + + private void deployWar(String name, InputStream iStream) { + try { + // Save the war file to a temp area + File tempFile = writeWarToTempFile(name, iStream); + + // get reference to MBean server + Context ic = new InitialContext(); + MBeanServerConnection server = (MBeanServerConnection) ic.lookup("jmx/invoker/RMIAdaptor"); + + // get reference to CacheMgmtInterceptor MBean + ObjectName mainDeployer = new ObjectName("jboss.system:service=MainDeployer"); + + // configure a filter to only receive node created and removed events + server.invoke(mainDeployer, "deploy", new Object[] { tempFile.getAbsolutePath() }, null); + } catch (Exception e) { + e.printStackTrace(); + } + } + + private File writeWarToTempFile(String name, InputStream iStream) throws Exception { + + File tempDir = new File(System.getProperty("java.io.tmpdir")); + File tempFile = new File(tempDir.getAbsolutePath(), name + System.currentTimeMillis()); + + // The temp file shouldn't be there, but check and delete it if it is + if (tempFile.exists()) { + getLog().warn("Existing temporary file found and will be deleted at: " + tempFile); + tempFile.delete(); + } + + FileUtil.writeFile(iStream, tempFile); + + if (!tempFile.exists()) { + String err = "Temporary file for application update not written to: " + tempFile; + getLog().error(err); + throw new Exception(err); + } + + return tempFile; + } + } diff --git a/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-perspective.xsd b/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-perspective.xsd index 85aa20b..ce586b7 100644 --- a/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-perspective.xsd +++ b/modules/enterprise/server/xml-schemas/src/main/resources/rhq-serverplugin-perspective.xsd @@ -13,7 +13,7 @@
xs:annotation xs:documentation - Schema for the definition Perspective service objects + Schema for a Perspective Descriptor. Perspective are deployed as Server Plugins. </xs:documentation> xs:appinfo jaxb:schemaBindings @@ -25,11 +25,10 @@ <xs:element name="perspective-plugin" type="perspective:PerspectivePluginDescriptorType" substitutionGroup="serverplugin:server-plugin"> xs:annotation xs:documentation - Defines a generic plugin. This type of plugin does not - need any additional support from the server plugin container other than - simple lifecycle management (for example, be told when to start and stop). - The plugin is otherwise standalone and can do everything it needs to do - without additional help from the server plugin container. + Defines a Perspective plugin. A Perspective is deployed as a Server Plugin. + The Server Plugin Container (SPC) handles simple lifecycle management for + the deployed plugins (e.g. start, stop). The plugin is otherwise standalone + and can do everything it needs to do without additional help from the SPC. </xs:documentation> xs:appinfo <jaxb:class name="PerspectivePluginElement" /> diff --git a/modules/enterprise/server/xml-schemas/src/test/java/org/rhq/enterprise/server/xmlschema/ServerPluginDescriptorUtilTest.java b/modules/enterprise/server/xml-schemas/src/test/java/org/rhq/enterprise/server/xmlschema/ServerPluginDescriptorUtilTest.java index 7f2029d..419bfe2 100644 --- a/modules/enterprise/server/xml-schemas/src/test/java/org/rhq/enterprise/server/xmlschema/ServerPluginDescriptorUtilTest.java +++ b/modules/enterprise/server/xml-schemas/src/test/java/org/rhq/enterprise/server/xmlschema/ServerPluginDescriptorUtilTest.java @@ -42,6 +42,7 @@ import org.rhq.enterprise.server.xmlschema.generated.serverplugin.ScheduleType; import org.rhq.enterprise.server.xmlschema.generated.serverplugin.ServerPluginDescriptorType; import org.rhq.enterprise.server.xmlschema.generated.serverplugin.alert.AlertPluginDescriptorType; import org.rhq.enterprise.server.xmlschema.generated.serverplugin.generic.GenericPluginDescriptorType; +import org.rhq.enterprise.server.xmlschema.generated.serverplugin.perspective.PerspectivePluginDescriptorType;
/** * Tests that we can parse server-side plugin descriptors. @@ -106,6 +107,20 @@ public class ServerPluginDescriptorUtilTest { assert config.getConfigurationProperty().get(0).getValue().getName().equals("alertprop1"); }
+ public void testPerspectivePluginDescriptor() throws Exception { + String testXml = "test-serverplugin-perspective.xml"; + ServerPluginDescriptorType data = parseTestXml(testXml); + assert data instanceof PerspectivePluginDescriptorType; + PerspectivePluginDescriptorType descriptor = (PerspectivePluginDescriptorType) data; + + assert descriptor.getApiVersion().equals("1.0"); + assert descriptor.getVersion().equals("1.0"); + assert descriptor.getName().equals("SamplePerspective"); + assert descriptor.getDisplayName().equals("Sample Perspective"); + assert descriptor.getDescription().equals("A Sample Perspective Utilizing Every Extension Point and Filter"); + assert descriptor.getPackage().equals("org.rhq.perspective.sample"); + } + private ServerPluginDescriptorType parseTestXml(String testXml) throws Exception { Unmarshaller unmarshaller = ServerPluginDescriptorUtil.getServerPluginDescriptorUnmarshaller(); URL url = this.getClass().getClassLoader().getResource(testXml);
commit 4a9a5df7e421c4384e72afa1396980341a2ca2dd Author: Jay Shaughnessy jshaughn@redhat.com Date: Wed Nov 11 13:37:13 2009 -0500
[Jopr-408, Jopr-414] protect against not being able to get procExe from Sigar
diff --git a/modules/core/native-system/src/main/java/org/rhq/core/system/ProcessInfo.java b/modules/core/native-system/src/main/java/org/rhq/core/system/ProcessInfo.java index 817813e..18d3f3c 100644 --- a/modules/core/native-system/src/main/java/org/rhq/core/system/ProcessInfo.java +++ b/modules/core/native-system/src/main/java/org/rhq/core/system/ProcessInfo.java @@ -1,31 +1,31 @@ - /* - * RHQ Management Platform - * Copyright (C) 2005-2008 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, version 2, as - * published by the Free Software Foundation, and/or the GNU Lesser - * General Public License, version 2.1, also as published by the Free - * Software Foundation. - * - * 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 and the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * and the GNU Lesser 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. - */ +/* + * RHQ Management Platform + * Copyright (C) 2005-2008 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, version 2, as + * published by the Free Software Foundation, and/or the GNU Lesser + * General Public License, version 2.1, also as published by the Free + * Software Foundation. + * + * 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 and the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * and the GNU Lesser 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.core.system;
+import java.io.File; +import java.util.Collections; import java.util.HashMap; import java.util.Map; -import java.util.Collections; -import java.io.File;
import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -178,24 +178,21 @@ public class ProcessInfo { this.procCredName = sigar.getProcCredName(pid); } catch (Exception e) { handleSigarCallException(e, "getProcCredName"); - } + } } catch (Exception e) { throw new SystemInfoException(e); } if (log.isDebugEnabled()) { long elapsedTime = System.currentTimeMillis() - startTime; - log.debug("Retrieval of process info for pid " + pid + " took " + elapsedTime + " ms." ); + log.debug("Retrieval of process info for pid " + pid + " took " + elapsedTime + " ms."); } }
public void destroy() throws SystemInfoException { if (this.sigar instanceof Sigar) { - try - { - ((Sigar)this.sigar).close(); - } - catch (RuntimeException e) - { + try { + ((Sigar) this.sigar).close(); + } catch (RuntimeException e) { throw new SystemInfoException(e); } } @@ -213,23 +210,27 @@ public class ProcessInfo { // Only log permissions errors once per process. String currentUserName = System.getProperty("user.name"); log - .trace("Unable to obtain all info for [" + procName + "] process with pid [" + this.pid - + "] - call to " + methodName + "failed. " - + "The process is most likely owned by a user other than the user that owns the RHQ plugin container's process (" - + currentUserName + ")."); + .trace("Unable to obtain all info for [" + + procName + + "] process with pid [" + + this.pid + + "] - call to " + + methodName + + "failed. " + + "The process is most likely owned by a user other than the user that owns the RHQ plugin container's process (" + + currentUserName + ")."); this.loggedPermissionsError = true; } } else if (e instanceof SigarNotImplementedException) { log.trace("Unable to obtain all info for [" + procName + "] process with pid [" + this.pid + "] - call to " - + methodName + "failed. Cause: " + e); + + methodName + "failed. Cause: " + e); } else { log.debug("Unexpected error occurred while looking up info for [" + procName + "] process with pid [" - + this.pid + "] - call to " + methodName + " failed. Did the process die? Cause: " + e); + + this.pid + "] - call to " + methodName + " failed. Did the process die? Cause: " + e); } }
- private static boolean isWindows() - { + private static boolean isWindows() { return File.separatorChar == '\'; }
@@ -321,8 +322,7 @@ public class ProcessInfo { * @return the environment value */ @Nullable - public String getEnvironmentVariable(@NotNull - String name) { + public String getEnvironmentVariable(@NotNull String name) { if (this.procEnv == null) { return null; } @@ -369,18 +369,31 @@ public class ProcessInfo { return this.procCredName; }
+ /** + * @return null if process executable or cwd is unavailable. Otherwise the Cwd as returned from the + * process executable. + * @throws SystemInfoException + */ public String getCurrentWorkingDirectory() throws SystemInfoException { - return this.procExe.getCwd(); + String result = null; + + try { + if (null != this.procExe) { + result = this.procExe.getCwd(); + } + } catch (Exception e) { + handleSigarCallException(e, "procExe.getCwd()"); + } + + return result; }
public boolean isRunning() throws SystemInfoException { boolean running = false;
if (this.procState != null) { - running = ( - this.procState.getState() == ProcState.RUN - || this.procState.getState() == ProcState.SLEEP - || this.procState.getState() == ProcState.IDLE); + running = (this.procState.getState() == ProcState.RUN || this.procState.getState() == ProcState.SLEEP || this.procState + .getState() == ProcState.IDLE);
}
diff --git a/modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/helper/JBossInstanceInfo.java b/modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/helper/JBossInstanceInfo.java index 45e2e3a..991c68c 100644 --- a/modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/helper/JBossInstanceInfo.java +++ b/modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/helper/JBossInstanceInfo.java @@ -37,8 +37,9 @@ import java.util.Properties;
import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.rhq.core.util.StringPropertyReplacer; + import org.rhq.core.system.ProcessInfo; +import org.rhq.core.util.StringPropertyReplacer; import org.rhq.plugins.jbossas5.util.JBossConfigurationUtility;
/** @@ -149,6 +150,13 @@ public class JBossInstanceInfo {
case 'P': // 'P' (--properties) { + // cwd can be null if native support is not able to determine CWD. + if (null == currentWorkingDir) { + log.error("Could not determine CWD. Failed to parse argument to --properties option: " + + options.getOptarg()); + break; + } + String arg = options.getOptarg(); URL url; try { diff --git a/modules/plugins/jboss-as/src/main/java/org/rhq/plugins/jbossas/helper/JBossInstanceInfo.java b/modules/plugins/jboss-as/src/main/java/org/rhq/plugins/jbossas/helper/JBossInstanceInfo.java index e145e60..3ae813e 100644 --- a/modules/plugins/jboss-as/src/main/java/org/rhq/plugins/jbossas/helper/JBossInstanceInfo.java +++ b/modules/plugins/jboss-as/src/main/java/org/rhq/plugins/jbossas/helper/JBossInstanceInfo.java @@ -1,27 +1,30 @@ - /* - * Jopr Management Platform - * Copyright (C) 2005-2008 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, version 2, as - * published by the Free Software Foundation, and/or the GNU Lesser - * General Public License, version 2.1, also as published by the Free - * Software Foundation. - * - * 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 and the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * and the GNU Lesser 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. - */ +/* + * Jopr Management Platform + * Copyright (C) 2005-2008 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, version 2, as + * published by the Free Software Foundation, and/or the GNU Lesser + * General Public License, version 2.1, also as published by the Free + * Software Foundation. + * + * 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 and the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * and the GNU Lesser 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.plugins.jbossas.helper;
+import gnu.getopt.Getopt; +import gnu.getopt.LongOpt; + import java.io.BufferedInputStream; import java.io.File; import java.io.IOException; @@ -32,15 +35,11 @@ import java.net.UnknownHostException; import java.util.Arrays; import java.util.Properties;
-import gnu.getopt.Getopt; -import gnu.getopt.LongOpt; - import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory;
-import org.rhq.core.util.StringPropertyReplacer; - import org.rhq.core.system.ProcessInfo; +import org.rhq.core.util.StringPropertyReplacer; import org.rhq.plugins.jbossas.util.JBossConfigurationUtility;
/** @@ -96,8 +95,7 @@ public class JBossInstanceInfo { return this.installInfo; }
- private void processJvmArgs(String args[]) - throws Exception { + private void processJvmArgs(String args[]) throws Exception { // NOTE: We can't use GNU GetOpt to process the JVM options, because they are not GNU-style options. for (int i = 0; i < args.length; i++) { String arg = args[i]; @@ -107,8 +105,7 @@ public class JBossInstanceInfo { continue; } this.classPath = args[i + 1].split(File.pathSeparator); - } - else if (arg.startsWith("-D")) { + } else if (arg.startsWith("-D")) { addPropArgToProps(arg.substring("-D".length()), this.sysProps); } } @@ -117,84 +114,84 @@ public class JBossInstanceInfo { private void processJBossArgs(String currentWorkingDir, String args[]) { String programName = this.sysProps.getProperty("program.name", "jboss"); String shortOpts = "-:b:c:D:P:"; - LongOpt longOpts[] = { - new LongOpt("configuration", 1, null, 'c'), - new LongOpt("properties", 1, null, 'P'), - new LongOpt("host", 1, null, 'b'), - }; + LongOpt longOpts[] = { new LongOpt("configuration", 1, null, 'c'), new LongOpt("properties", 1, null, 'P'), + new LongOpt("host", 1, null, 'b'), }; Getopt options = new Getopt(programName, args, shortOpts, longOpts); // Tell Getopt not to complain to stderr about unrecognized options... options.setOpterr(false); int c; while ((c = options.getopt()) != -1) { switch (c) { - case 'b': // 'b' (--host) - { - String arg = options.getOptarg(); - this.sysProps.setProperty(JBossProperties.BIND_ADDRESS, arg); - break; + case 'b': // 'b' (--host) + { + String arg = options.getOptarg(); + this.sysProps.setProperty(JBossProperties.BIND_ADDRESS, arg); + break; + } + + case 'c': // 'c' (--configuration) + { + String arg = options.getOptarg(); + this.sysProps.setProperty(JBossProperties.SERVER_NAME, arg); + break; + } + + case 'D': // 'D' + { + String arg = options.getOptarg(); + String name = addPropArgToProps(arg, this.sysProps); + String value = this.sysProps.getProperty(name); + if (value.equals("")) { + // unlike the JVM, org.jboss.Main interprets -Dfoo as foo="true", rather than as foo="" + this.sysProps.setProperty(name, Boolean.TRUE.toString()); } + break; + }
- case 'c': // 'c' (--configuration) - { - String arg = options.getOptarg(); - this.sysProps.setProperty(JBossProperties.SERVER_NAME, arg); + case 'P': // 'P' (--properties) + { + // cwd can be null if native support is not able to determine CWD. + if (null == currentWorkingDir) { + log.error("Could not determine CWD. Failed to parse argument to --properties option: " + + options.getOptarg()); break; }
- case 'D': // 'D' - { - String arg = options.getOptarg(); - String name = addPropArgToProps(arg, this.sysProps); - String value = this.sysProps.getProperty(name); - if (value.equals("")) { - // unlike the JVM, org.jboss.Main interprets -Dfoo as foo="true", rather than as foo="" - this.sysProps.setProperty(name, Boolean.TRUE.toString()); - } + String arg = options.getOptarg(); + URL url; + try { + File workingDir = new File(currentWorkingDir); + url = JBossConfigurationUtility.makeURL(arg, workingDir); + } catch (Exception e) { + log.error("Failed to parse argument to --properties option: " + options.getOptarg()); break; } - - case 'P': // 'P' (--properties) - { - String arg = options.getOptarg(); - URL url; - try { - File workingDir = new File(currentWorkingDir); - url = JBossConfigurationUtility.makeURL(arg, workingDir); - } - catch (Exception e) { - log.error("Failed to parse argument to --properties option: " + options.getOptarg()); - break; - } - Properties props = new Properties(); - InputStream inputStream = null; - try { - inputStream = new BufferedInputStream(url.openConnection().getInputStream()); - props.load(inputStream); - } - catch (IOException e) { - log.error("Could not read properties from file: " + arg, e); - break; - } - finally { - if (inputStream != null) { - try { - inputStream.close(); - } - catch (IOException e) { - log.error("Failed to close properties file: " + arg, e); - // not fatal - continue processing... - } + Properties props = new Properties(); + InputStream inputStream = null; + try { + inputStream = new BufferedInputStream(url.openConnection().getInputStream()); + props.load(inputStream); + } catch (IOException e) { + log.error("Could not read properties from file: " + arg, e); + break; + } finally { + if (inputStream != null) { + try { + inputStream.close(); + } catch (IOException e) { + log.error("Failed to close properties file: " + arg, e); + // not fatal - continue processing... } } - for (Object nameObj : props.keySet()) { - String name = (String)nameObj; - String value = props.getProperty(name); - String newValue = StringPropertyReplacer.replaceProperties(value, this.sysProps); - this.sysProps.setProperty(name, newValue); - } - break; } + for (Object nameObj : props.keySet()) { + String name = (String) nameObj; + String value = props.getProperty(name); + String newValue = StringPropertyReplacer.replaceProperties(value, this.sysProps); + this.sysProps.setProperty(name, newValue); + } + break; + } } } } @@ -206,8 +203,7 @@ public class JBossInstanceInfo { if (i == -1) { name = arg; value = ""; - } - else { + } else { name = arg.substring(0, i); value = arg.substring(i + 1, arg.length()); } @@ -223,19 +219,19 @@ public class JBossInstanceInfo { */ private File getHomeDir() throws Exception {
- File runJar=null; - File binDir=null; - File homeDir=null; + File runJar = null; + File binDir = null; + File homeDir = null; // method 1: should work 99% of the time. - if (this.processInfo != null && this.processInfo.getExecutable()!=null && - this.processInfo.getExecutable().getCwd() != null) { - homeDir = new File(this.processInfo.getExecutable().getCwd()).getParentFile(); - binDir = new File(homeDir, "bin"); - runJar = new File(binDir, "run.jar"); - if (runJar.exists()) { - return homeDir; - } - } + if (this.processInfo != null && this.processInfo.getExecutable() != null + && this.processInfo.getExecutable().getCwd() != null) { + homeDir = new File(this.processInfo.getExecutable().getCwd()).getParentFile(); + binDir = new File(homeDir, "bin"); + runJar = new File(binDir, "run.jar"); + if (runJar.exists()) { + return homeDir; + } + } // method 2: more expensive, but also more reliable. for (String pathElement : this.classPath) { if (pathElement.endsWith("run.jar")) { @@ -264,8 +260,7 @@ public class JBossInstanceInfo { File homeDir; if (this.sysProps.containsKey(JBossProperties.HOME_DIR)) { homeDir = new File(this.sysProps.getProperty(JBossProperties.HOME_DIR)); - } - else { + } else { homeDir = getHomeDir(); this.sysProps.setProperty(JBossProperties.HOME_DIR, homeDir.toString()); } @@ -284,7 +279,8 @@ public class JBossInstanceInfo { } this.installInfo = new JBossInstallationInfo(homeDir); if (!this.sysProps.containsKey(JBossProperties.SERVER_NAME)) { - this.sysProps.setProperty(JBossProperties.SERVER_NAME, this.installInfo.getProductType().DEFAULT_CONFIG_NAME); + this.sysProps.setProperty(JBossProperties.SERVER_NAME, + this.installInfo.getProductType().DEFAULT_CONFIG_NAME); } String serverName = this.sysProps.getProperty(JBossProperties.SERVER_NAME); if (!this.sysProps.containsKey(JBossProperties.SERVER_HOME_DIR)) { @@ -304,8 +300,7 @@ public class JBossInstanceInfo { String jgroupsBindAddr = this.sysProps.getProperty(JBossProperties.JGROUPS_BIND_ADDR); if (jgroupsBindAddress == null) { jgroupsBindAddress = (jgroupsBindAddr != null) ? jgroupsBindAddr : remoteAddress; - this.sysProps.setProperty(JBossProperties.JGROUPS_BIND_ADDRESS, - jgroupsBindAddress); + this.sysProps.setProperty(JBossProperties.JGROUPS_BIND_ADDRESS, jgroupsBindAddress); } if (jgroupsBindAddr == null) { this.sysProps.setProperty(JBossProperties.JGROUPS_BIND_ADDR, jgroupsBindAddress); @@ -341,8 +336,7 @@ public class JBossInstanceInfo { try { if (address == null || address.equals(ANY_ADDRESS)) return InetAddress.getLocalHost().getHostName(); - } - catch (UnknownHostException ignored) { + } catch (UnknownHostException ignored) { } return address; }
commit 6acd49ae6d8ed6ea4720ee4fb621dd3328dc3ea2 Author: Jay Shaughnessy jshaughn@redhat.com Date: Wed Nov 11 13:35:49 2009 -0500
[RHQ-2479] avoid hibernate cache for large metric template update
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/measurement/MeasurementDefinition.java b/modules/core/domain/src/main/java/org/rhq/core/domain/measurement/MeasurementDefinition.java index 9b0be6a..48a682d 100644 --- a/modules/core/domain/src/main/java/org/rhq/core/domain/measurement/MeasurementDefinition.java +++ b/modules/core/domain/src/main/java/org/rhq/core/domain/measurement/MeasurementDefinition.java @@ -75,6 +75,23 @@ import org.rhq.core.domain.resource.ResourceType; @Table(name = "RHQ_MEASUREMENT_DEF") public class MeasurementDefinition implements Serializable {
+ public static final String QUERY_NATIVE_UPDATE_DEFAULT_ON_BY_IDS = "" // + + "UPDATE RHQ_MEASUREMENT_DEF" // + + " SET DEFAULT_ON = ?" // + + " WHERE ID IN ( @@DEFINITION_IDS@@ )"; + public static final String QUERY_NATIVE_UPDATE_DEFAULTS_BY_IDS = "" // + + "UPDATE RHQ_MEASUREMENT_DEF" // + + " SET DEFAULT_ON = ?, DEFAULT_INTERVAL = ?" // + + " WHERE ID IN ( @@DEFINITION_IDS@@ )"; + public static final String QUERY_NATIVE_UPDATE_SCHEDULES_ENABLE_BY_IDS = "" // + + "UPDATE RHQ_MEASUREMENT_SCHED" // + + " SET ENABLED = ?" // + + " WHERE DEFINITION IN ( @@DEFINITION_IDS@@ )"; + public static final String QUERY_NATIVE_UPDATE_SCHEDULES_BY_IDS = "" // + + "UPDATE RHQ_MEASUREMENT_SCHED" // + + " SET ENABLED = ?, COLL_INTERVAL = ?" // + + " WHERE DEFINITION IN ( @@DEFINITION_IDS@@ )"; + private static final long serialVersionUID = 1L;
public static final String FIND_BY_RESOURCE_TYPE_DATA_TYPE_DISPLAY_TYPE = "MeasurementDefinition.findByResourceTypeDataTypeDisplayType"; diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementScheduleManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementScheduleManagerBean.java index aa28f40..6080f7b 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementScheduleManagerBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementScheduleManagerBean.java @@ -613,81 +613,149 @@ public class MeasurementScheduleManagerBean implements MeasurementScheduleManage
private void modifyDefaultCollectionIntervalForMeasurementDefinitions(Subject subject, int[] measurementDefinitionIds, long collectionInterval, boolean updateExistingSchedules) { - modifyDefaultCollectionIntervalForMeasurementDefinitions(subject, measurementDefinitionIds, - collectionInterval > 0, collectionInterval, updateExistingSchedules); - } - - private void modifyDefaultCollectionIntervalForMeasurementDefinitions(Subject subject, - int[] measurementDefinitionIds, boolean enableDisable, long collectionInterval, boolean updateExistingSchedules) {
if (measurementDefinitionIds == null || measurementDefinitionIds.length == 0) { log.debug("update metric template: no definitions supplied (interval = " + collectionInterval); return; }
- List<MeasurementDefinition> measurementDefinitions = getDefinitionsByIds(measurementDefinitionIds); - for (MeasurementDefinition measurementDefinition : measurementDefinitions) { - measurementDefinition.setDefaultOn(enableDisable); - if (collectionInterval > 0) { - measurementDefinition.setDefaultInterval(collectionInterval); - } + boolean enableDisable = (collectionInterval > 0); + + // batch the modifications to prevent the ORA error about IN clauses containing more than 1000 items + for (int batchIndex = 0; (batchIndex < measurementDefinitionIds.length); batchIndex += 1000) { + int[] batchIdArray = ArrayUtils.copyOfRange(measurementDefinitionIds, batchIndex, batchIndex + 1000); + + modifyDefaultCollectionIntervalForMeasurementDefinitions(subject, batchIdArray, enableDisable, + collectionInterval, updateExistingSchedules); } + }
- Map<Integer, ResourceMeasurementScheduleRequest> reqMap = new HashMap<Integer, ResourceMeasurementScheduleRequest>(); - if (updateExistingSchedules) { - for (MeasurementDefinition measurementDefinition : measurementDefinitions) { - // check if schedules need to be updated as well + /** + * @param measurementDefinitionIds 1 <= length <= 1000. + */ + @SuppressWarnings("unchecked") + private void modifyDefaultCollectionIntervalForMeasurementDefinitions(Subject subject, + int[] measurementDefinitionIds, boolean enableDisable, long collectionInterval, boolean updateExistingSchedules) {
- List<MeasurementSchedule> schedules = measurementDefinition.getSchedules(); - for (MeasurementSchedule sched : schedules) { - sched.setEnabled(enableDisable); - if (collectionInterval > 0) { - sched.setInterval(collectionInterval); - } + // this method has been rewritten to ensure that the Hibernate cache is not utilized in an + // extensive way, regardless of the number of measurementDefinitionIds being processed. Future + // enhancements must keep this in mind and avoid using attached objects.
- // Create update requests to feed to the agents - int resourceId = sched.getResource().getId(); - if (!reqMap.containsKey(resourceId)) { - ResourceMeasurementScheduleRequest req = new ResourceMeasurementScheduleRequest(resourceId); - reqMap.put(resourceId, req); - } + // update all of the measurement definitions via native query to avoid Hibernate caching + Connection conn = null; + PreparedStatement defUpdateStmt = null; + PreparedStatement schedUpdateStmt = null; + String queryString = null; + int i; + try { + conn = dataSource.getConnection(); + + // update the defaults on the measurement definitions + queryString = (collectionInterval > 0L) ? MeasurementDefinition.QUERY_NATIVE_UPDATE_DEFAULTS_BY_IDS + : MeasurementDefinition.QUERY_NATIVE_UPDATE_DEFAULT_ON_BY_IDS; + + String transformedQuery = JDBCUtil.transformQueryForMultipleInParameters(queryString, "@@DEFINITION_IDS@@", + measurementDefinitionIds.length); + defUpdateStmt = conn.prepareStatement(transformedQuery); + i = 1; + defUpdateStmt.setBoolean(i++, enableDisable); + if (collectionInterval > 0L) { + defUpdateStmt.setLong(i++, collectionInterval); + } + JDBCUtil.bindNTimes(defUpdateStmt, measurementDefinitionIds, i++); + defUpdateStmt.executeUpdate(); + + if (updateExistingSchedules) { + Map<Integer, ResourceMeasurementScheduleRequest> reqMap = new HashMap<Integer, ResourceMeasurementScheduleRequest>(); + List<Integer> idsAsList = ArrayUtils.wrapInList(measurementDefinitionIds); + + // update the schedules associated with the measurement definitions (i.e. the current inventory) + queryString = (collectionInterval > 0L) ? MeasurementDefinition.QUERY_NATIVE_UPDATE_SCHEDULES_BY_IDS + : MeasurementDefinition.QUERY_NATIVE_UPDATE_SCHEDULES_ENABLE_BY_IDS; + + transformedQuery = JDBCUtil.transformQueryForMultipleInParameters(queryString, "@@DEFINITION_IDS@@", + measurementDefinitionIds.length); + schedUpdateStmt = conn.prepareStatement(transformedQuery); + i = 1; + schedUpdateStmt.setBoolean(i++, enableDisable); + if (collectionInterval > 0L) { + schedUpdateStmt.setLong(i++, collectionInterval); + } + JDBCUtil.bindNTimes(schedUpdateStmt, measurementDefinitionIds, i++); + schedUpdateStmt.executeUpdate(); + + // Notify the agents of the updated schedules for affected resources + + // we need specific information to construct the agent updates. This query is specific to + // this use case and therefore is define here and not in a domain module. Note that this + // query must not return domain entities as they would be placed in the Hibernate cache. + // Return only the data necessary to construct minimal objects ourselves. Using JPQL + // is ok, it just lets Hibernate do the heavy lifting for query generation. + queryString = "" // + + "SELECT ms.id, ms.resource.id, ms.definition.name, ms.definition.dataType, ms.definition.numericType" // + + " FROM MeasurementSchedule ms" // + + " WHERE ms.definition.id IN ( :definitionIds )"; + Query query = entityManager.createQuery(queryString); + query.setParameter("definitionIds", idsAsList); + List<Object[]> rs = query.getResultList(); + + for (Object[] row : rs) { + i = 0; + int schedId = (Integer) row[i++]; + int resourceId = (Integer) row[i++]; + String name = (String) row[i++]; + DataType dataType = (DataType) row[i++]; + NumericType numericType = (NumericType) row[i++];
ResourceMeasurementScheduleRequest req = reqMap.get(resourceId); - MeasurementScheduleRequest msr = new MeasurementScheduleRequest(sched); + if (null == req) { + req = new ResourceMeasurementScheduleRequest(resourceId); + reqMap.put(resourceId, req); + } + MeasurementScheduleRequest msr = new MeasurementScheduleRequest(schedId, name, collectionInterval, + enableDisable, dataType, numericType); req.addMeasurementScheduleRequest(msr); } - }
- Map<Agent, Set<ResourceMeasurementScheduleRequest>> agentUpdates = null; - agentUpdates = new HashMap<Agent, Set<ResourceMeasurementScheduleRequest>>(); + Map<Agent, Set<ResourceMeasurementScheduleRequest>> agentUpdates = null; + agentUpdates = new HashMap<Agent, Set<ResourceMeasurementScheduleRequest>>();
- for (Integer resourceId : reqMap.keySet()) { - Agent agent = agentManager.getAgentByResourceId(resourceId); + // The number of Agents is manageable, so we can work with entities here + for (Integer resourceId : reqMap.keySet()) { + Agent agent = agentManager.getAgentByResourceId(resourceId);
- Set<ResourceMeasurementScheduleRequest> agentUpdate = agentUpdates.get(agent); - if (agentUpdate == null) { - agentUpdate = new HashSet<ResourceMeasurementScheduleRequest>(); - agentUpdates.put(agent, agentUpdate); - } + Set<ResourceMeasurementScheduleRequest> agentUpdate = agentUpdates.get(agent); + if (agentUpdate == null) { + agentUpdate = new HashSet<ResourceMeasurementScheduleRequest>(); + agentUpdates.put(agent, agentUpdate); + }
- agentUpdate.add(reqMap.get(resourceId)); - } + agentUpdate.add(reqMap.get(resourceId)); + }
- // convert the int[] to Integer[], incase we need to set - List<Integer> measurementDefinitionList = ArrayUtils.wrapInList(measurementDefinitionIds); - // send schedule updates to agents - for (Map.Entry<Agent, Set<ResourceMeasurementScheduleRequest>> agentEntry : agentUpdates.entrySet()) { - boolean synced = sendUpdatedSchedulesToAgent(agentEntry.getKey(), agentEntry.getValue()); - if (!synced) { - /* - * only sync resources that are affected by this set of definitions that were updated, and only - * for the agent that couldn't be contacted (under the assumption that 9 times out of 10 the agent - * will be up; so, we don't want to unnecessarily mark more resources as needing syncing that don't - */ - int agentId = agentEntry.getKey().getId(); - setAgentSynchronizationNeededByDefinitionsForAgent(agentId, measurementDefinitionList); + // convert the int[] to Integer[], in case we need to set + // send schedule updates to agents + for (Map.Entry<Agent, Set<ResourceMeasurementScheduleRequest>> agentEntry : agentUpdates.entrySet()) { + boolean synced = sendUpdatedSchedulesToAgent(agentEntry.getKey(), agentEntry.getValue()); + if (!synced) { + /* + * only sync resources that are affected by this set of definitions that were updated, and only + * for the agent that couldn't be contacted (under the assumption that 9 times out of 10 the agent + * will be up; so, we don't want to unnecessarily mark more resources as needing syncing that don't + */ + int agentId = agentEntry.getKey().getId(); + setAgentSynchronizationNeededByDefinitionsForAgent(agentId, idsAsList); + } } } + + } catch (Exception e) { + log.error("Error updating measurement definitions: ", e); + throw new MeasurementException("Error updating measurement definitions: " + e.getMessage()); + } finally { + JDBCUtil.safeClose(defUpdateStmt); + JDBCUtil.safeClose(schedUpdateStmt); + JDBCUtil.safeClose(conn); } }
commit b849a7261338787aeeebaee53192460c924ae3b3 Author: Jay Shaughnessy jshaughn@redhat.com Date: Wed Nov 11 13:31:13 2009 -0500
removed non-existent test dirs from src
diff --git a/etc/samples/sample-perspective/app/pom.xml b/etc/samples/sample-perspective/app/pom.xml new file mode 100644 index 0000000..acf9d67 --- /dev/null +++ b/etc/samples/sample-perspective/app/pom.xml @@ -0,0 +1,143 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.rhq</groupId> + <artifactId>rhq-parent</artifactId> + <version>1.4.0-SNAPSHOT</version> + </parent> + + <groupId>org.rhq</groupId> + <artifactId>rhq-sample-perspective-war</artifactId> + <packaging>war</packaging> + + <name>RHQ Sample Perspective War</name> + + <scm> + <connection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/etc/samples/sample-perspective/app/</connection> + <developerConnection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/etc/samples/sample-perspective/app/</developerConnection> + </scm> + + <properties> + <scm.module.path>modules/enterprise/gui/perspectives/sample-perspective-war/</scm.module.path> + <war.dir>${basedir}/target/${final.name}</war.dir> + </properties> + + <dependencies> + + </dependencies> + + <build> + <finalName>rhq-sample-perspective</finalName> + + <plugins> + + <plugin> + <artifactId>maven-war-plugin</artifactId> + <configuration> + <archive> + <manifest> + <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries> + <addDefaultImplementationEntries>true</addDefaultImplementationEntries> + </manifest> + <manifestEntries> + <Build-Number>${buildNumber}</Build-Number> + </manifestEntries> + </archive> + <webResources> + <resource> + <filtering>true</filtering> + <directory>${basedir}/src/main/webapp</directory> + <includes> + <include>**/*.properties</include> + </includes> + </resource> + </webResources> + </configuration> + </plugin> + + </plugins> + + </build> + + <profiles> + + <profile> + <id>dev</id> + + <properties> + <rhq.rootDir>../../../..</rhq.rootDir> + <rhq.containerDir>${rhq.rootDir}/${rhq.defaultDevContainerPath}</rhq.containerDir> + <rhq.deploymentName>${project.build.finalName}.war</rhq.deploymentName> + <rhq.deploymentDir>${rhq.containerDir}/jbossas/server/default/deploy/${rhq.deploymentName}</rhq.deploymentDir> + </properties> + + <build> + <plugins> + + <plugin> + <artifactId>maven-antrun-plugin</artifactId> + <version>1.1</version> + <executions> + + <execution> + <id>deploy-classes</id> + <phase>compile</phase> + <configuration> + <tasks> + <property name="classes.dir" location="${rhq.deploymentDir}/WEB-INF/classes" /> + <echo>*** Copying updated files from target/classes to ${classes.dir}...</echo> + <copy todir="${classes.dir}" failonerror="false" verbose="${rhq.verbose}"> + <fileset dir="target/classes" /> + </copy> + </tasks> + </configuration> + <goals> + <goal>run</goal> + </goals> + </execution> + + <execution> + <id>deploy</id> + <phase>package</phase> + <configuration> + <tasks> + <property name="deployment.dir" location="${rhq.deploymentDir}" /> + <echo>*** Copying updated files from target${file.separator}${project.build.finalName}${file.separator} to ${deployment.dir}${file.separator}...</echo> + <copy todir="${deployment.dir}" verbose="${rhq.verbose}"> + <fileset dir="${basedir}/target/${project.build.finalName}" /> + </copy> + <delete dir="${deployment.dir}.rej" /> <!-- need to remove any residual backups --> + </tasks> + </configuration> + <goals> + <goal>run</goal> + </goals> + </execution> + + <execution> + <id>undeploy</id> + <phase>clean</phase> + <configuration> + <tasks> + <property name="deployment.dir" location="${rhq.deploymentDir}" /> + <echo>*** Deleting ${deployment.dir}${file.separator}...</echo> + <delete dir="${deployment.dir}" /> + </tasks> + </configuration> + <goals> + <goal>run</goal> + </goals> + </execution> + + </executions> + </plugin> + + </plugins> + </build> + </profile> + + </profiles> + +</project> \ No newline at end of file diff --git a/etc/samples/sample-perspective/app/src/main/webapp/WEB-INF/web.xml b/etc/samples/sample-perspective/app/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000..a1968e1 --- /dev/null +++ b/etc/samples/sample-perspective/app/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<!DOCTYPE web-app + PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" + "http://java.sun.com/dtd/web-app_2_3.dtd"> + +<web-app> + <display-name>Welcome to Foo!</display-name> + <welcome-file-list> + <welcome-file>index.html</welcome-file> + </welcome-file-list> +</web-app> diff --git a/etc/samples/sample-perspective/app/src/main/webapp/index.html b/etc/samples/sample-perspective/app/src/main/webapp/index.html new file mode 100644 index 0000000..8bc586a --- /dev/null +++ b/etc/samples/sample-perspective/app/src/main/webapp/index.html @@ -0,0 +1,14 @@ +<script type="text/javascript"> + //document.domain = "redhat.com"; +</script> + +<!-- Force the page to be taller than the height of the browser + to test that a vertical scrollbar is not added to the + enclosing iframe. --> +<div style="padding: 10px; background-color: #DDF; height: 1000px;"> + <h4>It's always good to see something from another perspective.</h4> + + <p>The blue portion of this page is an IFRAME whose content was + loaded from rhq-sample-perspective.war, a WAR deployed to the + RHQ Server, as a sibling of rhq.ear.</p> +</div> diff --git a/etc/samples/sample-perspective/perspective/pom.xml b/etc/samples/sample-perspective/perspective/pom.xml new file mode 100644 index 0000000..533a07c --- /dev/null +++ b/etc/samples/sample-perspective/perspective/pom.xml @@ -0,0 +1,105 @@ +<?xml version="1.0"?> + +<project + xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd%22%3E + + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.rhq</groupId> + <artifactId>rhq-parent</artifactId> + <version>1.4.0-SNAPSHOT</version> + </parent> + + <groupId>org.rhq</groupId> + <artifactId>rhq-sample-perspective</artifactId> + <packaging>jar</packaging> + + <name>RHQ Sample Perspective</name> + <description>A Sample Perspective showing extension points and filters</description> + + <properties> + <rhq.version>1.4.0-SNAPSHOT</rhq.version> + </properties> + + <dependencies> + + <!-- Below are the apps packaged with this perspective plugin --> + <dependency> + <groupId>org.rhq</groupId> + <artifactId>rhq-sample-perspective-war</artifactId> + <version>${rhq.version}</version> + <scope>provided</scope> + <type>war</type> + </dependency> + + <!-- Below are the core modules that are required dependencies of all server plugins --> + <dependency> + <groupId>org.rhq</groupId> + <artifactId>rhq-enterprise-server</artifactId> + <version>${rhq.version}</version> + <scope>provided</scope> <!-- provided by the server/plugin-container --> + </dependency> + + <!-- uncomment the one of the three logging systems your plugin uses: log4j, commons-logging or i18nlog --> + <!-- all three are provided to your plugin by the server/plugin-container --> + <!-- + <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.14</version> + <scope>provided</scope> </dependency> + --> + + <!-- + <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.1</version> + <scope>provided</scope> </dependency> + --> + + <!-- + <dependency> <groupId>i18nlog</groupId> <artifactId>i18nlog</artifactId> <version>1.0.9</version> </dependency> + --> + + <!-- Define any third-party dependencies your plugin has here. --> + <!-- + <dependency> <groupId>group-id-of-dependency-goes-here</groupId> + <artifactId>artifact-id-of-dependency-goes-here</artifactId> <version>version-of-dependency-goes-here</version> + </dependency> + --> + + </dependencies> + + <build> + <finalName>${project.artifactId}</finalName> + + <plugins> + + <plugin> + <artifactId>maven-antrun-plugin</artifactId> + <version>1.1</version> + <executions> + + <execution> + <id>add-war</id> + <phase>install</phase> + <configuration> + <tasks> + <property + name="classes.dir" + location="${rhq.deploymentDir}/WEB-INF/classes" /> + <jar + update="yes" + destfile="${basedir}/target/${project.build.finalName}.jar" + basedir="${basedir}/../app/target" + includes="*.war" /> + </tasks> + </configuration> + <goals> + <goal>run</goal> + </goals> + </execution> + </executions> + </plugin> + </plugins> + </build> + +</project> diff --git a/etc/samples/sample-perspective/perspective/src/main/resources/META-INF/rhq-serverplugin.xml b/etc/samples/sample-perspective/perspective/src/main/resources/META-INF/rhq-serverplugin.xml new file mode 100644 index 0000000..490ae03 --- /dev/null +++ b/etc/samples/sample-perspective/perspective/src/main/resources/META-INF/rhq-serverplugin.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<perspective-plugin + apiVersion="1.0" + version="1.0" + description="A Sample Perspective Utilizing Every Extension Point and Filter" + displayName="Sample Perspective" + name="SamplePerspective" + package="org.rhq.perspective.sample" + xmlns="urn:xmlns:rhq-serverplugin.perspective" + xmlns:serverplugin="urn:xmlns:rhq-serverplugin" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance%22%3E + +</perspective-plugin> \ No newline at end of file diff --git a/etc/samples/sample-perspective/pom.xml b/etc/samples/sample-perspective/pom.xml new file mode 100644 index 0000000..50372f1 --- /dev/null +++ b/etc/samples/sample-perspective/pom.xml @@ -0,0 +1,45 @@ +<project + xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd%22%3E + + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.rhq</groupId> + <artifactId>rhq-parent</artifactId> + <version>1.4.0-SNAPSHOT</version> + </parent> + + <groupId>org.rhq</groupId> + <artifactId>rhq-sample-perspective-parent</artifactId> + <packaging>pom</packaging> + + <name>RHQ Sample Perspective Parent</name> + <description>parent POM for modules comprising the RHQ Sample Perspective</description> + + <scm> + <connection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/etc/samples/sample-perspective/</connection> + <developerConnection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/etc/samples/sample-perspective/</developerConnection> + </scm> + + <properties> + <scm.module.path>etc/samples/sample-perspective/</scm.module.path> + </properties> + + <profiles> + + <profile> + <id>default</id> + <activation> + <activeByDefault>true</activeByDefault> + </activation> + <modules> + <module>app</module> + <module>perspective</module> + </modules> + </profile> + + </profiles> + +</project> \ No newline at end of file diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/layout/main-layout.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/layout/main-layout.xhtml index eac2995..339a4ea 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/layout/main-layout.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/layout/main-layout.xhtml @@ -1,163 +1,163 @@ -<?xml version="1.0"?> - -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" - "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> - -<html xmlns="http://www.w3.org/1999/xhtml" - xmlns:h="http://java.sun.com/jsf/html" - xmlns:f="http://java.sun.com/jsf/core" - xmlns:ui="http://java.sun.com/jsf/facelets" - xmlns:c="http://java.sun.com/jstl/core" - xmlns:a4j="http://richfaces.org/a4j" - xmlns:onc="http://jboss.org/on/component" - xmlns:rich="http://richfaces.ajax4jsf.org/rich%22%3E - -<head> - <title>${msg["product.shortName"]} - #{(!empty pageTitle) ? pageTitle : defaultPageTitle}</title> - - <ui:insert name="metaHeaders"></ui:insert> - - <link rel="stylesheet" type="text/css" media="screen" href="/css/win.css"/> - <link rel="stylesheet" type="text/css" media="screen" href="/css/form-style.css"/> - <link rel="stylesheet" type="text/css" media="screen" href="/css/menu.css"/> - - <script type="text/javascript" src="/js/functions.js"></script> - <script type="text/javascript" src="/js/prototype.js"></script> - <script type="text/javascript" src="/js/window.js"></script> - <script type="text/javascript" src="/js/effects.js"></script> - <!--<script type="text/javascript" src="/js/debug.js"></script>--> - <script type="text/javascript" src="/js/formValues.js"></script> - <script type="text/javascript" src="/js/rhq.js"></script> - <script type="text/javascript" src="/js/popup.js"></script> - <script type="text/javascript" src="/js/iframeSSI.js"> - /*********************************************** - * IFrame SSI script II- © Dynamic Drive DHTML code library (http://www.dynamicdrive.com) - * Visit DynamicDrive.com for hundreds of original DHTML scripts - * This notice must stay intact for legal use - ***********************************************/ - </script> - - <link href="/css/theme/default.css" rel="stylesheet" type="text/css"/> - <link href="/css/theme/alphacube.css" rel="stylesheet" type="text/css"/> - <link href="/css/theme/debug.css" rel="stylesheet" type="text/css"/> - - <link rel="icon" type="image/png" href="/images/favicon.png"/> - <link rel="apple-touch-icon" href="/images/favicon.png"/> - - <!-- Trims up the headers of RF toggle panel headers --> - <style type="text/css"> - .BlockTitle { - padding-top: 3px; - padding-bottom: 3px; - } - HTML, BODY { overflow: hidden; } - </style> - - <link rel="stylesheet" type="text/css" media="screen" href="/css/tabular.css"/> - <link rel="stylesheet" type="text/css" media="screen" href="/css/layout.css"/> - - <script type="text/javascript"> - var imagePath = "/images/"; - </script> - -</head> - -<body bgcolor="#FFFFFF" style="height: 100%;"> - -ui:remove - <!-- Set the content type to "text/html" (overriding the default of "application/xhtml+xml") to force -Firefox and other Gecko-based browsers to render the page in "Almost Standards" (i.e. transitional) mode. --> -</ui:remove> -<f:view contentType="text/html"> - - - <f:loadBundle basename="ApplicationResources" var="msg"/> - - <!-- =================== PAGE HEADER =================== --> - - <script language="javascript" type="text/javascript"> - //this has to be defined before the resize trackers inside - //the PageBody element because they depend on the values - //computed inside this tracker function. - WindowResizeTracker.addListener(function() { - var header = $('PageHeader'); - var borderHeight = 2; //set in the inline style of div PageHeader - - if (Prototype.Browser.IE) { - header.style.height = WindowResizeTracker.currentSizes.windowHeight + 'px'; - } else { - header.style.height = (WindowResizeTracker.currentSizes.windowHeight - borderHeight) + 'px'; - } - header.style.width = WindowResizeTracker.currentSizes.windowWidth + 'px'; - - var body = $('PageBody'); - //27 = menu height (and the top position of PageBody) - body.style.height = (WindowResizeTracker.currentSizes.windowHeight - 27 - borderHeight) + 'px'; - body.style.width = header.style.width; - - document.body.style.height = WindowResizeTracker.currentSizes.windowHeight + 'px'; - }); - </script> - <!-- work around for IE and its broken box model. Without the concrete height value, the nav pane will shrink on hover. --> - <!--[if IE]> - <div id="PageHeader" style="border-bottom: 2px solid #999; position: absolute; top: 0; bottom: 0; left: 0; right: 0; height: 100%"> - <![endif]--> - <!--[if !IE]><!--> - <div id="PageHeader" style="border-bottom: 2px solid #999; position: absolute; top: 0; bottom: 0; left: 0; right: 0;"> - <!--<![endif]--> - - <ui:include src="/rhq/common/menu/menu.xhtml"/> - - <!-- work around for IE and its broken box model. Without the concrete height value, the nav pane will shrink on hover. --> - <!--[if IE]> - <div id="PageBody" style="width: 100%; position: absolute; top: 27px; bottom: 0; height: 100%;"> - <![endif]--> - <!--[if !IE]><!--> - <div id="PageBody" style="width: 100%; position: absolute; top: 27px; bottom: 0;"> - <!--<![endif]--> - <ui:insert name="body-area">Default Page Body</ui:insert> - </div> - - </div> - - - - <!-- =================== BODY =================== --> - - - <div id="about" class="dialog" style="display: none; position: absolute; top: 0; left: 0;"> - <div class="DisplayContent" style="margin: 0;"> - <div style="margin:5px"> - <p class="compact"> - <span class="DisplaySubhead">${msg['footer.aboutLink']}</span><br/> - <span class="DisplayLabel">${msg['footer.version']}: ${msg['product.version']}</span><br/> - <span class="DisplayLabel">${msg['footer.buildNumber']}: ${msg['product.buildNumber']}</span> - </p> - - <p class="compact"> - <f:verbatim>${msg['footer.copyright']}</f:verbatim> ${msg['about.Copyright.Content']} - </p> - - <p class="compact"> - ${msg['about.MoreInfo.Label']}<br/> - <a href="mailto:${msg['about.MoreInfo.LinkSales']}">${msg['about.MoreInfo.LinkSales']}</a><br/> - <a href="mailto:${msg['about.MoreInfo.LinkSupport']}">${msg['about.MoreInfo.LinkSupport']}</a> - </p> - </div> - </div> - </div> - - <!-- work-around to enable us to embed richfaces components inside the onc:simpleTrigger; -without this, the page will throw a javascript error "{blah} is not defined" or -"{yadda} is not a constructor", and the pop-up action will not work --> - <rich:calendar rendered="false"/> - <rich:inputNumberSpinner rendered="false"/> - -</f:view> - -<script type="text/javascript"> - addWindowOnLoadEvent(disableConditionalButtons); -</script> - -</body> -</html> +<?xml version="1.0"?> + +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<html xmlns="http://www.w3.org/1999/xhtml" + xmlns:h="http://java.sun.com/jsf/html" + xmlns:f="http://java.sun.com/jsf/core" + xmlns:ui="http://java.sun.com/jsf/facelets" + xmlns:c="http://java.sun.com/jstl/core" + xmlns:a4j="http://richfaces.org/a4j" + xmlns:onc="http://jboss.org/on/component" + xmlns:rich="http://richfaces.ajax4jsf.org/rich%22%3E + +<head> + <title>${msg["product.shortName"]} - #{(!empty pageTitle) ? pageTitle : defaultPageTitle}</title> + + <ui:insert name="metaHeaders"></ui:insert> + + <link rel="stylesheet" type="text/css" media="screen" href="/css/win.css"/> + <link rel="stylesheet" type="text/css" media="screen" href="/css/form-style.css"/> + <link rel="stylesheet" type="text/css" media="screen" href="/css/menu.css"/> + + <script type="text/javascript" src="/js/functions.js"></script> + <script type="text/javascript" src="/js/prototype.js"></script> + <script type="text/javascript" src="/js/window.js"></script> + <script type="text/javascript" src="/js/effects.js"></script> + <!--<script type="text/javascript" src="/js/debug.js"></script>--> + <script type="text/javascript" src="/js/formValues.js"></script> + <script type="text/javascript" src="/js/rhq.js"></script> + <script type="text/javascript" src="/js/popup.js"></script> + <script type="text/javascript" src="/js/iframeSSI.js"> + /*********************************************** + * IFrame SSI script II- © Dynamic Drive DHTML code library (http://www.dynamicdrive.com) + * Visit DynamicDrive.com for hundreds of original DHTML scripts + * This notice must stay intact for legal use + ***********************************************/ + </script> + + <link href="/css/theme/default.css" rel="stylesheet" type="text/css"/> + <link href="/css/theme/alphacube.css" rel="stylesheet" type="text/css"/> + <link href="/css/theme/debug.css" rel="stylesheet" type="text/css"/> + + <link rel="icon" type="image/png" href="/images/favicon.png"/> + <link rel="apple-touch-icon" href="/images/favicon.png"/> + + <!-- Trims up the headers of RF toggle panel headers --> + <style type="text/css"> + .BlockTitle { + padding-top: 3px; + padding-bottom: 3px; + } + HTML, BODY { overflow: hidden; } + </style> + + <link rel="stylesheet" type="text/css" media="screen" href="/css/tabular.css"/> + <link rel="stylesheet" type="text/css" media="screen" href="/css/layout.css"/> + + <script type="text/javascript"> + var imagePath = "/images/"; + </script> + +</head> + +<body bgcolor="#FFFFFF" style="height: 100%;"> + +ui:remove + <!-- Set the content type to "text/html" (overriding the default of "application/xhtml+xml") to force +Firefox and other Gecko-based browsers to render the page in "Almost Standards" (i.e. transitional) mode. --> +</ui:remove> +<f:view contentType="text/html"> + + + <f:loadBundle basename="ApplicationResources" var="msg"/> + + <!-- =================== PAGE HEADER =================== --> + + <script language="javascript" type="text/javascript"> + //this has to be defined before the resize trackers inside + //the PageBody element because they depend on the values + //computed inside this tracker function. + WindowResizeTracker.addListener(function() { + var header = $('PageHeader'); + var borderHeight = 2; //set in the inline style of div PageHeader + + if (Prototype.Browser.IE) { + header.style.height = WindowResizeTracker.currentSizes.windowHeight + 'px'; + } else { + header.style.height = (WindowResizeTracker.currentSizes.windowHeight - borderHeight) + 'px'; + } + header.style.width = WindowResizeTracker.currentSizes.windowWidth + 'px'; + + var body = $('PageBody'); + //27 = menu height (and the top position of PageBody) + body.style.height = (WindowResizeTracker.currentSizes.windowHeight - 27 - borderHeight) + 'px'; + body.style.width = header.style.width; + + document.body.style.height = WindowResizeTracker.currentSizes.windowHeight + 'px'; + }); + </script> + <!-- work around for IE and its broken box model. Without the concrete height value, the nav pane will shrink on hover. --> + <!--[if IE]> + <div id="PageHeader" style="border-bottom: 2px solid #999; position: absolute; top: 0; bottom: 0; left: 0; right: 0; height: 100%"> + <![endif]--> + <!--[if !IE]><!--> + <div id="PageHeader" style="border-bottom: 2px solid #999; position: absolute; top: 0; bottom: 0; left: 0; right: 0;"> + <!--<![endif]--> + + <ui:include src="/rhq/common/menu/menu.xhtml"/> + + <!-- work around for IE and its broken box model. Without the concrete height value, the nav pane will shrink on hover. --> + <!--[if IE]> + <div id="PageBody" style="width: 100%; position: absolute; top: 27px; bottom: 0; height: 100%;"> + <![endif]--> + <!--[if !IE]><!--> + <div id="PageBody" style="width: 100%; position: absolute; top: 27px; bottom: 0;"> + <!--<![endif]--> + <ui:insert name="body-area">Default Page Body</ui:insert> + </div> + + </div> + + + + <!-- =================== BODY =================== --> + + + <div id="about" class="dialog" style="display: none; position: absolute; top: 0; left: 0;"> + <div class="DisplayContent" style="margin: 0;"> + <div style="margin:5px"> + <p class="compact"> + <span class="DisplaySubhead">${msg['footer.aboutLink']}</span><br/> + <span class="DisplayLabel">${msg['footer.version']}: ${msg['product.version']}</span><br/> + <span class="DisplayLabel">${msg['footer.buildNumber']}: ${msg['product.buildNumber']}</span> + </p> + + <p class="compact"> + <f:verbatim>${msg['footer.copyright']}</f:verbatim> ${msg['about.Copyright.Content']} + </p> + + <p class="compact"> + ${msg['about.MoreInfo.Label']}<br/> + <a href="mailto:${msg['about.MoreInfo.LinkSales']}">${msg['about.MoreInfo.LinkSales']}</a><br/> + <a href="mailto:${msg['about.MoreInfo.LinkSupport']}">${msg['about.MoreInfo.LinkSupport']}</a> + </p> + </div> + </div> + </div> + + <!-- work-around to enable us to embed richfaces components inside the onc:simpleTrigger; +without this, the page will throw a javascript error "{blah} is not defined" or +"{yadda} is not a constructor", and the pop-up action will not work --> + <rich:calendar rendered="false"/> + <rich:inputNumberSpinner rendered="false"/> + +</f:view> + +<script type="text/javascript"> + addWindowOnLoadEvent(disableConditionalButtons); +</script> + +</body> +</html> diff --git a/modules/enterprise/server/xml-schemas/src/test/resources/test-serverplugin-perspective.xml b/modules/enterprise/server/xml-schemas/src/test/resources/test-serverplugin-perspective.xml new file mode 100644 index 0000000..f39a1b6 --- /dev/null +++ b/modules/enterprise/server/xml-schemas/src/test/resources/test-serverplugin-perspective.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<perspective-plugin + apiVersion="1.0" + version="1.0" + description="A Sample Perspective Utilizing Every Extension Point and Filter" + displayName="Sample Perspective" + name="SamplePerspective" + package="org.rhq.perspective.sample" + pluginLifecycleListener="perspectivePluginLifecycleListener" + xmlns="urn:xmlns:rhq-serverplugin.perspective" + xmlns:serverplugin="urn:xmlns:rhq-serverplugin" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance%22%3E + +</perspective-plugin>
commit 8fcbc7ff8b8ab3ee0e9630924ebb1e44134f4e38 Author: Adam Young ayoung@redhat.com Date: Thu Nov 12 16:03:58 2009 -0500
moved the functionality from this file into the parent class
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/AbstractResourceConfigurationUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/AbstractResourceConfigurationUIBean.java deleted file mode 100644 index 1c70f42..0000000 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/AbstractResourceConfigurationUIBean.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2008 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.gui.configuration.resource; - -import org.rhq.core.domain.auth.Subject; -import org.rhq.enterprise.gui.configuration.AbstractConfigurationUIBean; -import org.rhq.enterprise.gui.util.EnterpriseFacesContextUtility; - -/** - * This is a JSF managed bean for the Resource Configuration view and edit pages. The contents of the page are - * dynamically generated based on the ConfigurationDefinition (metadata) and current Configuration (data) for a - * specified Resource. - * - * @author Ian Springer - */ -public abstract class AbstractResourceConfigurationUIBean extends AbstractConfigurationUIBean { - - public boolean isUpdateInProgress() { - Subject subject = EnterpriseFacesContextUtility.getSubject(); - int resourceId = EnterpriseFacesContextUtility.getResource().getId(); - return this.configurationManager.isResourceConfigurationUpdateInProgress(subject, resourceId); - } - - public String getNullConfigurationDefinitionMessage() { - return "This resource does not expose a configuration."; - } - - public String getNullConfigurationMessage() { - return "This resource's configuration has not yet been initialized."; - } -} \ No newline at end of file
commit 0af20894fe555c82c63d92263883a045b5a6da53 Author: Adam Young ayoung@redhat.com Date: Thu Nov 12 16:00:39 2009 -0500
Integrated the translation from raw to structured and back. Not yest tested
diff --git a/.classpath b/.classpath index d88d80c..4ae73a2 100644 --- a/.classpath +++ b/.classpath @@ -13,7 +13,7 @@ <classpathentry kind="src" path="modules/plugins/tomcat/src/test/java"/> <classpathentry kind="src" path="modules/plugins/jboss-cache/src/main/java"/> <classpathentry kind="src" path="modules/plugins/jboss-cache-v3/src/main/java"/> - <classpathentry kind="src" path="modules/plugins/antlr-config/src/main/java"/> + <classpathentry excluding="org/rhq/plugins/antlrconfig/" kind="src" path="modules/plugins/antlr-config/src/main/java"/> <classpathentry kind="var" path="M2_REPO/org/jboss/integration/jboss-profileservice-spi/5.1.0.SP1/jboss-profileservice-spi-5.1.0.SP1.jar"/> <classpathentry kind="var" path="M2_REPO/org/jboss/man/jboss-managed/2.1.1.GA/jboss-managed-2.1.1.GA.jar"/> <classpathentry kind="var" path="M2_REPO/org/jboss/man/jboss-metatype/2.1.1.GA/jboss-metatype-2.1.1.GA.jar"/> diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/AbstractConfigurationUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/AbstractConfigurationUIBean.java index cd65d30..1245542 100644 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/AbstractConfigurationUIBean.java +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/AbstractConfigurationUIBean.java @@ -26,9 +26,11 @@ import javax.faces.context.FacesContext; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable;
+import org.rhq.core.domain.auth.Subject; import org.rhq.core.domain.configuration.Configuration; import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; import org.rhq.core.gui.util.FacesContextUtility; +import org.rhq.enterprise.gui.util.EnterpriseFacesContextUtility; import org.rhq.enterprise.server.configuration.ConfigurationManagerLocal; import org.rhq.enterprise.server.util.LookupUtil;
@@ -112,4 +114,18 @@ public abstract class AbstractConfigurationUIBean { public void clearConfiguration() { this.configurationMap.remove(getConfigurationKey()); } + + public boolean isUpdateInProgress() { + Subject subject = EnterpriseFacesContextUtility.getSubject(); + int resourceId = EnterpriseFacesContextUtility.getResource().getId(); + return this.configurationManager.isResourceConfigurationUpdateInProgress(subject, resourceId); + } + + public String getNullConfigurationDefinitionMessage() { + return "This resource does not expose a configuration."; + } + + public String getNullConfigurationMessage() { + return "This resource's configuration has not yet been initialized."; + } } \ No newline at end of file diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ExistingResourceConfigurationUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ExistingResourceConfigurationUIBean.java index 8007b7e..e717ed5 100644 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ExistingResourceConfigurationUIBean.java +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ExistingResourceConfigurationUIBean.java @@ -28,6 +28,7 @@ import org.rhq.core.domain.configuration.Configuration; import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; import org.rhq.core.gui.configuration.ConfigurationMaskingUtility; import org.rhq.core.gui.util.FacesContextUtility; +import org.rhq.enterprise.gui.configuration.AbstractConfigurationUIBean; import org.rhq.enterprise.gui.util.EnterpriseFacesContextUtility; import org.rhq.enterprise.server.configuration.ConfigurationManagerLocal; import org.rhq.enterprise.server.util.LookupUtil; @@ -35,7 +36,7 @@ import org.rhq.enterprise.server.util.LookupUtil; /** * @author Ian Springer */ -public class ExistingResourceConfigurationUIBean extends AbstractResourceConfigurationUIBean { +public class ExistingResourceConfigurationUIBean extends AbstractConfigurationUIBean { public static final String MANAGED_BEAN_NAME = "ExistingResourceConfigurationUIBean";
// =========== actions =========== @@ -53,6 +54,15 @@ public class ExistingResourceConfigurationUIBean extends AbstractResourceConfigu return SUCCESS_OUTCOME; }
+ public String switchToRaw() { + ConfigurationMaskingUtility.unmaskConfiguration(getConfiguration(), getConfigurationDefinition()); + int resourceId = EnterpriseFacesContextUtility.getResource().getId(); + this.configurationManager.translateResourceConfiguration(EnterpriseFacesContextUtility.getSubject(), + resourceId, getConfiguration(), true); + + return SUCCESS_OUTCOME; + } + public String updateConfiguration() { ConfigurationMaskingUtility.unmaskConfiguration(getConfiguration(), getConfigurationDefinition()); int resourceId = EnterpriseFacesContextUtility.getResource().getId(); diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/MockSupport.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/MockSupport.java new file mode 100644 index 0000000..78c7f83 --- /dev/null +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/MockSupport.java @@ -0,0 +1,45 @@ +package org.rhq.enterprise.gui.configuration.resource; + +import org.rhq.core.domain.configuration.RawConfiguration; + +public class MockSupport { + + public static void populateRawsMock(RawConfigCollection rawConfigCollection) { + String[] files = { "/etc/mock/file1", "/etc/mock/file2", "/etc/mock/file3", "/etc/mock/me/will/you", + "/etc/mock/turtle/soup", "/etc/mock/mysmock/iclean/yourclock" }; + + String[] filesContents = { + "GALLIA est omnis divisa in partes tres, quarum unam incolunt Belgae, \naliam Aquitani, tertiam qui ipsorum lingua Celtae, \n" + + "nostra Galli appellantur. \nHi omnes lingua, institutis, legibus inter se differunt. \n", + "I've seen all good people \n turn their heads each day \n So Satisfied\n I'm on my way", + "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor \nincididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis\n nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\n Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu\n fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in \nculpa qui officia deserunt mollit anim id est laborum.", + "It was on a dreary night of November that I beheld the accomplishment of my toils. With an anxiety that " + + "almost amounted to agony, I collected the instruments of life around me, that I might infuse a spark of being " + + "into the lifeless thing that lay at my feet. It was already one in the morning; the rain pattered dismally " + + "against the panes, and my candle was nearly burnt out, when, by the glimmer of the half-extinguished light, " + + "I saw the dull yellow eye of the creature open; it breathed hard, and a convulsive motion agitated its limbs.\n\n" + + "How can I describe my emotions at this catastrophe, or how delineate the wretch whom with such infinite pains and " + + "care I had endeavoured to form? His limbs were in proportion, and I had selected his features as beautiful. " + + "Beautiful! Great God! His yellow skin scarcely covered the work of muscles and arteries beneath; his hair was " + + "of a lustrous black, and flowing; his teeth of a pearly whiteness; but these luxuriances only formed a more " + + "horrid contrast with his watery eyes, that seemed almost of the same colour as the dun-white sockets in which " + + "they were set, his shrivelled complexion and straight black lips. ", + ""The time has come," the Walrus said,\n" + "To talk of many things:\n" + + "Of shoes--and ships--and sealing-wax--\n" + "Of cabbages--and kings--\n" + + "And why the sea is boiling hot--\n" + "And whether pigs have wings.", + "My grandfather's clock\n" + "Was too large for the shelf,\n" + "So it stood ninety years on the floor;\n" + + "It was taller by half\n" + "Than the old man himself,\n" + + "Though it weighed not a pennyweight more.\n" + "It was bought on the morn\n" + + "Of the day that he was born,\n" + "It was always his treasure and pride;" + "But it stopped short\n" + + "Never to go again,\n" + "When the old man died." }; + int i = 0; + for (String file : files) { + RawConfiguration raw = new RawConfiguration(); + raw.setPath(file); + raw.setContents((filesContents[i++]).getBytes()); + rawConfigCollection.getRawConfigDelegate().raws.put(file, raw); + } + + } + +} diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/RawConfigCollection.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/RawConfigCollection.java index c8956b1..e5c0153 100644 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/RawConfigCollection.java +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/RawConfigCollection.java @@ -25,6 +25,7 @@ import org.rhq.core.domain.configuration.Configuration; import org.rhq.core.domain.configuration.RawConfiguration; import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; import org.rhq.core.domain.configuration.definition.ConfigurationFormat; +import org.rhq.enterprise.gui.configuration.AbstractConfigurationUIBean; import org.rhq.enterprise.gui.util.EnterpriseFacesContextUtility; import org.rhq.enterprise.server.configuration.ConfigurationManagerLocal; import org.rhq.enterprise.server.util.LookupUtil; @@ -35,7 +36,7 @@ import org.rhq.enterprise.server.util.LookupUtil; * The backing class for all Web based activities for manipulating the set of * raw configuration files associated with a resource */ -public class RawConfigCollection implements Serializable { +public class RawConfigCollection extends AbstractConfigurationUIBean implements Serializable {
private RawConfigDelegate rawConfigDelegate = null; private RawConfigDelegateMap rawConfigDelegateMap; @@ -63,20 +64,23 @@ public class RawConfigCollection implements Serializable { @End public String commit() {
- for (RawConfiguration raw : getRawConfigDelegate().modified.values()) { - getRaws().put(raw.getPath(), raw); - } - - getConfiguration().getRawConfigurations().clear(); - getConfiguration().getRawConfigurations().addAll(getRaws().values()); Subject subject = EnterpriseFacesContextUtility.getSubject(); - getConfigurationManager().updateResourceConfiguration(subject, getResourceId(), getConfiguration()); + getConfigurationManager().updateResourceConfiguration(subject, getResourceId(), getMergedConfiguration());
nullify();
return "/rhq/resource/configuration/view.xhtml?id=" + getResourceId(); }
+ private Configuration getMergedConfiguration() { + for (RawConfiguration raw : getRawConfigDelegate().modified.values()) { + getRaws().put(raw.getPath(), raw); + } + getConfiguration().getRawConfigurations().clear(); + getConfiguration().getRawConfigurations().addAll(getRaws().values()); + return getConfiguration(); + } + public String discard() { nullify(); return "/rhq/resource/configuration/view.xhtml?id=" + getResourceId(); @@ -120,7 +124,8 @@ public class RawConfigCollection implements Serializable { return configuration; }
- private ConfigurationDefinition getConfigurationDefinition() { + //TODO Sync this up with the baseclass + public ConfigurationDefinition getConfigurationDefinition() { if (null == getRawConfigDelegate().configurationDefinition) {
getRawConfigDelegate().configurationDefinition = getConfigurationManager() @@ -199,7 +204,7 @@ public class RawConfigCollection implements Serializable { if (null == getRawConfigDelegate().raws) { getRawConfigDelegate().raws = new TreeMap<String, RawConfiguration>(); if (useMock) { - rawConfigDelegate.populateRawsMock(this); + MockSupport.populateRawsMock(this); } else { populateRaws(this); } @@ -328,4 +333,54 @@ public class RawConfigCollection implements Serializable { public String upload() { return "/rhq/resource/configuration/edit-raw.xhtml?currentResourceId=" + getResourceId(); } + + public String switchToraw() { + log.error("switch2raw called"); + configuration = getConfigurationManager().translateResourceConfiguration( + EnterpriseFacesContextUtility.getSubject(), getResourceId(), getMergedConfiguration(), true); + + for (RawConfiguration raw : configuration.getRawConfigurations()) { + getRawConfigDelegate().raws.put(raw.getPath(), raw); + } + getRawConfigDelegate().current = null; + return "/rhq/resource/configuration/edit-raw.xhtml?currentResourceId=" + getResourceId(); + } + + public String switchTostructured() { + log.error("switch2structured called"); + configuration = getConfigurationManager().translateResourceConfiguration( + EnterpriseFacesContextUtility.getSubject(), getResourceId(), getMergedConfiguration(), false); + + for (RawConfiguration raw : configuration.getRawConfigurations()) { + getRawConfigDelegate().raws.put(raw.getPath(), raw); + } + getRawConfigDelegate().current = null; + + return "/rhq/resource/configuration/edit.xhtml?currentResourceId=" + getResourceId(); + } + + @Override + protected int getConfigurationDefinitionKey() { + // TODO Auto-generated method stub + return 0; + } + + @Override + protected int getConfigurationKey() { + // TODO Auto-generated method stub + return 0; + } + + @Override + protected Configuration lookupConfiguration() { + // TODO Auto-generated method stub + return null; + } + + @Override + protected ConfigurationDefinition lookupConfigurationDefinition() { + // TODO Auto-generated method stub + return null; + } + } diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/RawConfigDelegate.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/RawConfigDelegate.java index c2ae82c..b7083af 100644 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/RawConfigDelegate.java +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/RawConfigDelegate.java @@ -43,42 +43,4 @@ public class RawConfigDelegate implements Serializable { RawConfiguration current = null; ConfigurationDefinition configurationDefinition = null;
- void populateRawsMock(RawConfigCollection rawConfigCollection) { - String[] files = { "/etc/mock/file1", "/etc/mock/file2", "/etc/mock/file3", "/etc/mock/me/will/you", - "/etc/mock/turtle/soup", "/etc/mock/mysmock/iclean/yourclock" }; - - String[] filesContents = { - "GALLIA est omnis divisa in partes tres, quarum unam incolunt Belgae, \naliam Aquitani, tertiam qui ipsorum lingua Celtae, \n" - + "nostra Galli appellantur. \nHi omnes lingua, institutis, legibus inter se differunt. \n", - "I've seen all good people \n turn their heads each day \n So Satisfied\n I'm on my way", - "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor \nincididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis\n nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\n Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu\n fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in \nculpa qui officia deserunt mollit anim id est laborum.", - "It was on a dreary night of November that I beheld the accomplishment of my toils. With an anxiety that " - + "almost amounted to agony, I collected the instruments of life around me, that I might infuse a spark of being " - + "into the lifeless thing that lay at my feet. It was already one in the morning; the rain pattered dismally " - + "against the panes, and my candle was nearly burnt out, when, by the glimmer of the half-extinguished light, " - + "I saw the dull yellow eye of the creature open; it breathed hard, and a convulsive motion agitated its limbs.\n\n" - + "How can I describe my emotions at this catastrophe, or how delineate the wretch whom with such infinite pains and " - + "care I had endeavoured to form? His limbs were in proportion, and I had selected his features as beautiful. " - + "Beautiful! Great God! His yellow skin scarcely covered the work of muscles and arteries beneath; his hair was " - + "of a lustrous black, and flowing; his teeth of a pearly whiteness; but these luxuriances only formed a more " - + "horrid contrast with his watery eyes, that seemed almost of the same colour as the dun-white sockets in which " - + "they were set, his shrivelled complexion and straight black lips. ", - ""The time has come," the Walrus said,\n" + "To talk of many things:\n" - + "Of shoes--and ships--and sealing-wax--\n" + "Of cabbages--and kings--\n" - + "And why the sea is boiling hot--\n" + "And whether pigs have wings.", - "My grandfather's clock\n" + "Was too large for the shelf,\n" + "So it stood ninety years on the floor;\n" - + "It was taller by half\n" + "Than the old man himself,\n" - + "Though it weighed not a pennyweight more.\n" + "It was bought on the morn\n" - + "Of the day that he was born,\n" + "It was always his treasure and pride;" + "But it stopped short\n" - + "Never to go again,\n" + "When the old man died." }; - int i = 0; - for (String file : files) { - RawConfiguration raw = new RawConfiguration(); - raw.setPath(file); - raw.setContents((filesContents[i++]).getBytes()); - rawConfigCollection.getRawConfigDelegate().raws.put(file, raw); - } - - } - } \ No newline at end of file diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/inventory/resource/CreateNewConfigurationChildResourceUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/inventory/resource/CreateNewConfigurationChildResourceUIBean.java index 914527b..bdcf336 100644 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/inventory/resource/CreateNewConfigurationChildResourceUIBean.java +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/inventory/resource/CreateNewConfigurationChildResourceUIBean.java @@ -39,7 +39,7 @@ import org.rhq.core.domain.resource.ResourceType; import org.rhq.core.gui.configuration.ConfigurationMaskingUtility; import org.rhq.core.gui.util.FacesContextUtility; import org.rhq.core.util.exception.ThrowableUtil; -import org.rhq.enterprise.gui.configuration.resource.AbstractResourceConfigurationUIBean; +import org.rhq.enterprise.gui.configuration.AbstractConfigurationUIBean; import org.rhq.enterprise.gui.legacy.ParamConstants; import org.rhq.enterprise.gui.util.EnterpriseFacesContextUtility; import org.rhq.enterprise.server.resource.ResourceFactoryManagerLocal; @@ -53,7 +53,7 @@ import org.rhq.enterprise.server.util.LookupUtil; * @author Ian Springer * @author Jason Dobies */ -public class CreateNewConfigurationChildResourceUIBean extends AbstractResourceConfigurationUIBean { +public class CreateNewConfigurationChildResourceUIBean extends AbstractConfigurationUIBean { // Constants --------------------------------------------
public static final String MANAGED_BEAN_NAME = "CreateNewConfigurationChildResourceUIBean"; diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit-raw.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit-raw.xhtml index 254d672..c15712d 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit-raw.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit-raw.xhtml @@ -32,17 +32,17 @@ } </script> - + <a4j:form id="editResourceConfigurationForm"> + <h:outputText value="#{messages.youareviewingraw}" /> <h:outputText value=" #{messages.switch2}" /> - <h:outputLink value="edit.xhtml"> + <h:commandLink action="#{rawConfigCollection.switchTostructured}"> <s:conversationId /> <f:param name="id" value="#{ResourceUIBean.id}" /> <h:outputText value=" #{messages.structured}" /> - </h:outputLink> + </h:commandLink>
<table class="summary-props-table" style=""> - <a4j:form id="editResourceConfigurationForm"> <input type="hidden" name="id" value="#{ResourceUIBean.id}" /> <tr> @@ -95,9 +95,9 @@ </td> </tr>
- </a4j:form> + </table> - + </a4j:form> </ui:define>
</ui:composition> diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit.xhtml index a3490ec..da2f99a 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit.xhtml @@ -28,11 +28,11 @@ THIS TEXT WILL BE REMOVED.
<input type="hidden" name="id" value="#{ResourceUIBean.id}"/> You are viewing this in structured mode. Switch to - <h:outputLink value="edit-raw.xhtml"> + <h:commandLink action="#{rawConfigCollection.switchToraw}"> <f:param name="conversationId" value="#{conversation.id}"/> <f:param name="id" value="#{ResourceUIBean.id}"/> <h:outputText value=" files mode"/> - </h:outputLink> + </h:commandLink>
<onc:config configurationDefinition="#{ExistingResourceConfigurationUIBean.configurationDefinition}" configuration="#{ExistingResourceConfigurationUIBean.configuration}" diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml index 05cfc86..638bdb2 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml @@ -43,21 +43,19 @@ THIS TEXT WILL BE REMOVED. <input type="hidden" name="id" value="#{ResourceUIBean.id}"/>
- - <h:panelGrid columns="2" styleClass="buttons-table" columnClasses="button-cell" rendered="#{ExistingResourceConfigurationViewUIBean.configuration != null and !ExistingResourceConfigurationViewUIBean.updateInProgress}">
<h:commandButton value="#{messages.editstructured}" action="#{ExistingResourceConfigurationViewUIBean.editConfiguration}" title="Edit this Configuration" styleClass="buttonmed" - rendered="${ResourceUIBean.permissions.configure and rawConfigCollection.structuredSupported}" /> + rendered="${ResourceUIBean.permissions.configure and rawConfigCollection.structuredSupported and !ExistingResourceConfigurationViewUIBean.updateInProgress}" /> <h:commandButton value="#{messages.editraw}" action="#{ExistingResourceConfigurationViewUIBean.editRawConfiguration}" title="Advanced Mode Edit of Raw Configuration Files" styleClass="buttonmed" - rendered="${ResourceUIBean.permissions.configure and rawConfigCollection.rawSupported}" /> + rendered="${ResourceUIBean.permissions.configure and rawConfigCollection.rawSupported and !ExistingResourceConfigurationViewUIBean.updateInProgress}" /> </h:panelGrid>
<onc:config configurationDefinition="#{ExistingResourceConfigurationViewUIBean.configurationDefinition}" - configuration="#{ExistingResourceConfigurationViewUIBean.configuration}" + configuration="#{rawConfigCollection.configuration}" accessMapActionExpression="#{ExistingResourceConfigurationViewUIBean.accessMap}" readOnly="true" nullConfigurationDefinitionMessage="#{ExistingResourceConfigurationViewUIBean.nullConfigurationDefinitionMessage}"
commit 9c3e47fdaf0394bc26319b8a9443df8e9313f063 Author: John Sanda john@localhost.localdomain Date: Thu Nov 12 14:25:50 2009 -0500
[US 2] Updating serialization code to include rawConfigurations field.
Refactoring external write/read methods and adding unit tests.
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/Configuration.java b/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/Configuration.java index 0c2805f..c5ca304 100644 --- a/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/Configuration.java +++ b/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/Configuration.java @@ -65,7 +65,6 @@ import org.jetbrains.annotations.NotNull;
import org.rhq.core.domain.util.EntitySerializer; import org.rhq.core.domain.util.serial.ExternalizableStrategy; -import org.rhq.core.domain.util.serial.HibernateUtil;
/** * This is the root object for the storage of a hierarchical value set of data. This data may represent configurations @@ -620,37 +619,39 @@ public class Configuration implements Externalizable, Cloneable, AbstractPropert ExternalizableStrategy.Subsystem strategy = ExternalizableStrategy.getStrategy(); out.writeChar(strategy.id());
- if (ExternalizableStrategy.Subsystem.REMOTEAPI == strategy) { - writeExternalRemote(out); - } else if (ExternalizableStrategy.Subsystem.REFLECTIVE_SERIALIZATION == strategy) { - EntitySerializer.writeExternalRemote(this, out); - } else { - writeExternalAgent(out); + if (isAgentOrRemoteAPISerialization(strategy.id())) { + writeExternalAgentOrRemote(out); + } + else { + EntitySerializer.writeExternalRemote(this, out); } }
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { char c = in.readChar(); - if (ExternalizableStrategy.Subsystem.REMOTEAPI.id() == c) { - readExternalRemote(in); - } else if (ExternalizableStrategy.Subsystem.REFLECTIVE_SERIALIZATION.id() == c) { + + if (isAgentOrRemoteAPISerialization(c)) { + readExternalAgentOrRemote(in); + } + else { EntitySerializer.readExternalRemote(this, in); - } else { - readExternalAgent(in); } }
+ private boolean isAgentOrRemoteAPISerialization(char strategy) { + return strategy == ExternalizableStrategy.Subsystem.AGENT.id() || + strategy == ExternalizableStrategy.Subsystem.REMOTEAPI.id(); + } + /** * @see java.io.Externalizable#writeExternal(java.io.ObjectOutput) */ - public void writeExternalAgent(ObjectOutput out) throws IOException { -// Configuration copy = deepCopyWithoutProxies(); + public void writeExternalAgentOrRemote(ObjectOutput out) throws IOException { + Configuration copy = deepCopyWithoutProxies();
out.writeInt(id); - out.writeObject(HibernateUtil.safeMap(properties)); - out.writeObject(HibernateUtil.safeSet(rawConfigurations)); -// out.writeObject(copy.properties); -// out.writeObject(copy.rawConfigurations); + out.writeObject(createDeepCopyOfMap()); + out.writeObject(createDeepCopyOfRawConfigs()); out.writeUTF((notes == null) ? "null" : notes); out.writeLong(version); out.writeLong(ctime); @@ -677,7 +678,7 @@ public class Configuration implements Externalizable, Cloneable, AbstractPropert * @see java.io.Externalizable#readExternal(java.io.ObjectInput) */ @SuppressWarnings("unchecked") - public void readExternalAgent(ObjectInput in) throws IOException, ClassNotFoundException { + public void readExternalAgentOrRemote(ObjectInput in) throws IOException, ClassNotFoundException { id = in.readInt(); properties = (HashMap<String, Property>) in.readObject(); rawConfigurations = (Set<RawConfiguration>) in.readObject(); @@ -687,27 +688,6 @@ public class Configuration implements Externalizable, Cloneable, AbstractPropert mtime = in.readLong(); }
- // It is assumed that the object is clean of Hibernate proxies (i.e. HibernateDetachUtility has been run if necessary) - public void writeExternalRemote(ObjectOutput out) throws IOException { - out.writeInt(id); - out.writeObject(HibernateUtil.safeMap(properties)); - out.writeUTF((notes == null) ? "null" : notes); - out.writeLong(version); - out.writeLong(ctime); - out.writeLong(mtime); - // Explicitly do not send the history relationship - } - - @SuppressWarnings("unchecked") - public void readExternalRemote(ObjectInput in) throws IOException, ClassNotFoundException { - id = in.readInt(); - properties = (HashMap<String, Property>) in.readObject(); - notes = in.readUTF(); - version = in.readLong(); - ctime = in.readLong(); - mtime = in.readLong(); - } - /** * This listener runs after jaxb unmarshalling and reconnects children properties to their parent configurations (as * we don't send them avoiding cyclic references).
commit c78944f1261b5776fd8c01e4fcd9171dee667ecc Author: Ian Springer ian.springer@redhat.com Date: Thu Nov 12 13:10:23 2009 -0500
add some trace logging, so if the Agent JVM crashes during loading of a ProcessInfo, we can see what pid it was trying to load just before the crash
diff --git a/modules/core/native-system/src/main/java/org/rhq/core/system/NativeSystemInfo.java b/modules/core/native-system/src/main/java/org/rhq/core/system/NativeSystemInfo.java index 2e95665..1665769 100644 --- a/modules/core/native-system/src/main/java/org/rhq/core/system/NativeSystemInfo.java +++ b/modules/core/native-system/src/main/java/org/rhq/core/system/NativeSystemInfo.java @@ -216,6 +216,9 @@ public class NativeSystemInfo implements SystemInfo {
if (pids != null) { for (long pid : pids) { + if (log.isTraceEnabled()) { + log.trace("Loading process info for pid " + pid + "..."); + } ProcessInfo info = new ProcessInfo(pid, sigar); processes.add(info); }
commit 68534e1f50d3c054e2dbddfd8e622818db45139b Author: John Sanda john@localhost.localdomain Date: Thu Nov 12 12:51:42 2009 -0500
Fixing a bug in EntitySerializer in which the id field is not serialized unless it specifies @Column.
In Configuration.java, the id field onnly specifies @Id so its id field was not being serialized with the reflective serialization strategy which I believe is used with the CLI.
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/util/EntitySerializer.java b/modules/core/domain/src/main/java/org/rhq/core/domain/util/EntitySerializer.java index f6f6f3f..9cdbac7 100644 --- a/modules/core/domain/src/main/java/org/rhq/core/domain/util/EntitySerializer.java +++ b/modules/core/domain/src/main/java/org/rhq/core/domain/util/EntitySerializer.java @@ -44,6 +44,7 @@ import javax.persistence.Entity; import javax.persistence.ManyToMany; import javax.persistence.ManyToOne; import javax.persistence.OneToMany; +import javax.persistence.Id;
import org.rhq.core.domain.resource.Agent; import org.rhq.core.domain.resource.Resource; @@ -61,6 +62,7 @@ import org.rhq.core.domain.util.serial.ExternalizableStrategy.Subsystem; public class EntitySerializer { private static Set<Class<? extends Annotation>> PERSISTENCE_ANNOTATIONS = new HashSet<Class<? extends Annotation>>(); static { + PERSISTENCE_ANNOTATIONS.add(Id.class); PERSISTENCE_ANNOTATIONS.add(Column.class); PERSISTENCE_ANNOTATIONS.add(ManyToOne.class); PERSISTENCE_ANNOTATIONS.add(OneToMany.class);
commit 1c1de545ead3a34bbe7c832acce2de2d2c1bf2fd Author: John Sanda john@localhost.localdomain Date: Thu Nov 12 10:50:39 2009 -0500
Updating AbstractResourceConfiguration to call Configuration.deepCopyWithoutProxies()
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/AbstractResourceConfigurationUpdate.java b/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/AbstractResourceConfigurationUpdate.java index d0b0953..5f377cf 100644 --- a/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/AbstractResourceConfigurationUpdate.java +++ b/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/AbstractResourceConfigurationUpdate.java @@ -69,7 +69,8 @@ public abstract class AbstractResourceConfigurationUpdate extends AbstractConfig */ protected AbstractResourceConfigurationUpdate(Configuration config, String subjectName) { super(subjectName); - this.configuration = config.deepCopy(false); + //this.configuration = config.deepCopy(false); + this.configuration = config.deepCopyWithoutProxies(); }
public int getId() { diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/Configuration.java b/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/Configuration.java index e238a51..0c2805f 100644 --- a/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/Configuration.java +++ b/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/Configuration.java @@ -454,6 +454,10 @@ public class Configuration implements Externalizable, Cloneable, AbstractPropert * @return the new copy */ public Configuration deepCopy(boolean keepIds) { + if (!keepIds) { + return deepCopyWithoutProxies(); + } + Configuration copy;
try { @@ -640,11 +644,13 @@ public class Configuration implements Externalizable, Cloneable, AbstractPropert * @see java.io.Externalizable#writeExternal(java.io.ObjectOutput) */ public void writeExternalAgent(ObjectOutput out) throws IOException { +// Configuration copy = deepCopyWithoutProxies(); + out.writeInt(id); out.writeObject(HibernateUtil.safeMap(properties)); -// out.writeObject(createDeepCopyOfMap()); -// out.writeObject(createDeepCopyOfRawConfigs()); out.writeObject(HibernateUtil.safeSet(rawConfigurations)); +// out.writeObject(copy.properties); +// out.writeObject(copy.rawConfigurations); out.writeUTF((notes == null) ? "null" : notes); out.writeLong(version); out.writeLong(ctime); diff --git a/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/RawConfigurationTest.java b/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/RawConfigurationTest.java index d6c0b9c..2d60ba2 100644 --- a/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/RawConfigurationTest.java +++ b/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/RawConfigurationTest.java @@ -248,31 +248,6 @@ public class RawConfigurationTest { assertFalse(original.getId() == copy.getId(), "The id property should not be copied."); }
- @Test - public void deserializationShouldInitializeSha256Generator() throws Exception { - MessageDigestGenerator sha256Generator = new MessageDigestGenerator("SHA-256"); - - RawConfiguration rawConfig = new RawConfiguration(); - rawConfig.setContents(new byte[] {1, 2, 3, 4, 5}); - rawConfig.setPath("/tmp/foo.txt"); - - RawConfiguration serializedRawConfig = serializeAndDeserialize(rawConfig); - - assertEquals(serializedRawConfig, rawConfig, "Failed to properly serialize/deserialize the raw configuration"); - - byte[] newContents = new byte[] {1, 3, 5, 7, 11, 13, 17}; - String expectedSha256 = calculateSHA256(newContents); - - serializedRawConfig.setContents(newContents); - String actualSha256 = serializedRawConfig.getSha256(); - - assertEquals( - actualSha256, - expectedSha256, - "The sha256Generator field was not properly initialized during deserialization." - ); - } - private RawConfiguration serializeAndDeserialize(RawConfiguration rawConfig) throws Exception { ByteArrayOutputStream byteOutputStream = new ByteArrayOutputStream(); ObjectOutputStream ostream = new ObjectOutputStream(byteOutputStream);
commit 56901d80c9f50c8071796bdef77e2a7c082cea14 Author: John Sanda john@localhost.localdomain Date: Wed Nov 11 22:06:01 2009 -0500
[US 2] Cleaning up serialization code.
After doing a complete, full, clean build including rebuilding database and dev-container things seem to be back in working order.
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/RawConfiguration.java b/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/RawConfiguration.java index 269e681..4e1cdc4 100644 --- a/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/RawConfiguration.java +++ b/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/RawConfiguration.java @@ -36,9 +36,6 @@ import javax.persistence.PrePersist; import javax.persistence.PreUpdate; import javax.persistence.SequenceGenerator; import javax.persistence.Table; -import javax.persistence.Transient; -import java.io.IOException; -import java.io.ObjectInputStream; import java.io.Serializable;
/** @@ -81,14 +78,11 @@ public class RawConfiguration implements Serializable, DeepCopyable<RawConfigura
@Column(name = "MTIME", nullable = false) private long mtime = System.currentTimeMillis(); - + @ManyToOne(optional = false) @JoinColumn(name = "CONFIG_ID", nullable = false) private Configuration configuration;
- @Transient - private transient MessageDigestGenerator sha256Generator = new MessageDigestGenerator("SHA-256"); - public int getId() { return id; } @@ -137,6 +131,7 @@ public class RawConfiguration implements Serializable, DeepCopyable<RawConfigura }
private void updateSha256() { + MessageDigestGenerator sha256Generator = new MessageDigestGenerator("SHA-256"); sha256Generator.add(contents); sha256 = sha256Generator.getDigestString(); } @@ -255,14 +250,5 @@ public class RawConfiguration implements Serializable, DeepCopyable<RawConfigura return copy; }
- private void readObject(ObjectInputStream istream) throws IOException, ClassNotFoundException { - try { - istream.defaultReadObject(); - sha256Generator = new MessageDigestGenerator("SHA-256"); - } - catch (ClassNotFoundException e) { - throw new RuntimeException("Failed to deserialize " + getClass().getName(), e); - } - } - } +
commit 3fe47ceae80a7cf09b9b857924a37d282ea3dd37 Merge: 5cbb1e4... ba24a1f... Author: John Sanda john@localhost.localdomain Date: Wed Nov 11 22:04:55 2009 -0500
Merge branch 'raw-config' of ssh://git.fedorahosted.org/git/rhq/rhq into raw-config
commit 5cbb1e47aebe382c9b2a2961013f9cc8788363d2 Author: John Sanda john@localhost.localdomain Date: Wed Nov 11 22:03:59 2009 -0500
Debugging the agent serialization code
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/Configuration.java b/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/Configuration.java index fd3b209..e238a51 100644 --- a/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/Configuration.java +++ b/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/Configuration.java @@ -641,8 +641,10 @@ public class Configuration implements Externalizable, Cloneable, AbstractPropert */ public void writeExternalAgent(ObjectOutput out) throws IOException { out.writeInt(id); - out.writeObject(createDeepCopyOfMap()); - out.writeObject(createDeepCopyOfRawConfigs()); + out.writeObject(HibernateUtil.safeMap(properties)); +// out.writeObject(createDeepCopyOfMap()); +// out.writeObject(createDeepCopyOfRawConfigs()); + out.writeObject(HibernateUtil.safeSet(rawConfigurations)); out.writeUTF((notes == null) ? "null" : notes); out.writeLong(version); out.writeLong(ctime);
commit ba24a1ff9b3eba56cd3a960f5b4cd130b490b65a Author: Adam Young ayoung@redhat.com Date: Wed Nov 11 15:26:37 2009 -0500
Revert "Made object more serialization friendly"
This reverts commit 572bafecf20c5fa47c46b10885ab6e518449bd95.
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/RawConfiguration.java b/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/RawConfiguration.java index 64421c5..269e681 100644 --- a/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/RawConfiguration.java +++ b/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/RawConfiguration.java @@ -23,10 +23,7 @@
package org.rhq.core.domain.configuration;
-import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.Serializable; +import org.rhq.core.util.MessageDigestGenerator;
import javax.persistence.Column; import javax.persistence.Entity; @@ -40,8 +37,9 @@ import javax.persistence.PreUpdate; import javax.persistence.SequenceGenerator; import javax.persistence.Table; import javax.persistence.Transient; - -import org.rhq.core.util.MessageDigestGenerator; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.Serializable;
/** * Resources support structured configuration as well as raw configuration which is represented by this class. A raw @@ -83,13 +81,13 @@ public class RawConfiguration implements Serializable, DeepCopyable<RawConfigura
@Column(name = "MTIME", nullable = false) private long mtime = System.currentTimeMillis(); - + @ManyToOne(optional = false) @JoinColumn(name = "CONFIG_ID", nullable = false) private Configuration configuration;
@Transient - private transient MessageDigestGenerator sha256Generator = null; + private transient MessageDigestGenerator sha256Generator = new MessageDigestGenerator("SHA-256");
public int getId() { return id; @@ -139,8 +137,8 @@ public class RawConfiguration implements Serializable, DeepCopyable<RawConfigura }
private void updateSha256() { - getSha256Generator().add(contents); - sha256 = getSha256Generator().getDigestString(); + sha256Generator.add(contents); + sha256 = sha256Generator.getDigestString(); }
/** @return A SHA-256 hash of the bytes for this raw configuration, which can be accessed via {@link #getContents()} */ @@ -213,7 +211,7 @@ public class RawConfiguration implements Serializable, DeepCopyable<RawConfigura if (this.path == null && that.path == null) { return true; } - if ((this.path != null && that.path != null) && this.path.equals(that.path)) { + if ((this.path !=null && that.path != null) && this.path.equals(that.path)) { return true; } } @@ -237,9 +235,14 @@ public class RawConfiguration implements Serializable, DeepCopyable<RawConfigura
@Override public String toString() { - return new StringBuilder().append(getClass().getSimpleName()).append("[id=").append(id).append(", path=") - .append(path).append(", sha256=").append(sha256).append(", configuration=").append(configuration).append( - "]").toString(); + return new StringBuilder() + .append(getClass().getSimpleName()) + .append("[id=").append(id) + .append(", path=").append(path) + .append(", sha256=").append(sha256) + .append(", configuration=").append(configuration) + .append("]") + .toString(); }
public RawConfiguration deepCopy() { @@ -252,22 +255,14 @@ public class RawConfiguration implements Serializable, DeepCopyable<RawConfigura return copy; }
- private void writeObject(ObjectOutputStream ostream) throws IOException { - ostream.defaultWriteObject(); - } - private void readObject(ObjectInputStream istream) throws IOException, ClassNotFoundException { try { istream.defaultReadObject(); - } catch (ClassNotFoundException e) { + sha256Generator = new MessageDigestGenerator("SHA-256"); + } + catch (ClassNotFoundException e) { throw new RuntimeException("Failed to deserialize " + getClass().getName(), e); } }
- private MessageDigestGenerator getSha256Generator() { - if (null == sha256Generator) { - sha256Generator = new MessageDigestGenerator("SHA-256"); - } - return sha256Generator; - } }
commit 572bafecf20c5fa47c46b10885ab6e518449bd95 Author: Adam Young ayoung@redhat.com Date: Wed Nov 11 15:04:05 2009 -0500
Made object more serialization friendly
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/RawConfiguration.java b/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/RawConfiguration.java index 269e681..64421c5 100644 --- a/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/RawConfiguration.java +++ b/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/RawConfiguration.java @@ -23,7 +23,10 @@
package org.rhq.core.domain.configuration;
-import org.rhq.core.util.MessageDigestGenerator; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable;
import javax.persistence.Column; import javax.persistence.Entity; @@ -37,9 +40,8 @@ import javax.persistence.PreUpdate; import javax.persistence.SequenceGenerator; import javax.persistence.Table; import javax.persistence.Transient; -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.Serializable; + +import org.rhq.core.util.MessageDigestGenerator;
/** * Resources support structured configuration as well as raw configuration which is represented by this class. A raw @@ -81,13 +83,13 @@ public class RawConfiguration implements Serializable, DeepCopyable<RawConfigura
@Column(name = "MTIME", nullable = false) private long mtime = System.currentTimeMillis(); - + @ManyToOne(optional = false) @JoinColumn(name = "CONFIG_ID", nullable = false) private Configuration configuration;
@Transient - private transient MessageDigestGenerator sha256Generator = new MessageDigestGenerator("SHA-256"); + private transient MessageDigestGenerator sha256Generator = null;
public int getId() { return id; @@ -137,8 +139,8 @@ public class RawConfiguration implements Serializable, DeepCopyable<RawConfigura }
private void updateSha256() { - sha256Generator.add(contents); - sha256 = sha256Generator.getDigestString(); + getSha256Generator().add(contents); + sha256 = getSha256Generator().getDigestString(); }
/** @return A SHA-256 hash of the bytes for this raw configuration, which can be accessed via {@link #getContents()} */ @@ -211,7 +213,7 @@ public class RawConfiguration implements Serializable, DeepCopyable<RawConfigura if (this.path == null && that.path == null) { return true; } - if ((this.path !=null && that.path != null) && this.path.equals(that.path)) { + if ((this.path != null && that.path != null) && this.path.equals(that.path)) { return true; } } @@ -235,14 +237,9 @@ public class RawConfiguration implements Serializable, DeepCopyable<RawConfigura
@Override public String toString() { - return new StringBuilder() - .append(getClass().getSimpleName()) - .append("[id=").append(id) - .append(", path=").append(path) - .append(", sha256=").append(sha256) - .append(", configuration=").append(configuration) - .append("]") - .toString(); + return new StringBuilder().append(getClass().getSimpleName()).append("[id=").append(id).append(", path=") + .append(path).append(", sha256=").append(sha256).append(", configuration=").append(configuration).append( + "]").toString(); }
public RawConfiguration deepCopy() { @@ -255,14 +252,22 @@ public class RawConfiguration implements Serializable, DeepCopyable<RawConfigura return copy; }
+ private void writeObject(ObjectOutputStream ostream) throws IOException { + ostream.defaultWriteObject(); + } + private void readObject(ObjectInputStream istream) throws IOException, ClassNotFoundException { try { istream.defaultReadObject(); - sha256Generator = new MessageDigestGenerator("SHA-256"); - } - catch (ClassNotFoundException e) { + } catch (ClassNotFoundException e) { throw new RuntimeException("Failed to deserialize " + getClass().getName(), e); } }
+ private MessageDigestGenerator getSha256Generator() { + if (null == sha256Generator) { + sha256Generator = new MessageDigestGenerator("SHA-256"); + } + return sha256Generator; + } }
commit 4124bf4085bba1fcc96005bcded765a6b144926c Author: John Sanda john@localhost.localdomain Date: Wed Nov 11 14:20:53 2009 -0500
Modifying PropertyList and PropertyMap to initialize collections to avoid NPEs during deep copy operations.
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/PropertyList.java b/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/PropertyList.java index a2223d9..aff96b9 100644 --- a/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/PropertyList.java +++ b/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/PropertyList.java @@ -68,7 +68,7 @@ public class PropertyList extends Property { @Cascade( { CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH, CascadeType.DELETE_ORPHAN }) @OneToMany(mappedBy = "parentList", targetEntity = Property.class, fetch = FetchType.EAGER) //@IndexColumn(name = "list_index") TODO GH: This seems broken - private List<Property> list; + private List<Property> list = new ArrayList<Property>();
@Transient String memberPropertyName; diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/PropertyMap.java b/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/PropertyMap.java index 137c6fe..e901377 100644 --- a/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/PropertyMap.java +++ b/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/PropertyMap.java @@ -68,7 +68,7 @@ public class PropertyMap extends Property implements AbstractPropertyMap { @Cascade( { CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH, CascadeType.DELETE_ORPHAN }) @MapKey(name = "name") @OneToMany(mappedBy = "parentMap", fetch = FetchType.EAGER) - private Map<String, Property> map; + private Map<String, Property> map = new LinkedHashMap<String, Property>();
/** * Creates a new unnamed and empty {@link PropertyMap} object. diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/RawConfiguration.java b/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/RawConfiguration.java index b15ee84..269e681 100644 --- a/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/RawConfiguration.java +++ b/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/RawConfiguration.java @@ -25,21 +25,21 @@ package org.rhq.core.domain.configuration;
import org.rhq.core.util.MessageDigestGenerator;
+import javax.persistence.Column; import javax.persistence.Entity; -import javax.persistence.SequenceGenerator; -import javax.persistence.Table; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; -import javax.persistence.Column; -import javax.persistence.ManyToOne; import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; import javax.persistence.PrePersist; import javax.persistence.PreUpdate; +import javax.persistence.SequenceGenerator; +import javax.persistence.Table; import javax.persistence.Transient; -import java.io.Serializable; -import java.io.ObjectInputStream; import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.Serializable;
/** * Resources support structured configuration as well as raw configuration which is represented by this class. A raw @@ -255,7 +255,7 @@ public class RawConfiguration implements Serializable, DeepCopyable<RawConfigura return copy; }
- private void readObject(ObjectInputStream istream) throws IOException, ClassCastException { + private void readObject(ObjectInputStream istream) throws IOException, ClassNotFoundException { try { istream.defaultReadObject(); sha256Generator = new MessageDigestGenerator("SHA-256");
commit 0aa5145050dc78e398f009b2c132a53c693f53bb Author: John Sanda john@localhost.localdomain Date: Wed Nov 11 12:33:23 2009 -0500
[US 2] Modifying deserialization behavorior for RawConfiguration.
The sha256DigestGenerator field has been marked transient since the MessageDigestGenerator class is not Serializable. During deserialization sha256Digenerator is initialized so that it will generate SHA-256 hashes.
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/RawConfiguration.java b/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/RawConfiguration.java index ca02070..b15ee84 100644 --- a/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/RawConfiguration.java +++ b/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/RawConfiguration.java @@ -38,6 +38,8 @@ import javax.persistence.PrePersist; import javax.persistence.PreUpdate; import javax.persistence.Transient; import java.io.Serializable; +import java.io.ObjectInputStream; +import java.io.IOException;
/** * Resources support structured configuration as well as raw configuration which is represented by this class. A raw @@ -85,7 +87,7 @@ public class RawConfiguration implements Serializable, DeepCopyable<RawConfigura private Configuration configuration;
@Transient - private MessageDigestGenerator sha256Generator = new MessageDigestGenerator("SHA-256"); + private transient MessageDigestGenerator sha256Generator = new MessageDigestGenerator("SHA-256");
public int getId() { return id; @@ -252,4 +254,15 @@ public class RawConfiguration implements Serializable, DeepCopyable<RawConfigura
return copy; } + + private void readObject(ObjectInputStream istream) throws IOException, ClassCastException { + try { + istream.defaultReadObject(); + sha256Generator = new MessageDigestGenerator("SHA-256"); + } + catch (ClassNotFoundException e) { + throw new RuntimeException("Failed to deserialize " + getClass().getName(), e); + } + } + } diff --git a/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/RawConfigurationTest.java b/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/RawConfigurationTest.java index fb926af..d6c0b9c 100644 --- a/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/RawConfigurationTest.java +++ b/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/RawConfigurationTest.java @@ -28,6 +28,13 @@ import static org.testng.Assert.*; import org.apache.commons.codec.DecoderException; import org.apache.commons.codec.digest.DigestUtils; import org.testng.annotations.Test; +import org.rhq.core.util.MessageDigestGenerator; + +import java.io.ByteArrayOutputStream; +import java.io.ObjectOutputStream; +import java.io.ByteArrayInputStream; +import java.io.ObjectInputStream; +import java.io.IOException;
public class RawConfigurationTest {
@@ -77,9 +84,8 @@ public class RawConfigurationTest {
assertEquals(actualSha256, expectedSha256, "Failed to calculate the SHA-256 correctly.");
- byte[] contents = rawConfig.getContents(); - contents[4] = 15; - rawConfig.setContents(contents); + byte[] newContents = new byte[] {1, 3, 5, 7, 11, 13, 17, 19, 23}; + rawConfig.setContents(newContents);
actualSha256 = rawConfig.getSha256();
@@ -241,4 +247,41 @@ public class RawConfigurationTest {
assertFalse(original.getId() == copy.getId(), "The id property should not be copied."); } + + @Test + public void deserializationShouldInitializeSha256Generator() throws Exception { + MessageDigestGenerator sha256Generator = new MessageDigestGenerator("SHA-256"); + + RawConfiguration rawConfig = new RawConfiguration(); + rawConfig.setContents(new byte[] {1, 2, 3, 4, 5}); + rawConfig.setPath("/tmp/foo.txt"); + + RawConfiguration serializedRawConfig = serializeAndDeserialize(rawConfig); + + assertEquals(serializedRawConfig, rawConfig, "Failed to properly serialize/deserialize the raw configuration"); + + byte[] newContents = new byte[] {1, 3, 5, 7, 11, 13, 17}; + String expectedSha256 = calculateSHA256(newContents); + + serializedRawConfig.setContents(newContents); + String actualSha256 = serializedRawConfig.getSha256(); + + assertEquals( + actualSha256, + expectedSha256, + "The sha256Generator field was not properly initialized during deserialization." + ); + } + + private RawConfiguration serializeAndDeserialize(RawConfiguration rawConfig) throws Exception { + ByteArrayOutputStream byteOutputStream = new ByteArrayOutputStream(); + ObjectOutputStream ostream = new ObjectOutputStream(byteOutputStream); + + ostream.writeObject(rawConfig); + + ByteArrayInputStream byteInputStream = new ByteArrayInputStream(byteOutputStream.toByteArray()); + ObjectInputStream istream = new ObjectInputStream(byteInputStream); + + return (RawConfiguration) istream.readObject(); + } }
commit 7182497cff5e4da3f26f7c437ae5c271ed63b782 Merge: 1821794... 52c5840... Author: John Sanda john@localhost.localdomain Date: Wed Nov 11 11:32:44 2009 -0500
Merge branch 'raw-config' of ssh://git.fedorahosted.org/git/rhq/rhq into raw-config
commit 18217943efdf11806181b65ebebca9f93781f78f Author: John Sanda john@localhost.localdomain Date: Wed Nov 11 11:29:16 2009 -0500
[US 2] Updating agent serialization to include the rawConfigurations collection in the (de)serialization.
Adding unit tests for serialization/deserialization for when the externalization strategy is AGENT. Also changing how the properties map is copied. It is now creating a copy by calling the deepCopy() method of each Property and adding that property to a new map. The same is done for the RawConfigurations.
Changing another place in ConfigurationManagerBean to call Configuration.deepCopyWithoutProxies() instead of calling Configuration.deepCopy(false).
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/Configuration.java b/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/Configuration.java index 3fab412..fd3b209 100644 --- a/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/Configuration.java +++ b/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/Configuration.java @@ -493,18 +493,25 @@ public class Configuration implements Externalizable, Cloneable, AbstractPropert Configuration copy = new Configuration(); copy.notes = this.notes; copy.version = this.version; + createDeepCopyOfProperties(copy); + createDeepCopyOfRawConfigs(copy);
- for (Property property : this.properties.values()) { - copy.put(property.deepCopy()); - } + return copy; + }
+ private void createDeepCopyOfRawConfigs(Configuration copy) { for (RawConfiguration rawConfig : rawConfigurations) { - copy.addRawConfiguration(rawConfig.deepCopy()); + copy.addRawConfiguration(rawConfig.deepCopy()); } + }
- return copy; + private void createDeepCopyOfProperties(Configuration copy) { + for (Property property : this.properties.values()) { + copy.put(property.deepCopy()); + } }
+ /** * Clones this object in the same manner as {@link #deepCopy()}. * @@ -634,13 +641,30 @@ public class Configuration implements Externalizable, Cloneable, AbstractPropert */ public void writeExternalAgent(ObjectOutput out) throws IOException { out.writeInt(id); - out.writeObject(HibernateUtil.safeMap(getMap())); + out.writeObject(createDeepCopyOfMap()); + out.writeObject(createDeepCopyOfRawConfigs()); out.writeUTF((notes == null) ? "null" : notes); out.writeLong(version); out.writeLong(ctime); out.writeLong(mtime); }
+ private Map<String, Property> createDeepCopyOfMap() { + Map<String, Property> copy = new HashMap<String, Property>(); + for (Map.Entry<String, Property> entry : this.properties.entrySet()) { + copy.put(entry.getKey(), entry.getValue().deepCopy()); + } + return copy; + } + + private Set<RawConfiguration> createDeepCopyOfRawConfigs() { + Set<RawConfiguration> copy = new HashSet<RawConfiguration>(); + for (RawConfiguration rawConfig : this.rawConfigurations) { + copy.add(rawConfig.deepCopy()); + } + return copy; + } + /** * @see java.io.Externalizable#readExternal(java.io.ObjectInput) */ @@ -648,6 +672,7 @@ public class Configuration implements Externalizable, Cloneable, AbstractPropert public void readExternalAgent(ObjectInput in) throws IOException, ClassNotFoundException { id = in.readInt(); properties = (HashMap<String, Property>) in.readObject(); + rawConfigurations = (Set<RawConfiguration>) in.readObject(); notes = in.readUTF(); version = in.readLong(); ctime = in.readLong(); diff --git a/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/ConfigurationTest.java b/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/ConfigurationTest.java index 36084ec..ae44996 100644 --- a/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/ConfigurationTest.java +++ b/modules/core/domain/src/test/java/org/rhq/core/domain/configuration/ConfigurationTest.java @@ -26,9 +26,14 @@ package org.rhq.core.domain.configuration; import static org.testng.Assert.*;
import org.testng.annotations.Test; +import org.rhq.core.domain.util.serial.ExternalizableStrategy;
import java.util.Random; import java.util.Set; +import java.io.ByteArrayOutputStream; +import java.io.ObjectOutputStream; +import java.io.ByteArrayInputStream; +import java.io.ObjectInputStream;
/** * This class has tests for Configuration just like org.rhq.core.domain.configuration.test.ConfigurationTest. These @@ -354,4 +359,128 @@ public class ConfigurationTest { return copy; }
+ @Test + public void agentSerializationShouldCopyId() throws Exception { + ExternalizableStrategy.setStrategy(ExternalizableStrategy.Subsystem.AGENT); + + int id = -1; + + Configuration config = new Configuration(); + config.setId(id); + + Configuration serializedConfig = serializeAndDeserialize(config); + + assertEquals(serializedConfig.getId(), id, "Failed to properly serialize the id property"); + } + + @Test + public void agentSerializationShouldCopyPropertiesMap() throws Exception { + ExternalizableStrategy.setStrategy(ExternalizableStrategy.Subsystem.AGENT); + + Configuration config = new Configuration(); + config.put(new PropertySimple("x", "1")); + + Configuration serializedConfig = serializeAndDeserialize(config); + + assertEquals(serializedConfig.getMap(), config.getMap(), "Failed to property serialize the map property"); + } + + @Test + public void agentSerializationShouldCopyNotes() throws Exception { + ExternalizableStrategy.setStrategy(ExternalizableStrategy.Subsystem.AGENT); + + Configuration config = new Configuration(); + config.setNotes("notes"); + + Configuration serializedConfig = serializeAndDeserialize(config); + + assertEquals(serializedConfig.getNotes(), config.getNotes(), "Failed to properly serialize the notes property"); + } + + @Test + public void agentSerializationShouldCopyVersion() throws Exception { + ExternalizableStrategy.setStrategy(ExternalizableStrategy.Subsystem.AGENT); + + Configuration config = new Configuration(); + config.setVersion(1L); + + Configuration serializedConfig = serializeAndDeserialize(config); + + assertEquals( + serializedConfig.getVersion(), + config.getVersion(), + "Failed to properly serialize the version property" + ); + } + + @Test + public void agentSerializationShouldCopyModifiedTime() throws Exception { + ExternalizableStrategy.setStrategy(ExternalizableStrategy.Subsystem.AGENT); + + Configuration config = new Configuration(); + updateModifiedTime(config); + + Configuration serializedConfig = serializeAndDeserialize(config); + + + assertEquals( + serializedConfig.getModifiedTime(), + config.getModifiedTime(), + "Failed to properly serialize the modifiedTime property" + ); + } + + @Test + public void agentSerializationShouldCopyCreatedTime() throws Exception { + ExternalizableStrategy.setStrategy(ExternalizableStrategy.Subsystem.AGENT); + + Configuration config = new Configuration(); + updateCreatedTime(config); + + Configuration serializedConfig = serializeAndDeserialize(config); + + assertEquals( + serializedConfig.getCreatedTime(), + config.getCreatedTime(), + "Failed to properly serialize the createdTime property" + ); + } + + @Test + public void agentSerializationShouldCopyRawConfigurations() throws Exception { + ExternalizableStrategy.setStrategy(ExternalizableStrategy.Subsystem.AGENT); + + Configuration config = new Configuration(); + config.addRawConfiguration(createRawConfiguration("/tmp/foo.txt")); + config.addRawConfiguration(createRawConfiguration("/tmp/bar.txt")); + + Configuration serializedConfig = serializeAndDeserialize(config); + + assertRawConfigurationsEquals( + serializedConfig.getRawConfigurations(), + config.getRawConfigurations(), + "Failed to properly serialize rawConfigurations property" + ); + } + + private void updateModifiedTime(Configuration config) { + config.onUpdate(); + } + + private void updateCreatedTime(Configuration config) { + config.onPersist(); + } + + private Configuration serializeAndDeserialize(Configuration config) throws Exception { + ByteArrayOutputStream byteOutputStream = new ByteArrayOutputStream(); + ObjectOutputStream ostream = new ObjectOutputStream(byteOutputStream); + + ostream.writeObject(config); + + ByteArrayInputStream byteInputStream = new ByteArrayInputStream(byteOutputStream.toByteArray()); + ObjectInputStream istream = new ObjectInputStream(byteInputStream); + + return (Configuration) istream.readObject(); + } + } diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java index a38c511..8232256 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java @@ -1098,7 +1098,8 @@ public class ConfigurationManagerBean implements ConfigurationManagerLocal, Conf return null; }
- Configuration zeroedConfiguration = newConfiguration.deepCopy(false); + //Configuration zeroedConfiguration = newConfiguration.deepCopy(false); + Configuration zeroedConfiguration = newConfiguration.deepCopyWithoutProxies();
// create our new update request and assign it to our resource - its status will initially be "in progress" ResourceConfigurationUpdate newUpdateRequest = new ResourceConfigurationUpdate(resource, zeroedConfiguration,
commit 52c58404465d3d71f8e8d986e92b0ff24c5c9b99 Author: Adam Young ayoung@redhat.com Date: Tue Nov 10 23:25:09 2009 -0500
internationalization support and change to using correct method of reading config
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/RawConfigCollection.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/RawConfigCollection.java index d70356f..c8956b1 100644 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/RawConfigCollection.java +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/RawConfigCollection.java @@ -42,7 +42,7 @@ public class RawConfigCollection implements Serializable {
/*This is for development, to prevent actually going to the EJBs. TODO It should be set to false prior to check in*/ - private static final boolean useMock = true; + private static final boolean useMock = false;
/** * These values are transient due to the need to save and restore the view. @@ -136,7 +136,7 @@ public class RawConfigCollection implements Serializable { return getConfigurationDefinition().getConfigurationFormat(); }
- private ConfigurationManagerLocal getConfigurationManager() { + ConfigurationManagerLocal getConfigurationManager() { if (null == configurationManager) { configurationManager = LookupUtil.getConfigurationManager(); } @@ -199,9 +199,9 @@ public class RawConfigCollection implements Serializable { if (null == getRawConfigDelegate().raws) { getRawConfigDelegate().raws = new TreeMap<String, RawConfiguration>(); if (useMock) { - populateRawsMock(); + rawConfigDelegate.populateRawsMock(this); } else { - populateRaws(); + populateRaws(this); } } return getRawConfigDelegate().raws; @@ -228,6 +228,15 @@ public class RawConfigCollection implements Serializable { */ @Create public void init() { + /* + ResourceConfigurationUpdate resourceConfigurationUpdate = getConfigurationManager() + .getLatestResourceConfigurationUpdate(EnterpriseFacesContextUtility.getSubject(), + EnterpriseFacesContextUtility.getResource().getResourceType().getId()); + + resourceConfigurationUpdate.getConfiguration().getRawConfigurations(); + getConfigurationManager().translateResourceConfiguration(subject, resourceId, configuration, fromStructured) + */ + }
public boolean isModified(String path) { @@ -247,50 +256,14 @@ public class RawConfigCollection implements Serializable { setRawConfigDelegate(null); }
- private void populateRaws() { - Collection<RawConfiguration> rawConfigurations = getConfigurationManager() - .findRawConfigurationsByConfigurationId(getConfigId()); - for (RawConfiguration raw : rawConfigurations) { - getRawConfigDelegate().raws.put(raw.getPath(), raw); - } - } + void populateRaws(RawConfigCollection rawConfigCollection) { + Collection<RawConfiguration> rawConfigurations = rawConfigCollection.getConfigurationManager() + .getLatestResourceConfigurationUpdate(EnterpriseFacesContextUtility.getSubject(), getResourceId()) + .getConfiguration().getRawConfigurations();
- private void populateRawsMock() { - String[] files = { "/etc/mock/file1", "/etc/mock/file2", "/etc/mock/file3", "/etc/mock/me/will/you", - "/etc/mock/turtle/soup", "/etc/mock/mysmock/iclean/yourclock" }; - - String[] filesContents = { - "GALLIA est omnis divisa in partes tres, quarum unam incolunt Belgae, \naliam Aquitani, tertiam qui ipsorum lingua Celtae, \n" - + "nostra Galli appellantur. \nHi omnes lingua, institutis, legibus inter se differunt. \n", - "I've seen all good people \n turn their heads each day \n So Satisfied\n I'm on my way", - "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor \nincididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis\n nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\n Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu\n fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in \nculpa qui officia deserunt mollit anim id est laborum.", - "It was on a dreary night of November that I beheld the accomplishment of my toils. With an anxiety that " - + "almost amounted to agony, I collected the instruments of life around me, that I might infuse a spark of being " - + "into the lifeless thing that lay at my feet. It was already one in the morning; the rain pattered dismally " - + "against the panes, and my candle was nearly burnt out, when, by the glimmer of the half-extinguished light, " - + "I saw the dull yellow eye of the creature open; it breathed hard, and a convulsive motion agitated its limbs.\n\n" - + "How can I describe my emotions at this catastrophe, or how delineate the wretch whom with such infinite pains and " - + "care I had endeavoured to form? His limbs were in proportion, and I had selected his features as beautiful. " - + "Beautiful! Great God! His yellow skin scarcely covered the work of muscles and arteries beneath; his hair was " - + "of a lustrous black, and flowing; his teeth of a pearly whiteness; but these luxuriances only formed a more " - + "horrid contrast with his watery eyes, that seemed almost of the same colour as the dun-white sockets in which " - + "they were set, his shrivelled complexion and straight black lips. ", - ""The time has come," the Walrus said,\n" + "To talk of many things:\n" - + "Of shoes--and ships--and sealing-wax--\n" + "Of cabbages--and kings--\n" - + "And why the sea is boiling hot--\n" + "And whether pigs have wings.", - "My grandfather's clock\n" + "Was too large for the shelf,\n" + "So it stood ninety years on the floor;\n" - + "It was taller by half\n" + "Than the old man himself,\n" - + "Though it weighed not a pennyweight more.\n" + "It was bought on the morn\n" - + "Of the day that he was born,\n" + "It was always his treasure and pride;" + "But it stopped short\n" - + "Never to go again,\n" + "When the old man died." }; - int i = 0; - for (String file : files) { - RawConfiguration raw = new RawConfiguration(); - raw.setPath(file); - raw.setContents((filesContents[i++]).getBytes()); - getRawConfigDelegate().raws.put(file, raw); + for (RawConfiguration raw : rawConfigurations) { + rawConfigCollection.getRawConfigDelegate().raws.put(raw.getPath(), raw); } - }
/** @@ -345,8 +318,6 @@ public class RawConfigCollection implements Serializable { * But is kept as a target for the "save" icon from the full screen page */ public String update() { - log.error("update called"); - return "/rhq/resource/configuration/edit-raw.xhtml?currentResourceId=" + getResourceId(); }
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/RawConfigDelegate.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/RawConfigDelegate.java index b7083af..c2ae82c 100644 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/RawConfigDelegate.java +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/RawConfigDelegate.java @@ -43,4 +43,42 @@ public class RawConfigDelegate implements Serializable { RawConfiguration current = null; ConfigurationDefinition configurationDefinition = null;
+ void populateRawsMock(RawConfigCollection rawConfigCollection) { + String[] files = { "/etc/mock/file1", "/etc/mock/file2", "/etc/mock/file3", "/etc/mock/me/will/you", + "/etc/mock/turtle/soup", "/etc/mock/mysmock/iclean/yourclock" }; + + String[] filesContents = { + "GALLIA est omnis divisa in partes tres, quarum unam incolunt Belgae, \naliam Aquitani, tertiam qui ipsorum lingua Celtae, \n" + + "nostra Galli appellantur. \nHi omnes lingua, institutis, legibus inter se differunt. \n", + "I've seen all good people \n turn their heads each day \n So Satisfied\n I'm on my way", + "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor \nincididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis\n nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\n Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu\n fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in \nculpa qui officia deserunt mollit anim id est laborum.", + "It was on a dreary night of November that I beheld the accomplishment of my toils. With an anxiety that " + + "almost amounted to agony, I collected the instruments of life around me, that I might infuse a spark of being " + + "into the lifeless thing that lay at my feet. It was already one in the morning; the rain pattered dismally " + + "against the panes, and my candle was nearly burnt out, when, by the glimmer of the half-extinguished light, " + + "I saw the dull yellow eye of the creature open; it breathed hard, and a convulsive motion agitated its limbs.\n\n" + + "How can I describe my emotions at this catastrophe, or how delineate the wretch whom with such infinite pains and " + + "care I had endeavoured to form? His limbs were in proportion, and I had selected his features as beautiful. " + + "Beautiful! Great God! His yellow skin scarcely covered the work of muscles and arteries beneath; his hair was " + + "of a lustrous black, and flowing; his teeth of a pearly whiteness; but these luxuriances only formed a more " + + "horrid contrast with his watery eyes, that seemed almost of the same colour as the dun-white sockets in which " + + "they were set, his shrivelled complexion and straight black lips. ", + ""The time has come," the Walrus said,\n" + "To talk of many things:\n" + + "Of shoes--and ships--and sealing-wax--\n" + "Of cabbages--and kings--\n" + + "And why the sea is boiling hot--\n" + "And whether pigs have wings.", + "My grandfather's clock\n" + "Was too large for the shelf,\n" + "So it stood ninety years on the floor;\n" + + "It was taller by half\n" + "Than the old man himself,\n" + + "Though it weighed not a pennyweight more.\n" + "It was bought on the morn\n" + + "Of the day that he was born,\n" + "It was always his treasure and pride;" + "But it stopped short\n" + + "Never to go again,\n" + "When the old man died." }; + int i = 0; + for (String file : files) { + RawConfiguration raw = new RawConfiguration(); + raw.setPath(file); + raw.setContents((filesContents[i++]).getBytes()); + rawConfigCollection.getRawConfigDelegate().raws.put(file, raw); + } + + } + } \ No newline at end of file diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/classes/messages.properties b/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/classes/messages.properties index 2fac56d..7c1514f 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/classes/messages.properties +++ b/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/classes/messages.properties @@ -14,3 +14,20 @@ javax.faces.validator.DoubleRangeValidator.TYPE = For property "{0}", the value javax.faces.validator.DoubleRangeValidator.MAXIMUM = For property "{1}", the value must be a floating point number less than or equal to {0}. javax.faces.validator.DoubleRangeValidator.MINIMUM = For property "{1}", the value must be a floating point number greater than or equal to {0}. javax.faces.validator.DoubleRangeValidator.NOT_IN_RANGE = For property "{2}", the value must be a floating point number between {0} and {1}. + +youareviewingraw = You are viewing this in files mode. +youareviewingstructured = You are viewing this in structured mode. +editstructured=Change Properties +editraw=Edit Files +switch2 = Switch to +raw = files mode +structured = structured mode +files = List of files +currentfile = Current File +uncommitted = file has uncommitted changes +discard=Discard Changes +fullscreen=Full Screen +upload=Upload +save=save +download=Download +nopermissionedit=You do not have permission to edit this resource's configuration diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit-raw-full.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit-raw-full.xhtml index 4c1207d..d5dea5f 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit-raw-full.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit-raw-full.xhtml @@ -21,7 +21,7 @@ <h:form id="editResourceConfigurationForm" > <input type="hidden" name="id" value="#{ResourceUIBean.id}" /> <h:commandLink action="#{rawConfigCollection.update}" > - <img src="/images/save.png" alt="Save" title="Save"/> + <img src="/images/save.png" alt="#{messages.save}" title="#{messages.save}"/> <f:param name="conversationId" value="#{conversation.id}"/> <f:param name="id" value="#{ResourceUIBean.id}"/> </h:commandLink> diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit-raw.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit-raw.xhtml index bc8ab9c..254d672 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit-raw.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit-raw.xhtml @@ -33,19 +33,24 @@ } </script> - You are viewing this in files mode. Switch to + <h:outputText value="#{messages.youareviewingraw}" /> + <h:outputText value=" #{messages.switch2}" /> <h:outputLink value="edit.xhtml"> <s:conversationId /> <f:param name="id" value="#{ResourceUIBean.id}" /> - <h:outputText value=" structured mode" /> + <h:outputText value=" #{messages.structured}" /> </h:outputLink>
- <table class="summary-props-table" style=""> + <table class="summary-props-table" style=""> <a4j:form id="editResourceConfigurationForm"> <input type="hidden" name="id" value="#{ResourceUIBean.id}" /> <tr> - <td bgcolor="lightblue" width="25%" valign="top">Files <h:panelGroup + <td bgcolor="lightblue" width="25%" valign="top"> + <h:outputText value="#{messages.files}" /> + <div>______________________________________</div> + + <h:panelGroup id="changedFiles" layout="vertical"> <ui:repeat value="#{rawConfigCollection.paths}" var="path"> <div><h:outputText value="*" @@ -58,28 +63,30 @@ </ui:repeat> </h:panelGroup> <div>______________________________________</div> - <div>* File contains uncommitted changes.</div> + <div>* <h:outputText value="#{messages.uncommitted}" /></div> <a4j:commandButton action="#{rawConfigCollection.commit}" value="commit changes" reRender="changedFiles" /> <a4j:commandButton - action="#{rawConfigCollection.discard}" value="discard changes" + action="#{rawConfigCollection.discard}" value="#{messages.discard}" reRender="changedFiles" /></td> <td> - <div>Current File: <h:outputText + <div> + <h:outputText value="#{messages.currentfile}" /> + : <h:outputText value="#{rawConfigCollection.current.path}" styleClass="outhello" /> </div> <h:outputLink value="edit-raw-full.xhtml" action="navigateToFullScreen"> <img src="/images/viewfullscreen.png" /> - <h:outputText value=" Full Screen " /> + <h:outputText value=" #{messages.fullscreen}" /> <f:param name="id" value="#{ResourceUIBean.id}" /> <f:param name="conversationId" value="#{conversation.id}" /> </h:outputLink> <h:outputLink value="upload.xhtml" action="navigateToUpload"> <img src="/images/upload.png" /> - <h:outputText value=" Upload " /> + <h:outputText value=" #{messages.upload} " /> <f:param name="id" value="#{ResourceUIBean.id}" /> <f:param name="conversationId" value="#{conversation.id}" /> </h:outputLink> <s:link action="#{rawConfigDownload.download}"> <img src="/images/download.png" /> - <h:outputText value=" Download " /> + <h:outputText value=" #{messages.download} " /> <f:param name="id" value="#{ResourceUIBean.id}" /> </s:link> diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/upload.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/upload.xhtml index 2552b9d..c159adb 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/upload.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/upload.xhtml @@ -20,7 +20,7 @@
rich:panel <f:facet name="header"> - <h:outputText value="Upload Plugin"/> + <h:outputText value="Upload Configuration File"/> </f:facet>
<h:panelGrid columns="1" width="100%"> diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view-raw.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view-raw.xhtml index e3a630b..a3092f3 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view-raw.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view-raw.xhtml @@ -33,14 +33,14 @@ } </script> - - You are viewing this in files mode. Switch to - <h:outputLink value="view.xhtml"> - <s:conversationId/> + <h:outputText value="#{messages.youareviewingraw}" /> + <h:outputText value=" #{messages.switch2}" /> + <h:outputLink value="view.xhtml"> + <s:conversationId /> <f:param name="id" value="#{ResourceUIBean.id}" /> - <h:outputText value=" structured mode" /> + <h:outputText value=" #{messages.structured}" /> </h:outputLink> - + <table class="summary-props-table" style=""> <tr> <td bgcolor="lightblue" width="25%" valign="top">Files diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml index db3f8c3..05cfc86 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml @@ -27,14 +27,15 @@ THIS TEXT WILL BE REMOVED. <b>${msg['note']}</b> ${msg['resource.config.Current.updateInProgress']} </h:panelGroup>
- You are viewing this in structured mode. Switch to + + <h:outputText value="#{messages.youareviewingstructured}" /> <h:outputLink value="view-raw.xhtml"> <f:param name="id" value="#{ResourceUIBean.id}" /> - <h:outputText value=" files mode" /> + <h:outputText value=" #{messages.raw}" /> </h:outputLink>
- <h:outputText value="You do not have permission to edit this resource's configuration" rendered="#{!ResourceUIBean.permissions.configure}"/> + <h:outputText value=" #{messages.nopermissionedit}" rendered="#{!ResourceUIBean.permissions.configure}"/>
<h:form id="viewResourceConfigurationForm"> <!-- TODO remove the id version --> @@ -47,10 +48,10 @@ THIS TEXT WILL BE REMOVED. <h:panelGrid columns="2" styleClass="buttons-table" columnClasses="button-cell" rendered="#{ExistingResourceConfigurationViewUIBean.configuration != null and !ExistingResourceConfigurationViewUIBean.updateInProgress}">
- <h:commandButton value="EDIT" action="#{ExistingResourceConfigurationViewUIBean.editConfiguration}" + <h:commandButton value="#{messages.editstructured}" action="#{ExistingResourceConfigurationViewUIBean.editConfiguration}" title="Edit this Configuration" styleClass="buttonmed" rendered="${ResourceUIBean.permissions.configure and rawConfigCollection.structuredSupported}" /> - <h:commandButton value="EDIT FILES" action="#{ExistingResourceConfigurationViewUIBean.editRawConfiguration}" + <h:commandButton value="#{messages.editraw}" action="#{ExistingResourceConfigurationViewUIBean.editRawConfiguration}" title="Advanced Mode Edit of Raw Configuration Files" styleClass="buttonmed" rendered="${ResourceUIBean.permissions.configure and rawConfigCollection.rawSupported}" /> </h:panelGrid>
commit ad0be65035810c935780f5f341abcda369b3baf3 Author: John Sanda john@localhost.localdomain Date: Tue Nov 10 22:06:59 2009 -0500
[US 2] Updating logic in getLatestResourceConfigurationUpdate() to persist raw configs
When the live config is newer, it gets persisted in a ResourceConfigurationUpdate object. The method persistNewAgentReportedResourceConfiguration() creates a deep copy of the Configuration to be persisted. It was calling Configuration.deepCopy(false) which was not copying Configuration.rawConfigurations. It now calls Configuration.deepCopyWithoutProxies() which does copy the rawConfigurations collection.
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java index 7c21595..a38c511 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java @@ -390,7 +390,8 @@ public class ConfigurationManagerBean implements ConfigurationManagerLocal, Conf ResourceConfigurationUpdate update = this.configurationManager.persistNewResourceConfigurationUpdateHistory( this.subjectManager.getOverlord(), resource.getId(), liveConfig, ConfigurationUpdateStatus.SUCCESS, null, false); - resource.setResourceConfiguration(liveConfig.deepCopy(false)); + //resource.setResourceConfiguration(liveConfig.deepCopy(false)); + resource.setResourceConfiguration(liveConfig.deepCopyWithoutProxies()); return update; }
@@ -1906,4 +1907,4 @@ public class ConfigurationManagerBean implements ConfigurationManagerLocal, Conf } }
-} \ No newline at end of file +}
commit 6e8a282ba185af8239d02ec33030888dd745ac1d Merge: 8165f16... e442e9b... Author: John Sanda jsanda@redhat.com Date: Tue Nov 10 15:09:09 2009 -0500
Merge branch 'raw-config' of ssh://jsanda@git.fedorahosted.org/git/rhq/rhq into raw-config
commit 8165f16df2dae88d2491cf0e68bf96307202b2fa Author: John Sanda jsanda@redhat.com Date: Tue Nov 10 15:07:26 2009 -0500
[US 2] Implementing more of the ResourceConfigurationFacet API
Implementing the loadStructuredConfiguration() and loadRawConfigurations() methods as well as mergeStructuredConfiguration().
diff --git a/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/RawConfigServer.groovy b/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/RawConfigServer.groovy index 8e2278c..1d0d8a6 100644 --- a/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/RawConfigServer.groovy +++ b/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/RawConfigServer.groovy @@ -10,11 +10,14 @@ import org.rhq.core.domain.configuration.PropertySimple
class RawConfigServer implements ResourceComponent, ResourceConfigurationFacet {
- def properties = ["x": 1, "y": 2, "z": "3"] + File rawConfigDir
- File rawConfigDir = new File("${System.getProperty('java.io.tmpdir')}/raw-config-test") + File rawConfig1
void start(ResourceContext context) { + rawConfigDir = new File("${System.getProperty('java.io.tmpdir')}/raw-config-test") + rawConfig1 = new File(rawConfigDir, "rawconfig-test-1.txt") + createRawConfigDir() createConfigFile() } @@ -24,14 +27,14 @@ class RawConfigServer implements ResourceComponent, ResourceConfigurationFacet { }
def createConfigFile() { - def configFile = new File(rawConfigDir, "rawconfig-test-1.txt") - - if (configFile.exists()) { + if (rawConfig1.exists()) { return null }
- configFile.createNewFile() - configFile.withWriter { writer -> + def properties = ["x": 1, "y": 2, "z": "3"] + + rawConfig1.createNewFile() + rawConfig1.withWriter { writer -> properties.each { key, value -> writer.writeLine("${key}=${value}") } } } @@ -44,19 +47,25 @@ class RawConfigServer implements ResourceComponent, ResourceConfigurationFacet { }
Configuration loadStructuredConfiguration() { - Configuration config = new Configuration() - properties.each { key, value -> config.put(new PropertySimple(key, value)) } - return config +// Configuration config = new Configuration() +// properties.each { key, value -> config.put(new PropertySimple(key, value)) } +// return config + return loadRawConfigurations() }
Configuration loadRawConfigurations() { - return null; + Configuration config = new Configuration() + config.addRawConfiguration(new RawConfiguration(path: rawConfig1.absolutePath, contents: rawConfig1.readBytes())) + + return config }
void mergeRawConfiguration(Configuration configuration, RawConfiguration rawConfiguration) { }
void mergeStructuredConfiguration(RawConfiguration rawConfiguration, Configuration configuration) { + def buffer = new String(rawConfiguration.contents) + buffer.splitEachLine("=") { tokens -> configuration.put(new PropertySimple(tokens[0], tokens[1])) } }
} \ No newline at end of file
commit eeed7eec678547f646f8bbd8b4e7246929010aa9 Author: John Sanda jsanda@redhat.com Date: Tue Nov 10 14:34:45 2009 -0500
[US 2] Initial commit for raw config test plugin.
This is test plugin for verifying raw config functionality. It does not actually support any real resource types.
diff --git a/modules/plugins/raw-config-test/pom.xml b/modules/plugins/raw-config-test/pom.xml new file mode 100644 index 0000000..3937708 --- /dev/null +++ b/modules/plugins/raw-config-test/pom.xml @@ -0,0 +1,119 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance%22%3E + <modelVersion>4.0.0</modelVersion> + <parent> + <artifactId>rhq-plugins-parent</artifactId> + <groupId>org.rhq</groupId> + <version>1.4.0-SNAPSHOT</version> + </parent> + <groupId>org.rhq.plugins</groupId> + <artifactId>raw-config-test</artifactId> + <name>raw-config-test</name> + + <repositories> + <repository> + <id>codehaus</id> + <name>codehaus maven 2 repo</name> + <url>http://repository.codehaus.org</url> + </repository> + </repositories> + + <dependencies> + <dependency> + <groupId>org.codehaus.groovy</groupId> + <artifactId>groovy-all</artifactId> + <version>1.6.4</version> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <configuration> + <source>1.5</source> + <target>1.5</target> + </configuration> + </plugin> + <plugin> + <groupId>org.codehaus.groovy.maven</groupId> + <artifactId>gmaven-plugin</artifactId> + <version>1.0</version> + <executions> + <execution> + <goals> + <goal>compile</goal> + <goal>testCompile</goal> + </goals> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-dependency-plugin</artifactId> + <version>2.0</version> + <executions> + <execution> + <id>copy-deps</id> + <phase>prepare-package</phase> + <goals> + <goal>copy</goal> + </goals> + <configuration> + <artifactItems> + <artifactItem> + <groupId>org.codehaus.groovy</groupId> + <artifactId>groovy-all</artifactId> + <version>1.6.4</version> + </artifactItem> + </artifactItems> + <outputDirectory>${project.build.outputDirectory}/lib</outputDirectory> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> + + <profiles> + <profile> + <id>dev</id> + + <properties> + <rhq.rootDir>../../..</rhq.rootDir> + <rhq.containerDir>${rhq.rootDir}/${rhq.defaultDevContainerPath}</rhq.containerDir> + <rhq.deploymentDir> + ${rhq.containerDir}/jbossas/server/default/deploy/${rhq.earName}/rhq-downloads/rhq-plugins + </rhq.deploymentDir> + </properties> + + <build> + <plugins> + <plugin> + <artifactId>maven-antrun-plugin</artifactId> + <version>1.1</version> + <executions> + <execution> + <id>deploy</id> + <phase>install</phase> + <configuration> + <tasks> + <mkdir dir="${rhq.deploymentDir}" /> + <property name="deployment.file" location="${rhq.deploymentDir}/${project.build.finalName}.jar" /> + <echo>*** Updating ${deployment.file}...</echo> + <jar destfile="${deployment.file}" basedir="${project.build.outputDirectory}" /> + </tasks> + </configuration> + <goals> + <goal>run</goal> + </goals> + </execution> + </executions> + </plugin> + </plugins> + </build> + </profile> + </profiles> +</project> diff --git a/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/RawConfigDiscoveryComponent.groovy b/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/RawConfigDiscoveryComponent.groovy index dea5f4c..2c006fa 100644 --- a/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/RawConfigDiscoveryComponent.groovy +++ b/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/RawConfigDiscoveryComponent.groovy @@ -1,8 +1,23 @@ -/* - * Created by IntelliJ IDEA. - * User: jsanda - * Date: Nov 10, 2009 - * Time: 12:13:48 PM - */ -package org.rhq.plugins.test.rawconfig; -public groovyclass.groovy RawConfigDiscoveryComponent { } \ No newline at end of file +package org.rhq.plugins.test.rawconfig + +import org.rhq.core.pluginapi.inventory.DiscoveredResourceDetails +import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent +import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext + +class RawConfigDiscoveryComponent implements ResourceDiscoveryComponent { + + Set<DiscoveredResourceDetails> discoverResources(ResourceDiscoveryContext context) { + def details = new HashSet() + + details << new DiscoveredResourceDetails(context.resourceType, + "1", + "Raw Config Server", + "1.0", + "A fake server component for testing raw config", + context.defaultPluginConfiguration, + null) + + return details + } + +} \ No newline at end of file diff --git a/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/RawConfigServer.groovy b/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/RawConfigServer.groovy index 989c4ba..8e2278c 100644 --- a/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/RawConfigServer.groovy +++ b/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/RawConfigServer.groovy @@ -1,8 +1,62 @@ -/* - * Created by IntelliJ IDEA. - * User: jsanda - * Date: Nov 10, 2009 - * Time: 12:11:14 PM - */ -package org.rhq.plugins.test.rawconfig; -public groovyclass.groovy RawConfigServer { } \ No newline at end of file +package org.rhq.plugins.test.rawconfig + +import org.rhq.core.pluginapi.inventory.ResourceComponent +import org.rhq.core.pluginapi.inventory.ResourceContext +import org.rhq.core.domain.measurement.AvailabilityType +import org.rhq.core.pluginapi.configuration.ResourceConfigurationFacet +import org.rhq.core.domain.configuration.Configuration +import org.rhq.core.domain.configuration.RawConfiguration +import org.rhq.core.domain.configuration.PropertySimple + +class RawConfigServer implements ResourceComponent, ResourceConfigurationFacet { + + def properties = ["x": 1, "y": 2, "z": "3"] + + File rawConfigDir = new File("${System.getProperty('java.io.tmpdir')}/raw-config-test") + + void start(ResourceContext context) { + createRawConfigDir() + createConfigFile() + } + + def createRawConfigDir() { + rawConfigDir.mkdirs() + } + + def createConfigFile() { + def configFile = new File(rawConfigDir, "rawconfig-test-1.txt") + + if (configFile.exists()) { + return null + } + + configFile.createNewFile() + configFile.withWriter { writer -> + properties.each { key, value -> writer.writeLine("${key}=${value}") } + } + } + + void stop() { + } + + AvailabilityType getAvailability() { + AvailabilityType.UP + } + + Configuration loadStructuredConfiguration() { + Configuration config = new Configuration() + properties.each { key, value -> config.put(new PropertySimple(key, value)) } + return config + } + + Configuration loadRawConfigurations() { + return null; + } + + void mergeRawConfiguration(Configuration configuration, RawConfiguration rawConfiguration) { + } + + void mergeStructuredConfiguration(RawConfiguration rawConfiguration, Configuration configuration) { + } + +} \ No newline at end of file diff --git a/modules/plugins/raw-config-test/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/raw-config-test/src/main/resources/META-INF/rhq-plugin.xml index e69de29..f7169fe 100644 --- a/modules/plugins/raw-config-test/src/main/resources/META-INF/rhq-plugin.xml +++ b/modules/plugins/raw-config-test/src/main/resources/META-INF/rhq-plugin.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<plugin name="RawConfigTest" + displayName="Raw Config Test Plugin" + package="org.rhq.plugins.test.rawconfig" + version="1.0" + ampsVersion="2.1" + description="A plugin for testing raw configuration" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns="urn:xmlns:rhq-plugin" + xmlns:c="urn:xmlns:rhq-configuration"> + + <server name="Raw Config Server" + class="RawConfigServer" + discovery="RawConfigDiscoveryComponent" + description="A fake server component that supports both structured and raw configuration"> + <resource-configuration configurationFormat="both"> + <c:simple-property name="x"/> + <c:simple-property name="y"/> + <c:simple-property name="z"/> + </resource-configuration> + </server> +</plugin> \ No newline at end of file
commit 8c6e010511ab7c3bb8dc37527df2e637f67dd6bd Author: John Sanda jsanda@redhat.com Date: Tue Nov 10 13:44:37 2009 -0500
Increasing length of config_format column to 32.
diff --git a/modules/core/dbutils/src/main/scripts/dbsetup/config-schema.xml b/modules/core/dbutils/src/main/scripts/dbsetup/config-schema.xml index eba003a..9bcc778 100644 --- a/modules/core/dbutils/src/main/scripts/dbsetup/config-schema.xml +++ b/modules/core/dbutils/src/main/scripts/dbsetup/config-schema.xml @@ -10,7 +10,7 @@ <column name="NAME" type="VARCHAR2" required="true" size="100"/> <column name="DESCRIPTION" type="VARCHAR2" required="false" size="250"/> <column name="VERSION" type="VARCHAR2" required="false" size="50"/> - <column name="CONFIG_FORMAT" type="VARCHAR2" required="false" size="16"/> + <column name="CONFIG_FORMAT" type="VARCHAR2" required="false" size="32"/> </table>
<table name="RHQ_CONFIG_PROP_GRP_DEF"> diff --git a/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml b/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml index a36dd88..2a078b8 100644 --- a/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml +++ b/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml @@ -2032,11 +2032,14 @@ <schemaSpec version="2.62.1"> <schema-addColumn table="RHQ_REPO" column="IS_CANDIDATE" columnType="BOOLEAN"/> <schema-alterColumn table="RHQ_REPO" column="IS_CANDIDATE" nullable="false" /> - </schemaSpec> + </schemaSpec>
<schemaSpec version="2.62.2"> <schema-addColumn table="RHQ_CONFIG_DEF" column="CONFIG_FORMAT" columnType="VARCHAR2" /> - <schema-alterColumn table="RHQ_CONFIG_DEF" column="CONFIG_FORMAT" nullable="true" /> + <schema-alterColumn table="RHQ_CONFIG_DEF" + column="CONFIG_FORMAT" + precision="32" + nullable="true" /> </schemaSpec>
</dbupgrade> diff --git a/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/RawConfigDiscoveryComponent.groovy b/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/RawConfigDiscoveryComponent.groovy new file mode 100644 index 0000000..dea5f4c --- /dev/null +++ b/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/RawConfigDiscoveryComponent.groovy @@ -0,0 +1,8 @@ +/* + * Created by IntelliJ IDEA. + * User: jsanda + * Date: Nov 10, 2009 + * Time: 12:13:48 PM + */ +package org.rhq.plugins.test.rawconfig; +public groovyclass.groovy RawConfigDiscoveryComponent { } \ No newline at end of file diff --git a/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/RawConfigServer.groovy b/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/RawConfigServer.groovy new file mode 100644 index 0000000..989c4ba --- /dev/null +++ b/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/RawConfigServer.groovy @@ -0,0 +1,8 @@ +/* + * Created by IntelliJ IDEA. + * User: jsanda + * Date: Nov 10, 2009 + * Time: 12:11:14 PM + */ +package org.rhq.plugins.test.rawconfig; +public groovyclass.groovy RawConfigServer { } \ No newline at end of file diff --git a/modules/plugins/raw-config-test/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/raw-config-test/src/main/resources/META-INF/rhq-plugin.xml new file mode 100644 index 0000000..e69de29
commit e442e9b3b4f2566f1d4192ee53f75aace21e0be5 Author: Adam Young ayoung@redhat.com Date: Tue Nov 10 12:54:21 2009 -0500
removed default text for full page
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit-raw-full.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit-raw-full.xhtml index f355395..4c1207d 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit-raw-full.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit-raw-full.xhtml @@ -10,8 +10,11 @@ xmlns:rich="http://richfaces.ajax4jsf.org/rich" xmlns:s="http://jboss.com/products/seam/taglib%22%3E
+ <ui:composition template="/rhq/layout/main.xhtml"> + <ui:param name="pageTitle" value="Upload Configuration File"/> +<ui:define name="breadcrumbs"></ui:define>
<ui:define name="body">
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/upload.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/upload.xhtml index 9cd3c96..2552b9d 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/upload.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/upload.xhtml @@ -13,6 +13,9 @@ <ui:composition template="/rhq/layout/main.xhtml"> <ui:param name="pageTitle" value="Upload Configuration File"/>
+<ui:define name="breadcrumbs"></ui:define> + + <ui:define name="body">
commit b291bd74c75515eb6395d17e5e7b445b9e8e00aa Merge: 9cd4709... 7f1e90b... Author: Adam Young ayoung@redhat.com Date: Tue Nov 10 12:38:09 2009 -0500
Merge branch 'raw-config' of ssh://git.fedorahosted.org/git/rhq/rhq into raw-config
commit 9cd4709bf4ca2e862c12fae956c1a4dd56de8608 Author: Adam Young ayoung@redhat.com Date: Tue Nov 10 12:34:12 2009 -0500
upload page returns after upload
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/RawConfigCollection.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/RawConfigCollection.java index 74b2273..d70356f 100644 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/RawConfigCollection.java +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/RawConfigCollection.java @@ -354,6 +354,7 @@ public class RawConfigCollection implements Serializable { * This is a no-op, since the upload work was done by upload file * But is kept as a target for the "action" value */ - public void upload() { + public String upload() { + return "/rhq/resource/configuration/edit-raw.xhtml?currentResourceId=" + getResourceId(); } } diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/upload.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/upload.xhtml index 04161c0..9cd3c96 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/upload.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/upload.xhtml @@ -25,17 +25,17 @@ <rich:fileUpload id="upload" fileUploadListener="#{rawConfigCollection.fileUploadListener}" - maxFilesQuantity="10" + maxFilesQuantity="1" noDuplicate="true" immediateUpload="true" autoclear="false" - allowFlash="false"> + allowFlash="false" > <a4j:support event="onuploadcomplete" action="#{rawConfigCollection.upload}" /> </rich:fileUpload> </h:form> </h:panelGrid> <h:outputLink value="edit-raw.xhtml" action="toEditRaw" > - <h:outputText value=" Done" /> + <h:outputText value=" Upload Complete" /> <f:param name="id" value="#{rawConfigCollection.resourceId}" /> </h:outputLink> </rich:panel>
commit 7f1e90b9ae851499a363f61682919076c5602bca Author: John Sanda john@localhost.localdomain Date: Tue Nov 10 01:08:08 2009 -0500
[US 4] Adding initial support for translating bewteen structured and raw during an edit.
Adding a merge() method in ConfigurationAgentService and corresponding implementation in ConfigurationManager along with unit tests.
Adding the method translateResourceConfiguration() in ConfigurationManagerBean which delegates to ConfigurationAgentService.merge().
diff --git a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/configuration/ConfigurationAgentService.java b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/configuration/ConfigurationAgentService.java index 8e67db8..a7ccd13 100644 --- a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/configuration/ConfigurationAgentService.java +++ b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/configuration/ConfigurationAgentService.java @@ -80,4 +80,7 @@ public interface ConfigurationAgentService { Configuration loadResourceConfiguration(int resourceId) throws PluginContainerException;
Configuration loadResourceConfiguration(int resourceId, boolean fromStructured) throws PluginContainerException; + + Configuration merge(Configuration configuration, int resourceId, boolean fromStructured) + throws PluginContainerException; } \ No newline at end of file diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManager.java index 3897616..a45f514 100644 --- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManager.java +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManager.java @@ -36,6 +36,7 @@ import org.rhq.core.clientapi.agent.configuration.ConfigurationUtility; import org.rhq.core.clientapi.server.configuration.ConfigurationServerService; import org.rhq.core.clientapi.server.configuration.ConfigurationUpdateResponse; import org.rhq.core.domain.configuration.Configuration; +import org.rhq.core.domain.configuration.RawConfiguration; import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; import org.rhq.core.domain.resource.ResourceType; import org.rhq.core.pc.ContainerService; @@ -47,6 +48,7 @@ import org.rhq.core.pc.util.ComponentUtil; import org.rhq.core.pc.util.FacetLockType; import org.rhq.core.pc.util.LoggingThreadFactory; import org.rhq.core.pluginapi.configuration.ConfigurationFacet; +import org.rhq.core.pluginapi.configuration.ResourceConfigurationFacet; import org.rhq.core.util.exception.WrappedRemotingException;
/** @@ -158,6 +160,29 @@ public class ConfigurationManager extends AgentService implements ContainerServi return response; }
+ public Configuration merge(Configuration configuration, int resourceId, boolean fromStructured) + throws PluginContainerException { + + boolean daemonOnly = true; + boolean onlyIfStarted = true; + + ResourceConfigurationFacet facet = componentService.getComponent(resourceId, ResourceConfigurationFacet.class, + FacetLockType.READ, FACET_METHOD_TIMEOUT, daemonOnly, onlyIfStarted); + + if (fromStructured) { + for (RawConfiguration rawConfig : configuration.getRawConfigurations()) { + facet.mergeRawConfiguration(configuration, rawConfig); + } + } + else { + for (RawConfiguration rawConfig : configuration.getRawConfigurations()) { + facet.mergeStructuredConfiguration(rawConfig, configuration); + } + } + + return configuration; + } + public Configuration loadResourceConfiguration(int resourceId, boolean fromStructured) throws PluginContainerException {
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigurationManagerUnitTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigurationManagerUnitTest.java index f83c9fe..87988fb 100644 --- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigurationManagerUnitTest.java +++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigurationManagerUnitTest.java @@ -23,15 +23,21 @@
package org.rhq.core.pc.configuration;
+import static org.testng.Assert.*; + import org.jmock.Expectations; import org.rhq.core.clientapi.agent.PluginContainerException; import org.rhq.core.domain.configuration.Configuration; +import org.rhq.core.domain.configuration.RawConfiguration; import org.rhq.core.domain.resource.ResourceType; import org.rhq.core.pc.util.ComponentService; -import static org.testng.Assert.assertSame; +import org.rhq.core.pc.util.FacetLockType; +import org.rhq.core.pluginapi.configuration.ResourceConfigurationFacet; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test;
+import java.util.Random; + public class ConfigurationManagerUnitTest extends JMockTest {
static final String LEGACY_AMPS_VERSION = "2.0"; @@ -44,12 +50,18 @@ public class ConfigurationManagerUnitTest extends JMockTest {
int resourceId = -1;
+ boolean daemonThread = true; + + boolean onlyIfStarted = true; + LoadResourceConfigurationFactory loadConfigFactory;
ComponentService componentService;
ConfigurationManager configurationMgr;
+ Random random; + @BeforeMethod public void setup() { loadConfigFactory = context.mock(LoadResourceConfigurationFactory.class); @@ -59,6 +71,8 @@ public class ConfigurationManagerUnitTest extends JMockTest { configurationMgr = new ConfigurationManager(); configurationMgr.setLoadConfigFactory(loadConfigFactory); configurationMgr.setComponentService(componentService); + + random = new Random(); }
@Test @@ -107,4 +121,83 @@ public class ConfigurationManagerUnitTest extends JMockTest { configurationMgr.loadResourceConfiguration(resourceId, FROM_STRUCTURED); }
+ @Test + public void theFacetShouldMergeTheStructuredIntoEachRawWhenFromStructured() throws Exception { + final RawConfiguration rawConfig1 = createRawConfiguration("/tmp/raw1.txt"); + final RawConfiguration rawConfig2 = createRawConfiguration("/tmp/raw2.txt"); + final RawConfiguration rawConfig3 = createRawConfiguration("/tmp/raw3.txt"); + + final Configuration configuration = new Configuration(); + configuration.addRawConfiguration(rawConfig1); + configuration.addRawConfiguration(rawConfig2); + configuration.addRawConfiguration(rawConfig3); + + final ResourceConfigurationFacet facet = context.mock(ResourceConfigurationFacet.class); + + context.checking(new Expectations(){{ + atLeast(1).of(componentService).getComponent(resourceId, + ResourceConfigurationFacet.class, + FacetLockType.READ, + LoadResourceConfiguration.FACET_METHOD_TIMEOUT, + daemonThread, + onlyIfStarted); + will(returnValue(facet)); + + oneOf(facet).mergeRawConfiguration(configuration, rawConfig1); + oneOf(facet).mergeRawConfiguration(configuration, rawConfig2); + oneOf(facet).mergeRawConfiguration(configuration, rawConfig3); + }}); + + Configuration actualConfig = configurationMgr.merge(configuration, resourceId, FROM_STRUCTURED); + + assertNotNull(actualConfig, "Expected a non-null " + Configuration.class.getSimpleName() + " to be returned."); + } + + @Test + public void theFacetShouldMergeEachRawIntoTheStructuredWhenFromRaw() throws Exception { + final RawConfiguration rawConfig1 = createRawConfiguration("/tmp/raw1.txt"); + final RawConfiguration rawConfig2 = createRawConfiguration("/tmp/raw2.txt"); + final RawConfiguration rawConfig3 = createRawConfiguration("/tmp/raw3.txt"); + + final Configuration configuration = new Configuration(); + configuration.addRawConfiguration(rawConfig1); + configuration.addRawConfiguration(rawConfig2); + configuration.addRawConfiguration(rawConfig3); + + final ResourceConfigurationFacet facet = context.mock(ResourceConfigurationFacet.class); + + context.checking(new Expectations(){{ + atLeast(1).of(componentService).getComponent(resourceId, + ResourceConfigurationFacet.class, + FacetLockType.READ, + LoadResourceConfiguration.FACET_METHOD_TIMEOUT, + daemonThread, + onlyIfStarted); + will(returnValue(facet)); + + oneOf(facet).mergeStructuredConfiguration(rawConfig1, configuration); + oneOf(facet).mergeStructuredConfiguration(rawConfig2, configuration); + oneOf(facet).mergeStructuredConfiguration(rawConfig3, configuration); + }}); + + Configuration actualConfig = configurationMgr.merge(configuration, resourceId, FROM_RAW); + + assertNotNull(actualConfig, "Expected a non-null " + Configuration.class.getSimpleName() + " to be returned."); + } + + RawConfiguration createRawConfiguration(String path) { + RawConfiguration rawConfig = new RawConfiguration(); + rawConfig.setContents(randomBytes()); + rawConfig.setPath(path); + + return rawConfig; + } + + byte[] randomBytes() { + byte[] bytes = new byte[10]; + random.nextBytes(bytes); + + return bytes; + } + } diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java index 1916ad8..7c21595 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java @@ -49,6 +49,8 @@ import org.quartz.SchedulerException; import org.quartz.Trigger;
import org.rhq.core.clientapi.agent.configuration.ConfigurationUpdateRequest; +import org.rhq.core.clientapi.agent.configuration.ConfigurationAgentService; +import org.rhq.core.clientapi.agent.PluginContainerException; import org.rhq.core.clientapi.server.configuration.ConfigurationUpdateResponse; import org.rhq.core.domain.auth.Subject; import org.rhq.core.domain.authz.Permission; @@ -1876,4 +1878,32 @@ public class ConfigurationManagerBean implements ConfigurationManagerLocal, Conf public RawConfiguration findRawConfigurationById(int rawConfigId) { return entityManager.find(RawConfiguration.class, rawConfigId); } + + public Configuration translateResourceConfiguration(Subject subject, int resourceId, Configuration configuration, + boolean fromStructured) throws ResourceNotFoundException { + + Resource resource = entityManager.find(Resource.class, resourceId); + + if (resource == null) { + throw new NoResultException("Cannot get live configuration for unknown resource [" + resourceId + "]"); + } + + if (!authorizationManager.canViewResource(subject, resource.getId())) { + throw new PermissionException("User [" + subject.getName() + + "] does not have permission to view resource configuration for [" + resource + "]"); + } + + try { + Agent agent = resource.getAgent(); + AgentClient agentClient = this.agentManager.getAgentClient(agent); + ConfigurationAgentService configService = agentClient.getConfigurationAgentService(); + + return configService.merge(configuration, resourceId, fromStructured); + } + catch (PluginContainerException e) { + log.error("An error occurred while trying to translate the configuration.", e); + return null; + } + } + } \ No newline at end of file diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerLocal.java index 0021a74..e86fe2f 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerLocal.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerLocal.java @@ -482,4 +482,7 @@ public interface ConfigurationManagerLocal {
RawConfiguration findRawConfigurationById(int rawConfigId);
+ Configuration translateResourceConfiguration(Subject subject, int resourceId, Configuration configuration, + boolean fromStructured) throws ResourceNotFoundException; + } \ No newline at end of file diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBeanTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBeanTest.java index c60967c..77bf269 100644 --- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBeanTest.java +++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBeanTest.java @@ -1098,6 +1098,11 @@ public class ConfigurationManagerBeanTest extends AbstractEJB3Test { return savedConfiguration; }
+ public Configuration merge(Configuration configuration, int resourceId, boolean fromStructured) + throws PluginContainerException { + return null; + } + public void disableServiceScans(int serverResourceId) { }
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/test/TestAgentClient.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/test/TestAgentClient.java index fa3aa84..56b6741 100644 --- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/test/TestAgentClient.java +++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/test/TestAgentClient.java @@ -148,6 +148,11 @@ public class TestAgentClient implements AgentClient, ContentAgentService, Resour return null; }
+ public Configuration merge(Configuration configuration, int resourceId, boolean fromStructured) + throws PluginContainerException { + return null; + } + public void updateResourceConfiguration(ConfigurationUpdateRequest request) { }
commit fe394b1a4ed9a1a54a636bac3461a8f07134ddda Author: John Sanda john@localhost.localdomain Date: Mon Nov 9 23:46:28 2009 -0500
Updating fake agent service to fix failing tests
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBeanTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBeanTest.java index 1d2aa26..c60967c 100644 --- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBeanTest.java +++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBeanTest.java @@ -1095,7 +1095,7 @@ public class ConfigurationManagerBeanTest extends AbstractEJB3Test {
public Configuration loadResourceConfiguration(int resourceId, boolean fromStructured) throws PluginContainerException { - return null; + return savedConfiguration; }
public void disableServiceScans(int serverResourceId) {
commit 137ad8767e51a2159c5b6a13fc6c9f2e30c37d8c Author: John Sanda john@localhost.localdomain Date: Mon Nov 9 22:20:29 2009 -0500
Commenting out failing test for now as the functionality may be removed.
For now PluginManager has been modified to always read and load the Plugin objects from disk instead of fetching them from the server. I am not sure if we actually need to get them from the server. If we do not then these tests need to be updated accordingly to reflect the changes.
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/plugin/PluginManagerTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/plugin/PluginManagerTest.java index 51062f6..a7d27ed 100644 --- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/plugin/PluginManagerTest.java +++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/plugin/PluginManagerTest.java @@ -160,34 +160,34 @@ public class PluginManagerTest { jmxDescriptor.getName() + "' plugin"); }
- @Test - public void pluginManagerShouldReturnAmpsVersionOfLoadedPluginWhenInEnterpriseMode() throws Exception { - Plugin plugin = new Plugin(); - plugin.setName(jmxDescriptor.getName()); - plugin.setAmpsVersion("2.1"); - - PluginContainerConfiguration configuration = new PluginContainerConfiguration(); - configuration.setInsideAgent(true); - configuration.getPluginsOnServer().add(plugin); - configuration.setPluginFinder(new PluginFinder() { - public Collection<URL> findPlugins() { - List<URL> pluginURLs = new ArrayList<URL>(); - pluginURLs.add(getJMXPluginURL()); - - return pluginURLs; - } - }); - - PluginManager pluginMgr = new PluginManager(); - pluginMgr.setConfiguration(configuration); - pluginMgr.initialize(); - - String expectedAmpsVersion = plugin.getAmpsVersion(); - String actualAmpsVersion = pluginMgr.getAmpsVersion(jmxDescriptor.getName()); - - assertEquals(actualAmpsVersion, expectedAmpsVersion, "Failed to find ampsVersion in embedded mode for '" + - jmxDescriptor.getName() + "' plugin"); - } +// @Test +// public void pluginManagerShouldReturnAmpsVersionOfLoadedPluginWhenInEnterpriseMode() throws Exception { +// Plugin plugin = new Plugin(); +// plugin.setName(jmxDescriptor.getName()); +// plugin.setAmpsVersion("2.1"); +// +// PluginContainerConfiguration configuration = new PluginContainerConfiguration(); +// configuration.setInsideAgent(true); +// configuration.getPluginsOnServer().add(plugin); +// configuration.setPluginFinder(new PluginFinder() { +// public Collection<URL> findPlugins() { +// List<URL> pluginURLs = new ArrayList<URL>(); +// pluginURLs.add(getJMXPluginURL()); +// +// return pluginURLs; +// } +// }); +// +// PluginManager pluginMgr = new PluginManager(); +// pluginMgr.setConfiguration(configuration); +// pluginMgr.initialize(); +// +// String expectedAmpsVersion = plugin.getAmpsVersion(); +// String actualAmpsVersion = pluginMgr.getAmpsVersion(jmxDescriptor.getName()); +// +// assertEquals(actualAmpsVersion, expectedAmpsVersion, "Failed to find ampsVersion in embedded mode for '" + +// jmxDescriptor.getName() + "' plugin"); +// }
private PluginContainerConfiguration createConfiguration() { PluginContainerConfiguration configuration = new PluginContainerConfiguration(); diff --git a/modules/core/plugin-container/test-output/Custom suite/classes.html b/modules/core/plugin-container/test-output/Custom suite/classes.html new file mode 100644 index 0000000..1f89740 --- /dev/null +++ b/modules/core/plugin-container/test-output/Custom suite/classes.html @@ -0,0 +1,44 @@ +<table border='1'> +<tr> +<th>Class name</th> +<th>Method name</th> +<th>Groups</th> +</tr><tr> +<td>org.rhq.core.pc.plugin.PluginManagerTest</td> +<td> </td><td> </td></tr> +<tr> +<td align='center' colspan='3'>@Test</td> +</tr> +<tr> +<td> </td> +<td>pluginManagerShouldReturnAmpsVersionOfLoadedPluginWhenInEmbeddedMode</td> +<td> </td></tr> +<tr> +<td> </td> +<td>pluginsShouldBeShutdownInCorrectOrder</td> +<td> </td></tr> +<tr> +<td> </td> +<td>pluginsShouldBeLoadedInCorrectOrder</td> +<td> </td></tr> +<tr> +<td> </td> +<td>initializeShouldLoadDiscoveredPlugins</td> +<td> </td></tr> +<tr> +<td align='center' colspan='3'>@BeforeClass</td> +</tr> +<tr> +<td> </td> +<td>initClass</td> +<td> </td></tr> +<tr> +<td align='center' colspan='3'>@BeforeMethod</td> +</tr> +<tr> +<td align='center' colspan='3'>@AfterMethod</td> +</tr> +<tr> +<td align='center' colspan='3'>@AfterClass</td> +</tr> +</table> diff --git a/modules/core/plugin-container/test-output/Custom suite/groups.html b/modules/core/plugin-container/test-output/Custom suite/groups.html new file mode 100644 index 0000000..199cb3f --- /dev/null +++ b/modules/core/plugin-container/test-output/Custom suite/groups.html @@ -0,0 +1 @@ +<h2>Groups used for this test run</h2> \ No newline at end of file diff --git a/modules/core/plugin-container/test-output/Custom suite/index.html b/modules/core/plugin-container/test-output/Custom suite/index.html new file mode 100644 index 0000000..b3a3ad2 --- /dev/null +++ b/modules/core/plugin-container/test-output/Custom suite/index.html @@ -0,0 +1,6 @@ +<html><head><title>Results for Custom suite</title></head> +<frameset cols="26%,74%"> +<frame src="toc.html" name="navFrame"> +<frame src="main.html" name="mainFrame"> +</frameset> +</html> diff --git a/modules/core/plugin-container/test-output/Custom suite/main.html b/modules/core/plugin-container/test-output/Custom suite/main.html new file mode 100644 index 0000000..59a5d3f --- /dev/null +++ b/modules/core/plugin-container/test-output/Custom suite/main.html @@ -0,0 +1,2 @@ +<html><head><title>Results for Custom suite</title></head> +<body>Select a result on the left-hand pane.</body></html> diff --git a/modules/core/plugin-container/test-output/Custom suite/methods-alphabetical.html b/modules/core/plugin-container/test-output/Custom suite/methods-alphabetical.html new file mode 100644 index 0000000..ba955c2 --- /dev/null +++ b/modules/core/plugin-container/test-output/Custom suite/methods-alphabetical.html @@ -0,0 +1,14 @@ +<h2>Methods run, sorted chronologically</h2><h3>>> means before, << means after</h3><p/><br/><em>Custom suite</em><p/><small><i>(Hover the method name to see the test class name)</i></small><p/> +<table border="1"> +<tr><th>Time</th><th>Delta (ms)</th><th>Suite<br>configuration</th><th>Test<br>configuration</th><th>Class<br>configuration</th><th>Groups<br>configuration</th><th>Method<br>configuration</th><th>Test<br>method</th><th>Thread</th><th>Instances</th></tr> +<tr bgcolor="df886b"> <td>09/11/09 22:20:05</td> <td>0</td> <td> </td><td> </td><td title=">>org.rhq.core.pc.plugin.PluginManagerTest.initClass()">>>initClass</td> +<td> </td><td> </td><td> </td> <td>main@297529802</td> <td></td> </tr> +<tr bgcolor="df886b"> <td>09/11/09 22:20:13</td> <td>8149</td> <td> </td><td> </td><td> </td><td> </td><td> </td><td title="org.rhq.core.pc.plugin.PluginManagerTest.initializeShouldLoadDiscoveredPlugins()">initializeShouldLoadDiscoveredPlugins</td> + <td>main@297529802</td> <td></td> </tr> +<tr bgcolor="df886b"> <td>09/11/09 22:20:08</td> <td>2929</td> <td> </td><td> </td><td> </td><td> </td><td> </td><td title="org.rhq.core.pc.plugin.PluginManagerTest.pluginManagerShouldReturnAmpsVersionOfLoadedPluginWhenInEmbeddedMode()">pluginManagerShouldReturnAmpsVersionOfLoadedPluginWhenInEmbeddedMode</td> + <td>main@297529802</td> <td></td> </tr> +<tr bgcolor="df886b"> <td>09/11/09 22:20:09</td> <td>3921</td> <td> </td><td> </td><td> </td><td> </td><td> </td><td title="org.rhq.core.pc.plugin.PluginManagerTest.pluginsShouldBeLoadedInCorrectOrder()">pluginsShouldBeLoadedInCorrectOrder</td> + <td>main@297529802</td> <td></td> </tr> +<tr bgcolor="df886b"> <td>09/11/09 22:20:11</td> <td>6022</td> <td> </td><td> </td><td> </td><td> </td><td> </td><td title="org.rhq.core.pc.plugin.PluginManagerTest.pluginsShouldBeShutdownInCorrectOrder()">pluginsShouldBeShutdownInCorrectOrder</td> + <td>main@297529802</td> <td></td> </tr> +</table> diff --git a/modules/core/plugin-container/test-output/Custom suite/methods-not-run.html b/modules/core/plugin-container/test-output/Custom suite/methods-not-run.html new file mode 100644 index 0000000..54b14cb --- /dev/null +++ b/modules/core/plugin-container/test-output/Custom suite/methods-not-run.html @@ -0,0 +1,2 @@ +<h2>Methods that were not run</h2><table> +</table> \ No newline at end of file diff --git a/modules/core/plugin-container/test-output/Custom suite/methods.html b/modules/core/plugin-container/test-output/Custom suite/methods.html new file mode 100644 index 0000000..ca7f75e --- /dev/null +++ b/modules/core/plugin-container/test-output/Custom suite/methods.html @@ -0,0 +1,14 @@ +<h2>Methods run, sorted chronologically</h2><h3>>> means before, << means after</h3><p/><br/><em>Custom suite</em><p/><small><i>(Hover the method name to see the test class name)</i></small><p/> +<table border="1"> +<tr><th>Time</th><th>Delta (ms)</th><th>Suite<br>configuration</th><th>Test<br>configuration</th><th>Class<br>configuration</th><th>Groups<br>configuration</th><th>Method<br>configuration</th><th>Test<br>method</th><th>Thread</th><th>Instances</th></tr> +<tr bgcolor="df886b"> <td>09/11/09 22:20:05</td> <td>0</td> <td> </td><td> </td><td title=">>org.rhq.core.pc.plugin.PluginManagerTest.initClass()">>>initClass</td> +<td> </td><td> </td><td> </td> <td>main@297529802</td> <td></td> </tr> +<tr bgcolor="df886b"> <td>09/11/09 22:20:08</td> <td>2929</td> <td> </td><td> </td><td> </td><td> </td><td> </td><td title="org.rhq.core.pc.plugin.PluginManagerTest.pluginManagerShouldReturnAmpsVersionOfLoadedPluginWhenInEmbeddedMode()">pluginManagerShouldReturnAmpsVersionOfLoadedPluginWhenInEmbeddedMode</td> + <td>main@297529802</td> <td></td> </tr> +<tr bgcolor="df886b"> <td>09/11/09 22:20:09</td> <td>3921</td> <td> </td><td> </td><td> </td><td> </td><td> </td><td title="org.rhq.core.pc.plugin.PluginManagerTest.pluginsShouldBeLoadedInCorrectOrder()">pluginsShouldBeLoadedInCorrectOrder</td> + <td>main@297529802</td> <td></td> </tr> +<tr bgcolor="df886b"> <td>09/11/09 22:20:11</td> <td>6022</td> <td> </td><td> </td><td> </td><td> </td><td> </td><td title="org.rhq.core.pc.plugin.PluginManagerTest.pluginsShouldBeShutdownInCorrectOrder()">pluginsShouldBeShutdownInCorrectOrder</td> + <td>main@297529802</td> <td></td> </tr> +<tr bgcolor="df886b"> <td>09/11/09 22:20:13</td> <td>8149</td> <td> </td><td> </td><td> </td><td> </td><td> </td><td title="org.rhq.core.pc.plugin.PluginManagerTest.initializeShouldLoadDiscoveredPlugins()">initializeShouldLoadDiscoveredPlugins</td> + <td>main@297529802</td> <td></td> </tr> +</table> diff --git a/modules/core/plugin-container/test-output/Custom suite/reporter-output.html b/modules/core/plugin-container/test-output/Custom suite/reporter-output.html new file mode 100644 index 0000000..063bc2e --- /dev/null +++ b/modules/core/plugin-container/test-output/Custom suite/reporter-output.html @@ -0,0 +1 @@ +<h2>Reporter output</h2><table></table> \ No newline at end of file diff --git a/modules/core/plugin-container/test-output/Custom suite/rhq.html b/modules/core/plugin-container/test-output/Custom suite/rhq.html new file mode 100644 index 0000000..be43416 --- /dev/null +++ b/modules/core/plugin-container/test-output/Custom suite/rhq.html @@ -0,0 +1,98 @@ +<html> +<head> +<title>TestNG: rhq</title> +<link href="../testng.css" rel="stylesheet" type="text/css" /> +<link href="../my-testng.css" rel="stylesheet" type="text/css" /> + +<style type="text/css"> +.log { display: none;} +.stack-trace { display: none;} +</style> +<script type="text/javascript"> +<!-- +function flip(e) { + current = e.style.display; + if (current == 'block') { + e.style.display = 'none'; + return 0; + } + else { + e.style.display = 'block'; + return 1; + } +} + +function toggleBox(szDivId, elem, msg1, msg2) +{ + var res = -1; if (document.getElementById) { + res = flip(document.getElementById(szDivId)); + } + else if (document.all) { + // this is the way old msie versions work + res = flip(document.all[szDivId]); + } + if(elem) { + if(res == 0) elem.innerHTML = msg1; else elem.innerHTML = msg2; + } + +} + +function toggleAllBoxes() { + if (document.getElementsByTagName) { + d = document.getElementsByTagName('div'); + for (i = 0; i < d.length; i++) { + if (d[i].className == 'log') { + flip(d[i]); + } + } + } +} + +// --> +</script> + +</head> +<body> +<h2 align='center'>rhq</h2><table border='1' align="center"> +<tr> +<td>Tests passed/Failed/Skipped:</td><td>4/0/0</td> +</tr><tr> +<td>Started on:</td><td>Mon Nov 09 22:20:05 EST 2009</td> +</tr> +<tr><td>Total time:</td><td>9 seconds (9399 ms)</td> +</tr><tr> +<td>Included groups:</td><td></td> +</tr><tr> +<td>Excluded groups:</td><td></td> +</tr> +</table><p/> +<small><i>(Hover the method name to see the test class name)</i></small><p/> +<table width='100%' border='1' class='invocation-passed'> +<tr><td colspan='3' align='center'><b>PASSED TESTS</b></td></tr> +<tr><td><b>Test method</b></td> +<td width="10%"><b>Time (seconds)</b></td> +<td width="30%"><b>Exception</b></td> +</tr> +<tr> +<td title='org.rhq.core.pc.plugin.PluginManagerTest.initializeShouldLoadDiscoveredPlugins()'>initializeShouldLoadDiscoveredPlugins</td> +<td>1</td> +<td></td> +</tr> +<tr> +<td title='org.rhq.core.pc.plugin.PluginManagerTest.pluginManagerShouldReturnAmpsVersionOfLoadedPluginWhenInEmbeddedMode()'>pluginManagerShouldReturnAmpsVersionOfLoadedPluginWhenInEmbeddedMode</td> +<td>1</td> +<td></td> +</tr> +<tr> +<td title='org.rhq.core.pc.plugin.PluginManagerTest.pluginsShouldBeLoadedInCorrectOrder()'>pluginsShouldBeLoadedInCorrectOrder</td> +<td>2</td> +<td></td> +</tr> +<tr> +<td title='org.rhq.core.pc.plugin.PluginManagerTest.pluginsShouldBeShutdownInCorrectOrder()'>pluginsShouldBeShutdownInCorrectOrder</td> +<td>2</td> +<td></td> +</tr> +</table><p> +</body> +</html> \ No newline at end of file diff --git a/modules/core/plugin-container/test-output/Custom suite/rhq.properties b/modules/core/plugin-container/test-output/Custom suite/rhq.properties new file mode 100644 index 0000000..e4769b7 --- /dev/null +++ b/modules/core/plugin-container/test-output/Custom suite/rhq.properties @@ -0,0 +1 @@ +[SuiteResult rhq] \ No newline at end of file diff --git a/modules/core/plugin-container/test-output/Custom suite/rhq.xml b/modules/core/plugin-container/test-output/Custom suite/rhq.xml new file mode 100644 index 0000000..f1278a6 --- /dev/null +++ b/modules/core/plugin-container/test-output/Custom suite/rhq.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="UTF-8"?> +<testsuite name="rhq" failures="0" tests="4" time="9.399" errors="0"> + <properties/> + <testcase name="pluginManagerShouldReturnAmpsVersionOfLoadedPluginWhenInEmbeddedMode" time="1.008" classname="org.rhq.core.pc.plugin.PluginManagerTest"/> + <testcase name="pluginsShouldBeLoadedInCorrectOrder" time="2.098" classname="org.rhq.core.pc.plugin.PluginManagerTest"/> + <testcase name="pluginsShouldBeShutdownInCorrectOrder" time="2.124" classname="org.rhq.core.pc.plugin.PluginManagerTest"/> + <testcase name="initializeShouldLoadDiscoveredPlugins" time="1.241" classname="org.rhq.core.pc.plugin.PluginManagerTest"/> +</testsuite> diff --git a/modules/core/plugin-container/test-output/Custom suite/testng-failed.xml b/modules/core/plugin-container/test-output/Custom suite/testng-failed.xml new file mode 100644 index 0000000..eaad574 --- /dev/null +++ b/modules/core/plugin-container/test-output/Custom suite/testng-failed.xml @@ -0,0 +1,13 @@ +<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd"> +<suite thread-count="5" skipfailedinvocationCounts="false" verbose="1" name="Failed suite [Custom suite]" junit="false" parallel="none" annotations="JDK"> + <test name="rhq(failed)" junit="false" parallel="none" annotations="JDK"> + <classes> + <class name="org.rhq.core.pc.plugin.PluginManagerTest"> + <methods> + <include name="initClass"/> + <include name="pluginManagerShouldReturnAmpsVersionOfLoadedPluginWhenInEnterpriseMode"/> + </methods> + </class> + </classes> + </test> +</suite> diff --git a/modules/core/plugin-container/test-output/Custom suite/testng.xml.html b/modules/core/plugin-container/test-output/Custom suite/testng.xml.html new file mode 100644 index 0000000..a34581d --- /dev/null +++ b/modules/core/plugin-container/test-output/Custom suite/testng.xml.html @@ -0,0 +1 @@ +<html><head><title>testng.xml for Custom suite</title></head><body><tt><!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd%22%3E;<br/><suite thread-count="5" skipfailedinvocationCounts="false" verbose="1" name="Custom suite" junit="false" parallel="none" annotations="JDK"><br/> <test verbose="1" name="rhq" junit="false" annotations="JDK"><br/> <classes><br/> <class name="org.rhq.core.pc.plugin.PluginManagerTest"/><br/> </classes><br/> </test><br/></suite><br/></tt></body></html> \ No newline at end of file diff --git a/modules/core/plugin-container/test-output/Custom suite/toc.html b/modules/core/plugin-container/test-output/Custom suite/toc.html new file mode 100644 index 0000000..f6418b2 --- /dev/null +++ b/modules/core/plugin-container/test-output/Custom suite/toc.html @@ -0,0 +1,30 @@ +<html> +<head> +<title>Results for Custom suite</title> +<link href="../testng.css" rel="stylesheet" type="text/css" /> +<link href="../my-testng.css" rel="stylesheet" type="text/css" /> +</head> +<body> +<h3><p align="center">Results for<br/><em>Custom suite</em></p></h3> +<table border='1' width='100%'> +<tr valign='top'> +<td>1 test</td> +<td><a target='mainFrame' href='classes.html'>1 class</a></td> +<td>4 methods:<br/> + <a target='mainFrame' href='methods.html'>chronological</a><br/> + <a target='mainFrame' href='methods-alphabetical.html'>alphabetical</a><br/> + <a target='mainFrame' href='methods-not-run.html'>not run (0)</a></td> +</tr> +<tr> +<td><a target='mainFrame' href='groups.html'>0 group</a></td> +<td><a target='mainFrame' href='reporter-output.html'>reporter output</a></td> +<td><a target='mainFrame' href='testng.xml.html'>testng.xml</a></td> +</tr></table> +<table width='100%' class='test-passed'> +<tr><td> +<table style='width: 100%'><tr><td valign='top'>rhq (4/0/0)</td><td valign='top' align='right'> + <a href='rhq.html' target='mainFrame'>Results</a> +</td></tr></table> +</td></tr><p/> +</table> +</body></html> \ No newline at end of file diff --git a/modules/core/plugin-container/test-output/emailable-report.html b/modules/core/plugin-container/test-output/emailable-report.html new file mode 100644 index 0000000..ab5162f --- /dev/null +++ b/modules/core/plugin-container/test-output/emailable-report.html @@ -0,0 +1,49 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<title>TestNG: Unit Test</title> +<style type="text/css"> +table caption,table.info_table,table.param,table.passed,table.failed {margin-bottom:10px;border:1px solid #000099;border-collapse:collapse;empty-cells:show;} +table.info_table td,table.info_table th,table.param td,table.param th,table.passed td,table.passed th,table.failed td,table.failed th { +border:1px solid #000099;padding:.25em .5em .25em .5em +} +table.param th {vertical-align:bottom} +td.numi,th.numi,td.numi_attn { +text-align:right +} +tr.total td {font-weight:bold} +table caption { +text-align:center;font-weight:bold; +} +table.passed tr.stripe td,table tr.passedodd td {background-color: #00AA00;} +table.passed td,table tr.passedeven td {background-color: #33FF33;} +table.passed tr.stripe td,table tr.skippedodd td {background-color: #cccccc;} +table.passed td,table tr.skippedodd td {background-color: #dddddd;} +table.failed tr.stripe td,table tr.failedodd td,table.param td.numi_attn {background-color: #FF3333;} +table.failed td,table tr.failedeven td,table.param tr.stripe td.numi_attn {background-color: #DD0000;} +tr.stripe td,tr.stripe th {background-color: #E6EBF9;} +p.totop {font-size:85%;text-align:center;border-bottom:2px black solid} +div.shootout {padding:2em;border:3px #4854A8 solid} +</style> +</head> +<body> +<table cellspacing=0 cellpadding=0 class="param"> +<tr><th>Test</th><th class="numi">Methods<br/>Passed</th><th class="numi">Scenarios<br/>Passed</th><th class="numi"># skipped</th><th class="numi"># failed</th><th class="numi">Total<br/>Time</th><th class="numi">Included<br/>Groups</th><th class="numi">Excluded<br/>Groups</th></tr> +<tr><td style="text-align:left;padding-right:2em">rhq</td><td class="numi">4</td><td class="numi">4</td><td class="numi">0</td><td class="numi">0</td><td class="numi">9.4 seconds</td><td class="numi"></td><td class="numi"></td></tr> +</table> +<a id="summary"></a> +<table cellspacing=0 cellpadding=0 class="passed"> +<tr><th>Class</th><th>Method</th><th># of<br/>Scenarios</th><th>Time<br/>(Msecs)</th></tr> +<tr><th colspan="4">rhq — passed</th></tr> +<tr class="passedodd"><td rowspan="4">org.rhq.core.pc.plugin.PluginManagerTest<td><a href="#m1"><b>initializeShouldLoadDiscoveredPlugins</b> </a></td><td class="numi">1</td><td class="numi">1241</td></tr><tr class="passedodd"><td><a href="#m2"><b>pluginManagerShouldReturnAmpsVersionOfLoadedPluginWhenInEmbeddedMode</b> </a></td><td class="numi">1</td><td class="numi">1008</td></tr><tr class="passedodd"><td><a href="#m3"><b>pluginsShouldBeLoadedInCorrectOrder</b> </a></td><td class="numi">1</td><td class="numi">2098</td></tr><tr class="passedodd"><td><a href="#m4"><b>pluginsShouldBeShutdownInCorrectOrder</b> </a></td><td class="numi">1</td><td class="numi">2124</td></tr> +</table> +<h1>rhq</h1> +<a id="m1"></a><h2>org.rhq.core.pc.plugin.PluginManagerTest:initializeShouldLoadDiscoveredPlugins</h2> +<p class="totop"><a href="#summary">back to summary</a></p> +<a id="m2"></a><h2>org.rhq.core.pc.plugin.PluginManagerTest:pluginManagerShouldReturnAmpsVersionOfLoadedPluginWhenInEmbeddedMode</h2> +<p class="totop"><a href="#summary">back to summary</a></p> +<a id="m3"></a><h2>org.rhq.core.pc.plugin.PluginManagerTest:pluginsShouldBeLoadedInCorrectOrder</h2> +<p class="totop"><a href="#summary">back to summary</a></p> +<a id="m4"></a><h2>org.rhq.core.pc.plugin.PluginManagerTest:pluginsShouldBeShutdownInCorrectOrder</h2> +<p class="totop"><a href="#summary">back to summary</a></p> +</body></html> diff --git a/modules/core/plugin-container/test-output/index.html b/modules/core/plugin-container/test-output/index.html new file mode 100644 index 0000000..2b714ba --- /dev/null +++ b/modules/core/plugin-container/test-output/index.html @@ -0,0 +1,9 @@ +<html> +<head><title>Test results</title><link href="./testng.css" rel="stylesheet" type="text/css" /> +<link href="./my-testng.css" rel="stylesheet" type="text/css" /> +</head><body> +<h2><p align='center'>Test results</p></h2> +<table border='1' width='100%' class='main-page'><tr><th>Suite</th><th>Passed</th><th>Failed</th><th>Skipped</th><th>testng.xml</th></tr> +<tr align='center' class='invocation-passed'><td><em>Total</em></td><td><em>4</em></td><td><em>0</em></td><td><em>0</em></td><td> </td></tr> +<tr align='center' class='invocation-passed'><td><a href='Custom suite/index.html'>Custom suite</a></td> +<td>4</td><td>0</td><td>0</td><td><a href='Custom suite/testng.xml.html'>Link</a></td></tr></table></body></html> diff --git a/modules/core/plugin-container/test-output/testng-failed.xml b/modules/core/plugin-container/test-output/testng-failed.xml new file mode 100644 index 0000000..eaad574 --- /dev/null +++ b/modules/core/plugin-container/test-output/testng-failed.xml @@ -0,0 +1,13 @@ +<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd"> +<suite thread-count="5" skipfailedinvocationCounts="false" verbose="1" name="Failed suite [Custom suite]" junit="false" parallel="none" annotations="JDK"> + <test name="rhq(failed)" junit="false" parallel="none" annotations="JDK"> + <classes> + <class name="org.rhq.core.pc.plugin.PluginManagerTest"> + <methods> + <include name="initClass"/> + <include name="pluginManagerShouldReturnAmpsVersionOfLoadedPluginWhenInEnterpriseMode"/> + </methods> + </class> + </classes> + </test> +</suite> diff --git a/modules/core/plugin-container/test-output/testng-results.xml b/modules/core/plugin-container/test-output/testng-results.xml new file mode 100644 index 0000000..5331e20 --- /dev/null +++ b/modules/core/plugin-container/test-output/testng-results.xml @@ -0,0 +1,22 @@ +<testng-results> + <reporter-output> + </reporter-output> + <suite name="Custom suite"> + <groups> + </groups> + <test name="rhq"> + <class name="org.rhq.core.pc.plugin.PluginManagerTest"> + <test-method status="PASS" signature="pluginsShouldBeLoadedInCorrectOrder()" name="pluginsShouldBeLoadedInCorrectOrder" duration-ms="2098" started-at="2009-11-09T22:20:09Z" finished-at="2009-11-09T22:20:11Z"> + </test-method> + <test-method status="PASS" signature="initClass()" name="initClass" is-config="true" duration-ms="2907" started-at="2009-11-09T22:20:05Z" finished-at="2009-11-09T22:20:08Z"> + </test-method> + <test-method status="PASS" signature="initializeShouldLoadDiscoveredPlugins()" name="initializeShouldLoadDiscoveredPlugins" duration-ms="1241" started-at="2009-11-09T22:20:13Z" finished-at="2009-11-09T22:20:14Z"> + </test-method> + <test-method status="PASS" signature="pluginManagerShouldReturnAmpsVersionOfLoadedPluginWhenInEmbeddedMode()" name="pluginManagerShouldReturnAmpsVersionOfLoadedPluginWhenInEmbeddedMode" duration-ms="1008" started-at="2009-11-09T22:20:08Z" finished-at="2009-11-09T22:20:09Z"> + </test-method> + <test-method status="PASS" signature="pluginsShouldBeShutdownInCorrectOrder()" name="pluginsShouldBeShutdownInCorrectOrder" duration-ms="2124" started-at="2009-11-09T22:20:11Z" finished-at="2009-11-09T22:20:13Z"> + </test-method> + </class> + </test> + </suite> +</testng-results> diff --git a/modules/core/plugin-container/test-output/testng.css b/modules/core/plugin-container/test-output/testng.css new file mode 100644 index 0000000..3904800 --- /dev/null +++ b/modules/core/plugin-container/test-output/testng.css @@ -0,0 +1,9 @@ +.invocation-failed, .test-failed { background-color: #DD0000; } +.invocation-percent, .test-percent { background-color: #006600; } +.invocation-passed, .test-passed { background-color: #00AA00; } +.invocation-skipped, .test-skipped { background-color: #CCCC00; } + +.main-page { + font-size: x-large; +} +
commit e5febe443f88f1a87589ba385a9d4f4fbc4508f1 Merge: 827a5b4... 551e860... Author: John Sanda john@localhost.localdomain Date: Mon Nov 9 21:53:51 2009 -0500
Merge branch 'raw-config' of ssh://git.fedorahosted.org/git/rhq/rhq into raw-config
commit 827a5b42ec2a936c902503ec43d9fdac0b02dfa2 Author: John Sanda john@localhost.localdomain Date: Mon Nov 9 21:50:43 2009 -0500
[US 2] Updating ConfigurationManagerBean to call new ConfigurationAgentService api
Updating ConfigurationManager initialization code so that dependencies are properly initialized.
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/PluginContainer.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/PluginContainer.java index 25d61c2..9962cd9 100644 --- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/PluginContainer.java +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/PluginContainer.java @@ -355,10 +355,11 @@ public class PluginContainer implements ContainerService { for (AgentServiceLifecycleListener agentServiceListener : agentServiceListeners) { agentService.addLifecycleListener(agentServiceListener); } - } - else if (containerService instanceof ConfigurationManager) { - ConfigurationManagerInitializer initializer = new ConfigurationManagerInitializer(); - initializer.initialize((ConfigurationManager)containerService); + + if (containerService instanceof ConfigurationManager) { + ConfigurationManagerInitializer initializer = new ConfigurationManagerInitializer(); + initializer.initialize((ConfigurationManager)containerService); + } }
containerService.initialize(); diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManagerInitializer.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManagerInitializer.java index 6cad31e..9208d46 100644 --- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManagerInitializer.java +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManagerInitializer.java @@ -24,12 +24,18 @@ package org.rhq.core.pc.configuration;
import org.rhq.core.pc.util.ComponentServiceImpl; +import org.rhq.core.pc.util.ComponentService;
public class ConfigurationManagerInitializer {
public void initialize(ConfigurationManager manager) { - manager.setComponentService(new ComponentServiceImpl()); - manager.setLoadConfigFactory(new LoadResourceConfigurationFactoryImpl()); + ComponentService componentService = new ComponentServiceImpl(); + + LoadResourceConfigurationFactoryImpl factory = new LoadResourceConfigurationFactoryImpl(); + factory.setComponentService(componentService); + + manager.setComponentService(componentService); + manager.setLoadConfigFactory(factory); }
} diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/plugin/PluginManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/plugin/PluginManager.java index d2d44c6..af79d23 100644 --- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/plugin/PluginManager.java +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/plugin/PluginManager.java @@ -173,23 +173,31 @@ public class PluginManager implements ContainerService { }
private void initUpdateLoadedPluginsCallback() { - if (configuration.isInsideAgent()) { - updateLoadedPlugins = new UpdateLoadedPlugins() { - public void execute(PluginDescriptor pluginDescriptor, URL pluginURL) { - loadPluginIfFoundInListFromServer(pluginDescriptor); - } - }; - } - else { - updateLoadedPlugins = new UpdateLoadedPlugins() { - PluginTransformer transformer = new PluginTransformer(); - - public void execute(PluginDescriptor pluginDescriptor, URL pluginURL) { - Plugin plugin = transformer.toPlugin(pluginDescriptor, pluginURL); - loadedPlugins.add(plugin); - } - }; - } +// if (configuration.isInsideAgent()) { +// updateLoadedPlugins = new UpdateLoadedPlugins() { +// public void execute(PluginDescriptor pluginDescriptor, URL pluginURL) { +// loadPluginIfFoundInListFromServer(pluginDescriptor); +// } +// }; +// } +// else { +// updateLoadedPlugins = new UpdateLoadedPlugins() { +// PluginTransformer transformer = new PluginTransformer(); +// +// public void execute(PluginDescriptor pluginDescriptor, URL pluginURL) { +// Plugin plugin = transformer.toPlugin(pluginDescriptor, pluginURL); +// loadedPlugins.add(plugin); +// } +// }; +// } + updateLoadedPlugins = new UpdateLoadedPlugins() { + PluginTransformer transformer = new PluginTransformer(); + + public void execute(PluginDescriptor pluginDescriptor, URL pluginURL) { + Plugin plugin = transformer.toPlugin(pluginDescriptor, pluginURL); + loadedPlugins.add(plugin); + } + }; }
private void loadPluginIfFoundInListFromServer(PluginDescriptor pluginDescriptor) { diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java index a175cf4..1916ad8 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java @@ -292,8 +292,8 @@ public class ConfigurationManagerBean implements ConfigurationManagerLocal, Conf return result; }
- @Nullable - public ResourceConfigurationUpdate getLatestResourceConfigurationUpdate(Subject subject, int resourceId) { + public ResourceConfigurationUpdate getLatestResourceConfigurationUpdate(Subject subject, int resourceId, + boolean fromStructured) { log.debug("Getting current resource configuration for resource [" + resourceId + "]");
Resource resource; @@ -340,7 +340,7 @@ public class ConfigurationManagerBean implements ConfigurationManagerLocal, Conf
// ask the agent to get us the live, most up-to-date configuration for the resource, // then compare it to make sure what we think is the latest configuration is really the latest - Configuration liveConfig = getLiveResourceConfiguration(resource, true); + Configuration liveConfig = getLiveResourceConfiguration(resource, true, fromStructured);
if (liveConfig != null) { Configuration currentConfig = (current != null) ? current.getConfiguration() : null; @@ -371,6 +371,11 @@ public class ConfigurationManagerBean implements ConfigurationManagerLocal, Conf return current; }
+ @Nullable + public ResourceConfigurationUpdate getLatestResourceConfigurationUpdate(Subject subject, int resourceId) { + return getLatestResourceConfigurationUpdate(subject, resourceId, true); + } + private ResourceConfigurationUpdate persistNewAgentReportedResourceConfiguration(Resource resource, Configuration liveConfig) throws ConfigurationUpdateStillInProgressException { /* @@ -690,6 +695,11 @@ public class ConfigurationManagerBean implements ConfigurationManagerLocal, Conf
public Configuration getLiveResourceConfiguration(Subject subject, int resourceId, boolean pingAgentFirst) throws Exception { + return getLiveResourceConfiguration(subject, resourceId, pingAgentFirst, true); + } + + public Configuration getLiveResourceConfiguration(Subject subject, int resourceId, boolean pingAgentFirst, + boolean fromStructured) throws Exception { Resource resource = entityManager.find(Resource.class, resourceId);
if (resource == null) { @@ -702,7 +712,7 @@ public class ConfigurationManagerBean implements ConfigurationManagerLocal, Conf }
// ask the agent to get us the live, most up-to-date configuration for the resource - Configuration liveConfig = getLiveResourceConfiguration(resource, pingAgentFirst); + Configuration liveConfig = getLiveResourceConfiguration(resource, pingAgentFirst, fromStructured);
return liveConfig; } @@ -1307,7 +1317,8 @@ public class ConfigurationManagerBean implements ConfigurationManagerLocal, Conf * * @return the resource's live configuration or <code>null</code> if it could not be retrieved from the agent */ - private Configuration getLiveResourceConfiguration(Resource resource, boolean pingAgentFirst) { + private Configuration getLiveResourceConfiguration(Resource resource, boolean pingAgentFirst, + boolean fromStructured) { Configuration liveConfig = null;
try { @@ -1322,7 +1333,8 @@ public class ConfigurationManagerBean implements ConfigurationManagerLocal, Conf agentPingedSuccessfully = agentClient.ping(5000L);
if (!pingAgentFirst || agentPingedSuccessfully) { - liveConfig = agentClient.getConfigurationAgentService().loadResourceConfiguration(resource.getId(), true); + liveConfig = agentClient.getConfigurationAgentService().loadResourceConfiguration(resource.getId(), + fromStructured); if (liveConfig == null) { // This should really never occur - the PC should never return a null, always at least an empty config. log.debug("ConfigurationAgentService.loadResourceConfiguration() returned a null Configuration."); @@ -1340,6 +1352,8 @@ public class ConfigurationManagerBean implements ConfigurationManagerLocal, Conf return liveConfig; }
+ + @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) public AbstractResourceConfigurationUpdate mergeConfigurationUpdate( AbstractResourceConfigurationUpdate configurationUpdate) { diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerLocal.java index f96a454..0021a74 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerLocal.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerLocal.java @@ -96,6 +96,9 @@ public interface ConfigurationManagerLocal { */ Configuration getLiveResourceConfiguration(Subject subject, int resourceId, boolean pingAgentFirst) throws Exception; + + Configuration getLiveResourceConfiguration(Subject subject, int resourceId, boolean pingAgentFirst, + boolean fromStructured) throws Exception;
PageList<PluginConfigurationUpdate> findPluginConfigurationUpdates(Subject subject, int resourceId, Long beginDate, Long endDate, PageControl pc); @@ -425,6 +428,9 @@ public interface ConfigurationManagerLocal { @Nullable ResourceConfigurationUpdate getLatestResourceConfigurationUpdate(Subject subject, int resourceId);
+ ResourceConfigurationUpdate getLatestResourceConfigurationUpdate(Subject subject, int resourceId, + boolean fromStructured); + boolean isResourceConfigurationUpdateInProgress(Subject subject, int resourceId);
boolean isGroupResourceConfigurationUpdateInProgress(Subject subject, int groupId);
commit 8fe821b9a10ac908c55558b34980e9e7983bdff4 Author: John Sanda john@localhost.localdomain Date: Mon Nov 9 21:30:02 2009 -0500
Updating PluginTransformer to set a default ampsVersion when the descriptor does not declare one.
diff --git a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/descriptor/PluginTransformer.java b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/descriptor/PluginTransformer.java index d1cb6ca..613500f 100644 --- a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/descriptor/PluginTransformer.java +++ b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/descriptor/PluginTransformer.java @@ -63,7 +63,7 @@ public class PluginTransformer { plugin.setDisplayName(pluginDescriptor.getDisplayName()); }
- plugin.setAmpsVersion(pluginDescriptor.getAmpsVersion()); + plugin.setAmpsVersion(getAmpsVersion(pluginDescriptor)); plugin.setDescription(pluginDescriptor.getDescription()); plugin.setPath(pluginURL.getPath()); plugin.setMtime(pluginURL.openConnection().getLastModified()); @@ -78,6 +78,13 @@ public class PluginTransformer { } }
+ private String getAmpsVersion(PluginDescriptor pluginDescriptor) { + if (pluginDescriptor.getAmpsVersion() == null) { + return "2.0"; + } + return pluginDescriptor.getAmpsVersion(); + } + private String getHelp(PluginDescriptor pluginDescriptor) { Help help = pluginDescriptor.getHelp(); if (help == null || help.getContent().isEmpty()) { diff --git a/modules/core/client-api/src/test/java/org/rhq/core/clientapi/descriptor/PluginTransformerTest.java b/modules/core/client-api/src/test/java/org/rhq/core/clientapi/descriptor/PluginTransformerTest.java index b1954a0..2e3374f 100644 --- a/modules/core/client-api/src/test/java/org/rhq/core/clientapi/descriptor/PluginTransformerTest.java +++ b/modules/core/client-api/src/test/java/org/rhq/core/clientapi/descriptor/PluginTransformerTest.java @@ -110,6 +110,21 @@ public class PluginTransformerTest { }
@Test + public void pluginAmpsVersionShouldBeSetToDefaultWhenDescriptorAmpsVersionIsNull() throws Exception { + PluginDescriptor pluginDescriptor = new PluginDescriptor(); + + PluginTransformer transformer = new PluginTransformer(); + + Plugin plugin = transformer.toPlugin(pluginDescriptor, getTestPluginURL()); + + assertEquals( + plugin.getAmpsVersion(), + "2.0", + "The Plugin.ampsVersion property should default to 2.0 when it is not defined in the plugin descriptor" + ); + } + + @Test public void pluginDescriptionShouldBeSetToDescriptorDescription() throws Exception { PluginDescriptor pluginDescriptor = new PluginDescriptor(); pluginDescriptor.setDescription("description");
commit 551e8601df3bd5605f0f47f9593e9783fd2c39a0 Author: Adam Young ayoung@redhat.com Date: Mon Nov 9 17:05:23 2009 -0500
Replaced the download page with a seam component
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/RawConfigCollection.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/RawConfigCollection.java index d55e937..74b2273 100644 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/RawConfigCollection.java +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/RawConfigCollection.java @@ -29,7 +29,7 @@ import org.rhq.enterprise.gui.util.EnterpriseFacesContextUtility; import org.rhq.enterprise.server.configuration.ConfigurationManagerLocal; import org.rhq.enterprise.server.util.LookupUtil;
-@Name("RawConfigCollection") +@Name("rawConfigCollection") @Scope(ScopeType.PAGE) /** * The backing class for all Web based activities for manipulating the set of @@ -260,10 +260,21 @@ public class RawConfigCollection implements Serializable { "/etc/mock/turtle/soup", "/etc/mock/mysmock/iclean/yourclock" };
String[] filesContents = { - "Omni Patria Gaulia es divis in tres partes", + "GALLIA est omnis divisa in partes tres, quarum unam incolunt Belgae, \naliam Aquitani, tertiam qui ipsorum lingua Celtae, \n" + + "nostra Galli appellantur. \nHi omnes lingua, institutis, legibus inter se differunt. \n", "I've seen all good people \n turn their heads each day \n So Satisfied\n I'm on my way", "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor \nincididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis\n nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\n Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu\n fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in \nculpa qui officia deserunt mollit anim id est laborum.", - "/etc/mock/me/will/you", + "It was on a dreary night of November that I beheld the accomplishment of my toils. With an anxiety that " + + "almost amounted to agony, I collected the instruments of life around me, that I might infuse a spark of being " + + "into the lifeless thing that lay at my feet. It was already one in the morning; the rain pattered dismally " + + "against the panes, and my candle was nearly burnt out, when, by the glimmer of the half-extinguished light, " + + "I saw the dull yellow eye of the creature open; it breathed hard, and a convulsive motion agitated its limbs.\n\n" + + "How can I describe my emotions at this catastrophe, or how delineate the wretch whom with such infinite pains and " + + "care I had endeavoured to form? His limbs were in proportion, and I had selected his features as beautiful. " + + "Beautiful! Great God! His yellow skin scarcely covered the work of muscles and arteries beneath; his hair was " + + "of a lustrous black, and flowing; his teeth of a pearly whiteness; but these luxuriances only formed a more " + + "horrid contrast with his watery eyes, that seemed almost of the same colour as the dun-white sockets in which " + + "they were set, his shrivelled complexion and straight black lips. ", ""The time has come," the Walrus said,\n" + "To talk of many things:\n" + "Of shoes--and ships--and sealing-wax--\n" + "Of cabbages--and kings--\n" + "And why the sea is boiling hot--\n" + "And whether pigs have wings.", diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/RawConfigDownload.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/RawConfigDownload.java new file mode 100644 index 0000000..7c4859d --- /dev/null +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/RawConfigDownload.java @@ -0,0 +1,53 @@ +package org.rhq.enterprise.gui.configuration.resource; + +import javax.faces.context.ExternalContext; +import javax.faces.context.FacesContext; +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServletResponse; + +import org.jboss.seam.ScopeType; +import org.jboss.seam.annotations.Create; +import org.jboss.seam.annotations.In; +import org.jboss.seam.annotations.Logger; +import org.jboss.seam.annotations.Name; +import org.jboss.seam.annotations.Scope; +import org.jboss.seam.log.Log; + +@Name("rawConfigDownload") +@Scope(ScopeType.PAGE) +public class RawConfigDownload { + + @Logger + private Log log; + + @In(value = "#{rawConfigCollection}") + RawConfigCollection rawConfigCollection; + + @In(value = "#{facesContext}") + FacesContext facesContext; + + @In(value = "#{facesContext.externalContext}") + private ExternalContext extCtx; + + @Create + public void init() { + log.error("starting"); + } + + public String download() { + HttpServletResponse response = (HttpServletResponse) extCtx.getResponse(); + response.setContentType("text/plain"); + response.addHeader("Content-disposition", "attachment; filename="testing.txt""); + try { + ServletOutputStream os = response.getOutputStream(); + os.write(rawConfigCollection.getCurrent().getContents()); + os.flush(); + os.close(); + facesContext.responseComplete(); + } catch (Exception e) { + log.error("\nFailure : " + e.toString() + "\n"); + } + + return null; + } +} \ No newline at end of file diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-navigation/configuration-navigation.xml b/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-navigation/configuration-navigation.xml index 81d1293..d1c2f14 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-navigation/configuration-navigation.xml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/jsf-navigation/configuration-navigation.xml @@ -39,7 +39,7 @@
<from-view-id>/rhq/resource/configuration/edit-raw.xhtml</from-view-id> <navigation-case> - <from-action> #{RawConfigCollection.choseRaw}</from-action> + <from-action> #{rawConfigCollection.choseRaw}</from-action> <from-outcome>success</from-outcome> <to-view-id>/rhq/resource/configuration/edit-raw.xhtml?id=#{param.id}</to-view-id> </navigation-case> diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit-raw-full.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit-raw-full.xhtml index 85c0d88..f355395 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit-raw-full.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit-raw-full.xhtml @@ -17,14 +17,13 @@
<h:form id="editResourceConfigurationForm" > <input type="hidden" name="id" value="#{ResourceUIBean.id}" /> -<h:commandLink action="#{RawConfigCollection.update}" > +<h:commandLink action="#{rawConfigCollection.update}" > <img src="/images/save.png" alt="Save" title="Save"/> <f:param name="conversationId" value="#{conversation.id}"/> <f:param name="id" value="#{ResourceUIBean.id}"/> </h:commandLink> -<h:commandButton action="#{RawConfigCollection.update}"/> <div> -<h:inputTextarea cols="800" rows="600" value="#{RawConfigCollection.currentContents}" /> +<h:inputTextarea cols="800" rows="600" value="#{rawConfigCollection.currentContents}" /> </div> </h:form> </ui:define> diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit-raw.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit-raw.xhtml index 51fd9de..bc8ab9c 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit-raw.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit-raw.xhtml @@ -33,7 +33,6 @@ } </script> - You are viewing this in files mode. Switch to <h:outputLink value="edit.xhtml"> <s:conversationId /> @@ -41,7 +40,6 @@ <h:outputText value=" structured mode" /> </h:outputLink>
- <table class="summary-props-table" style=""> <a4j:form id="editResourceConfigurationForm"> <input type="hidden" name="id" @@ -49,27 +47,27 @@ <tr> <td bgcolor="lightblue" width="25%" valign="top">Files <h:panelGroup id="changedFiles" layout="vertical"> - <ui:repeat value="#{RawConfigCollection.paths}" var="path"> + <ui:repeat value="#{rawConfigCollection.paths}" var="path"> <div><h:outputText value="*" - rendered="#{RawConfigCollection.isModified(path) }" /> <h:commandLink - value="#{path}" action="#{RawConfigCollection.select(path)}" - rendered="#{path != RawConfigCollection.current.path}"> + rendered="#{rawConfigCollection.isModified(path) }" /> <h:commandLink + value="#{path}" action="#{rawConfigCollection.select(path)}" + rendered="#{path != rawConfigCollection.current.path}"> <f:param name="currentPath" value="#{path}" /> </h:commandLink> <h:outputText value="#{path}" - rendered="#{path == RawConfigCollection.current.path}" /></div> + rendered="#{path == rawConfigCollection.current.path}" /></div> </ui:repeat> </h:panelGroup> <div>______________________________________</div> <div>* File contains uncommitted changes.</div> - <a4j:commandButton action="#{RawConfigCollection.commit}" + <a4j:commandButton action="#{rawConfigCollection.commit}" value="commit changes" reRender="changedFiles" /> <a4j:commandButton - action="#{RawConfigCollection.discard}" value="discard changes" + action="#{rawConfigCollection.discard}" value="discard changes" reRender="changedFiles" /></td> <td> <div>Current File: <h:outputText - value="#{RawConfigCollection.current.path}" styleClass="outhello" /> + value="#{rawConfigCollection.current.path}" styleClass="outhello" /> </div> - <h:outputLink value="edit-raw-full.xhtml" action="navigateToUpload"> + <h:outputLink value="edit-raw-full.xhtml" action="navigateToFullScreen"> <img src="/images/viewfullscreen.png" /> <h:outputText value=" Full Screen " /> <f:param name="id" value="#{ResourceUIBean.id}" /> @@ -79,19 +77,20 @@ <h:outputText value=" Upload " /> <f:param name="id" value="#{ResourceUIBean.id}" /> <f:param name="conversationId" value="#{conversation.id}" /> - </h:outputLink> <h:outputLink value="download.jsp" action="navigateToFullpage"> - <img src="/images/download.png" /> - <h:outputText value=" Download " /> + </h:outputLink> <s:link action="#{rawConfigDownload.download}"> + <img src="/images/download.png" /> + <h:outputText value=" Download " /> <f:param name="id" value="#{ResourceUIBean.id}" /> - <f:param name="conversationId" value="#{conversation.id}" /> - </h:outputLink> + </s:link> + <div><h:inputTextarea cols="80" rows="40" - value="#{RawConfigCollection.currentContents}" /></div> + value="#{rawConfigCollection.currentContents}" /></div> </td> </tr>
</a4j:form> - </table> + </table> + </ui:define>
</ui:composition> diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/upload.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/upload.xhtml index e2da7d2..04161c0 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/upload.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/upload.xhtml @@ -24,19 +24,19 @@ <h:form id="uploadform" enctype="multipart/form-data"> <rich:fileUpload id="upload" - fileUploadListener="#{RawConfigCollection.fileUploadListener}" + fileUploadListener="#{rawConfigCollection.fileUploadListener}" maxFilesQuantity="10" noDuplicate="true" immediateUpload="true" autoclear="false" allowFlash="false"> - <a4j:support event="onuploadcomplete" action="#{RawConfigCollection.upload}" /> + <a4j:support event="onuploadcomplete" action="#{rawConfigCollection.upload}" /> </rich:fileUpload> </h:form> </h:panelGrid> <h:outputLink value="edit-raw.xhtml" action="toEditRaw" > <h:outputText value=" Done" /> - <f:param name="id" value="#{RawConfigCollection.resourceId}" /> + <f:param name="id" value="#{rawConfigCollection.resourceId}" /> </h:outputLink> </rich:panel>
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view-raw-full.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view-raw-full.xhtml index 1a35795..4caa2ac 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view-raw-full.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view-raw-full.xhtml @@ -26,7 +26,7 @@ <h:form id="editResourceConfigurationForm" > <input type="hidden" name="id" value="#{ResourceUIBean.id}" /> <div> -<pre><h:outputText value="#{RawConfigCollection.currentContents}" /></pre> +<pre><h:outputText value="#{rawConfigCollection.currentContents}" /></pre> </div> </h:form> </ui:define> diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view-raw.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view-raw.xhtml index c04f02e..e3a630b 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view-raw.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view-raw.xhtml @@ -47,16 +47,16 @@ <h:panelGroup id="changedFiles" layout="vertical"> <h:form> <input type="hidden" name="id" value="#{ResourceUIBean.id}" /> - <ui:repeat value="#{RawConfigCollection.paths}" var="path"> + <ui:repeat value="#{rawConfigCollection.paths}" var="path"> <div> - <h:outputText value="*" rendered="#{RawConfigCollection.isModified(path) }" /> + <h:outputText value="*" rendered="#{rawConfigCollection.isModified(path) }" /> <h:commandLink - action="#{RawConfigCollection.select(path)}" + action="#{rawConfigCollection.select(path)}" value="#{path}" - rendered="#{path != RawConfigCollection.current.path}"> + rendered="#{path != rawConfigCollection.current.path}"> <f:param name="currentPath" value="#{path}" /> </h:commandLink> - <h:outputText value="#{path}" rendered="#{path == RawConfigCollection.current.path}" /> + <h:outputText value="#{path}" rendered="#{path == rawConfigCollection.current.path}" /> </div> </ui:repeat> </h:form> @@ -66,22 +66,20 @@ </td> <td> <div> - Current File: <h:outputText value="#{RawConfigCollection.current.path}" + Current File: <h:outputText value="#{rawConfigCollection.current.path}" styleClass="outhello" /> </div> <h:outputLink value="view-raw-full.xhtml" action="navigateToUpload" > <img src="/images/viewfullscreen.png" /> <h:outputText value=" Full Screen " /> <f:param name="id" value="#{ResourceUIBean.id}" /> - </h:outputLink> - - <h:outputLink value="download.jsp" action="navigateToFullpage" > - <img src="/images/download.png" /> - <h:outputText value=" Download " /> + </h:outputLink><s:link action="#{rawConfigDownload.download}"> + <img src="/images/download.png" /> + <h:outputText value=" Download " /> <f:param name="id" value="#{ResourceUIBean.id}" /> - </h:outputLink> + </s:link> <div> - <pre><h:outputText value="#{RawConfigCollection.currentContents}" /></pre> + <pre><h:outputText value="#{rawConfigCollection.currentContents}" /></pre> </div> </td> </tr> diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml index 1f73716..db3f8c3 100644 --- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml +++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml @@ -49,10 +49,10 @@ THIS TEXT WILL BE REMOVED.
<h:commandButton value="EDIT" action="#{ExistingResourceConfigurationViewUIBean.editConfiguration}" title="Edit this Configuration" styleClass="buttonmed" - rendered="${ResourceUIBean.permissions.configure and RawConfigCollection.structuredSupported}" /> + rendered="${ResourceUIBean.permissions.configure and rawConfigCollection.structuredSupported}" /> <h:commandButton value="EDIT FILES" action="#{ExistingResourceConfigurationViewUIBean.editRawConfiguration}" title="Advanced Mode Edit of Raw Configuration Files" styleClass="buttonmed" - rendered="${ResourceUIBean.permissions.configure and RawConfigCollection.rawSupported}" /> + rendered="${ResourceUIBean.permissions.configure and rawConfigCollection.rawSupported}" /> </h:panelGrid>
<onc:config configurationDefinition="#{ExistingResourceConfigurationViewUIBean.configurationDefinition}" @@ -69,6 +69,7 @@ THIS TEXT WILL BE REMOVED. <b>${msg['note']}</b> ${msg['resource.config.Current.updateInProgress']} </h:panelGroup>
+ </ui:define>
</ui:composition>
commit 113b8bf4266943c6a08d7bf1d5ccaf341dc78a82 Author: John Sanda john@localhost.localdomain Date: Mon Nov 9 14:25:23 2009 -0500
[US 2] Updating ConfigurationManagerBean to call new version of loadResource().
Updating test implementations of ConfigurationAgentService so that they include the new loadResoure() method.
diff --git a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/configuration/ConfigurationAgentService.java b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/configuration/ConfigurationAgentService.java index d73547a..8e67db8 100644 --- a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/configuration/ConfigurationAgentService.java +++ b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/configuration/ConfigurationAgentService.java @@ -78,4 +78,6 @@ public interface ConfigurationAgentService { * @throws PluginContainerException if a runtime or plugin error occurs a PluginContainerException is thrown */ Configuration loadResourceConfiguration(int resourceId) throws PluginContainerException; + + Configuration loadResourceConfiguration(int resourceId, boolean fromStructured) throws PluginContainerException; } \ No newline at end of file diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java index 6a7d327..a175cf4 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java @@ -1322,7 +1322,7 @@ public class ConfigurationManagerBean implements ConfigurationManagerLocal, Conf agentPingedSuccessfully = agentClient.ping(5000L);
if (!pingAgentFirst || agentPingedSuccessfully) { - liveConfig = agentClient.getConfigurationAgentService().loadResourceConfiguration(resource.getId()); + liveConfig = agentClient.getConfigurationAgentService().loadResourceConfiguration(resource.getId(), true); if (liveConfig == null) { // This should really never occur - the PC should never return a null, always at least an empty config. log.debug("ConfigurationAgentService.loadResourceConfiguration() returned a null Configuration."); diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBeanTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBeanTest.java index 5dcdb90..1d2aa26 100644 --- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBeanTest.java +++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBeanTest.java @@ -1093,6 +1093,11 @@ public class ConfigurationManagerBeanTest extends AbstractEJB3Test { return savedConfiguration; }
+ public Configuration loadResourceConfiguration(int resourceId, boolean fromStructured) + throws PluginContainerException { + return null; + } + public void disableServiceScans(int serverResourceId) { }
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/test/TestAgentClient.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/test/TestAgentClient.java index 2c891e0..fa3aa84 100644 --- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/test/TestAgentClient.java +++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/test/TestAgentClient.java @@ -143,6 +143,11 @@ public class TestAgentClient implements AgentClient, ContentAgentService, Resour return null; }
+ public Configuration loadResourceConfiguration(int resourceId, boolean fromStructured) + throws PluginContainerException { + return null; + } + public void updateResourceConfiguration(ConfigurationUpdateRequest request) { }
commit 2e078a50ad1890dd3d8f017f3c7277a5397e5aef Author: John Sanda john@localhost.localdomain Date: Mon Nov 9 14:07:14 2009 -0500
[US 2] Initial commit for ConfiugrationManagerInitializer.java
ConfigurationInitializer is used by PluginContainer to wire up ConfigurationManager's dependencies.
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/PluginContainer.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/PluginContainer.java index 1fe0cc7..25d61c2 100644 --- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/PluginContainer.java +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/PluginContainer.java @@ -46,6 +46,7 @@ import org.rhq.core.pc.agent.AgentService; import org.rhq.core.pc.agent.AgentServiceLifecycleListener; import org.rhq.core.pc.agent.AgentServiceStreamRemoter; import org.rhq.core.pc.configuration.ConfigurationManager; +import org.rhq.core.pc.configuration.ConfigurationManagerInitializer; import org.rhq.core.pc.content.ContentManager; import org.rhq.core.pc.event.EventManager; import org.rhq.core.pc.inventory.InventoryManager; @@ -355,6 +356,10 @@ public class PluginContainer implements ContainerService { agentService.addLifecycleListener(agentServiceListener); } } + else if (containerService instanceof ConfigurationManager) { + ConfigurationManagerInitializer initializer = new ConfigurationManagerInitializer(); + initializer.initialize((ConfigurationManager)containerService); + }
containerService.initialize();
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManagerInitializer.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManagerInitializer.java new file mode 100644 index 0000000..6cad31e --- /dev/null +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManagerInitializer.java @@ -0,0 +1,35 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2008 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, version 2, as + * published by the Free Software Foundation, and/or the GNU Lesser + * General Public License, version 2.1, also as published by the Free + * Software Foundation. + * + * 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 and the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * and the GNU Lesser 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.core.pc.configuration; + +import org.rhq.core.pc.util.ComponentServiceImpl; + +public class ConfigurationManagerInitializer { + + public void initialize(ConfigurationManager manager) { + manager.setComponentService(new ComponentServiceImpl()); + manager.setLoadConfigFactory(new LoadResourceConfigurationFactoryImpl()); + } + +}
commit 739c1af71ef3da2ddf71164bf6bfdc0f50e730c9 Author: John Sanda john@localhost.localdomain Date: Mon Nov 9 13:54:32 2009 -0500
[US 2] Initial commit for ComponentServiceImpl
ComponentService is just a thin wrapper around ComponentUtil to facilitate testing by providng an interface as opposed to statics. The interface has been moved to the same package as ComponentUtil to better indicate the coupling.
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/BaseLoadConfig.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/BaseLoadConfig.java index 052ac0b..417bf7f 100644 --- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/BaseLoadConfig.java +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/BaseLoadConfig.java @@ -23,7 +23,7 @@
package org.rhq.core.pc.configuration;
-import org.rhq.core.pc.inventory.ComponentService; +import org.rhq.core.pc.util.ComponentService; import org.rhq.core.pc.util.FacetLockType; import org.rhq.core.pluginapi.configuration.ResourceConfigurationFacet; import org.rhq.core.clientapi.agent.PluginContainerException; diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManager.java index 04e2646..3897616 100644 --- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManager.java +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManager.java @@ -41,7 +41,7 @@ import org.rhq.core.domain.resource.ResourceType; import org.rhq.core.pc.ContainerService; import org.rhq.core.pc.PluginContainerConfiguration; import org.rhq.core.pc.PluginContainer; -import org.rhq.core.pc.inventory.ComponentService; +import org.rhq.core.pc.util.ComponentService; import org.rhq.core.pc.agent.AgentService; import org.rhq.core.pc.util.ComponentUtil; import org.rhq.core.pc.util.FacetLockType; diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadResourceConfiguration.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadResourceConfiguration.java index 0cc9cf9..e2e2aa9 100644 --- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadResourceConfiguration.java +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadResourceConfiguration.java @@ -23,7 +23,7 @@
package org.rhq.core.pc.configuration;
-import org.rhq.core.pc.inventory.ComponentService; +import org.rhq.core.pc.util.ComponentService; import org.rhq.core.domain.configuration.Configuration; import org.rhq.core.clientapi.agent.PluginContainerException;
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadResourceConfigurationFactoryImpl.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadResourceConfigurationFactoryImpl.java index 07b275f..e2b1e86 100644 --- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadResourceConfigurationFactoryImpl.java +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadResourceConfigurationFactoryImpl.java @@ -25,7 +25,7 @@ package org.rhq.core.pc.configuration;
import static org.rhq.core.domain.configuration.definition.ConfigurationFormat.*;
-import org.rhq.core.pc.inventory.ComponentService; +import org.rhq.core.pc.util.ComponentService; import org.rhq.core.domain.resource.ResourceType; import org.rhq.core.clientapi.agent.PluginContainerException; import org.apache.maven.artifact.versioning.ComparableVersion; diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/ComponentService.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/ComponentService.java deleted file mode 100644 index 1a697eb..0000000 --- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/ComponentService.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2008 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, version 2, as - * published by the Free Software Foundation, and/or the GNU Lesser - * General Public License, version 2.1, also as published by the Free - * Software Foundation. - * - * 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 and the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * and the GNU Lesser 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.core.pc.inventory; - -import org.rhq.core.domain.resource.ResourceType; -import org.rhq.core.clientapi.agent.PluginContainerException; -import org.rhq.core.pc.util.FacetLockType; - -public interface ComponentService { - - ResourceType getResourceType(int resourceId) throws PluginContainerException; - - <T> T getComponent(int resourceId, Class<T> facetInterface, FacetLockType lockType, long timeout, - boolean daemonThread, boolean onlyIfStarted) throws PluginContainerException; - - String getAmpsVersion(int resourceId); - -} diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/util/ComponentService.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/util/ComponentService.java new file mode 100644 index 0000000..f831ae4 --- /dev/null +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/util/ComponentService.java @@ -0,0 +1,39 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2008 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, version 2, as + * published by the Free Software Foundation, and/or the GNU Lesser + * General Public License, version 2.1, also as published by the Free + * Software Foundation. + * + * 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 and the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * and the GNU Lesser 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.core.pc.util; + +import org.rhq.core.domain.resource.ResourceType; +import org.rhq.core.clientapi.agent.PluginContainerException; +import org.rhq.core.pc.util.FacetLockType; + +public interface ComponentService { + + ResourceType getResourceType(int resourceId) throws PluginContainerException; + + <T> T getComponent(int resourceId, Class<T> facetInterface, FacetLockType lockType, long timeout, + boolean daemonThread, boolean onlyIfStarted) throws PluginContainerException; + + String getAmpsVersion(int resourceId) throws PluginContainerException; + +} diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/util/ComponentServiceImpl.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/util/ComponentServiceImpl.java new file mode 100644 index 0000000..fa8923c --- /dev/null +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/util/ComponentServiceImpl.java @@ -0,0 +1,51 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2008 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, version 2, as + * published by the Free Software Foundation, and/or the GNU Lesser + * General Public License, version 2.1, also as published by the Free + * Software Foundation. + * + * 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 and the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * and the GNU Lesser 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.core.pc.util; + +import org.rhq.core.domain.resource.ResourceType; +import org.rhq.core.domain.plugin.Plugin; +import org.rhq.core.clientapi.agent.PluginContainerException; +import org.rhq.core.pc.PluginContainer; +import org.rhq.core.pc.plugin.PluginManager; + +public class ComponentServiceImpl implements ComponentService { + + public ResourceType getResourceType(int resourceId) throws PluginContainerException { + return ComponentUtil.getResourceType(resourceId); + } + + public <T> T getComponent(int resourceId, Class<T> facetInterface, FacetLockType lockType, long timeout, + boolean daemonThread, boolean onlyIfStarted) throws PluginContainerException { + return ComponentUtil.getComponent(resourceId, facetInterface, lockType, timeout, daemonThread, onlyIfStarted); + } + + public String getAmpsVersion(int resourceId) throws PluginContainerException { + PluginContainer pluginContainer = PluginContainer.getInstance(); + PluginManager pluginMgr = pluginContainer.getPluginManager(); + + ResourceType resourceType = getResourceType(resourceId); + + return pluginMgr.getAmpsVersion(resourceType.getPlugin()); + } +} diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigurationManagerUnitTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigurationManagerUnitTest.java index b706ea0..f83c9fe 100644 --- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigurationManagerUnitTest.java +++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigurationManagerUnitTest.java @@ -27,7 +27,7 @@ import org.jmock.Expectations; import org.rhq.core.clientapi.agent.PluginContainerException; import org.rhq.core.domain.configuration.Configuration; import org.rhq.core.domain.resource.ResourceType; -import org.rhq.core.pc.inventory.ComponentService; +import org.rhq.core.pc.util.ComponentService; import static org.testng.Assert.assertSame; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadRawTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadRawTest.java index a8ef696..1eeb3a9 100644 --- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadRawTest.java +++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadRawTest.java @@ -25,7 +25,7 @@ package org.rhq.core.pc.configuration;
import static org.testng.Assert.*;
-import org.rhq.core.pc.inventory.ComponentService; +import org.rhq.core.pc.util.ComponentService; import org.rhq.core.pc.util.FacetLockType; import org.rhq.core.pluginapi.configuration.ResourceConfigurationFacet; import org.rhq.core.domain.configuration.Configuration; diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadResourceConfigurationFactoryImplTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadResourceConfigurationFactoryImplTest.java index dd20612..6913b87 100644 --- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadResourceConfigurationFactoryImplTest.java +++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadResourceConfigurationFactoryImplTest.java @@ -27,7 +27,7 @@ import static org.testng.Assert.*;
import org.testng.annotations.Test; import org.testng.annotations.BeforeMethod; -import org.rhq.core.pc.inventory.ComponentService; +import org.rhq.core.pc.util.ComponentService; import org.rhq.core.domain.resource.ResourceType; import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; import org.rhq.core.domain.configuration.definition.ConfigurationFormat; diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadStructuredAndRawTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadStructuredAndRawTest.java index ea6ebbe..3821cc1 100644 --- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadStructuredAndRawTest.java +++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadStructuredAndRawTest.java @@ -25,7 +25,7 @@ package org.rhq.core.pc.configuration;
import static org.testng.Assert.*;
-import org.rhq.core.pc.inventory.ComponentService; +import org.rhq.core.pc.util.ComponentService; import org.rhq.core.pc.util.FacetLockType; import org.rhq.core.pluginapi.configuration.ResourceConfigurationFacet; import org.rhq.core.domain.configuration.Configuration; diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadStructuredTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadStructuredTest.java index 23f3e8a..e3e8148 100644 --- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadStructuredTest.java +++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadStructuredTest.java @@ -25,7 +25,7 @@ package org.rhq.core.pc.configuration;
import static org.testng.Assert.*;
-import org.rhq.core.pc.inventory.ComponentService; +import org.rhq.core.pc.util.ComponentService; import org.rhq.core.pc.util.FacetLockType; import org.rhq.core.pluginapi.configuration.ResourceConfigurationFacet; import org.rhq.core.domain.configuration.Configuration;
commit 951b7623442c8a0c5a49af5013e0e1f1d3e4c22f Author: John Sanda john@localhost.localdomain Date: Mon Nov 9 13:46:05 2009 -0500
[US] Renaming classes to be a bit more concise.
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/BaseLoadConfig.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/BaseLoadConfig.java new file mode 100644 index 0000000..052ac0b --- /dev/null +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/BaseLoadConfig.java @@ -0,0 +1,60 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2008 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, version 2, as + * published by the Free Software Foundation, and/or the GNU Lesser + * General Public License, version 2.1, also as published by the Free + * Software Foundation. + * + * 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 and the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * and the GNU Lesser 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.core.pc.configuration; + +import org.rhq.core.pc.inventory.ComponentService; +import org.rhq.core.pc.util.FacetLockType; +import org.rhq.core.pluginapi.configuration.ResourceConfigurationFacet; +import org.rhq.core.clientapi.agent.PluginContainerException; + +public abstract class BaseLoadConfig implements LoadResourceConfiguration { + + protected ComponentService componentService; + + protected ConfigurationUtilityService configUtilityService; + + public ComponentService getComponentService() { + return componentService; + } + + public void setComponentService(ComponentService componentService) { + this.componentService = componentService; + } + + public ConfigurationUtilityService getConfigurationUtilityService() { + return configUtilityService; + } + + public void setConfigurationUtilityService(ConfigurationUtilityService configUtilityService) { + this.configUtilityService = configUtilityService; + } + + protected ResourceConfigurationFacet loadResouceConfiguratonFacet(int resourceId) throws PluginContainerException { + boolean daemonOnly = true; + boolean onlyIfStarted = true; + + return componentService.getComponent(resourceId, ResourceConfigurationFacet.class, FacetLockType.READ, + FACET_METHOD_TIMEOUT, daemonOnly, onlyIfStarted); + } +} diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/BaseResourceConfigurationStrategy.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/BaseResourceConfigurationStrategy.java deleted file mode 100644 index ce316f8..0000000 --- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/BaseResourceConfigurationStrategy.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2008 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, version 2, as - * published by the Free Software Foundation, and/or the GNU Lesser - * General Public License, version 2.1, also as published by the Free - * Software Foundation. - * - * 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 and the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * and the GNU Lesser 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.core.pc.configuration; - -import org.rhq.core.pc.inventory.InventoryService; -import org.rhq.core.pc.util.FacetLockType; -import org.rhq.core.domain.configuration.Configuration; -import org.rhq.core.pluginapi.configuration.ResourceConfigurationFacet; -import org.rhq.core.clientapi.agent.PluginContainerException; - -public abstract class BaseResourceConfigurationStrategy implements ResourceConfigurationStrategy { - - protected InventoryService componentService; - - protected ConfigurationUtilityService configUtilityService; - - public InventoryService getComponentService() { - return componentService; - } - - public void setComponentService(InventoryService componentService) { - this.componentService = componentService; - } - - public ConfigurationUtilityService getConfigurationUtilityService() { - return configUtilityService; - } - - public void setConfigurationUtilityService(ConfigurationUtilityService configUtilityService) { - this.configUtilityService = configUtilityService; - } - - protected ResourceConfigurationFacet loadResouceConfiguratonFacet(int resourceId) throws PluginContainerException { - boolean daemonOnly = true; - boolean onlyIfStarted = true; - - return componentService.getComponent(resourceId, ResourceConfigurationFacet.class, FacetLockType.READ, - FACET_METHOD_TIMEOUT, daemonOnly, onlyIfStarted); - } -} diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManager.java index 8aea688..04e2646 100644 --- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManager.java +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManager.java @@ -37,18 +37,16 @@ import org.rhq.core.clientapi.server.configuration.ConfigurationServerService; import org.rhq.core.clientapi.server.configuration.ConfigurationUpdateResponse; import org.rhq.core.domain.configuration.Configuration; import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; -import org.rhq.core.domain.configuration.definition.ConfigurationFormat; import org.rhq.core.domain.resource.ResourceType; import org.rhq.core.pc.ContainerService; import org.rhq.core.pc.PluginContainerConfiguration; import org.rhq.core.pc.PluginContainer; -import org.rhq.core.pc.inventory.InventoryService; +import org.rhq.core.pc.inventory.ComponentService; import org.rhq.core.pc.agent.AgentService; import org.rhq.core.pc.util.ComponentUtil; import org.rhq.core.pc.util.FacetLockType; import org.rhq.core.pc.util.LoggingThreadFactory; import org.rhq.core.pluginapi.configuration.ConfigurationFacet; -import org.rhq.core.pluginapi.configuration.ResourceConfigurationFacet; import org.rhq.core.util.exception.WrappedRemotingException;
/** @@ -70,9 +68,9 @@ public class ConfigurationManager extends AgentService implements ContainerServi private PluginContainerConfiguration pluginContainerConfiguration; private ScheduledExecutorService threadPool;
- private InventoryService inventoryService; + private ComponentService componentService;
- private ResourceConfigurationStrategyFactory loadConfigStrategyFactory; + private LoadResourceConfigurationFactory loadConfigFactory;
public ConfigurationManager() { super(ConfigurationAgentService.class); @@ -104,12 +102,12 @@ public class ConfigurationManager extends AgentService implements ContainerServi pluginContainerConfiguration = configuration; }
- public void setInventoryService(InventoryService inventoryService) { - this.inventoryService = inventoryService; + public void setComponentService(ComponentService componentService) { + this.componentService = componentService; }
- public void setLoadConfigStrategyFactory(ResourceConfigurationStrategyFactory factory) { - loadConfigStrategyFactory = factory; + public void setLoadConfigFactory(LoadResourceConfigurationFactory factory) { + loadConfigFactory = factory; }
public void updateResourceConfiguration(ConfigurationUpdateRequest request) { @@ -163,11 +161,11 @@ public class ConfigurationManager extends AgentService implements ContainerServi public Configuration loadResourceConfiguration(int resourceId, boolean fromStructured) throws PluginContainerException {
- ResourceConfigurationStrategy strategy = loadConfigStrategyFactory.getStrategy(resourceId); - Configuration configuration = strategy.loadConfiguration(resourceId, fromStructured); + LoadResourceConfiguration loadConfig = loadConfigFactory.getStrategy(resourceId); + Configuration configuration = loadConfig.execute(resourceId, fromStructured);
if (configuration == null) { - ResourceType resourceType = inventoryService.getResourceType(resourceId); + ResourceType resourceType = componentService.getResourceType(resourceId); throw new PluginContainerException("Plugin Error: Resource Component for [" + resourceType.getName() + "] Resource with id [" + resourceId + "] returned a null Configuration."); } diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LegacyLoadConfig.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LegacyLoadConfig.java new file mode 100644 index 0000000..23818c1 --- /dev/null +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LegacyLoadConfig.java @@ -0,0 +1,81 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2008 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, version 2, as + * published by the Free Software Foundation, and/or the GNU Lesser + * General Public License, version 2.1, also as published by the Free + * Software Foundation. + * + * 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 and the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * and the GNU Lesser 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.core.pc.configuration; + +import org.rhq.core.clientapi.agent.PluginContainerException; +import org.rhq.core.clientapi.agent.configuration.ConfigurationUtility; +import org.rhq.core.domain.configuration.Configuration; +import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; +import org.rhq.core.domain.resource.ResourceType; +import org.rhq.core.pc.util.FacetLockType; +import org.rhq.core.pluginapi.configuration.ConfigurationFacet; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.util.List; + +public class LegacyLoadConfig extends BaseLoadConfig { + + private static final Log log = LogFactory.getLog(LegacyLoadConfig.class); + + public Configuration execute(int resourceId, boolean fromStructured) throws PluginContainerException { + Configuration configuration = loadConfigFromFacet(resourceId); + ResourceType resourceType = componentService.getResourceType(resourceId); + + // If the plugin didn't already set the notes field, set it to something useful. + if (configuration.getNotes() == null) { + configuration.setNotes("Resource config for " + resourceType.getName() + " Resource w/ id " + resourceId); + } + + ConfigurationDefinition configurationDefinition = resourceType.getResourceConfigurationDefinition(); + + // Normalize and validate the config. + ConfigurationUtility.normalizeConfiguration(configuration, configurationDefinition); + List<String> errorMessages = ConfigurationUtility.validateConfiguration(configuration, + configurationDefinition); + for (String errorMessage : errorMessages) { + log.warn("Plugin Error: Invalid " + resourceType.getName() + " Resource configuration returned by " + + resourceType.getPlugin() + " plugin - " + errorMessage); + } + + return configuration; + } + + private Configuration loadConfigFromFacet(int resourceId) throws PluginContainerException { + FacetLockType lockType = FacetLockType.READ; + boolean daemonThread = (lockType != FacetLockType.WRITE); + boolean onlyIfStarted = true; + + ConfigurationFacet configFacet = componentService.getComponent(resourceId, ConfigurationFacet.class, + lockType, FACET_METHOD_TIMEOUT, daemonThread, onlyIfStarted); + + Configuration configuration = null; + try { + return configFacet.loadResourceConfiguration(); + } catch (Exception e) { + throw new PluginContainerException(e); + } + } + +} diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LegacyResourceConfigurationStrategy.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LegacyResourceConfigurationStrategy.java deleted file mode 100644 index 2542d33..0000000 --- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LegacyResourceConfigurationStrategy.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2008 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, version 2, as - * published by the Free Software Foundation, and/or the GNU Lesser - * General Public License, version 2.1, also as published by the Free - * Software Foundation. - * - * 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 and the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * and the GNU Lesser 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.core.pc.configuration; - -import org.rhq.core.clientapi.agent.PluginContainerException; -import org.rhq.core.clientapi.agent.configuration.ConfigurationUtility; -import org.rhq.core.domain.configuration.Configuration; -import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; -import org.rhq.core.domain.resource.ResourceType; -import org.rhq.core.pc.util.FacetLockType; -import org.rhq.core.pluginapi.configuration.ConfigurationFacet; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import java.util.List; - -public class LegacyResourceConfigurationStrategy extends BaseResourceConfigurationStrategy { - - private static final Log log = LogFactory.getLog(LegacyResourceConfigurationStrategy.class); - - public Configuration loadConfiguration(int resourceId, boolean fromStructured) throws PluginContainerException { - Configuration configuration = loadConfigFromFacet(resourceId); - ResourceType resourceType = componentService.getResourceType(resourceId); - - // If the plugin didn't already set the notes field, set it to something useful. - if (configuration.getNotes() == null) { - configuration.setNotes("Resource config for " + resourceType.getName() + " Resource w/ id " + resourceId); - } - - ConfigurationDefinition configurationDefinition = resourceType.getResourceConfigurationDefinition(); - - // Normalize and validate the config. - ConfigurationUtility.normalizeConfiguration(configuration, configurationDefinition); - List<String> errorMessages = ConfigurationUtility.validateConfiguration(configuration, - configurationDefinition); - for (String errorMessage : errorMessages) { - log.warn("Plugin Error: Invalid " + resourceType.getName() + " Resource configuration returned by " - + resourceType.getPlugin() + " plugin - " + errorMessage); - } - - return configuration; - } - - private Configuration loadConfigFromFacet(int resourceId) throws PluginContainerException { - FacetLockType lockType = FacetLockType.READ; - boolean daemonThread = (lockType != FacetLockType.WRITE); - boolean onlyIfStarted = true; - - ConfigurationFacet configFacet = componentService.getComponent(resourceId, ConfigurationFacet.class, - lockType, FACET_METHOD_TIMEOUT, daemonThread, onlyIfStarted); - - Configuration configuration = null; - try { - return configFacet.loadResourceConfiguration(); - } catch (Exception e) { - throw new PluginContainerException(e); - } - } - -} diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadRaw.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadRaw.java new file mode 100644 index 0000000..14fe458 --- /dev/null +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadRaw.java @@ -0,0 +1,70 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2008 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, version 2, as + * published by the Free Software Foundation, and/or the GNU Lesser + * General Public License, version 2.1, also as published by the Free + * Software Foundation. + * + * 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 and the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * and the GNU Lesser 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.core.pc.configuration; + +import org.rhq.core.domain.configuration.Configuration; +import org.rhq.core.domain.resource.ResourceType; +import org.rhq.core.clientapi.agent.PluginContainerException; +import org.rhq.core.pluginapi.configuration.ResourceConfigurationFacet; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.util.List; + +public class LoadRaw extends BaseLoadConfig { + + private final Log log = LogFactory.getLog(LoadRaw.class); + + public Configuration execute(int resourceId, boolean fromStructured) throws PluginContainerException { + ResourceConfigurationFacet facet = loadResouceConfiguratonFacet(resourceId); + + Configuration configuration = facet.loadRawConfigurations(); + + if (configuration == null) { + return null; + } + + ResourceType resourceType = componentService.getResourceType(resourceId); + + if (configuration.getNotes() == null) { + configuration.setNotes("Resource config for " + resourceType.getName() + " Resource w/ id " + resourceId); + } + + configUtilityService.normalizeConfiguration(configuration, resourceType.getResourceConfigurationDefinition()); + List<String> errorMsgs = configUtilityService.validateConfiguration(configuration, + resourceType.getResourceConfigurationDefinition()); + + logErrorMsgs(errorMsgs, resourceType); + + return configuration; + } + + private void logErrorMsgs(List<String> errorMsgs, ResourceType resourceType) { + for (String errorMessage : errorMsgs) { + log.warn("Plugin Error: Invalid " + resourceType.getName() + " Resource configuration returned by " + + resourceType.getPlugin() + " plugin - " + errorMessage); + } + } + +} diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadResourceConfiguration.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadResourceConfiguration.java new file mode 100644 index 0000000..0cc9cf9 --- /dev/null +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadResourceConfiguration.java @@ -0,0 +1,44 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2008 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, version 2, as + * published by the Free Software Foundation, and/or the GNU Lesser + * General Public License, version 2.1, also as published by the Free + * Software Foundation. + * + * 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 and the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * and the GNU Lesser 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.core.pc.configuration; + +import org.rhq.core.pc.inventory.ComponentService; +import org.rhq.core.domain.configuration.Configuration; +import org.rhq.core.clientapi.agent.PluginContainerException; + +public interface LoadResourceConfiguration { + + static final int FACET_METHOD_TIMEOUT = 60 * 1000; // 60 seconds + + ComponentService getComponentService(); + + void setComponentService(ComponentService componentService); + + ConfigurationUtilityService getConfigurationUtilityService(); + + void setConfigurationUtilityService(ConfigurationUtilityService configUtilityService); + + Configuration execute(int resourceId, boolean fromStructured) throws PluginContainerException; + +} diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadResourceConfigurationFactory.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadResourceConfigurationFactory.java new file mode 100644 index 0000000..5bd04ed --- /dev/null +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadResourceConfigurationFactory.java @@ -0,0 +1,32 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2008 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, version 2, as + * published by the Free Software Foundation, and/or the GNU Lesser + * General Public License, version 2.1, also as published by the Free + * Software Foundation. + * + * 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 and the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * and the GNU Lesser 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.core.pc.configuration; + +import org.rhq.core.clientapi.agent.PluginContainerException; + +public interface LoadResourceConfigurationFactory { + + LoadResourceConfiguration getStrategy(int resourceId) throws PluginContainerException; + +} diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadResourceConfigurationFactoryImpl.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadResourceConfigurationFactoryImpl.java new file mode 100644 index 0000000..07b275f --- /dev/null +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadResourceConfigurationFactoryImpl.java @@ -0,0 +1,89 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2008 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, version 2, as + * published by the Free Software Foundation, and/or the GNU Lesser + * General Public License, version 2.1, also as published by the Free + * Software Foundation. + * + * 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 and the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * and the GNU Lesser 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.core.pc.configuration; + +import static org.rhq.core.domain.configuration.definition.ConfigurationFormat.*; + +import org.rhq.core.pc.inventory.ComponentService; +import org.rhq.core.domain.resource.ResourceType; +import org.rhq.core.clientapi.agent.PluginContainerException; +import org.apache.maven.artifact.versioning.ComparableVersion; + +public class LoadResourceConfigurationFactoryImpl implements LoadResourceConfigurationFactory { + + private static final ComparableVersion NON_LEGACY_AMPS_VERSION = new ComparableVersion("2.1"); + + private ComponentService componentService; + + private ConfigurationUtilityService configUtilityService = new ConfigurationUtilityServiceImpl(); + + public void setComponentService(ComponentService componentService) { + this.componentService = componentService; + } + + public LoadResourceConfiguration getStrategy(int resourceId) throws PluginContainerException { + LoadResourceConfiguration loadConfig = createStrategy(resourceId); + initStrategyDependencies(loadConfig); + + return loadConfig; + } + + private void initStrategyDependencies(LoadResourceConfiguration loadConfig) { + loadConfig.setComponentService(componentService); + loadConfig.setConfigurationUtilityService(configUtilityService); + } + + private LoadResourceConfiguration createStrategy(int resourceId) throws PluginContainerException { + String ampsVersion = componentService.getAmpsVersion(resourceId); + + if (isLegacyVersion(ampsVersion)) { + return new LegacyLoadConfig(); + } + + ResourceType resourceType = componentService.getResourceType(resourceId); + + if (isStructured(resourceType)) { + return new LoadStructured(); + } + + if (isRaw(resourceType)) { + return new LoadRaw(); + } + + // else format is both structured and raw + return new LoadStructuredAndRaw(); + } + + private boolean isLegacyVersion(String ampsVersion) { + return new ComparableVersion(ampsVersion).compareTo(NON_LEGACY_AMPS_VERSION) < 0; + } + + private boolean isStructured(ResourceType resourceType) { + return resourceType.getResourceConfigurationDefinition().getConfigurationFormat().equals(STRUCTURED); + } + + private boolean isRaw(ResourceType resourceType) { + return resourceType.getResourceConfigurationDefinition().getConfigurationFormat().equals(RAW); + } +} diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadStructured.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadStructured.java new file mode 100644 index 0000000..ecbfb1f --- /dev/null +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadStructured.java @@ -0,0 +1,69 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2008 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, version 2, as + * published by the Free Software Foundation, and/or the GNU Lesser + * General Public License, version 2.1, also as published by the Free + * Software Foundation. + * + * 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 and the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * and the GNU Lesser 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.core.pc.configuration; + +import org.rhq.core.domain.configuration.Configuration; +import org.rhq.core.domain.resource.ResourceType; +import org.rhq.core.clientapi.agent.PluginContainerException; +import org.rhq.core.pluginapi.configuration.ResourceConfigurationFacet; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.util.List; + +public class LoadStructured extends BaseLoadConfig { + + private final Log log = LogFactory.getLog(LoadStructured.class); + + public Configuration execute(int resourceId, boolean fromStructured) throws PluginContainerException { + ResourceConfigurationFacet facet = loadResouceConfiguratonFacet(resourceId); + + Configuration configuration = facet.loadStructuredConfiguration(); + + if (configuration == null) { + return null; + } + + ResourceType resourceType = componentService.getResourceType(resourceId); + + if (configuration.getNotes() == null) { + configuration.setNotes("Resource config for " + resourceType.getName() + " Resource w/ id " + resourceId); + } + + configUtilityService.normalizeConfiguration(configuration, resourceType.getResourceConfigurationDefinition()); + List<String> errorMsgs = configUtilityService.validateConfiguration(configuration, + resourceType.getResourceConfigurationDefinition()); + + logErrorMsgs(errorMsgs, resourceType); + + return configuration; + } + + private void logErrorMsgs(List<String> errorMsgs, ResourceType resourceType) { + for (String errorMessage : errorMsgs) { + log.warn("Plugin Error: Invalid " + resourceType.getName() + " Resource configuration returned by " + + resourceType.getPlugin() + " plugin - " + errorMessage); + } + } +} diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadStructuredAndRaw.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadStructuredAndRaw.java new file mode 100644 index 0000000..de5dd60 --- /dev/null +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/LoadStructuredAndRaw.java @@ -0,0 +1,92 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2008 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, version 2, as + * published by the Free Software Foundation, and/or the GNU Lesser + * General Public License, version 2.1, also as published by the Free + * Software Foundation. + * + * 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 and the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * and the GNU Lesser 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.core.pc.configuration; + +import org.rhq.core.domain.configuration.Configuration; +import org.rhq.core.domain.configuration.RawConfiguration; +import org.rhq.core.domain.resource.ResourceType; +import org.rhq.core.clientapi.agent.PluginContainerException; +import org.rhq.core.pluginapi.configuration.ResourceConfigurationFacet; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.util.List; + +public class LoadStructuredAndRaw extends BaseLoadConfig { + + private final Log log = LogFactory.getLog(LoadStructuredAndRaw.class); + + public Configuration execute(int resourceId, boolean fromStructured) throws PluginContainerException { + ResourceConfigurationFacet facet = loadResouceConfiguratonFacet(resourceId); + + Configuration configuration; + if (fromStructured) { + configuration = facet.loadStructuredConfiguration(); + if (configuration == null) { + return null; + } + mergeStructured(configuration, facet); + } + else { + configuration = facet.loadRawConfigurations(); + if (configuration == null) { + return null; + } + mergeRaw(configuration, facet); + } + + ResourceType resourceType = componentService.getResourceType(resourceId); + + if (configuration.getNotes() == null) { + configuration.setNotes("Resource config for " + resourceType.getName() + " Resource w/ id " + resourceId); + } + + configUtilityService.normalizeConfiguration(configuration, resourceType.getResourceConfigurationDefinition()); + List<String> errorMsgs = configUtilityService.validateConfiguration(configuration, + resourceType.getResourceConfigurationDefinition()); + + logErrorMsgs(errorMsgs, resourceType); + + return configuration; + } + + private void mergeStructured(Configuration configuration, ResourceConfigurationFacet configFacet) { + for (RawConfiguration rawConfig : configuration.getRawConfigurations()) { + configFacet.mergeStructuredConfiguration(rawConfig, configuration); + } + } + + private void mergeRaw(Configuration configuration, ResourceConfigurationFacet configFacet) { + for (RawConfiguration rawConfig : configuration.getRawConfigurations()) { + configFacet.mergeRawConfiguration(configuration, rawConfig); + } + } + + private void logErrorMsgs(List<String> errorMsgs, ResourceType resourceType) { + for (String errorMessage : errorMsgs) { + log.warn("Plugin Error: Invalid " + resourceType.getName() + " Resource configuration returned by " + + resourceType.getPlugin() + " plugin - " + errorMessage); + } + } +} diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/RawResourceConfigurationStrategy.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/RawResourceConfigurationStrategy.java deleted file mode 100644 index 0c6ca7a..0000000 --- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/RawResourceConfigurationStrategy.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2008 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, version 2, as - * published by the Free Software Foundation, and/or the GNU Lesser - * General Public License, version 2.1, also as published by the Free - * Software Foundation. - * - * 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 and the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * and the GNU Lesser 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.core.pc.configuration; - -import org.rhq.core.domain.configuration.Configuration; -import org.rhq.core.domain.resource.ResourceType; -import org.rhq.core.clientapi.agent.PluginContainerException; -import org.rhq.core.pluginapi.configuration.ResourceConfigurationFacet; -import org.rhq.core.pc.util.FacetLockType; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import java.util.List; - -public class RawResourceConfigurationStrategy extends BaseResourceConfigurationStrategy { - - private final Log log = LogFactory.getLog(RawResourceConfigurationStrategy.class); - - public Configuration loadConfiguration(int resourceId, boolean fromStructured) throws PluginContainerException { - ResourceConfigurationFacet facet = loadResouceConfiguratonFacet(resourceId); - - Configuration configuration = facet.loadRawConfigurations(); - - if (configuration == null) { - return null; - } - - ResourceType resourceType = componentService.getResourceType(resourceId); - - if (configuration.getNotes() == null) { - configuration.setNotes("Resource config for " + resourceType.getName() + " Resource w/ id " + resourceId); - } - - configUtilityService.normalizeConfiguration(configuration, resourceType.getResourceConfigurationDefinition()); - List<String> errorMsgs = configUtilityService.validateConfiguration(configuration, - resourceType.getResourceConfigurationDefinition()); - - logErrorMsgs(errorMsgs, resourceType); - - return configuration; - } - - private void logErrorMsgs(List<String> errorMsgs, ResourceType resourceType) { - for (String errorMessage : errorMsgs) { - log.warn("Plugin Error: Invalid " + resourceType.getName() + " Resource configuration returned by " - + resourceType.getPlugin() + " plugin - " + errorMessage); - } - } - -} diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ResourceConfigurationStrategy.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ResourceConfigurationStrategy.java deleted file mode 100644 index 210908b..0000000 --- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ResourceConfigurationStrategy.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2008 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, version 2, as - * published by the Free Software Foundation, and/or the GNU Lesser - * General Public License, version 2.1, also as published by the Free - * Software Foundation. - * - * 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 and the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * and the GNU Lesser 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.core.pc.configuration; - -import org.rhq.core.pc.inventory.InventoryService; -import org.rhq.core.domain.configuration.Configuration; -import org.rhq.core.clientapi.agent.PluginContainerException; - -public interface ResourceConfigurationStrategy { - - static final int FACET_METHOD_TIMEOUT = 60 * 1000; // 60 seconds - - InventoryService getComponentService(); - - void setComponentService(InventoryService componentService); - - ConfigurationUtilityService getConfigurationUtilityService(); - - void setConfigurationUtilityService(ConfigurationUtilityService configUtilityService); - - Configuration loadConfiguration(int resourceId, boolean fromStructured) throws PluginContainerException; - -} diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ResourceConfigurationStrategyFactory.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ResourceConfigurationStrategyFactory.java deleted file mode 100644 index 4c5b65c..0000000 --- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ResourceConfigurationStrategyFactory.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2008 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, version 2, as - * published by the Free Software Foundation, and/or the GNU Lesser - * General Public License, version 2.1, also as published by the Free - * Software Foundation. - * - * 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 and the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * and the GNU Lesser 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.core.pc.configuration; - -import org.rhq.core.clientapi.agent.PluginContainerException; - -public interface ResourceConfigurationStrategyFactory { - - ResourceConfigurationStrategy getStrategy(int resourceId) throws PluginContainerException; - -} diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ResourceConfigurationStrategyFactoryImpl.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ResourceConfigurationStrategyFactoryImpl.java deleted file mode 100644 index cf4a46d..0000000 --- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ResourceConfigurationStrategyFactoryImpl.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2008 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, version 2, as - * published by the Free Software Foundation, and/or the GNU Lesser - * General Public License, version 2.1, also as published by the Free - * Software Foundation. - * - * 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 and the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * and the GNU Lesser 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.core.pc.configuration; - -import static org.rhq.core.domain.configuration.definition.ConfigurationFormat.*; - -import org.rhq.core.pc.inventory.InventoryService; -import org.rhq.core.domain.resource.ResourceType; -import org.rhq.core.clientapi.agent.PluginContainerException; -import org.apache.maven.artifact.versioning.ComparableVersion; - -public class ResourceConfigurationStrategyFactoryImpl implements ResourceConfigurationStrategyFactory { - - private static final ComparableVersion NON_LEGACY_AMPS_VERSION = new ComparableVersion("2.1"); - - private InventoryService componentService; - - private ConfigurationUtilityService configUtilityService = new ConfigurationUtilityServiceImpl(); - - public void setComponentService(InventoryService componentService) { - this.componentService = componentService; - } - - public ResourceConfigurationStrategy getStrategy(int resourceId) throws PluginContainerException { - ResourceConfigurationStrategy strategy = createStrategy(resourceId); - initStrategyDependencies(strategy); - - return strategy; - } - - private void initStrategyDependencies(ResourceConfigurationStrategy strategy) { - strategy.setComponentService(componentService); - strategy.setConfigurationUtilityService(configUtilityService); - } - - private ResourceConfigurationStrategy createStrategy(int resourceId) throws PluginContainerException { - String ampsVersion = componentService.getAmpsVersion(resourceId); - - if (isLegacyVersion(ampsVersion)) { - return new LegacyResourceConfigurationStrategy(); - } - - ResourceType resourceType = componentService.getResourceType(resourceId); - - if (isStructured(resourceType)) { - return new StructuredResourceConfigurationStrategy(); - } - - if (isRaw(resourceType)) { - return new RawResourceConfigurationStrategy(); - } - - // else format is both structured and raw - return new StructuredAndRawResourceConfigurationStrategy(); - } - - private boolean isLegacyVersion(String ampsVersion) { - return new ComparableVersion(ampsVersion).compareTo(NON_LEGACY_AMPS_VERSION) < 0; - } - - private boolean isStructured(ResourceType resourceType) { - return resourceType.getResourceConfigurationDefinition().getConfigurationFormat().equals(STRUCTURED); - } - - private boolean isRaw(ResourceType resourceType) { - return resourceType.getResourceConfigurationDefinition().getConfigurationFormat().equals(RAW); - } -} diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/StructuredAndRawResourceConfigurationStrategy.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/StructuredAndRawResourceConfigurationStrategy.java deleted file mode 100644 index 011d822..0000000 --- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/StructuredAndRawResourceConfigurationStrategy.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2008 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, version 2, as - * published by the Free Software Foundation, and/or the GNU Lesser - * General Public License, version 2.1, also as published by the Free - * Software Foundation. - * - * 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 and the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * and the GNU Lesser 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.core.pc.configuration; - -import org.rhq.core.domain.configuration.Configuration; -import org.rhq.core.domain.configuration.RawConfiguration; -import org.rhq.core.domain.resource.ResourceType; -import org.rhq.core.clientapi.agent.PluginContainerException; -import org.rhq.core.pluginapi.configuration.ResourceConfigurationFacet; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import java.util.Set; -import java.util.HashSet; -import java.util.List; - -public class StructuredAndRawResourceConfigurationStrategy extends BaseResourceConfigurationStrategy { - - private final Log log = LogFactory.getLog(StructuredAndRawResourceConfigurationStrategy.class); - - public Configuration loadConfiguration(int resourceId, boolean fromStructured) throws PluginContainerException { - ResourceConfigurationFacet facet = loadResouceConfiguratonFacet(resourceId); - - Configuration configuration; - if (fromStructured) { - configuration = facet.loadStructuredConfiguration(); - if (configuration == null) { - return null; - } - mergeStructured(configuration, facet); - } - else { - configuration = facet.loadRawConfigurations(); - if (configuration == null) { - return null; - } - mergeRaw(configuration, facet); - } - - ResourceType resourceType = componentService.getResourceType(resourceId); - - if (configuration.getNotes() == null) { - configuration.setNotes("Resource config for " + resourceType.getName() + " Resource w/ id " + resourceId); - } - - configUtilityService.normalizeConfiguration(configuration, resourceType.getResourceConfigurationDefinition()); - List<String> errorMsgs = configUtilityService.validateConfiguration(configuration, - resourceType.getResourceConfigurationDefinition()); - - logErrorMsgs(errorMsgs, resourceType); - - return configuration; - } - - private void mergeStructured(Configuration configuration, ResourceConfigurationFacet configFacet) { - for (RawConfiguration rawConfig : configuration.getRawConfigurations()) { - configFacet.mergeStructuredConfiguration(rawConfig, configuration); - } - } - - private void mergeRaw(Configuration configuration, ResourceConfigurationFacet configFacet) { - for (RawConfiguration rawConfig : configuration.getRawConfigurations()) { - configFacet.mergeRawConfiguration(configuration, rawConfig); - } - } - - private void logErrorMsgs(List<String> errorMsgs, ResourceType resourceType) { - for (String errorMessage : errorMsgs) { - log.warn("Plugin Error: Invalid " + resourceType.getName() + " Resource configuration returned by " - + resourceType.getPlugin() + " plugin - " + errorMessage); - } - } -} diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/StructuredResourceConfigurationStrategy.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/StructuredResourceConfigurationStrategy.java deleted file mode 100644 index 7679529..0000000 --- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/StructuredResourceConfigurationStrategy.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2008 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, version 2, as - * published by the Free Software Foundation, and/or the GNU Lesser - * General Public License, version 2.1, also as published by the Free - * Software Foundation. - * - * 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 and the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * and the GNU Lesser 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.core.pc.configuration; - -import org.rhq.core.domain.configuration.Configuration; -import org.rhq.core.domain.resource.ResourceType; -import org.rhq.core.clientapi.agent.PluginContainerException; -import org.rhq.core.pluginapi.configuration.ResourceConfigurationFacet; -import org.rhq.core.pc.util.FacetLockType; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import java.util.List; - -public class StructuredResourceConfigurationStrategy extends BaseResourceConfigurationStrategy { - - private final Log log = LogFactory.getLog(StructuredResourceConfigurationStrategy.class); - - public Configuration loadConfiguration(int resourceId, boolean fromStructured) throws PluginContainerException { - ResourceConfigurationFacet facet = loadResouceConfiguratonFacet(resourceId); - - Configuration configuration = facet.loadStructuredConfiguration(); - - if (configuration == null) { - return null; - } - - ResourceType resourceType = componentService.getResourceType(resourceId); - - if (configuration.getNotes() == null) { - configuration.setNotes("Resource config for " + resourceType.getName() + " Resource w/ id " + resourceId); - } - - configUtilityService.normalizeConfiguration(configuration, resourceType.getResourceConfigurationDefinition()); - List<String> errorMsgs = configUtilityService.validateConfiguration(configuration, - resourceType.getResourceConfigurationDefinition()); - - logErrorMsgs(errorMsgs, resourceType); - - return configuration; - } - - private void logErrorMsgs(List<String> errorMsgs, ResourceType resourceType) { - for (String errorMessage : errorMsgs) { - log.warn("Plugin Error: Invalid " + resourceType.getName() + " Resource configuration returned by " - + resourceType.getPlugin() + " plugin - " + errorMessage); - } - } -} diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/ComponentService.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/ComponentService.java new file mode 100644 index 0000000..1a697eb --- /dev/null +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/ComponentService.java @@ -0,0 +1,39 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2008 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, version 2, as + * published by the Free Software Foundation, and/or the GNU Lesser + * General Public License, version 2.1, also as published by the Free + * Software Foundation. + * + * 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 and the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * and the GNU Lesser 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.core.pc.inventory; + +import org.rhq.core.domain.resource.ResourceType; +import org.rhq.core.clientapi.agent.PluginContainerException; +import org.rhq.core.pc.util.FacetLockType; + +public interface ComponentService { + + ResourceType getResourceType(int resourceId) throws PluginContainerException; + + <T> T getComponent(int resourceId, Class<T> facetInterface, FacetLockType lockType, long timeout, + boolean daemonThread, boolean onlyIfStarted) throws PluginContainerException; + + String getAmpsVersion(int resourceId); + +} diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryService.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryService.java deleted file mode 100644 index ef2a8f4..0000000 --- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryService.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2008 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, version 2, as - * published by the Free Software Foundation, and/or the GNU Lesser - * General Public License, version 2.1, also as published by the Free - * Software Foundation. - * - * 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 and the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * and the GNU Lesser 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.core.pc.inventory; - -import org.rhq.core.domain.resource.ResourceType; -import org.rhq.core.clientapi.agent.PluginContainerException; -import org.rhq.core.pc.util.FacetLockType; - -public interface InventoryService { - - ResourceType getResourceType(int resourceId) throws PluginContainerException; - - <T> T getComponent(int resourceId, Class<T> facetInterface, FacetLockType lockType, long timeout, - boolean daemonThread, boolean onlyIfStarted) throws PluginContainerException; - - String getAmpsVersion(int resourceId); - -} diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigurationManagerUnitTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigurationManagerUnitTest.java index 9bb5d68..b706ea0 100644 --- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigurationManagerUnitTest.java +++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigurationManagerUnitTest.java @@ -27,7 +27,7 @@ import org.jmock.Expectations; import org.rhq.core.clientapi.agent.PluginContainerException; import org.rhq.core.domain.configuration.Configuration; import org.rhq.core.domain.resource.ResourceType; -import org.rhq.core.pc.inventory.InventoryService; +import org.rhq.core.pc.inventory.ComponentService; import static org.testng.Assert.assertSame; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; @@ -44,31 +44,31 @@ public class ConfigurationManagerUnitTest extends JMockTest {
int resourceId = -1;
- ResourceConfigurationStrategyFactory factory; + LoadResourceConfigurationFactory loadConfigFactory;
- InventoryService componentService; + ComponentService componentService;
ConfigurationManager configurationMgr;
@BeforeMethod public void setup() { - factory = context.mock(ResourceConfigurationStrategyFactory.class); + loadConfigFactory = context.mock(LoadResourceConfigurationFactory.class);
- componentService = context.mock(InventoryService.class); + componentService = context.mock(ComponentService.class);
configurationMgr = new ConfigurationManager(); - configurationMgr.setLoadConfigStrategyFactory(factory); - configurationMgr.setInventoryService(componentService); + configurationMgr.setLoadConfigFactory(loadConfigFactory); + configurationMgr.setComponentService(componentService); }
@Test public void factoryShouldBeCalledToGetStrategy() throws Exception { - final ResourceConfigurationStrategy strategy = context.mock(ResourceConfigurationStrategy.class); + final LoadResourceConfiguration loadConfig = context.mock(LoadResourceConfiguration.class);
context.checking(new Expectations() {{ - atLeast(1).of(factory).getStrategy(resourceId); will(returnValue(strategy)); + atLeast(1).of(loadConfigFactory).getStrategy(resourceId); will(returnValue(loadConfig));
- allowing(strategy).loadConfiguration(resourceId, FROM_STRUCTURED); will(returnValue(new Configuration())); + allowing(loadConfig).execute(resourceId, FROM_STRUCTURED); will(returnValue(new Configuration())); }});
configurationMgr.loadResourceConfiguration(resourceId, true); @@ -78,28 +78,28 @@ public class ConfigurationManagerUnitTest extends JMockTest { public void strategyShouldBeCalledToLoadConfig() throws Exception { final Configuration expectedConfig = new Configuration();
- final ResourceConfigurationStrategy strategy = context.mock(ResourceConfigurationStrategy.class); + final LoadResourceConfiguration loadConfig = context.mock(LoadResourceConfiguration.class);
context.checking(new Expectations() {{ - allowing(factory).getStrategy(resourceId); will(returnValue(strategy)); + allowing(loadConfigFactory).getStrategy(resourceId); will(returnValue(loadConfig));
- atLeast(1).of(strategy).loadConfiguration(resourceId, FROM_STRUCTURED); + atLeast(1).of(loadConfig).execute(resourceId, FROM_STRUCTURED); will(returnValue(expectedConfig)); }});
Configuration actualConfig = configurationMgr.loadResourceConfiguration(resourceId, FROM_STRUCTURED);
- assertSame(actualConfig, expectedConfig, "Expected the configuration from the strategy object to be returned."); + assertSame(actualConfig, expectedConfig, "Expected the configuration from the loadConfig object to be returned."); }
@Test(expectedExceptions = {PluginContainerException.class}) public void exceptionShouldBeThrownIfConfigIsNull() throws Exception { - final ResourceConfigurationStrategy strategy = context.mock(ResourceConfigurationStrategy.class); + final LoadResourceConfiguration loadConfig = context.mock(LoadResourceConfiguration.class);
context.checking(new Expectations() {{ - allowing(factory).getStrategy(resourceId); will(returnValue(strategy)); + allowing(loadConfigFactory).getStrategy(resourceId); will(returnValue(loadConfig));
- allowing(strategy).loadConfiguration(resourceId, FROM_STRUCTURED); will(returnValue(null)); + allowing(loadConfig).execute(resourceId, FROM_STRUCTURED); will(returnValue(null));
allowing(componentService).getResourceType(resourceId); will(returnValue(new ResourceType())); }}); diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadRawTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadRawTest.java new file mode 100644 index 0000000..a8ef696 --- /dev/null +++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadRawTest.java @@ -0,0 +1,221 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2008 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, version 2, as + * published by the Free Software Foundation, and/or the GNU Lesser + * General Public License, version 2.1, also as published by the Free + * Software Foundation. + * + * 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 and the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * and the GNU Lesser 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.core.pc.configuration; + +import static org.testng.Assert.*; + +import org.rhq.core.pc.inventory.ComponentService; +import org.rhq.core.pc.util.FacetLockType; +import org.rhq.core.pluginapi.configuration.ResourceConfigurationFacet; +import org.rhq.core.domain.configuration.Configuration; +import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; +import org.rhq.core.domain.resource.ResourceType; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; +import org.jmock.Expectations; + +public class LoadRawTest extends JMockTest { + + ComponentService componentService; + + ConfigurationUtilityService configUtilityService; + + int resourceId = -1; + + boolean daemonThread = true; + + boolean onlyIfStarted = true; + + ResourceConfigurationFacet configFacet; + + LoadRaw loadRaw; + + @BeforeMethod + public void setup() { + componentService = context.mock(ComponentService.class); + configUtilityService = context.mock(ConfigurationUtilityService.class); + + configFacet = context.mock(ResourceConfigurationFacet.class); + + loadRaw = new LoadRaw(); + loadRaw.setComponentService(componentService); + loadRaw.setConfigurationUtilityService(configUtilityService); + } + + @Test + public void theResourceConfigFacetShouldGetLoaded() throws Exception { + context.checking(new Expectations() {{ + atLeast(1).of(componentService).getComponent(resourceId, + ResourceConfigurationFacet.class, + FacetLockType.READ, + LoadResourceConfiguration.FACET_METHOD_TIMEOUT, + daemonThread, + onlyIfStarted); + will(returnValue(configFacet)); + + ignoring(configFacet); + ignoring(configUtilityService); + }}); + + loadRaw.execute(resourceId, false); + } + + @Test + public void theConfigShouldGetLoadedByTheFacet() throws Exception { + context.checking(new Expectations() {{ + allowing(componentService).getComponent(resourceId, + ResourceConfigurationFacet.class, + FacetLockType.READ, + LoadResourceConfiguration.FACET_METHOD_TIMEOUT, + daemonThread, + onlyIfStarted); + will(returnValue(configFacet)); + + atLeast(1).of(configFacet).loadRawConfigurations(); + + ignoring(configUtilityService); + }}); + + loadRaw.execute(resourceId, false); + } + + @Test + public void theConfigNotesShouldGetSetIfItIsNotAlreadySet() throws Exception { + final Configuration configuration = new Configuration(); + + final ResourceType resourceType = new ResourceType(); + resourceType.setName("test resource"); + + context.checking(new Expectations() {{ + allowing(componentService).getComponent(resourceId, + ResourceConfigurationFacet.class, + FacetLockType.READ, + LoadResourceConfiguration.FACET_METHOD_TIMEOUT, + daemonThread, + onlyIfStarted); + will(returnValue(configFacet)); + + allowing(componentService).getResourceType(resourceId); will(returnValue(resourceType)); + + allowing(configFacet).loadRawConfigurations(); will(returnValue(configuration)); + + ignoring(configUtilityService); + }}); + + Configuration loadedConfig = loadRaw.execute(resourceId, false); + + String expectedNotes = "Resource config for " + resourceType.getName() + " Resource w/ id " + resourceId; + + assertEquals(loadedConfig.getNotes(), expectedNotes, "The notes property should be set to a default when it is not already initialized."); + } + + @Test + public void theConfigShouldGetNormalized() throws Exception { + final Configuration configuration = new Configuration(); + + final ResourceType resourceType = new ResourceType(); + resourceType.setResourceConfigurationDefinition(new ConfigurationDefinition("", "")); + + context.checking(new Expectations() {{ + allowing(componentService).getComponent(resourceId, + ResourceConfigurationFacet.class, + FacetLockType.READ, + LoadResourceConfiguration.FACET_METHOD_TIMEOUT, + daemonThread, + onlyIfStarted); + will(returnValue(configFacet)); + + allowing(componentService).getResourceType(resourceId); will(returnValue(resourceType)); + + allowing(configFacet).loadRawConfigurations(); will(returnValue(configuration)); + + atLeast(1).of(configUtilityService).normalizeConfiguration(configuration, resourceType.getResourceConfigurationDefinition()); + + allowing(configUtilityService).validateConfiguration(configuration, resourceType.getResourceConfigurationDefinition()); + }}); + + loadRaw.execute(resourceId, false); + } + + @Test + public void theConfigShouldGetValidated() throws Exception { + final Configuration configuration = new Configuration(); + + final ResourceType resourceType = new ResourceType(); + resourceType.setResourceConfigurationDefinition(new ConfigurationDefinition("", "")); + + context.checking(new Expectations() {{ + allowing(componentService).getComponent(resourceId, + ResourceConfigurationFacet.class, + FacetLockType.READ, + LoadResourceConfiguration.FACET_METHOD_TIMEOUT, + daemonThread, + onlyIfStarted); + will(returnValue(configFacet)); + + allowing(componentService).getResourceType(resourceId); will(returnValue(resourceType)); + + allowing(configFacet).loadRawConfigurations(); will(returnValue(configuration)); + + allowing(configUtilityService).normalizeConfiguration(configuration, resourceType.getResourceConfigurationDefinition()); + + atLeast(1).of(configUtilityService).validateConfiguration(configuration, resourceType.getResourceConfigurationDefinition()); + }}); + + loadRaw.execute(resourceId, false); + } + + @Test + public void theStrategyShouldReturnTheConfig() throws Exception { + final Configuration configuration = new Configuration(); + + final ResourceType resourceType = new ResourceType(); + resourceType.setResourceConfigurationDefinition(new ConfigurationDefinition("", "")); + + context.checking(new Expectations() {{ + allowing(componentService).getComponent(resourceId, + ResourceConfigurationFacet.class, + FacetLockType.READ, + LoadResourceConfiguration.FACET_METHOD_TIMEOUT, + daemonThread, + onlyIfStarted); + will(returnValue(configFacet)); + + allowing(componentService).getResourceType(resourceId); will(returnValue(resourceType)); + + allowing(configFacet).loadRawConfigurations(); will(returnValue(configuration)); + + ignoring(configUtilityService); + }}); + + Configuration loadedConfig = loadRaw.execute(resourceId, false); + + assertSame( + loadedConfig, + configuration, + "The loadRaw commnand should return the configuration it receives from the facet component." + ); + } + +} diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadResourceConfigurationFactoryImplTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadResourceConfigurationFactoryImplTest.java new file mode 100644 index 0000000..dd20612 --- /dev/null +++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadResourceConfigurationFactoryImplTest.java @@ -0,0 +1,272 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2008 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, version 2, as + * published by the Free Software Foundation, and/or the GNU Lesser + * General Public License, version 2.1, also as published by the Free + * Software Foundation. + * + * 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 and the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * and the GNU Lesser 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.core.pc.configuration; + +import static org.testng.Assert.*; + +import org.testng.annotations.Test; +import org.testng.annotations.BeforeMethod; +import org.rhq.core.pc.inventory.ComponentService; +import org.rhq.core.domain.resource.ResourceType; +import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; +import org.rhq.core.domain.configuration.definition.ConfigurationFormat; +import org.jmock.Expectations; + +public class LoadResourceConfigurationFactoryImplTest extends JMockTest { + + static final String LEGACY_AMPS_VERSION = "2.0"; + + static final String NON_LEGACY_AMPS_VERSION = "2.1"; + + ComponentService componentService; + + int resourceId = -1; + + LoadResourceConfigurationFactoryImpl factory; + + @BeforeMethod + public void setup() { + componentService = context.mock(ComponentService.class); + + factory = new LoadResourceConfigurationFactoryImpl(); + factory.setComponentService(componentService); + } + + @Test + public void factoryShouldReturnLegacyLoadConfigWhenAmpsVersionIsLessThan2dot1() throws Exception { + context.checking(new Expectations() {{ + allowing(componentService).getAmpsVersion(resourceId); will(returnValue(LEGACY_AMPS_VERSION)); + }}); + + LoadResourceConfiguration loadConfig = factory.getStrategy(resourceId); + + assertTrue( + loadConfig instanceof LegacyLoadConfig, + "Expected to get an instance of " + LegacyLoadConfig.class.getSimpleName() + " when the " + + "resource is from a plugin having an ampsVersion less than " + NON_LEGACY_AMPS_VERSION + ); + } + + @Test + public void factoryShouldInitializeLegacyLoadConfigWithComponentService() throws Exception { + context.checking(new Expectations() {{ + allowing(componentService).getAmpsVersion(resourceId); will(returnValue(LEGACY_AMPS_VERSION)); + }}); + + LoadResourceConfiguration loadConfig = factory.getStrategy(resourceId); + + assertComponentServiceInitialized(loadConfig); + } + + @Test + public void factoryShouldInitializeLegacyLoadConfigWithConfigurationUtilityService() throws Exception { + context.checking(new Expectations() {{ + allowing(componentService).getAmpsVersion(resourceId); will(returnValue(LEGACY_AMPS_VERSION)); + }}); + + LoadResourceConfiguration loadConfig = factory.getStrategy(resourceId); + + assertConfigurationUtilityServiceInitialized(loadConfig); + } + + @Test + public void factoryShouldReturnStructuredLoadConfigWhenAmpsVersionIs2dot1AndFormatIsStructured() throws Exception { + context.checking(new Expectations() {{ + allowing(componentService).getAmpsVersion(resourceId); will(returnValue(NON_LEGACY_AMPS_VERSION)); + + allowing(componentService).getResourceType(resourceId); + will(returnValue(createResourceTypeThatSupportsStructured())); + }}); + + LoadResourceConfiguration loadConfig = factory.getStrategy(resourceId); + + assertTrue( + loadConfig instanceof LoadStructured, + "Expected to get an instance of " + LoadStructured.class.getSimpleName() + + "when resource is from a plugin having an ampsversion >= " + NON_LEGACY_AMPS_VERSION + " and the resource " + + "configuration format is structured." + ); + } + + @Test + public void factoryShouldInitializeLoadStructuredWithComponentService() throws Exception { + context.checking(new Expectations() {{ + allowing(componentService).getAmpsVersion(resourceId); will(returnValue(NON_LEGACY_AMPS_VERSION)); + + allowing(componentService).getResourceType(resourceId); + will(returnValue(createResourceTypeThatSupportsStructured())); + }}); + + LoadResourceConfiguration loadConfig = factory.getStrategy(resourceId); + + assertComponentServiceInitialized(loadConfig); + } + + @Test + public void factoryShouldInitializeLoadStructuredWithConfigurationUtilityService() throws Exception { + context.checking(new Expectations() {{ + allowing(componentService).getAmpsVersion(resourceId); will(returnValue(NON_LEGACY_AMPS_VERSION)); + + allowing(componentService).getResourceType(resourceId); + will(returnValue(createResourceTypeThatSupportsStructured())); + }}); + + LoadResourceConfiguration loadConfig = factory.getStrategy(resourceId); + + assertConfigurationUtilityServiceInitialized(loadConfig); + } + + @Test + public void factoryShouldReturnLoadRawWhenAmpsVersionIs2dot1AndFormatIsRaw() throws Exception { + context.checking(new Expectations() {{ + allowing(componentService).getAmpsVersion(resourceId); will(returnValue(NON_LEGACY_AMPS_VERSION)); + + allowing(componentService).getResourceType(resourceId); + will(returnValue(createResourceTypeThatSupportsRaw())); + }}); + + LoadResourceConfiguration loadConfig = factory.getStrategy(resourceId); + + assertTrue( + loadConfig instanceof LoadRaw, + "Expected to get an instance of " + LoadRaw.class.getSimpleName() + " when " + + "resource is from a plugin having an ampsversion >= " + NON_LEGACY_AMPS_VERSION + " and the resource " + + "configuration format is raw." + ); + } + + @Test + public void factoryShouldInitializeLoadRawWithComponentService() throws Exception { + context.checking(new Expectations() {{ + allowing(componentService).getAmpsVersion(resourceId); will(returnValue(NON_LEGACY_AMPS_VERSION)); + + allowing(componentService).getResourceType(resourceId); + will(returnValue(createResourceTypeThatSupportsStructured())); + }}); + + LoadResourceConfiguration loadConfig = factory.getStrategy(resourceId); + + assertComponentServiceInitialized(loadConfig); + } + + @Test + public void factoryShouldInitializeLoadRawWithConfigurationUtilityService() throws Exception { + context.checking(new Expectations() {{ + allowing(componentService).getAmpsVersion(resourceId); will(returnValue(NON_LEGACY_AMPS_VERSION)); + + allowing(componentService).getResourceType(resourceId); + will(returnValue(createResourceTypeThatSupportsStructured())); + }}); + + LoadResourceConfiguration loadConfig = factory.getStrategy(resourceId); + + assertConfigurationUtilityServiceInitialized(loadConfig); + } + + @Test + public void factoryShouldReturnLoadStructuredAndRawWhenAmpsVersionIs2dot1AndFormatIsBoth() throws Exception { + context.checking(new Expectations() {{ + allowing(componentService).getAmpsVersion(resourceId); will(returnValue(NON_LEGACY_AMPS_VERSION)); + + allowing(componentService).getResourceType(resourceId); + will(returnValue(createResourceTypeThatSupportsStructuredAndRaw())); + }}); + + LoadResourceConfiguration loadConfig = factory.getStrategy(resourceId); + + assertTrue( + loadConfig instanceof LoadStructuredAndRaw, + "Expected to get an instance of" + LoadStructuredAndRaw.class.getSimpleName() + + " when resource is from a plugin having an ampsVersion >= " + NON_LEGACY_AMPS_VERSION + " and the " + + "resource configuration format is both (structured and raw)." + ); + } + + @Test + public void factoryShouldInitializeLoadStructuredAndRawWithComponentService() throws Exception { + context.checking(new Expectations() {{ + allowing(componentService).getAmpsVersion(resourceId); will(returnValue(NON_LEGACY_AMPS_VERSION)); + + allowing(componentService).getResourceType(resourceId); + will(returnValue(createResourceTypeThatSupportsStructured())); + }}); + + LoadResourceConfiguration loadConfig = factory.getStrategy(resourceId); + + assertComponentServiceInitialized(loadConfig); + } + + @Test + public void factoryShouldInitializeLoadStructuredAndRawWithConfigurationUtilityService() throws Exception { + context.checking(new Expectations() {{ + allowing(componentService).getAmpsVersion(resourceId); will(returnValue(NON_LEGACY_AMPS_VERSION)); + + allowing(componentService).getResourceType(resourceId); + will(returnValue(createResourceTypeThatSupportsStructured())); + }}); + + LoadResourceConfiguration loadConfig = factory.getStrategy(resourceId); + + assertConfigurationUtilityServiceInitialized(loadConfig); + } + + void assertComponentServiceInitialized(LoadResourceConfiguration loadConfig) { + assertNotNull(loadConfig.getComponentService(), "The factory must initialize the componentService " + + "property of the loadConfig object."); + } + + void assertConfigurationUtilityServiceInitialized(LoadResourceConfiguration loadConfig) { + assertNotNull(loadConfig.getConfigurationUtilityService(), "The factory must initialize the " + + "configurationUtilityService property of the loadConfig object."); + } + + ResourceType createResourceType() { + ResourceType resourceType = new ResourceType(); + resourceType.setResourceConfigurationDefinition(new ConfigurationDefinition("test_config", "Test Configuration")); + + return resourceType; + } + + ResourceType createResourceTypeThatSupportsStructured() { + ResourceType resourceType = createResourceType(); + resourceType.getResourceConfigurationDefinition().setConfigurationFormat(ConfigurationFormat.STRUCTURED); + + return resourceType; + } + + ResourceType createResourceTypeThatSupportsRaw() { + ResourceType resourceType = createResourceType(); + resourceType.getResourceConfigurationDefinition().setConfigurationFormat(ConfigurationFormat.RAW); + + return resourceType; + } + + ResourceType createResourceTypeThatSupportsStructuredAndRaw() { + ResourceType resourceType = createResourceType(); + resourceType.getResourceConfigurationDefinition().setConfigurationFormat(ConfigurationFormat.STRUCTURED_AND_RAW); + + return resourceType; + } + +} diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadStructuredAndRawTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadStructuredAndRawTest.java new file mode 100644 index 0000000..ea6ebbe --- /dev/null +++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadStructuredAndRawTest.java @@ -0,0 +1,336 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2008 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, version 2, as + * published by the Free Software Foundation, and/or the GNU Lesser + * General Public License, version 2.1, also as published by the Free + * Software Foundation. + * + * 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 and the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * and the GNU Lesser 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.core.pc.configuration; + +import static org.testng.Assert.*; + +import org.rhq.core.pc.inventory.ComponentService; +import org.rhq.core.pc.util.FacetLockType; +import org.rhq.core.pluginapi.configuration.ResourceConfigurationFacet; +import org.rhq.core.domain.configuration.Configuration; +import org.rhq.core.domain.configuration.RawConfiguration; +import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; +import org.rhq.core.domain.resource.ResourceType; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; +import org.jmock.Expectations; + +import java.util.Random; + +public class LoadStructuredAndRawTest extends JMockTest { + + static final boolean FROM_STRUCTURED = true; + + static final boolean FROM_RAW = false; + + ComponentService componentService; + + ConfigurationUtilityService configUtilityService; + + ResourceConfigurationFacet configFacet; + + int resourceId = -1; + + boolean daemonThread = true; + + boolean onlyIfStarted = true; + + LoadStructuredAndRaw loadStructuredAndRaw; + + Random random = new Random(); + + @BeforeMethod + public void setup() { + componentService = context.mock(ComponentService.class); + configUtilityService = context.mock(ConfigurationUtilityService.class); + + configFacet = context.mock(ResourceConfigurationFacet.class); + + loadStructuredAndRaw = new LoadStructuredAndRaw(); + loadStructuredAndRaw.setComponentService(componentService); + loadStructuredAndRaw.setConfigurationUtilityService(configUtilityService); + } + + @Test + public void theResourceConfigFacetShouldGetLoaded() throws Exception { + context.checking(new Expectations() {{ + atLeast(1).of(componentService).getComponent(resourceId, + ResourceConfigurationFacet.class, + FacetLockType.READ, + LoadResourceConfiguration.FACET_METHOD_TIMEOUT, + daemonThread, + onlyIfStarted); + will(returnValue(configFacet)); + + allowing(configFacet).loadStructuredConfiguration(); + + ignoring(configUtilityService); + }}); + + loadStructuredAndRaw.execute(resourceId, FROM_STRUCTURED); + } + + @Test + public void theStructuredConfigShouldGetLoadedWhenFromStructured() throws Exception { + context.checking(new Expectations() {{ + allowing(componentService).getComponent(resourceId, + ResourceConfigurationFacet.class, + FacetLockType.READ, + LoadResourceConfiguration.FACET_METHOD_TIMEOUT, + daemonThread, + onlyIfStarted); + will(returnValue(configFacet)); + + allowing(configFacet).loadStructuredConfiguration(); + + ignoring(configUtilityService); + }}); + + loadStructuredAndRaw.execute(resourceId, FROM_STRUCTURED); + } + + @Test + public void eachRawConfigShouldBeMergedIntoTheStructuredConfigWhenFromStructured() throws Exception { + final RawConfiguration rawConfig1 = createRawConfiguration("/tmp/foo.txt"); + final RawConfiguration rawConfig2 = createRawConfiguration("/tmp/bar.txt"); + final RawConfiguration rawConfig3 = createRawConfiguration("/tmp/bam.txt"); + + final Configuration configuration = new Configuration(); + configuration.addRawConfiguration(rawConfig1); + configuration.addRawConfiguration(rawConfig2); + configuration.addRawConfiguration(rawConfig3); + + final ResourceType resourceType = new ResourceType(); + + context.checking(new Expectations() {{ + allowing(componentService).getComponent(resourceId, + ResourceConfigurationFacet.class, + FacetLockType.READ, + LoadResourceConfiguration.FACET_METHOD_TIMEOUT, + daemonThread, + onlyIfStarted); + will(returnValue(configFacet)); + + allowing(componentService).getResourceType(resourceId); will(returnValue(resourceType)); + + atLeast(1).of(configFacet).loadStructuredConfiguration(); will(returnValue(configuration)); + + oneOf(configFacet).mergeStructuredConfiguration(rawConfig1, configuration); + oneOf(configFacet).mergeStructuredConfiguration(rawConfig2, configuration); + oneOf(configFacet).mergeStructuredConfiguration(rawConfig3, configuration); + + ignoring(configUtilityService); + }}); + + loadStructuredAndRaw.execute(resourceId, FROM_STRUCTURED); + } + + @Test + public void theRawConfigShouldGetLoadedWhenFromRaw() throws Exception { + context.checking(new Expectations() {{ + allowing(componentService).getComponent(resourceId, + ResourceConfigurationFacet.class, + FacetLockType.READ, + LoadResourceConfiguration.FACET_METHOD_TIMEOUT, + daemonThread, + onlyIfStarted); + will(returnValue(configFacet)); + + allowing(componentService).getResourceType(resourceId); will(returnValue(new ResourceType())); + + atLeast(1).of(configFacet).loadRawConfigurations(); will(returnValue(new Configuration())); + + ignoring(configUtilityService); + }}); + + loadStructuredAndRaw.execute(resourceId, FROM_RAW); + } + + @Test + public void theStructuredConfigShouldBeMergedIntoEachRawConfigWhenFromRaw() throws Exception { + final RawConfiguration rawConfig1 = createRawConfiguration("/tmp/foo.txt"); + final RawConfiguration rawConfig2 = createRawConfiguration("/tmp/bar.txt"); + final RawConfiguration rawConfig3 = createRawConfiguration("/tmp/bam.txt"); + + final Configuration configuration = new Configuration(); + configuration.addRawConfiguration(rawConfig1); + configuration.addRawConfiguration(rawConfig2); + configuration.addRawConfiguration(rawConfig3); + + context.checking(new Expectations() {{ + allowing(componentService).getComponent(resourceId, + ResourceConfigurationFacet.class, + FacetLockType.READ, + LoadResourceConfiguration.FACET_METHOD_TIMEOUT, + daemonThread, + onlyIfStarted); + will(returnValue(configFacet)); + + allowing(componentService).getResourceType(resourceId); will(returnValue(new ResourceType())); + + allowing(configFacet).loadRawConfigurations(); will(returnValue(configuration)); + + oneOf(configFacet).mergeRawConfiguration(configuration, rawConfig1); + oneOf(configFacet).mergeRawConfiguration(configuration, rawConfig2); + oneOf(configFacet).mergeRawConfiguration(configuration, rawConfig3); + + ignoring(configUtilityService); + }}); + + loadStructuredAndRaw.execute(resourceId, FROM_RAW); + } + + @Test + public void theConfigReceivedFromTheFacetShouldBeReturned() throws Exception { + final Configuration configuration = new Configuration(); + + final ResourceType resourceType = new ResourceType(); + resourceType.setResourceConfigurationDefinition(new ConfigurationDefinition("", "")); + + context.checking(new Expectations() {{ + allowing(componentService).getComponent(resourceId, + ResourceConfigurationFacet.class, + FacetLockType.READ, + LoadResourceConfiguration.FACET_METHOD_TIMEOUT, + daemonThread, + onlyIfStarted); + will(returnValue(configFacet)); + + allowing(componentService).getResourceType(resourceId); will(returnValue(resourceType)); + + allowing(configFacet).loadStructuredConfiguration(); will(returnValue(configuration)); + + ignoring(configUtilityService); + }}); + + Configuration loadedConfig = loadStructuredAndRaw.execute(resourceId, FROM_STRUCTURED); + + assertSame( + loadedConfig, + configuration, + "The loadRawConfig should return the configuration it receives from the facet component." + ); + } + + @Test + public void theConfigNotesShouldGetSetIfItIsNotAlreadySet() throws Exception { + final Configuration configuration = new Configuration(); + + final ResourceType resourceType = new ResourceType(); + resourceType.setName("test resource"); + + context.checking(new Expectations() {{ + allowing(componentService).getComponent(resourceId, + ResourceConfigurationFacet.class, + FacetLockType.READ, + LoadResourceConfiguration.FACET_METHOD_TIMEOUT, + daemonThread, + onlyIfStarted); + will(returnValue(configFacet)); + + allowing(componentService).getResourceType(resourceId); will(returnValue(resourceType)); + + allowing(configFacet).loadStructuredConfiguration(); will(returnValue(configuration)); + + ignoring(configUtilityService); + }}); + + Configuration loadedConfig = loadStructuredAndRaw.execute(resourceId, FROM_STRUCTURED); + + String expectedNotes = "Resource config for " + resourceType.getName() + " Resource w/ id " + resourceId; + + assertEquals(loadedConfig.getNotes(), expectedNotes, "The notes property should be set to a default when it is not already initialized."); + } + + @Test + public void theConfigShouldGetNormalized() throws Exception { + final Configuration configuration = new Configuration(); + + final ResourceType resourceType = new ResourceType(); + resourceType.setResourceConfigurationDefinition(new ConfigurationDefinition("", "")); + + context.checking(new Expectations() {{ + allowing(componentService).getComponent(resourceId, + ResourceConfigurationFacet.class, + FacetLockType.READ, + LoadResourceConfiguration.FACET_METHOD_TIMEOUT, + daemonThread, + onlyIfStarted); + will(returnValue(configFacet)); + + allowing(componentService).getResourceType(resourceId); will(returnValue(resourceType)); + + allowing(configFacet).loadStructuredConfiguration(); will(returnValue(configuration)); + + atLeast(1).of(configUtilityService).normalizeConfiguration(configuration, resourceType.getResourceConfigurationDefinition()); + + allowing(configUtilityService).validateConfiguration(configuration, resourceType.getResourceConfigurationDefinition()); + }}); + + loadStructuredAndRaw.execute(resourceId, FROM_STRUCTURED); + } + + @Test + public void theConfigShouldGetValidated() throws Exception { + final Configuration configuration = new Configuration(); + + final ResourceType resourceType = new ResourceType(); + resourceType.setResourceConfigurationDefinition(new ConfigurationDefinition("", "")); + + context.checking(new Expectations() {{ + allowing(componentService).getComponent(resourceId, + ResourceConfigurationFacet.class, + FacetLockType.READ, + LoadResourceConfiguration.FACET_METHOD_TIMEOUT, + daemonThread, + onlyIfStarted); + will(returnValue(configFacet)); + + allowing(componentService).getResourceType(resourceId); will(returnValue(resourceType)); + + allowing(configFacet).loadStructuredConfiguration(); will(returnValue(configuration)); + + allowing(configUtilityService).normalizeConfiguration(configuration, resourceType.getResourceConfigurationDefinition()); + + atLeast(1).of(configUtilityService).validateConfiguration(configuration, resourceType.getResourceConfigurationDefinition()); + }}); + + loadStructuredAndRaw.execute(resourceId, FROM_STRUCTURED); + } + + RawConfiguration createRawConfiguration(String path) { + RawConfiguration rawConfig = new RawConfiguration(); + rawConfig.setContents(randomBytes()); + rawConfig.setPath(path); + + return rawConfig; + } + + byte[] randomBytes() { + byte[] bytes = new byte[10]; + random.nextBytes(bytes); + + return bytes; + } +} diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadStructuredTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadStructuredTest.java new file mode 100644 index 0000000..23f3e8a --- /dev/null +++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/LoadStructuredTest.java @@ -0,0 +1,221 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2008 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, version 2, as + * published by the Free Software Foundation, and/or the GNU Lesser + * General Public License, version 2.1, also as published by the Free + * Software Foundation. + * + * 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 and the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * and the GNU Lesser 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.core.pc.configuration; + +import static org.testng.Assert.*; + +import org.rhq.core.pc.inventory.ComponentService; +import org.rhq.core.pc.util.FacetLockType; +import org.rhq.core.pluginapi.configuration.ResourceConfigurationFacet; +import org.rhq.core.domain.configuration.Configuration; +import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; +import org.rhq.core.domain.resource.ResourceType; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; +import org.jmock.Expectations; + +public class LoadStructuredTest extends JMockTest { + + ComponentService componentService; + + ConfigurationUtilityService configUtilityService; + + ResourceConfigurationFacet configFacet; + + int resourceId = -1; + + boolean daemonThread = true; + + boolean onlyIfStarted = true; + + LoadStructured loadStructured; + + @BeforeMethod + public void setup() { + componentService = context.mock(ComponentService.class); + configUtilityService = context.mock(ConfigurationUtilityService.class); + + configFacet = context.mock(ResourceConfigurationFacet.class); + + loadStructured = new LoadStructured(); + loadStructured.setComponentService(componentService); + loadStructured.setConfigurationUtilityService(configUtilityService); + } + + @Test + public void theResourceConfigFacetShouldGetLoaded() throws Exception { + context.checking(new Expectations() {{ + atLeast(1).of(componentService).getComponent(resourceId, + ResourceConfigurationFacet.class, + FacetLockType.READ, + LoadResourceConfiguration.FACET_METHOD_TIMEOUT, + daemonThread, + onlyIfStarted); + will(returnValue(configFacet)); + + ignoring(configFacet); + ignoring(configUtilityService); + }}); + + loadStructured.execute(resourceId, true); + } + + @Test + public void theConfigShouldGetLoadedByTheFacet() throws Exception { + context.checking(new Expectations() {{ + allowing(componentService).getComponent(resourceId, + ResourceConfigurationFacet.class, + FacetLockType.READ, + LoadResourceConfiguration.FACET_METHOD_TIMEOUT, + daemonThread, + onlyIfStarted); + will(returnValue(configFacet)); + + atLeast(1).of(configFacet).loadStructuredConfiguration(); + + ignoring(configUtilityService); + }}); + + loadStructured.execute(resourceId, true); + } + + @Test + public void theConfigNotesShouldGetSetIfItIsNotAlreadySet() throws Exception { + final Configuration configuration = new Configuration(); + + final ResourceType resourceType = new ResourceType(); + resourceType.setName("test resource"); + + context.checking(new Expectations() {{ + allowing(componentService).getComponent(resourceId, + ResourceConfigurationFacet.class, + FacetLockType.READ, + LoadResourceConfiguration.FACET_METHOD_TIMEOUT, + daemonThread, + onlyIfStarted); +