/**
* 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.taskomatic;
import com.redhat.rhn.common.conf.ConfigDefaults;
import com.redhat.rhn.common.security.PermissionException;
import com.redhat.rhn.common.validator.ValidatorException;
import com.redhat.rhn.domain.channel.Channel;
import com.redhat.rhn.domain.channel.ChannelFactory;
import com.redhat.rhn.domain.org.Org;
import com.redhat.rhn.domain.role.RoleFactory;
import com.redhat.rhn.domain.user.User;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import redstone.xmlrpc.XmlRpcClient;
import redstone.xmlrpc.XmlRpcException;
import redstone.xmlrpc.XmlRpcFault;
/**
*
* TaskomaticApi
* @version $Rev$
*/
public class TaskomaticApi {
private XmlRpcClient getClient() throws TaskomaticApiException {
try {
return new XmlRpcClient(
ConfigDefaults.get().getTaskoServerUrl(), false);
}
catch (MalformedURLException e) {
throw new TaskomaticApiException(e);
}
}
private Object invoke(String name, Object...args) {
try {
return getClient().invoke(name, args);
}
catch (XmlRpcException e) {
throw new TaskomaticApiException(e);
}
catch (XmlRpcFault e) {
throw new TaskomaticApiException(e);
}
}
/**
* Returns whether taskomatic is running
* @return True if taskomatic is running
*/
public boolean isRunning() {
try {
invoke("tasko.one", new Integer(0));
return true;
}
catch (Exception e) {
return false;
}
}
/**
* Schedule a single reposync
* @param chan the channel
* @param user the user
* @throws TaskomaticApiException if there was an error
*/
public void scheduleSingleRepoSync(Channel chan, User user)
throws TaskomaticApiException {
Map scheduleParams = new HashMap();
scheduleParams.put("channel_id", chan.getId().toString());
invoke("tasko.scheduleSingleBunchRun", user.getOrg().getId(),
"repo-sync-bunch", scheduleParams);
}
/**
* Schedule a single reposync
* @param chan the channel
* @param user the user
* @param params parameters
* @throws TaskomaticApiException if there was an error
*/
public void scheduleSingleRepoSync(Channel chan, User user, Map <String, String>params)
throws TaskomaticApiException {
Map <String, String> scheduleParams = new HashMap<String, String>();
scheduleParams.put("channel_id", chan.getId().toString());
scheduleParams.putAll(params);
invoke("tasko.scheduleSingleBunchRun", user.getOrg().getId(),
"repo-sync-bunch", scheduleParams);
}
private String createRepoSyncScheduleName(Channel chan, User user) {
return "repo-sync-" + user.getOrg().getId() + "-" + chan.getId();
}
/**
* Schedule a recurring reposync
* @param chan the channel
* @param user the user
* @param cron the cron format
* @return the Date?
* @throws TaskomaticApiException if there was an error
*/
public Date scheduleRepoSync(Channel chan, User user, String cron)
throws TaskomaticApiException {
String jobLabel = createRepoSyncScheduleName(chan, user);
Map task = findScheduleByBunchAndLabel("repo-sync-bunch", jobLabel, user);
if (task != null) {
unscheduleRepoTask(jobLabel, user);
}
Map scheduleParams = new HashMap();
scheduleParams.put("channel_id", chan.getId().toString());
return (Date) invoke("tasko.scheduleBunch", user.getOrg().getId(),
"repo-sync-bunch", jobLabel, cron, scheduleParams);
}
/**
* Schedule a recurring reposync
* @param chan the channel
* @param user the user
* @param cron the cron format
* @param params parameters
* @return the Date?
* @throws TaskomaticApiException if there was an error
*/
public Date scheduleRepoSync(Channel chan, User user, String cron,
Map<String, String> params) throws TaskomaticApiException {
String jobLabel = createRepoSyncScheduleName(chan, user);
Map task = findScheduleByBunchAndLabel("repo-sync-bunch", jobLabel, user);
if (task != null) {
unscheduleRepoTask(jobLabel, user);
}
Map <String, String> scheduleParams = new HashMap<String, String>();
scheduleParams.put("channel_id", chan.getId().toString());
scheduleParams.putAll(params);
return (Date) invoke("tasko.scheduleBunch", user.getOrg().getId(),
"repo-sync-bunch", jobLabel, cron, scheduleParams);
}
/**
* Creates a new single satellite schedule
* @param user shall be sat admin
* @param bunchName bunch name
* @return date of the first schedule
* @throws TaskomaticApiException if there was an error
*/
public Date scheduleSingleSatBunch(User user, String bunchName)
throws TaskomaticApiException {
ensureSatAdminRole(user);
return (Date) invoke("tasko.scheduleSingleSatBunchRun", bunchName, new HashMap());
}
/**
* Validates user has sat admin role
* @param user shall be sat admin
* @throws PermissionException if there was an error
*/
private void ensureSatAdminRole(User user) {
if (!user.hasRole(RoleFactory.SAT_ADMIN)) {
ValidatorException.raiseException("satadmin.jsp.error.notsatadmin",
user.getLogin());
}
}
/**
* Validates user has org admin role
* @param user shall be org admin
* @throws PermissionException if there was an error
*/
private void ensureOrgAdminRole(User user) {
if (!user.hasRole(RoleFactory.ORG_ADMIN)) {
throw new PermissionException(RoleFactory.ORG_ADMIN);
}
}
/**
* Validates user has channel admin role
* @param user shall be channel admin
* @throws PermissionException if there was an error
*/
private void ensureChannelAdminRole(User user) {
if (!user.hasRole(RoleFactory.CHANNEL_ADMIN)) {
throw new PermissionException(RoleFactory.CHANNEL_ADMIN);
}
}
/**
* Creates a new schedule, unschedules, if en existing is defined
* @param user shall be sat admin
* @param jobLabel name of the schedule
* @param bunchName bunch name
* @param cron cron expression
* @return date of the first schedule
* @throws TaskomaticApiException if there was an error
*/
public Date scheduleSatBunch(User user, String jobLabel, String bunchName, String cron)
throws TaskomaticApiException {
ensureSatAdminRole(user);
Map task = findSatScheduleByBunchAndLabel(bunchName, jobLabel, user);
if (task != null) {
unscheduleSatTask(jobLabel, user);
}
return (Date) invoke("tasko.scheduleSatBunch", bunchName, jobLabel , cron,
new HashMap());
}
/**
* Unchedule a reposync task
* @param chan the channel
* @param user the user
*/
public void unscheduleRepoSync(Channel chan, User user) {
String jobLabel = createRepoSyncScheduleName(chan, user);
Map task = findScheduleByBunchAndLabel("repo-sync-bunch", jobLabel, user);
if (task != null) {
unscheduleRepoTask(jobLabel, user);
}
}
private void unscheduleRepoTask(String jobLabel, User user) {
ensureChannelAdminRole(user);
invoke("tasko.unscheduleBunch", user.getOrg().getId(), jobLabel);
}
/**
* unschedule satellite task
* @param jobLabel schedule name
* @param user shall be satellite admin
*/
public void unscheduleSatTask(String jobLabel, User user) {
ensureSatAdminRole(user);
invoke("tasko.unscheduleSatBunch", jobLabel);
}
/**
* Return list of active schedules
* @param user shall be sat admin
* @return list of schedules
*/
public List findActiveSchedules(User user) {
List<Map> schedules = (List<Map>) invoke("tasko.listActiveSatSchedules");
return schedules;
}
/**
* Return list of bunch runs
* @param user shall be sat admin
* @param bunchName name of the bunch
* @return list of schedules
*/
public List findRunsByBunch(User user, String bunchName) {
List<Map> runs = (List<Map>) invoke("tasko.listBunchSatRuns", bunchName);
return runs;
}
private Map findScheduleByBunchAndLabel(String bunchName, String jobLabel, User user) {
List<Map> schedules = (List<Map>) invoke("tasko.listActiveSchedulesByBunch",
user.getOrg().getId(), bunchName);
for (Map schedule : schedules) {
if (schedule.get("job_label").equals(jobLabel)) {
return schedule;
}
}
return null;
}
private Map findSatScheduleByBunchAndLabel(String bunchName, String jobLabel,
User user) {
List<Map> schedules = (List<Map>) invoke("tasko.listActiveSatSchedulesByBunch",
bunchName);
for (Map schedule : schedules) {
if (schedule.get("job_label").equals(jobLabel)) {
return schedule;
}
}
return null;
}
/**
* Check whether there's an active schedule of given job label
* @param jobLabel job label
* @param user the user
* @return true, if schedule exists
*/
public boolean satScheduleActive(String jobLabel, User user) {
List<Map> schedules = (List<Map>) invoke("tasko.listActiveSatSchedules");
for (Map schedule : schedules) {
if (schedule.get("job_label").equals(jobLabel)) {
return Boolean.TRUE;
}
}
return Boolean.FALSE;
}
/**
* Get the cron format for a single channel
* @param chan the channel
* @param user the user
* @return the Cron format
*/
public String getRepoSyncSchedule(Channel chan, User user) {
String jobLabel = createRepoSyncScheduleName(chan, user);
Map task = findScheduleByBunchAndLabel("repo-sync-bunch", jobLabel, user);
if (task == null) {
return null;
}
return (String) task.get("cron_expr");
}
/**
* Return list of available bunches
* @param user shall be sat admin
* @return list of bunches
*/
public List listSatBunchSchedules(User user) {
List<Map> bunches = (List<Map>) invoke("tasko.listSatBunches");
return bunches;
}
/**
* looks up schedule according to id
* @param user shall be sat admin
* @param scheduleId schedule id
* @return schedule
*/
public Map lookupScheduleById(User user, Long scheduleId) {
return (Map) invoke("tasko.lookupScheduleById", scheduleId);
}
/**
* looks up schedule according to label
* @param user shall be sat admin
* @param bunchName bunch name
* @param scheduleLabel schedule label
* @return schedule
*/
public Map lookupScheduleByBunchAndLabel(User user, String bunchName,
String scheduleLabel) {
return findSatScheduleByBunchAndLabel(bunchName, scheduleLabel, user);
}
/**
* looks up bunch according to name
* @param user shall be sat admin
* @param bunchName bunch name
* @return bunch
*/
public Map lookupBunchByName(User user, String bunchName) {
return (Map) invoke("tasko.lookupBunchByName", bunchName);
}
/**
* List all reposync schedules within an organization
* @param org organization
* @return list of schedules
*/
private List<TaskoSchedule> listActiveRepoSyncSchedules(Org org) {
try {
return TaskoFactory.listActiveSchedulesByOrgAndBunch(org.getId().intValue(),
"repo-sync-bunch");
}
catch (NoSuchBunchTaskException e) {
// no such schedules available
return new ArrayList<TaskoSchedule>();
}
}
/**
* unschedule all outdated repo-sync schedules within an org
* @param orgIn organization
* @return number of removed schedules
*/
public int unscheduleInvalidRepoSyncSchedules(Org orgIn) {
int count = 0;
for (TaskoSchedule schedule : listActiveRepoSyncSchedules(orgIn)) {
String channelIdStr = (String) schedule.getDataMap().get("channel_id");
Long channelId = null;
try {
channelId = Long.parseLong(channelIdStr);
}
catch (NumberFormatException nfe) {
// no valid channel id given
}
if (channelId == null || ChannelFactory.lookupById(channelId) == null) {
invoke("tasko.unscheduleBunch", orgIn.getId(), schedule.getJobLabel());
count++;
}
}
return count;
}
}