#region License Information
/* HeuristicLab
* Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
*
* This file is part of HeuristicLab.
*
* HeuristicLab 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, either version 3 of the License, or
* (at your option) any later version.
*
* HeuristicLab 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 HeuristicLab. If not, see .
*/
#endregion
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security;
using System.ServiceModel;
using HeuristicLab.Services.Access;
using HeuristicLab.Services.Hive.DataAccess.Interfaces;
using HeuristicLab.Services.Hive.DataTransfer;
using HeuristicLab.Services.Hive.Manager;
using HeuristicLab.Services.Hive.ServiceContracts;
using DA = HeuristicLab.Services.Hive.DataAccess;
using DT = HeuristicLab.Services.Hive.DataTransfer;
namespace HeuristicLab.Services.Hive {
///
/// Implementation of the Hive service (interface ).
/// We need 'IgnoreExtensionDataObject' Attribute for the slave to work.
///
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, IgnoreExtensionDataObject = true)]
[HiveOperationContextBehavior]
public class HiveService : IHiveService {
private static readonly DA.TaskState[] CompletedStates = { DA.TaskState.Finished, DA.TaskState.Aborted, DA.TaskState.Failed };
private IPersistenceManager PersistenceManager {
get { return ServiceLocator.Instance.PersistenceManager; }
}
private IUserManager UserManager {
get { return ServiceLocator.Instance.UserManager; }
}
private IRoleVerifier RoleVerifier {
get { return ServiceLocator.Instance.RoleVerifier; }
}
private IAuthorizationManager AuthorizationManager {
get { return ServiceLocator.Instance.AuthorizationManager; }
}
private IEventManager EventManager {
get { return ServiceLocator.Instance.EventManager; }
}
private HeartbeatManager HeartbeatManager {
get { return ServiceLocator.Instance.HeartbeatManager; }
}
#region Task Methods
public Guid AddTask(DT.Task task, DT.TaskData taskData, IEnumerable resourceIds) {
RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
var pm = PersistenceManager;
using (new PerformanceLogger("AddTask")) {
var taskDao = pm.TaskDao;
var stateLogDao = pm.StateLogDao;
var newTask = task.ToEntity();
newTask.JobData = taskData.ToEntity();
newTask.JobData.LastUpdate = DateTime.Now;
newTask.AssignedResources.AddRange(resourceIds.Select(
x => new DA.AssignedResource {
ResourceId = x
}));
newTask.State = DA.TaskState.Waiting;
return pm.UseTransaction(() => {
taskDao.Save(newTask);
pm.SubmitChanges();
stateLogDao.Save(new DA.StateLog {
State = DA.TaskState.Waiting,
DateTime = DateTime.Now,
TaskId = newTask.TaskId,
UserId = UserManager.CurrentUserId,
SlaveId = null,
Exception = null
});
pm.SubmitChanges();
return newTask.TaskId;
}, false, true);
}
}
public Guid AddChildTask(Guid parentTaskId, DT.Task task, DT.TaskData taskData) {
RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
IEnumerable resourceIds;
var pm = PersistenceManager;
using (new PerformanceLogger("AddChildTask")) {
var assignedResourceDao = pm.AssignedResourceDao;
resourceIds = pm.UseTransaction(() => {
return assignedResourceDao.GetByTaskId(parentTaskId)
.Select(x => x.ResourceId)
.ToList();
});
}
task.ParentTaskId = parentTaskId;
return AddTask(task, taskData, resourceIds);
}
public DT.Task GetTask(Guid taskId) {
RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
AuthorizationManager.AuthorizeForTask(taskId, Permission.Read);
var pm = PersistenceManager;
using (new PerformanceLogger("GetTask")) {
var taskDao = pm.TaskDao;
return pm.UseTransaction(() => {
var task = taskDao.GetById(taskId);
return task.ToDto();
});
}
}
public IEnumerable GetLightweightJobTasks(Guid jobId) {
RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
AuthorizationManager.AuthorizeForJob(jobId, Permission.Read);
var pm = PersistenceManager;
using (new PerformanceLogger("GetLightweightJobTasks")) {
var taskDao = pm.TaskDao;
return pm.UseTransaction(() => {
return taskDao.GetByJobId(jobId)
.ToList()
.Select(x => new DT.LightweightTask {
Id = x.TaskId,
ExecutionTime = TimeSpan.FromMilliseconds(x.ExecutionTimeMs),
ParentTaskId = x.ParentTaskId,
StateLog = x.StateLogs.OrderBy(y => y.DateTime)
.Select(z => z.ToDto())
.ToList(),
State = x.State.ToDto(),
Command = x.Command.ToDto(),
LastTaskDataUpdate = x.JobData.LastUpdate
})
.ToList();
}, false, true);
}
}
public IEnumerable GetLightweightJobTasksWithoutStateLog(Guid jobId) {
RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
AuthorizationManager.AuthorizeForJob(jobId, Permission.Read);
var pm = PersistenceManager;
using (new PerformanceLogger("GetLightweightJobTasksWithoutStateLog")) {
var taskDao = pm.TaskDao;
return pm.UseTransaction(() => {
return taskDao.GetByJobId(jobId)
.ToList()
.Select(x => new DT.LightweightTask {
Id = x.TaskId,
ExecutionTime = TimeSpan.FromMilliseconds(x.ExecutionTimeMs),
ParentTaskId = x.ParentTaskId,
StateLog = new List(),
State = x.State.ToDto(),
Command = x.Command.ToDto(),
LastTaskDataUpdate = x.JobData.LastUpdate
})
.ToList();
}, false, true);
}
}
public DT.TaskData GetTaskData(Guid taskId) {
RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
AuthorizationManager.AuthorizeForTask(taskId, Permission.Read);
var pm = PersistenceManager;
using (new PerformanceLogger("GetTaskData")) {
var taskDataDao = pm.TaskDataDao;
return pm.UseTransaction(() => taskDataDao.GetById(taskId).ToDto());
}
}
public void UpdateTask(DT.Task taskDto) {
RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
AuthorizationManager.AuthorizeForTask(taskDto.Id, Permission.Full);
var pm = PersistenceManager;
using (new PerformanceLogger("UpdateTask")) {
var taskDao = pm.TaskDao;
pm.UseTransaction(() => {
var task = taskDao.GetById(taskDto.Id);
taskDto.CopyToEntity(task);
pm.SubmitChanges();
});
}
}
public void UpdateTaskData(DT.Task taskDto, DT.TaskData taskDataDto) {
RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
AuthorizationManager.AuthorizeForTask(taskDto.Id, Permission.Full);
var pm = PersistenceManager;
using (new PerformanceLogger("UpdateTaskData")) {
var taskDao = pm.TaskDao;
var taskDataDao = pm.TaskDataDao;
pm.UseTransaction(() => {
var task = taskDao.GetById(taskDto.Id);
var taskData = taskDataDao.GetById(taskDataDto.TaskId);
taskDto.CopyToEntity(task);
taskDataDto.CopyToEntity(taskData);
taskData.LastUpdate = DateTime.Now;
pm.SubmitChanges();
});
}
}
public DT.Task UpdateTaskState(Guid taskId, DT.TaskState taskState, Guid? slaveId, Guid? userId, string exception) {
RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
AuthorizationManager.AuthorizeForTask(taskId, Permission.Full);
var pm = PersistenceManager;
using (new PerformanceLogger("UpdateTaskState")) {
var taskDao = pm.TaskDao;
return pm.UseTransaction(() => {
var task = taskDao.GetById(taskId);
UpdateTaskState(pm, task, taskState, slaveId, userId, exception);
pm.SubmitChanges();
return task.ToDto();
});
}
}
#endregion
#region Task Control Methods
public void StopTask(Guid taskId) {
RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
AuthorizationManager.AuthorizeForTask(taskId, Permission.Full);
var pm = PersistenceManager;
using (new PerformanceLogger("StopTask")) {
var taskDao = pm.TaskDao;
pm.UseTransaction(() => {
var task = taskDao.GetById(taskId);
if (task.State == DA.TaskState.Calculating || task.State == DA.TaskState.Transferring) {
task.Command = DA.Command.Stop;
} else if (task.State != DA.TaskState.Aborted
&& task.State != DA.TaskState.Finished
&& task.State != DA.TaskState.Failed) {
UpdateTaskState(pm, task, DT.TaskState.Aborted, null, null, string.Empty);
}
pm.SubmitChanges();
});
}
}
public void PauseTask(Guid taskId) {
RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
AuthorizationManager.AuthorizeForTask(taskId, Permission.Full);
var pm = PersistenceManager;
using (new PerformanceLogger("PauseTask")) {
var taskDao = pm.TaskDao;
pm.UseTransaction(() => {
var task = taskDao.GetById(taskId);
if (task.State == DA.TaskState.Calculating || task.State == DA.TaskState.Transferring) {
task.Command = DA.Command.Pause;
} else if (task.State != DA.TaskState.Paused
&& task.State != DA.TaskState.Aborted
&& task.State != DA.TaskState.Finished
&& task.State != DA.TaskState.Failed) {
UpdateTaskState(pm, task, DT.TaskState.Paused, null, null, string.Empty);
}
pm.SubmitChanges();
});
}
}
public void RestartTask(Guid taskId) {
RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
AuthorizationManager.AuthorizeForTask(taskId, Permission.Full);
var pm = PersistenceManager;
using (new PerformanceLogger("RestartTask")) {
var taskDao = pm.TaskDao;
pm.UseTransaction(() => {
var task = taskDao.GetById(taskId);
task.Command = null;
UpdateTaskState(pm, task, DT.TaskState.Waiting, null, UserManager.CurrentUserId, string.Empty);
pm.SubmitChanges();
});
}
}
#endregion
#region Job Methods
public DT.Job GetJob(Guid id) {
RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
AuthorizationManager.AuthorizeForJob(id, DT.Permission.Read);
var pm = PersistenceManager;
using (new PerformanceLogger("GetJob")) {
var jobDao = pm.JobDao;
var jobPermissionDao = pm.JobPermissionDao;
var taskDao = pm.TaskDao;
var currentUserId = UserManager.CurrentUserId;
return pm.UseTransaction(() => {
var job = jobDao.GetById(id).ToDto();
if (job != null) {
var statistics = taskDao.GetByJobId(job.Id)
.GroupBy(x => x.JobId)
.Select(x => new {
TotalCount = x.Count(),
CalculatingCount = x.Count(y => y.State == DA.TaskState.Calculating),
FinishedCount = x.Count(y => CompletedStates.Contains(y.State))
}).FirstOrDefault();
if (statistics != null) {
job.JobCount = statistics.TotalCount;
job.CalculatingCount = statistics.CalculatingCount;
job.FinishedCount = statistics.FinishedCount;
}
job.OwnerUsername = UserManager.GetUserNameById(job.OwnerUserId);
if (currentUserId == job.OwnerUserId) {
job.Permission = Permission.Full;
} else {
var jobPermission = jobPermissionDao.GetByJobAndUserId(job.Id, currentUserId);
job.Permission = jobPermission == null ? Permission.NotAllowed : jobPermission.Permission.ToDto();
}
}
return job;
});
}
}
public IEnumerable GetJobs() {
RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
var pm = PersistenceManager;
using (new PerformanceLogger("GetJobs")) {
var jobDao = pm.JobDao;
var jobPermissionDao = pm.JobPermissionDao;
var taskDao = pm.TaskDao;
var currentUserId = UserManager.CurrentUserId;
return pm.UseTransaction(() => {
var jobs = jobDao.GetAll()
.Where(x => x.OwnerUserId == currentUserId
|| x.JobPermissions.Count(y => y.Permission != DA.Permission.NotAllowed
&& y.GrantedUserId == currentUserId) > 0)
.Select(x => x.ToDto())
.ToList();
var statistics = taskDao.GetAll()
.GroupBy(x => x.JobId)
.Select(x => new {
x.Key,
TotalCount = x.Count(),
CalculatingCount = x.Count(y => y.State == DA.TaskState.Calculating),
FinishedCount = x.Count(y => CompletedStates.Contains(y.State))
})
.ToList();
foreach (var job in jobs) {
var statistic = statistics.FirstOrDefault(x => x.Key == job.Id);
if (statistic != null) {
job.JobCount = statistic.TotalCount;
job.CalculatingCount = statistic.CalculatingCount;
job.FinishedCount = statistic.FinishedCount;
}
job.OwnerUsername = UserManager.GetUserNameById(job.OwnerUserId);
if (currentUserId == job.OwnerUserId) {
job.Permission = Permission.Full;
} else {
var jobPermission = jobPermissionDao.GetByJobAndUserId(job.Id, currentUserId);
job.Permission = jobPermission == null ? Permission.NotAllowed : jobPermission.Permission.ToDto();
}
}
return jobs;
});
}
}
public Guid AddJob(DT.Job jobDto) {
RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
var pm = PersistenceManager;
using (new PerformanceLogger("AddJob")) {
var jobDao = pm.JobDao;
var userPriorityDao = pm.UserPriorityDao;
return pm.UseTransaction(() => {
jobDto.OwnerUserId = UserManager.CurrentUserId;
jobDto.DateCreated = DateTime.Now;
var job = jobDao.Save(jobDto.ToEntity());
if (userPriorityDao.GetById(jobDto.OwnerUserId) == null) {
userPriorityDao.Save(new DA.UserPriority {
UserId = jobDto.OwnerUserId,
DateEnqueued = jobDto.DateCreated
});
}
pm.SubmitChanges();
return job.JobId;
});
}
}
public void UpdateJob(DT.Job jobDto) {
RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
AuthorizationManager.AuthorizeForJob(jobDto.Id, DT.Permission.Full);
var pm = PersistenceManager;
using (new PerformanceLogger("UpdateJob")) {
bool exists = true;
var jobDao = pm.JobDao;
pm.UseTransaction(() => {
var job = jobDao.GetById(jobDto.Id);
if (job == null) {
exists = false;
job = new DA.Job();
}
jobDto.CopyToEntity(job);
if (!exists) {
jobDao.Save(job);
}
pm.SubmitChanges();
});
}
}
public void DeleteJob(Guid jobId) {
RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
AuthorizationManager.AuthorizeForJob(jobId, DT.Permission.Full);
var pm = PersistenceManager;
using (new PerformanceLogger("DeleteJob")) {
var jobDao = pm.JobDao;
pm.UseTransaction(() => {
// child task will be deleted by db-trigger
jobDao.Delete(jobId);
pm.SubmitChanges();
});
}
}
#endregion
#region JobPermission Methods
public void GrantPermission(Guid jobId, Guid grantedUserId, DT.Permission permission) {
RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
AuthorizationManager.AuthorizeForJob(jobId, Permission.Full);
var pm = PersistenceManager;
using (new PerformanceLogger("GrantPermission")) {
var jobPermissionDao = pm.JobPermissionDao;
var currentUserId = UserManager.CurrentUserId;
pm.UseTransaction(() => {
jobPermissionDao.SetJobPermission(jobId, currentUserId, grantedUserId, permission.ToEntity());
pm.SubmitChanges();
});
}
}
public void RevokePermission(Guid jobId, Guid grantedUserId) {
RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
AuthorizationManager.AuthorizeForJob(jobId, Permission.Full);
var pm = PersistenceManager;
using (new PerformanceLogger("RevokePermission")) {
var jobPermissionDao = pm.JobPermissionDao;
var currentUserId = UserManager.CurrentUserId;
pm.UseTransaction(() => {
jobPermissionDao.SetJobPermission(jobId, currentUserId, grantedUserId, DA.Permission.NotAllowed);
pm.SubmitChanges();
});
}
}
public IEnumerable GetJobPermissions(Guid jobId) {
RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
AuthorizationManager.AuthorizeForJob(jobId, Permission.Full);
var pm = PersistenceManager;
using (new PerformanceLogger("GetJobPermissions")) {
var jobPermissionDao = pm.JobPermissionDao;
return pm.UseTransaction(() => jobPermissionDao.GetByJobId(jobId)
.Select(x => x.ToDto())
.ToList()
);
}
}
// BackwardsCompatibility3.3
#region Backwards compatible code, remove with 3.4
public bool IsAllowedPrivileged() {
return true;
}
#endregion
#endregion
#region Login Methods
public void Hello(DT.Slave slaveInfo) {
RoleVerifier.AuthenticateForAnyRole(HiveRoles.Slave);
if (UserManager.CurrentUser.UserName != "hiveslave") {
slaveInfo.OwnerUserId = UserManager.CurrentUserId;
}
var pm = PersistenceManager;
using (new PerformanceLogger("Hello")) {
var slaveDao = pm.SlaveDao;
pm.UseTransaction(() => {
var slave = slaveDao.GetById(slaveInfo.Id);
if (slave == null) {
slaveDao.Save(slaveInfo.ToEntity());
} else {
bool oldIsAllowedToCalculate = slave.IsAllowedToCalculate;
Guid? oldParentResourceId = slave.ParentResourceId;
bool? oldIsDisposable = slave.IsDisposable;
slaveInfo.CopyToEntity(slave);
slave.IsAllowedToCalculate = oldIsAllowedToCalculate;
slave.ParentResourceId = oldParentResourceId;
slave.IsDisposable = oldIsDisposable;
slave.LastHeartbeat = DateTime.Now;
slave.SlaveState = DA.SlaveState.Idle;
}
pm.SubmitChanges();
});
}
}
public void GoodBye(Guid slaveId) {
RoleVerifier.AuthenticateForAnyRole(HiveRoles.Slave);
var pm = PersistenceManager;
using (new PerformanceLogger("GoodBye")) {
var slaveDao = pm.SlaveDao;
pm.UseTransaction(() => {
var slave = slaveDao.GetById(slaveId);
if (slave != null) {
slave.SlaveState = DA.SlaveState.Offline;
pm.SubmitChanges();
}
});
}
}
#endregion
#region Heartbeat Methods
public List Heartbeat(DT.Heartbeat heartbeat) {
RoleVerifier.AuthenticateForAnyRole(HiveRoles.Slave);
List result = new List();
try {
using (new PerformanceLogger("ProcessHeartbeat")) {
result = HeartbeatManager.ProcessHeartbeat(heartbeat);
}
}
catch (Exception ex) {
DA.LogFactory.GetLogger(this.GetType().Namespace).Log(string.Format("Exception processing Heartbeat: {0}", ex));
}
if (HeuristicLab.Services.Hive.Properties.Settings.Default.TriggerEventManagerInHeartbeat) {
TriggerEventManager(false);
}
return result;
}
#endregion
#region Plugin Methods
public DT.Plugin GetPlugin(Guid pluginId) {
RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
var pm = PersistenceManager;
using (new PerformanceLogger("GetPlugin")) {
var pluginDao = pm.PluginDao;
return pm.UseTransaction(() => pluginDao.GetById(pluginId).ToDto());
}
}
public Guid AddPlugin(DT.Plugin plugin, List pluginData) {
RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
var pm = PersistenceManager;
using (new PerformanceLogger("AddPlugin")) {
var pluginDao = pm.PluginDao;
plugin.UserId = UserManager.CurrentUserId;
plugin.DateCreated = DateTime.Now;
return pm.UseTransaction(() => {
var pluginEntity = pluginDao.GetByHash(plugin.Hash).SingleOrDefault();
if (pluginEntity != null) {
throw new FaultException(new PluginAlreadyExistsFault(pluginEntity.PluginId));
}
pluginEntity = plugin.ToEntity();
foreach (var data in pluginData) {
data.PluginId = default(Guid); // real id will be assigned from linq2sql
pluginEntity.PluginData.Add(data.ToEntity());
}
pluginDao.Save(pluginEntity);
pm.SubmitChanges();
return pluginEntity.PluginId;
});
}
}
public IEnumerable GetPlugins() {
RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
var pm = PersistenceManager;
using (new PerformanceLogger("GetPlugins")) {
var pluginDao = pm.PluginDao;
return pm.UseTransaction(() => pluginDao.GetAll()
.Where(x => x.Hash != null)
.Select(x => x.ToDto())
.ToList()
);
}
}
public IEnumerable GetPluginDatas(List pluginIds) {
RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
var pm = PersistenceManager;
using (new PerformanceLogger("GetPluginDatas")) {
var pluginDataDao = pm.PluginDataDao;
return pm.UseTransaction(() => pluginDataDao.GetAll()
.Where(x => pluginIds.Contains(x.PluginId))
.Select(x => x.ToDto())
.ToList()
);
}
}
#endregion
#region ResourcePermission Methods
public void GrantResourcePermissions(Guid resourceId, Guid[] grantedUserIds) {
RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
var pm = PersistenceManager;
using (new PerformanceLogger("GrantResourcePermissions")) {
pm.UseTransaction(() => {
var resource = AuthorizeForResource(pm, resourceId);
var resourcePermissions = resource.ResourcePermissions.ToList();
foreach (var id in grantedUserIds) {
if (resourcePermissions.All(x => x.GrantedUserId != id)) {
resource.ResourcePermissions.Add(new DA.ResourcePermission {
GrantedUserId = id,
GrantedByUserId = UserManager.CurrentUserId
});
}
}
pm.SubmitChanges();
});
}
}
public void RevokeResourcePermissions(Guid resourceId, Guid[] grantedUserIds) {
RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
var pm = PersistenceManager;
using (new PerformanceLogger("RevokeResourcePermissions")) {
var resourcePermissionDao = pm.ResourcePermissionDao;
pm.UseTransaction(() => {
AuthorizeForResource(pm, resourceId);
resourcePermissionDao.DeleteByResourceAndGrantedUserId(resourceId, grantedUserIds);
pm.SubmitChanges();
});
}
}
public IEnumerable GetResourcePermissions(Guid resourceId) {
RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
var pm = PersistenceManager;
using (new PerformanceLogger("GetResourcePermissions")) {
var resourcePermissionDao = pm.ResourcePermissionDao;
return pm.UseTransaction(() => resourcePermissionDao.GetByResourceId(resourceId)
.Select(x => x.ToDto())
.ToList()
);
}
}
#endregion
#region Slave Methods
public Guid AddSlave(DT.Slave slaveDto) {
RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator);
var pm = PersistenceManager;
using (new PerformanceLogger("AddSlave")) {
var slaveDao = pm.SlaveDao;
return pm.UseTransaction(() => {
var slave = slaveDao.Save(slaveDto.ToEntity());
pm.SubmitChanges();
return slave.ResourceId;
});
}
}
public Guid AddSlaveGroup(DT.SlaveGroup slaveGroupDto) {
RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
var pm = PersistenceManager;
using (new PerformanceLogger("AddSlaveGroup")) {
var slaveGroupDao = pm.SlaveGroupDao;
return pm.UseTransaction(() => {
if (slaveGroupDto.Id == Guid.Empty) {
slaveGroupDto.Id = Guid.NewGuid();
}
var slaveGroup = slaveGroupDao.Save(slaveGroupDto.ToEntity());
pm.SubmitChanges();
return slaveGroup.ResourceId;
});
}
}
public DT.Slave GetSlave(Guid slaveId) {
RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator);
var pm = PersistenceManager;
using (new PerformanceLogger("GetSlave")) {
var slaveDao = pm.SlaveDao;
return pm.UseTransaction(() => slaveDao.GetById(slaveId).ToDto());
}
}
public IEnumerable GetSlaves() {
RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
bool isAdministrator = RoleVerifier.IsInRole(HiveRoles.Administrator);
var pm = PersistenceManager;
using (new PerformanceLogger("GetSlaves")) {
var slaveDao = pm.SlaveDao;
var resourcePermissionDao = pm.ResourcePermissionDao;
var currentUserId = UserManager.CurrentUserId;
return pm.UseTransaction(() => {
var resourcePermissions = resourcePermissionDao.GetAll();
return slaveDao.GetAll().ToList()
.Where(x => isAdministrator
|| x.OwnerUserId == null
|| x.OwnerUserId == currentUserId
|| UserManager.VerifyUser(currentUserId, resourcePermissions
.Where(y => y.ResourceId == x.ResourceId)
.Select(z => z.GrantedUserId)
.ToList())
)
.Select(x => x.ToDto())
.ToList();
});
}
}
public IEnumerable GetSlaveGroups() {
RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
bool isAdministrator = RoleVerifier.IsInRole(HiveRoles.Administrator);
var pm = PersistenceManager;
using (new PerformanceLogger("GetSlaveGroups")) {
var slaveGroupDao = pm.SlaveGroupDao;
var resourcePermissionDao = pm.ResourcePermissionDao;
var currentUserId = UserManager.CurrentUserId;
return pm.UseTransaction(() => {
var resourcePermissions = resourcePermissionDao.GetAll();
return slaveGroupDao.GetAll().ToList()
.Where(x => isAdministrator
|| x.OwnerUserId == null
|| x.OwnerUserId == currentUserId
|| UserManager.VerifyUser(currentUserId, resourcePermissions
.Where(y => y.ResourceId == x.ResourceId)
.Select(z => z.GrantedUserId)
.ToList())
)
.Select(x => x.ToDto())
.ToList();
});
}
}
public void UpdateSlave(DT.Slave slaveDto) {
RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
var pm = PersistenceManager;
using (new PerformanceLogger("UpdateSlave")) {
var slaveDao = pm.SlaveDao;
pm.UseTransaction(() => {
var slave = slaveDao.GetById(slaveDto.Id);
if (slave != null) {
slaveDto.CopyToEntity(slave);
} else {
slaveDao.Save(slaveDto.ToEntity());
}
pm.SubmitChanges();
});
}
}
public void UpdateSlaveGroup(DT.SlaveGroup slaveGroupDto) {
RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
var pm = PersistenceManager;
using (new PerformanceLogger("UpdateSlaveGroup")) {
var slaveGroupDao = pm.SlaveGroupDao;
pm.UseTransaction(() => {
var slaveGroup = slaveGroupDao.GetById(slaveGroupDto.Id);
if (slaveGroup != null) {
slaveGroupDto.CopyToEntity(slaveGroup);
} else {
slaveGroupDao.Save(slaveGroupDto.ToEntity());
}
pm.SubmitChanges();
});
}
}
public void DeleteSlave(Guid slaveId) {
RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
AuthorizationManager.AuthorizeForResourceAdministration(slaveId);
var pm = PersistenceManager;
using (new PerformanceLogger("DeleteSlave")) {
var slaveDao = pm.SlaveDao;
pm.UseTransaction(() => {
slaveDao.Delete(slaveId);
pm.SubmitChanges();
});
}
}
public void DeleteSlaveGroup(Guid slaveGroupId) {
RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
AuthorizationManager.AuthorizeForResourceAdministration(slaveGroupId);
var pm = PersistenceManager;
using (new PerformanceLogger("DeleteSlaveGroup")) {
var slaveGroupDao = pm.SlaveGroupDao;
pm.UseTransaction(() => {
slaveGroupDao.Delete(slaveGroupId);
pm.SubmitChanges();
});
}
}
public void AddResourceToGroup(Guid slaveGroupId, Guid resourceId) {
RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator);
var pm = PersistenceManager;
using (new PerformanceLogger("AddResourceToGroup")) {
var resourceDao = pm.ResourceDao;
pm.UseTransaction(() => {
var resource = resourceDao.GetById(resourceId);
resource.ParentResourceId = slaveGroupId;
pm.SubmitChanges();
});
}
}
public void RemoveResourceFromGroup(Guid slaveGroupId, Guid resourceId) {
RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator);
var pm = PersistenceManager;
using (new PerformanceLogger("RemoveResourceFromGroup")) {
var resourceDao = pm.ResourceDao;
pm.UseTransaction(() => {
var resource = resourceDao.GetById(resourceId);
resource.ParentResourceId = null;
pm.SubmitChanges();
});
}
}
public Guid GetResourceId(string resourceName) {
RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
var pm = PersistenceManager;
using (new PerformanceLogger("GetResourceId")) {
var resourceDao = pm.ResourceDao;
return pm.UseTransaction(() => {
var resource = resourceDao.GetByName(resourceName);
return resource != null ? resource.ResourceId : Guid.Empty;
});
}
}
public void TriggerEventManager(bool force) {
RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator);
// use a serializable transaction here to ensure not two threads execute this simultaniously (mutex-lock would not work since IIS may use multiple AppDomains)
bool cleanup;
var pm = PersistenceManager;
using (new PerformanceLogger("TriggerEventManager")) {
cleanup = false;
var lifecycleDao = pm.LifecycleDao;
pm.UseTransaction(() => {
var lastLifecycle = lifecycleDao.GetLastLifecycle();
DateTime lastCleanup = lastLifecycle != null ? lastLifecycle.LastCleanup : DateTime.MinValue;
if (force || DateTime.Now - lastCleanup > HeuristicLab.Services.Hive.Properties.Settings.Default.CleanupInterval) {
lifecycleDao.UpdateLifecycle();
cleanup = true;
pm.SubmitChanges();
}
}, true);
}
if (cleanup) {
EventManager.Cleanup();
}
}
public int GetNewHeartbeatInterval(Guid slaveId) {
RoleVerifier.AuthenticateForAnyRole(HiveRoles.Slave);
var pm = PersistenceManager;
using (new PerformanceLogger("GetNewHeartbeatInterval")) {
var slaveDao = pm.SlaveDao;
return pm.UseTransaction(() => {
var slave = slaveDao.GetById(slaveId);
if (slave != null) {
return slave.HbInterval;
}
return -1;
});
}
}
#endregion
#region Downtime Methods
public Guid AddDowntime(DT.Downtime downtimeDto) {
RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
AuthorizationManager.AuthorizeForResourceAdministration(downtimeDto.ResourceId);
var pm = PersistenceManager;
using (new PerformanceLogger("AddDowntime")) {
var downtimeDao = pm.DowntimeDao;
return pm.UseTransaction(() => {
var downtime = downtimeDao.Save(downtimeDto.ToEntity());
pm.SubmitChanges();
return downtime.ResourceId;
});
}
}
public void DeleteDowntime(Guid downtimeId) {
RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
var pm = PersistenceManager;
using (new PerformanceLogger("DeleteDowntime")) {
var downtimeDao = pm.DowntimeDao;
pm.UseTransaction(() => {
downtimeDao.Delete(downtimeId);
pm.SubmitChanges();
});
}
}
public void UpdateDowntime(DT.Downtime downtimeDto) {
RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
AuthorizationManager.AuthorizeForResourceAdministration(downtimeDto.ResourceId);
var pm = PersistenceManager;
using (new PerformanceLogger("UpdateDowntime")) {
var downtimeDao = pm.DowntimeDao;
pm.UseTransaction(() => {
var downtime = downtimeDao.GetById(downtimeDto.Id);
if (downtime != null) {
downtimeDto.CopyToEntity(downtime);
} else {
downtimeDao.Save(downtimeDto.ToEntity());
}
pm.SubmitChanges();
});
}
}
public IEnumerable GetDowntimesForResource(Guid resourceId) {
RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
var pm = PersistenceManager;
using (new PerformanceLogger("GetDowntimesForResource")) {
var downtimeDao = pm.DowntimeDao;
return pm.UseTransaction(() => downtimeDao.GetByResourceId(resourceId)
.Select(x => x.ToDto())
.ToList()
);
}
}
#endregion
#region User Methods
public string GetUsernameByUserId(Guid userId) {
RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
var user = UserManager.GetUserById(userId);
return user != null ? user.UserName : null;
}
public Guid GetUserIdByUsername(string username) {
RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
var user = ServiceLocator.Instance.UserManager.GetUserByName(username);
return user != null ? (Guid?)user.ProviderUserKey ?? Guid.Empty : Guid.Empty;
}
#endregion
#region UserPriorities Methods
public IEnumerable GetUserPriorities() {
var pm = PersistenceManager;
using (new PerformanceLogger("GetUserPriorities")) {
var userPriorityDao = pm.UserPriorityDao;
return pm.UseTransaction(() => userPriorityDao.GetAll()
.Select(x => x.ToDto())
.ToList()
);
}
}
#endregion
#region Private Helper Methods
private void UpdateTaskState(IPersistenceManager pm, DA.Task task, DT.TaskState taskState, Guid? slaveId, Guid? userId, string exception) {
var stateLogDao = pm.StateLogDao;
var taskStateEntity = taskState.ToEntity();
if (task.State == DA.TaskState.Transferring && taskStateEntity == DA.TaskState.Paused && task.Command == null) {
// slave paused and uploaded the task (no user-command) -> set waiting.
taskStateEntity = DA.TaskState.Waiting;
}
stateLogDao.Save(new DA.StateLog {
State = taskStateEntity,
DateTime = DateTime.Now,
TaskId = task.TaskId,
UserId = userId,
SlaveId = slaveId,
Exception = exception
});
task.State = taskStateEntity;
if (task.Command == DA.Command.Pause && task.State == DA.TaskState.Paused
|| task.Command == DA.Command.Abort && task.State == DA.TaskState.Aborted
|| task.Command == DA.Command.Stop && task.State == DA.TaskState.Aborted) {
task.Command = null;
}
}
private DA.Resource AuthorizeForResource(IPersistenceManager pm, Guid resourceId) {
var resourceDao = pm.ResourceDao;
var resource = resourceDao.GetById(resourceId);
if (resource == null) throw new SecurityException("Not authorized");
if (resource.OwnerUserId != UserManager.CurrentUserId
&& !RoleVerifier.IsInRole(HiveRoles.Administrator)) {
throw new SecurityException("Not authorized");
}
return resource;
}
#endregion
}
}