java/code/src/com/redhat/rhn/common/db/datasource/xml/Action_queries.xml | 11 java/code/src/com/redhat/rhn/domain/server/ServerFactory.java | 24 ++ java/code/src/com/redhat/rhn/domain/server/Server_legacyUser.hbm.xml | 41 ++- java/code/src/com/redhat/rhn/frontend/events/SsmInstallPackagesAction.java | 41 +-- java/code/src/com/redhat/rhn/frontend/events/SsmRemovePackagesAction.java | 36 +-- java/code/src/com/redhat/rhn/frontend/events/SsmUpgradePackagesAction.java | 21 - java/code/src/com/redhat/rhn/manager/action/ActionManager.java | 117 +++++----- 7 files changed, 174 insertions(+), 117 deletions(-)
New commits: commit 98bc6fc9f6dd8d5c41f734e77a100bdf1197505f Author: Justin Sherrill jsherril@redhat.com Date: Mon Sep 28 20:23:18 2009 -0400
525549 - fixing issue where SSM package operations would run out of memory
diff --git a/java/code/src/com/redhat/rhn/common/db/datasource/xml/Action_queries.xml b/java/code/src/com/redhat/rhn/common/db/datasource/xml/Action_queries.xml index 32e63d1..1fbb305 100644 --- a/java/code/src/com/redhat/rhn/common/db/datasource/xml/Action_queries.xml +++ b/java/code/src/com/redhat/rhn/common/db/datasource/xml/Action_queries.xml @@ -294,4 +294,15 @@ SELECT 1 </query> </mode>
+<write-mode name="insert_server_actions"> + <query params="parent_id, status_id, tries"> +INSERT INTO rhnServerAction (server_id, action_id, status, REMAINING_TRIES) + select s.id as server_id, :parent_id as action_id, + :status_id as status, :tries as REMAINING_TRIES + from rhnServer s + where s.id in (%s) + </query> +</write-mode> + + </datasource_modes> diff --git a/java/code/src/com/redhat/rhn/domain/server/ServerFactory.java b/java/code/src/com/redhat/rhn/domain/server/ServerFactory.java index 28e62c6..1b40a33 100644 --- a/java/code/src/com/redhat/rhn/domain/server/ServerFactory.java +++ b/java/code/src/com/redhat/rhn/domain/server/ServerFactory.java @@ -38,6 +38,7 @@ import org.hibernate.Session;
import java.sql.Types; import java.util.ArrayList; +import java.util.Collection; import java.util.Date; import java.util.HashMap; import java.util.Iterator; @@ -739,4 +740,27 @@ public class ServerFactory extends HibernateFactory { "ServerSnapshot.findTags", params); return snaps; } + + /** + * Filter out a list of systemIds with ones that are solaris systems + * @param systemIds list of system ids + * @return list of system ids that are solaris systems + */ + public static List<Long> listSolarisSystems(Collection<Long> systemIds) { + return ServerFactory.getSession().getNamedQuery("Server.listSolarisSystems"). + setParameterList("sids", systemIds).list(); + } + + /** + * Filter out a list of systemIds with ones that are linux systems + * (i.e. not solaris systems) + * @param systemIds list of system ids + * @return list of system ids that are linux systems + */ + public static List<Long> listLinuxSystems(Collection<Long> systemIds) { + return ServerFactory.getSession().getNamedQuery("Server.listRedHatSystems"). + setParameterList("sids", systemIds).list(); + + } + } diff --git a/java/code/src/com/redhat/rhn/domain/server/Server_legacyUser.hbm.xml b/java/code/src/com/redhat/rhn/domain/server/Server_legacyUser.hbm.xml index 2c833df..1fe9135 100644 --- a/java/code/src/com/redhat/rhn/domain/server/Server_legacyUser.hbm.xml +++ b/java/code/src/com/redhat/rhn/domain/server/Server_legacyUser.hbm.xml @@ -89,36 +89,36 @@ PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" </set>
<many-to-one name="org" class="com.redhat.rhn.domain.org.OrgImpl" - column="org_id"/> + column="org_id" lazy="proxy"/>
<many-to-one name="creator" class="com.redhat.rhn.domain.user.legacy.LegacyRhnUserImpl" - column="creator_id"/> + column="creator_id" lazy="proxy"/>
<many-to-one name="serverArch" class="com.redhat.rhn.domain.server.ServerArch" - column="server_arch_id"/> + column="server_arch_id" lazy="proxy"/>
<many-to-one name="provisionState" class="com.redhat.rhn.domain.common.ProvisionState" - column="provision_state_id" cascade="save-update"/> + column="provision_state_id" cascade="save-update" lazy="proxy"/>
<one-to-one name="serverInfo" - class="com.redhat.rhn.domain.server.ServerInfo" cascade="all"/> + class="com.redhat.rhn.domain.server.ServerInfo" cascade="all" lazy="proxy"/>
<one-to-one name="cpu" class="com.redhat.rhn.domain.server.CPU" - property-ref="server" cascade="all"/> + property-ref="server" cascade="all" lazy="proxy"/>
<one-to-one name="lock" class="com.redhat.rhn.domain.server.ServerLock" - cascade="all"/> + cascade="all" lazy="proxy"/>
<one-to-one name="serverUuid" class="com.redhat.rhn.domain.server.ServerUuid" - cascade="all"/> + cascade="all" lazy="proxy"/>
<one-to-one name="proxyInfo" class="com.redhat.rhn.domain.server.ProxyInfo" - cascade="all"/> + cascade="all" lazy="proxy"/>
<one-to-one name="pushClient" class="com.redhat.rhn.domain.server.PushClient" - property-ref="server" /> + property-ref="server" lazy="proxy" />
<!-- we want to access the ram object via the field directly. @@ -127,16 +127,16 @@ PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" create a RAM object on a server. --> <one-to-one name="ram" class="com.redhat.rhn.domain.server.Ram" - property-ref="server" cascade="all" access="field"/> + property-ref="server" cascade="all" access="field" lazy="proxy"/> <one-to-one name="dmi" class="com.redhat.rhn.domain.server.Dmi" - property-ref="server" cascade="all"/> + property-ref="server" cascade="all" lazy="proxy"/> <one-to-one name="location" class="com.redhat.rhn.domain.server.Location" - property-ref="server" cascade="all"/> + property-ref="server" cascade="all" lazy="proxy" />
<one-to-one name="virtualInstance" class="com.redhat.rhn.domain.server.VirtualInstance" property-ref="guestSystem" - cascade="save-update"/> + cascade="save-update" lazy="proxy"/>
<set name="history" cascade="all" lazy="true" inverse="true"> <key column="server_id"/> @@ -179,6 +179,19 @@ PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" <query name="Server.findByIdsAndOrgId"> <![CDATA[from com.redhat.rhn.domain.server.Server as s where ORG_ID = :orgId and s.id in (:serverIds)]]> </query> + + <query name="Server.listRedHatSystems"> + <![CDATA[ select s.id + from com.redhat.rhn.domain.server.Server as s + where s.id in (:sids) and s.serverArch.archType.label != 'sysv-solaris']]> + </query> + + <query name="Server.listSolarisSystems"> + <![CDATA[ select s.id + from com.redhat.rhn.domain.server.Server as s + where s.id in (:sids) and s.serverArch.archType.label = 'sysv-solaris']]> + </query> +
<sql-query name="Server.findVirtPlatformHostsByOrg"> <![CDATA[select s.id as id, s.name as name, count(vi.id) as count diff --git a/java/code/src/com/redhat/rhn/frontend/events/SsmInstallPackagesAction.java b/java/code/src/com/redhat/rhn/frontend/events/SsmInstallPackagesAction.java index 77c4024..09441fc 100644 --- a/java/code/src/com/redhat/rhn/frontend/events/SsmInstallPackagesAction.java +++ b/java/code/src/com/redhat/rhn/frontend/events/SsmInstallPackagesAction.java @@ -14,28 +14,27 @@ */ package com.redhat.rhn.frontend.events;
+import com.redhat.rhn.common.localization.LocalizationService; +import com.redhat.rhn.common.messaging.EventMessage; +import com.redhat.rhn.domain.user.User; import com.redhat.rhn.domain.user.UserFactory; +import com.redhat.rhn.frontend.action.SetLabels; +import com.redhat.rhn.frontend.dto.EssentialServerDto; +import com.redhat.rhn.frontend.dto.PackageListItem; +import com.redhat.rhn.manager.action.ActionManager; +import com.redhat.rhn.manager.rhnset.RhnSetDecl; +import com.redhat.rhn.manager.ssm.SsmOperationManager; +import com.redhat.rhn.manager.system.SystemManager; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory;
-import java.util.Set; -import java.util.List; import java.util.ArrayList; -import java.util.Map; import java.util.Date; import java.util.LinkedList; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import com.redhat.rhn.common.messaging.EventMessage; -import com.redhat.rhn.common.localization.LocalizationService; -import com.redhat.rhn.manager.ssm.SsmOperationManager; -import com.redhat.rhn.manager.action.ActionManager; -import com.redhat.rhn.manager.rhnset.RhnSetDecl; -import com.redhat.rhn.manager.system.SystemManager; -import com.redhat.rhn.domain.user.User; -import com.redhat.rhn.domain.server.Server; -import com.redhat.rhn.domain.server.ServerFactory; -import com.redhat.rhn.frontend.dto.PackageListItem; -import com.redhat.rhn.frontend.dto.EssentialServerDto; -import com.redhat.rhn.frontend.action.SetLabels; +import java.util.List; +import java.util.Map; +import java.util.Set;
/** * Schedules package installations on systems in the SSM. @@ -92,17 +91,13 @@ public class SsmInstallPackagesAction extends AbstractDatabaseAction { PackageListItem.toKeyMaps(packageListItems);
// Create one action for all servers to which the packages are installed - List<Server> actionServers = new ArrayList<Server>(servers.size()); List<Long> serverIds = new LinkedList<Long>(); for (EssentialServerDto dto : servers) { serverIds.add(dto.getId()); } - log.debug("Looking up server objects."); - actionServers.addAll(ServerFactory.lookupByIdsAndUser(serverIds, user)); - log.debug("Scheduling actions.");
- - ActionManager.schedulePackageInstall(user, actionServers, + log.debug("Scheduling actions."); + ActionManager.schedulePackageInstall(user, serverIds, packageListData, earliest); log.debug("Done scheduling package installations.");
diff --git a/java/code/src/com/redhat/rhn/frontend/events/SsmRemovePackagesAction.java b/java/code/src/com/redhat/rhn/frontend/events/SsmRemovePackagesAction.java index 55ee1dc..ee3fafa 100644 --- a/java/code/src/com/redhat/rhn/frontend/events/SsmRemovePackagesAction.java +++ b/java/code/src/com/redhat/rhn/frontend/events/SsmRemovePackagesAction.java @@ -14,26 +14,25 @@ */ package com.redhat.rhn.frontend.events;
-import java.util.ArrayList; -import java.util.Date; -import java.util.HashSet; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Set; -import org.apache.log4j.Logger; import com.redhat.rhn.common.db.datasource.DataResult; import com.redhat.rhn.common.localization.LocalizationService; import com.redhat.rhn.common.messaging.EventMessage; -import com.redhat.rhn.domain.server.Server; -import com.redhat.rhn.domain.server.ServerFactory; import com.redhat.rhn.domain.user.User; import com.redhat.rhn.domain.user.UserFactory; import com.redhat.rhn.frontend.dto.PackageListItem; import com.redhat.rhn.manager.action.ActionManager; -import com.redhat.rhn.manager.ssm.SsmOperationManager; import com.redhat.rhn.manager.rhnset.RhnSetDecl; +import com.redhat.rhn.manager.ssm.SsmOperationManager; + +import org.apache.log4j.Logger; + +import java.util.ArrayList; +import java.util.Date; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set;
/** * Handles removing packages from servers in the SSM. @@ -91,8 +90,8 @@ public class SsmRemovePackagesAction extends AbstractDatabaseAction { // total of all packages selected Set<PackageListItem> allPackages = new HashSet<PackageListItem>();
- // Looking up all the server objects in Hibernate was *brutally* slow here: - List<Long> allServerIds = new LinkedList<Long>(); + + Set<Long> allServerIds = new HashSet<Long>();
// Iterate the data, which is essentially each unique package/server combination // to remove. Note that this is only for servers that we have marked as having the @@ -118,16 +117,17 @@ public class SsmRemovePackagesAction extends AbstractDatabaseAction { } }
- List<Server> allServers = new ArrayList<Server>(result.size()); - allServers.addAll(ServerFactory.lookupByIdsAndUser(allServerIds, user));
log.debug("Converting data to maps."); - List<PackageListItem> allPackagesList = new ArrayList<PackageListItem>(allPackages); + List<PackageListItem> allPackagesList = + new ArrayList<PackageListItem>(allPackages); List<Map<String, Long>> packageListData = PackageListItem.toKeyMaps(allPackagesList);
log.debug("Scheduling package removals."); - ActionManager.schedulePackageRemoval(user, allServers, packageListData, earliest); + ActionManager.schedulePackageRemoval(user, allServerIds, + packageListData, earliest); + log.debug("Done."); }
diff --git a/java/code/src/com/redhat/rhn/frontend/events/SsmUpgradePackagesAction.java b/java/code/src/com/redhat/rhn/frontend/events/SsmUpgradePackagesAction.java index 5647b81..af22b5b 100644 --- a/java/code/src/com/redhat/rhn/frontend/events/SsmUpgradePackagesAction.java +++ b/java/code/src/com/redhat/rhn/frontend/events/SsmUpgradePackagesAction.java @@ -14,22 +14,22 @@ */ package com.redhat.rhn.frontend.events;
-import java.util.ArrayList; -import java.util.Date; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import org.apache.log4j.Logger; import com.redhat.rhn.common.db.datasource.DataResult; import com.redhat.rhn.common.localization.LocalizationService; import com.redhat.rhn.common.messaging.EventMessage; -import com.redhat.rhn.domain.server.Server; -import com.redhat.rhn.domain.server.ServerFactory; import com.redhat.rhn.domain.user.User; import com.redhat.rhn.domain.user.UserFactory; import com.redhat.rhn.manager.action.ActionManager; -import com.redhat.rhn.manager.ssm.SsmOperationManager; import com.redhat.rhn.manager.rhnset.RhnSetDecl; +import com.redhat.rhn.manager.ssm.SsmOperationManager; + +import org.apache.log4j.Logger; + +import java.util.ArrayList; +import java.util.Date; +import java.util.Iterator; +import java.util.List; +import java.util.Map;
/** * Handles removing packages from servers in the SSM. @@ -103,8 +103,7 @@ public class SsmUpgradePackagesAction extends AbstractDatabaseAction { serverIds.add(serverId); }
- List<Server> serverList = ServerFactory.lookupByIdsAndUser(serverIds, user); - ActionManager.schedulePackageUpgrades(user, serverList, packageListItems, earliest); + ActionManager.schedulePackageUpgrades(user, serverIds, packageListItems, earliest);
if (log.isDebugEnabled()) { log.debug("Time to schedule all actions: " + diff --git a/java/code/src/com/redhat/rhn/manager/action/ActionManager.java b/java/code/src/com/redhat/rhn/manager/action/ActionManager.java index b98c1a2..ee8268f 100644 --- a/java/code/src/com/redhat/rhn/manager/action/ActionManager.java +++ b/java/code/src/com/redhat/rhn/manager/action/ActionManager.java @@ -54,6 +54,7 @@ import com.redhat.rhn.domain.rhnpackage.PatchSet; import com.redhat.rhn.domain.rhnset.RhnSet; import com.redhat.rhn.domain.rhnset.RhnSetElement; import com.redhat.rhn.domain.server.Server; +import com.redhat.rhn.domain.server.ServerFactory; import com.redhat.rhn.domain.user.User; import com.redhat.rhn.frontend.dto.PackageMetadata; import com.redhat.rhn.frontend.listview.PageControl; @@ -1103,41 +1104,32 @@ public class ActionManager extends BaseManager { * Schedules one or more package removal actions on one or more servers. * * @param scheduler user scheduling the action. - * @param servers servers from which to remove the packages + * @param serverIds servers from which to remove the packages * @param pkgs list of packages to be removed. * @param earliestAction date of earliest action to be executed */ public static void schedulePackageRemoval(User scheduler, - List<Server> servers, List<Map<String, Long>> pkgs, Date earliestAction) { + Collection<Long> serverIds, List<Map<String, Long>> pkgs, Date earliestAction) {
// Different handling for package removal on solaris v. rhel, so split out // the servers first in case the list is mixed. - List<Server> rhelServers = new ArrayList<Server>(); - List<Server> solarisServers = new ArrayList<Server>(); - - for (Server server : servers) { - if (server.isSolaris()) { - solarisServers.add(server); - } - else { - rhelServers.add(server); - } - } + Set<Long> rhelServers = new HashSet<Long>(); + rhelServers.addAll(ServerFactory.listLinuxSystems(serverIds)); + Set<Long> solarisServers = new HashSet<Long>(); + solarisServers.addAll(ServerFactory.listSolarisSystems(serverIds));
// Since the solaris v. rhel distinction results in a different action type, // we'll end up with 2 actions created if the server list is mixed if (!rhelServers.isEmpty()) { - Server[] s = rhelServers.toArray(new Server[rhelServers.size()]); schedulePackageAction(scheduler, pkgs, ActionFactory.TYPE_PACKAGES_REMOVE, - earliestAction, s); + earliestAction, rhelServers); }
if (!solarisServers.isEmpty()) { - Server[] s = solarisServers.toArray(new Server[solarisServers.size()]); schedulePackageAction(scheduler, pkgs, ActionFactory.TYPE_SOLARISPKGS_REMOVE, - earliestAction, s); + earliestAction, solarisServers); } - } + }
/** * Schedules one or more package upgrade actions for the given server. @@ -1157,13 +1149,13 @@ public class ActionManager extends BaseManager { * Schedules one or more package upgrade actions for the given servers. * Note: package upgrade = package install * @param scheduler User scheduling the action. - * @param srvr list of servers on which the action affects. + * @param sids list of server ids on which the action affects. * @param pkgs The set of packages to be removed. * @param earliestAction Date of earliest action to be executed */ public static void schedulePackageUpgrades(User scheduler, - List<Server> srvr, List<Map<String, Long>> pkgs, Date earliestAction) { - schedulePackageInstall(scheduler, srvr, pkgs, earliestAction); + List<Long> sids, List<Map<String, Long>> pkgs, Date earliestAction) { + schedulePackageInstall(scheduler, sids, pkgs, earliestAction); }
/** @@ -1203,39 +1195,30 @@ public class ActionManager extends BaseManager { /** * Schedules one or more package installation actions on one or more servers. * @param scheduler user scheduling the action. - * @param servers servers for which the packages should be installed + * @param serverIds server ids for which the packages should be installed * @param pkgs set of packages to be removed. * @param earliestAction date of earliest action to be executed */ public static void schedulePackageInstall(User scheduler, - List<Server> servers, List pkgs, Date earliestAction) { + Collection<Long> serverIds, List pkgs, Date earliestAction) {
// Different handling for package installs on solaris v. rhel, so split out // the servers first in case the list is mixed. - List<Server> rhelServers = new ArrayList<Server>(); - List<Server> solarisServers = new ArrayList<Server>(); - - for (Server server : servers) { - if (server.isSolaris()) { - solarisServers.add(server); - } - else { - rhelServers.add(server); - } - } + Set<Long> rhelServers = new HashSet<Long>(); + rhelServers.addAll(ServerFactory.listLinuxSystems(serverIds)); + Set<Long> solarisServers = new HashSet<Long>(); + solarisServers.addAll(ServerFactory.listSolarisSystems(serverIds));
// Since the solaris v. rhel distinction results in a different action type, // we'll end up with 2 actions created if the server list is mixed if (!rhelServers.isEmpty()) { - Server[] s = rhelServers.toArray(new Server[rhelServers.size()]); schedulePackageAction(scheduler, pkgs, ActionFactory.TYPE_PACKAGES_UPDATE, - earliestAction, s); + earliestAction, rhelServers); }
if (!solarisServers.isEmpty()) { - Server[] s = solarisServers.toArray(new Server[solarisServers.size()]); schedulePackageAction(scheduler, pkgs, ActionFactory.TYPE_SOLARISPKGS_INSTALL, - earliestAction, s); + earliestAction, solarisServers); }
} @@ -1285,8 +1268,7 @@ public class ActionManager extends BaseManager { public static PackageAction schedulePackageVerify(User scheduler, Server srvr, List<Map<String, Long>> pkgs, Date earliest) { return (PackageAction) schedulePackageAction(scheduler, pkgs, - ActionFactory.TYPE_PACKAGES_VERIFY, earliest, srvr - ); + ActionFactory.TYPE_PACKAGES_VERIFY, earliest, srvr); } /** * Schedules one or more package installation actions for the given server. @@ -1334,19 +1316,28 @@ public class ActionManager extends BaseManager { }
private static Action scheduleAction(User scheduler, ActionType type, String name, - Date earliestAction, Server... servers) { + Date earliestAction, Set<Long> serverIds) {
Action action = createScheduledAction(scheduler, type, name, earliestAction); + ActionFactory.save(action);
- for (Server server : servers) { - ServerAction sa = new ServerAction(); - sa.setStatus(ActionFactory.STATUS_QUEUED); - sa.setRemainingTries(REMAINING_TRIES); - sa.setServer(server); + action = (Action) ActionFactory.reload(action); + + + Map params = new HashMap(); + params.put("status_id", ActionFactory.STATUS_QUEUED.getId()); + params.put("tries", REMAINING_TRIES); + params.put("parent_id", action.getId()); + //params.put("sid", sid); + + WriteMode m = ModeFactory.getWriteMode("Action_queries", + "insert_server_actions"); + List<Long> sidList = new ArrayList<Long>(); + sidList.addAll(serverIds); + m.executeUpdate(params, sidList);
- action.addServerAction(sa); - sa.setParentAction(action); - } + + //action.addServerAction(sa);
return action; } @@ -1612,10 +1603,34 @@ public class ActionManager extends BaseManager { * @return The action that has been scheduled. */ public static Action schedulePackageAction(User scheduler, + List pkgs, + ActionType type, + Date earliestAction, + Server...servers) { + Set<Long> serverIds = new HashSet<Long>(); + for (Server s : servers) { + serverIds.add(s.getId()); + } + return schedulePackageAction(scheduler, pkgs, type, earliestAction, serverIds); + } + + /** + * Schedules a package action of the given type for the given server with the + * packages given as a list. + * @param scheduler The user scheduling the action. + * @param pkgs A list of maps containing keys 'name_id', 'evr_id' and + * optional 'arch_id' with Long values. + * @param type The type of the package action. One of the static types found in + * ActionFactory + * @param earliestAction The earliest time that this action could happen. + * @param serverIds The server ids that this action is for. + * @return The action that has been scheduled. + */ + public static Action schedulePackageAction(User scheduler, List pkgs, ActionType type, Date earliestAction, - Server... servers) { + Set<Long> serverIds) {
String name = ""; if (type.equals(ActionFactory.TYPE_PACKAGES_REMOVE) || @@ -1633,7 +1648,7 @@ public class ActionManager extends BaseManager { name = "Package Synchronization"; }
- Action action = scheduleAction(scheduler, type, name, earliestAction, servers); + Action action = scheduleAction(scheduler, type, name, earliestAction, serverIds); ActionFactory.save(action);
if (pkgs != null) {