/** * Copyright (c) 2013--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.frontend.xmlrpc.sync.master; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import com.redhat.rhn.FaultException; import com.redhat.rhn.common.hibernate.LookupException; import com.redhat.rhn.common.localization.LocalizationService; import com.redhat.rhn.domain.iss.IssFactory; import com.redhat.rhn.domain.iss.IssMaster; import com.redhat.rhn.domain.iss.IssMasterOrg; import com.redhat.rhn.domain.org.Org; import com.redhat.rhn.domain.org.OrgFactory; import com.redhat.rhn.domain.user.User; import com.redhat.rhn.frontend.xmlrpc.BaseHandler; import com.redhat.rhn.frontend.xmlrpc.IssDuplicateMasterException; /** * MasterHandler * * @version $Rev$ * * @xmlrpc.namespace sync.master * @xmlrpc.doc Contains methods to set up information about known-"masters", for use * on the "slave" side of ISS */ public class MasterHandler extends BaseHandler { public static final String[] VALID_MASTER_ORG_ATTRS = { "masterId", "masterOrgId", "masterOrgName", "localOrgId" }; private static final Set<String> VALIDMASTERORGATTR; static { VALIDMASTERORGATTR = new HashSet<String>(Arrays.asList(VALID_MASTER_ORG_ATTRS)); } public static final String[] REQUIRED_MASTER_ORG_ATTRS = { "masterOrgId", "masterOrgName" }; private static final Set<String> REQUIREDMASTERORGATTRS; static { REQUIREDMASTERORGATTRS = new HashSet<String>(Arrays.asList(REQUIRED_MASTER_ORG_ATTRS)); } /** * Create a new Master, known to this Slave. * @param loggedInUser The current user * @param label Master's fully-qualified domain name * @return Newly created ISSMaster object. * * @xmlrpc.doc Create a new Master, known to this Slave. * @xmlrpc.param #param("string", "sessionKey") * @xmlrpc.param #param_desc("string", "label", "Master's fully-qualified domain name") * @xmlrpc.returntype $IssMasterSerializer */ public IssMaster create(User loggedInUser, String label) { ensureSatAdmin(loggedInUser); if (IssFactory.lookupMasterByLabel(label) != null) { throw new IssDuplicateMasterException(label); } IssMaster master = new IssMaster(); master.setLabel(label); IssFactory.save(master); master = (IssMaster) IssFactory.reload(master); return master; } /** * Updates the label of the specified Master * @param loggedInUser The current user * @param masterId Id of the Master to update * @param newLabel new label * @return updated IssMaster * * @xmlrpc.doc Updates the label of the specified Master * @xmlrpc.param #param("string", "sessionKey") * @xmlrpc.param #param_desc("int", "id", "Id of the Master to update") * @xmlrpc.param #param_desc("string", "label", "Desired new label") * @xmlrpc.returntype $IssMasterSerializer */ public IssMaster update(User loggedInUser, Integer masterId, String newLabel) { IssMaster master = getMaster(loggedInUser, masterId); master.setLabel(newLabel); IssFactory.save(master); return master; } /** * Removes a specified Master * * @param loggedInUser The current user * @param masterId Id of the Master to remove * @return 1 on success, exception otherwise * * @xmlrpc.doc Remove the specified Master * @xmlrpc.param #param("string", "sessionKey") * @xmlrpc.param #param_desc("int", "id", "Id of the Master to remove") * @xmlrpc.returntype #return_int_success() */ public int delete(User loggedInUser, Integer masterId) { IssMaster master = getMaster(loggedInUser, masterId); IssFactory.delete(master); return 1; } /** * Make the specified Master the default for this Slave's satellite-sync * @param loggedInUser The current user * @param masterId Id of the Master to be the default * @return 1 on success, exception otherwise * * @xmlrpc.doc Make the specified Master the default for this Slave's satellite-sync * @xmlrpc.param #param("string", "sessionKey") * @xmlrpc.param #param_desc("int", "id", "Id of the Master to make the default") * @xmlrpc.returntype #return_int_success() */ public int makeDefault(User loggedInUser, Integer masterId) { IssMaster master = getMaster(loggedInUser, masterId); master.makeDefaultMaster(); IssFactory.save(master); return 1; } /** * Return the current default-Master for this Slave * @param loggedInUser The current user * @return current default Master, null if there isn't one * * @xmlrpc.doc Return the current default-Master for this Slave * @xmlrpc.param #param("string", "sessionKey") * @xmlrpc.returntype $IssMasterSerializer */ public IssMaster getDefaultMaster(User loggedInUser) { ensureSatAdmin(loggedInUser); IssMaster dflt = IssFactory.getCurrentMaster(); validateExists(dflt, "Default Master"); return dflt; } /** * Make this slave have no default Master for satellite-sync * @param loggedInUser The current user * @return 1 on success, exception otherwise * * @xmlrpc.doc Make this slave have no default Master for satellite-sync * @xmlrpc.param #param("string", "sessionKey") * @xmlrpc.returntype #return_int_success() */ public int unsetDefaultMaster(User loggedInUser) { ensureSatAdmin(loggedInUser); IssFactory.unsetCurrentMaster(); return 1; } /** * Set the CA-CERT filename for specified Master on this Slave * @param loggedInUser The current user * @param masterId Id of the Master we're affecting * @param caCertFilename path to this Master's CA Cert on this Slave * @return 1 on success, exception otherwise * * @xmlrpc.doc Set the CA-CERT filename for specified Master on this Slave * @xmlrpc.param #param("string", "sessionKey") * @xmlrpc.param #param_desc("int", "id", "Id of the Master to affect") * @xmlrpc.param #param_desc("string", "caCertFilename", * "path to specified Master's CA cert") * @xmlrpc.returntype #return_int_success() */ public int setCaCert(User loggedInUser, Integer masterId, String caCertFilename) { IssMaster master = getMaster(loggedInUser, masterId); master.setCaCert(caCertFilename); return 1; } /** * Find a Master by specifying its ID * @param loggedInUser The current user * @param masterId Id of the Master to look for * @return the specified Master if found, exception otherwise * * @xmlrpc.doc Find a Master by specifying its ID * @xmlrpc.param #param("string", "sessionKey") * @xmlrpc.param #param_desc("int", "id", "Id of the desired Master") * @xmlrpc.returntype $IssMasterSerializer */ public IssMaster getMaster(User loggedInUser, Integer masterId) { ensureSatAdmin(loggedInUser); IssMaster master = IssFactory.lookupMasterById(masterId.longValue()); validateExists(master, masterId.toString()); return master; } /** * Find a Master by specifying its label * @param loggedInUser The current user * @param masterLabel Label of the Master to look for * @return the specified Master if found, exception otherwise * * @xmlrpc.doc Find a Master by specifying its label * @xmlrpc.param #param("string", "sessionKey") * @xmlrpc.param #param_desc("string", "label", "Label of the desired Master") * @xmlrpc.returntype $IssMasterSerializer */ public IssMaster getMasterByLabel(User loggedInUser, String masterLabel) { ensureSatAdmin(loggedInUser); IssMaster master = IssFactory.lookupMasterByLabel(masterLabel); validateExists(master, masterLabel); return master; } /** * Get all the Masters this Slave knows about * @param loggedInUser The current user * @return list of all the IssMasters we know about * * @xmlrpc.doc Get all the Masters this Slave knows about * @xmlrpc.param #param("string", "sessionKey") * @xmlrpc.returntype * #array() * $IssMasterSerializer * #array_end() */ public List<IssMaster> getMasters(User loggedInUser) { ensureSatAdmin(loggedInUser); return IssFactory.listAllMasters(); } /** * List all organizations the specified Master has exported to this Slave * * @param loggedInUser The current user * @param masterId Id of the Master to look for * @return List of MasterOrgs we know about * * @xmlrpc.doc List all organizations the specified Master has exported to this Slave * @xmlrpc.param #param("string", "sessionKey") * @xmlrpc.param #param_desc("int", "id", "Id of the desired Master") * @xmlrpc.returntype * #array() * $IssMasterOrgSerializer * #array_end() */ public List<IssMasterOrg> getMasterOrgs(User loggedInUser, Integer masterId) { IssMaster master = getMaster(loggedInUser, masterId); ArrayList<IssMasterOrg> orgs = new ArrayList<IssMasterOrg>(); orgs.addAll(master.getMasterOrgs()); return orgs; } /** * Reset all organizations the specified Master has exported to this Slave * * @param loggedInUser The current user * @param masterId Id of the Master to look for * @param orgMaps List of MasterOrgs we know about * @return 1 if successful, exception otherwise * * @xmlrpc.doc Reset all organizations the specified Master has exported to this Slave * @xmlrpc.param #param("string", "sessionKey") * @xmlrpc.param #param_desc("int", "id", "Id of the desired Master") * @xmlrpc.param * #array() * #struct("master-org details") * #prop("int", "masterOrgId") * #prop("string", "masterOrgName") * #prop("int", "localOrgId") * #struct_end() * #array_end() * @xmlrpc.returntype #return_int_success() */ public int setMasterOrgs(User loggedInUser, Integer masterId, List<Map<String, Object>> orgMaps) { IssMaster master = getMaster(loggedInUser, masterId); Set<IssMasterOrg> orgs = new HashSet<IssMasterOrg>(); for (Map<String, Object> anOrgMap : orgMaps) { IssMasterOrg o = validateOrg(anOrgMap); orgs.add(o); } master.resetMasterOrgs(orgs); return 1; } /** * Add a single organizations to the list of those the specified Master has * exported to this Slave * * @param loggedInUser The current user * @param masterId Id of the Master to look for * @param newOrg new master-organization to add * @return 1 if success, exception otherwise * * @xmlrpc.doc Add a single organizations to the list of those the specified Master has * exported to this Slave * @xmlrpc.param #param("string", "sessionKey") * @xmlrpc.param #param_desc("int", "id", "Id of the desired Master") * @xmlrpc.param * #struct("master-org details") * #prop("int", "masterOrgId") * #prop("string", "masterOrgName") * #prop("int", "localOrgId") * #struct_end() * @xmlrpc.returntype #return_int_success() * */ public int addToMaster(User loggedInUser, Integer masterId, Map<String, Object> newOrg) { IssMaster master = getMaster(loggedInUser, masterId); IssMasterOrg org = validateOrg(newOrg); master.addToMaster(org); return 1; } /** * Map a given master-organization to a specific local-organization * * @param loggedInUser The current user * @param masterId Id of the Master to look for * @param masterOrgId id of the master-organization to work with * @param localOrgId id of the local organization to map to masterOrgId * @return 1 if success, exception otherwise * * @xmlrpc.doc Add a single organizations to the list of those the specified Master has * exported to this Slave * @xmlrpc.param #param("string", "sessionKey") * @xmlrpc.param #param_desc("int", "masterId", "Id of the desired Master") * @xmlrpc.param #param_desc("int", "masterOrgId", "Id of the desired Master") * @xmlrpc.param #param_desc("int", "localOrgId", "Id of the desired Master") * @xmlrpc.returntype #return_int_success() * */ public int mapToLocal(User loggedInUser, Integer masterId, Integer masterOrgId, Integer localOrgId) { boolean found = false; IssMaster master = getMaster(loggedInUser, masterId); Set<IssMasterOrg> orgs = master.getMasterOrgs(); Org localOrg = OrgFactory.lookupById(localOrgId.longValue()); if (localOrg == null) { fail("Unable to locate or access Local Organization :" + localOrgId, "lookup.issmaster.local.title", "lookup.issmaster.local.reason1", localOrgId.toString()); } for (IssMasterOrg o : orgs) { if (o.getMasterOrgId().equals(masterOrgId.longValue())) { o.setLocalOrg(localOrg); found = true; break; } } if (!found) { fail("Unable to locate or access ISS Master Organization : " + masterOrgId, "lookup.issmasterorg.title", "lookup.issmasterorg.reason1", masterOrgId.toString()); } IssFactory.save(master); return 1; } private static Set<String> getValidMasterOrgsAttrs() { return VALIDMASTERORGATTR; } private static Set<String> getRequiredMasterOrgsAttrs() { return REQUIREDMASTERORGATTRS; } private IssMasterOrg validateOrg(Map<String, Object> anOrg) { validateMap(getValidMasterOrgsAttrs(), anOrg); Set<String> attrs = anOrg.keySet(); if (!attrs.containsAll(getRequiredMasterOrgsAttrs())) { throw new FaultException(-6, "requiredOptionMissing", "Required option missing. List of required options: " + REQUIREDMASTERORGATTRS); } IssMasterOrg o = new IssMasterOrg(); for (String attr : attrs) { if ("localOrgId".equals(attr)) { Integer localId = (Integer)anOrg.get(attr); Org local = OrgFactory.lookupById(localId.longValue()); o.setLocalOrg(local); } else if ("masterOrgId".equals(attr)) { Integer moId = (Integer)anOrg.get(attr); o.setMasterOrgId(moId.longValue()); } else { setEntityAttribute(attr, o, anOrg.get(attr)); } } return o; } private void validateExists(IssMaster master, String srchString) { if (master == null) { fail("Unable to locate or access ISS Master : " + srchString, "lookup.issmaster.title", "lookup.issmaster.reason1", srchString); } } private void fail(String msg, String titleKey, String reasonKey, String arg) { LocalizationService ls = LocalizationService.getInstance(); LookupException e = new LookupException(msg); e.setLocalizedTitle(ls.getMessage(titleKey)); e.setLocalizedReason1(ls.getMessage(reasonKey, arg)); throw e; } }