#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.IO; using System.Linq; using System.ServiceModel; using HeuristicLab.Clients.Common; using HeuristicLab.Common; using HeuristicLab.Core; using HeuristicLab.Persistence.Default.Xml; namespace HeuristicLab.Clients.OKB.Query { [Item("QueryClient", "OKB query client.")] public sealed class QueryClient : IContent { private static QueryClient instance; public static QueryClient Instance { get { if (instance == null) instance = new QueryClient(); return instance; } } private int endpointRetries; private string workingEndpoint; #region Properties private List filters; public IEnumerable Filters { get { return filters; } } private List valueNames; public IEnumerable ValueNames { get { return valueNames; } } #endregion private QueryClient() { filters = new List(); valueNames = new List(); } #region Refresh public void Refresh() { OnRefreshing(); filters = 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 QueryServiceClient NewServiceClient() { if (endpointRetries >= Properties.Settings.Default.MaxEndpointRetries) return CreateClient(workingEndpoint); var configurations = Properties.Settings.Default.EndpointConfigurationPriorities; Exception exception = null; foreach (var endpointConfigurationName in configurations) { try { var cl = CreateClient(endpointConfigurationName); cl.Open(); workingEndpoint = endpointConfigurationName; return cl; } catch (EndpointNotFoundException e) { exception = e; ++endpointRetries; } } throw exception ?? new EndpointNotFoundException("No endpoint for Query service found."); } private QueryServiceClient CreateClient(string endpointConfigurationName) { var cl = ClientFactory.CreateClient(endpointConfigurationName); return cl; } private T CallQueryService(Func call) { QueryServiceClient client = NewServiceClient(); try { return call(client); } finally { try { client.Close(); } catch (Exception) { client.Abort(); } } } #endregion } }