[5028] | 1 | using System;
|
---|
| 2 | using System.Collections.Generic;
|
---|
| 3 | using System.Linq;
|
---|
| 4 | using System.ServiceModel;
|
---|
[5375] | 5 | using HeuristicLab.Services.Hive.Common;
|
---|
| 6 | using HeuristicLab.Services.Hive.Common.DataTransfer;
|
---|
[5028] | 7 | using HeuristicLab.Services.Hive.Common.ServiceContracts;
|
---|
| 8 |
|
---|
| 9 | namespace HeuristicLab.Services.Hive {
|
---|
| 10 |
|
---|
| 11 | /// <summary>
|
---|
| 12 | /// Implementation of the Hive service (interface <see cref="IHiveService"/>).
|
---|
| 13 | /// </summary>
|
---|
[5106] | 14 | [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
|
---|
[5028] | 15 | public class HiveService : IHiveService {
|
---|
| 16 | private DataAccess.IHiveDao dao {
|
---|
| 17 | get { return ServiceLocator.Instance.HiveDao; }
|
---|
| 18 | }
|
---|
| 19 | private HeuristicLab.Services.Hive.DataAccess.TransactionManager trans {
|
---|
| 20 | get { return ServiceLocator.Instance.TransactionManager; }
|
---|
| 21 | }
|
---|
| 22 | private IAuthorizationManager auth {
|
---|
| 23 | get { return ServiceLocator.Instance.AuthorizationManager; }
|
---|
| 24 | }
|
---|
[5095] | 25 | private ILifecycleManager lifecycleManager {
|
---|
| 26 | get { return ServiceLocator.Instance.LifecycleManager; }
|
---|
[5028] | 27 | }
|
---|
| 28 |
|
---|
| 29 | #region Job Methods
|
---|
[5095] | 30 | //[PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]
|
---|
| 31 | //[PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Client)]
|
---|
[5155] | 32 | public Guid AddJob(Job job, JobData jobData, IEnumerable<Guid> slaveGroupIds) {
|
---|
[5028] | 33 | using (trans.OpenTransaction()) {
|
---|
[5106] | 34 | job.UserId = auth.UserId;
|
---|
| 35 | job.DateCreated = DateTime.Now;
|
---|
| 36 | job.JobState = JobState.Waiting;
|
---|
[5155] | 37 | job.Id = dao.AddJob(job);
|
---|
| 38 | jobData.JobId = job.Id;
|
---|
[5106] | 39 | jobData.LastUpdate = DateTime.Now;
|
---|
[5155] | 40 | if (slaveGroupIds != null) {
|
---|
| 41 | foreach (Guid slaveGroupId in slaveGroupIds) {
|
---|
| 42 | dao.AssignJobToResource(job.Id, slaveGroupId);
|
---|
| 43 | }
|
---|
| 44 | } else {
|
---|
| 45 | // todo: use default group
|
---|
| 46 | }
|
---|
[5028] | 47 | dao.AddJobData(jobData);
|
---|
| 48 | return jobData.JobId;
|
---|
| 49 | }
|
---|
| 50 | }
|
---|
| 51 |
|
---|
| 52 | public Guid AddChildJob(Guid parentJobId, Job job, JobData jobData) {
|
---|
| 53 | using (trans.OpenTransaction()) {
|
---|
| 54 | job.ParentJobId = parentJobId;
|
---|
[5155] | 55 | return AddJob(job, jobData, dao.GetAssignedResources(parentJobId).Select(x => x.Id));
|
---|
[5028] | 56 | }
|
---|
| 57 | }
|
---|
| 58 |
|
---|
| 59 | public Job GetJob(Guid jobId) {
|
---|
| 60 | return dao.GetJob(jobId);
|
---|
| 61 | }
|
---|
| 62 |
|
---|
| 63 | public IEnumerable<Job> GetJobs() {
|
---|
| 64 | return dao.GetJobs(x => true);
|
---|
| 65 | }
|
---|
| 66 |
|
---|
| 67 | public IEnumerable<LightweightJob> GetLightweightJobs(IEnumerable<Guid> jobIds) {
|
---|
| 68 | return dao.GetJobs(x => jobIds.Contains(x.JobId)).Select(x => new LightweightJob(x)).ToArray();
|
---|
| 69 | }
|
---|
| 70 |
|
---|
| 71 | public IEnumerable<LightweightJob> GetLightweightChildJobs(Guid? parentJobId, bool recursive, bool includeParent) {
|
---|
| 72 | return GetChildJobs(parentJobId, recursive, includeParent).Select(x => new LightweightJob(x)).ToArray();
|
---|
| 73 | }
|
---|
| 74 |
|
---|
| 75 | public JobData GetJobData(Guid jobId) {
|
---|
| 76 | return dao.GetJobData(jobId);
|
---|
| 77 | }
|
---|
| 78 |
|
---|
[5106] | 79 | public void UpdateJob(Job job, JobData jobData) {
|
---|
[5028] | 80 | using (trans.OpenTransaction()) {
|
---|
[5106] | 81 | jobData.LastUpdate = DateTime.Now;
|
---|
| 82 | dao.UpdateJob(job);
|
---|
| 83 | dao.UpdateJobData(jobData);
|
---|
[5028] | 84 | }
|
---|
| 85 | }
|
---|
| 86 |
|
---|
[5106] | 87 | public void DeleteJob(Guid jobId) {
|
---|
[5028] | 88 | using (trans.OpenTransaction()) {
|
---|
[5106] | 89 | dao.DeleteJob(jobId);
|
---|
[5028] | 90 | }
|
---|
| 91 | }
|
---|
| 92 |
|
---|
[5106] | 93 | public void DeleteChildJobs(Guid parentJobId) {
|
---|
[5028] | 94 | using (trans.OpenTransaction()) {
|
---|
[5106] | 95 | var jobs = GetChildJobs(parentJobId, true, false);
|
---|
[5028] | 96 | foreach (var job in jobs) {
|
---|
| 97 | dao.DeleteJob(job.Id);
|
---|
| 98 | dao.DeleteJobData(job.Id);
|
---|
| 99 | };
|
---|
| 100 | }
|
---|
| 101 | }
|
---|
| 102 |
|
---|
| 103 | public Job AquireJob(Guid slaveId) {
|
---|
| 104 | using (trans.OpenTransaction()) {
|
---|
| 105 | var slave = dao.GetSlave(slaveId);
|
---|
| 106 | var availableJobs = dao.GetWaitingJobs(slave);
|
---|
| 107 | var job = availableJobs.FirstOrDefault();
|
---|
| 108 |
|
---|
| 109 | if (job != null) {
|
---|
| 110 | job.SlaveId = slaveId;
|
---|
| 111 | job.JobState = JobState.Calculating;
|
---|
| 112 | }
|
---|
| 113 | return job;
|
---|
| 114 | }
|
---|
| 115 | }
|
---|
[5102] | 116 |
|
---|
| 117 | public PluginData GetConfigurationFile() {
|
---|
[5375] | 118 | using (trans.OpenTransaction()) {
|
---|
| 119 | //TODO: move filename to app.config
|
---|
| 120 | PluginData configFile = dao.GetPluginDatas(x => x.FileName == "HeuristicLab 3.3.exe.config").SingleOrDefault();
|
---|
| 121 | if (configFile == null) {
|
---|
| 122 | //TODO: error handling
|
---|
| 123 | return null;
|
---|
| 124 | } else {
|
---|
| 125 | return configFile;
|
---|
| 126 | }
|
---|
| 127 | }
|
---|
[5102] | 128 | }
|
---|
| 129 |
|
---|
[5028] | 130 | #endregion
|
---|
| 131 |
|
---|
| 132 | #region Job Control Methods
|
---|
[5053] | 133 | public void StopJob(Guid jobId) {
|
---|
[5028] | 134 | using (trans.OpenTransaction()) {
|
---|
| 135 | throw new NotImplementedException();
|
---|
| 136 | }
|
---|
| 137 | }
|
---|
[5062] | 138 | public void PauseJob(Guid jobId) {
|
---|
[5028] | 139 | using (trans.OpenTransaction()) {
|
---|
| 140 | throw new NotImplementedException();
|
---|
| 141 | }
|
---|
| 142 | }
|
---|
| 143 | #endregion
|
---|
| 144 |
|
---|
| 145 | #region HiveExperiment Methods
|
---|
| 146 |
|
---|
| 147 | public HiveExperiment GetHiveExperiment(Guid id) {
|
---|
| 148 | return dao.GetHiveExperiments(x => x.UserId == auth.UserId && x.HiveExperimentId == id).FirstOrDefault();
|
---|
| 149 | }
|
---|
| 150 |
|
---|
| 151 | public IEnumerable<HiveExperiment> GetHiveExperiments() {
|
---|
| 152 | return dao.GetHiveExperiments(x => x.UserId == auth.UserId);
|
---|
| 153 | }
|
---|
| 154 |
|
---|
| 155 | public Guid AddHiveExperiment(HiveExperiment hiveExperimentDto) {
|
---|
| 156 | using (trans.OpenTransaction()) {
|
---|
| 157 | hiveExperimentDto.UserId = auth.UserId;
|
---|
[5106] | 158 | hiveExperimentDto.DateCreated = DateTime.Now;
|
---|
[5028] | 159 | return dao.AddHiveExperiment(hiveExperimentDto);
|
---|
| 160 | }
|
---|
| 161 | }
|
---|
| 162 |
|
---|
| 163 | public void UpdateHiveExperiment(HiveExperiment hiveExperimentDto) {
|
---|
| 164 | using (trans.OpenTransaction()) {
|
---|
| 165 | dao.UpdateHiveExperiment(hiveExperimentDto);
|
---|
| 166 | }
|
---|
| 167 | }
|
---|
| 168 |
|
---|
| 169 | public void DeleteHiveExperiment(Guid hiveExperimentId) {
|
---|
| 170 | using (trans.OpenTransaction()) {
|
---|
| 171 | HiveExperiment he = dao.GetHiveExperiment(hiveExperimentId);
|
---|
[5106] | 172 | dao.DeleteHiveExperiment(hiveExperimentId); // child jobs will be deleted by db-trigger
|
---|
[5028] | 173 | }
|
---|
| 174 | }
|
---|
| 175 | #endregion
|
---|
[5106] | 176 |
|
---|
[5028] | 177 | #region Login Methods
|
---|
[5053] | 178 | public void Hello(Guid slaveId, string name, int cores, int memory) {
|
---|
[5375] | 179 | using (trans.OpenTransaction()) {
|
---|
| 180 | var slave = dao.GetSlave(slaveId);
|
---|
| 181 |
|
---|
| 182 | if (slave == null) {
|
---|
| 183 | slave = new Slave { Id = slaveId, Name = name, Cores = cores, Memory = memory };
|
---|
| 184 | slave.IsAllowedToCalculate = true; //a little bit to optimistic?
|
---|
| 185 | slave.SlaveState = SlaveState.Idle;
|
---|
| 186 | dao.AddSlave(slave);
|
---|
| 187 | } else {
|
---|
| 188 | //TODO: error handling?
|
---|
| 189 | }
|
---|
| 190 | }
|
---|
[5053] | 191 | }
|
---|
[5028] | 192 |
|
---|
[5375] | 193 | public void GoodBye(Guid slaveId) {
|
---|
| 194 | using (trans.OpenTransaction()) {
|
---|
| 195 | var slave = dao.GetSlave(slaveId);
|
---|
| 196 | if (slave != null) {
|
---|
| 197 | slave.SlaveState = SlaveState.Offline;
|
---|
| 198 | dao.UpdateSlave(slave);
|
---|
| 199 | }
|
---|
| 200 | }
|
---|
[5053] | 201 | }
|
---|
[5028] | 202 | #endregion
|
---|
| 203 |
|
---|
| 204 | #region Heartbeat Methods
|
---|
[5053] | 205 | public List<MessageContainer> Heartbeat(Heartbeat heartbeat) {
|
---|
[5028] | 206 | using (trans.OpenTransaction()) {
|
---|
[5095] | 207 | return lifecycleManager.ProcessHeartbeat(heartbeat);
|
---|
[5028] | 208 | }
|
---|
| 209 | }
|
---|
| 210 | #endregion
|
---|
| 211 |
|
---|
| 212 | #region Plugin Methods
|
---|
| 213 | public Guid AddPlugin(Plugin plugin, List<PluginData> pluginDatas) {
|
---|
| 214 | using (trans.OpenTransaction()) {
|
---|
[5402] | 215 | plugin.UserId = auth.UserId;
|
---|
| 216 | plugin.DateCreated = DateTime.Now;
|
---|
[5028] | 217 | Guid pluginId = dao.AddPlugin(plugin);
|
---|
| 218 | foreach (PluginData pluginData in pluginDatas) {
|
---|
| 219 | pluginData.PluginId = pluginId;
|
---|
| 220 | dao.AddPluginData(pluginData);
|
---|
| 221 | }
|
---|
| 222 | return pluginId;
|
---|
| 223 | }
|
---|
| 224 | }
|
---|
[5053] | 225 | public IEnumerable<Plugin> GetPlugins() {
|
---|
| 226 | return dao.GetPlugins(x => true);
|
---|
[5028] | 227 | }
|
---|
[5375] | 228 |
|
---|
[5053] | 229 | public IEnumerable<PluginData> GetPluginDatas(List<Guid> pluginIds) {
|
---|
[5375] | 230 | List<PluginData> pluginDatas = new List<PluginData>();
|
---|
| 231 |
|
---|
| 232 | using (trans.OpenTransaction()) {
|
---|
| 233 | foreach (Guid guid in pluginIds) {
|
---|
| 234 | List<PluginData> pluginData = dao.GetPluginDatas(x => x.PluginId == guid).ToList();
|
---|
| 235 | if (pluginData != null) {
|
---|
| 236 | pluginDatas.AddRange(pluginData);
|
---|
| 237 | } else {
|
---|
| 238 | //ignore ?
|
---|
| 239 | }
|
---|
| 240 | }
|
---|
| 241 | return pluginDatas;
|
---|
| 242 | }
|
---|
[5028] | 243 | }
|
---|
[5375] | 244 |
|
---|
[5028] | 245 | #endregion
|
---|
[5106] | 246 |
|
---|
[5028] | 247 | #region Slave Methods
|
---|
| 248 | public Guid AddSlave(Slave slave) {
|
---|
| 249 | using (trans.OpenTransaction()) {
|
---|
| 250 | return dao.AddSlave(slave);
|
---|
| 251 | }
|
---|
| 252 | }
|
---|
| 253 |
|
---|
| 254 | public Guid AddSlaveGroup(SlaveGroup slaveGroup) {
|
---|
| 255 | using (trans.OpenTransaction()) {
|
---|
| 256 | return dao.AddSlaveGroup(slaveGroup);
|
---|
| 257 | }
|
---|
| 258 | }
|
---|
| 259 |
|
---|
[5106] | 260 | public Slave GetSlave(Guid slaveId) {
|
---|
| 261 | return dao.GetSlave(slaveId);
|
---|
| 262 | }
|
---|
| 263 |
|
---|
| 264 | public SlaveGroup GetSlaveGroup(Guid slaveGroupId) {
|
---|
| 265 | return dao.GetSlaveGroup(slaveGroupId);
|
---|
| 266 | }
|
---|
| 267 |
|
---|
[5028] | 268 | public IEnumerable<Slave> GetSlaves() {
|
---|
| 269 | return dao.GetSlaves(x => true);
|
---|
| 270 | }
|
---|
| 271 |
|
---|
| 272 | public IEnumerable<SlaveGroup> GetSlaveGroups() {
|
---|
| 273 | return dao.GetSlaveGroups(x => true);
|
---|
| 274 | }
|
---|
| 275 |
|
---|
[5106] | 276 | public void UpdateSlave(Slave slave) {
|
---|
[5028] | 277 | using (trans.OpenTransaction()) {
|
---|
[5106] | 278 | dao.UpdateSlave(slave);
|
---|
[5028] | 279 | }
|
---|
| 280 | }
|
---|
| 281 |
|
---|
[5106] | 282 | public void UpdateSlaveGroup(SlaveGroup slaveGroup) {
|
---|
[5028] | 283 | using (trans.OpenTransaction()) {
|
---|
[5106] | 284 | dao.UpdateSlaveGroup(slaveGroup);
|
---|
[5028] | 285 | }
|
---|
| 286 | }
|
---|
| 287 |
|
---|
[5106] | 288 | public void DeleteSlave(Guid slaveId) {
|
---|
[5028] | 289 | using (trans.OpenTransaction()) {
|
---|
[5106] | 290 | dao.DeleteSlave(slaveId);
|
---|
[5028] | 291 | }
|
---|
| 292 | }
|
---|
| 293 |
|
---|
[5106] | 294 | public void DeleteSlaveGroup(Guid slaveGroupId) {
|
---|
[5028] | 295 | using (trans.OpenTransaction()) {
|
---|
[5106] | 296 | dao.DeleteSlaveGroup(slaveGroupId);
|
---|
[5028] | 297 | }
|
---|
| 298 | }
|
---|
[5106] | 299 |
|
---|
| 300 | public void AddResourceToGroup(Guid slaveGroupId, Guid resourceId) {
|
---|
| 301 | using (trans.OpenTransaction()) {
|
---|
| 302 | var resource = dao.GetResource(resourceId);
|
---|
| 303 | resource.ParentResourceId = slaveGroupId;
|
---|
| 304 | dao.UpdateResource(resource);
|
---|
| 305 | }
|
---|
| 306 | }
|
---|
| 307 |
|
---|
| 308 | public void RemoveResourceFromGroup(Guid slaveGroupId, Guid resourceId) {
|
---|
| 309 | using (trans.OpenTransaction()) {
|
---|
| 310 | var resource = dao.GetResource(resourceId);
|
---|
| 311 | resource.ParentResourceId = null;
|
---|
| 312 | dao.UpdateResource(resource);
|
---|
| 313 | }
|
---|
| 314 | }
|
---|
| 315 |
|
---|
[5028] | 316 | #endregion
|
---|
| 317 |
|
---|
| 318 | #region Helper Methods
|
---|
| 319 | private IEnumerable<Job> GetChildJobs(Guid? parentJobId, bool recursive, bool includeParent) {
|
---|
| 320 | var jobs = new List<Job>(dao.GetJobs(x => parentJobId == null ? !x.ParentJobId.HasValue : x.ParentJobId.Value == parentJobId));
|
---|
| 321 |
|
---|
| 322 | if (includeParent) {
|
---|
| 323 | jobs.Add(GetJob(parentJobId.Value));
|
---|
| 324 | }
|
---|
| 325 |
|
---|
| 326 | if (recursive) {
|
---|
| 327 | var childs = new List<Job>();
|
---|
| 328 | foreach (var job in jobs) {
|
---|
| 329 | childs.AddRange(GetChildJobs(job.Id, recursive, false));
|
---|
| 330 | }
|
---|
| 331 | jobs.AddRange(childs);
|
---|
| 332 | }
|
---|
| 333 | return jobs;
|
---|
| 334 | }
|
---|
| 335 |
|
---|
| 336 | #endregion
|
---|
[5375] | 337 |
|
---|
[5028] | 338 | }
|
---|
| 339 | }
|
---|