/** * Copyright (c) 2009--2014 Red Hat, Inc. * * This software is licensed to you under the GNU General Public License, * version 2 (GPLv2). There is NO WARRANTY for this software, express or * implied, including the implied warranties of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2 * along with this software; if not, see * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. * * Red Hat trademarks are not licensed under GPLv2. No permission is * granted to use or replicate Red Hat trademarks that are incorporated * in this software or its documentation. */ package com.redhat.rhn.manager.system; import com.redhat.rhn.FaultException; import com.redhat.rhn.common.hibernate.LookupException; import com.redhat.rhn.common.security.PermissionException; import com.redhat.rhn.common.validator.ValidatorError; import com.redhat.rhn.domain.channel.Channel; import com.redhat.rhn.domain.channel.ChannelFactory; import com.redhat.rhn.domain.server.Server; import com.redhat.rhn.domain.user.User; import com.redhat.rhn.frontend.xmlrpc.ChannelSubscriptionException; import com.redhat.rhn.frontend.xmlrpc.InvalidChannelException; import com.redhat.rhn.frontend.xmlrpc.PermissionCheckFailureException; import com.redhat.rhn.manager.channel.ChannelManager; import org.apache.log4j.Logger; import java.util.ArrayList; import java.util.Set; import java.util.List; /** * UpdateChildChannelsCommand - this will *NOT* remove Proxy or Satellite child channel * subscriptions. * @version $Rev$ */ public class UpdateChildChannelsCommand extends BaseUpdateChannelCommand { /** * Logger for this class */ private static Logger log = Logger.getLogger(UpdateChildChannelsCommand.class); private List<Long> cids; private Server server; /** * Constructor * @param userIn making the call * @param s server to update * @param channelIdsIn List of Long channel ids */ public UpdateChildChannelsCommand(User userIn, Server s, List <Long> channelIdsIn) { this.cids = channelIdsIn; this.user = userIn; this.server = s; } /** * {@inheritDoc} */ public ValidatorError store() { List<Long> remove = new ArrayList<Long>(); /* * Loop through the server channels and take any channels the server is already * subscribed to out of the cids list. Also, keep track of any we will have to * unsubscribe from in the remove list. */ for (Channel c : server.getChannels()) { if (cids.contains(c.getId())) { // already subscribed cids.remove(c.getId()); } else if (!c.isProxy() && !c.isSatellite() && !c.isBaseChannel()) { // Don't remove base channels, satellite or proxy subscriptions // need to unsubscribe since it is not in cids remove.add(c.getId()); } } // Check whether channelsIds are childs of the current base if the system has a base if (server.getBaseChannel() != null) { Set<Long> subscribableChannelIds = SystemManager.subscribableChannelIds( server.getId(), user.getId(), server.getBaseChannel().getId()); for (Long channelId : cids) { if (!subscribableChannelIds.contains(channelId)) { Channel channel = ChannelFactory.lookupById(channelId); if (channel == null) { throw new InvalidChannelException(); } throw new ChannelSubscriptionException(channel.getLabel()); } } } //Subscribe to new channels log.debug("subscribing to new channels"); boolean failedChannels = subscribeToNewChannels(user, cids, server); //Unsubscribe from any channels in remove log.debug("unsubscribing from other channels"); unsubscribeFromOldChannels(user, remove, server); super.store(); if (failedChannels) { return new ValidatorError("sdc.channels.edit.failed_channels"); } return null; } private static boolean subscribeToNewChannels(User loggedInUser, List<Long> channelIds, Server serverIn) throws FaultException { boolean failedChannels = false; /* * Loop through the list of new channel ids for the server. Make sure each one is * a valid child channel (parentChannel == null) and subscribe the server to the * channel. */ for (Long cid : channelIds) { Channel channel = null; try { channel = ChannelManager.lookupByIdAndUser(cid, loggedInUser); } catch (LookupException e) { //convert to FaultException throw new InvalidChannelException(); } // Make sure we have a valid child channel if (channel.isBaseChannel()) { throw new InvalidChannelException(); } if (log.isDebugEnabled()) { log.debug("checking to see if we can sub: " + channel.getLabel()); } // do quick unsubscribe + quick subscribe... I don't know why we do the // unsubscribe first... It is what the perl code does though. try { log.debug("unsub from channel to be sure"); SystemManager.unsubscribeServerFromChannel(loggedInUser, serverIn, channel); log.debug("Sub to channel."); SystemManager.subscribeServerToChannel(loggedInUser, serverIn, channel, false); } catch (IncompatibleArchException iae) { throw new InvalidChannelException(iae); } catch (PermissionException e) { //convert to FaultException throw new PermissionCheckFailureException(); } } return failedChannels; } private static void unsubscribeFromOldChannels(User loggedInUser, List<Long> remove, Server serverIn) throws FaultException { /* * Loop through the list of cids to remove and unsubscribe the server from the * channel. Make sure we don't do anything to the base channel. */ for (Long cid : remove) { Channel channel = null; try { channel = ChannelManager.lookupByIdAndUser(cid, loggedInUser); } catch (LookupException e) { throw new InvalidChannelException(); } // unsubscribe from channel try { SystemManager.unsubscribeServerFromChannel(loggedInUser, serverIn, channel); } catch (PermissionException e) { //convert to FaultException throw new PermissionCheckFailureException(); } } } }