#region License Information /* HeuristicLab * Copyright (C) 2002-2015 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.IO; using System.Linq; using HeuristicLab.Clients.Common; using HeuristicLab.Common; using HeuristicLab.Core; using HeuristicLab.Persistence.Default.Xml; using System.ServiceModel; using HeuristicLab.Clients.Hive.WebJobManager.Services; using HeuristicLab.Clients.OKB.Query; using System.ServiceModel.Security; using HeuristicLab.Clients.Hive.WebJobManager.ViewModels; namespace HeuristicLab.Clients.Hive.WebJobManager.Services.Imports { [Item("QueryWebClient", "OKB query client.")] public sealed class QueryWebClient : IContent { private string log; private string pass; private QueryServiceClient client; public Guid UserId { get; set; } public QueryWebClient(Guid u) : this() { UserId = u; client = null; log = WebLoginService.Instance.getServiceLocator(UserId).Username; pass = WebLoginService.Instance.getServiceLocator(UserId).Password; } public QueryWebClient(LoginViewModel log, string pass): this() { client = null; this.UserId = log.userId; this.log = log.loginName; this.pass = pass; } #region Properties private List filters; public IEnumerable Filters { get { return filters; } } private List valueNames; public IEnumerable ValueNames { get { return valueNames; } } #endregion private QueryWebClient() { filters = new List(); valueNames = new List(); } #region Refresh public void Refresh() { OnRefreshing(); filters = new List(); valueNames = new List(); try { filters.AddRange(CallQueryService>(s => s.GetFilters())); valueNames.AddRange(CallQueryService>(s => s.GetValueNames())); } finally { OnRefreshed(); } } public void RefreshAsync(Action exceptionCallback) { var call = new Func(delegate () { try { Refresh(); } catch (Exception ex) { return ex; } return null; }); call.BeginInvoke(delegate (IAsyncResult result) { Exception ex = call.EndInvoke(result); if (ex != null) exceptionCallback(ex); }, null); } #endregion #region Query Methods public long GetNumberOfRuns(Filter filter) { return CallQueryService(x => x.GetNumberOfRuns(filter)); } public IEnumerable GetRunIds(Filter filter) { return CallQueryService>(x => x.GetRunIds(filter)); } public IEnumerable GetRuns(IEnumerable ids, bool includeBinaryValues) { return CallQueryService>(s => s.GetRuns(ids.ToList(), includeBinaryValues)); } public IEnumerable GetRunsWithValues(IEnumerable ids, bool includeBinaryValues, IEnumerable vn) { return CallQueryService>(s => s.GetRunsWithValues(ids.ToList(), includeBinaryValues, vn.ToList())); } #endregion #region OKB-Item Conversion public Optimization.IRun ConvertToOptimizationRun(Run run) { Optimization.Run optRun = new Optimization.Run(); foreach (Value value in run.ParameterValues) optRun.Parameters.Add(value.Name, ConvertToItem(value)); foreach (Value value in run.ResultValues) optRun.Results.Add(value.Name, ConvertToItem(value)); return optRun; } public IItem ConvertToItem(Value value) { if (value is BinaryValue) { IItem item = null; var binaryValue = (BinaryValue)value; if (binaryValue.Value != null) { using (var stream = new MemoryStream(binaryValue.Value)) { try { item = XmlParser.Deserialize(stream); } catch (Exception) { } stream.Close(); } } return item ?? new Data.StringValue(value.DataType.Name); } else if (value is BoolValue) { return new Data.BoolValue(((BoolValue)value).Value); } else if (value is FloatValue) { return new Data.DoubleValue(((FloatValue)value).Value); } else if (value is PercentValue) { return new Data.PercentValue(((PercentValue)value).Value); } else if (value is DoubleValue) { return new Data.DoubleValue(((DoubleValue)value).Value); } else if (value is IntValue) { return new Data.IntValue((int)((IntValue)value).Value); } else if (value is LongValue) { return new Data.IntValue((int)((LongValue)value).Value); } else if (value is StringValue) { return new Data.StringValue(((StringValue)value).Value); } else if (value is TimeSpanValue) { return new Data.TimeSpanValue(TimeSpan.FromSeconds((long)((TimeSpanValue)value).Value)); } return null; } #endregion #region Events public event EventHandler Refreshing; private void OnRefreshing() { EventHandler handler = Refreshing; if (handler != null) handler(this, EventArgs.Empty); } public event EventHandler Refreshed; private void OnRefreshed() { EventHandler handler = Refreshed; if (handler != null) handler(this, EventArgs.Empty); } #endregion #region Helpers private T CallQueryService(Func call) { if (client == null || client.State == CommunicationState.Closed || client.State == CommunicationState.Faulted) { client = createServiceClient(); } try { return call(client); } finally { try { client.Close(); } catch (Exception) { client.Abort(); } } } private QueryServiceClient createServiceClient() { WSHttpBinding binding = new WSHttpBinding(); // I think most (or all) of these are defaults--I just copied them from app.config: binding.Name = "wsHttpBinding_IQueryService"; binding.CloseTimeout = TimeSpan.FromMinutes(1); binding.OpenTimeout = TimeSpan.FromMinutes(1); binding.ReceiveTimeout = TimeSpan.FromMinutes(10); binding.SendTimeout = TimeSpan.FromMinutes(1); binding.BypassProxyOnLocal = false; binding.TransactionFlow = false; binding.HostNameComparisonMode = HostNameComparisonMode.StrongWildcard; binding.MaxBufferPoolSize = 524288; binding.MaxReceivedMessageSize = 200000000; binding.MessageEncoding = WSMessageEncoding.Text; binding.TextEncoding = System.Text.Encoding.UTF8; binding.UseDefaultWebProxy = true; // binding.TransferMode = TransferMode.Buffered; binding.AllowCookies = false; binding.ReaderQuotas.MaxDepth = 32; binding.ReaderQuotas.MaxStringContentLength = 8192; binding.ReaderQuotas.MaxArrayLength = 200000000; binding.ReaderQuotas.MaxBytesPerRead = 4096; binding.ReaderQuotas.MaxNameTableCharCount = 16384; binding.ReliableSession.Ordered = true; binding.ReliableSession.InactivityTimeout = TimeSpan.Parse("00:10:00"); binding.ReliableSession.Enabled = false; binding.Security.Mode = SecurityMode.Message; binding.Security.Message.ClientCredentialType = MessageCredentialType.UserName; binding.Security.Message.AlgorithmSuite = System.ServiceModel.Security.SecurityAlgorithmSuite.Default; // binding.Security.Message.NegotiateServiceCredential = true; EndpointAddress end = new EndpointAddress("http://services.heuristiclab.com/OKB-3.3/QueryService.svc"); QueryServiceClient client = new QueryServiceClient(binding, end); client.ClientCredentials.UserName.UserName = log; client.ClientCredentials.UserName.Password = pass; client.ClientCredentials.ServiceCertificate.Authentication.CertificateValidationMode = System.ServiceModel.Security.X509CertificateValidationMode.None; return client; } internal bool CheckLogin() { try { this.Refresh(); return true; } catch (MessageSecurityException e) { return false; } catch (SecurityAccessDeniedException e) { return false; } } #endregion } }