Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.PluginInfrastructure/Advanced/InstallationManager.cs @ 3038

Last change on this file since 3038 was 3006, checked in by gkronber, 15 years ago

Implemented deployment service on servdev.heuristiclab.com and changed all service references and configurations to point to the service address. Improved GUI of installation manager. Implemented user name authentication and authorization for the deployment service. #860 (Deployment server for plugin installation from web locations)

File size: 11.3 KB
RevLine 
[2612]1#region License Information
2/* HeuristicLab
[2790]3 * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
[2612]4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
[2513]23using System.Collections.Generic;
24using System.Linq;
25using System.Text;
26using HeuristicLab.PluginInfrastructure.Manager;
27using System.IO;
[2517]28using System.ComponentModel;
[2688]29using System.Reflection;
[2922]30using ICSharpCode.SharpZipLib.Zip;
[3006]31using System.ServiceModel;
[2513]32
33namespace HeuristicLab.PluginInfrastructure.Advanced {
[2517]34  internal class InstallationManager {
[2513]35
[2517]36    internal event EventHandler<PluginInfrastructureCancelEventArgs> PreUpdatePlugin;
37    internal event EventHandler<PluginInfrastructureCancelEventArgs> PreRemovePlugin;
38    internal event EventHandler<PluginInfrastructureCancelEventArgs> PreInstallPlugin;
39
40    internal event EventHandler<PluginInfrastructureEventArgs> PluginUpdated;
41    internal event EventHandler<PluginInfrastructureEventArgs> PluginRemoved;
42    internal event EventHandler<PluginInfrastructureEventArgs> PluginInstalled;
43
[2513]44    private string pluginDir;
[2517]45    public InstallationManager(string pluginDir) {
46      this.pluginDir = pluginDir;
[2513]47    }
48
[2922]49    //public IEnumerable<string> Show(IEnumerable<string> pluginNames) {
50    //  foreach (PluginDescription desc in GetPluginDescriptions(pluginNames)) {
51    //    yield return GetInformation(desc);
52    //  }
53    //}
[2513]54
[2922]55    //internal string GetInformation(string pluginName) {
56    //  return GetInformation(GetPluginDescription(pluginName));
57    //}
[2517]58
[2922]59    //private string GetInformation(PluginDescription desc) {
60    //  StringBuilder builder = new StringBuilder();
61    //  builder.Append("Name: ").AppendLine(desc.Name);
62    //  builder.Append("Version: ").AppendLine(desc.Version.ToString());
63    //  builder.AppendLine("Description:").AppendLine(desc.Description);
64    //  if (!string.IsNullOrEmpty(desc.ContactName)) {
65    //    builder.Append("Contact: ").Append(desc.ContactName).Append(", ").AppendLine(desc.ContactEmail);
66    //  }
67    //  builder.AppendLine("This plugin is " + desc.PluginState.ToString().ToLowerInvariant() + ".");
68    //  builder.AppendLine("Files: ");
69    //  foreach (var file in desc.Files) {
70    //    builder.AppendLine(file.Type + " " + file.Name);
71    //  }
72    //  builder.AppendLine().AppendLine("Directly depends on:");
73    //  if (desc.Dependencies.Count() == 0) builder.AppendLine("None");
74    //  foreach (var dependency in desc.Dependencies) {
75    //    builder.AppendLine(dependency.Name + " " + dependency.Version);
76    //  }
77    //  builder.AppendLine().AppendFormat("Plugins directly dependent on {0}:", desc.Name).AppendLine();
78    //  var dependents = from x in pluginManager.Plugins
79    //                   where x.Dependencies.Contains(desc)
80    //                   select x;
81    //  if (dependents.Count() == 0) builder.AppendLine("None");
82    //  foreach (var dependent in dependents) {
83    //    builder.AppendLine(dependent.Name + " " + dependent.Version);
84    //  }
85    //  builder.AppendLine();
86    //  if (desc.PluginState == PluginState.Disabled) {
87    //    builder.AppendLine(DetermineProblem(desc));
88    //  }
[2513]89
[2922]90    //  return builder.ToString();
91    //}
[2513]92
[2922]93    //private static string DetermineProblem(PluginDescription desc) {
94    //  // either any file is missing
95    //  StringBuilder builder = new StringBuilder();
96    //  builder.AppendLine("Problem report:");
97    //  builder.AppendLine(desc.LoadingErrorInformation);
98    //  return builder.ToString();
99    //}
[2517]100
[2922]101    //private PluginDescription GetPluginDescription(string pluginName) {
102    //  var exactMatch = from pluginDesc in pluginManager.Plugins
103    //                   where string.Equals(pluginName, pluginDesc.Name, StringComparison.InvariantCultureIgnoreCase)
104    //                   select pluginDesc;
105    //  var inexactMatch = from pluginDesc in pluginManager.Plugins
106    //                     where MatchPluginNameInexact(pluginName, pluginDesc.Name)
107    //                     select pluginDesc;
108    //  return exactMatch.Count() > 0 ? exactMatch.Single() : inexactMatch.First();
109    //}
[2517]110
[2922]111    //private IEnumerable<PluginDescription> GetPluginDescriptions(IEnumerable<string> pluginNames) {
112    //  return from pluginName in pluginNames
113    //         select GetPluginDescription(pluginName);
114    //}
115
116    //private static bool MatchPluginNameInexact(string similarName, string actualName) {
117    //  return
118    //    // Core-3.2 == HeuristicLab.Core-3.2
119    //    actualName.Equals("HeuristicLab." + similarName, StringComparison.InvariantCultureIgnoreCase) ||
120    //    // HeuristicLab.Core == HeuristicLab.Core-3.2 (this should be save because we checked for exact matches first)
121    //    (Math.Abs(actualName.Length - similarName.Length) <= 4 && actualName.StartsWith(similarName, StringComparison.InvariantCultureIgnoreCase)) ||
122    //    // Core == HeuristicLab.Core-3.2
123    //    (Math.Abs(actualName.Length - similarName.Length) <= 17 && actualName.StartsWith("HeuristicLab." + similarName, StringComparison.InvariantCultureIgnoreCase));
124    //}
125
126
127    /// <summary>
128    /// Retrieves a list of plugins available at the remote server
129    /// </summary>
130    /// <param name="connectionString"></param>
131    /// <returns></returns>
[3006]132    public IEnumerable<IPluginDescription> GetRemotePluginList() {
133      var client = DeploymentService.UpdateClientFactory.CreateClient();
134      try {
135        List<IPluginDescription> plugins = new List<IPluginDescription>(client.GetPlugins());
136        client.Close();
137        return plugins;
[2922]138      }
[3006]139      catch (FaultException) {
140        client.Abort();
141        return new IPluginDescription[] { };
142      }
[2517]143    }
144
[2922]145    /// <summary>
146    /// Retrieves the list of products available at the remote server
147    /// </summary>
148    /// <param name="connectionString"></param>
149    /// <returns></returns>
[3006]150    public IEnumerable<DeploymentService.ProductDescription> GetRemoteProductList() {
151      var client = DeploymentService.UpdateClientFactory.CreateClient();
152      try {
153        List<DeploymentService.ProductDescription> products = new List<DeploymentService.ProductDescription>(client.GetProducts());
154        client.Close();
155        return products;
[2922]156      }
[3006]157      catch (FaultException) {
158        client.Abort();
159        return new DeploymentService.ProductDescription[] { };
160      }
[2513]161    }
162
[2922]163    /// <summary>
164    ///  Installs plugins from remote server
165    /// </summary>
166    /// <param name="connectionString"></param>
167    /// <param name="pluginNames"></param>
[3006]168    public void Install(IEnumerable<IPluginDescription> plugins) {
169      var args = new PluginInfrastructureCancelEventArgs(plugins);
170      OnPreInstall(args);
171      if (!args.Cancel) {
172        var client = DeploymentService.UpdateClientFactory.CreateClient();
173        try {
174          foreach (DeploymentService.PluginDescription plugin in plugins) {
175            byte[] zippedPackage = client.GetPlugin(plugin);
176            Unpack(zippedPackage);
177            OnInstalled(new PluginInfrastructureEventArgs(plugin));
178          }
179          client.Close();
[2922]180        }
[3006]181        catch (FaultException) {
182          client.Abort();
183        }
[2922]184      }
[2517]185    }
186
[2922]187    /// <summary>
188    /// Updates plugins from remote server
189    /// </summary>
190    /// <param name="pluginNames"></param>
[3006]191    public void Update(IEnumerable<IPluginDescription> plugins) {
192      PluginInfrastructureCancelEventArgs args = new PluginInfrastructureCancelEventArgs(plugins);
[2922]193      OnPreUpdate(args);
194      if (!args.Cancel) {
[3006]195        var client = DeploymentService.UpdateClientFactory.CreateClient();
196        try {
[2922]197          foreach (DeploymentService.PluginDescription plugin in plugins) {
198            byte[] zippedPackage = client.GetPlugin(plugin);
199            Unpack(zippedPackage);
200            OnUpdated(new PluginInfrastructureEventArgs(plugin));
201          }
[3006]202          client.Close();
[2922]203        }
[3006]204        catch (FaultException) {
205          client.Abort();
206        }
[2922]207      }
[2513]208    }
209
[2922]210    /// <summary>
211    /// Deletes all plugin files from local installation
212    /// </summary>
213    /// <param name="pluginNames"></param>
214    public void Remove(IEnumerable<IPluginDescription> plugins) {
215      var fileNames = from pluginToDelete in plugins
[2688]216                      from file in pluginToDelete.Files
217                      select Path.Combine(pluginDir, file.Name);
[3006]218      var args = new PluginInfrastructureCancelEventArgs(plugins);
[2517]219      OnPreDelete(args);
220      if (!args.Cancel) {
221        foreach (string fileName in fileNames) {
[2922]222          File.Delete(fileName);
223          OnDeleted(new PluginInfrastructureEventArgs(fileName));
[2513]224        }
225      }
226    }
227
[2922]228    private void Unpack(byte[] zippedPackage) {
229      using (ZipInputStream s = new ZipInputStream(new MemoryStream(zippedPackage))) {
230        ZipEntry theEntry;
231        string tmpEntry = String.Empty;
232        while ((theEntry = s.GetNextEntry()) != null) {
233          string directoryName = pluginDir;
234          string fileName = Path.GetFileName(theEntry.Name);
235          // create directory
236          if (directoryName != "") {
237            Directory.CreateDirectory(directoryName);
[2527]238          }
[2922]239          if (fileName != String.Empty) {
240            string fullPath = Path.Combine(directoryName, fileName);
241            string fullDirPath = Path.GetDirectoryName(fullPath);
242            if (!Directory.Exists(fullDirPath)) Directory.CreateDirectory(fullDirPath);
243            FileStream streamWriter = File.Create(fullPath);
244            int size = 2048;
245            byte[] data = new byte[2048];
246            while (true) {
247              size = s.Read(data, 0, data.Length);
248              if (size > 0) {
249                streamWriter.Write(data, 0, size);
250              } else {
251                break;
252              }
[2527]253            }
[2922]254            streamWriter.Close();
[2527]255          }
256        }
257      }
[2513]258    }
[2517]259
[2527]260    private void OnPreUpdate(PluginInfrastructureCancelEventArgs args) {
261      if (PreUpdatePlugin != null) PreUpdatePlugin(this, args);
262    }
263
264    private void OnUpdated(PluginInfrastructureEventArgs args) {
265      if (PluginUpdated != null) PluginUpdated(this, args);
266    }
267
[2517]268    private void OnPreDelete(PluginInfrastructureCancelEventArgs args) {
269      if (PreRemovePlugin != null) PreRemovePlugin(this, args);
270    }
271
272    private void OnDeleted(PluginInfrastructureEventArgs args) {
273      if (PluginRemoved != null) PluginRemoved(this, args);
274    }
275
276    private void OnPreInstall(PluginInfrastructureCancelEventArgs args) {
277      if (PreInstallPlugin != null) PreInstallPlugin(this, args);
278    }
279
280    private void OnInstalled(PluginInfrastructureEventArgs args) {
281      if (PluginInstalled != null) PluginInstalled(this, args);
282    }
[2513]283  }
284}
Note: See TracBrowser for help on using the repository browser.