using System; using System.Diagnostics; using System.Timers; using System.Windows.Forms; using HeuristicLab.Clients.Hive.CloudManager.Model; using HeuristicLab.Common; using HeuristicLab.Core; using HeuristicLab.Core.Views; using HeuristicLab.MainForm; namespace HeuristicLab.Clients.Hive.CloudManager.Views { [View("Cloud Resources View")] [Content(typeof(IItemList), IsDefaultView = true)] public partial class CloudResourcesView : ItemView, IDisposable { private System.Timers.Timer timer = new System.Timers.Timer(); private int updateInterval = 15000; private DateTime dueTime; private const int subscriptionImageIndex = 0; private const int serviceImageIndex = 1; private const int deploymentImageIndex = 2; public new IItemList Content { get { return (IItemList)base.Content; } set { base.Content = value; } } private IItemList hostedServices; public IItemList HostedServices { get { return hostedServices; } set { hostedServices = value; } } public CloudResourcesView() { InitializeComponent(); treeCloudResources.ImageList.Images.Add(HeuristicLab.Common.Resources.VSImageLibrary.NewFolder); treeCloudResources.ImageList.Images.Add(HeuristicLab.Common.Resources.VSImageLibrary.NetworkCenterLarge); treeCloudResources.ImageList.Images.Add(HeuristicLab.Common.Resources.VSImageLibrary.MonitorLarge); HostedServices = CloudManagerClient.Instance.HostedServices; Content = CloudManagerClient.Instance.Subscriptions; CloudManagerClient.Instance.Refreshing += new EventHandler(Instance_Refreshing); CloudManagerClient.Instance.Refreshed += new EventHandler(Instance_Refreshed); timer.AutoReset = true; timer.Interval = 1000; timer.Elapsed += PerformUpdate; timer.Start(); dueTime = DateTime.Now.AddMilliseconds(updateInterval); } #region Register Content Events protected override void DeregisterContentEvents() { Content.ItemsAdded -= new Collections.CollectionItemsChangedEventHandler>(Content_ItemsAdded); Content.ItemsRemoved -= new Collections.CollectionItemsChangedEventHandler>(Content_ItemsRemoved); base.DeregisterContentEvents(); } protected override void RegisterContentEvents() { base.RegisterContentEvents(); Content.ItemsAdded += new Collections.CollectionItemsChangedEventHandler>(Content_ItemsAdded); Content.ItemsRemoved += new Collections.CollectionItemsChangedEventHandler>(Content_ItemsRemoved); } #endregion /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); CloudManagerClient.Instance.Refreshing -= new EventHandler(Instance_Refreshing); CloudManagerClient.Instance.Refreshed -= new EventHandler(Instance_Refreshed); timer.Stop(); timer.Dispose(); timer = null; } base.Dispose(disposing); } protected override void SetEnabledStateOfControls() { base.SetEnabledStateOfControls(); if (Content == null || Content.Count == 0) { btnAddSlaveService.Enabled = false; btnDelete.Enabled = false; btnSave.Enabled = false; } else { btnAddSlaveService.Enabled = true; btnDelete.Enabled = true; btnSave.Enabled = true; } } protected override void OnContentChanged() { base.OnContentChanged(); SetEnabledStateOfControls(); if (Content == null) { viewHost.Content = null; treeCloudResources.Nodes.Clear(); } else { treeCloudResources.BeginUpdate(); treeCloudResources.Nodes.Clear(); foreach (Subscription sub in Content) { TreeNode nodeSub = new TreeNode(); nodeSub.Tag = sub; nodeSub.Text = sub.SubscriptionName; nodeSub.ImageIndex = subscriptionImageIndex; nodeSub.SelectedImageIndex = nodeSub.ImageIndex; foreach (HostedService s in HostedServices) { if (s.Subscription.SubscriptionID == sub.SubscriptionID) { TreeNode nodeServ = new TreeNode(); nodeServ.Tag = s; nodeServ.Text = s.HostedServiceProperties.Label; nodeServ.ImageIndex = serviceImageIndex; nodeServ.SelectedImageIndex = nodeServ.ImageIndex; foreach (Deployment d in s.Deployments) { TreeNode nodeDepl = new TreeNode(); nodeDepl.Tag = d; nodeDepl.Text = d.Label + " (" + d.DeploymentSlot + ")"; nodeDepl.ImageIndex = deploymentImageIndex; nodeDepl.SelectedImageIndex = nodeDepl.ImageIndex; nodeServ.Nodes.Add(nodeDepl); } nodeSub.Nodes.Add(nodeServ); } } treeCloudResources.Nodes.Add(nodeSub); } treeCloudResources.EndUpdate(); } } private void Instance_Refreshing(object sender, EventArgs e) { Debug.WriteLine("Instance_Refreshing"); //if (treeCloudResources.InvokeRequired) { // treeCloudResources.Invoke((MethodInvoker)delegate { OnContentChanged(); }); //} else { // OnContentChanged(); //} } private void Instance_Refreshed(object sender, EventArgs e) { Debug.WriteLine("Instance_Refreshed"); if (treeCloudResources.InvokeRequired) { treeCloudResources.Invoke((MethodInvoker)delegate { OnContentChanged(); }); } else { OnContentChanged(); } } private void Content_ItemsRemoved(object sender, Collections.CollectionItemsChangedEventArgs> e) { OnContentChanged(); } private void Content_ItemsAdded(object sender, Collections.CollectionItemsChangedEventArgs> e) { OnContentChanged(); } private void PerformUpdate(object sender, ElapsedEventArgs e) { TimeSpan timeToRefresh = dueTime - DateTime.Now; if (timeToRefresh.Seconds >= 0) { this.Invoke((MethodInvoker)delegate { lblRefresh.Text = "Done. " + timeToRefresh.Seconds + "s to next refresh."; }); } else { timer.Stop(); this.Invoke((MethodInvoker)delegate { lblRefresh.Text = "Refreshing data ..."; }); // statistics Debug.WriteLine("perform update"); CloudManagerClient.Instance.Refresh(); dueTime = DateTime.Now.AddMilliseconds(updateInterval); if (timer != null) { timer.Start(); } } } private void btnAddSubscription_Click(object sender, EventArgs e) { using (var form = new AddSubscriptionDialog()) { form.ShowDialog(); if (!form.ErrorOccured) { if (form.Subscription != null) { Subscription sub = form.Subscription; CloudManagerClient.Instance.Add(sub); } } } } private void btnAddSlaveService_Click(object sender, EventArgs e) { // When refreshing subscriptions in the dialog, // discoverservices and safetoconfig properties are always set to false // -> work on deep copy Cloner cloner = new Cloner(); IItemList subscriptions = cloner.Clone(Content); using (var form = new AddAzureServiceDialog(subscriptions)) { form.ShowDialog(); } } private void treeCloudResources_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e) { viewHost.Content = (IContent)e.Node.Tag; } } }