From 2faacfcaa5332e7d295dd38ba46ecb43c379b465 Mon Sep 17 00:00:00 2001 From: Matthew Christopher Date: Tue, 20 Aug 2019 15:55:48 -0700 Subject: [PATCH] Set up CI with Azure Pipelines (#280) * Set up CI with Azure Pipelines [skip ci] * Update azure-pipelines.yml * Update azure-pipelines.yml for Azure Pipelines * Update azure-pipelines.yml for Azure Pipelines * Update azure-pipelines.yml for Azure Pipelines * Update azure-pipelines.yml for Azure Pipelines * Update azure-pipelines.yml for Azure Pipelines * Remove deprecated BatchExplorer * Remove deprecated BE desc text --- CSharp/BatchExplorer/App.config | 25 - CSharp/BatchExplorer/App.xaml | 6 - .../BatchExplorer/Assets/Icons/add_all_24.png | Bin 310 -> 0 bytes .../Assets/Icons/add_incremental_24.png | Bin 311 -> 0 bytes .../BatchExplorer/Assets/Icons/refresh_24.png | Bin 685 -> 0 bytes CSharp/BatchExplorer/BatchExplorer.csproj | 430 ---- CSharp/BatchExplorer/BatchExplorer.jpg | Bin 263987 -> 0 bytes CSharp/BatchExplorer/BatchExplorer.sln | 22 - .../Converters/BoolToVisibilityConverter.cs | 32 - .../Converters/BooleanAndConverter.cs | 35 - .../Converters/EnumToStringConverter.cs | 27 - .../InvertedBoolToVisibilityConverter.cs | 33 - .../Converters/InvertedBooleanConverter.cs | 39 - .../Converters/IsNotNullToBooleanConverter.cs | 23 - .../Converters/IsNullToBooleanConverter.cs | 23 - .../JobScheduleStateColorConverter.cs | 47 - .../Converters/JobStateColorConverter.cs | 46 - .../Converters/NullToVisibilityConverter.cs | 32 - .../PoolAllocationStateColorConverter.cs | 43 - .../Converters/TaskStatusColorConverter.cs | 44 - .../Helpers/AccountManagerContainer.cs | 18 - .../Helpers/AsyncOperationTracker.cs | 175 -- .../Helpers/BasicDataProvider.cs | 163 -- CSharp/BatchExplorer/Helpers/Cached.cs | 31 - .../Helpers/ChangeTrackedAttribute.cs | 28 - CSharp/BatchExplorer/Helpers/CommandBase.cs | 64 - CSharp/BatchExplorer/Helpers/Common.cs | 133 -- CSharp/BatchExplorer/Helpers/EntityBase.cs | 51 - .../Helpers/EnumerableExtensions.cs | 25 - CSharp/BatchExplorer/Helpers/Exceptions.cs | 10 - CSharp/BatchExplorer/Helpers/IDataProvider.cs | 123 -- CSharp/BatchExplorer/Helpers/Operations.cs | 201 -- .../Helpers/ResourceFileStringParser.cs | 77 - .../BatchExplorer/Helpers/WaitSpinnerPanel.cs | 6 - CSharp/BatchExplorer/Images/LeftArrow.png | Bin 1911 -> 0 bytes CSharp/BatchExplorer/Images/RightArrow.png | Bin 1935 -> 0 bytes CSharp/BatchExplorer/Images/add.png | Bin 344 -> 0 bytes CSharp/BatchExplorer/Images/azure.png | Bin 74078 -> 0 bytes CSharp/BatchExplorer/Images/backArrow.png | Bin 25627 -> 0 bytes CSharp/BatchExplorer/Images/batchExplorer.ico | Bin 9062 -> 0 bytes CSharp/BatchExplorer/Images/cancel.png | Bin 516 -> 0 bytes CSharp/BatchExplorer/Images/check.png | Bin 684 -> 0 bytes CSharp/BatchExplorer/Images/delete.png | Bin 667 -> 0 bytes .../BatchExplorer/Images/feature.heatmap.png | Bin 711 -> 0 bytes .../BatchExplorer/Images/feature.settings.png | Bin 806 -> 0 bytes CSharp/BatchExplorer/Images/forwardArrow.png | Bin 25924 -> 0 bytes .../BatchExplorer/Images/magnifyingGlass.png | Bin 15859 -> 0 bytes CSharp/BatchExplorer/Images/refresh.png | Bin 818 -> 0 bytes CSharp/BatchExplorer/Images/search.ico | Bin 92176 -> 0 bytes CSharp/BatchExplorer/Images/share.png | Bin 827 -> 0 bytes .../Messages/AddAccountMessage.cs | 14 - .../AsyncOperationListChangedMessage.cs | 12 - .../CertificateUpdateCompleteMessage.cs | 12 - .../Messages/CloseGenericMessage.cs | 8 - .../Messages/CloseGenericPopup.cs | 11 - .../Messages/ComputeNodeUserActionMessage.cs | 35 - .../Messages/ConfirmAccountAddMessage.cs | 16 - .../Messages/ConfirmAccountDeleteMessage.cs | 11 - .../Messages/ConfirmAccountEditMessage.cs | 16 - ...chedulingComputeNodeConfirmationMessage.cs | 20 - .../DisableSchedulingComputeNodeMessage.cs | 8 - .../Messages/EditAccountMessage.cs | 14 - .../EnableSchedulingComputeNodeMessage.cs | 8 - .../Messages/GenericDialogMessage.cs | 23 - .../HeatMapPollIntervalUpdatedMessage.cs | 16 - .../Messages/JobUpdateCompleteMessage.cs | 11 - .../LaunchMultibuttonDialogMessage.cs | 35 - .../Messages/ModelNotFoundAfterRefresh.cs | 16 - .../MultibuttonDialogReturnMessage.cs | 25 - .../Messages/NodeSchedulingMessage.cs | 23 - .../Messages/PoolUpdateCompleteMessage.cs | 11 - .../RebootComputeNodeConfirmationMessage.cs | 20 - .../Messages/RebootComputeNodeMessage.cs | 8 - .../BatchExplorer/Messages/RefreshMessage.cs | 22 - .../ReimageComputeNodeConfirmationMessage.cs | 20 - .../Messages/ReimageComputeNodeMessage.cs | 8 - .../BatchExplorer/Messages/ShowAboutWindow.cs | 11 - .../Messages/ShowAddTaskWindow.cs | 14 - .../ShowAsyncOperationDetailWindow.cs | 16 - .../Messages/ShowAsyncOperationTabMessage.cs | 14 - .../Messages/ShowCreateCertificateWindow.cs | 12 - .../ShowCreateComputeNodeUserWindow.cs | 16 - .../Messages/ShowCreateJobScheduleWindow.cs | 11 - .../Messages/ShowCreateJobWindow.cs | 11 - .../Messages/ShowCreatePoolWindow.cs | 18 - .../Messages/ShowDeleteWarningMessage.cs | 11 - .../Messages/ShowHeatMapMessage.cs | 16 - .../Messages/ShowOptionsDialogMessage.cs | 12 - .../Messages/ShowResizePoolWindow.cs | 20 - .../Messages/UpdateWaitSpinnerMessage.cs | 31 - CSharp/BatchExplorer/Models/Account.cs | 70 - CSharp/BatchExplorer/Models/AddTaskOptions.cs | 29 - .../Models/AsyncOperationModel.cs | 206 -- .../BatchExplorer/Models/CertificateModel.cs | 116 -- .../CloudServiceConfigurationOptions.cs | 9 - .../BatchExplorer/Models/ComputeNodeFile.cs | 44 - .../BatchExplorer/Models/ComputeNodeModel.cs | 393 ---- .../Models/CreateAutoPoolOptions.cs | 25 - .../Models/CreateCertificateOptions.cs | 18 - .../Models/CreateJobManagerOptions.cs | 25 - .../BatchExplorer/Models/CreateJobOptions.cs | 25 - .../Models/CreateJobScheduleOptions.cs | 34 - CSharp/BatchExplorer/Models/Field.cs | 22 - CSharp/BatchExplorer/Models/HeatmapModel.cs | 182 -- CSharp/BatchExplorer/Models/JobModel.cs | 404 ---- .../BatchExplorer/Models/JobScheduleModel.cs | 331 --- CSharp/BatchExplorer/Models/ModelBase.cs | 173 -- CSharp/BatchExplorer/Models/OptionsModel.cs | 169 -- CSharp/BatchExplorer/Models/Pool.cs | 14 - CSharp/BatchExplorer/Models/PoolModel.cs | 284 --- .../Models/PropertyDisplayModel.cs | 73 - .../BatchExplorer/Models/ResourceFileInfo.cs | 30 - .../BatchExplorer/Models/StartTaskOptions.cs | 17 - CSharp/BatchExplorer/Models/SubtaskModel.cs | 56 - CSharp/BatchExplorer/Models/TaskModel.cs | 402 ---- .../VirtualMachineConfigurationOptions.cs | 18 - CSharp/BatchExplorer/Models/WorkItem.cs | 14 - .../AccountManagementAddOperation.cs | 30 - .../AccountManagementEditOperation.cs | 30 - .../AccountManagementOperation.cs | 33 - .../AccountPlugin/IAccountAdder.cs | 18 - .../AccountPlugin/IAccountEditor.cs | 18 - .../AccountPlugin/IAccountManager.cs | 75 - .../AccountPlugin/IAccountManagerMetadata.cs | 15 - .../AccountPlugin/IAccountOperationFactory.cs | 15 - .../Plugins/AccountPlugin/DefaultAccount.cs | 80 - .../DefaultAccountDialogViewModel.cs | 98 - .../DefaultAccountManagementControl.xaml | 58 - .../DefaultAccountManagementControl.xaml.cs | 22 - .../AccountPlugin/DefaultAccountManager.cs | 341 ---- .../DefaultAccountOperationFactory.cs | 48 - .../DefaultAccountSerializationContainer.cs | 40 - .../AccountPlugin/SerializableAccount.cs | 53 - .../LegacyAccountSupport/LegacyAccount.cs | 33 - .../LegacyAccountManager.cs | 24 - .../BatchExplorer/Properties/AssemblyInfo.cs | 55 - .../Properties/Resources.Designer.cs | 63 - .../BatchExplorer/Properties/Resources.resx | 117 -- .../Properties/Settings.Designer.cs | 26 - .../Properties/Settings.settings | 7 - CSharp/BatchExplorer/README.md | 32 - CSharp/BatchExplorer/Service/BatchService.cs | 496 ----- .../BatchExplorer/Styles/ExplorerStyles.xaml | 419 ---- .../ViewModels/AccountDialogViewModel.cs | 81 - .../ViewModels/AddTaskViewModel.cs | 277 --- .../AsyncOperationDetailsViewModel.cs | 21 - .../ViewModels/CreateCertificateViewModel.cs | 167 -- .../CreateComputeNodeUserViewModel.cs | 179 -- .../ViewModels/CreateJobScheduleViewModel.cs | 616 ------ .../ViewModels/CreateJobViewModel.cs | 551 ----- .../ViewModels/CreatePoolViewModel.cs | 668 ------ .../ViewModels/GenericMessageViewModel.cs | 31 - .../ViewModels/HeatmapViewModel.cs | 50 - .../BatchExplorer/ViewModels/MainViewModel.cs | 1808 ----------------- .../ViewModels/OptionsViewModel.cs | 86 - .../ViewModels/ResizePoolViewModel.cs | 333 --- CSharp/BatchExplorer/Views/AboutWindow.xaml | 22 - .../BatchExplorer/Views/AboutWindow.xaml.cs | 17 - .../Views/AccountManagementControl.xaml | 42 - .../Views/AccountManagementControl.xaml.cs | 25 - .../Views/AsyncOperationDetailsControl.xaml | 162 -- .../AsyncOperationDetailsControl.xaml.cs | 23 - .../Views/CreateControls/AddTaskControl.xaml | 213 -- .../CreateControls/AddTaskControl.xaml.cs | 23 - .../CreateCertificateControl.xaml | 67 - .../CreateCertificateControl.xaml.cs | 34 - .../CreateComputeNodeUserControl.xaml | 203 -- .../CreateComputeNodeUserControl.xaml.cs | 23 - .../CreateControls/CreateJobControl.xaml | 456 ----- .../CreateControls/CreateJobControl.xaml.cs | 23 - .../CreateJobScheduleControl.xaml | 559 ----- .../CreateJobScheduleControl.xaml.cs | 23 - .../CreateControls/CreatePoolControl.xaml | 503 ----- .../CreateControls/CreatePoolControl.xaml.cs | 23 - .../CreateControls/ResizePoolControl.xaml | 175 -- .../CreateControls/ResizePoolControl.xaml.cs | 23 - .../Views/GenericEmptyWindow.xaml | 8 - .../Views/GenericEmptyWindow.xaml.cs | 17 - .../Views/GenericMessageControl.xaml | 48 - .../Views/GenericMessageControl.xaml.cs | 23 - .../BatchExplorer/Views/HeatmapControl.xaml | 193 -- .../Views/HeatmapControl.xaml.cs | 310 --- CSharp/BatchExplorer/Views/LogIn.xaml | 121 -- CSharp/BatchExplorer/Views/LogIn.xaml.cs | 87 - CSharp/BatchExplorer/Views/MainView.xaml | 1396 ------------- CSharp/BatchExplorer/Views/MainView.xaml.cs | 475 ----- .../BatchExplorer/Views/OptionsControl.xaml | 84 - .../Views/OptionsControl.xaml.cs | 23 - CSharp/BatchExplorer/Views/WaitSpinner.xaml | 144 -- .../BatchExplorer/Views/WaitSpinner.xaml.cs | 46 - CSharp/BatchExplorer/packages.config | 11 - CSharp/README.md | 7 +- azure-pipelines.yml | 59 + 193 files changed, 60 insertions(+), 18576 deletions(-) delete mode 100644 CSharp/BatchExplorer/App.config delete mode 100644 CSharp/BatchExplorer/App.xaml delete mode 100644 CSharp/BatchExplorer/Assets/Icons/add_all_24.png delete mode 100644 CSharp/BatchExplorer/Assets/Icons/add_incremental_24.png delete mode 100644 CSharp/BatchExplorer/Assets/Icons/refresh_24.png delete mode 100644 CSharp/BatchExplorer/BatchExplorer.csproj delete mode 100644 CSharp/BatchExplorer/BatchExplorer.jpg delete mode 100644 CSharp/BatchExplorer/BatchExplorer.sln delete mode 100644 CSharp/BatchExplorer/Converters/BoolToVisibilityConverter.cs delete mode 100644 CSharp/BatchExplorer/Converters/BooleanAndConverter.cs delete mode 100644 CSharp/BatchExplorer/Converters/EnumToStringConverter.cs delete mode 100644 CSharp/BatchExplorer/Converters/InvertedBoolToVisibilityConverter.cs delete mode 100644 CSharp/BatchExplorer/Converters/InvertedBooleanConverter.cs delete mode 100644 CSharp/BatchExplorer/Converters/IsNotNullToBooleanConverter.cs delete mode 100644 CSharp/BatchExplorer/Converters/IsNullToBooleanConverter.cs delete mode 100644 CSharp/BatchExplorer/Converters/JobScheduleStateColorConverter.cs delete mode 100644 CSharp/BatchExplorer/Converters/JobStateColorConverter.cs delete mode 100644 CSharp/BatchExplorer/Converters/NullToVisibilityConverter.cs delete mode 100644 CSharp/BatchExplorer/Converters/PoolAllocationStateColorConverter.cs delete mode 100644 CSharp/BatchExplorer/Converters/TaskStatusColorConverter.cs delete mode 100644 CSharp/BatchExplorer/Helpers/AccountManagerContainer.cs delete mode 100644 CSharp/BatchExplorer/Helpers/AsyncOperationTracker.cs delete mode 100644 CSharp/BatchExplorer/Helpers/BasicDataProvider.cs delete mode 100644 CSharp/BatchExplorer/Helpers/Cached.cs delete mode 100644 CSharp/BatchExplorer/Helpers/ChangeTrackedAttribute.cs delete mode 100644 CSharp/BatchExplorer/Helpers/CommandBase.cs delete mode 100644 CSharp/BatchExplorer/Helpers/Common.cs delete mode 100644 CSharp/BatchExplorer/Helpers/EntityBase.cs delete mode 100644 CSharp/BatchExplorer/Helpers/EnumerableExtensions.cs delete mode 100644 CSharp/BatchExplorer/Helpers/Exceptions.cs delete mode 100644 CSharp/BatchExplorer/Helpers/IDataProvider.cs delete mode 100644 CSharp/BatchExplorer/Helpers/Operations.cs delete mode 100644 CSharp/BatchExplorer/Helpers/ResourceFileStringParser.cs delete mode 100644 CSharp/BatchExplorer/Helpers/WaitSpinnerPanel.cs delete mode 100644 CSharp/BatchExplorer/Images/LeftArrow.png delete mode 100644 CSharp/BatchExplorer/Images/RightArrow.png delete mode 100644 CSharp/BatchExplorer/Images/add.png delete mode 100644 CSharp/BatchExplorer/Images/azure.png delete mode 100644 CSharp/BatchExplorer/Images/backArrow.png delete mode 100644 CSharp/BatchExplorer/Images/batchExplorer.ico delete mode 100644 CSharp/BatchExplorer/Images/cancel.png delete mode 100644 CSharp/BatchExplorer/Images/check.png delete mode 100644 CSharp/BatchExplorer/Images/delete.png delete mode 100644 CSharp/BatchExplorer/Images/feature.heatmap.png delete mode 100644 CSharp/BatchExplorer/Images/feature.settings.png delete mode 100644 CSharp/BatchExplorer/Images/forwardArrow.png delete mode 100644 CSharp/BatchExplorer/Images/magnifyingGlass.png delete mode 100644 CSharp/BatchExplorer/Images/refresh.png delete mode 100644 CSharp/BatchExplorer/Images/search.ico delete mode 100644 CSharp/BatchExplorer/Images/share.png delete mode 100644 CSharp/BatchExplorer/Messages/AddAccountMessage.cs delete mode 100644 CSharp/BatchExplorer/Messages/AsyncOperationListChangedMessage.cs delete mode 100644 CSharp/BatchExplorer/Messages/CertificateUpdateCompleteMessage.cs delete mode 100644 CSharp/BatchExplorer/Messages/CloseGenericMessage.cs delete mode 100644 CSharp/BatchExplorer/Messages/CloseGenericPopup.cs delete mode 100644 CSharp/BatchExplorer/Messages/ComputeNodeUserActionMessage.cs delete mode 100644 CSharp/BatchExplorer/Messages/ConfirmAccountAddMessage.cs delete mode 100644 CSharp/BatchExplorer/Messages/ConfirmAccountDeleteMessage.cs delete mode 100644 CSharp/BatchExplorer/Messages/ConfirmAccountEditMessage.cs delete mode 100644 CSharp/BatchExplorer/Messages/DisableSchedulingComputeNodeConfirmationMessage.cs delete mode 100644 CSharp/BatchExplorer/Messages/DisableSchedulingComputeNodeMessage.cs delete mode 100644 CSharp/BatchExplorer/Messages/EditAccountMessage.cs delete mode 100644 CSharp/BatchExplorer/Messages/EnableSchedulingComputeNodeMessage.cs delete mode 100644 CSharp/BatchExplorer/Messages/GenericDialogMessage.cs delete mode 100644 CSharp/BatchExplorer/Messages/HeatMapPollIntervalUpdatedMessage.cs delete mode 100644 CSharp/BatchExplorer/Messages/JobUpdateCompleteMessage.cs delete mode 100644 CSharp/BatchExplorer/Messages/LaunchMultibuttonDialogMessage.cs delete mode 100644 CSharp/BatchExplorer/Messages/ModelNotFoundAfterRefresh.cs delete mode 100644 CSharp/BatchExplorer/Messages/MultibuttonDialogReturnMessage.cs delete mode 100644 CSharp/BatchExplorer/Messages/NodeSchedulingMessage.cs delete mode 100644 CSharp/BatchExplorer/Messages/PoolUpdateCompleteMessage.cs delete mode 100644 CSharp/BatchExplorer/Messages/RebootComputeNodeConfirmationMessage.cs delete mode 100644 CSharp/BatchExplorer/Messages/RebootComputeNodeMessage.cs delete mode 100644 CSharp/BatchExplorer/Messages/RefreshMessage.cs delete mode 100644 CSharp/BatchExplorer/Messages/ReimageComputeNodeConfirmationMessage.cs delete mode 100644 CSharp/BatchExplorer/Messages/ReimageComputeNodeMessage.cs delete mode 100644 CSharp/BatchExplorer/Messages/ShowAboutWindow.cs delete mode 100644 CSharp/BatchExplorer/Messages/ShowAddTaskWindow.cs delete mode 100644 CSharp/BatchExplorer/Messages/ShowAsyncOperationDetailWindow.cs delete mode 100644 CSharp/BatchExplorer/Messages/ShowAsyncOperationTabMessage.cs delete mode 100644 CSharp/BatchExplorer/Messages/ShowCreateCertificateWindow.cs delete mode 100644 CSharp/BatchExplorer/Messages/ShowCreateComputeNodeUserWindow.cs delete mode 100644 CSharp/BatchExplorer/Messages/ShowCreateJobScheduleWindow.cs delete mode 100644 CSharp/BatchExplorer/Messages/ShowCreateJobWindow.cs delete mode 100644 CSharp/BatchExplorer/Messages/ShowCreatePoolWindow.cs delete mode 100644 CSharp/BatchExplorer/Messages/ShowDeleteWarningMessage.cs delete mode 100644 CSharp/BatchExplorer/Messages/ShowHeatMapMessage.cs delete mode 100644 CSharp/BatchExplorer/Messages/ShowOptionsDialogMessage.cs delete mode 100644 CSharp/BatchExplorer/Messages/ShowResizePoolWindow.cs delete mode 100644 CSharp/BatchExplorer/Messages/UpdateWaitSpinnerMessage.cs delete mode 100644 CSharp/BatchExplorer/Models/Account.cs delete mode 100644 CSharp/BatchExplorer/Models/AddTaskOptions.cs delete mode 100644 CSharp/BatchExplorer/Models/AsyncOperationModel.cs delete mode 100644 CSharp/BatchExplorer/Models/CertificateModel.cs delete mode 100644 CSharp/BatchExplorer/Models/CloudServiceConfigurationOptions.cs delete mode 100644 CSharp/BatchExplorer/Models/ComputeNodeFile.cs delete mode 100644 CSharp/BatchExplorer/Models/ComputeNodeModel.cs delete mode 100644 CSharp/BatchExplorer/Models/CreateAutoPoolOptions.cs delete mode 100644 CSharp/BatchExplorer/Models/CreateCertificateOptions.cs delete mode 100644 CSharp/BatchExplorer/Models/CreateJobManagerOptions.cs delete mode 100644 CSharp/BatchExplorer/Models/CreateJobOptions.cs delete mode 100644 CSharp/BatchExplorer/Models/CreateJobScheduleOptions.cs delete mode 100644 CSharp/BatchExplorer/Models/Field.cs delete mode 100644 CSharp/BatchExplorer/Models/HeatmapModel.cs delete mode 100644 CSharp/BatchExplorer/Models/JobModel.cs delete mode 100644 CSharp/BatchExplorer/Models/JobScheduleModel.cs delete mode 100644 CSharp/BatchExplorer/Models/ModelBase.cs delete mode 100644 CSharp/BatchExplorer/Models/OptionsModel.cs delete mode 100644 CSharp/BatchExplorer/Models/Pool.cs delete mode 100644 CSharp/BatchExplorer/Models/PoolModel.cs delete mode 100644 CSharp/BatchExplorer/Models/PropertyDisplayModel.cs delete mode 100644 CSharp/BatchExplorer/Models/ResourceFileInfo.cs delete mode 100644 CSharp/BatchExplorer/Models/StartTaskOptions.cs delete mode 100644 CSharp/BatchExplorer/Models/SubtaskModel.cs delete mode 100644 CSharp/BatchExplorer/Models/TaskModel.cs delete mode 100644 CSharp/BatchExplorer/Models/VirtualMachineConfigurationOptions.cs delete mode 100644 CSharp/BatchExplorer/Models/WorkItem.cs delete mode 100644 CSharp/BatchExplorer/PluginInterfaces/AccountPlugin/AccountManagementAddOperation.cs delete mode 100644 CSharp/BatchExplorer/PluginInterfaces/AccountPlugin/AccountManagementEditOperation.cs delete mode 100644 CSharp/BatchExplorer/PluginInterfaces/AccountPlugin/AccountManagementOperation.cs delete mode 100644 CSharp/BatchExplorer/PluginInterfaces/AccountPlugin/IAccountAdder.cs delete mode 100644 CSharp/BatchExplorer/PluginInterfaces/AccountPlugin/IAccountEditor.cs delete mode 100644 CSharp/BatchExplorer/PluginInterfaces/AccountPlugin/IAccountManager.cs delete mode 100644 CSharp/BatchExplorer/PluginInterfaces/AccountPlugin/IAccountManagerMetadata.cs delete mode 100644 CSharp/BatchExplorer/PluginInterfaces/AccountPlugin/IAccountOperationFactory.cs delete mode 100644 CSharp/BatchExplorer/Plugins/AccountPlugin/DefaultAccount.cs delete mode 100644 CSharp/BatchExplorer/Plugins/AccountPlugin/DefaultAccountDialogViewModel.cs delete mode 100644 CSharp/BatchExplorer/Plugins/AccountPlugin/DefaultAccountManagementControl.xaml delete mode 100644 CSharp/BatchExplorer/Plugins/AccountPlugin/DefaultAccountManagementControl.xaml.cs delete mode 100644 CSharp/BatchExplorer/Plugins/AccountPlugin/DefaultAccountManager.cs delete mode 100644 CSharp/BatchExplorer/Plugins/AccountPlugin/DefaultAccountOperationFactory.cs delete mode 100644 CSharp/BatchExplorer/Plugins/AccountPlugin/DefaultAccountSerializationContainer.cs delete mode 100644 CSharp/BatchExplorer/Plugins/AccountPlugin/SerializableAccount.cs delete mode 100644 CSharp/BatchExplorer/Plugins/LegacyAccountSupport/LegacyAccount.cs delete mode 100644 CSharp/BatchExplorer/Plugins/LegacyAccountSupport/LegacyAccountManager.cs delete mode 100644 CSharp/BatchExplorer/Properties/AssemblyInfo.cs delete mode 100644 CSharp/BatchExplorer/Properties/Resources.Designer.cs delete mode 100644 CSharp/BatchExplorer/Properties/Resources.resx delete mode 100644 CSharp/BatchExplorer/Properties/Settings.Designer.cs delete mode 100644 CSharp/BatchExplorer/Properties/Settings.settings delete mode 100644 CSharp/BatchExplorer/README.md delete mode 100644 CSharp/BatchExplorer/Service/BatchService.cs delete mode 100644 CSharp/BatchExplorer/Styles/ExplorerStyles.xaml delete mode 100644 CSharp/BatchExplorer/ViewModels/AccountDialogViewModel.cs delete mode 100644 CSharp/BatchExplorer/ViewModels/AddTaskViewModel.cs delete mode 100644 CSharp/BatchExplorer/ViewModels/AsyncOperationDetailsViewModel.cs delete mode 100644 CSharp/BatchExplorer/ViewModels/CreateCertificateViewModel.cs delete mode 100644 CSharp/BatchExplorer/ViewModels/CreateComputeNodeUserViewModel.cs delete mode 100644 CSharp/BatchExplorer/ViewModels/CreateJobScheduleViewModel.cs delete mode 100644 CSharp/BatchExplorer/ViewModels/CreateJobViewModel.cs delete mode 100644 CSharp/BatchExplorer/ViewModels/CreatePoolViewModel.cs delete mode 100644 CSharp/BatchExplorer/ViewModels/GenericMessageViewModel.cs delete mode 100644 CSharp/BatchExplorer/ViewModels/HeatmapViewModel.cs delete mode 100644 CSharp/BatchExplorer/ViewModels/MainViewModel.cs delete mode 100644 CSharp/BatchExplorer/ViewModels/OptionsViewModel.cs delete mode 100644 CSharp/BatchExplorer/ViewModels/ResizePoolViewModel.cs delete mode 100644 CSharp/BatchExplorer/Views/AboutWindow.xaml delete mode 100644 CSharp/BatchExplorer/Views/AboutWindow.xaml.cs delete mode 100644 CSharp/BatchExplorer/Views/AccountManagementControl.xaml delete mode 100644 CSharp/BatchExplorer/Views/AccountManagementControl.xaml.cs delete mode 100644 CSharp/BatchExplorer/Views/AsyncOperationDetailsControl.xaml delete mode 100644 CSharp/BatchExplorer/Views/AsyncOperationDetailsControl.xaml.cs delete mode 100644 CSharp/BatchExplorer/Views/CreateControls/AddTaskControl.xaml delete mode 100644 CSharp/BatchExplorer/Views/CreateControls/AddTaskControl.xaml.cs delete mode 100644 CSharp/BatchExplorer/Views/CreateControls/CreateCertificateControl.xaml delete mode 100644 CSharp/BatchExplorer/Views/CreateControls/CreateCertificateControl.xaml.cs delete mode 100644 CSharp/BatchExplorer/Views/CreateControls/CreateComputeNodeUserControl.xaml delete mode 100644 CSharp/BatchExplorer/Views/CreateControls/CreateComputeNodeUserControl.xaml.cs delete mode 100644 CSharp/BatchExplorer/Views/CreateControls/CreateJobControl.xaml delete mode 100644 CSharp/BatchExplorer/Views/CreateControls/CreateJobControl.xaml.cs delete mode 100644 CSharp/BatchExplorer/Views/CreateControls/CreateJobScheduleControl.xaml delete mode 100644 CSharp/BatchExplorer/Views/CreateControls/CreateJobScheduleControl.xaml.cs delete mode 100644 CSharp/BatchExplorer/Views/CreateControls/CreatePoolControl.xaml delete mode 100644 CSharp/BatchExplorer/Views/CreateControls/CreatePoolControl.xaml.cs delete mode 100644 CSharp/BatchExplorer/Views/CreateControls/ResizePoolControl.xaml delete mode 100644 CSharp/BatchExplorer/Views/CreateControls/ResizePoolControl.xaml.cs delete mode 100644 CSharp/BatchExplorer/Views/GenericEmptyWindow.xaml delete mode 100644 CSharp/BatchExplorer/Views/GenericEmptyWindow.xaml.cs delete mode 100644 CSharp/BatchExplorer/Views/GenericMessageControl.xaml delete mode 100644 CSharp/BatchExplorer/Views/GenericMessageControl.xaml.cs delete mode 100644 CSharp/BatchExplorer/Views/HeatmapControl.xaml delete mode 100644 CSharp/BatchExplorer/Views/HeatmapControl.xaml.cs delete mode 100644 CSharp/BatchExplorer/Views/LogIn.xaml delete mode 100644 CSharp/BatchExplorer/Views/LogIn.xaml.cs delete mode 100644 CSharp/BatchExplorer/Views/MainView.xaml delete mode 100644 CSharp/BatchExplorer/Views/MainView.xaml.cs delete mode 100644 CSharp/BatchExplorer/Views/OptionsControl.xaml delete mode 100644 CSharp/BatchExplorer/Views/OptionsControl.xaml.cs delete mode 100644 CSharp/BatchExplorer/Views/WaitSpinner.xaml delete mode 100644 CSharp/BatchExplorer/Views/WaitSpinner.xaml.cs delete mode 100644 CSharp/BatchExplorer/packages.config create mode 100644 azure-pipelines.yml diff --git a/CSharp/BatchExplorer/App.config b/CSharp/BatchExplorer/App.config deleted file mode 100644 index 92ddf6d3..00000000 --- a/CSharp/BatchExplorer/App.config +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/CSharp/BatchExplorer/App.xaml b/CSharp/BatchExplorer/App.xaml deleted file mode 100644 index 66251e05..00000000 --- a/CSharp/BatchExplorer/App.xaml +++ /dev/null @@ -1,6 +0,0 @@ - - diff --git a/CSharp/BatchExplorer/Assets/Icons/add_all_24.png b/CSharp/BatchExplorer/Assets/Icons/add_all_24.png deleted file mode 100644 index 5073e1bf5ac1b70d0940e2c106d684862de0d928..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 310 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjjKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBugD~Uq{1qucL5ULAh?3y^w370~qEv>0#LT=By}Z;C1rt33 zJ>#Bd(*uBNmV3H5hIn`shZbSm-1qFfbexcvr0#LT=By}Z;C1rt33 zJ>#Bd(*uBNR(QHNhIn}2y<*LE$U>m6n;92c)$;_jIHfVGG*`}~As#W!wLa9Df$ zKNJnR*{QJTr+Qg)>zg#DXYKrDvvuAm2f1^ne=1XRPv^~e{^s?;5YK1lq%NGEd1uaF zf7>ng&hx`gT+mIQSZZKwR*}@NxJc@-+%wrox{)$ms}Lfl92iaz%oL#F`F zqQ_i+H{@MpWOlh~9%QqjHLmGYbW(4aHd&l=mIJz(!PC{xWt~$(698&} BbMgQH diff --git a/CSharp/BatchExplorer/Assets/Icons/refresh_24.png b/CSharp/BatchExplorer/Assets/Icons/refresh_24.png deleted file mode 100644 index 5bf8a3d42a89730633b6644af75dffeba580e176..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 685 zcmV;e0#f~nP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D02p*dSaefwW^{L9 za%BK;VQFr3E^cLXAT%y8E;Eegmrwuz0v<_3K~zXft(MJ87Eu(3r;MT`D1$&lq(7vh zMUuIZKqVwFH?@kSGH4Tl+aPcy*hUZpi56{wL?c>gTS1gS1dE~qDX|axe4c5pjPE$p zyy_1g@E&J=_sqHH-up%=?S{Q@2u?#UjKUl=LY{nY*S|kE*9o`Ki8aun$W=(*_Nc`}%AutORKJza>xc|*SIYm%s^%b zZc*c)r~4tgpA0_2F$3F_t!l&Q`P6_r(7{h=H?U2efzYOX20SL-CV?r~N^1t~0XL^! zZqx>d>wX6eI`efXI-ZNv4OT+05d%SP>2O@EKr2+c;4SbO^!NaA_Gz60&3(XA@hTME zWI>k2%!BzFbU;RC>>(G9T+8JiF*CP+rR)|L)S8E~Xnq-Tzutd%$G!(&2orfzxe*_L zo5=RF6+^d(Wij(orS-BHf}*=RV7IuSnVOf;QMd_@;WY$Pe`)v?_IVTJD2o09duFag T!|tQ*00000NkvXXu0mjfU(X - - - - Debug - AnyCPU - {37FDF30B-537D-4216-A406-FD00ADDDD61A} - WinExe - Properties - Microsoft.Azure.BatchExplorer - BatchExplorer - v4.5.2 - 512 - {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - 4 - 5.0.40218.0 - .\ - true - - - AnyCPU - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - false - true - - - AnyCPU - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - true - - - Images\batchExplorer.ico - - - - packages\MvvmLightLibs.4.4.32.7\lib\net45\GalaSoft.MvvmLight.dll - - - packages\MvvmLightLibs.4.4.32.7\lib\net45\GalaSoft.MvvmLight.Extras.dll - - - packages\Azure.Batch.8.0.0\lib\net452\Microsoft.Azure.Batch.dll - True - - - packages\Microsoft.Azure.KeyVault.Core.1.0.0\lib\net40\Microsoft.Azure.KeyVault.Core.dll - True - - - - packages\Microsoft.Rest.ClientRuntime.2.3.10\lib\net452\Microsoft.Rest.ClientRuntime.dll - True - - - packages\Microsoft.Rest.ClientRuntime.Azure.3.3.10\lib\net452\Microsoft.Rest.ClientRuntime.Azure.dll - True - - - packages\Newtonsoft.Json.10.0.2\lib\net45\Newtonsoft.Json.dll - True - - - - - - - - - - - - - packages\MvvmLightLibs.4.4.32.7\lib\net45\System.Windows.Interactivity.dll - - - - - 4.0 - - - - - - False - packages\Extended.Wpf.Toolkit.2.2.1\lib\net40\Xceed.Wpf.AvalonDock.dll - - - False - packages\Extended.Wpf.Toolkit.2.2.1\lib\net40\Xceed.Wpf.AvalonDock.Themes.Aero.dll - - - False - packages\Extended.Wpf.Toolkit.2.2.1\lib\net40\Xceed.Wpf.AvalonDock.Themes.Metro.dll - - - False - packages\Extended.Wpf.Toolkit.2.2.1\lib\net40\Xceed.Wpf.AvalonDock.Themes.VS2010.dll - - - False - packages\Extended.Wpf.Toolkit.2.2.1\lib\net40\Xceed.Wpf.DataGrid.dll - - - False - packages\Extended.Wpf.Toolkit.2.2.1\lib\net40\Xceed.Wpf.Toolkit.dll - - - - - MSBuild:Compile - Designer - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - DefaultAccountManagementControl.xaml - - - - - - - - - - - - - - - - - - - - - - - AboutWindow.xaml - - - AccountManagementControl.xaml - - - AsyncOperationDetailsControl.xaml - - - AddTaskControl.xaml - - - CreateCertificateControl.xaml - - - CreateJobControl.xaml - - - ResizePoolControl.xaml - - - CreateComputeNodeUserControl.xaml - - - HeatMapControl.xaml - - - CreateJobScheduleControl.xaml - - - GenericMessageControl.xaml - - - OptionsControl.xaml - - - CreatePoolControl.xaml - - - GenericEmptyWindow.xaml - - - MainView.xaml - - - - - - WaitSpinner.xaml - - - MSBuild:Compile - Designer - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - - - MSBuild:Compile - Designer - - - MSBuild:Compile - Designer - - - MSBuild:Compile - Designer - - - Designer - MSBuild:Compile - - - MSBuild:Compile - Designer - - - MSBuild:Compile - Designer - - - MSBuild:Compile - Designer - - - MSBuild:Compile - Designer - - - MSBuild:Compile - Designer - - - MSBuild:Compile - Designer - - - MSBuild:Compile - Designer - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - - - - - Code - - - True - True - Resources.resx - - - True - Settings.settings - True - - - ResXFileCodeGenerator - Resources.Designer.cs - - - Designer - - - SettingsSingleFileGenerator - Settings.Designer.cs - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/CSharp/BatchExplorer/BatchExplorer.jpg b/CSharp/BatchExplorer/BatchExplorer.jpg deleted file mode 100644 index 1a398ba59106ce3693f1c001a608942d6e85451e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 263987 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

E5jhjbBE@Gb+NF9i9`I#no6qFHzyt)1za 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

qD0hs{2Xq@&6+xsPIYq8zx4Fim3R*4iEQ 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

#M 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 diff --git a/CSharp/BatchExplorer/BatchExplorer.sln b/CSharp/BatchExplorer/BatchExplorer.sln deleted file mode 100644 index 45d9aa1e..00000000 --- a/CSharp/BatchExplorer/BatchExplorer.sln +++ /dev/null @@ -1,22 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 14.00 -# Visual Studio 2015 -VisualStudioVersion = 14.0.25123.0 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BatchExplorer", "BatchExplorer.csproj", "{37FDF30B-537D-4216-A406-FD00ADDDD61A}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {37FDF30B-537D-4216-A406-FD00ADDDD61A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {37FDF30B-537D-4216-A406-FD00ADDDD61A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {37FDF30B-537D-4216-A406-FD00ADDDD61A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {37FDF30B-537D-4216-A406-FD00ADDDD61A}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/CSharp/BatchExplorer/Converters/BoolToVisibilityConverter.cs b/CSharp/BatchExplorer/Converters/BoolToVisibilityConverter.cs deleted file mode 100644 index 099fc170..00000000 --- a/CSharp/BatchExplorer/Converters/BoolToVisibilityConverter.cs +++ /dev/null @@ -1,32 +0,0 @@ -//Copyright (c) Microsoft Corporation - -using System; -using System.Globalization; -using System.Windows; -using System.Windows.Data; - -namespace Microsoft.Azure.BatchExplorer.Converters -{ - ///

- /// Converts a boolean to a Visibility value - /// - public class BoolToVisibilityConverter : IValueConverter - { - public object Convert(object value, Type targetType, object parameter, CultureInfo culture) - { - var returnVisible = (bool)value; - - if (returnVisible) - { - return Visibility.Visible; - } - - return Visibility.Collapsed; - } - - public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) - { - throw new NotImplementedException(); - } - } -} diff --git a/CSharp/BatchExplorer/Converters/BooleanAndConverter.cs b/CSharp/BatchExplorer/Converters/BooleanAndConverter.cs deleted file mode 100644 index 7e5bc334..00000000 --- a/CSharp/BatchExplorer/Converters/BooleanAndConverter.cs +++ /dev/null @@ -1,35 +0,0 @@ -//Copyright (c) Microsoft Corporation - -using System; -using System.Globalization; -using System.Windows.Data; - -namespace Microsoft.Azure.BatchExplorer.Converters -{ - /// - /// Converts a set of booleans to a single bool value by ANDing each value. - /// - public class BooleanAndConverter : IMultiValueConverter - { - public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) - { - bool result = true; - - foreach (object value in values) - { - bool? boolean = value as bool?; - if (boolean != null) - { - result &= boolean.Value; - } - } - - return result; - } - - public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) - { - throw new NotImplementedException(); - } - } -} diff --git a/CSharp/BatchExplorer/Converters/EnumToStringConverter.cs b/CSharp/BatchExplorer/Converters/EnumToStringConverter.cs deleted file mode 100644 index 334cca7f..00000000 --- a/CSharp/BatchExplorer/Converters/EnumToStringConverter.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Windows.Data; - -namespace Microsoft.Azure.BatchExplorer.Converters -{ - public class EnumToStringConverter : IValueConverter - { - public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) - { - if (value != null && value.GetType().BaseType == typeof(Enum)) - { - return value.ToString(); - } - - return null; - } - - public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) - { - throw new NotImplementedException(); - } - } -} diff --git a/CSharp/BatchExplorer/Converters/InvertedBoolToVisibilityConverter.cs b/CSharp/BatchExplorer/Converters/InvertedBoolToVisibilityConverter.cs deleted file mode 100644 index d2e2ecd7..00000000 --- a/CSharp/BatchExplorer/Converters/InvertedBoolToVisibilityConverter.cs +++ /dev/null @@ -1,33 +0,0 @@ -//Copyright (c) Microsoft Corporation - -using System; -using System.Globalization; -using System.Windows; -using System.Windows.Data; - -namespace Microsoft.Azure.BatchExplorer.Converters -{ - /// - /// Converts a boolean to a Visibility value (returning hidden for true) - /// - public class InvertedBoolToVisibilityConverter : IValueConverter - { - public object Convert(object value, Type targetType, object parameter, CultureInfo culture) - { - var returnCollapsed = (bool)value; - if (returnCollapsed) - { - return Visibility.Collapsed; - } - else - { - return Visibility.Visible; - } - } - - public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) - { - throw new NotImplementedException(); - } - } -} diff --git a/CSharp/BatchExplorer/Converters/InvertedBooleanConverter.cs b/CSharp/BatchExplorer/Converters/InvertedBooleanConverter.cs deleted file mode 100644 index 6ae0bd10..00000000 --- a/CSharp/BatchExplorer/Converters/InvertedBooleanConverter.cs +++ /dev/null @@ -1,39 +0,0 @@ -//Copyright (c) Microsoft Corporation - -using System; -using System.Globalization; -using System.Windows.Data; - -namespace Microsoft.Azure.BatchExplorer.Converters -{ - /// - /// Converts between a bool and its inverse - /// - public class InvertedBooleanConverter : IValueConverter - { - public object Convert(object value, Type targetType, object parameter, CultureInfo culture) - { - return ConvertImpl(value, targetType); - } - - public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) - { - return ConvertImpl(value, targetType); - } - - private static object ConvertImpl(object value, Type targetType) - { - if (targetType != typeof(bool) && targetType != typeof(bool?)) - { - throw new InvalidOperationException("The target must be a bool or nullable bool"); - } - - if (targetType == typeof(bool?)) - { - return !(bool?)value; - } - - return !(bool)value; - } - } -} diff --git a/CSharp/BatchExplorer/Converters/IsNotNullToBooleanConverter.cs b/CSharp/BatchExplorer/Converters/IsNotNullToBooleanConverter.cs deleted file mode 100644 index 14469be5..00000000 --- a/CSharp/BatchExplorer/Converters/IsNotNullToBooleanConverter.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System; -using System.Windows.Data; - -namespace Microsoft.Azure.BatchExplorer.Converters -{ - public class IsNotNullToBooleanConverter : IValueConverter - { - public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) - { - if (value == null) - { - return false; - } - - return true; - } - - public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) - { - throw new NotImplementedException(); - } - } -} diff --git a/CSharp/BatchExplorer/Converters/IsNullToBooleanConverter.cs b/CSharp/BatchExplorer/Converters/IsNullToBooleanConverter.cs deleted file mode 100644 index 53b34566..00000000 --- a/CSharp/BatchExplorer/Converters/IsNullToBooleanConverter.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System; -using System.Windows.Data; - -namespace Microsoft.Azure.BatchExplorer.Converters -{ - public class IsNullToBooleanConverter : IValueConverter - { - public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) - { - if (value == null) - { - return true; - } - - return false; - } - - public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) - { - throw new NotImplementedException(); - } - } -} diff --git a/CSharp/BatchExplorer/Converters/JobScheduleStateColorConverter.cs b/CSharp/BatchExplorer/Converters/JobScheduleStateColorConverter.cs deleted file mode 100644 index e74c3f85..00000000 --- a/CSharp/BatchExplorer/Converters/JobScheduleStateColorConverter.cs +++ /dev/null @@ -1,47 +0,0 @@ -//Copyright (c) Microsoft Corporation - -using System; -using System.Globalization; -using System.Windows.Data; -using System.Windows.Media; -using Microsoft.Azure.Batch.Common; - -namespace Microsoft.Azure.BatchExplorer.Converters -{ - /// - /// Converts job schedule states to color for UI display - /// - public class JobScheduleStateColorConverter : IValueConverter - { - //TODO: Switch this and other color converters to be colorblind friendly? - public object Convert(object value, Type targetType, object parameter, CultureInfo culture) - { - JobScheduleState? state = null; - if (value != null) - { - state = (JobScheduleState) value; - } - - switch (state) - { - case JobScheduleState.Active: - return new SolidColorBrush(Colors.Blue); - case JobScheduleState.Completed: - return new SolidColorBrush(Colors.Green); - case JobScheduleState.Deleting: - return new SolidColorBrush(Colors.Gray); - case JobScheduleState.Disabled: - return new SolidColorBrush(Colors.Gray); - case JobScheduleState.Terminating: - return new SolidColorBrush(Colors.DarkRed); - default: - return new SolidColorBrush(Colors.Gray); - } - } - - public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) - { - throw new NotImplementedException(); - } - } -} diff --git a/CSharp/BatchExplorer/Converters/JobStateColorConverter.cs b/CSharp/BatchExplorer/Converters/JobStateColorConverter.cs deleted file mode 100644 index a53180e7..00000000 --- a/CSharp/BatchExplorer/Converters/JobStateColorConverter.cs +++ /dev/null @@ -1,46 +0,0 @@ -//Copyright (c) Microsoft Corporation - -using System; -using System.Globalization; -using System.Windows.Data; -using System.Windows.Media; -using Microsoft.Azure.Batch.Common; - -namespace Microsoft.Azure.BatchExplorer.Converters -{ - /// - /// Converts job states to color for UI display - /// - public class JobStateColorConverter : IValueConverter - { - //TODO: Switch this and other color converters to be colorblind friendly? - public object Convert(object value, Type targetType, object parameter, CultureInfo culture) - { - JobState state = (JobState)value; - switch (state) - { - case JobState.Active: - return new SolidColorBrush(Colors.Blue); - case JobState.Completed: - return new SolidColorBrush(Colors.Green); - case JobState.Deleting: - return new SolidColorBrush(Colors.Gray); - case JobState.Disabled: - return new SolidColorBrush(Colors.Gray); - case JobState.Disabling: - return new SolidColorBrush(Colors.Gray); - case JobState.Enabling: - return new SolidColorBrush(Colors.LightBlue); - case JobState.Terminating: - return new SolidColorBrush(Colors.DarkRed); - default: - return new SolidColorBrush(Colors.Gray); - } - } - - public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) - { - throw new NotImplementedException(); - } - } -} diff --git a/CSharp/BatchExplorer/Converters/NullToVisibilityConverter.cs b/CSharp/BatchExplorer/Converters/NullToVisibilityConverter.cs deleted file mode 100644 index a15efe7b..00000000 --- a/CSharp/BatchExplorer/Converters/NullToVisibilityConverter.cs +++ /dev/null @@ -1,32 +0,0 @@ -//Copyright (c) Microsoft Corporation - -using System; -using System.Globalization; -using System.Windows; -using System.Windows.Data; - -namespace Microsoft.Azure.BatchExplorer.Converters -{ - /// - /// Converts null to Visibility.Collapsed - /// - public class NullToVisibilityConverter : IValueConverter - { - public object Convert(object value, Type targetType, object parameter, CultureInfo culture) - { - if (value == null) - { - return Visibility.Collapsed; - } - else - { - return Visibility.Visible; - } - } - - public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) - { - throw new NotImplementedException(); - } - } -} diff --git a/CSharp/BatchExplorer/Converters/PoolAllocationStateColorConverter.cs b/CSharp/BatchExplorer/Converters/PoolAllocationStateColorConverter.cs deleted file mode 100644 index c3b20eb8..00000000 --- a/CSharp/BatchExplorer/Converters/PoolAllocationStateColorConverter.cs +++ /dev/null @@ -1,43 +0,0 @@ -//Copyright (c) Microsoft Corporation - -using System; -using System.Globalization; -using System.Windows.Data; -using System.Windows.Media; -using Microsoft.Azure.Batch.Common; - -namespace Microsoft.Azure.BatchExplorer.Converters -{ - /// - /// Converts pool allocation states to color for UI display - /// - public class PoolAllocationStateColorConverter : IValueConverter - { - //TODO: Switch this and other color converters to be colorblind friendly? - public object Convert(object value, Type targetType, object parameter, CultureInfo culture) - { - AllocationState? state = null; - if (value != null) - { - state = (AllocationState)value; - } - - switch (state) - { - case AllocationState.Steady: - return new SolidColorBrush(Colors.Blue); - case AllocationState.Resizing: - return new SolidColorBrush(Colors.LightBlue); - case AllocationState.Stopping: - return new SolidColorBrush(Colors.Red); - default: - throw new ArgumentOutOfRangeException(); - } - } - - public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) - { - throw new NotImplementedException(); - } - } -} diff --git a/CSharp/BatchExplorer/Converters/TaskStatusColorConverter.cs b/CSharp/BatchExplorer/Converters/TaskStatusColorConverter.cs deleted file mode 100644 index 19c7c579..00000000 --- a/CSharp/BatchExplorer/Converters/TaskStatusColorConverter.cs +++ /dev/null @@ -1,44 +0,0 @@ -//Copyright (c) Microsoft Corporation - -using System; -using System.Globalization; -using System.Windows.Data; -using System.Windows.Media; -using Microsoft.Azure.Batch.Common; - -namespace Microsoft.Azure.BatchExplorer.Converters -{ - /// - /// Converts task status states to color for UI display - /// - public class TaskStatusColorConverter : IValueConverter - { - public object Convert(object value, Type targetType, object parameter, CultureInfo culture) - { - TaskState? state = null; - if (value != null) - { - state = (TaskState) value; - } - - switch (state) - { - case TaskState.Active: - return new SolidColorBrush(Colors.Orange); - case TaskState.Preparing: - return new SolidColorBrush(Colors.LightBlue); - case TaskState.Running: - return new SolidColorBrush(Colors.Blue); - case TaskState.Completed: - return new SolidColorBrush(Colors.LimeGreen); - default: - return new SolidColorBrush(Colors.DarkGray); - } - } - - public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) - { - throw new NotImplementedException(); - } - } -} diff --git a/CSharp/BatchExplorer/Helpers/AccountManagerContainer.cs b/CSharp/BatchExplorer/Helpers/AccountManagerContainer.cs deleted file mode 100644 index 6f6511a5..00000000 --- a/CSharp/BatchExplorer/Helpers/AccountManagerContainer.cs +++ /dev/null @@ -1,18 +0,0 @@ -//Copyright (c) Microsoft Corporation - -using Microsoft.Azure.BatchExplorer.PluginInterfaces.AccountPlugin; - -namespace Microsoft.Azure.BatchExplorer.Helpers -{ - public sealed class AccountManagerContainer - { - public IAccountManager AccountManager { get; private set; } - public IAccountManagerMetadata Metadata { get; private set; } - - public AccountManagerContainer(IAccountManager accountManager, IAccountManagerMetadata metadata) - { - this.AccountManager = accountManager; - this.Metadata = metadata; - } - } -} diff --git a/CSharp/BatchExplorer/Helpers/AsyncOperationTracker.cs b/CSharp/BatchExplorer/Helpers/AsyncOperationTracker.cs deleted file mode 100644 index 5dc3e9dc..00000000 --- a/CSharp/BatchExplorer/Helpers/AsyncOperationTracker.cs +++ /dev/null @@ -1,175 +0,0 @@ -//Copyright (c) Microsoft Corporation - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using GalaSoft.MvvmLight.Messaging; -using Microsoft.Azure.BatchExplorer.Messages; -using Microsoft.Azure.BatchExplorer.Models; - -namespace Microsoft.Azure.BatchExplorer.Helpers -{ - /// - /// Tracks async operations issued by the BatchExplorer - /// - public class AsyncOperationTracker - { - #region Singleton properties - //We don't require lazy instantiation for this type so this is okay. - //See: http://csharpindepth.com/articles/general/singleton.aspx for other implementations of the singleton pattern - private static readonly AsyncOperationTracker instance = new AsyncOperationTracker(); - - public static AsyncOperationTracker Instance - { - get { return instance; } - } - - #endregion - - private readonly LinkedList trackedOperations; - private readonly LinkedList trackedInternalOperations; - private readonly object trackedOperationsLock; - private readonly object trackedInternalOperationsLock; - internal const int DefaultMaxTrackedOperations = 50; - - private AsyncOperationTracker() - { - //Note: we use LinkedList here for O(1) AddLast and RemoveFirst - this.trackedOperations = new LinkedList(); - this.trackedOperationsLock = new object(); - - this.trackedInternalOperations = new LinkedList(); - this.trackedInternalOperationsLock = new object(); - } - - /// - /// Snapshot of the tracked operations. - /// - public IEnumerable AsyncOperations - { - get - { - lock (this.trackedOperationsLock) - { - //Perform a shallow copy of our list and return that to avoid any threading issues with this list being read/modified in multiple threads - //TODO: Should we avoid doing this copy and do something more intelligent instead...? - IEnumerable shallowCopy = new List(this.trackedOperations); - return shallowCopy; - } - } - } - - /// - /// Snapshot of the tracked internal operations. - /// - internal IEnumerable InternalAsyncOperations - { - get - { - lock (this.trackedInternalOperationsLock) - { - //Perform a shallow copy of our list and return that to avoid any threading issues with this list being read/modified in multiple threads - //TODO: Should we avoid doing this copy and do something more intelligent instead...? - IEnumerable shallowCopy = new List(this.trackedInternalOperations); - return shallowCopy; - } - } - } - - /// - /// Add the specified operation to the tracker. - /// - /// The operation to track. - public void AddTrackedOperation(AsyncOperationModel asyncOperation) - { - lock (this.trackedOperationsLock) - { - //Check the current size of the collection and remove items if needed - while(this.trackedOperations.Count >= OptionsModel.Instance.MaxTrackedOperations) - { - this.trackedOperations.RemoveLast(); - } - - this.trackedOperations.AddFirst(asyncOperation); - } - Messenger.Default.Send(new Messages.AsyncOperationListChangedMessage()); - } - - /// - /// Clears the cache of tracked operations. - /// - public void Clear() - { - lock (this.trackedOperationsLock) - { - this.trackedOperations.Clear(); - } - Messenger.Default.Send(new Messages.AsyncOperationListChangedMessage()); - } - - /// - /// Adds a tracked internal operation, which is not displayed in the AsyncOperationTracker list. - /// - /// - internal void AddTrackedInternalOperation(Task internalAsyncOperation) - { - lock (this.trackedInternalOperationsLock) - { - this.trackedInternalOperations.AddFirst(internalAsyncOperation); - } - } - - /// - /// Removes a tracked internal operation. - /// - /// - internal void RemoveTrackedInternalOperation(Task internalAsyncOperation) - { - lock (this.trackedInternalOperationsLock) - { - this.trackedInternalOperations.Remove(internalAsyncOperation); - } - } - - public static async Task InternalOperationResultHandler() - { - AsyncOperationTracker asyncOperationTracker = AsyncOperationTracker.Instance; - while (true) - { - IEnumerable pendingInternalOperations = asyncOperationTracker.InternalAsyncOperations; - - //Wait for any async operation to complete - if (pendingInternalOperations.Any()) - { - Task whenAnyTask = Task.WhenAny(pendingInternalOperations); - - try - { - await whenAnyTask; //This can throw - } - catch (Exception) - { - //Supress all errors -- they are processed in the following foreach - } - } - - //Process all tasks which have completed and remove them from tracking - foreach (Task internalOperation in pendingInternalOperations) - { - if (internalOperation.IsCompleted) - { - if (internalOperation.IsFaulted) - { - string message = string.Format("Hit internal async operation error: {0}", internalOperation.Exception); - Messenger.Default.Send(new GenericDialogMessage(message)); - } - asyncOperationTracker.RemoveTrackedInternalOperation(internalOperation); - } - } - - await Task.Delay(TimeSpan.FromSeconds(5)); - } - } - } -} diff --git a/CSharp/BatchExplorer/Helpers/BasicDataProvider.cs b/CSharp/BatchExplorer/Helpers/BasicDataProvider.cs deleted file mode 100644 index d1e48b7e..00000000 --- a/CSharp/BatchExplorer/Helpers/BasicDataProvider.cs +++ /dev/null @@ -1,163 +0,0 @@ -//Copyright (c) Microsoft Corporation - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.Azure.Batch; -using Microsoft.Azure.Batch.Auth; -using Microsoft.Azure.Batch.Common; -using Microsoft.Azure.BatchExplorer.Models; -using Microsoft.Azure.BatchExplorer.Service; - -namespace Microsoft.Azure.BatchExplorer.Helpers -{ - /// - /// Gets all jobs, tasks, jobschedules, and pools for the current account with no caching or other frills - /// - public class BasicDataProvider : IDataProvider - { - public Account CurrentAccount { get; private set; } - - public BatchService Service { get; private set; } - - public BasicDataProvider(Account currentAccount) - { - this.CurrentAccount = currentAccount; - this.Service = new BatchService(new BatchSharedKeyCredentials(this.CurrentAccount.BatchServiceUrl, this.CurrentAccount.AccountName, this.CurrentAccount.Key)); - } - - public async Task> GetJobScheduleCollectionAsync() - { - IPagedEnumerable jobSchedules = this.Service.ListJobSchedules(OptionsModel.Instance.ListDetailLevel); - List jobScheduleModels = new List(); - - await jobSchedules.ForEachAsync(item => jobScheduleModels.Add(new JobScheduleModel(item))); - - return jobScheduleModels; - } - - public async Task CreateJobScheduleAsync(CreateJobScheduleOptions options) - { - await this.Service.CreateJobScheduleAsync(options); - } - - public async Task> GetJobCollectionAsync(string jobSearchFilter) - { - IPagedEnumerable jobs = this.Service.ListJobs(OptionsModel.Instance.ListDetailLevel); - List jobModels = new List(); - - // The properties we want to filter on are not available in a ODATADetailLevel query. Filter them client side - if (!String.IsNullOrWhiteSpace(jobSearchFilter)) - { - var jobSearchFilterL = jobSearchFilter.ToLowerInvariant(); - var filteredJobs = jobs.Where(f => f.DisplayName.ToLowerInvariant().Contains(jobSearchFilterL) || - f.Id.ToLowerInvariant().Contains(jobSearchFilterL) || - f.Metadata.Any(g => g.Name.ToLowerInvariant().Contains(jobSearchFilterL)) || - f.Metadata.Any(g => g.Value.ToLowerInvariant().Contains(jobSearchFilterL))); - - jobModels.AddRange(filteredJobs.Select(item => new JobModel(item))); - } - else - { - await jobs.ForEachAsync(item => jobModels.Add(new JobModel(item))); - } - - return jobModels; - } - - public Task CreateJobAsync(CreateJobOptions options) - { - return this.Service.CreateJobAsync(options); - } - - public async Task AddTaskAsync(AddTaskOptions options) - { - await this.Service.AddTaskAsync(options); - } - - public async Task> GetPoolCollectionAsync() - { - IPagedEnumerable pools = this.Service.ListPools(OptionsModel.Instance.ListDetailLevel); - IList poolModels = new List(); - - await pools.ForEachAsync(item => poolModels.Add(new PoolModel(item))); - - return poolModels; - } - - public async Task> GetCertificatesCollectionAsync() - { - IPagedEnumerable certificates = this.Service.ListCertificates(null); - IList certificateModels = new List(); - - await certificates.ForEachAsync(item => certificateModels.Add(new CertificateModel(item))); - - return certificateModels; - } - - public Task CreateCertificateAsync(CreateCertificateOptions options) - { - return this.Service.CreateCertificateAsync(options); - } - - public async Task CreatePoolAsync( - string poolId, - string virtualMachineSize, - int? targetDedicated, - int? targetLowPriority, - string autoScaleFormula, - bool communicationEnabled, - string subnetId, - CloudServiceConfigurationOptions cloudServiceConfigurationOptions, - VirtualMachineConfigurationOptions virtualMachineConfigurationOptions, - int maxTasksPerComputeNode, - TimeSpan? timeout, - StartTaskOptions startTask) - { - await this.Service.CreatePoolAsync( - poolId, - virtualMachineSize, - targetDedicated, - targetLowPriority, - autoScaleFormula, - communicationEnabled, - subnetId, - cloudServiceConfigurationOptions, - virtualMachineConfigurationOptions, - maxTasksPerComputeNode, - timeout, - startTask); - } - - public async Task CreateComputeNodeUserAsync(string poolId, string nodeId, string userName, string password, DateTime expiryTime, bool admin) - { - await this.Service.CreateNodeUserAsync(poolId, nodeId, userName, password, expiryTime, admin); - } - - public async Task ResizePoolAsync(string poolId, int targetDedicated, int targetLowPriority, TimeSpan? timeout, ComputeNodeDeallocationOption? computeNodeDeallocationOption) - { - await this.Service.ResizePool(poolId, targetDedicated, targetLowPriority, timeout, computeNodeDeallocationOption); - } - - public async Task> ListNodeAgentSkusAsync() - { - IPagedEnumerable nodeAgentSkus = this.Service.ListNodeAgentSkus(); - - IList results = await nodeAgentSkus.ToListAsync(); - - return results; - } - - public async Task EvaluateAutoScaleFormulaAsync(string poolId, string autoScaleFormula) - { - return await this.Service.EvaluateAutoScaleFormula(poolId, autoScaleFormula); - } - - public async Task EnableAutoScaleAsync(string poolId, string autoScaleFormula) - { - await this.Service.EnableAutoScale(poolId, autoScaleFormula); - } - } -} diff --git a/CSharp/BatchExplorer/Helpers/Cached.cs b/CSharp/BatchExplorer/Helpers/Cached.cs deleted file mode 100644 index 8cea0b0d..00000000 --- a/CSharp/BatchExplorer/Helpers/Cached.cs +++ /dev/null @@ -1,31 +0,0 @@ -namespace Microsoft.Azure.BatchExplorer.Helpers -{ - using System; - using System.Threading.Tasks; - - public class Cached - { - private DateTime? lastUpdateTime; - private readonly Func> refreshFunc; - private readonly TimeSpan expiryTime; - private T data; - - public Cached(Func> refreshFunc, TimeSpan expiryTime) - { - this.refreshFunc = refreshFunc; - this.lastUpdateTime = null; //Hasn't been updated yet - this.expiryTime = expiryTime; - } - - public async Task GetDataAsync() - { - if (this.lastUpdateTime == null || this.lastUpdateTime + this.expiryTime <= DateTime.UtcNow) - { - this.data = await this.refreshFunc(); - this.lastUpdateTime = DateTime.UtcNow; - } - - return this.data; - } - } -} diff --git a/CSharp/BatchExplorer/Helpers/ChangeTrackedAttribute.cs b/CSharp/BatchExplorer/Helpers/ChangeTrackedAttribute.cs deleted file mode 100644 index c5a2b5c3..00000000 --- a/CSharp/BatchExplorer/Helpers/ChangeTrackedAttribute.cs +++ /dev/null @@ -1,28 +0,0 @@ -//Copyright (c) Microsoft Corporation - -using System; -using Microsoft.Azure.BatchExplorer.Models; - -namespace Microsoft.Azure.BatchExplorer.Helpers -{ - [AttributeUsage(AttributeTargets.Property)] - public class ChangeTrackedAttribute : Attribute - { - private readonly ModelRefreshType refreshType; - - public ChangeTrackedAttribute(ModelRefreshType refreshType) - { - this.refreshType = refreshType; - } - - /// - /// Returns true if this property has been changed based on the refresh type - /// - /// The type of refresh which was performed - /// - public bool HasChanged(ModelRefreshType changeRefreshType) - { - return this.refreshType.HasFlag(changeRefreshType); - } - } -} diff --git a/CSharp/BatchExplorer/Helpers/CommandBase.cs b/CSharp/BatchExplorer/Helpers/CommandBase.cs deleted file mode 100644 index 50a5cbcd..00000000 --- a/CSharp/BatchExplorer/Helpers/CommandBase.cs +++ /dev/null @@ -1,64 +0,0 @@ -//Copyright (c) Microsoft Corporation - -using System; -using System.Windows.Input; - -namespace Microsoft.Azure.BatchExplorer.Helpers -{ - /// - /// The basic implementation for ICommand - use directly with command binding or as a base for more advanced command types - /// - public class CommandBase : ICommand - { - /// - /// Create a command that is ALWAYS ready to be invoked...ALWAYS - /// - /// the delegate to execute when the command is invoked - public CommandBase(Action execute) - :this(execute,null) - { - - } - /// - /// Create a command that needs a test method to see if it can be executed - /// - /// The delegate to execute when the command is invoked - /// The method to test whether this command CAN be invoked - public CommandBase(Action execute, Func canExecute) - { - this.execute = execute; - if (canExecute != null) - { - this.canExecute = canExecute; - } - else - { - //if the canExecute was null, replace it with an anonymous delegate that always returns true - this.canExecute = (o) => { return true; }; - } - } - /// - /// The method that evaluates whether this command can be invoked - /// - /// the parameter for this evaluation - /// true if the command can be invoked - public bool CanExecute(object parameter) - { - return this.canExecute(parameter); - } - /// - /// The method executed when this command is invoked - /// - /// the parameter for this command - public void Execute(object parameter) - { - this.execute(parameter); - } -#pragma warning disable 67 // we're required to declare this for ICommand interface, but we don't use it in any of our command classes - public event EventHandler CanExecuteChanged; -#pragma warning restore - - private readonly Action execute; - private readonly Func canExecute; - } -} diff --git a/CSharp/BatchExplorer/Helpers/Common.cs b/CSharp/BatchExplorer/Helpers/Common.cs deleted file mode 100644 index bc43194f..00000000 --- a/CSharp/BatchExplorer/Helpers/Common.cs +++ /dev/null @@ -1,133 +0,0 @@ -//Copyright (c) Microsoft Corporation - -namespace Microsoft.Azure.BatchExplorer.Helpers -{ - using System; - using System.Collections.Generic; - using System.ComponentModel.Composition; - using System.ComponentModel.Composition.Hosting; - using System.IO; - using System.Linq; - using System.Net; - using System.Reflection; - using Microsoft.Azure.Batch.Common; - using Microsoft.Azure.BatchExplorer.ViewModels; - - public static class Common - { - public readonly static string LocalAppDataDirectory = System.Environment.GetEnvironmentVariable("LOCALAPPDATA"); - public const string LocalAppDataSubfolder = @"Microsoft\Azure Batch Explorer"; - - public const string PluginSubfolderName = "Plugins"; - - public static readonly IReadOnlyDictionary SupportedOSFamilyDictionary = - new Dictionary - { - {"Windows Server 2008 R2", "2"}, - {"Windows Server 2012", "3"}, - {"Windows Server 2012 R2", "4"}, - }; - - public static readonly IReadOnlyList SupportedVirtualMachineSizesList = - new List - { - "Small", - "Medium", - "Large", - "ExtraLarge", - "A5", - "A6", - "A7", - "A8", - "A9", - "STANDARD_D1", - "STANDARD_D2", - "STANDARD_D3", - "STANDARD_D4", - "STANDARD_D11", - "STANDARD_D12", - "STANDARD_D13", - "STANDARD_D14", - }; - - /// - /// Determines if an exception is a "NotFound" exception from the Batch service - /// - /// - /// - public static bool IsExceptionNotFound(Exception e) - { - AggregateException aggEx = e as AggregateException; - BatchException batchException = e as BatchException; - - if (aggEx != null) - { - aggEx = aggEx.Flatten(); //Flatten the aggregate exception - - batchException = aggEx.InnerExceptions.Cast().FirstOrDefault(); - } - - if (batchException != null) - { - if (batchException.RequestInformation != null && - batchException.RequestInformation.BatchError != null) - { - if(batchException.RequestInformation.HttpStatusCode == HttpStatusCode.NotFound) - { - return true; - } - } - } - - return false; - } - - /// - /// Loads plugins for the specified plugin target from the plugin folder. - /// - /// The target to load plugins for. - public static void LoadPlugins(object pluginTarget) - { - AggregateCatalog catalog = new AggregateCatalog(new AssemblyCatalog(typeof(MainViewModel).Assembly)); - - if (!Directory.Exists(Common.PluginSubfolderName)) - { - Directory.CreateDirectory(Common.PluginSubfolderName); - } - string[] subDirectories = Directory.GetDirectories(Common.PluginSubfolderName); - - foreach (string subDirectory in subDirectories) - { - catalog.Catalogs.Add(new DirectoryCatalog(subDirectory)); - } - - CompositionContainer container = new CompositionContainer(catalog); - - try - { - container.ComposeParts(pluginTarget); - } - catch (ReflectionTypeLoadException e) - { - //Catch any exceptions thrown by the loader and dump them before throwing - foreach (Exception loaderException in e.LoaderExceptions) - { - Console.WriteLine(loaderException); - } - throw; - } - } - - public static int? GetNullableIntValue(string content) - { - int value; - int? output = null; - if (Int32.TryParse(content, out value)) - { - output = value; - } - - return output; - } - } -} diff --git a/CSharp/BatchExplorer/Helpers/EntityBase.cs b/CSharp/BatchExplorer/Helpers/EntityBase.cs deleted file mode 100644 index e97a6b15..00000000 --- a/CSharp/BatchExplorer/Helpers/EntityBase.cs +++ /dev/null @@ -1,51 +0,0 @@ -//Copyright (c) Microsoft Corporation - -using System.ComponentModel; -using System.Runtime.Serialization; - -namespace Microsoft.Azure.BatchExplorer.Helpers -{ - /// - /// Serves as the base for both models and viewmodels - provides all common functionality needed by both - /// - [DataContract] - public class EntityBase : INotifyPropertyChanged - { - private bool isBusy; - - /// - /// Is Busy - /// Determines whether the control is busy - /// - public bool IsBusy - { - get - { - return this.isBusy; - } - set - { - this.isBusy = value; - this.FirePropertyChangedEvent("IsBusy"); - } - } - - /// - /// Raise a PropertyChanged event - /// - /// The name of the property that has changed - protected void FirePropertyChangedEvent(string propertyName) - { - //PropertyChanged will be null if there are no listeners for this event on this object - if (PropertyChanged != null) - { - //There is at least one listener, so raise the event - PropertyChanged(this,new PropertyChangedEventArgs(propertyName)); - } - } - /// - /// Event fired whenever a property changes - /// - public event PropertyChangedEventHandler PropertyChanged; - } -} diff --git a/CSharp/BatchExplorer/Helpers/EnumerableExtensions.cs b/CSharp/BatchExplorer/Helpers/EnumerableExtensions.cs deleted file mode 100644 index 36bef76e..00000000 --- a/CSharp/BatchExplorer/Helpers/EnumerableExtensions.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Microsoft.Azure.BatchExplorer.Helpers -{ - internal static class EnumerableExtensions - { - internal static IEnumerable SelectMany(this IEnumerable source, Func> selector) - { - int index = 0; - foreach (var item in source) - { - foreach (var result in selector(item, index)) - { - yield return result; - } - ++index; - } - } - } -} diff --git a/CSharp/BatchExplorer/Helpers/Exceptions.cs b/CSharp/BatchExplorer/Helpers/Exceptions.cs deleted file mode 100644 index c0769543..00000000 --- a/CSharp/BatchExplorer/Helpers/Exceptions.cs +++ /dev/null @@ -1,10 +0,0 @@ -//Copyright (c) Microsoft Corporation - -using System; - -namespace Microsoft.Azure.BatchExplorer.Helpers -{ - public class HeatMapTerminatedException : Exception - { - } -} diff --git a/CSharp/BatchExplorer/Helpers/IDataProvider.cs b/CSharp/BatchExplorer/Helpers/IDataProvider.cs deleted file mode 100644 index 3c6fd35c..00000000 --- a/CSharp/BatchExplorer/Helpers/IDataProvider.cs +++ /dev/null @@ -1,123 +0,0 @@ -//Copyright (c) Microsoft Corporation - -using System; -using System.Collections.Generic; -using System.Threading.Tasks; -using Microsoft.Azure.Batch; -using Microsoft.Azure.Batch.Common; -using Microsoft.Azure.BatchExplorer.Models; -using Microsoft.Azure.BatchExplorer.Service; - -namespace Microsoft.Azure.BatchExplorer.Helpers -{ - /// - /// Provides a layer of abstraction between the display logic and the data-fetching logic - /// - public interface IDataProvider - { - /// - /// The current account the data provider is using - /// - Account CurrentAccount { get; } - - /// - /// The batch service associated with this data provider - /// - BatchService Service { get; } - - /// - /// Get a collection of Job Schedules from the default source (if any) - /// - /// a collection of Job Schedules, or null if no JobSchedules are available - Task> GetJobScheduleCollectionAsync(); - - /// - /// Creates a job schedule - /// - Task CreateJobScheduleAsync(CreateJobScheduleOptions options); - - /// - /// Get a collection of Jobs from the default source (if any) - /// - /// A whose result is a collection of Jobs - Task> GetJobCollectionAsync(string jobSearchFilter); - - /// - /// Creates a job - /// - Task CreateJobAsync(CreateJobOptions options); - - /// - /// Add a task - /// - /// add task options - id, cli, etc. - Task AddTaskAsync(AddTaskOptions options); - - /// - /// Get a collection of Pools from the default source (if any) - /// - /// A whose result is a collection of Pools - Task> GetPoolCollectionAsync(); - - /// - /// Creates a Pool - /// - Task CreatePoolAsync( - string poolId, - string virtualMachineSize, - int? targetDedicated, - int? targetLowPriority, - string autoScaleFormula, - bool communicationEnabled, - string subnetId, - CloudServiceConfigurationOptions cloudServiceConfigurationOptions, - VirtualMachineConfigurationOptions virtualMachineConfigurationOptions, - int maxTasksPerComputeNode, - TimeSpan? timeout, - StartTaskOptions startTask); - - /// - /// Creates a ComputeNode user. - /// - /// - Task CreateComputeNodeUserAsync(string poolId, string nodeId, string userName, string password, DateTime expiryTime, bool admin); - - /// - /// Resizes a pool - /// - Task ResizePoolAsync(string poolId, int targetDedicated, int targetLowPriority, TimeSpan? timeout, ComputeNodeDeallocationOption? computeNodeDeallocationOption); - - /// - /// Get a collection of certificates from the default source (if any) - /// - /// A whose result is a collection of certificates - Task> GetCertificatesCollectionAsync(); - - /// - /// Creates a certificate - /// - Task CreateCertificateAsync(CreateCertificateOptions options); - - /// - /// Lists the collection of support node agent skus. - /// - /// A whose result is a collection of 's. - Task> ListNodeAgentSkusAsync(); - - /// - /// Evaluates the automatic scale formula supplied on the specified pool asynchronously. - /// - /// The pool identifier. - /// The autoscale formula. - /// Returns the result of evaluation - Task EvaluateAutoScaleFormulaAsync(string poolId, string autoScaleFormula); - - /// - /// Enables an autoscale formula on the specified pool asynchronously. - /// - /// The pool identifier. - /// The autoscale formula. - /// - Task EnableAutoScaleAsync(string poolId, string autoScaleformula); - } -} diff --git a/CSharp/BatchExplorer/Helpers/Operations.cs b/CSharp/BatchExplorer/Helpers/Operations.cs deleted file mode 100644 index 240dea55..00000000 --- a/CSharp/BatchExplorer/Helpers/Operations.cs +++ /dev/null @@ -1,201 +0,0 @@ -//Copyright (c) Microsoft Corporation - -using System.Globalization; - -namespace Microsoft.Azure.BatchExplorer.Helpers -{ - /// - /// Abstract class describing an operation (e.g. GetTask, ListTasks). - /// - public abstract class Operation - { - /// - /// The name of the operation. - /// - public string OperationName { get; private set; } - - /// - /// The target of the operation. - /// - public abstract string OperationTarget { get; } - - protected Operation(string operationName) - { - this.OperationName = operationName; - } - } - - public class AccountOperation : Operation - { - public const string ListJobSchedules = "ListJobSchedules"; - public const string ListJobs = "ListJobs"; - public const string ListPools = "ListPools"; - public const string ListOSVersions = "ListOSVersions"; - public const string ListCertificates = "ListCertificates"; - - public AccountOperation(string operationName) - : base(operationName) - { - } - - public override string OperationTarget - { - get { return string.Empty; } - } - } - - public class JobScheduleOperation : Operation - { - public const string Enable = "Enable"; - public const string Disable = "Disable"; - public const string Delete = "Delete"; - public const string Terminate = "Terminate"; - public const string ListJobs = "ListJobs"; - public const string Refresh = "Refresh"; - - private readonly string jobScheduleId; - private const string OperationTargetFormatString = @"JobSchedule: {0}"; - - public override string OperationTarget - { - get { return string.Format(CultureInfo.CurrentCulture, OperationTargetFormatString, this.jobScheduleId); } - } - - public JobScheduleOperation(string operationName, string jobScheduleId) - : base(operationName) - { - this.jobScheduleId = jobScheduleId; - } - } - - public class JobOperation : Operation - { - public const string Enable = "Enable"; - public const string Disable = "Disable"; - public const string Terminate = "Terminate"; - public const string Delete = "Delete"; - public const string Refresh = "Refresh"; - public const string ListTasks = "ListTasks"; - - private readonly string jobId; - - private const string OperationTargetFormatString = @"Job: {0}"; - - public override string OperationTarget - { - get { return string.Format(CultureInfo.CurrentCulture, OperationTargetFormatString, this.jobId); } - } - - public JobOperation(string operationName, string jobId) - : base(operationName) - { - this.jobId = jobId; - } - } - - public class TaskOperation : Operation - { - public const string Terminate = "Terminate"; - public const string Delete = "Delete"; - public const string Refresh = "Refresh"; - public const string ListFiles = "ListFiles"; - public const string GetFile = "GetFile"; - public const string ListSubtasks = "ListSubtasks"; - - private readonly string jobId; - private readonly string taskId; - - private const string OperationTargetFormatString = @"Job: {0}, Task: {1}"; - - public override string OperationTarget - { - get { return string.Format(CultureInfo.CurrentCulture, OperationTargetFormatString, this.jobId, this.taskId); } - } - - public TaskOperation(string operationName, string jobId, string taskId) - : base(operationName) - { - this.jobId = jobId; - this.taskId = taskId; - } - } - - public class PoolOperation : Operation - { - public const string AddPool = "AddPool"; - public const string Resize = "Resize"; - public const string Delete = "Delete"; - public const string Refresh = "Refresh"; - public const string ListComputeNodes = "ListComputeNodes"; - public const string GetPool = "GetPool"; - public const string EvaluateAutoScaleFormula = "EvaluateAutoScaleFormula"; - public const string EnableAutoScale = "EnableAutoScale"; - public const string StopResize = "StopResize"; - - private readonly string poolId; - private const string OperationTargetFormatString = @"Pool: {0}"; - - public override string OperationTarget - { - get { return string.Format(CultureInfo.CurrentCulture, OperationTargetFormatString, this.poolId); } - } - - public PoolOperation(string operationName, string poolId) - : base(operationName) - { - this.poolId = poolId; - } - } - - public class ComputeNodeOperation : Operation - { - public const string Reboot = "Reboot"; - public const string Reimage = "Reimage"; - public const string Refresh = "Refresh"; - public const string ListFiles = "ListFiles"; - public const string GetRdp = "GetRdp"; - public const string GetSsh = "GetSsh"; - public const string GetFile = "GetFile"; - public const string CreateUser = "CreateUser"; - public const string DisableScheduling = "DisableScheduling"; - public const string EnableScheduling = "EnableScheduling"; - - private readonly string poolId; - private readonly string nodeId; - private const string OperationTargetFormatString = @"Pool: {0}, Node: {1}"; - - public override string OperationTarget - { - get { return string.Format(CultureInfo.CurrentCulture, OperationTargetFormatString, this.poolId, this.nodeId); } - } - - public ComputeNodeOperation(string operationName, string poolId, string nodeId) - : base(operationName) - { - this.poolId = poolId; - this.nodeId = nodeId; - } - } - - public class CertificateOperation : Operation - { - public const string Refresh = "Refresh"; - public const string Delete = "Delete"; - - private readonly string thumbprint; - private readonly string thumbprintAlgorithm; - private const string OperationTargetFormatString = @"Certificate: {0} ({1})"; - - public override string OperationTarget - { - get { return string.Format(CultureInfo.CurrentCulture, OperationTargetFormatString, this.thumbprint, this.thumbprintAlgorithm); } - } - - public CertificateOperation(string operationName, string thumbprint, string thumbprintAlgorithm) - : base(operationName) - { - this.thumbprint = thumbprint; - this.thumbprintAlgorithm = thumbprintAlgorithm; - } - } -} diff --git a/CSharp/BatchExplorer/Helpers/ResourceFileStringParser.cs b/CSharp/BatchExplorer/Helpers/ResourceFileStringParser.cs deleted file mode 100644 index dfaa0b0a..00000000 --- a/CSharp/BatchExplorer/Helpers/ResourceFileStringParser.cs +++ /dev/null @@ -1,77 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Microsoft.Azure.BatchExplorer.Models; - -namespace Microsoft.Azure.BatchExplorer.Helpers -{ - public static class ResourceFileStringParser - { - private static readonly string[] FileDelimiter = new[] { ";", Environment.NewLine }; - private static readonly string[] PartDelimiter = new[] { "=>" }; - - public static ResourceFileParseResult Parse(string text) - { - if (string.IsNullOrWhiteSpace(text)) - { - return ResourceFileParseResult.Empty; - } - - var fileStrings = text.Split(FileDelimiter, StringSplitOptions.RemoveEmptyEntries) - .Select(s => s.Trim()) - .ToList(); - - var errors = new List(); - var files = new List(); - - foreach (var fileString in fileStrings) - { - var rawParse = fileString.Split(PartDelimiter, StringSplitOptions.None) - .Select(s => s.Trim()) - .ToList(); - - if (rawParse.Count == 2 && rawParse[0].Length > 0 && rawParse[1].Length > 0) - { - files.Add(new ResourceFileInfo(rawParse[0], rawParse[1])); - } - else - { - errors.Add(string.Format("Resource file '{0}' was not of the form 'blobSource => filePath'", fileString)); - } - } - - return new ResourceFileParseResult(errors, files); - } - } - - public sealed class ResourceFileParseResult - { - private readonly IReadOnlyList errors; - private readonly IReadOnlyList files; - - public static readonly ResourceFileParseResult Empty = new ResourceFileParseResult(new List(), new List()); - - public ResourceFileParseResult(List errors, List files) - { - this.errors = errors.AsReadOnly(); - this.files = files.AsReadOnly(); - } - - public bool HasErrors - { - get { return errors.Any(); } - } - - public IReadOnlyList Errors - { - get { return errors; } - } - - public IReadOnlyList Files - { - get { return files; } - } - } -} diff --git a/CSharp/BatchExplorer/Helpers/WaitSpinnerPanel.cs b/CSharp/BatchExplorer/Helpers/WaitSpinnerPanel.cs deleted file mode 100644 index b76053fc..00000000 --- a/CSharp/BatchExplorer/Helpers/WaitSpinnerPanel.cs +++ /dev/null @@ -1,6 +0,0 @@ -//Copyright (c) Microsoft Corporation - -namespace Microsoft.Azure.BatchExplorer.Helpers -{ - public enum WaitSpinnerPanel { Left, UpperRight, LowerRight } -} diff --git a/CSharp/BatchExplorer/Images/LeftArrow.png b/CSharp/BatchExplorer/Images/LeftArrow.png deleted file mode 100644 index c1c0bcff1ce6ceebf5155cdb0c7783b350fbcbde..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1911 zcmV--2Z;EIP)z@;j(q!3lK=n!AY({UO#lFTB>(_`g8%^e{{R4h=>PzA zFaQARU;qF*m;eA5Z<1fdMgRZ??MXyIRCwC#SzByeR~21*pL54E_INyY;zymCJP0Bc zP#`I(L{X}$e;|ZVKTtucC{-LDA4o+)YM}oh!AAv(kQymQd_e``2T>8J`DjWKi597e zOGBGSLlQepY#Ki@9^biVZ$8eMd+&JCmqdsy`ASFk;W_uNwa?mX?|V(EiuJrP*7>$U zV1vL0fpxyw|HVz}2Y&Mmh@LE2{_C5E9{=9DAyAu`EC6(rE$^$0*7(*tSH4R`KTy@y znwL;*VsfVvT{Je@H#lD7kJm>45CD|cd=AtmCcmacQ$3}=@xgkXIVylH2mFZEG=bX0 zk)JEkAIjCiVr6s`#0)YFA_EEx)?^NhPfV5=I0`loR)h1NwnZaxVi8V@~HZl1L zB06rY-8?Wh&TJ!)p$vE+g1fK+{2?UsbtO8}Q|cWV+)`(bBCug_4!BVbsc2*+gQZ zLiSt3AmbC94Fk;nm7jB-1($;Qrk^aPG`y22clZ89*n2+QgB^l=!zjrQWDAJOU7>;3);4i)>p`hC$Y5@?!R~ zpmvlgOYpGb>B=jhP^g4s6{spGB>+GiNCYIN?Q{bGu64LjZU2#9EAxSJb%=|VN(z)r zrhDX$Jqb^WjR9K&GN$7=s}W%i0l1CTQs5#Gh$x(sF#Jk5=O9keh+UV|Y|#5lF!r<6 z&BGj(N&p*>p`6E)Phev*DFxZE^`OaG58g1y*pB&LLP+a`D&Q1oIZek(B4{~5;siqq!ryuI3J|ccWm}Ed7%at_6)5Hme5kUi-i-%utO1Pi zWP*I!d7>aJ3(!n}rT{GwIQ2Mu9w;E*UPv{Uu$|z=xpWVaE(uxy#pz2|u>E6o3=b6X zZo_#{sRZ)ApJ|+pO(V~SA#AX$gyk4$0Z0J2kgVx56<}!UG;N3RF5}YZi_;F^o{aM( zR<{zC^wS&_nitMpqAgqR!RYWN%q}}9Q6`CYG6%_+036032BXm;Gz4%VNhuVse9roy z=fQ{J1R|NVKy5Hi9&pjDmKl-cPrAl?-@};Y|^6zPkReI19nU3hQHL%ve zMh3zLi;ghU1ZJ9w`Gnwt#EkJpidGk;Jm|Je!qEIa2VO$d{c1RfXg2`>SUP+Bjq`^d z|4ae#@&DYI!`Z2~u&LLguNZ-?K@>$GW6@B?Y)qJLDrQ@Rm^fPz_Sy$=S4GW$Ye-5> zlQWIHbCATPjw4BKpUZ{!YUWz5F+X$hxdV^7xBvd5IF9x7t5fKa76$qXcsBv2n~Ha0 zU{M%q{Aw7J^Ly@Wr?p*GMSXF~MO;FpGoTJG?B8p+#6iS$^@|<75D^&weM5V`ynE9l z`~Tc*G|GcJcA#f$9CIxN8Jjvy7jPmxcux^TCRb&>%Sh@nfsFHeajTtYm5qu5K{_ge zV$0#RYl}Gh%-$~o_?N2Abv1KD!~hDW)IVH5aQKgIrM0(j%Q!~v-G$kNkx;Jx$${U| zZ_zmQ3IyW2QR1x8V}@y)Lfej!Kc_G!YdxHE9p?aW+Jpa6Xd^DD>cVZiQSvh^fXcQf zp8X;EMh@Cag|_b9gPT-9Q^Jjz+wO>6LuD-d?F5b;eCT0#C%sc!BM_KV)z5N`K%BO>Q-MqW(=o z+rM-8SSxPr8olq6DAu=Pwy99~f_m>z8H*=R;>D-;ZC2H}HSPI{*_*^w*i4F{1zg002ovPDHLkV1jIhdjkLf diff --git a/CSharp/BatchExplorer/Images/RightArrow.png b/CSharp/BatchExplorer/Images/RightArrow.png deleted file mode 100644 index 6e9963d2d056d91bcbf348bee7dc3592edd1efed..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1935 zcmV;A2XOd_P)z@;j(q!3lK=n!AY({UO#lFTB>(_`g8%^e{{R4h=>PzA zFaQARU;qF*m;eA5Z<1fdMgRZ@1xZ9fRCwC#nR|#_XBozS@AsYA+3ariGTB_(bd!>c zxtO-Wm>^PVZM4R;)T#tQq!9hXn*0}|V5x>l~Q9tK`BK_NJK3*Nn52=5;R~- zQ(Mxsnq*_L&2DDrx-;i|-|HXeoSE6pg|wK<;vP6K=bPD?=Xu}fdERf&5mjX}ABIVO zOc9tOFhyXBz_mSstMMcAHa+u{Aghh=^m|W!b=RcpfCvxHx%JjnV$72(w(j0NYxRBE z$wdGmw_qM~*Q~Z}?Vb0}z3UrCmOSvoIU*vHqyqv*=GN)RXXTb> z?-UU;86+%>n^fI2a@?d< z4-AsNZww}>JR&qatKhs+cgk3#)SV}cJYnRhM==5K9NzgvLLPMv?;JSK>s80%>FwEE z@2o%EyW`czMdVRcb?2E_ti>4HkcvqFw*t380zNrY@W!NnBN!8RBT^`b%23raSauAS z97C0ebJd7q%~7p;qR64nq0U2crr^Dc->-#^BWDX7uVrkutM8%vpZNP9Z`<(Q&ht8u zf^Mz8B;80WEMR;yb^iEdmlU2x1Nc4oo`m&d3@yJGr86% zCF3|YG{Q(nyS;5@$6brpe(h}$SqRisRbvS?44Qyy1sMblB4Uy?Yfv%NRTy(hIf9x` zvYpric*UsV6O*dfCO9`iI?mx6a*Bzxt~uu!=u&D%OuM54=mkcAFeYFP#s-LyCisTd z1B^A;Anr~ihGHa?oDwN05=UxF$j3P!gKkvYH-R?@M6Co8LM@e7=P~NJb5S?5d%GwW zBdz&JfKFhvK_E7(Z`39@NTpk*_&teKyqREe}w zExQwkU-;3Xr?>tl0iOqI>0k>)_yI458he9!=Tr3w}-@Rk=u|GX~7#ISIK-4;w zMO9h$(C>Y{SQcrSt|kF(q*?v=wKRrS8l%QE*DrKrG8rnfW^wFnHSS1@QPVE88)faH zUiy2w86GaWa(?*eD^GlLQ~tzT{{qeem5D>FK|n;hfdQcVO6*4O-f`%!qci$>_e?2~ z)cET6Wre$!<}lLENWSDp2ao=4|6^Zzv_Z>v;+6F}yQZK%KKAJqvm> z+_88Dm8xgBP^u69WB>MpyS6-+fG+@{Ug8-*kQgxp!Yc)S-Oj%?C6h=A5T&ypYCz4t6PgA zg8GP=?ZWzx&c@YM2Zsu^|Gf6nV+VI_*_}wHcsY`}HUx~|YL0tW+(5BV3D1pIM~>{> zx#^vko;jRIrgFKGxkeo@%$w28iBqFtSQ&loRjWlE&OooolfNUC8Q6Fv3=)_?!~qr%(ZDF2F!j>b zAP<+EO_pa$`j<}e7B1bkY5Dww-8t)w?`~gHobS1-9jFMXl9|m1MDWb8S^nyqpUa%h zH|s3-)Ej=AcYMQwEy?GKR~R0@CEankrQCkUhQEhCf19?X8f4j<{p&@!<2{!xU$EY7 znu-AhGdt70b`gZKO-AMKbOXweR~r=0z-kp M)78&qol`;+0QL=o9RL6T diff --git a/CSharp/BatchExplorer/Images/azure.png b/CSharp/BatchExplorer/Images/azure.png deleted file mode 100644 index be5028b2f245165f015927020e41247f8a3c0dfe..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 74078 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%0AZH5sxRN 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
~P!ClXE~eM+`gSNoJmY@UJ($V? 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 SE#EEu0H`RukS~=r@&6z1I>HJ7 diff --git a/CSharp/BatchExplorer/Images/batchExplorer.ico b/CSharp/BatchExplorer/Images/batchExplorer.ico deleted file mode 100644 index 33871dcbf220af5dda73d8cc30d4311cc9291479..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9062 zcmeHNTW=dx5I*)MUbji=O`X;8*a(FUZ|a2ndNFQ9&uCR1}&B5b%J+6CiFX zf``7QffN)7f`BL>P}*D?piNRC6#-R6Kp>$?3^QkU*5mc=dKHWnp&e;FbIx48GqabR zV@IikYEb#SLYY^mET!&H${DBCskBnpaLz&|`)GqwFSheItwtM_`nyZ10~CXNJ2Lrc za)dpIKjRMk|2t496u`^%teUXTO&oHW#zFYfFN!Yn1l3qie7PRhHv@i9Z+ML?qx4+* za2!d(kYm=p*kfa3zJBD-xqrKQ8Lt2JhcB}aNyZ=19t&?kB z_~<3L@adbr%swQe)K7RaCJMgv57P<1udnYavA0fM+eYyJT>lAzNUn!5NCwrl5&XG{ zhst^;F{K_AKd3h{o^;MVr{CAK20t#n%Vm66{SrUQ^Uv$3CZpg>pK5wFJg;5m3#woG zRMWlrz2mU>Abi<-)`RkR@w{V-<2i4RFno?78RRE(OMj`ej~AQ9L3wF@=B9iKa)do_KLOt_(9_ccy}iAF zdmiZT?}veb0T>({)X(@(u>iwE1t=Da@W6e;aQOZ^;n4?2;KY%;?03-V!*HH>@(9eo z^9anpdkp5M9)pFc$l;`;v`&Inu4D%&BC=Gz5!fu%yAFmd!V-WfcqlYL`uTY z6u2TIO_U0;Z_8x1nq=Q+m1q}^O(ereH@CEG@wYb`M#4x3#}lf?H#L4mezrHYjFZrr0OTe6G#$$pC_VYln&_1|zuo@`^}83KR6pXB>bLFLwzf{}hwf^!kqEzo7uRoZS680x<@MX~ zdCS^fvR7Weyp=_B#r5C6+o7AaneA>o#Z-{MudvYs*`4d}Z^tH^_VxF**KN{o@8Iky zaNkj%eG2~MqJK$oe^2q>r_`+{wE)6B)im=)^2zfJ$IJ7c)Y(okQs*2zCu5|}cE5PG zk(4n~XCE1ld&xCsw#yi)vt7pX+U1;#k@|lb&$&rTOxAz>alWkQ?2mir>&!gIF=#AWDn1HUJ$wMWta%+J^7sVuq$5f9jL8RncVaM>&O@d5jPrs?`mS7`gXHyN6ye@`hT!1nFdREHqR&41+;jS2Jog-h1w8jGOd+2+4vS|VhsF1vaL+%> zA3W`zcfSAR1z7p~6+G{}4r^bYr28l4xCik)usQAl-LaA-xs1 z_7;y533Chn(@3VZqobo4?F#*Op#S#H&Q2avba}oX-gVOJKoLj#8dul n)=oPg#p5{B)a>H7=W@ASEw}?UFkT-}c_hpyNa diff --git a/CSharp/BatchExplorer/Images/cancel.png b/CSharp/BatchExplorer/Images/cancel.png deleted file mode 100644 index 2ff10eda44bf994ef917b0f64cdf90219b9966d9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 516 zcmeAS@N?(olHy`uVBq!ia0vp^J|N7&1|*M957Y)yk|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*9U+7?*jvIEGZ*dUNNY?_mRhw!}G{5=(O!qz#;AG)z3hwt-Q5 zgQI%`?-|LRLQWE7Ji6W*&nB8YmRQVz3~P zGUk0Y=krGCzVZon$C9^qci2Dqma&pUH0U?mW7j3$P2z0icEz+ag_+*sUvoj&mwUCu zTb?lUE#Ap%r6YD<{CB|WYvD7=X}!}rO~3JEx2CbKmX6?^rMhNaf@;RK4ZE7(I&SU| zy`8zIamKuF*H0zdEqVXs_kQ2~)2DRTOgMZwBVyI;_gp5XI$yUeV(=Axoo%`CgV@$J zndggkoVWPuCVbjOZrY-mx6fRb|6kfLV?*51^~Uy_ww<}$#-x3~sBs%l+tR*m5=Xnr z4~tLEn7iF|_crUbixvi6?pm~Wp{dE`2(gQ2k|Uj^nNADM`ZoFBy1j|bQx5-&ElQpy z+FmbheD?gV7vbtl_b>PvDX%^2=&Ab`{!9`4`f};SX@b2yJ5N>Iy=HoRKNrumc1AV{ rR*8fLAeA73LNx?7#4fU9m0(EHd0OAI`R@T>v@&?Q`njxgN@xNA9ZuhA diff --git a/CSharp/BatchExplorer/Images/check.png b/CSharp/BatchExplorer/Images/check.png deleted file mode 100644 index 3da8d2e5cace6658783fac632cc2c840d9abd51d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 684 zcmV;d0#p5oP)FWTD&=GJ0 z-Jot@H_!>H6F35P0=og-KsV40a07Z*&sPgbg5^S@|Gk%|uR=6m!;u_OQ4|A&eLR5x zU;qOczyO8-7{CAqFn}Qd1~7mD3}66501RLN0~o+Ojwp(z)Cy`DwOH+Y?%^>T0VVX3 zQ9DB&sf}rDJIt^u79*t>SOa;#rO##ns|I5wS3XH}p3%U~wC{!0H@~|I1gf&W)D?af|*&7FY{cSQ=n91GGYu ze3cve+PK8hx+K#s(Bzn=KK5;9tG8e+(6WZ}R~AV=agC)0)&ec9Id5ul-n0)aZLrwl zvigJ8aEEO~z6-FnXqLxr`^4g=zBQ6ndS=)#p9_7aO*K~_4!v&CTsO}WhZE2PvimRWL3EPcRoUahdKI5?@C22Rcnm(bWvWN6yaoQBmKKux-#SXx`*K|3H`i1LYmB!+x>UGHdIxYIamKUJ81(w5u;&fmzXP>&%tLW#|4MR#a4U z{`K{V|Dm3@7JaN=*RcpNNHj2l5K96B8wd$NxDb(JGBa{-vvRo$i!*!+?vDL6?cZ7X z?(J?LHXLMg`!{*-k>)aIiB)2(EF>{_J!|DK;U=tJT*DKTRNFJ>Wne68_gSCB&^YoMTcYaO0wB5DV^p*7DU;D1a zE%|2quybP0`-Q0ze*>Tr((sa>7Ncq78*?DVNwc{MS8@8TIx5`Ov0KQ>-8XMx1C2Z_^zY~LsUnV=CY##4Q5MyXRlTxh})=8OB*Zh0T{+iGfdps&Rj z^ZW1GHN)!nZ@sbben8LXNq4qb?brOITwbnw)atOyw4IV-UsfMtJG)otx2olfL&r5B p(Z#?9jy0#LT=By}Z;C1rt33 zJ+nVO$@du;m@GV9978JN-d+pLiVoy)y?AC3^Naf96BeeH@QPTeeb+3^YuVF3IjZQL zdtZX%R>PQ&3K!ZhzfAehxHwb7_i%=k+hv1UZ5K^?mL;0-;uR{B`TShq|Bbiicdxf@ zTr9IUbZ;)xvA(J=eqXn7N?5Id~f}B z-vc)$^7o}4Ui1BRuCPJbljdYk=fBU?{vAoamX9p*jQ^Y6{H*&An`^Hkl>SUO_HX(8 zw7v29vl})l%gcC6y}GQM_OM_k`=3!yY;#@9M<2m_6khI?gCG)k!V s{hZx@@5Rh_uMd$Bk-+Gla`~|R%B%BI12YJTGruZhmb%P$;7!A?5)RMyqBj?2n zDH+xZcPA}dk{qA>Ztlvb_F{LZ@NsI&-#qoKBv(Q&0ZsD|kz9+p+Jo zVRdg}lHyCoSe?v2%F~nIS+-1`;CE#2HzSJ;x4(y-o5Yf-lXvux@tt-Vb@r0eo1gl= zZs>GfDzu?rQ~HwibE(!)i8M zc~mF!Ims{Pf8xfOFROi7(oVffW?qvUDV-V4s*}fTaM`JPO~z)^FIzV?L|rNUxU1@^ zMrQ4lD-ZlXMOv6IuPBRq^{GSct<$$F zcGoQEKW}-uQZpha`Bm-adSK-ea1bPWIt9X}6trfBO|b!T5*q zDVIx)b05ZOoqS){{KVTVf4VrgPoUJTpDb5264HMPF+vm40R{Ag#L&zDPHS5O>sTZh Yv`;bI?~e6i1}1z4Pgg&ebxsLQ02t$6>;M1& diff --git a/CSharp/BatchExplorer/Images/forwardArrow.png b/CSharp/BatchExplorer/Images/forwardArrow.png deleted file mode 100644 index 4072bbde28eada52f4297bd76013a1969eeb37a1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 25924 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 diff --git a/CSharp/BatchExplorer/Images/search.ico b/CSharp/BatchExplorer/Images/search.ico deleted file mode 100644 index a6f5bf0ea289e53833649b7247700a56679d84b2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 92176 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 - /// Send this message when adding a new account - /// - public class AddAccountMessage - { - public AccountDialogViewModel AccountDialogViewModel { get; set; } - } -} diff --git a/CSharp/BatchExplorer/Messages/AsyncOperationListChangedMessage.cs b/CSharp/BatchExplorer/Messages/AsyncOperationListChangedMessage.cs deleted file mode 100644 index 6899bfb5..00000000 --- a/CSharp/BatchExplorer/Messages/AsyncOperationListChangedMessage.cs +++ /dev/null @@ -1,12 +0,0 @@ -//Copyright (c) Microsoft Corporation - -namespace Microsoft.Azure.BatchExplorer.Messages -{ - /// - /// Send this message when the AsyncOperationTracker has updated its list of async operations - /// - public class AsyncOperationListChangedMessage - { - - } -} diff --git a/CSharp/BatchExplorer/Messages/CertificateUpdateCompleteMessage.cs b/CSharp/BatchExplorer/Messages/CertificateUpdateCompleteMessage.cs deleted file mode 100644 index 00e7f80c..00000000 --- a/CSharp/BatchExplorer/Messages/CertificateUpdateCompleteMessage.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Microsoft.Azure.BatchExplorer.Messages -{ - public class CertificateUpdateCompleteMessage - { - } -} diff --git a/CSharp/BatchExplorer/Messages/CloseGenericMessage.cs b/CSharp/BatchExplorer/Messages/CloseGenericMessage.cs deleted file mode 100644 index d162549a..00000000 --- a/CSharp/BatchExplorer/Messages/CloseGenericMessage.cs +++ /dev/null @@ -1,8 +0,0 @@ -//Copyright (c) Microsoft Corporation - -namespace Microsoft.Azure.BatchExplorer.Messages -{ - public class CloseGenericMessage - { - } -} diff --git a/CSharp/BatchExplorer/Messages/CloseGenericPopup.cs b/CSharp/BatchExplorer/Messages/CloseGenericPopup.cs deleted file mode 100644 index e5c7cf68..00000000 --- a/CSharp/BatchExplorer/Messages/CloseGenericPopup.cs +++ /dev/null @@ -1,11 +0,0 @@ -//Copyright (c) Microsoft Corporation - -namespace Microsoft.Azure.BatchExplorer.Messages -{ - /// - /// Use this to signal to close the generic popup control - /// - public class CloseGenericPopup - { - } -} diff --git a/CSharp/BatchExplorer/Messages/ComputeNodeUserActionMessage.cs b/CSharp/BatchExplorer/Messages/ComputeNodeUserActionMessage.cs deleted file mode 100644 index a80182c7..00000000 --- a/CSharp/BatchExplorer/Messages/ComputeNodeUserActionMessage.cs +++ /dev/null @@ -1,35 +0,0 @@ -//Copyright (c) Microsoft Corporation - -using System; - -namespace Microsoft.Azure.BatchExplorer.Messages -{ - public enum ComputeNodeUserAction - { - AddUser, - DeleteUser, - EditUser - } - - public class ComputeNodeUserActionMessage - { - public ComputeNodeUserAction Action { get; private set; } - - public string UserName { get; private set; } - - public string Password { get; private set; } - - public bool IsAdmin { get; private set; } - - public DateTime? ExpiryDate { get; private set; } - - public ComputeNodeUserActionMessage(ComputeNodeUserAction action, string userName, string password = null, bool? isAdmin = null, DateTime? expiryDate = null) - { - this.Action = action; - this.UserName = userName; - this.Password = password; - this.IsAdmin = isAdmin.HasValue && isAdmin.Value; - this.ExpiryDate = expiryDate; - } - } -} diff --git a/CSharp/BatchExplorer/Messages/ConfirmAccountAddMessage.cs b/CSharp/BatchExplorer/Messages/ConfirmAccountAddMessage.cs deleted file mode 100644 index d80f7d88..00000000 --- a/CSharp/BatchExplorer/Messages/ConfirmAccountAddMessage.cs +++ /dev/null @@ -1,16 +0,0 @@ -//Copyright (c) Microsoft Corporation - -using Microsoft.Azure.BatchExplorer.Models; -using Microsoft.Azure.BatchExplorer.PluginInterfaces.AccountPlugin; - -namespace Microsoft.Azure.BatchExplorer.Messages -{ - /// - /// Send this when confirming the addition of a new account - /// - public class ConfirmAccountAddMessage - { - public IAccountManager AccountManager { get; set; } - public Account AccountToAdd { get; set; } - } -} diff --git a/CSharp/BatchExplorer/Messages/ConfirmAccountDeleteMessage.cs b/CSharp/BatchExplorer/Messages/ConfirmAccountDeleteMessage.cs deleted file mode 100644 index 323e93c6..00000000 --- a/CSharp/BatchExplorer/Messages/ConfirmAccountDeleteMessage.cs +++ /dev/null @@ -1,11 +0,0 @@ -//Copyright (c) Microsoft Corporation - -namespace Microsoft.Azure.BatchExplorer.Messages -{ - /// - /// Send this when a delete dialog is confirmed - /// - public class ConfirmAccountDeleteMessage - { - } -} diff --git a/CSharp/BatchExplorer/Messages/ConfirmAccountEditMessage.cs b/CSharp/BatchExplorer/Messages/ConfirmAccountEditMessage.cs deleted file mode 100644 index 08364436..00000000 --- a/CSharp/BatchExplorer/Messages/ConfirmAccountEditMessage.cs +++ /dev/null @@ -1,16 +0,0 @@ -//Copyright (c) Microsoft Corporation - -using Microsoft.Azure.BatchExplorer.Models; -using Microsoft.Azure.BatchExplorer.PluginInterfaces.AccountPlugin; - -namespace Microsoft.Azure.BatchExplorer.Messages -{ - /// - /// Send this when an edit is confirmed - /// - public class ConfirmAccountEditMessage - { - public IAccountManager AccountManager { get; set; } - public Account AccountToEdit { get; set; } - } -} diff --git a/CSharp/BatchExplorer/Messages/DisableSchedulingComputeNodeConfirmationMessage.cs b/CSharp/BatchExplorer/Messages/DisableSchedulingComputeNodeConfirmationMessage.cs deleted file mode 100644 index 1f548ef2..00000000 --- a/CSharp/BatchExplorer/Messages/DisableSchedulingComputeNodeConfirmationMessage.cs +++ /dev/null @@ -1,20 +0,0 @@ -//Copyright (c) Microsoft Corporation - -namespace Microsoft.Azure.BatchExplorer.Messages -{ - public enum ComputeNodeDisableSchedulingConfimation - { - Confirmed, - Cancelled - } - - public class DisableSchedulingComputeNodeConfirmationMessage - { - public ComputeNodeDisableSchedulingConfimation Confirmation { get; private set; } - - public DisableSchedulingComputeNodeConfirmationMessage(ComputeNodeDisableSchedulingConfimation confirmation) - { - this.Confirmation = confirmation; - } - } -} diff --git a/CSharp/BatchExplorer/Messages/DisableSchedulingComputeNodeMessage.cs b/CSharp/BatchExplorer/Messages/DisableSchedulingComputeNodeMessage.cs deleted file mode 100644 index 4bae880d..00000000 --- a/CSharp/BatchExplorer/Messages/DisableSchedulingComputeNodeMessage.cs +++ /dev/null @@ -1,8 +0,0 @@ -//Copyright (c) Microsoft Corporation - -namespace Microsoft.Azure.BatchExplorer.Messages -{ - public class DisableSchedulingComputeNodeMessage - { - } -} diff --git a/CSharp/BatchExplorer/Messages/EditAccountMessage.cs b/CSharp/BatchExplorer/Messages/EditAccountMessage.cs deleted file mode 100644 index c007d956..00000000 --- a/CSharp/BatchExplorer/Messages/EditAccountMessage.cs +++ /dev/null @@ -1,14 +0,0 @@ -//Copyright (c) Microsoft Corporation - -using Microsoft.Azure.BatchExplorer.ViewModels; - -namespace Microsoft.Azure.BatchExplorer.Messages -{ - /// - /// Send this message when editing an account - /// - public class EditAccountMessage - { - public AccountDialogViewModel AccountDialogViewModel { get; set; } - } -} diff --git a/CSharp/BatchExplorer/Messages/EnableSchedulingComputeNodeMessage.cs b/CSharp/BatchExplorer/Messages/EnableSchedulingComputeNodeMessage.cs deleted file mode 100644 index c4219333..00000000 --- a/CSharp/BatchExplorer/Messages/EnableSchedulingComputeNodeMessage.cs +++ /dev/null @@ -1,8 +0,0 @@ -//Copyright (c) Microsoft Corporation - -namespace Microsoft.Azure.BatchExplorer.Messages -{ - public class EnableSchedulingComputeNodeMessage - { - } -} diff --git a/CSharp/BatchExplorer/Messages/GenericDialogMessage.cs b/CSharp/BatchExplorer/Messages/GenericDialogMessage.cs deleted file mode 100644 index 859fd89a..00000000 --- a/CSharp/BatchExplorer/Messages/GenericDialogMessage.cs +++ /dev/null @@ -1,23 +0,0 @@ -//Copyright (c) Microsoft Corporation - -namespace Microsoft.Azure.BatchExplorer.Messages -{ - /// - /// Launch a dialog with a message - /// - public class GenericDialogMessage - { - /// - /// Create a new GenericDialogMessage with the specified message - /// - /// - public GenericDialogMessage(string messageString) - { - MessageString = messageString; - } - /// - /// The message in the dialog - /// - public string MessageString { get; set; } - } -} diff --git a/CSharp/BatchExplorer/Messages/HeatMapPollIntervalUpdatedMessage.cs b/CSharp/BatchExplorer/Messages/HeatMapPollIntervalUpdatedMessage.cs deleted file mode 100644 index aaa2d7a2..00000000 --- a/CSharp/BatchExplorer/Messages/HeatMapPollIntervalUpdatedMessage.cs +++ /dev/null @@ -1,16 +0,0 @@ -//Copyright (c) Microsoft Corporation - -using Microsoft.Azure.BatchExplorer.ViewModels; - -namespace Microsoft.Azure.BatchExplorer.Messages -{ - public class HeatMapPollIntervalUpdatedMessage - { - public HeatMapViewModel UpdatedViewModel { get; private set; } - - public HeatMapPollIntervalUpdatedMessage(HeatMapViewModel updatedViewModel) - { - this.UpdatedViewModel = updatedViewModel; - } - } -} diff --git a/CSharp/BatchExplorer/Messages/JobUpdateCompleteMessage.cs b/CSharp/BatchExplorer/Messages/JobUpdateCompleteMessage.cs deleted file mode 100644 index 043bb215..00000000 --- a/CSharp/BatchExplorer/Messages/JobUpdateCompleteMessage.cs +++ /dev/null @@ -1,11 +0,0 @@ -//Copyright (c) Microsoft Corporation - -namespace Microsoft.Azure.BatchExplorer.Messages -{ - /// - /// Signals when a job is updated - /// - public class JobUpdateCompleteMessage - { - } -} diff --git a/CSharp/BatchExplorer/Messages/LaunchMultibuttonDialogMessage.cs b/CSharp/BatchExplorer/Messages/LaunchMultibuttonDialogMessage.cs deleted file mode 100644 index 4ae6b3ff..00000000 --- a/CSharp/BatchExplorer/Messages/LaunchMultibuttonDialogMessage.cs +++ /dev/null @@ -1,35 +0,0 @@ -//Copyright (c) Microsoft Corporation - -using System.Windows; - -namespace Microsoft.Azure.BatchExplorer.Messages -{ - /// - /// A message that calls for a dialog box beyond the standard Ok-box (though you could use it to get one of those too) - /// - public class LaunchMultibuttonDialogMessage - { - private MessageBoxImage messageBoxImage = MessageBoxImage.None; - - /// - /// The message at the top of the dialog box - /// - public string Caption { get; set; } - /// - /// The message in the dialog - /// - public string DialogMessage { get; set; } - /// - /// The type of buttons on the dialog - /// - public MessageBoxButton MessageBoxButton { get; set; } - /// - /// The type of icon on the dialog - OPTIONAL - defaults to .None if not used - /// - public MessageBoxImage MessageBoxImage - { - get { return this.messageBoxImage; } - set { this.messageBoxImage = value; } - } - } -} diff --git a/CSharp/BatchExplorer/Messages/ModelNotFoundAfterRefresh.cs b/CSharp/BatchExplorer/Messages/ModelNotFoundAfterRefresh.cs deleted file mode 100644 index 1e91fc2d..00000000 --- a/CSharp/BatchExplorer/Messages/ModelNotFoundAfterRefresh.cs +++ /dev/null @@ -1,16 +0,0 @@ -//Copyright (c) Microsoft Corporation - -using Microsoft.Azure.BatchExplorer.Models; - -namespace Microsoft.Azure.BatchExplorer.Messages -{ - public class ModelNotFoundAfterRefresh - { - public ModelBase Model { get; private set; } - - public ModelNotFoundAfterRefresh(ModelBase model) - { - this.Model = model; - } - } -} diff --git a/CSharp/BatchExplorer/Messages/MultibuttonDialogReturnMessage.cs b/CSharp/BatchExplorer/Messages/MultibuttonDialogReturnMessage.cs deleted file mode 100644 index 35758c1e..00000000 --- a/CSharp/BatchExplorer/Messages/MultibuttonDialogReturnMessage.cs +++ /dev/null @@ -1,25 +0,0 @@ -//Copyright (c) Microsoft Corporation - -using System.Windows; - -namespace Microsoft.Azure.BatchExplorer.Messages -{ - /// - /// Message launched when a multibutton dialog closes - /// - public class MultibuttonDialogReturnMessage - { - /// - /// The result of the closing dialog - /// - public MessageBoxResult MessageBoxResult { get; private set; } - /// - /// Construct the message - /// - /// the result gotten from the closing dialog box - public MultibuttonDialogReturnMessage(MessageBoxResult messageBoxResult) - { - MessageBoxResult = messageBoxResult; - } - } -} diff --git a/CSharp/BatchExplorer/Messages/NodeSchedulingMessage.cs b/CSharp/BatchExplorer/Messages/NodeSchedulingMessage.cs deleted file mode 100644 index 1121d9fa..00000000 --- a/CSharp/BatchExplorer/Messages/NodeSchedulingMessage.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Microsoft.Azure.BatchExplorer.Messages -{ - public enum SchedulingType - { - Enable = 0, - Disable = 1 - } - public class NodeSchedulingMessage - { - public SchedulingType ScheduleType { get; set; } - - public NodeSchedulingMessage(SchedulingType schedulingType) - { - this.ScheduleType = schedulingType; - } - } -} diff --git a/CSharp/BatchExplorer/Messages/PoolUpdateCompleteMessage.cs b/CSharp/BatchExplorer/Messages/PoolUpdateCompleteMessage.cs deleted file mode 100644 index f063933d..00000000 --- a/CSharp/BatchExplorer/Messages/PoolUpdateCompleteMessage.cs +++ /dev/null @@ -1,11 +0,0 @@ -//Copyright (c) Microsoft Corporation - -namespace Microsoft.Azure.BatchExplorer.Messages -{ - /// - /// Signals when a pool is updated - /// - public class PoolUpdateCompleteMessage - { - } -} diff --git a/CSharp/BatchExplorer/Messages/RebootComputeNodeConfirmationMessage.cs b/CSharp/BatchExplorer/Messages/RebootComputeNodeConfirmationMessage.cs deleted file mode 100644 index a03ed5fe..00000000 --- a/CSharp/BatchExplorer/Messages/RebootComputeNodeConfirmationMessage.cs +++ /dev/null @@ -1,20 +0,0 @@ -//Copyright (c) Microsoft Corporation - -namespace Microsoft.Azure.BatchExplorer.Messages -{ - public enum ComputeNodeRebootConfimation - { - Confirmed, - Cancelled - } - - public class RebootComputeNodeConfirmationMessage - { - public ComputeNodeRebootConfimation Confirmation { get; private set; } - - public RebootComputeNodeConfirmationMessage(ComputeNodeRebootConfimation confirmation) - { - this.Confirmation = confirmation; - } - } -} diff --git a/CSharp/BatchExplorer/Messages/RebootComputeNodeMessage.cs b/CSharp/BatchExplorer/Messages/RebootComputeNodeMessage.cs deleted file mode 100644 index 5632ce44..00000000 --- a/CSharp/BatchExplorer/Messages/RebootComputeNodeMessage.cs +++ /dev/null @@ -1,8 +0,0 @@ -//Copyright (c) Microsoft Corporation - -namespace Microsoft.Azure.BatchExplorer.Messages -{ - public class RebootComputeNodeMessage - { - } -} diff --git a/CSharp/BatchExplorer/Messages/RefreshMessage.cs b/CSharp/BatchExplorer/Messages/RefreshMessage.cs deleted file mode 100644 index b8703b16..00000000 --- a/CSharp/BatchExplorer/Messages/RefreshMessage.cs +++ /dev/null @@ -1,22 +0,0 @@ -//Copyright (c) Microsoft Corporation - -namespace Microsoft.Azure.BatchExplorer.Messages -{ - public enum RefreshTarget - { - Pools, - Jobs, - JobSchedules, - Certificates, - } - - public class RefreshMessage - { - public RefreshTarget ItemToRefresh { get; private set; } - - public RefreshMessage(RefreshTarget itemToRefresh) - { - this.ItemToRefresh = itemToRefresh; - } - } -} diff --git a/CSharp/BatchExplorer/Messages/ReimageComputeNodeConfirmationMessage.cs b/CSharp/BatchExplorer/Messages/ReimageComputeNodeConfirmationMessage.cs deleted file mode 100644 index 5c2b2401..00000000 --- a/CSharp/BatchExplorer/Messages/ReimageComputeNodeConfirmationMessage.cs +++ /dev/null @@ -1,20 +0,0 @@ -//Copyright (c) Microsoft Corporation - -namespace Microsoft.Azure.BatchExplorer.Messages -{ - public enum ComputeNodeReimageConfimation - { - Confirmed, - Cancelled - } - - public class ReimageComputeNodeConfirmationMessage - { - public ComputeNodeReimageConfimation Confirmation { get; private set; } - - public ReimageComputeNodeConfirmationMessage(ComputeNodeReimageConfimation confirmation) - { - this.Confirmation = confirmation; - } - } -} diff --git a/CSharp/BatchExplorer/Messages/ReimageComputeNodeMessage.cs b/CSharp/BatchExplorer/Messages/ReimageComputeNodeMessage.cs deleted file mode 100644 index cc585570..00000000 --- a/CSharp/BatchExplorer/Messages/ReimageComputeNodeMessage.cs +++ /dev/null @@ -1,8 +0,0 @@ -//Copyright (c) Microsoft Corporation - -namespace Microsoft.Azure.BatchExplorer.Messages -{ - public class ReimageComputeNodeMessage - { - } -} diff --git a/CSharp/BatchExplorer/Messages/ShowAboutWindow.cs b/CSharp/BatchExplorer/Messages/ShowAboutWindow.cs deleted file mode 100644 index 154e43e3..00000000 --- a/CSharp/BatchExplorer/Messages/ShowAboutWindow.cs +++ /dev/null @@ -1,11 +0,0 @@ -//Copyright (c) Microsoft Corporation - -namespace Microsoft.Azure.BatchExplorer.Messages -{ - public class ShowAboutWindow - { - public ShowAboutWindow() - { - } - } -} diff --git a/CSharp/BatchExplorer/Messages/ShowAddTaskWindow.cs b/CSharp/BatchExplorer/Messages/ShowAddTaskWindow.cs deleted file mode 100644 index f730f33a..00000000 --- a/CSharp/BatchExplorer/Messages/ShowAddTaskWindow.cs +++ /dev/null @@ -1,14 +0,0 @@ -//Copyright (c) Microsoft Corporation - -namespace Microsoft.Azure.BatchExplorer.Messages -{ - public class ShowAddTaskWindow - { - public string JobId { get; private set; } - - public ShowAddTaskWindow(string jobId) - { - this.JobId = jobId; - } - } -} diff --git a/CSharp/BatchExplorer/Messages/ShowAsyncOperationDetailWindow.cs b/CSharp/BatchExplorer/Messages/ShowAsyncOperationDetailWindow.cs deleted file mode 100644 index b43afd2d..00000000 --- a/CSharp/BatchExplorer/Messages/ShowAsyncOperationDetailWindow.cs +++ /dev/null @@ -1,16 +0,0 @@ -//Copyright (c) Microsoft Corporation - -using Microsoft.Azure.BatchExplorer.Models; - -namespace Microsoft.Azure.BatchExplorer.Messages -{ - public class ShowAsyncOperationDetailWindow - { - public AsyncOperationModel AsyncOperation { get; private set; } - - public ShowAsyncOperationDetailWindow(AsyncOperationModel asyncOperation) - { - this.AsyncOperation = asyncOperation; - } - } -} diff --git a/CSharp/BatchExplorer/Messages/ShowAsyncOperationTabMessage.cs b/CSharp/BatchExplorer/Messages/ShowAsyncOperationTabMessage.cs deleted file mode 100644 index 8e066e46..00000000 --- a/CSharp/BatchExplorer/Messages/ShowAsyncOperationTabMessage.cs +++ /dev/null @@ -1,14 +0,0 @@ -//Copyright (c) Microsoft Corporation - -namespace Microsoft.Azure.BatchExplorer.Messages -{ - public class ShowAsyncOperationTabMessage - { - public bool Show { get; set; } - - public ShowAsyncOperationTabMessage(bool show) - { - this.Show = show; - } - } -} diff --git a/CSharp/BatchExplorer/Messages/ShowCreateCertificateWindow.cs b/CSharp/BatchExplorer/Messages/ShowCreateCertificateWindow.cs deleted file mode 100644 index 4e9a4000..00000000 --- a/CSharp/BatchExplorer/Messages/ShowCreateCertificateWindow.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Microsoft.Azure.BatchExplorer.Messages -{ - public class ShowCreateCertificateWindow - { - } -} diff --git a/CSharp/BatchExplorer/Messages/ShowCreateComputeNodeUserWindow.cs b/CSharp/BatchExplorer/Messages/ShowCreateComputeNodeUserWindow.cs deleted file mode 100644 index 0de7658d..00000000 --- a/CSharp/BatchExplorer/Messages/ShowCreateComputeNodeUserWindow.cs +++ /dev/null @@ -1,16 +0,0 @@ -//Copyright (c) Microsoft Corporation - -namespace Microsoft.Azure.BatchExplorer.Messages -{ - public class ShowCreateComputeNodeUserWindow - { - public string PoolId { get; private set; } - public string ComputeNodeId { get; private set; } - - public ShowCreateComputeNodeUserWindow(string poolId, string computeNodeId) - { - this.PoolId = poolId; - this.ComputeNodeId = computeNodeId; - } - } -} diff --git a/CSharp/BatchExplorer/Messages/ShowCreateJobScheduleWindow.cs b/CSharp/BatchExplorer/Messages/ShowCreateJobScheduleWindow.cs deleted file mode 100644 index b10a4cb7..00000000 --- a/CSharp/BatchExplorer/Messages/ShowCreateJobScheduleWindow.cs +++ /dev/null @@ -1,11 +0,0 @@ -//Copyright (c) Microsoft Corporation - -namespace Microsoft.Azure.BatchExplorer.Messages -{ - public class ShowCreateJobScheduleWindow - { - public ShowCreateJobScheduleWindow() - { - } - } -} diff --git a/CSharp/BatchExplorer/Messages/ShowCreateJobWindow.cs b/CSharp/BatchExplorer/Messages/ShowCreateJobWindow.cs deleted file mode 100644 index 61c5281d..00000000 --- a/CSharp/BatchExplorer/Messages/ShowCreateJobWindow.cs +++ /dev/null @@ -1,11 +0,0 @@ -//Copyright (c) Microsoft Corporation - -namespace Microsoft.Azure.BatchExplorer.Messages -{ - public class ShowCreateJobWindow - { - public ShowCreateJobWindow() - { - } - } -} diff --git a/CSharp/BatchExplorer/Messages/ShowCreatePoolWindow.cs b/CSharp/BatchExplorer/Messages/ShowCreatePoolWindow.cs deleted file mode 100644 index 526cdac4..00000000 --- a/CSharp/BatchExplorer/Messages/ShowCreatePoolWindow.cs +++ /dev/null @@ -1,18 +0,0 @@ -//Copyright (c) Microsoft Corporation - -namespace Microsoft.Azure.BatchExplorer.Messages -{ - using System.Collections.Generic; - using Batch; - using Helpers; - - public class ShowCreatePoolWindow - { - public Cached> NodeAgentSkus { get; private set; } - - public ShowCreatePoolWindow(Cached> nodeAgentSkus) - { - this.NodeAgentSkus = nodeAgentSkus; - } - } -} diff --git a/CSharp/BatchExplorer/Messages/ShowDeleteWarningMessage.cs b/CSharp/BatchExplorer/Messages/ShowDeleteWarningMessage.cs deleted file mode 100644 index 46b12323..00000000 --- a/CSharp/BatchExplorer/Messages/ShowDeleteWarningMessage.cs +++ /dev/null @@ -1,11 +0,0 @@ -//Copyright (c) Microsoft Corporation - -namespace Microsoft.Azure.BatchExplorer.Messages -{ - /// - /// Send this message when showing the delete warning dialog - /// - public class ShowDeleteWarningMessage - { - } -} diff --git a/CSharp/BatchExplorer/Messages/ShowHeatMapMessage.cs b/CSharp/BatchExplorer/Messages/ShowHeatMapMessage.cs deleted file mode 100644 index 69c7246a..00000000 --- a/CSharp/BatchExplorer/Messages/ShowHeatMapMessage.cs +++ /dev/null @@ -1,16 +0,0 @@ -//Copyright (c) Microsoft Corporation - -using Microsoft.Azure.Batch; - -namespace Microsoft.Azure.BatchExplorer.Messages -{ - public class ShowHeatMapMessage - { - public CloudPool Pool { get; private set; } - - public ShowHeatMapMessage(CloudPool pool) - { - this.Pool = pool; - } - } -} diff --git a/CSharp/BatchExplorer/Messages/ShowOptionsDialogMessage.cs b/CSharp/BatchExplorer/Messages/ShowOptionsDialogMessage.cs deleted file mode 100644 index 1cadce01..00000000 --- a/CSharp/BatchExplorer/Messages/ShowOptionsDialogMessage.cs +++ /dev/null @@ -1,12 +0,0 @@ -//Copyright (c) Microsoft Corporation - -namespace Microsoft.Azure.BatchExplorer.Messages -{ - /// - /// Send this message when editing the options - /// - public class ShowOptionsDialogMessage - { - - } -} diff --git a/CSharp/BatchExplorer/Messages/ShowResizePoolWindow.cs b/CSharp/BatchExplorer/Messages/ShowResizePoolWindow.cs deleted file mode 100644 index b4630732..00000000 --- a/CSharp/BatchExplorer/Messages/ShowResizePoolWindow.cs +++ /dev/null @@ -1,20 +0,0 @@ -//Copyright (c) Microsoft Corporation - -namespace Microsoft.Azure.BatchExplorer.Messages -{ - public class ShowResizePoolWindow - { - public string PoolId { get; private set; } - public int? CurrentDedicated { get; private set; } - public int? CurrentLowPriority { get; private set; } - public string CurrentAutoScaleFormula { get; private set; } - - public ShowResizePoolWindow(string poolId, int? currentDedicated, int? currentLowPriority, string currentAutoScaleFormula) - { - this.PoolId = poolId; - this.CurrentDedicated = currentDedicated; - this.CurrentLowPriority = currentLowPriority; - this.CurrentAutoScaleFormula = currentAutoScaleFormula; - } - } -} diff --git a/CSharp/BatchExplorer/Messages/UpdateWaitSpinnerMessage.cs b/CSharp/BatchExplorer/Messages/UpdateWaitSpinnerMessage.cs deleted file mode 100644 index 64ba4bbd..00000000 --- a/CSharp/BatchExplorer/Messages/UpdateWaitSpinnerMessage.cs +++ /dev/null @@ -1,31 +0,0 @@ -//Copyright (c) Microsoft Corporation - -using Microsoft.Azure.BatchExplorer.Helpers; - -namespace Microsoft.Azure.BatchExplorer.Messages -{ - /// - /// Update the visibility of a panel containing a wait-spinner - /// - public class UpdateWaitSpinnerMessage - { - /// - /// The wait spinner panel whose visibility is to be updated - /// - public WaitSpinnerPanel PanelToChange { get; private set; } - /// - /// True if the panel is to be made visible, otherwise false - /// - public bool MakeSpinnerVisible { get; private set; } - /// - /// Construct a new message to change the visibility of a wait-spinner-panel - /// - /// the panel to update - /// true if we want to make it visible, otherwise false - public UpdateWaitSpinnerMessage(WaitSpinnerPanel panelToChange, bool makePanelVisible=false) - { - PanelToChange = panelToChange; - MakeSpinnerVisible = makePanelVisible; - } - } -} diff --git a/CSharp/BatchExplorer/Models/Account.cs b/CSharp/BatchExplorer/Models/Account.cs deleted file mode 100644 index ff342fb3..00000000 --- a/CSharp/BatchExplorer/Models/Account.cs +++ /dev/null @@ -1,70 +0,0 @@ -//Copyright (c) Microsoft Corporation - -using System; -using Microsoft.Azure.BatchExplorer.PluginInterfaces.AccountPlugin; - -namespace Microsoft.Azure.BatchExplorer.Models -{ - /// - /// A Batch Account. - /// - public abstract class Account - { - /// - /// A friendly name for the account. This is what BatchExplorer will refer to the account as in all dropdowns. - /// - public abstract string Alias { get; set; } - - /// - /// The name of the account. - /// - public abstract string AccountName { get; set; } - - /// - /// The service url for the Batch account. - /// - public abstract string BatchServiceUrl { get; set; } - - /// - /// The key for the account. - /// - public abstract string Key { get; set; } - - /// - /// The unique identifier for this account. - /// - public abstract Guid UniqueIdentifier { get; set; } - - /// - /// The parent account manager. - /// - public IAccountManager ParentAccountManager { get; set; } - - /// - /// Creates an account. - /// - /// The parent account manager. - protected Account(IAccountManager parentAccountManager) - { - this.ParentAccountManager = parentAccountManager; - } - - protected bool Equals(Account other) - { - return string.Equals(this.Alias, other.Alias, StringComparison.CurrentCultureIgnoreCase); - } - - public override bool Equals(object obj) - { - if (ReferenceEquals(null, obj)) return false; - if (ReferenceEquals(this, obj)) return true; - if (obj.GetType() != this.GetType()) return false; - return Equals((Account)obj); - } - - public override int GetHashCode() - { - return (this.Alias != null ? this.Alias.GetHashCode() : 0); - } - } -} diff --git a/CSharp/BatchExplorer/Models/AddTaskOptions.cs b/CSharp/BatchExplorer/Models/AddTaskOptions.cs deleted file mode 100644 index cb83f67f..00000000 --- a/CSharp/BatchExplorer/Models/AddTaskOptions.cs +++ /dev/null @@ -1,29 +0,0 @@ -//Copyright (c) Microsoft Corporation - -using System.Collections.Generic; - -namespace Microsoft.Azure.BatchExplorer.Models -{ - public class AddTaskOptions - { - public string JobId { get; set; } - - public string CommandLine { get; set; } - - public string TaskId { get; set; } - - public List ResourceFiles { get; set; } - - public bool RunElevated { get; set; } - - public int MaxTaskRetryCount { get; set; } - - public string BackgroundCommand { get; set; } - - public List CommonResourceFiles { get; set; } - - public int InstanceNumber { get; set; } - - public bool IsMultiInstanceTask { get; set; } - } -} diff --git a/CSharp/BatchExplorer/Models/AsyncOperationModel.cs b/CSharp/BatchExplorer/Models/AsyncOperationModel.cs deleted file mode 100644 index bc2b6fc4..00000000 --- a/CSharp/BatchExplorer/Models/AsyncOperationModel.cs +++ /dev/null @@ -1,206 +0,0 @@ -//Copyright (c) Microsoft Corporation - -using System; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.Azure.Batch.Common; -using Microsoft.Azure.BatchExplorer.Helpers; - -namespace Microsoft.Azure.BatchExplorer.Models -{ - /// - /// Model representing a pending or completed async operation. - /// - public class AsyncOperationModel : EntityBase - { - private static int globalOperationCount = 0; - - /// - /// The TPL task corresponding to the operation. - /// - public Task AsyncTask { get; private set; } - - /// - /// Operation object which describes what the operation is doing and what the target was. - /// - public Operation AsyncOperation { get; private set; } - - /// - /// The global count of the operation (each operation will monotonically increasing from 1, 2, 3...) - /// - public int OperationNumber { get; private set; } - - /// - /// The time at which this operation was started. - /// - public DateTime StartTimeLocal - { - get { return this.startTimeLocal; } - private set - { - this.startTimeLocal = value; - this.FirePropertyChangedEvent("StartTimeLocal"); - } - } - - /// - /// The time at which this operation was started. - /// - public DateTime StartTimeUtc - { - get { return this.startTimeUtc; } - private set - { - this.startTimeUtc = value; - this.FirePropertyChangedEvent("StartTimeUtc"); - } - } - - /// - /// The time at which this operation finished. - /// - public DateTime EndTimeUtc - { - get { return this.endTimeUtc; } - private set - { - this.endTimeUtc = value; - this.FirePropertyChangedEvent("EndTimeUtc"); - } - } - - /// - /// True if this operation is completed, false if it is still ongoing - /// - public bool IsCompleted - { - get { return this.isCompleted; } - private set - { - this.isCompleted = value; - this.FirePropertyChangedEvent("IsCompleted"); - this.FirePropertyChangedEvent("HasFault"); - } - } - - /// - /// True if this operation has completed successfully, false if it has failed - /// - public bool CompletedSuccessfully - { - get { return this.completedSuccessfully; } - private set - { - this.completedSuccessfully = value; - this.FirePropertyChangedEvent("CompletedSuccessfully"); - this.FirePropertyChangedEvent("HasFault"); - } - } - - /// - /// The exception associated with this operations failure - /// - public Exception FaultException - { - get { return this.faultException; } - private set - { - this.faultException = value; - this.FirePropertyChangedEvent("FaultException"); - } - } - - /// - /// The client request ID associated with the request which failed - /// - public Guid? FaultClientRequestId - { - get { return this.faultClientRequestId; } - set - { - this.faultClientRequestId = value; - this.FirePropertyChangedEvent("FaultClientRequestId"); - } - } - - /// - /// The server request ID associated with the request which failed - /// - public string FaultServerRequestId - { - get { return this.faultServerRequestId; } - set - { - this.faultServerRequestId = value; - this.FirePropertyChangedEvent("FaultServerRequestId"); - } - } - - /// - /// Determines if this operation has a fault. - /// - public bool HasFault - { - get { return this.IsCompleted && !this.CompletedSuccessfully; } - } - - private bool completedSuccessfully; - private bool isCompleted; - private Exception faultException; - private DateTime startTimeUtc; - private DateTime endTimeUtc; - private DateTime startTimeLocal; - private Guid? faultClientRequestId; - private string faultServerRequestId; - - public AsyncOperationModel(Task asyncTask, Operation asyncOperation) - { - this.AsyncTask = asyncTask; - this.AsyncOperation = asyncOperation; - - //Increment the global operation count - this.OperationNumber = Interlocked.Increment(ref globalOperationCount); - this.StartTimeUtc = DateTime.UtcNow; - this.StartTimeLocal = this.StartTimeUtc.ToLocalTime(); - - //Register to be informed when this task completes - asyncTask.ContinueWith(this.HandleTaskCompletion); - } - - private void HandleTaskCompletion(Task t) - { - this.IsCompleted = true; - this.EndTimeUtc = DateTime.UtcNow; - if (t.Status == TaskStatus.RanToCompletion) - { - this.CompletedSuccessfully = true; - } - else if (t.Status == TaskStatus.Faulted || - t.Status == TaskStatus.Canceled) - { - this.CompletedSuccessfully = false; - this.FaultException = t.Exception; - - //Process exception for client/server request ID if applicable - if (this.FaultException is BatchException) - { - BatchException batchE = this.FaultException as BatchException; - this.FaultClientRequestId = batchE.RequestInformation.ClientRequestId; - this.FaultServerRequestId = batchE.RequestInformation.ServiceRequestId; - } - else if (this.FaultException is AggregateException) - { - //If there is only 1 batch exception we hit - AggregateException agg = this.FaultException as AggregateException; - agg = agg.Flatten(); - - BatchException batchE = agg.InnerExceptions.Where(e => e is BatchException).Cast().First(); - this.FaultClientRequestId = batchE.RequestInformation.ClientRequestId; - this.FaultServerRequestId = batchE.RequestInformation.ServiceRequestId; - - } - } - } - } -} diff --git a/CSharp/BatchExplorer/Models/CertificateModel.cs b/CSharp/BatchExplorer/Models/CertificateModel.cs deleted file mode 100644 index a9ff1978..00000000 --- a/CSharp/BatchExplorer/Models/CertificateModel.cs +++ /dev/null @@ -1,116 +0,0 @@ -using GalaSoft.MvvmLight.Messaging; -using Microsoft.Azure.Batch; -using Microsoft.Azure.Batch.Common; -using Microsoft.Azure.BatchExplorer.Helpers; -using Microsoft.Azure.BatchExplorer.Messages; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Microsoft.Azure.BatchExplorer.Models -{ - public class CertificateModel : ModelBase - { - public CertificateModel(Certificate source) - { - this.Certificate = source; - } - - [ChangeTracked(ModelRefreshType.Basic)] - public string Thumbprint - { - get { return this.Certificate.Thumbprint; } - } - - [ChangeTracked(ModelRefreshType.Basic)] - public string ThumbprintAlgorithm - { - get { return this.Certificate.ThumbprintAlgorithm; } - } - - [ChangeTracked(ModelRefreshType.Basic)] - public CertificateState? State - { - get { return this.Certificate.State; } - } - - private Certificate Certificate { get; set; } - - public override List PropertyModel - { - get { return this.ObjectToPropertyModel(this.Certificate); } - } - - public override async Task RefreshAsync(ModelRefreshType refreshType, bool showTrackedOperation = true) - { - Messenger.Default.Send(new UpdateWaitSpinnerMessage(WaitSpinnerPanel.UpperRight, true)); - - if (refreshType.HasFlag(ModelRefreshType.Basic)) - { - try - { - System.Threading.Tasks.Task asyncTask = this.Certificate.RefreshAsync(OptionsModel.Instance.ListDetailLevel); - if (showTrackedOperation) - { - AsyncOperationTracker.Instance.AddTrackedOperation(new AsyncOperationModel( - asyncTask, - new CertificateOperation(CertificateOperation.Refresh, this.Certificate.Thumbprint, this.Certificate.ThumbprintAlgorithm))); - } - else - { - AsyncOperationTracker.Instance.AddTrackedInternalOperation(asyncTask); - } - - await asyncTask; - this.LastUpdatedTime = DateTime.UtcNow; - - // - // Fire property change events for this models properties - // - this.FireChangesOnRefresh(ModelRefreshType.Basic); - } - catch (Exception e) - { - this.HandleException(e); - } - } - - Messenger.Default.Send(new UpdateWaitSpinnerMessage(WaitSpinnerPanel.UpperRight, false)); - Messenger.Default.Send(new CertificateUpdateCompleteMessage()); - } - - private void HandleException(Exception e) - { - //Swallow 404's and fire a message - if (Microsoft.Azure.BatchExplorer.Helpers.Common.IsExceptionNotFound(e)) - { - Messenger.Default.Send(new ModelNotFoundAfterRefresh(this)); - } - else - { - Messenger.Default.Send(new GenericDialogMessage(e.ToString())); - } - } - - /// - /// Delete this certificate from the server - /// - public async Task DeleteAsync() - { - try - { - Task asyncTask = this.Certificate.DeleteAsync(); - AsyncOperationTracker.Instance.AddTrackedOperation(new AsyncOperationModel( - asyncTask, - new CertificateOperation(CertificateOperation.Delete, this.Certificate.Thumbprint, this.Certificate.ThumbprintAlgorithm))); - await asyncTask; - } - catch (Exception e) - { - Messenger.Default.Send(new GenericDialogMessage(e.ToString())); - } - } - } -} diff --git a/CSharp/BatchExplorer/Models/CloudServiceConfigurationOptions.cs b/CSharp/BatchExplorer/Models/CloudServiceConfigurationOptions.cs deleted file mode 100644 index b595ba94..00000000 --- a/CSharp/BatchExplorer/Models/CloudServiceConfigurationOptions.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Microsoft.Azure.BatchExplorer.Models -{ - public class CloudServiceConfigurationOptions - { - public string OSFamily { get; set; } - - public string OSVersion { get; set; } - } -} diff --git a/CSharp/BatchExplorer/Models/ComputeNodeFile.cs b/CSharp/BatchExplorer/Models/ComputeNodeFile.cs deleted file mode 100644 index dca3e5ff..00000000 --- a/CSharp/BatchExplorer/Models/ComputeNodeFile.cs +++ /dev/null @@ -1,44 +0,0 @@ -//Copyright (c) Microsoft Corporation - -using System; - -namespace Microsoft.Azure.BatchExplorer.Models -{ - public class ComputeNodeFile - { - /// - /// Name of the file or directory - /// - public string Name { get; set; } - - /// - /// Full file path - /// - public string Url { get; set; } - - /// - /// True if is a directory, false if file - /// - public bool IsDirectory { get; set; } - - /// - /// Date file was created - /// - public DateTime CreationTime { get; set; } - - /// - /// Content type - /// - public string ContentType { get; set; } - - /// - /// File size - /// - public long FileSize { get; set; } - - /// - /// Last modified time - /// - public DateTime LastModifiedTime { get; set; } - } -} diff --git a/CSharp/BatchExplorer/Models/ComputeNodeModel.cs b/CSharp/BatchExplorer/Models/ComputeNodeModel.cs deleted file mode 100644 index 1f95bd1f..00000000 --- a/CSharp/BatchExplorer/Models/ComputeNodeModel.cs +++ /dev/null @@ -1,393 +0,0 @@ -//Copyright (c) Microsoft Corporation - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Threading.Tasks; -using GalaSoft.MvvmLight.Messaging; -using Microsoft.Azure.Batch; -using Microsoft.Azure.Batch.Common; -using Microsoft.Azure.BatchExplorer.Helpers; -using Microsoft.Azure.BatchExplorer.Messages; - -namespace Microsoft.Azure.BatchExplorer.Models -{ - /// - /// The data model for the ComputeNode object - /// - public class ComputeNodeModel : ModelBase - { - #region Public properties - /// - /// The pool associated with this ComputeNode. - /// - public PoolModel ParentPool { get; private set; } - - /// - /// The id of this ComputeNode - /// - [ChangeTracked(ModelRefreshType.Basic)] - public string Id { get { return this.ComputeNode.Id; } } - - /// - /// The state of this ComputeNode - /// - [ChangeTracked(ModelRefreshType.Basic)] - public ComputeNodeState? State { get { return this.ComputeNode.State; } } - - - /// - /// The SchedulingState of this ComputeNode - /// - [ChangeTracked(ModelRefreshType.Basic)] - public SchedulingState? SchedulingState { get { return this.ComputeNode.SchedulingState; } } - - /// - /// The allocation time of the ComputeNode. - /// - [ChangeTracked(ModelRefreshType.Basic)] - public DateTime? CreationTime { get { return this.ComputeNode.AllocationTime; } } - - /// - /// True if there are files available, otherwise false - /// - [ChangeTracked(ModelRefreshType.Children)] - public bool HasFiles - { - get { return (this.Files != null && this.Files.Count > 0); } - } - - /// - /// The collection of files on this ComputeNode. - /// - [ChangeTracked(ModelRefreshType.Children)] - public List Files - { - get - { - return this.files; - } - private set - { - this.files = value; - FirePropertyChangedEvent("Files"); - } - } - - /// - /// True if there are any recent tasks, otherwise false - /// - [ChangeTracked(ModelRefreshType.Basic)] - public bool HasRecentTasks - { - get { return (this.RecentTasks != null && this.RecentTasks.Count > 0); } - } - /// - /// The collection of recent tasks for this ComputeNode. - /// - [ChangeTracked(ModelRefreshType.Basic)] - public List RecentTasks - { - get - { - if (this.ComputeNode.RecentTasks != null) - { - return this.ComputeNode.RecentTasks.ToList(); - } - else - { - return null; - } - } - } - - /// - /// True if this ComputeNode has start task info, false otherwise - /// - [ChangeTracked(ModelRefreshType.Basic)] - public bool HasStartTaskInfo - { - get - { - return this.StartTaskInfo != null; - } - } - - /// - /// The start task info associated with this ComputeNode - /// - [ChangeTracked(ModelRefreshType.Basic)] - public StartTaskInformation StartTaskInfo { get { return this.ComputeNode.StartTaskInformation; } } - - #endregion - - private ComputeNode ComputeNode { get; set; } - private List files; - - public ComputeNodeModel(PoolModel parentPool, ComputeNode computeNode) - { - this.ComputeNode = computeNode; - this.ParentPool = parentPool; - this.LastUpdatedTime = DateTime.UtcNow; - } - - #region ModelBase implementation - - public override List PropertyModel - { - get { return this.ObjectToPropertyModel(this.ComputeNode); } - } - - public override async Task RefreshAsync(ModelRefreshType refreshType, bool showTrackedOperation = true) - { - if (refreshType.HasFlag(ModelRefreshType.Basic)) - { - try - { - Messenger.Default.Send(new UpdateWaitSpinnerMessage(WaitSpinnerPanel.UpperRight, true)); - Task asyncTask = this.ComputeNode.RefreshAsync(); - if (showTrackedOperation) - { - AsyncOperationTracker.Instance.AddTrackedOperation(new AsyncOperationModel( - asyncTask, - new ComputeNodeOperation(ComputeNodeOperation.Refresh, this.ParentPool.Id, this.ComputeNode.Id))); - } - else - { - AsyncOperationTracker.Instance.AddTrackedInternalOperation(asyncTask); - } - - await asyncTask; - this.LastUpdatedTime = DateTime.UtcNow; - - // - // Fire property change events for this models properties - // - this.FireChangesOnRefresh(ModelRefreshType.Basic); - - } - catch (Exception e) - { - this.HandleException(e); - } - finally - { - Messenger.Default.Send(new UpdateWaitSpinnerMessage(WaitSpinnerPanel.UpperRight, false)); - } - } - - if (refreshType.HasFlag(ModelRefreshType.Children)) - { - try - { - Messenger.Default.Send(new UpdateWaitSpinnerMessage(WaitSpinnerPanel.LowerRight, true)); - //Set this before the children load so that on revisit we know we have loaded the children (or are in the process) - this.HasLoadedChildren = true; - - try - { - Task> asyncTask = this.ListFilesAsync(); - AsyncOperationTracker.Instance.AddTrackedOperation(new AsyncOperationModel( - asyncTask, - new ComputeNodeOperation(ComputeNodeOperation.ListFiles, this.ParentPool.Id, this.ComputeNode.Id))); - - this.Files = await asyncTask; - } - catch (Exception) - { - this.HasLoadedChildren = false; //On exception, we failed to load children so try again next time - //Swallow the exception to stop popups from occuring for every bad ComputeNode - } - - this.FireChangesOnRefresh(ModelRefreshType.Children); - } - catch (Exception e) - { - this.HasLoadedChildren = false; //On exception, we failed to load children so try again next time - this.HandleException(e); - } - finally - { - Messenger.Default.Send(new UpdateWaitSpinnerMessage(WaitSpinnerPanel.LowerRight, false)); - } - } - } - - #endregion - - #region Operations on ComputeNodes - /// - /// Reboots the ComputeNode. - /// - public async Task RebootAsync() - { - try - { - Task asyncTask = this.ComputeNode.RebootAsync(); - AsyncOperationTracker.Instance.AddTrackedOperation(new AsyncOperationModel( - asyncTask, - new ComputeNodeOperation(ComputeNodeOperation.Reboot, this.ParentPool.Id, this.ComputeNode.Id))); - await asyncTask; - await this.RefreshAsync(ModelRefreshType.Basic, showTrackedOperation: false); - } - catch (Exception e) - { - Messenger.Default.Send(new GenericDialogMessage(e.ToString())); - } - } - - /// - /// Reimages the ComputeNode. - /// - public async Task ReimageAsync() - { - try - { - Task asyncTask = this.ComputeNode.ReimageAsync(); - AsyncOperationTracker.Instance.AddTrackedOperation(new AsyncOperationModel( - asyncTask, - new ComputeNodeOperation(ComputeNodeOperation.Reimage, this.ParentPool.Id, this.ComputeNode.Id))); - await asyncTask; - await this.RefreshAsync(ModelRefreshType.Basic, showTrackedOperation: false); - } - catch (Exception e) - { - Messenger.Default.Send(new GenericDialogMessage(e.ToString())); - } - } - - /// - /// Disables scheduling on the ComputeNode. - /// - public async Task DisableSchedulingAsync() - { - try - { - if (this.ComputeNode.SchedulingState != Microsoft.Azure.Batch.Common.SchedulingState.Disabled) - { - Task asyncTask = this.ComputeNode.DisableSchedulingAsync(DisableComputeNodeSchedulingOption.Requeue); - AsyncOperationTracker.Instance.AddTrackedOperation(new AsyncOperationModel( - asyncTask, - new ComputeNodeOperation(ComputeNodeOperation.DisableScheduling, this.ParentPool.Id, this.ComputeNode.Id))); - await asyncTask; - await this.RefreshAsync(ModelRefreshType.Basic, showTrackedOperation: false); - } - } - catch (Exception e) - { - Messenger.Default.Send(new GenericDialogMessage(e.ToString())); - } - } - - /// - /// Enables scheduling on the ComputeNode. - /// - public async Task EnableSchedulingAsync() - { - try - { - if (this.ComputeNode.SchedulingState != Microsoft.Azure.Batch.Common.SchedulingState.Enabled) - { - Task asyncTask = this.ComputeNode.EnableSchedulingAsync(); - AsyncOperationTracker.Instance.AddTrackedOperation(new AsyncOperationModel( - asyncTask, - new ComputeNodeOperation(ComputeNodeOperation.EnableScheduling, this.ParentPool.Id, this.ComputeNode.Id))); - await asyncTask; - await this.RefreshAsync(ModelRefreshType.Basic, showTrackedOperation: false); - } - } - catch (Exception e) - { - Messenger.Default.Send(new GenericDialogMessage(e.ToString())); - } - } - - /// - /// Downloads an RDP file associated with this ComputeNode. - /// - /// The target stream to place the RDP file into - public async Task DownloadRDPAsync(Stream destinationStream) - { - try - { - Task asyncTask = this.ComputeNode.GetRDPFileAsync(destinationStream); - AsyncOperationTracker.Instance.AddTrackedOperation(new AsyncOperationModel( - asyncTask, - new ComputeNodeOperation(ComputeNodeOperation.GetRdp, this.ParentPool.Id, this.ComputeNode.Id))); - await asyncTask; - } - catch (Exception e) - { - Messenger.Default.Send(new GenericDialogMessage(e.ToString())); - } - } - - public async Task GetSSHSettingsAsync() - { - Task asyncTask = this.ComputeNode.GetRemoteLoginSettingsAsync(); - AsyncOperationTracker.Instance.AddTrackedOperation(new AsyncOperationModel( - asyncTask, - new ComputeNodeOperation(ComputeNodeOperation.GetSsh, this.ParentPool.Id, this.ComputeNode.Id))); - return await asyncTask; - } - - /// - /// Downloads a file on this compute node. - /// - /// The path of the file on the node. - /// The target stream to place the file into - public async Task DownloadFileAsync(string filePath, Stream destinationStream) - { - Task asyncTask = this.DownloadFile(filePath, destinationStream); - AsyncOperationTracker.Instance.AddTrackedOperation(new AsyncOperationModel( - asyncTask, - new ComputeNodeOperation(ComputeNodeOperation.GetFile, this.ParentPool.Id, this.ComputeNode.Id))); - await asyncTask; - } - - /// - /// Lists the files on this ComputeNode. - /// - /// - private async Task> ListFilesAsync() - { - IPagedEnumerable vmFiles = this.ComputeNode.ListNodeFiles(recursive: true); - - List results = await vmFiles.ToListAsync(); - - return results; - } - - /// - /// Downloads the contents of the specific file on the ComputeNode. - /// - /// The path to the file. - /// The destination stream. - /// - private async Task DownloadFile(string filePath, Stream destinationStream) - { - NodeFile file = await this.ComputeNode.GetNodeFileAsync(filePath); - await file.CopyToStreamAsync(destinationStream); - } - - #endregion - - #region Private methods - - private void HandleException(Exception e) - { - //Swallow 404's and fire a message - if (Microsoft.Azure.BatchExplorer.Helpers.Common.IsExceptionNotFound(e)) - { - Messenger.Default.Send(new ModelNotFoundAfterRefresh(this)); - } - else - { - Messenger.Default.Send(new GenericDialogMessage(e.ToString())); - } - } - - #endregion - } -} diff --git a/CSharp/BatchExplorer/Models/CreateAutoPoolOptions.cs b/CSharp/BatchExplorer/Models/CreateAutoPoolOptions.cs deleted file mode 100644 index 6ae0ca0b..00000000 --- a/CSharp/BatchExplorer/Models/CreateAutoPoolOptions.cs +++ /dev/null @@ -1,25 +0,0 @@ -//Copyright (c) Microsoft Corporation - -namespace Microsoft.Azure.BatchExplorer.Models -{ - public class CreateAutoPoolOptions - { - public bool? UseAutoPool { get; set; } - - public string AutoPoolPrefix { get; set; } - - public string LifeTimeOption { get; set; } - - public string SelectedLifetimeOption { get; set; } - - public bool? KeepAlive { get; set; } - - public string VirutalMachineSize { get; set; } - - public string OSFamily { get; set; } - - public int TargetDedicated { get; set; } - - public int TargetLowPriority { get; set; } - } -} diff --git a/CSharp/BatchExplorer/Models/CreateCertificateOptions.cs b/CSharp/BatchExplorer/Models/CreateCertificateOptions.cs deleted file mode 100644 index a1d2769f..00000000 --- a/CSharp/BatchExplorer/Models/CreateCertificateOptions.cs +++ /dev/null @@ -1,18 +0,0 @@ -using Microsoft.Azure.Batch.Common; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Microsoft.Azure.BatchExplorer.Models -{ - public class CreateCertificateOptions - { - public string FilePath { get; set; } - - public string Password { get; set; } - - public CertificateFormat CertificateFormat { get; set; } - } -} diff --git a/CSharp/BatchExplorer/Models/CreateJobManagerOptions.cs b/CSharp/BatchExplorer/Models/CreateJobManagerOptions.cs deleted file mode 100644 index d97eda6e..00000000 --- a/CSharp/BatchExplorer/Models/CreateJobManagerOptions.cs +++ /dev/null @@ -1,25 +0,0 @@ -//Copyright (c) Microsoft Corporation - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Microsoft.Azure.BatchExplorer.Models -{ - public class CreateJobManagerOptions - { - public string JobManagerId { get; set; } - - public string CommandLine { get; set; } - - public int? MaxTaskRetryCount { get; set; } - - public TimeSpan? MaxTaskWallClockTime { get; set; } - - public TimeSpan? RetentionTime { get; set; } - - public bool? KillOnCompletion { get; set; } - } -} diff --git a/CSharp/BatchExplorer/Models/CreateJobOptions.cs b/CSharp/BatchExplorer/Models/CreateJobOptions.cs deleted file mode 100644 index bf422677..00000000 --- a/CSharp/BatchExplorer/Models/CreateJobOptions.cs +++ /dev/null @@ -1,25 +0,0 @@ -//Copyright (c) Microsoft Corporation - -using System; - -namespace Microsoft.Azure.BatchExplorer.Models -{ - public class CreateJobOptions - { - public string JobId { get; set; } - - public int? Priority { get; set; } - - public int? MaxRetryCount { get; set; } - - public bool? CreateJobManager { get; set; } - - public TimeSpan? MaxWallClockTime { get; set; } - - public string PoolId { get; set; } - - public CreateJobManagerOptions JobManagerOptions { get; set; } - - public CreateAutoPoolOptions AutoPoolOptions { get; set; } - } -} diff --git a/CSharp/BatchExplorer/Models/CreateJobScheduleOptions.cs b/CSharp/BatchExplorer/Models/CreateJobScheduleOptions.cs deleted file mode 100644 index 029332f2..00000000 --- a/CSharp/BatchExplorer/Models/CreateJobScheduleOptions.cs +++ /dev/null @@ -1,34 +0,0 @@ -//Copyright (c) Microsoft Corporation - -using System; - -namespace Microsoft.Azure.BatchExplorer.Models -{ - public class CreateJobScheduleOptions - { - public string JobScheduleId { get; set; } - - public int? Priority { get; set; } - - public int? MaxRetryCount { get; set; } - - public bool? CreateJobManager { get; set; } - - public TimeSpan? MaxWallClockTime { get; set; } - - // Schedule - public DateTime? DoNotRunUntil { get; set; } - - public DateTime? DoNotRunAfter { get; set; } - - public TimeSpan? StartWindow { get; set; } - - public TimeSpan? RecurrenceInterval { get; set; } - - public CreateJobManagerOptions JobManagerOptions { get; set; } - - public string PoolId { get; set; } - - public CreateAutoPoolOptions AutoPoolOptions { get; set; } - } -} diff --git a/CSharp/BatchExplorer/Models/Field.cs b/CSharp/BatchExplorer/Models/Field.cs deleted file mode 100644 index 0b63919f..00000000 --- a/CSharp/BatchExplorer/Models/Field.cs +++ /dev/null @@ -1,22 +0,0 @@ -//Copyright (c) Microsoft Corporation - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Microsoft.Azure.BatchExplorer -{ - public class Field - { - public string Value { get; set; } - - public Field(Object obj) - { - if (obj != null) - Value = obj.ToString(); - else - Value = ""; - } - } -} diff --git a/CSharp/BatchExplorer/Models/HeatmapModel.cs b/CSharp/BatchExplorer/Models/HeatmapModel.cs deleted file mode 100644 index 9f12d25f..00000000 --- a/CSharp/BatchExplorer/Models/HeatmapModel.cs +++ /dev/null @@ -1,182 +0,0 @@ -//Copyright (c) Microsoft Corporation - -using System; -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; -using GalaSoft.MvvmLight.Messaging; -using Microsoft.Azure.Batch; -using Microsoft.Azure.Batch.Common; -using Microsoft.Azure.BatchExplorer.Helpers; -using Microsoft.Azure.BatchExplorer.Messages; - -namespace Microsoft.Azure.BatchExplorer.Models -{ - /// - /// Model representing the heatmap - /// - public class HeatMapModel : EntityBase - { - public string VirtualMachineSize - { - get { return this.Pool.VirtualMachineSize; } - } - - public int? CurrentDedicated - { - get { return this.Pool.CurrentDedicatedComputeNodes; } - } - - public int? TargetDedicated - { - get { return this.Pool.TargetDedicatedComputeNodes; } - } - - public string AllocationState - { - get { return this.Pool.AllocationState.ToString(); } - } - - public string PoolId - { - get { return this.Pool.Id; } - } - - public int? MaxTasksPerComputeNode - { - get { return this.Pool.MaxTasksPerComputeNode; } - } - - public int SchedulableComputeNodes { get; private set; } - - public int RunningTasks { get; private set; } - - public List ComputeNodes - { - get { return this.computeNodes; } - private set { this.computeNodes = value; } - } - - private List computeNodes; - private CloudPool Pool { get; set; } - - public HeatMapModel(CloudPool pool) - { - this.Pool = pool; - this.computeNodes = new List(); - } - - /// - /// Refreshes the state of the HeatMap model from the Batch service. - /// - /// - public async Task RefreshAsync() - { - try - { - //Refresh the pool - Task refreshPoolTask = this.Pool.RefreshAsync(); - - AsyncOperationTracker.Instance.AddTrackedOperation( - new AsyncOperationModel(refreshPoolTask, new PoolOperation(PoolOperation.GetPool, this.PoolId))); - - //Refresh the VM list - Task refreshComputeNodesTask = this.RefreshComputeNodesAsync(); - - AsyncOperationTracker.Instance.AddTrackedOperation( - new AsyncOperationModel(refreshComputeNodesTask, new PoolOperation(PoolOperation.ListComputeNodes, this.PoolId))); - - await refreshComputeNodesTask; - - this.UpdateFinished(); - } - catch (Exception e) - { - this.HandleException(e); - } - } - - #region Private methods - - /// - /// Refreshes the status of the ComputeNodes from the Batch service. - /// - /// - private async Task RefreshComputeNodesAsync() - { - // Get the list of pool compute nodess - can't use this because ComputeNode does not support RecentTasks property yet - DetailLevel detailLevel = new ODATADetailLevel() - { - SelectClause = "recentTasks,state,id" - }; - - IPagedEnumerable computeNodeEnumerableAsync = this.Pool.ListComputeNodes(detailLevel); - List computeNodeList = await computeNodeEnumerableAsync.ToListAsync(); - - this.RunningTasks = 0; - this.SchedulableComputeNodes = 0; - foreach (ComputeNode computeNode in computeNodeList) - { - if (computeNode.State == ComputeNodeState.Idle || computeNode.State == ComputeNodeState.Running) - { - this.SchedulableComputeNodes++; - } - - if (computeNode.State == ComputeNodeState.Running && this.Pool.MaxTasksPerComputeNode == 1) - { - this.RunningTasks++; - } - else if (this.Pool.MaxTasksPerComputeNode > 1) - { - IEnumerable taskInfoList = computeNode.RecentTasks; - if (taskInfoList != null) - { - foreach (TaskInformation ti in taskInfoList) - { - if (ti.TaskState == TaskState.Running) - { - this.RunningTasks++; - } - } - } - } - } - - Interlocked.Exchange(ref this.computeNodes, computeNodeList); //Threadsafe swap - } - - /// - /// Fires the associated set of property changes when the update is finished. - /// - private void UpdateFinished() - { - //Fire set of property changed events - this.FirePropertyChangedEvent("SchedulableComputeNodes"); - this.FirePropertyChangedEvent("RunningTasks"); - this.FirePropertyChangedEvent("ComputeNodes"); - this.FirePropertyChangedEvent("Pool"); - this.FirePropertyChangedEvent("PoolId"); - this.FirePropertyChangedEvent("TargetDedicated"); - this.FirePropertyChangedEvent("CurrentDedicated"); - this.FirePropertyChangedEvent("AllocationState"); - this.FirePropertyChangedEvent("VirtualMachineSize"); - } - - private void HandleException(Exception e) - { - //Swallow 404's - if (Microsoft.Azure.BatchExplorer.Helpers.Common.IsExceptionNotFound(e)) - { - Messenger.Default.Send(new GenericDialogMessage(string.Format("Pool {0} was deleted. The heatmap has stopped updating", this.PoolId))); - //Swallow it and terminate the heat map - throw new HeatMapTerminatedException(); - } - else - { - Messenger.Default.Send(new GenericDialogMessage(e.ToString())); - } - } - - #endregion - } -} diff --git a/CSharp/BatchExplorer/Models/JobModel.cs b/CSharp/BatchExplorer/Models/JobModel.cs deleted file mode 100644 index e03dc7de..00000000 --- a/CSharp/BatchExplorer/Models/JobModel.cs +++ /dev/null @@ -1,404 +0,0 @@ -//Copyright (c) Microsoft Corporation - -namespace Microsoft.Azure.BatchExplorer.Models -{ - using System; - using System.Collections.Generic; - using System.ComponentModel; - using System.Globalization; - using System.Threading.Tasks; - using System.Windows; - using System.Windows.Data; - using GalaSoft.MvvmLight.Messaging; - using Microsoft.Azure.Batch; - using Microsoft.Azure.Batch.Common; - using Microsoft.Azure.BatchExplorer.Helpers; - using Microsoft.Azure.BatchExplorer.Messages; - using ViewModels; - - /// - /// The data model for the Job object - /// - public class JobModel : ModelBase - { - #region Public properties - - private bool isChecked; - /// - /// Marker for multi selection - /// - public bool IsChecked - { - get - { - return this.isChecked; - } - set - { - this.isChecked = value; - this.FirePropertyChangedEvent("IsChecked"); - } - } - - /// - /// Gets the id of the job - /// - [ChangeTracked(ModelRefreshType.Basic)] - public string Id { get { return this.Job.Id; } } - - /// - /// Gets the display name of the job - /// - [ChangeTracked(ModelRefreshType.Basic)] - public string DisplayName { get { return this.Job.DisplayName; } } - - /// - /// Gets the creation time of the job. - /// - [ChangeTracked(ModelRefreshType.Basic)] - public DateTime? CreationTime { get { return this.Job.CreationTime; } } - - /// - /// Gets the state of the job. - /// - [ChangeTracked(ModelRefreshType.Basic)] - public JobState? State { get { return this.Job.State; } } - - /// - /// Gets the tasks associated with this job. - /// - public List Tasks { get; private set; } - - /// - /// Gets the task collection associated with this job. - /// - [ChangeTracked(ModelRefreshType.Children)] - public ICollectionView TaskCollection { get; private set; } - #endregion - - #region Commands - - /// - /// Enable the selected job - /// - public CommandBase EnableJob - { - get - { - return - new CommandBase( - (param) => AsyncOperationTracker.Instance.AddTrackedInternalOperation(this.EnableAsync())); - } - } - - - /// - /// Disable the selected job in the specified way - /// - public CommandBase DisableJob - { - get - { - return new CommandBase( - (disableOption) => - { - var castDisableOption = ((DisableJobOption)disableOption); - AsyncOperationTracker.Instance.AddTrackedInternalOperation(this.DisableAsync(castDisableOption)); - }); - } - } - - /// - /// Terminate the selected job - /// - public CommandBase TerminateJob - { - get - { - return new CommandBase( - (item) => AsyncOperationTracker.Instance.AddTrackedInternalOperation(this.TerminateAsync())); - } - } - - /// - /// Delete the selected item - /// - public CommandBase Delete - { - get - { - return new CommandBase( - (item) => - { - var job = (item as JobModel); - if (job != null) - { - Messenger.Default.Register(this, (message) => - { - if (message.MessageBoxResult == MessageBoxResult.Yes) - { - AsyncOperationTracker.Instance.AddTrackedInternalOperation(this.DeleteAsync()); - } - Messenger.Default.Unregister(this); - }); - Messenger.Default.Send(new LaunchMultibuttonDialogMessage() - { - Caption = "Confirm delete", - DialogMessage = "Do you want to delete this item?", - MessageBoxButton = MessageBoxButton.YesNo - }); - } - }); - } - } - - /// - /// Creates a popup to add task to the specified job. - /// - public CommandBase AddTask - { - get - { - return new CommandBase( - (o) => - { - JobModel job = (JobModel)o; - // Call a new window to show the Add Task UI - Messenger.Default.Send(new ShowAddTaskWindow(job.Id)); - } - ); - } - } - - /// - /// Refresh the selected item - /// - public CommandBase RefreshItem - { - get - { - return new CommandBase( - (item) => - { - var job = (item as JobModel); - if (job != null) - { - Task refreshTask = job.RefreshAsync(ModelRefreshType.Children | ModelRefreshType.Basic).ContinueWith((t) => - { - FirePropertyChangedEvent("Jobs"); - }); - AsyncOperationTracker.Instance.AddTrackedInternalOperation(refreshTask); - } - }); - } - } - - - #endregion - - private CloudJob Job { get; set; } - - public JobModel(CloudJob job) - { - this.Job = job; - this.Tasks = new List(); - this.LastUpdatedTime = DateTime.UtcNow; - - this.TaskCollection = CollectionViewSource.GetDefaultView(this.Tasks); - this.UpdateTaskView(); - } - - #region ModelBase implementation - - public override List PropertyModel - { - get { return this.ObjectToPropertyModel(this.Job); } - } - - public override async System.Threading.Tasks.Task RefreshAsync(ModelRefreshType refreshType, bool showTrackedOperation = true) - { - Messenger.Default.Send(new UpdateWaitSpinnerMessage(WaitSpinnerPanel.UpperRight, true)); - - if (refreshType.HasFlag(ModelRefreshType.Basic)) - { - try - { - System.Threading.Tasks.Task asyncTask = this.Job.RefreshAsync(OptionsModel.Instance.ListDetailLevel); - if (showTrackedOperation) - { - AsyncOperationTracker.Instance.AddTrackedOperation(new AsyncOperationModel( - asyncTask, - new JobOperation(JobOperation.Refresh, this.Job.Id))); - } - else - { - AsyncOperationTracker.Instance.AddTrackedInternalOperation(asyncTask); - } - - await asyncTask; - this.LastUpdatedTime = DateTime.UtcNow; - - // - // Fire property change events for this models properties - // - this.FireChangesOnRefresh(ModelRefreshType.Basic); - } - catch (Exception e) - { - this.HandleException(e); - } - } - - if (refreshType.HasFlag(ModelRefreshType.Children)) - { - try - { - //Set this before the children load so that on revisit we know we have loaded the children (or are in the process) - this.HasLoadedChildren = true; - - System.Threading.Tasks.Task> asyncTask = this.ListTasksAsync(); - AsyncOperationTracker.Instance.AddTrackedOperation(new AsyncOperationModel( - asyncTask, - new JobOperation(JobOperation.ListTasks, this.Job.Id))); - - this.Tasks = await asyncTask; - this.TaskCollection = CollectionViewSource.GetDefaultView(this.Tasks); - this.UpdateTaskView(); - } - catch (Exception e) - { - this.HasLoadedChildren = false; //On exception, we failed to load children so try again next time - this.HandleException(e); - } - } - - Messenger.Default.Send(new UpdateWaitSpinnerMessage(WaitSpinnerPanel.UpperRight, false)); - Messenger.Default.Send(new JobUpdateCompleteMessage()); - } - #endregion - - #region Job operations - - /// - /// Enable this job - /// - public async System.Threading.Tasks.Task EnableAsync() - { - try - { - System.Threading.Tasks.Task asyncTask = this.Job.EnableAsync(); - AsyncOperationTracker.Instance.AddTrackedOperation(new AsyncOperationModel( - asyncTask, - new JobOperation(JobOperation.Enable, this.Job.Id))); - await asyncTask; - await this.RefreshAsync(ModelRefreshType.Basic, showTrackedOperation: false); - } - catch (Exception e) - { - Messenger.Default.Send(new GenericDialogMessage(e.ToString())); - } - } - - /// - /// Disable this job - /// - public async System.Threading.Tasks.Task DisableAsync(DisableJobOption option) - { - try - { - System.Threading.Tasks.Task asyncTask = this.Job.DisableAsync(option); - AsyncOperationTracker.Instance.AddTrackedOperation(new AsyncOperationModel( - asyncTask, - new JobOperation(JobOperation.Disable, this.Job.Id))); - await asyncTask; - await this.RefreshAsync(ModelRefreshType.Basic, showTrackedOperation: false); - } - catch (Exception e) - { - Messenger.Default.Send(new GenericDialogMessage(e.ToString())); - } - } - /// - /// Delete this job - /// - public async System.Threading.Tasks.Task DeleteAsync(bool refresh = true) - { - try - { - System.Threading.Tasks.Task asyncTask = this.Job.DeleteAsync(); - AsyncOperationTracker.Instance.AddTrackedOperation(new AsyncOperationModel( - asyncTask, - new JobOperation(JobOperation.Delete, this.Job.Id))); - await asyncTask; - if (refresh) - { - Messenger.Default.Send(new RefreshMessage(RefreshTarget.Jobs)); - } - } - catch (Exception e) - { - Messenger.Default.Send(new GenericDialogMessage(e.ToString())); - } - } - - /// - /// Terminate the job - /// - public async System.Threading.Tasks.Task TerminateAsync() - { - try - { - System.Threading.Tasks.Task asyncTask = this.Job.TerminateAsync(); - AsyncOperationTracker.Instance.AddTrackedOperation(new AsyncOperationModel( - asyncTask, - new JobOperation(JobOperation.Terminate, this.Job.Id))); - await asyncTask; - await this.RefreshAsync(ModelRefreshType.Basic, showTrackedOperation: false); - } - catch (Exception e) - { - Messenger.Default.Send(new GenericDialogMessage(e.ToString())); - } - } - - private async System.Threading.Tasks.Task> ListTasksAsync() - { - List results = new List(); - IPagedEnumerable taskList = this.Job.ListTasks(OptionsModel.Instance.ListDetailLevel); - - await taskList.ForEachAsync(item => results.Add(new TaskModel(this, item))); - - return results; - } - - #endregion - - #region Public methods - /// - /// Updates the associated list of Tasks view - /// - public void UpdateTaskView() - { - this.FireChangesOnRefresh(ModelRefreshType.Children); - } - - #endregion - - #region Private methods - - private void HandleException(Exception e) - { - //Swallow 404's and fire a message - if (Microsoft.Azure.BatchExplorer.Helpers.Common.IsExceptionNotFound(e)) - { - Messenger.Default.Send(new ModelNotFoundAfterRefresh(this)); - } - else - { - Messenger.Default.Send(new GenericDialogMessage(e.ToString())); - } - } - - #endregion - } -} diff --git a/CSharp/BatchExplorer/Models/JobScheduleModel.cs b/CSharp/BatchExplorer/Models/JobScheduleModel.cs deleted file mode 100644 index 930eeae5..00000000 --- a/CSharp/BatchExplorer/Models/JobScheduleModel.cs +++ /dev/null @@ -1,331 +0,0 @@ -//Copyright (c) Microsoft Corporation - -namespace Microsoft.Azure.BatchExplorer.Models -{ - using System; - using System.Collections.Generic; - using System.Threading.Tasks; - using System.Windows; - using GalaSoft.MvvmLight.Messaging; - using Microsoft.Azure.Batch; - using Microsoft.Azure.Batch.Common; - using Microsoft.Azure.BatchExplorer.Helpers; - using Microsoft.Azure.BatchExplorer.Messages; - - /// - /// The data model for the JobSchedule object - /// - public class JobScheduleModel : ModelBase - { - #region Properties - - /// - /// The id of the JobSchedule. - /// - [ChangeTracked(ModelRefreshType.Basic)] - public string Id { get { return this.JobSchedule.Id; } } - - /// - /// The display name of the JobSchedule. - /// - [ChangeTracked(ModelRefreshType.Basic)] - public string DisplayName { get { return this.JobSchedule.DisplayName; } } - - /// - /// The state of the JobSchedule. - /// - [ChangeTracked(ModelRefreshType.Basic)] - public JobScheduleState? State { get { return this.JobSchedule.State; } } - - #endregion - - private CloudJobSchedule JobSchedule { get; set; } - - /// - /// Create a JobScheduleModel backed by a CloudJobSchedule - /// - public JobScheduleModel(CloudJobSchedule jobSchedule) - { - this.JobSchedule = jobSchedule; - this.LastUpdatedTime = DateTime.UtcNow; - } - - #region ModelBase implementation - - public override List PropertyModel - { - get { return this.ObjectToPropertyModel(this.JobSchedule); } - } - - public override async Task RefreshAsync(ModelRefreshType refreshType, bool showTrackedOperation = true) - { - if (refreshType.HasFlag(ModelRefreshType.Basic)) - { - try - { - Task asyncTask = this.JobSchedule.RefreshAsync(); - if (showTrackedOperation) - { - AsyncOperationTracker.Instance.AddTrackedOperation(new AsyncOperationModel( - asyncTask, - new JobScheduleOperation(JobScheduleOperation.Refresh, this.JobSchedule.Id))); - } - else - { - AsyncOperationTracker.Instance.AddTrackedInternalOperation(asyncTask); - } - - await asyncTask; - this.LastUpdatedTime = DateTime.UtcNow; - - // - // Fire property change events for this models properties - // - this.FireChangesOnRefresh(ModelRefreshType.Basic); - } - catch (Exception e) - { - this.HandleException(e); - } - } - } - - #endregion - - #region Commands - - /// - /// Refresh the selected item - /// - public CommandBase RefreshItem - { - get - { - return new CommandBase( - (item) => - { - var jobSchedule = (item as JobScheduleModel); - if (jobSchedule != null) - { - Task refreshTask = jobSchedule.RefreshAsync(ModelRefreshType.Children | ModelRefreshType.Basic).ContinueWith((t) => - { - FirePropertyChangedEvent("JobSchedules"); - }); - AsyncOperationTracker.Instance.AddTrackedInternalOperation(refreshTask); - } - }); - } - } - - - /// - /// Enable the selected job schedule - /// - public CommandBase EnableJobSchedule - { - get - { - return new CommandBase( - (param) => AsyncOperationTracker.Instance.AddTrackedInternalOperation(this.EnableAsync())); - } - } - - - - /// - /// Disable the selected job schedule in the specified way - /// - - public CommandBase DisableJobSchedule - { - get - { - return new CommandBase( - (jobSchedule) => AsyncOperationTracker.Instance.AddTrackedInternalOperation(this.DisableAsync())); - } - } - - - /// - /// Terminate the selected job schedule - /// - public CommandBase TerminateJobSchedule - { - get - { - return new CommandBase( - (item) => AsyncOperationTracker.Instance.AddTrackedInternalOperation(this.TerminateAsync())); - } - } - - /// - /// Delete the selected item - /// - public CommandBase Delete - { - get - { - return new CommandBase( - (item) => - { - var jobSchedule = (item as JobScheduleModel); - if (jobSchedule != null) - { - Messenger.Default.Register(this, (message) => - { - if (message.MessageBoxResult == MessageBoxResult.Yes) - { - AsyncOperationTracker.Instance.AddTrackedInternalOperation(this.DeleteAsync()); - } - Messenger.Default.Unregister(this); - }); - Messenger.Default.Send(new LaunchMultibuttonDialogMessage() - { - Caption = "Confirm delete", - DialogMessage = "Do you want to delete this item?", - MessageBoxButton = MessageBoxButton.YesNo - }); - } - }); - } - } - - - #endregion - - #region JobSchedule operations - /// - /// Terminates this JobSchedule - /// - public async Task TerminateAsync() - { - try - { - Task asyncTask = this.JobSchedule.TerminateAsync(); - AsyncOperationTracker.Instance.AddTrackedOperation(new AsyncOperationModel( - asyncTask, - new JobScheduleOperation(JobScheduleOperation.Terminate, this.JobSchedule.Id))); - await asyncTask; - await this.RefreshAsync(ModelRefreshType.Basic, false); - } - catch (Exception e) - { - Messenger.Default.Send(new GenericDialogMessage(e.ToString())); - } - } - - /// - /// Deletes this JobSchedule - /// - public async Task DeleteAsync() - { - try - { - Task asyncTask = this.JobSchedule.DeleteAsync(); - AsyncOperationTracker.Instance.AddTrackedOperation(new AsyncOperationModel( - asyncTask, - new JobScheduleOperation(JobScheduleOperation.Delete, this.JobSchedule.Id))); - await asyncTask; - Messenger.Default.Send(new RefreshMessage(RefreshTarget.JobSchedules)); - } - catch (Exception e) - { - Messenger.Default.Send(new GenericDialogMessage(e.ToString())); - } - } - - /// - /// Enables this JobSchedule - /// - public async Task EnableAsync() - { - try - { - Task asyncTask = this.JobSchedule.EnableAsync(); - AsyncOperationTracker.Instance.AddTrackedOperation(new AsyncOperationModel( - asyncTask, - new JobScheduleOperation(JobScheduleOperation.Enable, this.JobSchedule.Id))); - await asyncTask; - await this.RefreshAsync(ModelRefreshType.Basic, false); - } - catch (Exception e) - { - Messenger.Default.Send(new GenericDialogMessage(e.ToString())); - } - } - - /// - /// Disables this JobSchedule - /// - public async Task DisableAsync() - { - try - { - Task asyncTask = this.JobSchedule.DisableAsync(); - AsyncOperationTracker.Instance.AddTrackedOperation(new AsyncOperationModel( - asyncTask, - new JobScheduleOperation(JobScheduleOperation.Disable, this.JobSchedule.Id))); - await asyncTask; - await this.RefreshAsync(ModelRefreshType.Basic, false); - } - catch (Exception e) - { - Messenger.Default.Send(new GenericDialogMessage(e.ToString())); - } - } - - private async Task> ListJobsAsync() - { - List results = new List(); - var detailLevel = new ODATADetailLevel() { SelectClause = "id,state,creationTime" }; - IPagedEnumerable jobList = this.JobSchedule.ListJobs(detailLevel); - - await jobList.ForEachAsync(item => results.Add(new JobModel(item))); - - return results; - } - - private async Task> ListJobsAsync(int min, int max) - { - List results = new List(); - - string uppperBound = string.Format("job-{0:D10}", max); - string lowerBound = string.Format("job-{0:D10}", min); - - // TODO: Need to use the detail level to limit amount of data we download from the server - // TODO: and increase the performace of listing jobs in the UI - //var detailLevel = new ODATADetailLevel() { SelectClause = "id,state,creationTime" }; - //if (string.IsNullOrEmpty(detailLevel.FilterClause)) - //{ - // detailLevel.FilterClause = string.Empty; - //} - //detailLevel.FilterClause += string.Format("(jobId le '{0}' and jobId gt '{1}')", uppperBound, lowerBound); - //IEnumerableAsyncExtended jobList = this.JobSchedule.ListJobs(detailLevel); - // END TODO - - IPagedEnumerable jobList = this.JobSchedule.ListJobs(); - await jobList.ForEachAsync(item => results.Add(new JobModel(item))); - - return results; - } - - #endregion - - #region Private methods - - private void HandleException(Exception e) - { - //Swallow 404's and fire a message - if (Microsoft.Azure.BatchExplorer.Helpers.Common.IsExceptionNotFound(e)) - { - Messenger.Default.Send(new ModelNotFoundAfterRefresh(this)); - } - else - { - Messenger.Default.Send(new GenericDialogMessage(e.ToString())); - } - } - - #endregion - } -} diff --git a/CSharp/BatchExplorer/Models/ModelBase.cs b/CSharp/BatchExplorer/Models/ModelBase.cs deleted file mode 100644 index 0917c3ff..00000000 --- a/CSharp/BatchExplorer/Models/ModelBase.cs +++ /dev/null @@ -1,173 +0,0 @@ -//Copyright (c) Microsoft Corporation - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using System.Reflection; -using Microsoft.Azure.BatchExplorer.Helpers; -using System.Diagnostics; - -namespace Microsoft.Azure.BatchExplorer.Models -{ - /// - /// The different types of refresh available. - /// - [Flags] - public enum ModelRefreshType - { - /// - /// Refresh just this one object - /// - Basic = 1, - - /// - /// Refresh this objects children - /// - Children = 2 - }; - - public abstract class ModelBase : EntityBase - { - public const string LastUpdateFromServerString = "Last Update from Server"; - - /// - /// The time at which this model was last updated from the server - /// - [ChangeTracked(ModelRefreshType.Basic)] - public DateTime LastUpdatedTime { get; protected set; } - - /// - /// Sorted dictionary of property values representing the state of this object - /// - [ChangeTracked(ModelRefreshType.Basic)] - public abstract List PropertyModel { get; } - - /// - /// Determines if this model has loaded its children from the server or not - /// - public bool HasLoadedChildren { get; protected set; } - - /// - /// Refreshes this model with the specified refresh type - /// - /// The refresh type to use - /// Show the refresh row in the tracking list - /// - public abstract System.Threading.Tasks.Task RefreshAsync(ModelRefreshType refreshType, bool showTrackedOperation = true); - - /// - /// Uses reflection to build a hierarchy of properties on a given object. - /// BEWARE THAT BAD THINGS WILL HAPPEN WITH CIRCULAR REFERENCES. - /// - /// The object to process. - /// The names of properties to omit - /// A list of objects which represent the properties of the object. - protected List ObjectToPropertyModel(object o, List propertiesToOmit = null) - { - if (propertiesToOmit == null) - { - propertiesToOmit = new List(); - } - propertiesToOmit.Add("CustomBehaviors"); - - List result = ExtractPropertyCollection(o, propertiesToOmit); - result.Add(new SimplePropertyModel(LastUpdateFromServerString, this.LastUpdatedTime.ToString())); - return result; - } - - private static List ExtractPropertyCollection(object o, List propertiesToOmit) - { - Debug.Assert(propertiesToOmit != null); - - if (o == null) - { - return new List(); - } - - return o.GetType() - .GetProperties() - .Where(prop => !propertiesToOmit.Contains(prop.Name)) - .SelectMany(prop => ExtractPropertyModel(o, prop, propertiesToOmit)) - .ToList(); - } - - private static IEnumerable ExtractPropertyModel(object o, PropertyInfo property, List propertiesToOmit) - { - Debug.Assert(o != null); - Debug.Assert(propertiesToOmit != null); - - try - { - object propertyValue = property.GetValue(o); - return ObjectToPropertyModelRecursive(property.Name, propertyValue, propertiesToOmit); - } - catch (TargetInvocationException) - { - // Skip. Cannot access all properties for bound objects - return Enumerable.Empty(); - } - } - - private static IEnumerable ObjectToPropertyModelRecursive(string propertyName, object propertyValue, List propertiesToOmit = null) - { - if (propertyValue == null) - { - yield break; - } - - Type objectType = propertyValue.GetType(); - bool isStringable = objectType.GetMethod("ToString", Type.EmptyTypes).DeclaringType != typeof(object); // declares a nondefault ToString() which we will use to represent the value instead of recursing into a property tree - IEnumerable enumerable = propertyValue as IEnumerable; - - if ((objectType == typeof(TimeSpan) || objectType == typeof(TimeSpan?)) && propertyValue.Equals(TimeSpan.MaxValue)) - { - yield return new SimplePropertyModel(propertyName, "Unlimited"); - } - else if (isStringable) - { - yield return new SimplePropertyModel(propertyName, propertyValue.ToString()); - } - else if (enumerable != null) - { - string prefix = CollectionPropertyModel.GetItemDisplayPrefix(enumerable); - - List collectionModel = - enumerable.SelectMany((item, index) => ObjectToPropertyModelRecursive(prefix + index, item, propertiesToOmit)) - .ToList(); - - yield return new CollectionPropertyModel(propertyName, collectionModel); - } - else - { - yield return new CollectionPropertyModel(propertyName, ExtractPropertyCollection(propertyValue, propertiesToOmit)); - } - } - - /// - /// Fires a set of property changes on refresh based on the refresh type - /// - /// - protected void FireChangesOnRefresh(ModelRefreshType refreshType) - { - Type myType = this.GetType(); - - //Get all the public properties of this type - PropertyInfo[] properties = myType.GetProperties(BindingFlags.Public | BindingFlags.Instance); - - foreach (PropertyInfo property in properties) - { - //Find all attributes on this property - Attribute[] attributes = Attribute.GetCustomAttributes(property, true); - IEnumerable changeTrackedAttributes = attributes.OfType(); - bool hasPropertyChanged = changeTrackedAttributes.Any() && changeTrackedAttributes.All(attribute => attribute.HasChanged(refreshType)); - - if (hasPropertyChanged) - { - this.FirePropertyChangedEvent(property.Name); //Fire the event associated with this property on change - } - } - } - } -} diff --git a/CSharp/BatchExplorer/Models/OptionsModel.cs b/CSharp/BatchExplorer/Models/OptionsModel.cs deleted file mode 100644 index 7811fd27..00000000 --- a/CSharp/BatchExplorer/Models/OptionsModel.cs +++ /dev/null @@ -1,169 +0,0 @@ -//Copyright (c) Microsoft Corporation - -using System; -using System.IO; -using System.Runtime.Serialization; -using System.Xml; -using GalaSoft.MvvmLight.Messaging; -using Microsoft.Azure.Batch; -using Microsoft.Azure.BatchExplorer.Helpers; -using Microsoft.Azure.BatchExplorer.Messages; - -namespace Microsoft.Azure.BatchExplorer.Models -{ - /// - /// Model representing the different options selected by the user - /// - [DataContract] - public class OptionsModel : EntityBase - { - #region Public properties - - //TODO: Note that this is not thread safe currently - //TODO: Note that this should be changed to a detail level per-type - public ODATADetailLevel ListDetailLevel { get; set; } - - [DataMember] - public int MaxTrackedOperations { get; set; } - - [DataMember] - public bool DisplayOperationHistory - { - get { return this.displayOperationHistory; } - set - { - bool origialValue = this.displayOperationHistory; - this.displayOperationHistory = value; - if (origialValue != value) - { - Messenger.Default.Send(new ShowAsyncOperationTabMessage(this.displayOperationHistory)); - this.FirePropertyChangedEvent("DisplayOperationHistory"); - } - } - } - - [DataMember] - public bool UseStatsDuringList - { - get - { - return this.useStatsDuringList; - } - set - { - this.useStatsDuringList = value; - this.ListDetailLevel = this.useStatsDuringList ? StatsDetailLevel : null; - } - } - - #endregion - - public const string OptionsFileName = "Options.xml"; - - //See: http://csharpindepth.com/articles/general/singleton.aspx for other implementations of the singleton pattern - private static OptionsModel instance; - private static readonly object instanceLock = new object(); - - public static OptionsModel Instance - { - get - { - //Need thread safety - lock (instanceLock) - { - if (instance == null) - { - instance = LoadOptions(); - } - return instance; - } - } - } - - public static ODATADetailLevel StatsDetailLevel = new ODATADetailLevel() { ExpandClause = "stats" }; - private bool displayOperationHistory; - private bool useStatsDuringList; - - private OptionsModel() - { - // TODO: Pick and choose which properties we need to download initially - //this.ListDetailLevel = new ODATADetailLevel() { SelectClause = "name,state,creationTime,executionInfo" }; - - this.ListDetailLevel = new ODATADetailLevel(); - this.MaxTrackedOperations = AsyncOperationTracker.DefaultMaxTrackedOperations; - this.DisplayOperationHistory = true; //Show operation history by default - this.UseStatsDuringList = false; //By default we don't use stats during list - } - - #region Serialization helpers - - /// - /// Writes the options to their file location on disk. - /// - public void WriteOptions() - { - string filePath = GetOptionsFilePath(); - using (FileStream fileStream = new FileStream(filePath, FileMode.Create)) - { - DataContractSerializer serializer = new DataContractSerializer(typeof(OptionsModel)); - XmlWriterSettings settings = new XmlWriterSettings { Indent = true }; - using (XmlWriter writer = XmlWriter.Create(fileStream, settings)) - { - serializer.WriteObject(writer, this); - } - } - } - - /// - /// Loads the options from their location on disk. - /// - /// An OptionsModel instance with the loaded options. - private static OptionsModel LoadOptions() - { - string filePath = GetOptionsFilePath(); - - OptionsModel result; - if (File.Exists(filePath)) - { - try - { - using (FileStream fileStream = new FileStream(filePath, FileMode.Open)) - { - DataContractSerializer serializer = new DataContractSerializer(typeof(OptionsModel)); - result = (OptionsModel)serializer.ReadObject(fileStream); - } - } - catch (Exception) - { - //Ignoring exception and skipping file load - result = new OptionsModel(); - } - } - else - { - result = new OptionsModel(); - } - - return result; - } - - /// - /// Gets the path of the options file. - /// - /// The path of the options file. - private static string GetOptionsFilePath() - { - // create the directory if necessary - string fullDirectoryPath = Path.Combine( - Microsoft.Azure.BatchExplorer.Helpers.Common.LocalAppDataDirectory, - Microsoft.Azure.BatchExplorer.Helpers.Common.LocalAppDataSubfolder); - Directory.CreateDirectory(fullDirectoryPath); - - string path = Path.Combine(fullDirectoryPath, OptionsFileName); - - return path; - } - - #endregion - } -} diff --git a/CSharp/BatchExplorer/Models/Pool.cs b/CSharp/BatchExplorer/Models/Pool.cs deleted file mode 100644 index b4e70c14..00000000 --- a/CSharp/BatchExplorer/Models/Pool.cs +++ /dev/null @@ -1,14 +0,0 @@ -//Copyright (c) Microsoft Corporation - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Microsoft.Azure.BatchExplorer.Models -{ - public class Pool : EntityBase - { - } -} diff --git a/CSharp/BatchExplorer/Models/PoolModel.cs b/CSharp/BatchExplorer/Models/PoolModel.cs deleted file mode 100644 index f0735706..00000000 --- a/CSharp/BatchExplorer/Models/PoolModel.cs +++ /dev/null @@ -1,284 +0,0 @@ -//Copyright (c) Microsoft Corporation - -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Windows.Data; -using System.Threading.Tasks; -using GalaSoft.MvvmLight.Messaging; -using Microsoft.Azure.Batch; -using Microsoft.Azure.Batch.Common; -using Microsoft.Azure.BatchExplorer.Helpers; -using Microsoft.Azure.BatchExplorer.Messages; - -namespace Microsoft.Azure.BatchExplorer.Models -{ - /// - /// The data model for the Pool object - /// - public class PoolModel : ModelBase - { - #region Public properties - - /// - /// The set of compute nodes associated with this pool - /// - public List ComputeNodes { get; private set; } - - /// - /// The id of this pool - /// - [ChangeTracked(ModelRefreshType.Basic)] - public string Id { get { return this.Pool.Id; } } - - /// - /// Creation time of the pool - /// - [ChangeTracked(ModelRefreshType.Basic)] - public DateTime? CreationTime { get { return this.Pool.CreationTime; } } - - /// - /// State of the pool - /// - [ChangeTracked(ModelRefreshType.Basic)] - public PoolState? State { get { return this.Pool.State; } } - - /// - /// The size of ComputeNodes in this pool - /// - [ChangeTracked(ModelRefreshType.Basic)] - public string VirtualMachineSize { get { return this.Pool.VirtualMachineSize; } } - - /// - /// The current dedicated size of this pool - /// - [ChangeTracked(ModelRefreshType.Basic)] - public int? CurrentDedicated { get { return this.Pool.CurrentDedicatedComputeNodes; } } - - /// - /// The current dedicated size of this pool - /// - [ChangeTracked(ModelRefreshType.Basic)] - public int? CurrentLowPriority { get { return this.Pool.CurrentLowPriorityComputeNodes; } } - - /// - /// The pool allocation state - /// - [ChangeTracked(ModelRefreshType.Basic)] - public AllocationState? AllocationState { get { return this.Pool.AllocationState; } } - - /// - /// The ComputeNode collection associated with this pool - /// - [ChangeTracked(ModelRefreshType.Children)] - public ICollectionView ComputeNodeCollection { get; set; } - - /// - /// Gets the current autoscale formula. - /// - [ChangeTracked(ModelRefreshType.Basic)] - public string CurrentAutoScaleFormula { get { return this.Pool.AutoScaleFormula; } } - - - #endregion - - private CloudPool Pool { get; set; } - - /// - /// Create a pool model from the pool cache entity - /// - public PoolModel(CloudPool pool) - { - this.Pool = pool; - this.LastUpdatedTime = DateTime.UtcNow; - this.ComputeNodes = new List(); - - this.ComputeNodeCollection = CollectionViewSource.GetDefaultView(this.ComputeNodes); - this.UpdateNodeView(); - } - - #region ModelBase implementation - - public override List PropertyModel - { - get - { - return this.ObjectToPropertyModel(this.Pool); - } - } - - public override async Task RefreshAsync(ModelRefreshType refreshType, bool showTrackedOperation = true) - { - if (refreshType.HasFlag(ModelRefreshType.Basic)) - { - try - { - Messenger.Default.Send(new UpdateWaitSpinnerMessage(WaitSpinnerPanel.Left, true)); - Task asyncTask = this.Pool.RefreshAsync(); - if (showTrackedOperation) - { - AsyncOperationTracker.Instance.AddTrackedOperation(new AsyncOperationModel( - asyncTask, - new PoolOperation(PoolOperation.Refresh, this.Pool.Id))); - } - else - { - AsyncOperationTracker.Instance.AddTrackedInternalOperation(asyncTask); - } - - await asyncTask; - this.LastUpdatedTime = DateTime.UtcNow; - - // - // Fire property change events for this models properties - // - this.FireChangesOnRefresh(ModelRefreshType.Basic); - } - catch (Exception e) - { - this.HandleException(e); - } - finally - { - Messenger.Default.Send(new UpdateWaitSpinnerMessage(WaitSpinnerPanel.Left, false)); - } - } - - if (refreshType.HasFlag(ModelRefreshType.Children)) - { - try - { - Messenger.Default.Send(new UpdateWaitSpinnerMessage(WaitSpinnerPanel.UpperRight, true)); - - //Set this before the children load so that on revisit we know we have loaded the children (or are in the process) - this.HasLoadedChildren = true; - - Task> asyncTask = this.ListComputeNodesAsync(); - AsyncOperationTracker.Instance.AddTrackedOperation(new AsyncOperationModel( - asyncTask, - new PoolOperation(PoolOperation.ListComputeNodes, this.Pool.Id))); - this.ComputeNodes = await asyncTask; - - this.ComputeNodeCollection = CollectionViewSource.GetDefaultView(this.ComputeNodes); - this.UpdateNodeView(); - } - catch (Exception e) - { - this.HasLoadedChildren = false; //On exception, we failed to load children so try again next time - this.HandleException(e); - } - finally - { - Messenger.Default.Send(new UpdateWaitSpinnerMessage(WaitSpinnerPanel.UpperRight, false)); - } - } - - Messenger.Default.Send(new PoolUpdateCompleteMessage()); - } - - #endregion - - #region Operations on pool - - /// - /// Delete this pool from the server - /// - public async Task DeleteAsync() - { - try - { - Task asyncTask = this.Pool.DeleteAsync(); - AsyncOperationTracker.Instance.AddTrackedOperation(new AsyncOperationModel( - asyncTask, - new PoolOperation(PoolOperation.Delete, this.Pool.Id))); - await asyncTask; - Messenger.Default.Send(new RefreshMessage(RefreshTarget.Pools)); - } - catch (Exception e) - { - Messenger.Default.Send(new GenericDialogMessage(e.ToString())); - } - } - - /// - /// Resize this pool - /// - public async Task ResizeAsync(int targetDedicated, int targetLowPriority, TimeSpan timeout, ComputeNodeDeallocationOption deallocationOption) - { - try - { - Task asyncTask = this.Pool.ResizeAsync(targetDedicated, targetLowPriority, timeout, deallocationOption); - AsyncOperationTracker.Instance.AddTrackedOperation(new AsyncOperationModel( - asyncTask, - new PoolOperation(PoolOperation.Resize, this.Pool.Id))); - await asyncTask; - await this.RefreshAsync(ModelRefreshType.Basic, showTrackedOperation: false); - } - catch (Exception e) - { - Messenger.Default.Send(new GenericDialogMessage(e.ToString())); - } - } - - /// - /// Stop an ongoing resize on this pool - /// - public async Task StopResizeAsync() - { - try - { - Task asyncTask = this.Pool.StopResizeAsync(); - AsyncOperationTracker.Instance.AddTrackedOperation(new AsyncOperationModel( - asyncTask, - new PoolOperation(PoolOperation.StopResize, this.Pool.Id))); - await asyncTask; - await this.RefreshAsync(ModelRefreshType.Basic, showTrackedOperation: false); - } - catch (Exception e) - { - Messenger.Default.Send(new GenericDialogMessage(e.ToString())); - } - } - - private async Task> ListComputeNodesAsync() - { - List results = new List(); - IPagedEnumerable jobList = this.Pool.ListComputeNodes(); - - await jobList.ForEachAsync(item => results.Add(new ComputeNodeModel(this, item))); - - return results; - } - - #endregion - - #region Public methods - - /// - /// Updates associated list of ComputeNodes view - /// - public void UpdateNodeView() - { - this.FireChangesOnRefresh(ModelRefreshType.Children); - } - - #endregion - - #region Private methods - - private void HandleException(Exception e) - { - //Swallow 404's and fire a message - if (Microsoft.Azure.BatchExplorer.Helpers.Common.IsExceptionNotFound(e)) - { - Messenger.Default.Send(new ModelNotFoundAfterRefresh(this)); - } - else - { - Messenger.Default.Send(new GenericDialogMessage(e.ToString())); - } - } - - #endregion - } -} diff --git a/CSharp/BatchExplorer/Models/PropertyDisplayModel.cs b/CSharp/BatchExplorer/Models/PropertyDisplayModel.cs deleted file mode 100644 index bd5d6057..00000000 --- a/CSharp/BatchExplorer/Models/PropertyDisplayModel.cs +++ /dev/null @@ -1,73 +0,0 @@ -//Copyright (c) Microsoft Corporation - -namespace Microsoft.Azure.BatchExplorer.Models -{ - using System; - using System.Collections; - using System.Collections.Generic; - using System.Diagnostics; - using System.Linq; - using System.Text; - using System.Threading.Tasks; - using System.Windows; - using System.Windows.Controls; - using System.Windows.Documents; - using System.Windows.Input; - - public abstract class PropertyModel - { - public string PropertyName { get; private set; } - - protected PropertyModel(string propertyName) - { - this.PropertyName = propertyName; - } - } - - public class SimplePropertyModel : PropertyModel - { - public string PropertyValue { get; private set; } - - public SimplePropertyModel(string propertyName, string propertyValue) - : base(propertyName) - { - this.PropertyValue = propertyValue; - } - } - - public class CollectionPropertyModel : PropertyModel - { - public List Items { get; private set; } - - public CollectionPropertyModel(string propertyName, List items) - : base(propertyName) - { - this.Items = items; - } - - internal static string GetItemDisplayPrefix(IEnumerable collection) - { - Type elementType = ElementType(collection.GetType()); - if (elementType == null) - { - return "item"; - } - return elementType.Name; - } - - private static Type ElementType(Type collectionType) - { - Debug.Assert(collectionType != null); - Debug.Assert(typeof(IEnumerable).IsAssignableFrom(collectionType)); - - Type[] stronglyTypedInterfaces = collectionType.FindInterfaces((m, c) => m.IsConstructedGenericType && m.GetGenericTypeDefinition() == typeof(IEnumerable<>), null); - - if (stronglyTypedInterfaces == null || stronglyTypedInterfaces.Length == 0 || stronglyTypedInterfaces.Length > 1) - { - return null; // not a strongly typed collection, or a strongly typed collection of more than one thing (yikes) - } - - return stronglyTypedInterfaces[0].GetGenericArguments()[0]; - } - } -} diff --git a/CSharp/BatchExplorer/Models/ResourceFileInfo.cs b/CSharp/BatchExplorer/Models/ResourceFileInfo.cs deleted file mode 100644 index d97a2251..00000000 --- a/CSharp/BatchExplorer/Models/ResourceFileInfo.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Microsoft.Azure.BatchExplorer.Models -{ - public sealed class ResourceFileInfo - { - private readonly string blobSource; - private readonly string filePath; - - public ResourceFileInfo(string blobSource, string filePath) - { - this.blobSource = blobSource; - this.filePath = filePath; - } - - public string BlobSource - { - get { return blobSource; } - } - - public string FilePath - { - get { return filePath; } - } - } -} diff --git a/CSharp/BatchExplorer/Models/StartTaskOptions.cs b/CSharp/BatchExplorer/Models/StartTaskOptions.cs deleted file mode 100644 index 605479c3..00000000 --- a/CSharp/BatchExplorer/Models/StartTaskOptions.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Microsoft.Azure.BatchExplorer.Models -{ - public class StartTaskOptions - { - public string CommandLine { get; set; } - - public List ResourceFiles { get; set; } - - public bool RunElevated { get; set; } - } -} diff --git a/CSharp/BatchExplorer/Models/SubtaskModel.cs b/CSharp/BatchExplorer/Models/SubtaskModel.cs deleted file mode 100644 index 49a3ba57..00000000 --- a/CSharp/BatchExplorer/Models/SubtaskModel.cs +++ /dev/null @@ -1,56 +0,0 @@ -using Microsoft.Azure.Batch; -using Microsoft.Azure.Batch.Common; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Microsoft.Azure.BatchExplorer.Models -{ - public class SubtaskModel - { - private readonly int? id; - private readonly SubtaskState? state; - private readonly string nodeId; - private readonly int? exitCode; - private readonly string taskRoot; - - public SubtaskModel(SubtaskInformation subtask) - { - this.id = subtask.Id; - this.state = subtask.State; - if (subtask.ComputeNodeInformation != null) - { - this.nodeId = subtask.ComputeNodeInformation.ComputeNodeId; - this.taskRoot = subtask.ComputeNodeInformation.TaskRootDirectory; - } - this.exitCode = subtask.ExitCode; - } - - public string Id - { - get { return id.HasValue ? id.Value.ToString() : String.Empty; } - } - - public string State - { - get { return state.HasValue ? state.Value.ToString() : String.Empty; } - } - - public string NodeId - { - get { return nodeId; } - } - - public string TaskRootDir - { - get { return taskRoot; } - } - - public string ExitCode - { - get { return exitCode.HasValue ? exitCode.Value.ToString() : String.Empty; } - } - } -} diff --git a/CSharp/BatchExplorer/Models/TaskModel.cs b/CSharp/BatchExplorer/Models/TaskModel.cs deleted file mode 100644 index 9dfeefa9..00000000 --- a/CSharp/BatchExplorer/Models/TaskModel.cs +++ /dev/null @@ -1,402 +0,0 @@ -//Copyright (c) Microsoft Corporation - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using GalaSoft.MvvmLight.Messaging; -using Microsoft.Azure.Batch; -using Microsoft.Azure.Batch.Common; -using Microsoft.Azure.BatchExplorer.Helpers; -using Microsoft.Azure.BatchExplorer.Messages; -using Microsoft.Azure.BatchExplorer.ViewModels; -using System.Text; - -namespace Microsoft.Azure.BatchExplorer.Models -{ - /// - /// The data model for the Task object - /// - public class TaskModel : ModelBase - { - #region Public properties - - /// - /// The parent job of this task - /// - public JobModel ParentJob { get; set; } - - /// - /// The id of this task - /// - [ChangeTracked(ModelRefreshType.Basic)] - public string Id { get { return this.Task.Id; } } - - /// - /// The state of this task - /// - [ChangeTracked(ModelRefreshType.Basic)] - public TaskState? State { get { return this.Task.State; } } - - /// - /// The creation time of this task - /// - [ChangeTracked(ModelRefreshType.Basic)] - public DateTime? CreationTime { get { return this.Task.CreationTime; } } - - /// - /// The commandline this task runs - /// - [ChangeTracked(ModelRefreshType.Basic)] - public string CommandLine { get { return this.Task.CommandLine; } } - - /// - /// The exit code of the task - /// - [ChangeTracked(ModelRefreshType.Basic)] - public int? ExitCode { get { return this.Task?.ExecutionInformation?.ExitCode; } } - - /// - /// The set of Windows Azure blobs downloaded to run the task - /// - [ChangeTracked(ModelRefreshType.Basic)] - public IEnumerable ResourceFiles { get { return this.Task.ResourceFiles; } } - - /// - /// The number of times to retry this task - /// - [ChangeTracked(ModelRefreshType.Basic)] - public int? MaxTaskRetryCount { get { return this.Task.Constraints.MaxTaskRetryCount; } } - - /// - /// Maximum time a task is allowed to run after it is created - /// - [ChangeTracked(ModelRefreshType.Basic)] - public TimeSpan? MaxWallClockTime { get { return this.Task.Constraints.MaxWallClockTime; } } - - /// - /// Duration of time for which files in the task's working directory are retained, from the time execution completed - /// - [ChangeTracked(ModelRefreshType.Basic)] - public TimeSpan? RetentionTime { get { return this.Task.Constraints.RetentionTime; } } - - /// - /// The environmental settings - /// - [ChangeTracked(ModelRefreshType.Basic)] - public IEnumerable EnvironmentSettings { get { return this.Task.EnvironmentSettings; } } - - /// - /// The set of output files for this task object - /// - [ChangeTracked(ModelRefreshType.Children)] - public IEnumerable OutputFiles { get; private set; } - - /// - /// True if there are output files to be had - /// - [ChangeTracked(ModelRefreshType.Children)] - public bool HasOutputFiles - { - get - { - if (this.attemptToLoadOutputs && (this.OutputFiles == null || !this.OutputFiles.Any())) - { - AsyncOperationTracker.Instance.AddTrackedInternalOperation( - this.RefreshAsync(ModelRefreshType.Basic | ModelRefreshType.Children)); - } - - this.attemptToLoadOutputs = false; - return (this.OutputFiles != null && this.OutputFiles.Any()); - } - } - - /// - /// The set of Subtask information - /// - [ChangeTracked(ModelRefreshType.Children)] - public IEnumerable Subtasks { get { return this.SubtasksInfo; } } - - #endregion - - #region Public UI Properties - - private NodeFile selectedTaskFile; - - public NodeFile SelectedTaskFile - { - get { return this.selectedTaskFile; } - set - { - this.selectedTaskFile = value; - this.FirePropertyChangedEvent("SelectedTaskFile"); - } - } - - private string noOutputFilesReason; - public string NoOutputFilesReason - { - get - { - if (string.IsNullOrEmpty(this.noOutputFilesReason)) - { - return "No outputs available. Try refreshing the Task."; - } - - return this.noOutputFilesReason; - } - set - { - this.noOutputFilesReason = value; - this.FirePropertyChangedEvent("NoOutputFilesReason"); - } - } - - #endregion - - private bool attemptToLoadOutputs; - private CloudTask Task { get; set; } - private IList SubtasksInfo { get; set; } - private static readonly List PropertiesToOmitFromDisplay = new List { "FilesToStage" }; - - public TaskModel(JobModel parentJob, CloudTask task) - { - this.attemptToLoadOutputs = true; - - this.ParentJob = parentJob; - this.Task = task; - this.LastUpdatedTime = DateTime.UtcNow; - this.SubtasksInfo = null; - } - - #region ModelBase implementation - - public override List PropertyModel - { - get { return this.ObjectToPropertyModel(this.Task, PropertiesToOmitFromDisplay); } - } - - public override async System.Threading.Tasks.Task RefreshAsync(ModelRefreshType refreshType, bool showTrackedOperation = true) - { - this.attemptToLoadOutputs = true; - - if (refreshType.HasFlag(ModelRefreshType.Basic)) - { - try - { - //await this.Task.RefreshAsync(); TODO: This doesnt' work right now due to bug with OM, so must do GetTask directly - Messenger.Default.Send(new UpdateWaitSpinnerMessage(WaitSpinnerPanel.UpperRight, true)); - - System.Threading.Tasks.Task asyncTask = MainViewModel.dataProvider.Service.GetTaskAsync( - this.ParentJob.Id, - this.Task.Id, - OptionsModel.Instance.ListDetailLevel); - - if (showTrackedOperation) - { - AsyncOperationTracker.Instance.AddTrackedOperation(new AsyncOperationModel( - asyncTask, - new TaskOperation(TaskOperation.Refresh, this.ParentJob.Id, this.Task.Id))); - } - else - { - AsyncOperationTracker.Instance.AddTrackedInternalOperation(asyncTask); - } - - this.Task = await asyncTask; - this.LastUpdatedTime = DateTime.UtcNow; - - // - // Fire property change events for this models properties - // - this.FireChangesOnRefresh(ModelRefreshType.Basic); - } - catch (Exception e) - { - this.HandleException(e); - } - finally - { - Messenger.Default.Send(new UpdateWaitSpinnerMessage(WaitSpinnerPanel.UpperRight, false)); - } - } - - if (refreshType.HasFlag(ModelRefreshType.Children)) - { - try - { - Messenger.Default.Send(new UpdateWaitSpinnerMessage(WaitSpinnerPanel.LowerRight, true)); - //Set this before the children load so that on revisit we know we have loaded the children (or are in the process) - this.HasLoadedChildren = true; - try - { - System.Threading.Tasks.Task> asyncTask = this.ListTaskFilesAsync(); - AsyncOperationTracker.Instance.AddTrackedOperation(new AsyncOperationModel( - asyncTask, - new TaskOperation(TaskOperation.ListFiles, this.ParentJob.Id, this.Task.Id))); - - this.OutputFiles = await asyncTask; - } - catch (BatchException be) - { - StringBuilder noOutputReasonBuilder = new StringBuilder(); - - if (be.RequestInformation != null && be.RequestInformation.BatchError != null) - { - - if (!string.IsNullOrEmpty(be.RequestInformation.BatchError.Code)) - { - noOutputReasonBuilder.AppendLine(be.RequestInformation.BatchError.Code); - } - - if (be.RequestInformation.BatchError.Message != null && !string.IsNullOrEmpty(be.RequestInformation.BatchError.Message.Value)) - { - noOutputReasonBuilder.AppendLine(be.RequestInformation.BatchError.Message.Value); - } - - if (be.RequestInformation.BatchError.Values != null) - { - noOutputReasonBuilder.AppendLine(); - - foreach (var errorDetail in be.RequestInformation.BatchError.Values) - { - noOutputReasonBuilder.AppendLine(string.Format("{0}: {1}", errorDetail.Key, errorDetail.Value)); - } - } - - this.NoOutputFilesReason = noOutputReasonBuilder.ToString(); - } - } - catch (Exception) - { - this.HasLoadedChildren = false; //On exception, we failed to load children so try again next time - //Swallow the exception to stop popups from occuring for every bad VM - } - - IPagedEnumerable subtasks = this.Task.ListSubtasks(OptionsModel.Instance.ListDetailLevel); - - this.SubtasksInfo = new List(); - - System.Threading.Tasks.Task asyncListSubtasksTask = subtasks.ForEachAsync(item => this.SubtasksInfo.Add(new SubtaskModel(item))); - - AsyncOperationTracker.Instance.AddTrackedOperation(new AsyncOperationModel( - asyncListSubtasksTask, - new TaskOperation(TaskOperation.ListSubtasks, this.ParentJob.Id, this.Task.Id))); - - await asyncListSubtasksTask; - - this.FireChangesOnRefresh(ModelRefreshType.Children); - } - catch (Exception e) - { - this.HasLoadedChildren = false; //On exception, we failed to load children so try again next time - this.HandleException(e); - } - finally - { - Messenger.Default.Send(new UpdateWaitSpinnerMessage(WaitSpinnerPanel.LowerRight, false)); - } - } - } - #endregion - - #region Task operations - - /// - /// Delete this task - /// - public async System.Threading.Tasks.Task DeleteAsync() - { - try - { - System.Threading.Tasks.Task asyncTask = this.Task.DeleteAsync(); - AsyncOperationTracker.Instance.AddTrackedOperation(new AsyncOperationModel( - asyncTask, - new TaskOperation(TaskOperation.Delete, this.ParentJob.Id, this.Task.Id))); - await asyncTask; - } - catch (Exception e) - { - Messenger.Default.Send(new GenericDialogMessage(e.ToString())); - } - } - - /// - /// Terminate the task - /// - public async System.Threading.Tasks.Task TerminateAsync() - { - try - { - System.Threading.Tasks.Task asyncTask = this.Task.TerminateAsync(); - AsyncOperationTracker.Instance.AddTrackedOperation(new AsyncOperationModel( - asyncTask, - new TaskOperation(TaskOperation.Terminate, this.ParentJob.Id, this.Task.Id))); - await asyncTask; - await this.RefreshAsync(ModelRefreshType.Basic, showTrackedOperation: false); - } - catch (Exception e) - { - Messenger.Default.Send(new GenericDialogMessage(e.ToString())); - } - } - - /// - /// Downloads a task file - /// - /// The file path to download - /// The stream to download the file into - /// - public async System.Threading.Tasks.Task GetTaskFileAsync(string filePath, Stream outputStream) - { - System.Threading.Tasks.Task asyncTask = this.DownloadTaskFile(filePath, outputStream); - AsyncOperationTracker.Instance.AddTrackedOperation(new AsyncOperationModel( - asyncTask, - new TaskOperation(TaskOperation.GetFile, this.ParentJob.Id, this.Task.Id))); - await asyncTask; - } - - #endregion - - #region Private methods - /// - /// Lists the task files associated with this task - /// - /// - private async System.Threading.Tasks.Task> ListTaskFilesAsync() - { - IPagedEnumerable vmFiles = this.Task.ListNodeFiles(recursive: true); - - List results = await vmFiles.ToListAsync(); - - return results; - } - - /// - /// Downloads the contents of the specific file of the task. - /// - /// The path to the file. - /// The destination stream. - /// - private async System.Threading.Tasks.Task DownloadTaskFile(string filePath, Stream destinationStream) - { - NodeFile file = await this.Task.GetNodeFileAsync(filePath); - await file.CopyToStreamAsync(destinationStream); - } - - private void HandleException(Exception e) - { - //Swallow 404's and fire a message - if (Microsoft.Azure.BatchExplorer.Helpers.Common.IsExceptionNotFound(e)) - { - Messenger.Default.Send(new ModelNotFoundAfterRefresh(this)); - } - else - { - Messenger.Default.Send(new GenericDialogMessage(e.ToString())); - } - } - - #endregion - } -} diff --git a/CSharp/BatchExplorer/Models/VirtualMachineConfigurationOptions.cs b/CSharp/BatchExplorer/Models/VirtualMachineConfigurationOptions.cs deleted file mode 100644 index ba8d7679..00000000 --- a/CSharp/BatchExplorer/Models/VirtualMachineConfigurationOptions.cs +++ /dev/null @@ -1,18 +0,0 @@ -namespace Microsoft.Azure.BatchExplorer.Models -{ - public class VirtualMachineConfigurationOptions - { - - public string Offer { get; set; } - - public string Publisher { get; set; } - - public string SkuId { get; set; } - - public string Version { get; set; } - - public string NodeAgentSkuId { get; set; } - - public bool? EnableWindowsAutomaticUpdates { get; set; } - } -} diff --git a/CSharp/BatchExplorer/Models/WorkItem.cs b/CSharp/BatchExplorer/Models/WorkItem.cs deleted file mode 100644 index 411db0d3..00000000 --- a/CSharp/BatchExplorer/Models/WorkItem.cs +++ /dev/null @@ -1,14 +0,0 @@ -//Copyright (c) Microsoft Corporation - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Microsoft.Azure.BatchExplorer -{ - public class WorkItem : EntityBase - { - } -} diff --git a/CSharp/BatchExplorer/PluginInterfaces/AccountPlugin/AccountManagementAddOperation.cs b/CSharp/BatchExplorer/PluginInterfaces/AccountPlugin/AccountManagementAddOperation.cs deleted file mode 100644 index 34b43628..00000000 --- a/CSharp/BatchExplorer/PluginInterfaces/AccountPlugin/AccountManagementAddOperation.cs +++ /dev/null @@ -1,30 +0,0 @@ -//Copyright (c) Microsoft Corporation - -using System.Windows.Controls; -using Microsoft.Azure.BatchExplorer.Models; - -namespace Microsoft.Azure.BatchExplorer.PluginInterfaces.AccountPlugin -{ - /// - /// Account management add operation. - /// - public class AccountManagementAddOperation : AccountManagementOperation - { - private readonly IAccountAdder accountAdder; - - public AccountManagementAddOperation(IAccountAdder accountAdder, Control control) - : base(control) - { - this.accountAdder = accountAdder; - } - - /// - /// See . - /// - /// The account associated with this operation. - public override Account Complete() - { - return this.accountAdder.CreateAccountForAdd(); - } - } -} diff --git a/CSharp/BatchExplorer/PluginInterfaces/AccountPlugin/AccountManagementEditOperation.cs b/CSharp/BatchExplorer/PluginInterfaces/AccountPlugin/AccountManagementEditOperation.cs deleted file mode 100644 index 8dba5f7e..00000000 --- a/CSharp/BatchExplorer/PluginInterfaces/AccountPlugin/AccountManagementEditOperation.cs +++ /dev/null @@ -1,30 +0,0 @@ -//Copyright (c) Microsoft Corporation - -using System.Windows.Controls; -using Microsoft.Azure.BatchExplorer.Models; - -namespace Microsoft.Azure.BatchExplorer.PluginInterfaces.AccountPlugin -{ - /// - /// Account management edit operation. - /// - public class AccountManagementEditOperation : AccountManagementOperation - { - private readonly IAccountEditor accountEditor; - - public AccountManagementEditOperation(IAccountEditor accountEditor, Control control) - : base(control) - { - this.accountEditor = accountEditor; - } - - /// - /// See . - /// - /// The account associated with this operation. - public override Account Complete() - { - return this.accountEditor.CreateAccountForEdit(); - } - } -} diff --git a/CSharp/BatchExplorer/PluginInterfaces/AccountPlugin/AccountManagementOperation.cs b/CSharp/BatchExplorer/PluginInterfaces/AccountPlugin/AccountManagementOperation.cs deleted file mode 100644 index 6ed0f49b..00000000 --- a/CSharp/BatchExplorer/PluginInterfaces/AccountPlugin/AccountManagementOperation.cs +++ /dev/null @@ -1,33 +0,0 @@ -//Copyright (c) Microsoft Corporation - -using System.Windows.Controls; -using Microsoft.Azure.BatchExplorer.Models; - -namespace Microsoft.Azure.BatchExplorer.PluginInterfaces.AccountPlugin -{ - /// - /// Represents an account management operation associated with a UI control. - /// - public abstract class AccountManagementOperation - { - /// - /// The UI control associated with the account management operation. - /// - public Control Control { get; private set; } - - /// - /// Initializes a new operation with the specified backing control. - /// - /// The control associated with this operation. - protected AccountManagementOperation(Control control) - { - this.Control = control; - } - - /// - /// Completes the operation and returns the associated account. - /// - /// The account which was a result of the operation. - public abstract Account Complete(); - } -} diff --git a/CSharp/BatchExplorer/PluginInterfaces/AccountPlugin/IAccountAdder.cs b/CSharp/BatchExplorer/PluginInterfaces/AccountPlugin/IAccountAdder.cs deleted file mode 100644 index c53c0936..00000000 --- a/CSharp/BatchExplorer/PluginInterfaces/AccountPlugin/IAccountAdder.cs +++ /dev/null @@ -1,18 +0,0 @@ -//Copyright (c) Microsoft Corporation - -using Microsoft.Azure.BatchExplorer.Models; - -namespace Microsoft.Azure.BatchExplorer.PluginInterfaces.AccountPlugin -{ - /// - /// Interface exposing the functionality to Create an account object for the purposes of "adding" it. - /// - public interface IAccountAdder - { - /// - /// Creates an account object populated appropriately. - /// - /// An account object ready to be used. - Account CreateAccountForAdd(); - } -} diff --git a/CSharp/BatchExplorer/PluginInterfaces/AccountPlugin/IAccountEditor.cs b/CSharp/BatchExplorer/PluginInterfaces/AccountPlugin/IAccountEditor.cs deleted file mode 100644 index e870ce39..00000000 --- a/CSharp/BatchExplorer/PluginInterfaces/AccountPlugin/IAccountEditor.cs +++ /dev/null @@ -1,18 +0,0 @@ -//Copyright (c) Microsoft Corporation - -using Microsoft.Azure.BatchExplorer.Models; - -namespace Microsoft.Azure.BatchExplorer.PluginInterfaces.AccountPlugin -{ - /// - /// Interface exposing the functionality to create an account object for "Edit" purposes. - /// - public interface IAccountEditor - { - /// - /// Creates an account object populated appropriately. - /// - /// An account object ready to be used. - Account CreateAccountForEdit(); - } -} diff --git a/CSharp/BatchExplorer/PluginInterfaces/AccountPlugin/IAccountManager.cs b/CSharp/BatchExplorer/PluginInterfaces/AccountPlugin/IAccountManager.cs deleted file mode 100644 index 590e16de..00000000 --- a/CSharp/BatchExplorer/PluginInterfaces/AccountPlugin/IAccountManager.cs +++ /dev/null @@ -1,75 +0,0 @@ -//Copyright (c) Microsoft Corporation - -using System.Collections.ObjectModel; -using System.ComponentModel; -using System.Threading.Tasks; -using Microsoft.Azure.BatchExplorer.Models; - -namespace Microsoft.Azure.BatchExplorer.PluginInterfaces.AccountPlugin -{ - /// - /// Account manager interface which defines the control operations allowed on accounts. - /// - public interface IAccountManager : INotifyPropertyChanged - { - /// - /// The object associated with this account manager. The manages - /// account management operations and their UI (such as Add and Edit). - /// - IAccountOperationFactory OperationFactory { get; } - - /// - /// Adds the associated account to the manager. - /// - /// The account for the manager to track. - /// The asynchronous operation. - Task AddAccountAsync(Account account); - - /// - /// True if the manager can edit accounts. False if it cannot. - /// - bool CanEditAccount { get; } - - /// - /// Creates a copy of the specified account for editing purposes. - /// - /// The account object to copy. - /// A copy of the specified account object. - Task CloneAccountForEditAsync(Account account); - - /// - /// Commits an edit to the manager, overriding the existing account and replacing it with the new account with modified properties. - /// - /// The edited account. - /// The asynchronous operation. - Task CommitEditAsync(Account account); - - /// - /// True if the manager can delete accounts. False if it cannot. - /// - bool CanDeleteAccount { get; } - - /// - /// Deletes the specified account from the manager. - /// - /// The account object to remove from tracking. - /// The asynchronous operation. - Task DeleteAccountAsync(Account account); - - /// - /// True if this manager has any accounts. False otherwise. - /// - bool HasAccounts { get; } - - /// - /// A collection of accounts currently being tracked by the . - /// - ObservableCollection Accounts { get; } - - /// - /// Performs one time initialization of the account manager (such as reading from a file or database). - /// - /// The asynchronous operation. - Task InitalizeAsync(); - } -} diff --git a/CSharp/BatchExplorer/PluginInterfaces/AccountPlugin/IAccountManagerMetadata.cs b/CSharp/BatchExplorer/PluginInterfaces/AccountPlugin/IAccountManagerMetadata.cs deleted file mode 100644 index d83f00c1..00000000 --- a/CSharp/BatchExplorer/PluginInterfaces/AccountPlugin/IAccountManagerMetadata.cs +++ /dev/null @@ -1,15 +0,0 @@ -//Copyright (c) Microsoft Corporation - -namespace Microsoft.Azure.BatchExplorer.PluginInterfaces.AccountPlugin -{ - /// - /// Account manager metadata assoicated with an . - /// - public interface IAccountManagerMetadata - { - /// - /// The name of the account manager. - /// - string Name { get; } - } -} diff --git a/CSharp/BatchExplorer/PluginInterfaces/AccountPlugin/IAccountOperationFactory.cs b/CSharp/BatchExplorer/PluginInterfaces/AccountPlugin/IAccountOperationFactory.cs deleted file mode 100644 index c1227fff..00000000 --- a/CSharp/BatchExplorer/PluginInterfaces/AccountPlugin/IAccountOperationFactory.cs +++ /dev/null @@ -1,15 +0,0 @@ -//Copyright (c) Microsoft Corporation - -using Microsoft.Azure.BatchExplorer.Models; - -namespace Microsoft.Azure.BatchExplorer.PluginInterfaces.AccountPlugin -{ - /// - /// Factory for account management operations and their corresponding UIs. - /// - public interface IAccountOperationFactory - { - AccountManagementAddOperation CreateAddAccountOperation(); - AccountManagementEditOperation CreateEditAccountOperation(Account account); - } -} diff --git a/CSharp/BatchExplorer/Plugins/AccountPlugin/DefaultAccount.cs b/CSharp/BatchExplorer/Plugins/AccountPlugin/DefaultAccount.cs deleted file mode 100644 index ffba1563..00000000 --- a/CSharp/BatchExplorer/Plugins/AccountPlugin/DefaultAccount.cs +++ /dev/null @@ -1,80 +0,0 @@ -//Copyright (c) Microsoft Corporation - -using System; -using System.Security.Cryptography; -using System.Text; -using System.Xml.Serialization; -using Microsoft.Azure.BatchExplorer.Models; -using Microsoft.Azure.BatchExplorer.PluginInterfaces.AccountPlugin; - -namespace Microsoft.Azure.BatchExplorer.Plugins.AccountPlugin -{ - /// - /// Account used by the default BatchExplorer plugin. - /// - public sealed class DefaultAccount : Account - { - /// - /// See . - /// - public override string Alias { get; set; } - - /// - /// See . - /// - public override string AccountName { get; set; } - - /// - /// See . - /// - public override string BatchServiceUrl { get; set; } - - /// - /// See . - /// - [XmlIgnore] - public override string Key - { - get - { - string result; - if (this.SecureKey == null) - { - result = null; - } - else - { - result = Encoding.ASCII.GetString(ProtectedData.Unprotect(this.SecureKey, null, DataProtectionScope.CurrentUser)); - } - - return result; - } - set - { - if (value != null) - { - this.SecureKey = ProtectedData.Protect(Encoding.ASCII.GetBytes(value), null, DataProtectionScope.CurrentUser); - } - else - { - this.SecureKey = null; - } - } - } - - /// - /// The secure (encrypted) key which will be written to disk. - /// - public byte[] SecureKey { get; set; } - - /// - /// See . - /// - public override Guid UniqueIdentifier { get; set; } - - public DefaultAccount(IAccountManager parentAccountManager) : base(parentAccountManager) - { - this.UniqueIdentifier = Guid.NewGuid(); - } - } -} diff --git a/CSharp/BatchExplorer/Plugins/AccountPlugin/DefaultAccountDialogViewModel.cs b/CSharp/BatchExplorer/Plugins/AccountPlugin/DefaultAccountDialogViewModel.cs deleted file mode 100644 index a0e15e4b..00000000 --- a/CSharp/BatchExplorer/Plugins/AccountPlugin/DefaultAccountDialogViewModel.cs +++ /dev/null @@ -1,98 +0,0 @@ -//Copyright (c) Microsoft Corporation - -using Microsoft.Azure.BatchExplorer.Helpers; -using Microsoft.Azure.BatchExplorer.Models; -using Microsoft.Azure.BatchExplorer.PluginInterfaces.AccountPlugin; - -namespace Microsoft.Azure.BatchExplorer.Plugins.AccountPlugin -{ - public class DefaultAccountDialogViewModel : EntityBase, IAccountAdder, IAccountEditor - { - private readonly Account account; - - /// - /// Use this constructor when creating a dialog that will be used on an edited account - /// - /// the existing account to be edited - public DefaultAccountDialogViewModel(Account account) - { - this.account = account; - } - - /// - /// The Alias of the account - /// - public string Alias - { - get { return this.account.Alias; } - set - { - this.account.Alias = value; - FirePropertyChangedEvent("Alias"); - } - } - /// - /// The Name of the account - /// - public string AccountName - { - get { return this.account.AccountName; } - set - { - this.account.AccountName = value; - FirePropertyChangedEvent("AccountName"); - } - } - /// - /// The Key of the account - /// - public string Key - { - get { return this.account.Key; } - set - { - this.account.Key = value; - FirePropertyChangedEvent("Key"); - } - } - /// - /// The Batch Service Url of the account. - /// - public string BatchServiceUrl - { - get { return this.account.BatchServiceUrl; } - set - { - this.account.BatchServiceUrl = value; - FirePropertyChangedEvent("BatchServiceUrl"); - } - } - - #region IAccountAdder - - /// - /// See . - /// - /// - public Account CreateAccountForAdd() - { - return this.account; - } - - #endregion - - #region IAccountEditor - - /// - /// See . - /// - /// - public Account CreateAccountForEdit() - { - return this.account; - } - - #endregion - } - -} diff --git a/CSharp/BatchExplorer/Plugins/AccountPlugin/DefaultAccountManagementControl.xaml b/CSharp/BatchExplorer/Plugins/AccountPlugin/DefaultAccountManagementControl.xaml deleted file mode 100644 index 6f2f5d07..00000000 --- a/CSharp/BatchExplorer/Plugins/AccountPlugin/DefaultAccountManagementControl.xaml +++ /dev/null @@ -1,58 +0,0 @@ - - - - - - - - - - - - - - - - - - - - diff --git a/CSharp/BatchExplorer/Plugins/AccountPlugin/DefaultAccountManagementControl.xaml.cs b/CSharp/BatchExplorer/Plugins/AccountPlugin/DefaultAccountManagementControl.xaml.cs deleted file mode 100644 index cb08482e..00000000 --- a/CSharp/BatchExplorer/Plugins/AccountPlugin/DefaultAccountManagementControl.xaml.cs +++ /dev/null @@ -1,22 +0,0 @@ -//Copyright (c) Microsoft Corporation - -using System.Windows.Controls; - -namespace Microsoft.Azure.BatchExplorer.Plugins.AccountPlugin -{ - /// - /// Interaction logic for AccountManagementControl.xaml - /// - public partial class DefaultAccountManagementControl : UserControl - { - private readonly DefaultAccountDialogViewModel viewModel; - - public DefaultAccountManagementControl(DefaultAccountDialogViewModel viewModel) - { - InitializeComponent(); - - this.viewModel = viewModel; - this.DataContext = this.viewModel; - } - } -} diff --git a/CSharp/BatchExplorer/Plugins/AccountPlugin/DefaultAccountManager.cs b/CSharp/BatchExplorer/Plugins/AccountPlugin/DefaultAccountManager.cs deleted file mode 100644 index c8dbd8cf..00000000 --- a/CSharp/BatchExplorer/Plugins/AccountPlugin/DefaultAccountManager.cs +++ /dev/null @@ -1,341 +0,0 @@ -//Copyright (c) Microsoft Corporation - -namespace Microsoft.Azure.BatchExplorer.Plugins.AccountPlugin -{ - using System; - using System.Collections.Generic; - using System.Collections.ObjectModel; - using System.ComponentModel.Composition; - using System.Globalization; - using System.IO; - using System.Linq; - using System.Text.RegularExpressions; - using System.Threading.Tasks; - using System.Windows; - using System.Xml.Serialization; - using Microsoft.Azure.BatchExplorer.Helpers; - using Microsoft.Azure.BatchExplorer.Models; - using Microsoft.Azure.BatchExplorer.PluginInterfaces.AccountPlugin; - using Microsoft.Azure.BatchExplorer.Plugins.LegacyAccountSupport; - - - /// - /// See . - /// - [Export(typeof(IAccountManager))] - [ExportMetadata("Name", "Default Account Manager")] - public class DefaultAccountManager : EntityBase, IAccountManager - { - private int editingIndex; - - /// - /// Default constructor - /// - public DefaultAccountManager() - { - this.Accounts = new ObservableCollection(); - this.OperationFactory = new DefaultAccountOperationFactory(this); - this.editingIndex = -1; - } - - #region IAccountManager - - /// - /// See . - /// - public IAccountOperationFactory OperationFactory { get; private set; } - - /// - /// See . - /// - public ObservableCollection Accounts { get; private set; } - - /// - /// See . - /// - public bool HasAccounts - { - get { return this.Accounts.Any(); } - } - - /// - /// See . - /// - public bool CanDeleteAccount - { - get { return true; } - } - - /// - /// See . - /// - public bool CanEditAccount - { - get { return true; } - } - - /// - /// See . - /// - public Task InitalizeAsync() - { - return this.LoadAccountsAsync(); - } - - /// - /// See . - /// - /// The account to be removed. - /// The asynchronous operation. - public async Task DeleteAccountAsync(Account account) - { - if (!this.Accounts.Contains(account)) - { - throw new Exception("Attept to remove unrecognized account"); - } - Account tempAccount = null; - //We are waiting on an account being edited, so we need to make sure our editing index is still accurate after the move - if (this.editingIndex >= 0) - { - tempAccount = this.Accounts[this.editingIndex]; - } - this.Accounts.Remove(account); - - //We were tracking an account before the remove, so update the edit index - if (tempAccount != null) - { - this.editingIndex = this.Accounts.IndexOf(tempAccount); - } - - this.FirePropertyChangedEvent("HasAccounts"); - await this.SaveAccountsAsync().ConfigureAwait(false); - } - - /// - /// See . - /// - /// The account to be added. - /// The asynchronous operation. - public async Task AddAccountAsync(Account account) - { - if (this.Accounts.Contains(account)) - { - //TODO: Should this be a custom exception type? - throw new Exception(string.Format(CultureInfo.CurrentCulture, "Account with alias {0} has already been added", account.Alias)); - } - - if (!(account is DefaultAccount)) - { - throw new Exception(string.Format("Account type: {0}, expected Type: {1}", account.GetType().Name, typeof(DefaultAccount).Name)); - } - - this.Accounts.Add(account); - this.FirePropertyChangedEvent("HasAccounts"); - - await this.SaveAccountsAsync().ConfigureAwait(false); - } - - /// - /// See . - /// - /// The account to clone. - /// A deep clone of the account. - public Task CloneAccountForEditAsync(Account account) - { - this.editingIndex = this.Accounts.IndexOf(account); - if (this.editingIndex < 0) - { - throw new Exception("Attempt was made to edit unrecognized account"); - } - - var clone = new DefaultAccount(this) - { - AccountName = account.AccountName, - Alias = account.Alias, - Key = account.Key, - BatchServiceUrl = account.BatchServiceUrl, - UniqueIdentifier = account.UniqueIdentifier, - ParentAccountManager = this - }; - return Task.FromResult(clone); - } - - /// - /// See . - /// - /// The edited clone. - /// The asynchronous operation. - public async Task CommitEditAsync(Account account) - { - if (this.editingIndex < 0) - { - throw new Exception("Commit was called but no account was selected for edit"); - } - bool accountAlreadyExists = this.Accounts.Any(acct => acct.Equals(account) && acct.UniqueIdentifier != account.UniqueIdentifier); - if (accountAlreadyExists) - { - throw new Exception(string.Format(CultureInfo.CurrentCulture, "Account with alias {0} has already been added", account.Alias)); - } - - //Replace the selected account with the cloned account - this.Accounts[this.editingIndex] = account; - this.Accounts.RemoveAt(this.editingIndex); - this.Accounts.Insert(this.editingIndex, account); - this.editingIndex = -1; - await this.SaveAccountsAsync().ConfigureAwait(false); - } - - #endregion - - #region Private methods - - /// - /// Load the accounts from the accounts file - /// - private async Task LoadAccountsAsync() - { - string accountFileName = GetAccountFileName(); - FileInfo fileInfo = new FileInfo(accountFileName); - - if (!fileInfo.Exists || fileInfo.Length == 0) - { - using (File.Create(accountFileName)) - { - } - await this.SaveAccountsAsync().ConfigureAwait(false); - } - - //Try first to deserialize using the new account deserialization mechanism, if that fails, fall back to the old way - bool writeBackToFile = false; - try - { - XmlSerializer x = new XmlSerializer(typeof(DefaultAccountSerializationContainer)); - using (StreamReader reader = new StreamReader(accountFileName)) - { - object deserializedObject = x.Deserialize(reader); //TODO: This is not technically async... - - DefaultAccountSerializationContainer accountContainer = (DefaultAccountSerializationContainer)deserializedObject; - - List accounts = accountContainer.GetAccountCollection(this); - - //Update accounts to the new URI format if required - writeBackToFile = this.UpdateAccountsToNewUriFormat(accounts); - - this.Accounts = new ObservableCollection(accounts); - } - } - catch (InvalidOperationException) - { - writeBackToFile = true; - XmlSerializer x = new XmlSerializer(typeof(LegacyAccountManager)); - using (StreamReader reader = new StreamReader(accountFileName)) - { - object deserializedObject = x.Deserialize(reader); //TODO: This is not technically async... - - LegacyAccountManager legacyAccountManager = (LegacyAccountManager)deserializedObject; - this.Accounts = new ObservableCollection(legacyAccountManager.CreateAccounts(this)); - } - } - - //One time write back to change format of the file - if (writeBackToFile) - { - await this.SaveAccountsAsync().ConfigureAwait(false); - } - } - - - private bool UpdateAccountsToNewUriFormat(IEnumerable accounts) - { - bool hasUpdatedAnAccount = false; - - foreach (Account account in accounts) - { - if (String.IsNullOrEmpty(account.BatchServiceUrl) || String.IsNullOrEmpty(account.AccountName)) - { - // Skip the bad setting of old accounts - continue; - } - - //The new format requires the account name to be in the Url - if (!account.BatchServiceUrl.Contains(account.AccountName)) - { - int doubleSlashIndex = account.BatchServiceUrl.IndexOf(@"//", System.StringComparison.Ordinal); - if (doubleSlashIndex != -1) - { - hasUpdatedAnAccount = true; - - string prefix = account.BatchServiceUrl.Substring(0, doubleSlashIndex + 2); - string postfix = account.BatchServiceUrl.Substring(doubleSlashIndex + 2, account.BatchServiceUrl.Length - prefix.Length); - - //Remove trailing slashes from postfix - postfix = postfix.Trim('/'); - - //Regex to match an IP endpoint - Regex ipMatchingRegex = new Regex(@"^(?:[0-9]{1,3}\.){3}[0-9]{1,3}(?::[0-9]+)?$"); - - //check if this is a path or a host style URL - if (!ipMatchingRegex.Match(postfix).Success) - { - //Host style - postfix = account.AccountName + "." + postfix; - } - else - { - //Path style - postfix = postfix + "/" + account.AccountName; - } - - string updatedUrl = prefix + postfix; - account.BatchServiceUrl = updatedUrl; - } - } - } - - return hasUpdatedAnAccount; - } - - /// - /// Save the accounts to the account file - /// - private async Task SaveAccountsAsync() - { - string fileName = GetAccountFileName(); - - IEnumerable defaultAccountList = this.Accounts.Cast(); - DefaultAccountSerializationContainer serializationContainer = new DefaultAccountSerializationContainer(defaultAccountList); - - XmlSerializer x = new XmlSerializer(typeof(DefaultAccountSerializationContainer)); - using (var writer = new StreamWriter(fileName, false)) - { - x.Serialize(writer, serializationContainer); - await writer.FlushAsync().ConfigureAwait(false); - } - } - - /// - /// Gets the magic string representing the path to the account file - /// - /// - private static string GetAccountFileName() - { - const string fileName = "accounts.xml"; - - if (String.IsNullOrEmpty(Microsoft.Azure.BatchExplorer.Helpers.Common.LocalAppDataDirectory)) - { - MessageBox.Show("LocalAppData environment variable is not set", "Azure Batch Explorer", MessageBoxButton.OK); - throw new InvalidProgramException("LocalAppData not defined in environment"); - } - - // create the directory if necessary - string fullDirectoryPath = Path.Combine( - Microsoft.Azure.BatchExplorer.Helpers.Common.LocalAppDataDirectory, - Microsoft.Azure.BatchExplorer.Helpers.Common.LocalAppDataSubfolder); - Directory.CreateDirectory(fullDirectoryPath); - - return Path.Combine(fullDirectoryPath, fileName); - } - - #endregion - } -} diff --git a/CSharp/BatchExplorer/Plugins/AccountPlugin/DefaultAccountOperationFactory.cs b/CSharp/BatchExplorer/Plugins/AccountPlugin/DefaultAccountOperationFactory.cs deleted file mode 100644 index 9b94c71c..00000000 --- a/CSharp/BatchExplorer/Plugins/AccountPlugin/DefaultAccountOperationFactory.cs +++ /dev/null @@ -1,48 +0,0 @@ -//Copyright (c) Microsoft Corporation - -using Microsoft.Azure.BatchExplorer.Models; -using Microsoft.Azure.BatchExplorer.PluginInterfaces.AccountPlugin; - -namespace Microsoft.Azure.BatchExplorer.Plugins.AccountPlugin -{ - public class DefaultAccountOperationFactory : IAccountOperationFactory - { - private readonly DefaultAccountManager parentAccountManager; - - public DefaultAccountOperationFactory(DefaultAccountManager parentAccountManager) - { - this.parentAccountManager = parentAccountManager; - } - - /// - /// See . - /// - /// - public AccountManagementAddOperation CreateAddAccountOperation() - { - Account account = new DefaultAccount(this.parentAccountManager); //Create an empty account to be added. - - DefaultAccountDialogViewModel accountAdder = new DefaultAccountDialogViewModel(account); - - DefaultAccountManagementControl control = new DefaultAccountManagementControl(accountAdder); - AccountManagementAddOperation operation = new AccountManagementAddOperation(accountAdder, control); - - return operation; - } - - /// - /// See . - /// - /// The account to edit. - /// - public AccountManagementEditOperation CreateEditAccountOperation(Account account) - { - DefaultAccountDialogViewModel accountEditor = new DefaultAccountDialogViewModel(account); - - DefaultAccountManagementControl control = new DefaultAccountManagementControl(accountEditor); - AccountManagementEditOperation operation = new AccountManagementEditOperation(accountEditor, control); - - return operation; - } - } -} diff --git a/CSharp/BatchExplorer/Plugins/AccountPlugin/DefaultAccountSerializationContainer.cs b/CSharp/BatchExplorer/Plugins/AccountPlugin/DefaultAccountSerializationContainer.cs deleted file mode 100644 index 41cbac54..00000000 --- a/CSharp/BatchExplorer/Plugins/AccountPlugin/DefaultAccountSerializationContainer.cs +++ /dev/null @@ -1,40 +0,0 @@ -//Copyright (c) Microsoft Corporation - -using System.Collections.Generic; -using Microsoft.Azure.BatchExplorer.Models; -using Microsoft.Azure.BatchExplorer.PluginInterfaces.AccountPlugin; - -namespace Microsoft.Azure.BatchExplorer.Plugins.AccountPlugin -{ - public class DefaultAccountSerializationContainer - { - public List Accounts { get; private set; } - - public DefaultAccountSerializationContainer() - { - this.Accounts = new List(); - } - - public DefaultAccountSerializationContainer(IEnumerable accounts) - { - this.Accounts = new List(); - - foreach (DefaultAccount account in accounts) - { - this.Accounts.Add(new SerializableAccount(account)); - } - } - - public List GetAccountCollection(IAccountManager parentAccountManager) - { - List results = new List(); - - foreach (SerializableAccount serializableAccount in Accounts) - { - results.Add(serializableAccount.CreateAccountFromSerialization(parentAccountManager)); - } - - return results; - } - } -} diff --git a/CSharp/BatchExplorer/Plugins/AccountPlugin/SerializableAccount.cs b/CSharp/BatchExplorer/Plugins/AccountPlugin/SerializableAccount.cs deleted file mode 100644 index 36878f2d..00000000 --- a/CSharp/BatchExplorer/Plugins/AccountPlugin/SerializableAccount.cs +++ /dev/null @@ -1,53 +0,0 @@ -//Copyright (c) Microsoft Corporation - -using System; -using System.Xml.Serialization; -using Microsoft.Azure.BatchExplorer.PluginInterfaces.AccountPlugin; - -namespace Microsoft.Azure.BatchExplorer.Plugins.AccountPlugin -{ - public sealed class SerializableAccount - { - public string Alias { get; set; } - - public string AccountName { get; set; } - - public string BatchServiceUrl { get; set; } - - [XmlIgnore] - public string Key { get; set; } - - public byte[] SecureKey { get; set; } - - public Guid UniqueIdentifier { get; set; } - - public SerializableAccount() - { - } - - public SerializableAccount(DefaultAccount account) - { - this.Alias = account.Alias; - this.AccountName = account.AccountName; - this.BatchServiceUrl = account.BatchServiceUrl; - this.Key = account.Key; - this.SecureKey = account.SecureKey; - this.UniqueIdentifier = account.UniqueIdentifier; - } - - public DefaultAccount CreateAccountFromSerialization(IAccountManager parentAccountManager) - { - DefaultAccount account = new DefaultAccount(parentAccountManager) - { - AccountName = this.AccountName, - Alias = this.Alias, - BatchServiceUrl = this.BatchServiceUrl, - Key = this.Key, - SecureKey = this.SecureKey, - UniqueIdentifier = this.UniqueIdentifier - }; - - return account; - } - } -} diff --git a/CSharp/BatchExplorer/Plugins/LegacyAccountSupport/LegacyAccount.cs b/CSharp/BatchExplorer/Plugins/LegacyAccountSupport/LegacyAccount.cs deleted file mode 100644 index 88652737..00000000 --- a/CSharp/BatchExplorer/Plugins/LegacyAccountSupport/LegacyAccount.cs +++ /dev/null @@ -1,33 +0,0 @@ -//Copyright (c) Microsoft Corporation - -using System; -using System.Xml.Serialization; -using Microsoft.Azure.BatchExplorer.Models; -using Microsoft.Azure.BatchExplorer.PluginInterfaces.AccountPlugin; -using Microsoft.Azure.BatchExplorer.Plugins.AccountPlugin; - -namespace Microsoft.Azure.BatchExplorer.Plugins.LegacyAccountSupport -{ - //TODO: Remove this in a future release - [XmlType("Account")] - public class LegacyAccount - { - public string Alias { get; set; } - public string AccountName { get; set; } - public string BatchServiceUrl { get; set; } - public byte[] SecureKey { get; set; } - public Guid UniqueIdentifier { get; set; } - - public Account ToAccount(IAccountManager manager) - { - return new DefaultAccount(manager) - { - AccountName = this.AccountName, - Alias = this.Alias, - BatchServiceUrl = this.BatchServiceUrl, - SecureKey = this.SecureKey, - UniqueIdentifier = this.UniqueIdentifier - }; - } - } -} diff --git a/CSharp/BatchExplorer/Plugins/LegacyAccountSupport/LegacyAccountManager.cs b/CSharp/BatchExplorer/Plugins/LegacyAccountSupport/LegacyAccountManager.cs deleted file mode 100644 index 7fdc01bb..00000000 --- a/CSharp/BatchExplorer/Plugins/LegacyAccountSupport/LegacyAccountManager.cs +++ /dev/null @@ -1,24 +0,0 @@ -//Copyright (c) Microsoft Corporation - -using System.Collections.Generic; -using System.Linq; -using System.Xml.Serialization; -using Microsoft.Azure.BatchExplorer.Models; -using Microsoft.Azure.BatchExplorer.PluginInterfaces.AccountPlugin; - -namespace Microsoft.Azure.BatchExplorer.Plugins.LegacyAccountSupport -{ - //TODO: Remove this in a future release - [XmlRoot("AccountManager")] - public class LegacyAccountManager - { - public bool IsBusy { get; set; } - public List Accounts { get; set; } - - public List CreateAccounts(IAccountManager manager) - { - List results = this.Accounts.Select(a => a.ToAccount(manager)).ToList(); - return results; - } - } -} diff --git a/CSharp/BatchExplorer/Properties/AssemblyInfo.cs b/CSharp/BatchExplorer/Properties/AssemblyInfo.cs deleted file mode 100644 index 39504404..00000000 --- a/CSharp/BatchExplorer/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,55 +0,0 @@ -//Copyright (c) Microsoft Corporation - -using System.Reflection; -using System.Runtime.InteropServices; -using System.Windows; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("Azure Batch Explorer")] -[assembly: AssemblyDescription("A sample UI tool for simple navagation of Azure Batch objects")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("Microsoft Corporation")] -[assembly: AssemblyProduct("Azure Batch Explorer")] -[assembly: AssemblyCopyright("Copyright © Microsoft")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -//In order to begin building localizable applications, set -//CultureYouAreCodingWith in your .csproj file -//inside a . For example, if you are using US english -//in your source files, set the to en-US. Then uncomment -//the NeutralResourceLanguage attribute below. Update the "en-US" in -//the line below to match the UICulture setting in the project file. - -//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] - - -[assembly: ThemeInfo( - ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located - //(used if a resource is not found in the page, - // or application resource dictionaries) - ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located - //(used if a resource is not found in the page, - // app, or any theme specific resource dictionaries) -)] - - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/CSharp/BatchExplorer/Properties/Resources.Designer.cs b/CSharp/BatchExplorer/Properties/Resources.Designer.cs deleted file mode 100644 index 2e561db1..00000000 --- a/CSharp/BatchExplorer/Properties/Resources.Designer.cs +++ /dev/null @@ -1,63 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.18444 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace Microsoft.Azure.BatchExplorer.Properties { - using System; - - - /// - /// A strongly-typed resource class, for looking up localized strings, etc. - /// - // This class was auto-generated by the StronglyTypedResourceBuilder - // class via a tool like ResGen or Visual Studio. - // To add or remove a member, edit your .ResX file then rerun ResGen - // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class Resources { - - private static global::System.Resources.ResourceManager resourceMan; - - private static global::System.Globalization.CultureInfo resourceCulture; - - [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal Resources() { - } - - /// - /// Returns the cached ResourceManager instance used by this class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager { - get { - if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Microsoft.Azure.BatchExplorer.Properties.Resources", typeof(Resources).Assembly); - resourceMan = temp; - } - return resourceMan; - } - } - - /// - /// Overrides the current thread's CurrentUICulture property for all - /// resource lookups using this strongly typed resource class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture { - get { - return resourceCulture; - } - set { - resourceCulture = value; - } - } - } -} diff --git a/CSharp/BatchExplorer/Properties/Resources.resx b/CSharp/BatchExplorer/Properties/Resources.resx deleted file mode 100644 index af7dbebb..00000000 --- a/CSharp/BatchExplorer/Properties/Resources.resx +++ /dev/null @@ -1,117 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/CSharp/BatchExplorer/Properties/Settings.Designer.cs b/CSharp/BatchExplorer/Properties/Settings.Designer.cs deleted file mode 100644 index bda219b0..00000000 --- a/CSharp/BatchExplorer/Properties/Settings.Designer.cs +++ /dev/null @@ -1,26 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.18444 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace Microsoft.Azure.BatchExplorer.Properties { - - - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] - internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { - - private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); - - public static Settings Default { - get { - return defaultInstance; - } - } - } -} diff --git a/CSharp/BatchExplorer/Properties/Settings.settings b/CSharp/BatchExplorer/Properties/Settings.settings deleted file mode 100644 index 033d7a5e..00000000 --- a/CSharp/BatchExplorer/Properties/Settings.settings +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/CSharp/BatchExplorer/README.md b/CSharp/BatchExplorer/README.md deleted file mode 100644 index 0009533c..00000000 --- a/CSharp/BatchExplorer/README.md +++ /dev/null @@ -1,32 +0,0 @@ -## Azure Batch Explorer - -**Note:** [Batch Labs](https://github.com/Azure/BatchLabs) is a cross-platform client tool for browsing Azure Batch resources. Batch Labs is supported by Microsoft and is the preferred client tool to use with Azure Batch. Batch Explorer will continue to exist in this repository only as a sample and will not be updated to expose the latest features of Azure Batch. We will not be accepting new feature contributions. - -![Azure Batch Explorer][1]
- -The **Azure Batch Explorer** is a Windows Presentation Foundation (WPF) application used for viewing, managing, monitoring, and debugging entities within an Azure Batch account. While this application is not officially supported, it is updated periodically, and is an invaluable tool not only for those new to Batch, but anyone developing or managing Batch applications. - -Some features of the Batch Explorer: - -- List Batch entities like pools, compute nodes, jobs, tasks, and schedules, and view their properties -- View task status and execution information -- List and download files from compute nodes -- Create user accounts on compute nodes and download RDP files for remote connection -- Resize pools and reboot, reimage, or delete compute nodes -- Create and delete pools, jobs, tasks, and job schedules -- Monitor task execution with the *Heat Map* - -### Using the Batch Explorer - -To manage entities in your Batch account with the Batch Explorer, you must first configure it by adding your account information. **Build** and **run** the application using *Visual Studio 2015 or above*, then perform the following to add your account information and connect to the Batch service: - -1. Click **Accounts** > **Add** > **Default Account Manager** -2. In the *Add Account* dialog that is displayed, add an **Account Alias**, a unique identifier for this account within Batch Explorer -3. Enter the **Batch Service URL**, **Account** name, and account **Key** in the other three textboxes. These values can be found within the Batch Account blade within the [Azure Portal][portal]. -4. Click **OK**. -5. Click **Accounts** > **Connect** > **Default Account Manager**, followed by your account name, to connect the Batch Explorer to your account. - -You may now start exploring the entities within your Batch account. You can start by refreshing an entity type via the **Refresh** menu, selecting one in the top-left pane, then viewing its details in the top- and middle-right panes. - -[portal]: http://portal.azure.com -[1]: BatchExplorer.jpg "Batch solution workflow (full diagram)" diff --git a/CSharp/BatchExplorer/Service/BatchService.cs b/CSharp/BatchExplorer/Service/BatchService.cs deleted file mode 100644 index 8d933c3e..00000000 --- a/CSharp/BatchExplorer/Service/BatchService.cs +++ /dev/null @@ -1,496 +0,0 @@ -//Copyright (c) Microsoft Corporation - -namespace Microsoft.Azure.BatchExplorer.Service -{ - using System; - using System.Threading.Tasks; - using Microsoft.Azure.Batch; - using Microsoft.Azure.Batch.Common; - using Microsoft.Azure.BatchExplorer.Models; - using BatchSharedKeyCredential=Microsoft.Azure.Batch.Auth.BatchSharedKeyCredentials; - - /// - /// Manages communication with the Batch service - /// - public class BatchService : IDisposable - { - public BatchSharedKeyCredential Credentials { get; private set; } - - private BatchClient Client { get; set; } - private readonly IRetryPolicy retryPolicy; - private bool disposed; - - public BatchService(BatchSharedKeyCredential credentials) - { - this.Client = BatchClient.Open(credentials); - this.Credentials = credentials; - this.retryPolicy = new ExponentialRetry(TimeSpan.FromSeconds(5), 3); - - this.Client.CustomBehaviors.Add(new RetryPolicyProvider(this.retryPolicy)); - } - - #region JobSchedule related operations - - /// - /// Returns a list of JobSchedules - /// - /// - public IPagedEnumerable ListJobSchedules(DetailLevel detailLevel = null) - { - return this.Client.JobScheduleOperations.ListJobSchedules(detailLevel); - } - - /// - /// Creates a job schedule with the specified options. - /// - /// The options describing the job schedule to create. - /// - public async Task CreateJobScheduleAsync(CreateJobScheduleOptions options) - { - CloudJobSchedule unboundJobSchedule = this.Client.JobScheduleOperations.CreateJobSchedule(); - unboundJobSchedule.Id = options.JobScheduleId; - - PoolInformation poolInformation = new PoolInformation(); - if (options.AutoPoolOptions.UseAutoPool.HasValue && options.AutoPoolOptions.UseAutoPool.Value) - { - AutoPoolSpecification autoPoolSpecification = new AutoPoolSpecification() - { - AutoPoolIdPrefix = options.AutoPoolOptions.AutoPoolPrefix, - KeepAlive = options.AutoPoolOptions.KeepAlive, - PoolLifetimeOption = (PoolLifetimeOption)Enum.Parse(typeof(PoolLifetimeOption), options.AutoPoolOptions.LifeTimeOption), - PoolSpecification = new PoolSpecification() - { - CloudServiceConfiguration = new CloudServiceConfiguration(options.AutoPoolOptions.OSFamily), - VirtualMachineSize = options.AutoPoolOptions.VirutalMachineSize, - TargetDedicatedComputeNodes = options.AutoPoolOptions.TargetDedicated, - TargetLowPriorityComputeNodes = options.AutoPoolOptions.TargetLowPriority - } - }; - - poolInformation.AutoPoolSpecification = autoPoolSpecification; - } - else - { - poolInformation.PoolId = options.PoolId; - } - - unboundJobSchedule.JobSpecification = new JobSpecification() - { - Priority = options.Priority, - PoolInformation = poolInformation - }; - - // TODO: These are read only - unboundJobSchedule.JobSpecification.Constraints = new JobConstraints(options.MaxWallClockTime, options.MaxRetryCount); - - Schedule schedule = new Schedule() - { - DoNotRunAfter = options.DoNotRunAfter, - DoNotRunUntil = options.DoNotRunUntil, - RecurrenceInterval = options.RecurrenceInterval, - StartWindow = options.StartWindow - }; - unboundJobSchedule.Schedule = schedule; - - if (options.CreateJobManager.HasValue && options.CreateJobManager.Value == true) - { - JobManagerTask jobManager = new JobManagerTask() - { - CommandLine = options.JobManagerOptions.CommandLine, - KillJobOnCompletion = options.JobManagerOptions.KillOnCompletion, - Id = options.JobManagerOptions.JobManagerId - }; - - jobManager.Constraints = new TaskConstraints(options.JobManagerOptions.MaxTaskWallClockTime, options.JobManagerOptions.RetentionTime, options.JobManagerOptions.MaxTaskRetryCount); - - unboundJobSchedule.JobSpecification.JobManagerTask = jobManager; - } - - await unboundJobSchedule.CommitAsync(); - } - - #endregion - - #region Pool related operations - - /// - /// Returns a list of pools - /// - /// - public IPagedEnumerable ListPools(DetailLevel detailLevel = null) - { - return this.Client.PoolOperations.ListPools(detailLevel); - } - - public Task GetPoolAsync(string poolId) - { - return this.Client.PoolOperations.GetPoolAsync(poolId); - } - - /// - /// Creates a pool. - /// - /// - public async Task CreatePoolAsync( - string poolId, - string virtualMachineSize, - int? targetDedicated, - int? targetLowPriority, - string autoScaleFormula, - bool communicationEnabled, - string subnetId, - CloudServiceConfigurationOptions cloudServiceConfigurationOptions, - VirtualMachineConfigurationOptions virtualMachineConfigurationOptions, - int maxTasksPerComputeNode, - TimeSpan? timeout, - StartTaskOptions startTask) - { - CloudPool unboundPool; - - if (cloudServiceConfigurationOptions != null) - { - unboundPool = this.Client.PoolOperations.CreatePool( - poolId, - virtualMachineSize: virtualMachineSize, - cloudServiceConfiguration: new CloudServiceConfiguration(cloudServiceConfigurationOptions.OSFamily, cloudServiceConfigurationOptions.OSVersion), - targetDedicatedComputeNodes: targetDedicated, - targetLowPriorityComputeNodes: targetLowPriority); - } - else if (virtualMachineConfigurationOptions != null) - { - unboundPool = this.Client.PoolOperations.CreatePool( - poolId, - virtualMachineSize: virtualMachineSize, - virtualMachineConfiguration: new VirtualMachineConfiguration( - nodeAgentSkuId: virtualMachineConfigurationOptions.NodeAgentSkuId, - imageReference: new ImageReference( - publisher: virtualMachineConfigurationOptions.Publisher, - offer: virtualMachineConfigurationOptions.Offer, - sku: virtualMachineConfigurationOptions.SkuId, - version: virtualMachineConfigurationOptions.Version)) - { - WindowsConfiguration = virtualMachineConfigurationOptions.EnableWindowsAutomaticUpdates.HasValue ? - new WindowsConfiguration(virtualMachineConfigurationOptions.EnableWindowsAutomaticUpdates) : - null - }, - targetDedicatedComputeNodes: targetDedicated, - targetLowPriorityComputeNodes: targetLowPriority); - } - else - { - throw new ArgumentException("Must set cloudServiceConfiguration or virtualMachineConfiguration"); - } - - unboundPool.InterComputeNodeCommunicationEnabled = communicationEnabled; - unboundPool.ResizeTimeout = timeout; - unboundPool.MaxTasksPerComputeNode = maxTasksPerComputeNode; - - if (!string.IsNullOrEmpty(subnetId)) - { - unboundPool.NetworkConfiguration = new NetworkConfiguration - { - SubnetId = subnetId - }; - } - - if (!string.IsNullOrEmpty(autoScaleFormula)) - { - unboundPool.AutoScaleEnabled = true; - unboundPool.AutoScaleFormula = autoScaleFormula; - } - - if (startTask != null) - { - unboundPool.StartTask = new StartTask - { - CommandLine = startTask.CommandLine, - UserIdentity = new UserIdentity(new AutoUserSpecification( - elevationLevel: startTask.RunElevated ? ElevationLevel.Admin : ElevationLevel.NonAdmin)), - ResourceFiles = startTask.ResourceFiles.ConvertAll(f => new ResourceFile(f.BlobSource, f.FilePath)), - WaitForSuccess = true, - }; - } - - await unboundPool.CommitAsync(); - } - - public async Task ResizePool( - string poolId, - int targetDedicated, - int targetLowPriority, - TimeSpan? timeout, - ComputeNodeDeallocationOption? deallocationOption) - { - var pool = await this.GetPoolAsync(poolId); - if (pool.AutoScaleEnabled.HasValue && pool.AutoScaleEnabled.Value) - { - await this.Client.PoolOperations.DisableAutoScaleAsync(poolId); - if (!await this.WaitForResizingOperationToFinish(poolId)) - { - throw new InvalidOperationException("Autoscale disable operation is already in progress. Please try again after sometime to Resize the pool."); - } - } - - await this.Client.PoolOperations.ResizePoolAsync(poolId, targetDedicated, targetLowPriority, timeout, deallocationOption); - } - - public async Task EnableAutoScale(string poolId, string autoScaleformula) - { - await this.Client.PoolOperations.EnableAutoScaleAsync(poolId, autoScaleformula); - } - - public IPagedEnumerable ListNodeAgentSkus() - { - return this.Client.PoolOperations.ListNodeAgentSkus(); - } - - /// - /// Evaluates the autoscale formula. - /// - /// The pool identifier. - /// The autoscale formula. - /// Result of evaluation - public async Task EvaluateAutoScaleFormula(string poolId, string autoScaleformula) - { - AutoScaleRun eval = await this.Client.PoolOperations.EvaluateAutoScaleAsync(poolId, autoScaleformula); - - if (eval.Error == null) - { - return eval.Results; - } - else - { - return eval.Error.Message; - } - } - - #endregion - - #region Job related operations - - public async Task CreateJobAsync(CreateJobOptions createJobOptions) - { - CloudJob unboundJob = this.Client.JobOperations.CreateJob(); - - unboundJob.Id = createJobOptions.JobId; - unboundJob.Priority = createJobOptions.Priority; - unboundJob.Constraints = new JobConstraints(createJobOptions.MaxWallClockTime, createJobOptions.MaxRetryCount); - - PoolInformation poolInformation = new PoolInformation(); - if (createJobOptions.AutoPoolOptions.UseAutoPool.HasValue && createJobOptions.AutoPoolOptions.UseAutoPool.Value) - { - AutoPoolSpecification autoPoolSpecification = new AutoPoolSpecification() - { - AutoPoolIdPrefix = createJobOptions.AutoPoolOptions.AutoPoolPrefix, - KeepAlive = createJobOptions.AutoPoolOptions.KeepAlive, - PoolLifetimeOption = (PoolLifetimeOption)Enum.Parse(typeof(PoolLifetimeOption), createJobOptions.AutoPoolOptions.LifeTimeOption), - PoolSpecification = new PoolSpecification() - { - CloudServiceConfiguration = new CloudServiceConfiguration(createJobOptions.AutoPoolOptions.OSFamily), - VirtualMachineSize = createJobOptions.AutoPoolOptions.VirutalMachineSize, - TargetDedicatedComputeNodes = createJobOptions.AutoPoolOptions.TargetDedicated, - TargetLowPriorityComputeNodes = createJobOptions.AutoPoolOptions.TargetLowPriority - } - }; - - poolInformation.AutoPoolSpecification = autoPoolSpecification; - } - else - { - poolInformation.PoolId = createJobOptions.PoolId; - } - - unboundJob.PoolInformation = poolInformation; - - if (createJobOptions.CreateJobManager.HasValue && createJobOptions.CreateJobManager.Value == true) - { - JobManagerTask jobManager = new JobManagerTask() - { - CommandLine = createJobOptions.JobManagerOptions.CommandLine, - KillJobOnCompletion = createJobOptions.JobManagerOptions.KillOnCompletion, - Id = createJobOptions.JobManagerOptions.JobManagerId - }; - - jobManager.Constraints = new TaskConstraints( - createJobOptions.JobManagerOptions.MaxTaskWallClockTime, - createJobOptions.JobManagerOptions.RetentionTime, - createJobOptions.JobManagerOptions.MaxTaskRetryCount); - - unboundJob.JobManagerTask = jobManager; - } - - await unboundJob.CommitAsync(); - } - - /// - /// Returns a list of jobs. - /// - /// - /// - public IPagedEnumerable ListJobs(DetailLevel detailLevel = null) - { - return this.Client.JobOperations.ListJobs(detailLevel); - } - - public CloudJob GetJob(string jobId, DetailLevel detailLevel) - { - using (System.Threading.Tasks.Task getJobTask = this.GetJobAsync(jobId, detailLevel)) - { - getJobTask.Wait(); - return getJobTask.Result; - } - } - - public Task GetJobAsync(string jobId, DetailLevel detailLevel) - { - return this.Client.JobOperations.GetJobAsync(jobId, detailLevel); - } - - #endregion - - #region Task related operations - - public CloudTask GetTask(string jobId, string taskId, DetailLevel detailLevel) - { - using (Task getTaskTask = this.GetTaskAsync(jobId, taskId, detailLevel)) - { - getTaskTask.Wait(); - return getTaskTask.Result; - } - } - - public Task GetTaskAsync(string jobId, string taskId, DetailLevel detailLevel) - { - return this.Client.JobOperations.GetTaskAsync(jobId, taskId, detailLevel); - - } - - /// - /// Adds a task. - /// - /// The options describing the task to add. - /// - public async Task AddTaskAsync(AddTaskOptions options) - { - CloudTask unboundTask = new CloudTask(options.TaskId, options.CommandLine); - if (options.IsMultiInstanceTask) - { - unboundTask.MultiInstanceSettings = new MultiInstanceSettings(options.BackgroundCommand, options.InstanceNumber); - unboundTask.MultiInstanceSettings.CommonResourceFiles = options.CommonResourceFiles.ConvertAll(f => new ResourceFile(f.BlobSource, f.FilePath)); - } - unboundTask.UserIdentity = new UserIdentity(new AutoUserSpecification( - elevationLevel: options.RunElevated ? ElevationLevel.Admin : ElevationLevel.NonAdmin)); - unboundTask.Constraints = new TaskConstraints(null, null, options.MaxTaskRetryCount); - unboundTask.ResourceFiles = options.ResourceFiles.ConvertAll(f => new ResourceFile(f.BlobSource, f.FilePath)); - await this.Client.JobOperations.AddTaskAsync(options.JobId, unboundTask); - } - #endregion - - #region Node related operations - - public Task CreateNodeUserAsync(string poolId, string computeNodeId, string userName, string password, DateTime expiryTime, bool admin) - { - ComputeNodeUser user = this.Client.PoolOperations.CreateComputeNodeUser(poolId, computeNodeId); - user.Name = userName; - user.Password = password; - user.ExpiryTime = expiryTime; - user.IsAdmin = admin; - - return user.CommitAsync(); - } - - #endregion - - #region Certificate related operations - - /// - /// Returns a list of certificates - /// - /// - public IPagedEnumerable ListCertificates(DetailLevel detailLevel = null) - { - return this.Client.CertificateOperations.ListCertificates(detailLevel); - } - - public Task GetCertificateAsync(string thumbprint, string thumbprintAlgorithm) - { - return this.Client.CertificateOperations.GetCertificateAsync(thumbprint, thumbprintAlgorithm); - } - - public Task CreateCertificateAsync(CreateCertificateOptions options) - { - Certificate certificate; - - switch (options.CertificateFormat) - { - case CertificateFormat.Pfx: - certificate = this.Client.CertificateOperations.CreateCertificate(options.FilePath, options.Password); - break; - case CertificateFormat.Cer: - certificate = this.Client.CertificateOperations.CreateCertificate(options.FilePath); - break; - default: - throw new ArgumentException("Invalid certificate format " + options.CertificateFormat); - } - - return certificate.CommitAsync(); - } - - #endregion - - /// - /// Dispose of this object and all members - /// - public void Dispose() - { - this.Dispose(true); - GC.SuppressFinalize(this); - } - - ~BatchService() - { - this.Dispose(false); - } - - /// - /// Disposes of this object - /// - private void Dispose(bool disposing) - { - if (this.disposed) - { - return; - } - - if (disposing) - { - this.Client.Dispose(); - } - - this.disposed = true; - } - - private async Task WaitForResizingOperationToFinish(string poolId) - { - var pool = await this.GetPoolAsync(poolId); - - int waitForSeconds = 10; - int count = 1; - while (count < waitForSeconds) - { - if (pool.AllocationState == AllocationState.Steady) - { - return true; - } - else - { - await Task.Delay(1000); - count++; - await pool.RefreshAsync(); - } - } - - return false; - } - } -} \ No newline at end of file diff --git a/CSharp/BatchExplorer/Styles/ExplorerStyles.xaml b/CSharp/BatchExplorer/Styles/ExplorerStyles.xaml deleted file mode 100644 index 2778891d..00000000 --- a/CSharp/BatchExplorer/Styles/ExplorerStyles.xaml +++ /dev/null @@ -1,419 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/CSharp/BatchExplorer/ViewModels/AccountDialogViewModel.cs b/CSharp/BatchExplorer/ViewModels/AccountDialogViewModel.cs deleted file mode 100644 index 98101b17..00000000 --- a/CSharp/BatchExplorer/ViewModels/AccountDialogViewModel.cs +++ /dev/null @@ -1,81 +0,0 @@ -//Copyright (c) Microsoft Corporation - -using System.Windows.Controls; -using GalaSoft.MvvmLight.Messaging; -using Microsoft.Azure.BatchExplorer.Helpers; -using Microsoft.Azure.BatchExplorer.Messages; -using Microsoft.Azure.BatchExplorer.Models; -using Microsoft.Azure.BatchExplorer.PluginInterfaces.AccountPlugin; - -namespace Microsoft.Azure.BatchExplorer.ViewModels -{ - public class AccountDialogViewModel : EntityBase - { - private readonly AccountManagementOperation accountOperation; - private readonly IAccountManager accountManager; - - /// - /// Use this constructor when creating a dialog that will be used on a new account - /// - public AccountDialogViewModel(IAccountManager accountManager, IAccountOperationFactory factory) - : this(null, accountManager, factory) - { } - - /// - /// Use this constructor when creating a dialog that will be used on an edited account - /// - /// the existing account to be edited - /// - public AccountDialogViewModel(Account account, IAccountManager accountManager, IAccountOperationFactory factory) - { - this.accountManager = accountManager; - - if (account != null) - { - this.accountOperation = factory.CreateEditAccountOperation(account); - Confirm = new CommandBase(ConfirmEdit); - Cancel = new CommandBase(CancelEdit); - } - else - { - this.accountOperation = factory.CreateAddAccountOperation(); - Confirm = new CommandBase(ConfirmNew); - Cancel = new CommandBase(CancelNew); - } - } - /// - /// Invoke this command when the confirmation button (at this time it is the one labeled submit) is pressed - /// - public CommandBase Confirm { get; private set; } - - /// - /// Invoke this command when the cancel button is pressed - /// - public CommandBase Cancel { get; private set; } - - public Control PluginControl - { - get { return this.accountOperation.Control; } - } - - private void ConfirmNew(object o) - { - Messenger.Default.Send(new ConfirmAccountAddMessage() { AccountManager = this.accountManager, AccountToAdd = this.accountOperation.Complete() }); - } - - private void ConfirmEdit(object o) - { - Messenger.Default.Send(new ConfirmAccountEditMessage() { AccountManager = this.accountManager, AccountToEdit = this.accountOperation.Complete() }); - } - - private void CancelNew(object o) - { - Messenger.Default.Send(new CloseGenericPopup()); - } - - private void CancelEdit(object o) - { - Messenger.Default.Send(new CloseGenericPopup()); - } - } -} diff --git a/CSharp/BatchExplorer/ViewModels/AddTaskViewModel.cs b/CSharp/BatchExplorer/ViewModels/AddTaskViewModel.cs deleted file mode 100644 index d230a9e5..00000000 --- a/CSharp/BatchExplorer/ViewModels/AddTaskViewModel.cs +++ /dev/null @@ -1,277 +0,0 @@ -//Copyright (c) Microsoft Corporation - -using System; -using System.Linq; -using System.Threading.Tasks; -using GalaSoft.MvvmLight.Messaging; -using Microsoft.Azure.BatchExplorer.Helpers; -using Microsoft.Azure.BatchExplorer.Messages; -using Microsoft.Azure.BatchExplorer.Models; - -namespace Microsoft.Azure.BatchExplorer.ViewModels -{ - public class AddTaskViewModel : EntityBase - { - #region Services - private readonly IDataProvider batchService; - #endregion - - #region Public UI Properties - - - private string jobId; - public string JobId - { - get - { - return this.jobId; - } - set - { - this.jobId = value; - this.FirePropertyChangedEvent("JobId"); - } - } - - // Basic Task Details - private string taskId; - public string TaskId - { - get - { - return this.taskId; - } - set - { - this.taskId = value; - this.FirePropertyChangedEvent("TaskId"); - } - } - - private string commandLine; - public string CommandLine - { - get - { - return this.commandLine; - } - set - { - this.commandLine = value; - this.FirePropertyChangedEvent("CommandLine"); - } - } - - private int maxTaskRetryCount; - public int MaxTaskRetryCount - { - get - { - return this.maxTaskRetryCount; - } - set - { - this.maxTaskRetryCount = value; - this.FirePropertyChangedEvent("MaxTaskRetryCount"); - } - } - - private bool runElevated; - public bool RunElevated - { - get - { - return this.runElevated; - } - set - { - this.runElevated = value; - this.FirePropertyChangedEvent("RunElevated"); - } - } - - private bool isMultiInstanceTask; - public bool IsMultiInstanceTask - { - get - { - return this.isMultiInstanceTask; - } - set - { - this.isMultiInstanceTask = value; - this.FirePropertyChangedEvent("IsMultiInstanceTask"); - } - } - - private string backgroundCommand; - public string BackgroundCommand - { - get - { - return this.backgroundCommand; - } - set - { - this.backgroundCommand = value; - this.FirePropertyChangedEvent("BackgroundCommand"); - } - } - - private string instanceNumber; - public string InstanceNumber - { - get - { - return this.instanceNumber; - } - set - { - this.instanceNumber = value; - this.FirePropertyChangedEvent("InstanceNumber"); - } - } - - private string commonResourceFiles; - public string CommonResourceFiles - { - get - { - return this.commonResourceFiles; - } - set - { - this.commonResourceFiles = value; - this.FirePropertyChangedEvent("CommonResourceFiles"); - } - } - - private string resourceFiles; - public string ResourceFiles - { - get - { - return this.resourceFiles; - } - set - { - this.resourceFiles = value; - this.FirePropertyChangedEvent("ResourceFiles"); - } - } - - #endregion - - #region Commands - public CommandBase AddTask - { - get - { - return new CommandBase( - async (o) => - { - try - { - this.IsBusy = true; - await this.AddTaskAsync(); - } - finally - { - this.IsBusy = false; - } - } - ); - } - } - #endregion - - public AddTaskViewModel(IDataProvider batchService, string jobId) - { - this.batchService = batchService; - this.IsBusy = false; - - this.JobId = jobId; - } - - private async Task AddTaskAsync() - { - try - { - if (this.IsInputValid()) - { - AddTaskOptions options = new AddTaskOptions() - { - JobId = this.jobId, - CommandLine = this.CommandLine, - TaskId = this.TaskId, - IsMultiInstanceTask = this.IsMultiInstanceTask, - ResourceFiles = ResourceFileStringParser.Parse(this.ResourceFiles).Files.ToList(), - RunElevated = this.RunElevated, - MaxTaskRetryCount = this.MaxTaskRetryCount, - }; - - if (this.IsMultiInstanceTask) - { - options.BackgroundCommand = this.BackgroundCommand; - options.InstanceNumber = Int32.Parse(this.InstanceNumber); - options.CommonResourceFiles = ResourceFileStringParser.Parse(this.commonResourceFiles).Files.ToList(); - } - - await this.batchService.AddTaskAsync(options); - - Messenger.Default.Send(new GenericDialogMessage(string.Format("Successfully added Task {0}", this.TaskId))); - this.TaskId = string.Empty; //So that the user cannot accidentally try to create the same task twice - } - } - catch (Exception e) - { - Messenger.Default.Send(new GenericDialogMessage(e.ToString())); - } - } - - private bool IsInputValid() - { - if (string.IsNullOrEmpty(this.TaskId)) - { - Messenger.Default.Send(new GenericDialogMessage("Invalid values for Task Id")); - return false; - } - - if (string.IsNullOrEmpty(this.CommandLine)) - { - Messenger.Default.Send(new GenericDialogMessage("Invalid values for Command Line")); - return false; - } - - if (this.IsMultiInstanceTask) - { - if (string.IsNullOrEmpty(this.InstanceNumber)) - { - Messenger.Default.Send(new GenericDialogMessage("Invalid values for Instance Number")); - } - - int i; - if (!Int32.TryParse(this.InstanceNumber, out i)) - { - Messenger.Default.Send(new GenericDialogMessage("Instance Number must be an integer")); - } - - var commonResourceFiles = ResourceFileStringParser.Parse(this.CommonResourceFiles); - if (commonResourceFiles.HasErrors) - { - Messenger.Default.Send(new GenericDialogMessage(String.Join(Environment.NewLine, commonResourceFiles.Errors))); - return false; - } - } - - var resourceFiles = ResourceFileStringParser.Parse(this.ResourceFiles); - if (resourceFiles.HasErrors) - { - Messenger.Default.Send(new GenericDialogMessage(String.Join(Environment.NewLine, resourceFiles.Errors))); - return false; - } - - return true; - } - } -} diff --git a/CSharp/BatchExplorer/ViewModels/AsyncOperationDetailsViewModel.cs b/CSharp/BatchExplorer/ViewModels/AsyncOperationDetailsViewModel.cs deleted file mode 100644 index 6ad00c67..00000000 --- a/CSharp/BatchExplorer/ViewModels/AsyncOperationDetailsViewModel.cs +++ /dev/null @@ -1,21 +0,0 @@ -//Copyright (c) Microsoft Corporation - -using Microsoft.Azure.BatchExplorer.Helpers; -using Microsoft.Azure.BatchExplorer.Models; - -namespace Microsoft.Azure.BatchExplorer.ViewModels -{ - public class AsyncOperationDetailsViewModel : EntityBase - { - #region Public UI Properties - - public AsyncOperationModel AsyncOperation { get; private set; } - - #endregion - - public AsyncOperationDetailsViewModel(AsyncOperationModel model) - { - this.AsyncOperation = model; - } - } -} diff --git a/CSharp/BatchExplorer/ViewModels/CreateCertificateViewModel.cs b/CSharp/BatchExplorer/ViewModels/CreateCertificateViewModel.cs deleted file mode 100644 index e1546eb6..00000000 --- a/CSharp/BatchExplorer/ViewModels/CreateCertificateViewModel.cs +++ /dev/null @@ -1,167 +0,0 @@ -using GalaSoft.MvvmLight.Messaging; -using Microsoft.Azure.Batch.Common; -using Microsoft.Azure.BatchExplorer.Helpers; -using Microsoft.Azure.BatchExplorer.Messages; -using Microsoft.Azure.BatchExplorer.Models; -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Microsoft.Azure.BatchExplorer.ViewModels -{ - public class CreateCertificateViewModel : EntityBase - { - private readonly IDataProvider batchService; - - public CreateCertificateViewModel(IDataProvider batchService) - { - this.batchService = batchService; - } - - private string filePath; - - public string FilePath - { - get - { - return this.filePath; - } - set - { - this.filePath = value; - this.FirePropertyChangedEvent("FilePath"); - this.FirePropertyChangedEvent("IsCreateCertificateButtonEnabled"); - } - } - - private string password; - - public string Password - { - get - { - return this.password; - } - set - { - this.password = value; - this.FirePropertyChangedEvent("Password"); - this.FirePropertyChangedEvent("IsCreateCertificateButtonEnabled"); - } - } - - public bool IsCreateCertificateButtonEnabled - { - get - { - if (!FilePathExists()) - { - return false; - } - - var format = InferFormat(); - - if (format == null) - { - return false; - } - - if (format.Value == CertificateFormat.Pfx && string.IsNullOrEmpty(Password)) - { - return false; - } - - return true; - } - } - - public CommandBase CreateCertificate - { - get - { - return new CommandBase( - async (o) => - { - try - { - this.IsBusy = true; - await this.CreateCertificateAsync(); - } - finally - { - this.IsBusy = false; - } - } - ); - } - } - - private bool FilePathExists() - { - if (String.IsNullOrWhiteSpace(FilePath)) - { - return false; - } - - try - { - return System.IO.File.Exists(FilePath); - } - catch - { - return false; - } - } - - private CertificateFormat? InferFormat() - { - var fileExtension = System.IO.Path.GetExtension(FilePath); - var comparer = StringComparer.OrdinalIgnoreCase; - - if (comparer.Equals(".pfx", fileExtension)) - { - return CertificateFormat.Pfx; - } - if (comparer.Equals(".cer", fileExtension)) - { - return CertificateFormat.Cer; - } - return null; - } - - private async Task CreateCertificateAsync() - { - try - { - var certificateFormat = InferFormat(); - - if (certificateFormat == null) - { - Debug.Assert(false, "Create button should not have enabled when we were unable to infer a certificate format"); - return; - } - - CreateCertificateOptions options = new CreateCertificateOptions - { - FilePath = FilePath, - CertificateFormat = certificateFormat.Value, - Password = Password, - }; - - await this.batchService.CreateCertificateAsync(options); - - Messenger.Default.Send(new RefreshMessage(RefreshTarget.Certificates)); - - Messenger.Default.Send(new GenericDialogMessage(string.Format("Successfully uploaded certificate from {0}", this.FilePath))); - this.FilePath = string.Empty; //So that the user doesn't accidentally try to upload the same certificate twice - } - catch (Exception e) - { - Messenger.Default.Send(new GenericDialogMessage(e.ToString())); - } - } - } -} diff --git a/CSharp/BatchExplorer/ViewModels/CreateComputeNodeUserViewModel.cs b/CSharp/BatchExplorer/ViewModels/CreateComputeNodeUserViewModel.cs deleted file mode 100644 index 8577b248..00000000 --- a/CSharp/BatchExplorer/ViewModels/CreateComputeNodeUserViewModel.cs +++ /dev/null @@ -1,179 +0,0 @@ -//Copyright (c) Microsoft Corporation - -using System; -using System.Threading.Tasks; -using System.Windows.Controls; -using GalaSoft.MvvmLight.Messaging; -using Microsoft.Azure.BatchExplorer.Helpers; -using Microsoft.Azure.BatchExplorer.Messages; -using Microsoft.Azure.BatchExplorer.Models; - -namespace Microsoft.Azure.BatchExplorer.ViewModels -{ - public class CreateComputeNodeUserViewModel : EntityBase - { - #region Services - private readonly IDataProvider batchService; - #endregion - - #region Public UI Properties - private string poolId; - public string PoolId - { - get - { - return this.poolId; - } - set - { - this.poolId = value; - this.FirePropertyChangedEvent("PoolId"); - } - } - - private string computeNodeId; - public string ComputeNodeId - { - get - { - return this.computeNodeId; - } - private set - { - this.computeNodeId = value; - this.FirePropertyChangedEvent("ComputeNodeId"); - } - } - - private string userName; - public string UserName - { - get - { - return this.userName; - } - set - { - this.userName = value; - this.FirePropertyChangedEvent("UserName"); - } - } - - private DateTime expiryTime; - public DateTime ExpiryTime - { - get - { - return this.expiryTime; - } - set - { - this.expiryTime = value; - this.FirePropertyChangedEvent("ExpiryTime"); - } - } - - private bool isAdmin; - public bool IsAdmin - { - get - { - return this.isAdmin; - } - set - { - this.isAdmin = value; - this.FirePropertyChangedEvent("IsAdmin"); - } - } - #endregion - - public CreateComputeNodeUserViewModel(IDataProvider batchService, string poolId, string computeNodeId) - { - this.batchService = batchService; - - this.PoolId = poolId; - this.ComputeNodeId = computeNodeId; - this.IsAdmin = true; - this.ExpiryTime = DateTime.UtcNow + TimeSpan.FromDays(1); - - this.IsBusy = false; - } - - public CommandBase CreateUser - { - get - { - return new CommandBase( - async (o) => - { - this.IsBusy = true; - - //TODO: This breaks MVVM seperation, but due to the way passwordbox works we must... - //TODO: Maybe implement our own passwordbox that allows SecureString bindings or use - //TODO: the codebehind on the view to push this data to us? - PasswordBox pwBox = (PasswordBox)o; - - try - { - await this.CreateVMUserAsync(pwBox.Password); - } - finally - { - this.IsBusy = false; - } - } - ); - } - } - - private async Task CreateVMUserAsync(string password) - { - try - { - if (this.IsInputValid(password)) - { - Task asyncTask = this.batchService.CreateComputeNodeUserAsync( - this.PoolId, - this.ComputeNodeId, - this.UserName, - password, - this.ExpiryTime, - this.IsAdmin); - - AsyncOperationTracker.Instance.AddTrackedOperation(new AsyncOperationModel( - asyncTask, - new ComputeNodeOperation(ComputeNodeOperation.CreateUser, this.PoolId, this.ComputeNodeId))); - await asyncTask; - - Messenger.Default.Send(new CloseGenericPopup()); - } - } - catch (Exception e) - { - Messenger.Default.Send(new GenericDialogMessage(e.ToString())); - } - } - - private bool IsInputValid(string password) - { - if (string.IsNullOrEmpty(this.PoolId)) - { - Messenger.Default.Send(new GenericDialogMessage("Invalid values for Pool Id")); - return false; - } - else if (string.IsNullOrEmpty(this.UserName)) - { - Messenger.Default.Send(new GenericDialogMessage("Invalid value for user name")); - return false; - } - else if (string.IsNullOrEmpty(password)) - { - Messenger.Default.Send(new GenericDialogMessage("Invalid value for password")); - return false; - } - - return true; - } - } -} diff --git a/CSharp/BatchExplorer/ViewModels/CreateJobScheduleViewModel.cs b/CSharp/BatchExplorer/ViewModels/CreateJobScheduleViewModel.cs deleted file mode 100644 index 6297ffa3..00000000 --- a/CSharp/BatchExplorer/ViewModels/CreateJobScheduleViewModel.cs +++ /dev/null @@ -1,616 +0,0 @@ -//Copyright (c) Microsoft Corporation - -namespace Microsoft.Azure.BatchExplorer.ViewModels -{ - using System; - using System.Collections.Generic; - using System.Threading.Tasks; - using GalaSoft.MvvmLight.Messaging; - using Microsoft.Azure.BatchExplorer.Helpers; - using Microsoft.Azure.BatchExplorer.Messages; - using Microsoft.Azure.BatchExplorer.Models; - using Common = Helpers.Common; - - public class CreateJobScheduleViewModel : EntityBase - { - #region Services - private readonly IDataProvider batchService; - #endregion - - #region Public UI Properties - // Basic job schedule details - - private string jobScheduleId; - public string JobScheduleId - { - get - { - return this.jobScheduleId; - } - set - { - this.jobScheduleId = value; - this.FirePropertyChangedEvent("JobScheduleId"); - this.FirePropertyChangedEvent("IsCreateJobScheduleButtonEnabled"); - } - } - - private string priority; - public string Priority - { - get - { - return this.priority; - } - set - { - this.priority = value; - this.FirePropertyChangedEvent("Priority"); - } - } - - private string maxRetryCount; - public string MaxRetryCount - { - get - { - return this.maxRetryCount; - } - set - { - this.maxRetryCount = value; - this.FirePropertyChangedEvent("MaxRetryCount"); - } - } - - private bool isCreateJobManagerSelected; - public bool IsCreateJobManagerSelected - { - get - { - return this.isCreateJobManagerSelected; - } - set - { - this.isCreateJobManagerSelected = value; - this.FirePropertyChangedEvent("IsCreateJobManagerSelected"); - } - } - - private TimeSpan? maxWallClockTime; - public TimeSpan? MaxWallClockTime - { - get - { - return this.maxWallClockTime; - } - set - { - this.maxWallClockTime = value; - this.FirePropertyChangedEvent("MaxWallClockTime"); - } - } - - // Schedule - private DateTime? doNotRunUntil; - public DateTime? DoNotRunUntil - { - get - { - return this.doNotRunUntil; - } - set - { - this.doNotRunUntil = value; - this.FirePropertyChangedEvent("DoNotRunUntil"); - this.FirePropertyChangedEvent("IsCreateJobScheduleButtonEnabled"); - } - } - - private DateTime? doNotRunAfter; - public DateTime? DoNotRunAfter - { - get - { - return this.doNotRunAfter; - } - set - { - this.doNotRunAfter = value; - this.FirePropertyChangedEvent("DoNotRunAfter"); - this.FirePropertyChangedEvent("IsCreateJobScheduleButtonEnabled"); - } - } - - private TimeSpan? startWindow; - public TimeSpan? StartWindow - { - get - { - return this.startWindow; - } - set - { - this.startWindow = value; - this.FirePropertyChangedEvent("StartWindow"); - this.FirePropertyChangedEvent("IsCreateJobScheduleButtonEnabled"); - } - } - - private TimeSpan? recurrenceInterval; - public TimeSpan? RecurrenceInterval - { - get - { - return this.recurrenceInterval; - } - set - { - this.recurrenceInterval = value; - this.FirePropertyChangedEvent("RecurrenceInterval"); - this.FirePropertyChangedEvent("IsCreateJobScheduleButtonEnabled"); - } - } - - // Job Manager - private string jobManagerId; - public string JobManagerId - { - get - { - return this.jobManagerId; - } - set - { - this.jobManagerId = value; - this.FirePropertyChangedEvent("JobManagerId"); - } - } - - private string commandLine; - public string CommandLine - { - get - { - return this.commandLine; - } - set - { - this.commandLine = value; - this.FirePropertyChangedEvent("CommandLine"); - } - } - - private string maxTaskRetryCount; - public string MaxTaskRetryCount - { - get - { - return this.maxTaskRetryCount; - } - set - { - this.maxTaskRetryCount = value; - this.FirePropertyChangedEvent("MaxTaskRetryCount"); - } - } - - private TimeSpan? maxTaskWallClockTime; - public TimeSpan? MaxTaskWallClockTime - { - get - { - return this.maxTaskWallClockTime; - } - set - { - this.maxTaskWallClockTime = value; - this.FirePropertyChangedEvent("MaxWallClockTime"); - } - } - - private TimeSpan? retentionTime; - public TimeSpan? RetentionTime - { - get - { - return this.retentionTime; - } - set - { - this.retentionTime = value; - this.FirePropertyChangedEvent("RetentionTime"); - } - } - - private List availableKillOnCompletionOptions; - public List AvailableKillOnCompletionOptions - { - get - { - return this.availableKillOnCompletionOptions; - } - set - { - this.availableKillOnCompletionOptions = value; - this.FirePropertyChangedEvent("AvailableKillOnCompletionOptions"); - } - } - - private bool killOnCompletionSelectedItem; - public bool KillOnCompletionSelectedItem - { - get - { - return this.killOnCompletionSelectedItem; - } - set - { - this.killOnCompletionSelectedItem = value; - this.FirePropertyChangedEvent("KillOnCompletionSelectedItem"); - } - } - - // Pool Settings - private bool useAutoPool; - public bool UseAutoPool - { - get - { - return this.useAutoPool; - } - set - { - this.useAutoPool = value; - this.FirePropertyChangedEvent("UseAutoPool"); - } - } - - private string poolId; - public string PoolId - { - get - { - return this.poolId; - } - set - { - this.poolId = value; - this.FirePropertyChangedEvent("PoolId"); - } - } - - private string autoPoolPrefix; - public string AutoPoolPrefix - { - get - { - return this.autoPoolPrefix; - } - set - { - this.autoPoolPrefix = value; - this.FirePropertyChangedEvent("AutoPoolPrefix"); - } - } - - private List availableLifeTimeOptions; - public List AvailableLifeTimeOptions - { - get - { - return this.availableLifeTimeOptions; - } - set - { - this.availableLifeTimeOptions = value; - this.FirePropertyChangedEvent("AvailableLifeTimeOptions"); - } - } - - private string selectedLifetimeOption; - public string SelectedLifetimeOption - { - get - { - return this.selectedLifetimeOption; - } - set - { - this.selectedLifetimeOption = value; - this.FirePropertyChangedEvent("SelectedLifetimeOption"); - } - } - - - private List availableKeepAliveOptions; - public List AvailableKeepAliveOptions - { - get - { - return this.availableKeepAliveOptions; - } - set - { - this.availableKeepAliveOptions = value; - this.FirePropertyChangedEvent("AvailableKeepAliveOptions"); - } - } - - private bool selectedKeepAliveItem; - public bool SelectedKeepAliveItem - { - get - { - return this.selectedKeepAliveItem; - } - set - { - this.selectedKeepAliveItem = value; - this.FirePropertyChangedEvent("SelectedKeepAliveItem"); - } - } - - private string selectedOSFamily; - public string SelectedOSFamily - { - get - { - return this.selectedOSFamily; - } - set - { - this.selectedOSFamily = value; - this.FirePropertyChangedEvent("SelectedOSFamily"); - } - } - - private int targetDedicated; - public int TargetDedicated - { - get - { - return this.targetDedicated; - } - set - { - this.targetDedicated = value; - this.FirePropertyChangedEvent("TargetDedicated"); - } - } - - private int targetLowPriority; - public int TargetLowPriority - { - get - { - return this.targetLowPriority; - } - set - { - this.targetLowPriority = value; - this.FirePropertyChangedEvent("TargetLowPriority"); - } - } - - private string selectedVirtualMachineSize; - public string SelectedVirtualMachineSize - { - get - { - return this.selectedVirtualMachineSize; - } - set - { - this.selectedVirtualMachineSize = value; - this.FirePropertyChangedEvent("selectedVirtualMachineSize"); - } - } - - private IReadOnlyList availableVirtualMachineSizes; - public IReadOnlyList AvailableVirtualMachineSizes - { - get - { - return this.availableVirtualMachineSizes; - } - set - { - this.availableVirtualMachineSizes = value; - this.FirePropertyChangedEvent("availableVirtualMachineSizes"); - } - } - - private List availableOSFamilies; - public List AvailableOSFamilies - { - get - { - return this.availableOSFamilies; - } - set - { - this.availableOSFamilies = value; - this.FirePropertyChangedEvent("AvailableOSFamilies"); - } - } - - public bool IsCreateJobScheduleButtonEnabled - { - get - { - return (!string.IsNullOrEmpty(this.JobScheduleId)) && (this.RecurrenceInterval != null || this.StartWindow != null || this.DoNotRunUntil != null || this.DoNotRunAfter != null); - } - } - #endregion - - #region Commands - public CommandBase CreateJobSchedule - { - get - { - return new CommandBase( - async (o) => - { - try - { - this.IsBusy = true; - await this.CreateJobScheduleAsync(); - } - finally - { - this.IsBusy = false; - } - } - ); - } - } - - public CommandBase CancelCreateJobSchedule - { - get - { - return new CommandBase( - (o) => - { - // TODO: Close window - } - ); - } - } - #endregion - - public CreateJobScheduleViewModel(IDataProvider batchService) - { - this.batchService = batchService; - this.IsBusy = false; - - // pre-populate values - this.AvailableKeepAliveOptions = new List { false, true }; - this.AvailableLifeTimeOptions = new List { "Job", "JobSchedule" }; - this.AvailableKillOnCompletionOptions = new List { true, false }; - - this.SelectedKeepAliveItem = this.AvailableKeepAliveOptions[0]; - this.SelectedLifetimeOption = this.AvailableLifeTimeOptions[0]; - this.KillOnCompletionSelectedItem = this.AvailableKillOnCompletionOptions[0]; - - this.AvailableVirtualMachineSizes = Common.SupportedVirtualMachineSizesList; - this.AvailableOSFamilies = new List(Common.SupportedOSFamilyDictionary.Keys); - } - - private async Task CreateJobScheduleAsync() - { - try - { - if (this.IsInputValid()) - { - string osFamilyString = null; - - if (this.UseAutoPool) - { - if (Common.SupportedOSFamilyDictionary.ContainsKey(this.SelectedOSFamily)) - { - osFamilyString = Common.SupportedOSFamilyDictionary[this.SelectedOSFamily]; - } - else - { - osFamilyString = this.SelectedOSFamily; - } - } - - CreateJobScheduleOptions options = new CreateJobScheduleOptions() - { - DoNotRunAfter = this.DoNotRunAfter, - DoNotRunUntil = this.DoNotRunUntil, - CreateJobManager = this.IsCreateJobManagerSelected, - MaxRetryCount = Common.GetNullableIntValue(this.MaxRetryCount), - MaxWallClockTime = this.MaxWallClockTime, - Priority = Common.GetNullableIntValue(this.Priority), - RecurrenceInterval = this.RecurrenceInterval, - StartWindow = this.StartWindow, - JobScheduleId = this.JobScheduleId, - PoolId = this.PoolId, - AutoPoolOptions = new CreateAutoPoolOptions() - { - AutoPoolPrefix = this.AutoPoolPrefix, - LifeTimeOption = this.SelectedLifetimeOption, - KeepAlive = this.SelectedKeepAliveItem, - OSFamily = osFamilyString, - SelectedLifetimeOption = this.SelectedLifetimeOption, - TargetDedicated = this.TargetDedicated, - TargetLowPriority = this.TargetLowPriority, - UseAutoPool = this.UseAutoPool, - VirutalMachineSize = this.SelectedVirtualMachineSize - }, - JobManagerOptions = new CreateJobManagerOptions() - { - CommandLine = this.CommandLine, - JobManagerId = this.JobManagerId, - KillOnCompletion = this.KillOnCompletionSelectedItem, - MaxTaskRetryCount = Common.GetNullableIntValue(this.MaxRetryCount), - MaxTaskWallClockTime = this.MaxTaskWallClockTime, - RetentionTime = this.RetentionTime - } - }; - - await this.batchService.CreateJobScheduleAsync(options); - - Messenger.Default.Send(new RefreshMessage(RefreshTarget.JobSchedules)); - - Messenger.Default.Send(new GenericDialogMessage(string.Format("Successfully created job schedule {0}", this.JobScheduleId))); - this.JobScheduleId = string.Empty; //So that the user cannot accidentally try to create the same job schedule twice - } - } - catch (Exception e) - { - Messenger.Default.Send(new GenericDialogMessage(e.ToString())); - } - } - - private bool IsInputValid() - { - // TODO: Validate string to int inputs. e.g. Retry Count should be an int - if (string.IsNullOrEmpty(this.JobScheduleId)) - { - Messenger.Default.Send(new GenericDialogMessage("Invalid values for job schedule Id")); - return false; - } - - if (!this.UseAutoPool && string.IsNullOrEmpty(this.PoolId)) - { - Messenger.Default.Send(new GenericDialogMessage("Invalid values for Pool Id")); - return false; - } - - if (this.UseAutoPool) - { - if (string.IsNullOrEmpty(this.SelectedVirtualMachineSize)) - { - Messenger.Default.Send(new GenericDialogMessage("Auto pool requires virtual machine size to be specified")); - return false; - } - if (string.IsNullOrEmpty(this.SelectedOSFamily)) - { - Messenger.Default.Send(new GenericDialogMessage("Auto pool requires OS family to be specified")); - return false; - } - } - - if (this.IsCreateJobManagerSelected) - { - if (string.IsNullOrEmpty(this.JobManagerId)) - { - Messenger.Default.Send(new GenericDialogMessage("Invalid values for Job Manager Id")); - return false; - } - if (string.IsNullOrEmpty(this.CommandLine)) - { - Messenger.Default.Send(new GenericDialogMessage("Invalid values for Command Line")); - return false; - } - } - - return true; - } - } -} diff --git a/CSharp/BatchExplorer/ViewModels/CreateJobViewModel.cs b/CSharp/BatchExplorer/ViewModels/CreateJobViewModel.cs deleted file mode 100644 index f2d9f408..00000000 --- a/CSharp/BatchExplorer/ViewModels/CreateJobViewModel.cs +++ /dev/null @@ -1,551 +0,0 @@ -//Copyright (c) Microsoft Corporation - -namespace Microsoft.Azure.BatchExplorer.ViewModels -{ - using System; - using System.Collections.Generic; - using System.Threading.Tasks; - using GalaSoft.MvvmLight.Messaging; - using Microsoft.Azure.BatchExplorer.Helpers; - using Microsoft.Azure.BatchExplorer.Messages; - using Microsoft.Azure.BatchExplorer.Models; - using Common = Helpers.Common; - - public class CreateJobViewModel : EntityBase - { - #region Services - private readonly IDataProvider batchService; - #endregion - - #region Public UI Properties - // Basic job schedule details - - private string jobId; - public string JobId - { - get - { - return this.jobId; - } - set - { - this.jobId = value; - this.FirePropertyChangedEvent("JobId"); - this.FirePropertyChangedEvent("IsCreateJobButtonEnabled"); - } - } - - private string priority; - public string Priority - { - get - { - return this.priority; - } - set - { - this.priority = value; - this.FirePropertyChangedEvent("Priority"); - } - } - - private string maxRetryCount; - public string MaxRetryCount - { - get - { - return this.maxRetryCount; - } - set - { - this.maxRetryCount = value; - this.FirePropertyChangedEvent("MaxRetryCount"); - } - } - - private bool isCreateJobManagerSelected; - public bool IsCreateJobManagerSelected - { - get - { - return this.isCreateJobManagerSelected; - } - set - { - this.isCreateJobManagerSelected = value; - this.FirePropertyChangedEvent("IsCreateJobManagerSelected"); - } - } - - private TimeSpan? maxWallClockTime; - public TimeSpan? MaxWallClockTime - { - get - { - return this.maxWallClockTime; - } - set - { - this.maxWallClockTime = value; - this.FirePropertyChangedEvent("MaxWallClockTime"); - } - } - - // Job Manager - private string jobManagerId; - public string JobManagerId - { - get - { - return this.jobManagerId; - } - set - { - this.jobManagerId = value; - this.FirePropertyChangedEvent("JobManagerId"); - } - } - - private string commandLine; - public string CommandLine - { - get - { - return this.commandLine; - } - set - { - this.commandLine = value; - this.FirePropertyChangedEvent("CommandLine"); - } - } - - private string maxTaskRetryCount; - public string MaxTaskRetryCount - { - get - { - return this.maxTaskRetryCount; - } - set - { - this.maxTaskRetryCount = value; - this.FirePropertyChangedEvent("MaxTaskRetryCount"); - } - } - - private TimeSpan? maxTaskWallClockTime; - public TimeSpan? MaxTaskWallClockTime - { - get - { - return this.maxTaskWallClockTime; - } - set - { - this.maxTaskWallClockTime = value; - this.FirePropertyChangedEvent("MaxWallClockTime"); - } - } - - private TimeSpan? retentionTime; - public TimeSpan? RetentionTime - { - get - { - return this.retentionTime; - } - set - { - this.retentionTime = value; - this.FirePropertyChangedEvent("RetentionTime"); - } - } - - private List availableKillOnCompletionOptions; - public List AvailableKillOnCompletionOptions - { - get - { - return this.availableKillOnCompletionOptions; - } - set - { - this.availableKillOnCompletionOptions = value; - this.FirePropertyChangedEvent("AvailableKillOnCompletionOptions"); - } - } - - private bool killOnCompletionSelectedItem; - public bool KillOnCompletionSelectedItem - { - get - { - return this.killOnCompletionSelectedItem; - } - set - { - this.killOnCompletionSelectedItem = value; - this.FirePropertyChangedEvent("KillOnCompletionSelectedItem"); - } - } - - // Pool Settings - private bool useAutoPool; - public bool UseAutoPool - { - get - { - return this.useAutoPool; - } - set - { - this.useAutoPool = value; - this.FirePropertyChangedEvent("UseAutoPool"); - } - } - - private string poolId; - public string PoolId - { - get - { - return this.poolId; - } - set - { - this.poolId = value; - this.FirePropertyChangedEvent("PoolId"); - } - } - - private string autoPoolPrefix; - public string AutoPoolPrefix - { - get - { - return this.autoPoolPrefix; - } - set - { - this.autoPoolPrefix = value; - this.FirePropertyChangedEvent("AutoPoolPrefix"); - } - } - - private List availableLifeTimeOptions; - public List AvailableLifeTimeOptions - { - get - { - return this.availableLifeTimeOptions; - } - set - { - this.availableLifeTimeOptions = value; - this.FirePropertyChangedEvent("AvailableLifeTimeOptions"); - } - } - - private string selectedLifetimeOption; - public string SelectedLifetimeOption - { - get - { - return this.selectedLifetimeOption; - } - set - { - this.selectedLifetimeOption = value; - this.FirePropertyChangedEvent("SelectedLifetimeOption"); - } - } - - - private List availableKeepAliveOptions; - public List AvailableKeepAliveOptions - { - get - { - return this.availableKeepAliveOptions; - } - set - { - this.availableKeepAliveOptions = value; - this.FirePropertyChangedEvent("AvailableKeepAliveOptions"); - } - } - - private bool selectedKeepAliveItem; - public bool SelectedKeepAliveItem - { - get - { - return this.selectedKeepAliveItem; - } - set - { - this.selectedKeepAliveItem = value; - this.FirePropertyChangedEvent("SelectedKeepAliveItem"); - } - } - - private string selectedOSFamily; - public string SelectedOSFamily - { - get - { - return this.selectedOSFamily; - } - set - { - this.selectedOSFamily = value; - this.FirePropertyChangedEvent("SelectedOSFamily"); - } - } - - private int targetDedicated; - public int TargetDedicated - { - get - { - return this.targetDedicated; - } - set - { - this.targetDedicated = value; - this.FirePropertyChangedEvent("TargetDedicated"); - } - } - - private int targetLowPriority; - public int TargetLowPriority - { - get - { - return this.targetLowPriority; - } - set - { - this.targetLowPriority = value; - this.FirePropertyChangedEvent("TargetLowPriority"); - } - } - - private string selectedVirtualMachineSize; - public string SelectedVirtualMachineSize - { - get - { - return this.selectedVirtualMachineSize; - } - set - { - this.selectedVirtualMachineSize = value; - this.FirePropertyChangedEvent("selectedVirtualMachineSize"); - } - } - - private IReadOnlyList availableVirtualMachineSizes; - public IReadOnlyList AvailableVirtualMachineSizes - { - get - { - return this.availableVirtualMachineSizes; - } - set - { - this.availableVirtualMachineSizes = value; - this.FirePropertyChangedEvent("availableVirtualMachineSizes"); - } - } - - private List availableOSFamilies; - public List AvailableOSFamilies - { - get - { - return this.availableOSFamilies; - } - set - { - this.availableOSFamilies = value; - this.FirePropertyChangedEvent("AvailableOSFamilies"); - } - } - - public bool IsCreateJobButtonEnabled - { - get - { - return (!string.IsNullOrEmpty(this.JobId)); - } - } - #endregion - - #region Commands - public CommandBase CreateJobSchedule - { - get - { - return new CommandBase( - async (o) => - { - try - { - this.IsBusy = true; - await this.CreateJobScheduleAsync(); - } - finally - { - this.IsBusy = false; - } - } - ); - } - } - - public CommandBase CancelCreateJobSchedule - { - get - { - return new CommandBase( - (o) => - { - // TODO: Close window - } - ); - } - } - #endregion - - public CreateJobViewModel(IDataProvider batchService) - { - this.batchService = batchService; - this.IsBusy = false; - - // pre-populate values - this.AvailableKeepAliveOptions = new List { false, true }; - this.AvailableLifeTimeOptions = new List { "Job" }; - this.AvailableKillOnCompletionOptions = new List { true, false }; - - this.SelectedKeepAliveItem = this.AvailableKeepAliveOptions[0]; - this.SelectedLifetimeOption = this.AvailableLifeTimeOptions[0]; - this.KillOnCompletionSelectedItem = this.AvailableKillOnCompletionOptions[0]; - - this.AvailableVirtualMachineSizes = Common.SupportedVirtualMachineSizesList; - this.AvailableOSFamilies = new List(Common.SupportedOSFamilyDictionary.Keys); - } - - private async Task CreateJobScheduleAsync() - { - try - { - if (this.IsInputValid()) - { - string osFamilyString = null; - - if (this.UseAutoPool) - { - if (Common.SupportedOSFamilyDictionary.ContainsKey(this.SelectedOSFamily)) - { - osFamilyString = Common.SupportedOSFamilyDictionary[this.SelectedOSFamily]; - } - else - { - osFamilyString = this.SelectedOSFamily; - } - } - - CreateJobOptions options = new CreateJobOptions() - { - CreateJobManager = this.IsCreateJobManagerSelected, - MaxRetryCount = Common.GetNullableIntValue(this.MaxRetryCount), - MaxWallClockTime = this.MaxWallClockTime, - Priority = Common.GetNullableIntValue(this.Priority), - JobId = this.JobId, - PoolId = this.PoolId, - AutoPoolOptions = new CreateAutoPoolOptions() - { - AutoPoolPrefix = this.AutoPoolPrefix, - LifeTimeOption = this.SelectedLifetimeOption, - KeepAlive = this.SelectedKeepAliveItem, - OSFamily = osFamilyString, - SelectedLifetimeOption = this.SelectedLifetimeOption, - TargetDedicated = this.TargetDedicated, - TargetLowPriority = this.TargetLowPriority, - UseAutoPool = this.UseAutoPool, - VirutalMachineSize = this.SelectedVirtualMachineSize - }, - JobManagerOptions = new CreateJobManagerOptions() - { - CommandLine = this.CommandLine, - JobManagerId = this.JobManagerId, - KillOnCompletion = this.KillOnCompletionSelectedItem, - MaxTaskRetryCount = Common.GetNullableIntValue(this.MaxRetryCount), - MaxTaskWallClockTime = this.MaxTaskWallClockTime, - RetentionTime = this.RetentionTime - } - }; - - await this.batchService.CreateJobAsync(options); - - Messenger.Default.Send(new RefreshMessage(RefreshTarget.Jobs)); - - Messenger.Default.Send(new GenericDialogMessage(string.Format("Successfully created job {0}", this.JobId))); - this.JobId = string.Empty; //So that the user cannot accidentally try to create the same job schedule twice - } - } - catch (Exception e) - { - Messenger.Default.Send(new GenericDialogMessage(e.ToString())); - } - } - - private bool IsInputValid() - { - // TODO: Validate string to int inputs. e.g. Retry Count should be an int - if (string.IsNullOrEmpty(this.JobId)) - { - Messenger.Default.Send(new GenericDialogMessage("Invalid values for job Id")); - return false; - } - - if (!this.UseAutoPool && string.IsNullOrEmpty(this.PoolId)) - { - Messenger.Default.Send(new GenericDialogMessage("Invalid values for Pool Id")); - return false; - } - - if (this.UseAutoPool) - { - if (string.IsNullOrEmpty(this.SelectedVirtualMachineSize)) - { - Messenger.Default.Send(new GenericDialogMessage("Auto pool requires virtual machine size to be specified")); - return false; - } - if (string.IsNullOrEmpty(this.SelectedOSFamily)) - { - Messenger.Default.Send(new GenericDialogMessage("Auto pool requires OS family to be specified")); - return false; - } - } - - if (this.IsCreateJobManagerSelected) - { - if (string.IsNullOrEmpty(this.JobManagerId)) - { - Messenger.Default.Send(new GenericDialogMessage("Invalid values for Job Manager Id")); - return false; - } - if (string.IsNullOrEmpty(this.CommandLine)) - { - Messenger.Default.Send(new GenericDialogMessage("Invalid values for Command Line")); - return false; - } - } - - return true; - } - } -} diff --git a/CSharp/BatchExplorer/ViewModels/CreatePoolViewModel.cs b/CSharp/BatchExplorer/ViewModels/CreatePoolViewModel.cs deleted file mode 100644 index c5aaad80..00000000 --- a/CSharp/BatchExplorer/ViewModels/CreatePoolViewModel.cs +++ /dev/null @@ -1,668 +0,0 @@ -//Copyright (c) Microsoft Corporation - -namespace Microsoft.Azure.BatchExplorer.ViewModels -{ - using System; - using System.Collections.Generic; - using System.Collections.ObjectModel; - using System.Linq; - using System.Threading.Tasks; - using Batch; - using GalaSoft.MvvmLight.Messaging; - using Microsoft.Azure.BatchExplorer.Helpers; - using Microsoft.Azure.BatchExplorer.Messages; - using Microsoft.Azure.BatchExplorer.Models; - using Common = Helpers.Common; - - public class CreatePoolViewModel : EntityBase - { - #region Services - private readonly IDataProvider batchService; - #endregion - - #region Public UI Properties - private string poolId; - public string PoolId - { - get - { - return this.poolId; - } - set - { - this.poolId = value; - this.FirePropertyChangedEvent("PoolId"); - } - } - - private string selectedVirtualMachineSize; - public string SelectedVirtualMachineSize - { - get - { - return this.selectedVirtualMachineSize; - } - set - { - this.selectedVirtualMachineSize = value; - this.FirePropertyChangedEvent("selectedVirtualMachineSize"); - } - } - - private IReadOnlyList availableVirtualMachineSizes; - public IReadOnlyList AvailableVirtualMachineSizes - { - get - { - return this.availableVirtualMachineSizes; - } - set - { - this.availableVirtualMachineSizes = value; - this.FirePropertyChangedEvent("availableVirtualMachineSizes"); - } - } - - private IReadOnlyList availableNodeAgentSkus; - public IReadOnlyList AvailableNodeAgentSkus - { - get - { - return this.availableNodeAgentSkus; - } - set - { - this.availableNodeAgentSkus = value; - this.FirePropertyChangedEvent("availableNodeAgentSkus"); - this.FirePropertyChangedEvent("AvailablePublishers"); - this.FirePropertyChangedEvent("AvailableNodeAgentSkuIds"); - this.FirePropertyChangedEvent("AvailableImageReferences"); - } - } - - public IEnumerable AvailableNodeAgentSkuIds - { - get - { - return this.AvailableNodeAgentSkus.Where( - sku => sku.VerifiedImageReferences.Any(imageRef => - imageRef.Publisher == this.Publisher && imageRef.Offer == this.offer && imageRef.Sku == this.Sku)).Select( - sku => sku.Id); - } - } - - public IEnumerable AvailableImageReferences - { - get - { - return this.AvailableNodeAgentSkus.SelectMany(sku => sku.VerifiedImageReferences); - } - } - - public IEnumerable AvailablePublishers - { - get { return this.AvailableImageReferences.Select(imageRef => imageRef.Publisher).Distinct(); } - } - - public IEnumerable AvailableOffers - { - get - { - return this.AvailableImageReferences.Where( - imageRef => imageRef.Publisher == this.Publisher).Select( - imageRef => imageRef.Offer).Distinct(); - } - } - - public IEnumerable AvailableSkus - { - get - { - return this.AvailableImageReferences.Where( - imageRef => imageRef.Publisher == this.Publisher && imageRef.Offer == this.Offer).Select( - imageRef => imageRef.Sku).Distinct(); - } - } - - private int resizeTimeoutInMinutes; - public int ResizeTimeoutInMinutes - { - get - { - return this.resizeTimeoutInMinutes; - } - set - { - this.resizeTimeoutInMinutes = value; - this.FirePropertyChangedEvent("ResizeTimeoutInMinutes"); - } - } - - private int targetDedicated; - public int TargetDedicated - { - get - { - return this.targetDedicated; - } - set - { - this.targetDedicated = value; - this.FirePropertyChangedEvent("TargetDedicated"); - } - } - - private int targetLowPriority; - public int TargetLowPriority - { - get - { - return this.targetLowPriority; - } - set - { - this.targetLowPriority = value; - this.FirePropertyChangedEvent("TargetLowPriority"); - } - } - - private bool useAutoscale; - public bool UseAutoscale - { - get - { - return this.useAutoscale; - } - set - { - this.useAutoscale = value; - this.FirePropertyChangedEvent("UseAutoscale"); - } - } - - private string autoscaleFormula; - public string AutoscaleFormula - { - get - { - return this.autoscaleFormula; - } - set - { - this.autoscaleFormula = value; - this.FirePropertyChangedEvent("AutoscaleFormula"); - } - } - - private string selectedOSFamily; - public string SelectedOSFamily - { - get - { - return this.selectedOSFamily; - } - set - { - this.selectedOSFamily = value; - this.FirePropertyChangedEvent("SelectedOSFamily"); - } - } - - private List availableOSFamilies; - public List AvailableOSFamilies - { - get - { - return this.availableOSFamilies; - } - set - { - this.availableOSFamilies = value; - this.FirePropertyChangedEvent("AvailableOSFamilies"); - } - } - - private string selectedOSVersion; - public string SelectedOSVersion - { - get - { - return this.selectedOSVersion; - } - set - { - this.selectedOSVersion = value; - this.FirePropertyChangedEvent("SelectedOSVersion"); - } - } - - private List availableOSVersions; - public List AvailableOSVersions - { - get - { - return this.availableOSVersions; - } - set - { - this.availableOSVersions = value; - this.FirePropertyChangedEvent("AvailableOSVersions"); - } - } - - - private bool interComputeNodeCommunicationEnabled; - public bool InterComputeNodeCommunicationEnabled - { - get - { - return this.interComputeNodeCommunicationEnabled; - } - set - { - this.interComputeNodeCommunicationEnabled = value; - this.FirePropertyChangedEvent("InterComputeNodeCommunicationEnabled"); - } - } - - private string virtualSubnetId; - public string VirtualSubnetId - { - get - { - return this.virtualSubnetId; - } - set - { - this.virtualSubnetId = value; - this.FirePropertyChangedEvent("VirtualSubnetId"); - } - } - - private TimeSpan? timeout; - public TimeSpan? Timeout - { - get - { - return this.timeout; - } - set - { - this.timeout = value; - this.FirePropertyChangedEvent("Timeout"); - } - } - - private int maxTasksPerComputeNode; - public int MaxTasksPerComputeNode - { - get - { - return this.maxTasksPerComputeNode; - } - set - { - this.maxTasksPerComputeNode = value; - this.FirePropertyChangedEvent("MaxTasksPerComputeNode"); - } - } - - private bool hasStartTask; - public bool HasStartTask - { - get - { - return this.hasStartTask; - } - set - { - this.hasStartTask = value; - this.FirePropertyChangedEvent("HasStartTask"); - } - } - - private string startTaskCommandLine; - public string StartTaskCommandLine - { - get - { - return this.startTaskCommandLine; - } - set - { - this.startTaskCommandLine = value; - this.FirePropertyChangedEvent("StartTaskCommandLine"); - } - } - - private string startTaskResourceFiles; - public string StartTaskResourceFiles - { - get - { - return this.startTaskResourceFiles; - } - set - { - this.startTaskResourceFiles = value; - this.FirePropertyChangedEvent("StartTaskResourceFiles"); - } - } - - private bool startTaskRunElevated; - public bool StartTaskRunElevated - { - get - { - return this.startTaskRunElevated; - } - set - { - this.startTaskRunElevated = value; - this.FirePropertyChangedEvent("StartTaskRunElevated"); - } - } - - private bool hasVirtualMachineConfiguration; - public bool HasVirtualMachineConfiguration - { - get - { - return this.hasVirtualMachineConfiguration; - } - set - { - this.hasVirtualMachineConfiguration = value; - this.FirePropertyChangedEvent("HasVirtualMachineConfiguration"); - } - } - - private string offer; - public string Offer - { - get - { - return this.offer; - } - set - { - this.offer = value; - this.FirePropertyChangedEvent("Offer"); - this.FirePropertyChangedEvent("AvailableSkus"); - this.FirePropertyChangedEvent("AvailableNodeAgentSkuIds"); - } - } - - private string publisher; - public string Publisher - { - get - { - return this.publisher; - } - set - { - this.publisher = value; - this.FirePropertyChangedEvent("Publisher"); - this.FirePropertyChangedEvent("AvailableOffers"); - this.FirePropertyChangedEvent("AvailableSkus"); - this.FirePropertyChangedEvent("AvailableNodeAgentSkuIds"); - } - } - - private string sku; - public string Sku - { - get - { - return this.sku; - } - set - { - this.sku = value; - this.FirePropertyChangedEvent("Sku"); - this.FirePropertyChangedEvent("AvailableNodeAgentSkuIds"); - } - } - - private string version; - public string Version - { - get - { - return this.version; - } - set - { - this.version = value; - this.FirePropertyChangedEvent("Version"); - } - } - - private string nodeAgentSkuId; - public string NodeAgentSkuId - { - get - { - return this.nodeAgentSkuId; - } - set - { - this.nodeAgentSkuId = value; - this.FirePropertyChangedEvent("NodeAgentSkuId"); - } - } - - private bool? enableWindowsAutomaticUpdates; - public bool? EnableWindowsAutomaticUpdates - { - get - { - return this.enableWindowsAutomaticUpdates; - } - set - { - this.enableWindowsAutomaticUpdates = value; - this.FirePropertyChangedEvent("EnableWindowsAutomaticUpdates"); - } - } - - #endregion - - public CreatePoolViewModel(IDataProvider batchService, Cached> nodeAgentSkus) - { - this.batchService = batchService; - - // pre-populate the available VM sizes - this.AvailableVirtualMachineSizes = Common.SupportedVirtualMachineSizesList; - this.AvailableNodeAgentSkus = new List(); //Initially empty - - Task task = nodeAgentSkus.GetDataAsync().ContinueWith( - (t) => this.AvailableNodeAgentSkus = new ReadOnlyCollection(t.Result)); - AsyncOperationTracker.Instance.AddTrackedInternalOperation(task); - - this.Version = "latest"; //Default to latest - this.AvailableOSVersions = new List { "*" }; - this.TargetDedicated = 1; - this.MaxTasksPerComputeNode = 1; - this.IsBusy = false; - this.HasVirtualMachineConfiguration = false; - - this.AvailableOSFamilies = new List(Common.SupportedOSFamilyDictionary.Keys); - } - - public CommandBase CreatePool - { - get - { - return new CommandBase( - async (o) => - { - this.IsBusy = true; - try - { - await this.CreatePoolAsync(); - } - finally - { - this.IsBusy = false; - } - } - ); - } - } - - private async Task CreatePoolAsync() - { - try - { - if (this.IsInputValid()) - { - System.Threading.Tasks.Task asyncTask; - - if (!this.UseAutoscale) - { - asyncTask = this.batchService.CreatePoolAsync( - this.PoolId, - this.SelectedVirtualMachineSize, - this.TargetDedicated, - this.TargetLowPriority, - null, - this.InterComputeNodeCommunicationEnabled, - this.VirtualSubnetId, - this.GetCloudServiceConfigurationOptions(), - this.GetVirtualMachineConfigurationOptions(), - this.MaxTasksPerComputeNode, - this.Timeout, - this.GetStartTaskOptions()); - } - else - { - asyncTask = this.batchService.CreatePoolAsync( - this.PoolId, - this.SelectedVirtualMachineSize, - null, - null, - this.AutoscaleFormula, - this.InterComputeNodeCommunicationEnabled, - this.VirtualSubnetId, - this.GetCloudServiceConfigurationOptions(), - this.GetVirtualMachineConfigurationOptions(), - this.MaxTasksPerComputeNode, - this.Timeout, - this.GetStartTaskOptions()); - } - - AsyncOperationTracker.Instance.AddTrackedOperation(new AsyncOperationModel( - asyncTask, - new PoolOperation(PoolOperation.AddPool, this.poolId))); - await asyncTask; - - Messenger.Default.Send(new RefreshMessage(RefreshTarget.Pools)); - - Messenger.Default.Send(new GenericDialogMessage(string.Format("Successfully created pool {0}", this.PoolId))); - this.PoolId = string.Empty; //So that the user cannot accidentally try to create the same pool twice - } - } - catch (Exception e) - { - Messenger.Default.Send(new GenericDialogMessage(e.ToString())); - } - } - - private StartTaskOptions GetStartTaskOptions() - { - if (HasStartTask) - { - return new StartTaskOptions - { - CommandLine = this.StartTaskCommandLine, - ResourceFiles = ResourceFileStringParser.Parse(this.StartTaskResourceFiles).Files.ToList(), - RunElevated = this.StartTaskRunElevated, - }; - } - - return null; - } - - private CloudServiceConfigurationOptions GetCloudServiceConfigurationOptions() - { - if (!this.HasVirtualMachineConfiguration) - { - string osFamilyString; - if (Common.SupportedOSFamilyDictionary.ContainsKey(this.SelectedOSFamily)) - { - osFamilyString = Common.SupportedOSFamilyDictionary[this.SelectedOSFamily]; - } - else - { - osFamilyString = this.SelectedOSFamily; - } - - return new CloudServiceConfigurationOptions() - { - OSFamily = osFamilyString, - OSVersion = this.SelectedOSVersion - }; - } - - return null; - } - - private VirtualMachineConfigurationOptions GetVirtualMachineConfigurationOptions() - { - if (this.HasVirtualMachineConfiguration) - { - return new VirtualMachineConfigurationOptions() - { - Version = this.Version, - EnableWindowsAutomaticUpdates = this.EnableWindowsAutomaticUpdates, - NodeAgentSkuId = this.NodeAgentSkuId, - Offer = this.Offer, - Publisher = this.Publisher, - SkuId = this.Sku - }; - } - - return null; - } - - private bool IsInputValid() - { - if (string.IsNullOrEmpty(this.PoolId)) - { - Messenger.Default.Send(new GenericDialogMessage("Invalid values for Pool Id")); - return false; - } - else if (this.UseAutoscale) - { - if (string.IsNullOrEmpty(this.AutoscaleFormula)) - { - Messenger.Default.Send(new GenericDialogMessage("Invalid value for Autoscale Formula")); - return false; - } - } - else if (this.TargetDedicated < 0) - { - Messenger.Default.Send(new GenericDialogMessage("Invalid values for Target Dedicated")); - return false; - } - else if (this.HasStartTask) - { - if (string.IsNullOrEmpty(this.StartTaskCommandLine)) - { - Messenger.Default.Send(new GenericDialogMessage("Start task must have a command line")); - return false; - } - var resourceFiles = ResourceFileStringParser.Parse(this.StartTaskResourceFiles); - if (resourceFiles.HasErrors) - { - Messenger.Default.Send(new GenericDialogMessage(String.Join(Environment.NewLine, resourceFiles.Errors))); - return false; - } - } - - return true; - } - } -} diff --git a/CSharp/BatchExplorer/ViewModels/GenericMessageViewModel.cs b/CSharp/BatchExplorer/ViewModels/GenericMessageViewModel.cs deleted file mode 100644 index a15f745d..00000000 --- a/CSharp/BatchExplorer/ViewModels/GenericMessageViewModel.cs +++ /dev/null @@ -1,31 +0,0 @@ -//Copyright (c) Microsoft Corporation - -using GalaSoft.MvvmLight.Messaging; -using Microsoft.Azure.BatchExplorer.Helpers; -using Microsoft.Azure.BatchExplorer.Messages; - -namespace Microsoft.Azure.BatchExplorer.ViewModels -{ - public class GenericMessageViewModel : EntityBase - { - #region Public UI Properties - - public string Message { get; private set; } - - public CommandBase Ok - { - get - { - return new CommandBase((item) => Messenger.Default.Send(new CloseGenericMessage())); - } - } - - #endregion - - public GenericMessageViewModel(string message) - { - this.Message = message; - - } - } -} diff --git a/CSharp/BatchExplorer/ViewModels/HeatmapViewModel.cs b/CSharp/BatchExplorer/ViewModels/HeatmapViewModel.cs deleted file mode 100644 index 37a74ab2..00000000 --- a/CSharp/BatchExplorer/ViewModels/HeatmapViewModel.cs +++ /dev/null @@ -1,50 +0,0 @@ -//Copyright (c) Microsoft Corporation - -using System; -using System.Collections.ObjectModel; -using GalaSoft.MvvmLight.Messaging; -using Microsoft.Azure.BatchExplorer.Helpers; -using Microsoft.Azure.BatchExplorer.Messages; -using Microsoft.Azure.BatchExplorer.Models; - -namespace Microsoft.Azure.BatchExplorer.ViewModels -{ - public class HeatMapViewModel : EntityBase - { - #region Public UI Properties - - public HeatMapModel HeatMap { get; private set; } - - public ObservableCollection RefreshIntervalChoices { get; private set; } - - private int refreshIntervalSeconds; - public int RefreshIntervalSeconds - { - get { return this.refreshIntervalSeconds; } - set - { - this.refreshIntervalSeconds = value; - Messenger.Default.Send(new HeatMapPollIntervalUpdatedMessage(this)); - } - } - - public TimeSpan RefreshInterval - { - get { return TimeSpan.FromSeconds(this.RefreshIntervalSeconds); } - } - - #endregion - - public HeatMapViewModel(HeatMapModel heatMapModel) - { - this.HeatMap = heatMapModel; - - this.RefreshIntervalChoices = new ObservableCollection() - { - 1, 5, 15, 30, 60, 180 - }; - this.RefreshIntervalSeconds = 30; //Default - } - - } -} diff --git a/CSharp/BatchExplorer/ViewModels/MainViewModel.cs b/CSharp/BatchExplorer/ViewModels/MainViewModel.cs deleted file mode 100644 index b1055d7d..00000000 --- a/CSharp/BatchExplorer/ViewModels/MainViewModel.cs +++ /dev/null @@ -1,1808 +0,0 @@ -//Copyright (c) Microsoft Corporation - -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.ComponentModel; -using System.ComponentModel.Composition; -using System.Diagnostics; -using System.Globalization; -using System.IO; -using System.Linq; -using System.Threading.Tasks; -using System.Windows; -using System.Windows.Data; -using GalaSoft.MvvmLight.Messaging; -using Microsoft.Azure.Batch; -using Microsoft.Azure.BatchExplorer.Helpers; -using Microsoft.Azure.BatchExplorer.Messages; -using Microsoft.Azure.BatchExplorer.Models; -using Microsoft.Azure.BatchExplorer.PluginInterfaces.AccountPlugin; - -namespace Microsoft.Azure.BatchExplorer.ViewModels -{ - /// - /// The viewmodel for the main view of the UI - /// - public class MainViewModel : EntityBase - { - /// - /// The manager for the accounts and the related data - /// - [ImportMany(typeof(IAccountManager))] - private IEnumerable> ManagerCollection { get; set; } - - public List AccountManagers { get; private set; } - - public Account ActiveAccount { get; private set; } - - #region Public UI Properties - - private bool poolTabIsSelected; - /// - /// True if the Pool Tab is selected - /// - public bool PoolTabIsSelected - { - get - { - return this.poolTabIsSelected; - } - set - { - this.poolTabIsSelected = value; - FirePropertyChangedEvent("PoolTabIsSelected"); - } - } - - private bool jobScheduleTabIsSelected; - /// - /// True if the Pool Tab is selected - /// - public bool JobScheduleTabIsSelected - { - get - { - return this.jobScheduleTabIsSelected; - } - set - { - this.jobScheduleTabIsSelected = value; - FirePropertyChangedEvent("JobScheduleTabIsSelected"); - if (value) - { - this.JobScheduleDetailTabIsSelected = true; - } - } - } - - private bool jobTabIsSelected; - /// - /// True if the Job Tab is selected - /// - public bool JobTabIsSelected - { - get - { - return this.jobTabIsSelected; - } - set - { - this.jobTabIsSelected = value; - FirePropertyChangedEvent("JobTabIsSelected"); - } - } - - private ICollectionView jobCollection; - - /// - /// The collection of jobs for an account - /// - public ICollectionView Jobs - { - get - { - return this.jobCollection; - } - set - { - this.jobCollection = value; - FirePropertyChangedEvent("Jobs"); - } - } - - private ICollectionView jobScheduleCollection; - /// - /// The collection of job schedules for an account - /// - public ICollectionView JobSchedules - { - get - { - return this.jobScheduleCollection; - } - set - { - this.jobScheduleCollection = value; - FirePropertyChangedEvent("JobSchedules"); - } - } - - private bool jobScheduleDetailTabIsSelected; - /// - /// True if the job schedule tab is selected - /// - public bool JobScheduleDetailTabIsSelected - { - get - { - return this.jobScheduleDetailTabIsSelected; - } - set - { - this.jobScheduleDetailTabIsSelected = value; - FirePropertyChangedEvent("JobScheduleDetailTabIsSelected"); - } - } - - private bool certificatesTabIsSelected; - /// - /// True if the Certificates tab is selected - /// - public bool CertificatesTabIsSelected - { - get - { - return this.certificatesTabIsSelected; - } - set - { - this.certificatesTabIsSelected = value; - FirePropertyChangedEvent("CertificatesTabIsSelected"); - } - } - - private ICollectionView certificatesCollection; - - /// - /// The collection of certificates for an account - /// - public ICollectionView Certificates - { - get - { - return this.certificatesCollection; - } - set - { - this.certificatesCollection = value; - FirePropertyChangedEvent("Certificates"); - } - } - - private bool leftSpinnerIsVisible; - /// - /// Controls visibility of the wait spinner on the left - /// - public bool LeftSpinnerIsVisible - { - get - { - return this.leftSpinnerIsVisible; - } - set - { - this.leftSpinnerIsVisible = value; - FirePropertyChangedEvent("LeftSpinnerIsVisible"); - } - } - - private bool upperRightSpinnerIsVisible; - /// - /// Controls visibility of the wait spinner on the upper right - /// - public bool UpperRightSpinnerIsVisible - { - get - { - return this.upperRightSpinnerIsVisible; - } - set - { - this.upperRightSpinnerIsVisible = value; - FirePropertyChangedEvent("UpperRightSpinnerIsVisible"); - } - } - - private bool _lowerRightSpinnerIsVisible; - /// - /// Controls visibility of the wait spinnner on the lower right - /// - public bool LowerRightSpinnerIsVisible - { - get - { - return _lowerRightSpinnerIsVisible; - } - set - { - _lowerRightSpinnerIsVisible = value; - FirePropertyChangedEvent("LowerRightSpinnerIsVisible"); - } - } - - private PoolModel selectedPool; - - public PoolModel SelectedPool - { - get - { - return this.selectedPool; - } - set - { - this.selectedPool = value; - if (this.selectedPool != null) - { - //Load the ComputeNodes in this pool just in time if they haven't been loaded yet - if (!this.selectedPool.HasLoadedChildren) - { - this.selectedPool.RefreshAsync(ModelRefreshType.Children).ContinueWith( - (t) => - { - FirePropertyChangedEvent("SelectedPool"); - FirePropertyChangedEvent("ComputeNodesTabTitle"); - }, - TaskContinuationOptions.NotOnFaulted); - } - else - { - this.SelectedComputeNode = this.selectedPool.ComputeNodes.Count > 0 ? this.selectedPool.ComputeNodes[0] : null; - FirePropertyChangedEvent("SelectedPool"); - FirePropertyChangedEvent("ComputeNodesTabTitle"); - } - } - } - } - - private ComputeNodeModel selectedComputeNode; - /// - /// The computeNode selected from the list of nodes - /// - public ComputeNodeModel SelectedComputeNode - { - get - { - return this.selectedComputeNode; - } - set - { - this.selectedComputeNode = value; - if (this.selectedComputeNode != null) - { - if (!this.selectedComputeNode.HasLoadedChildren) - { - AsyncOperationTracker.Instance.AddTrackedInternalOperation( - this.selectedComputeNode.RefreshAsync(ModelRefreshType.Children)); - } - } - FirePropertyChangedEvent("SelectedComputeNode"); - } - } - - private NodeFile selectedNodeFile; - public NodeFile SelectedNodeFile - { - get - { - return this.selectedNodeFile; - } - set - { - this.selectedNodeFile = value; - this.FirePropertyChangedEvent("SelectedNodeFile"); - } - - } - - private NodeFile selectedTaskFile; - public NodeFile SelectedTaskFile - { - get - { - return this.selectedTaskFile; - } - set - { - this.selectedTaskFile = value; - this.FirePropertyChangedEvent("SelectedTaskFile"); - } - } - - private JobScheduleModel selectedJobSchedule; - - public JobScheduleModel SelectedJobSchedule - { - get - { - return this.selectedJobSchedule; - } - set - { - this.selectedJobSchedule = value; - FirePropertyChangedEvent("SelectedJobSchedule"); - } - } - - private JobModel selectedJob; - - public JobModel SelectedJob - { - get - { - return this.selectedJob; - } - set - { - this.selectedJob = value; - if (this.selectedJob != null) - { - if (!this.selectedJob.HasLoadedChildren) - { - AsyncOperationTracker.Instance.AddTrackedInternalOperation( - this.selectedJob.RefreshAsync(ModelRefreshType.Children).ContinueWith( - (t) => - { - FirePropertyChangedEvent("SelectedJob"); - FirePropertyChangedEvent("TasksTabTitle"); - }, - TaskContinuationOptions.NotOnFaulted)); - } - else - { - this.SelectedTask = this.selectedJob.Tasks.Count > 0 ? this.selectedJob.Tasks[0] : null; - FirePropertyChangedEvent("SelectedJob"); - FirePropertyChangedEvent("TasksTabTitle"); - } - } - } - } - - private TaskModel selectedTask; - public TaskModel SelectedTask - { - get - { - return this.selectedTask; - } - set - { - this.selectedTask = value; - this.FirePropertyChangedEvent("SelectedTask"); - } - } - - private CertificateModel selectedCertificate; - - public CertificateModel SelectedCertificate - { - get - { - return this.selectedCertificate; - } - set - { - this.selectedCertificate = value; - FirePropertyChangedEvent("SelectedCertificate"); - } - } - - public string TitleString - { - get - { - if (this.ActiveAccount != null && - this.ActiveAccount.Alias != null && - this.ActiveAccount.Alias.Length > 0) - { - return string.Format(CultureInfo.CurrentCulture, "Batch Explorer - {0}", this.ActiveAccount.Alias); - } - else - { - return "Batch Explorer"; - } - } - } - - public bool IsAccountConnected - { - get - { - return this.ActiveAccount != null; - } - } - - public string JobsSearchFilter { get; set; } - - #endregion - - private ObservableCollection pools; - - /// - /// The collection of pools for this account - /// - public ICollectionView Pools { get; private set; } - - private ObservableCollection jobSchedules; - - private ObservableCollection jobs; - - private ObservableCollection certificates; - - private Task asyncOperationCompletionMonitoringTask; - - private Cached> cachedNodeAgentSkus; - - #region Tab title binding properties - public string JobScheduleTabTitle - { - get - { - const string jobScheduleTabPrefix = "Job Schedules"; - return this.jobSchedules == null ? jobScheduleTabPrefix : string.Format(CultureInfo.CurrentCulture, "{0} ({1})", jobScheduleTabPrefix, this.jobSchedules.Count); - } - } - - public string PoolTabTitle - { - get - { - const string poolTabPrefix = "Pools"; - return this.pools == null ? poolTabPrefix : string.Format(CultureInfo.CurrentCulture, "{0} ({1})", poolTabPrefix, this.pools.Count); - } - } - - public string JobTabTitle - { - get - { - const string jobTabPrefix = "Jobs"; - return this.jobs == null ? jobTabPrefix : string.Format(CultureInfo.CurrentCulture, "{0} ({1})", jobTabPrefix, this.jobs.Count); - } - } - - public string CertificatesTabTitle - { - get - { - const string certsTabPrefix = "Certificates"; - return this.certificates == null ? certsTabPrefix : string.Format(CultureInfo.CurrentCulture, "{0} ({1})", certsTabPrefix, this.certificates.Count); - } - } - - public string TasksTabTitle - { - get - { - const string taskTabPrefix = "Tasks"; - return this.SelectedJob == null || this.SelectedJob.Tasks == null ? taskTabPrefix : string.Format(CultureInfo.CurrentCulture, "{0} ({1})", taskTabPrefix, this.SelectedJob.Tasks.Count); - } - } - - public string ComputeNodesTabTitle - { - get - { - const string computeNodeTabPrefix = "Compute Nodes"; - return SelectedPool == null || SelectedPool.ComputeNodes == null ? computeNodeTabPrefix : string.Format(CultureInfo.CurrentCulture, "{0} ({1})", computeNodeTabPrefix, SelectedPool.ComputeNodes.Count); - } - } - - #endregion - - //TODO: This should NOT be static, but for now it is to allow easy access by poor - //TODO: models/viewmodels who are missing object model functionality and so must resort to the - //TODO: protocol layer. Once we are fully OM integrated this should become a private instance variable again - public static IDataProvider dataProvider; - - /// - /// The parameterless constructor for the MainViewModel - currently provides dummy data if USE_DUMMY_DATA is defined - /// - public MainViewModel() - { - AddAccount = new CommandBase(this.AddAccountImpl); - EditAccount = new CommandBase(this.EditAccountImpl); - - this.RegisterMessages(); - - //TODO: Should do this all in an "onload" or something to avoid overloaded constructor work? - Microsoft.Azure.BatchExplorer.Helpers.Common.LoadPlugins(this); - - this.AccountManagers = new List(); - - foreach (Lazy manager in this.ManagerCollection) - { - manager.Value.InitalizeAsync().Wait(); //TODO: Do this elsewhere and use the async method? - this.AccountManagers.Add(new AccountManagerContainer(manager.Value, manager.Metadata)); - } - - JobTabIsSelected = true; - - //Register for async operation updates - Messenger.Default.Register(this, (o) => this.FirePropertyChangedEvent("AsyncOperations")); - - //Begin a background thread which monitors the status of internal async operations and observes any exceptions - asyncOperationCompletionMonitoringTask = AsyncOperationTracker.InternalOperationResultHandler(); - } - - #region Account operations - - /// - /// Add an account - /// - public CommandBase AddAccount { get; } - - private void AddAccountImpl(object o) - { - try - { - AccountManagerContainer managerContainer = (AccountManagerContainer)o; - - //Make sure we are prepared to respond to a confirm AND a cancel message - don't forget to unregister both listeners - Messenger.Default.Register(this, message => - { - //We got a confirm, so extract the account from the message and add it - try - { - message.AccountManager.AddAccountAsync(message.AccountToAdd).Wait(); - Messenger.Default.Send(new CloseGenericPopup()); //Inform the view to close - } - catch (Exception e) - { - Messenger.Default.Send(new GenericDialogMessage(e.ToString())); - } - }); - - Messenger.Default.Register(this, message => - { - Messenger.Default.Unregister(this); - Messenger.Default.Unregister(this); - }); - - - Messenger.Default.Send(new AddAccountMessage() - { - AccountDialogViewModel = new AccountDialogViewModel(managerContainer.AccountManager, managerContainer.AccountManager.OperationFactory) - }); - } - catch (Exception e) - { - Messenger.Default.Send(new GenericDialogMessage(e.ToString())); - } - } - - /// - /// Connect to an account - /// - public CommandBase ConnectAccount - { - get - { - return new CommandBase( - (selectedAccount) => - { - try - { - dataProvider = new BasicDataProvider(selectedAccount as Account); - this.ActiveAccount = (selectedAccount as Account); - GetDataAsync(dataProvider, true, true, true, true).ContinueWith( - (task) => - { - FirePropertyChangedEvent("TitleString"); - FirePropertyChangedEvent("IsAccountConnected"); - }); - - //Set up the cache functions for this account - this.cachedNodeAgentSkus = new Cached>(() => dataProvider.ListNodeAgentSkusAsync(), TimeSpan.FromMinutes(10)); - } - catch (Exception e) - { - Messenger.Default.Send(new GenericDialogMessage(e.ToString())); - } - }); - } - } - - /// - /// Edit an account - /// - public CommandBase EditAccount { get; } - - private void EditAccountImpl(object selectedAccount) - { - try - { - Account account = selectedAccount as Account; - IAccountManager accountManager = account.ParentAccountManager; - - //Make sure we are set up to respond to both a confirm AND a cancel message - don't forget to unregister both listeners - Messenger.Default.Register(this, (message) => - { - try - { - message.AccountManager.CommitEditAsync(message.AccountToEdit).Wait(); - Messenger.Default.Send(new CloseGenericPopup()); - } - catch (Exception e) - { - Messenger.Default.Send(new GenericDialogMessage(e.ToString())); - } - }); - - Messenger.Default.Register(this, message => - { - Messenger.Default.Unregister(this); - Messenger.Default.Unregister(this); - }); - - Account tempAccount = accountManager.CloneAccountForEditAsync(account).Result; - Messenger.Default.Send(new EditAccountMessage() - { - AccountDialogViewModel = new AccountDialogViewModel(tempAccount, accountManager, accountManager.OperationFactory) - }); - } - catch (Exception e) - { - Messenger.Default.Send(new GenericDialogMessage(e.ToString())); - } - } - - /// - /// Delete an account - /// - public CommandBase DeleteAccount - { - get - { - return new CommandBase( - (selectedAccount) => - { - try - { - Account account = selectedAccount as Account; - IAccountManager accountManager = account.ParentAccountManager; - - Messenger.Default.Register(this, (message) => - { - accountManager.DeleteAccountAsync(account).Wait(); - Messenger.Default.Send(new CloseGenericPopup()); - }); - - Messenger.Default.Register(this, (message) => - { - Messenger.Default.Unregister(this); - Messenger.Default.Unregister(this); - }); - Messenger.Default.Send(new ShowDeleteWarningMessage()); - } - catch (Exception e) - { - Messenger.Default.Send(new GenericDialogMessage(e.ToString())); - } - - }); - } - } - - #endregion - - #region Refresh operations - - /// - /// Refresh all job schedules, jobs, and pools - /// - public CommandBase RefreshAll - { - get - { - return new CommandBase( - (o) => AsyncOperationTracker.Instance.AddTrackedInternalOperation(GetDataAsync(dataProvider, true, true, true, true))); - } - } - - /// - /// Refresh all job schedules - /// - public CommandBase RefreshJobSchedules - { - get - { - return new CommandBase( - (o) => AsyncOperationTracker.Instance.AddTrackedInternalOperation(this.GetDataAsync(dataProvider, jobSchedules: true, jobs: false, pools: false, certificates: false))); - } - } - - /// - /// Refresh all jobs - /// - public CommandBase RefreshJobs - { - get - { - return new CommandBase( - (o) => AsyncOperationTracker.Instance.AddTrackedInternalOperation(this.GetDataAsync(dataProvider, jobSchedules: false, jobs: true, pools: false, certificates: false))); - } - } - - /// - /// Delete selected jobs - /// - public CommandBase DeleteSelectedJobs - { - get - { - return new CommandBase( - async (commandArg) => - { - if (this.jobs.Any(a => a.IsChecked)) - { - try - { - IEnumerable deletedIds = this.jobs.Where(a => a.IsChecked).Select(s => s.Id); - Messenger.Default.Register(this, async (message) => - { - if (message.MessageBoxResult == MessageBoxResult.Yes) - { - this.LeftSpinnerIsVisible = true; - FirePropertyChangedEvent("LeftSpinnerIsVisible"); - foreach (var job in this.jobs) - { - if (job.IsChecked) - { - await job.DeleteAsync(false); - } - } - } - Messenger.Default.Unregister(this); - }); - Messenger.Default.Send(new LaunchMultibuttonDialogMessage() - { - Caption = "Confirm delete", - DialogMessage = deletedIds.Count() > 1 ? - string.Format("Are you sure you want to delete {0} selected jobs?", deletedIds.Count()) : - "Are you sure you want to delete the job?", - MessageBoxButton = MessageBoxButton.YesNo - }); - - //NOTE: There is an outstanding issue where the tab count does not refresh after awating completion of asynchronous opration. - //So keep on refreshing until we see the deleted record inside the list or timeout the retry after 1 min, which ever is earlier. - bool isRefreshRequired = true; - DateTime startTime = DateTime.Now; - while (isRefreshRequired) - { - var refreshedJobs = await dataProvider.GetJobCollectionAsync(this.JobsSearchFilter); - isRefreshRequired = refreshedJobs.Any(a => deletedIds.Contains(a.Id)) && (DateTime.Now - startTime).TotalMilliseconds < 60000; - if (!isRefreshRequired) - { - this.jobs = new ObservableCollection(refreshedJobs); - this.jobCollection = CollectionViewSource.GetDefaultView(this.jobs); - this.selectedJob = null; - this.Jobs.Refresh(); - - //Refresh the job pane - FirePropertyChangedEvent("Jobs"); - FirePropertyChangedEvent("JobTabTitle"); - - //Refresh the task pane - FirePropertyChangedEvent("SelectedJob"); - FirePropertyChangedEvent("TasksTabTitle"); - } - else - { - await Task.Delay(1000); - } - } - } - catch (Exception ex) - { - Messenger.Default.Send(new GenericDialogMessage(ex.Message)); - } - finally - { - this.LeftSpinnerIsVisible = false; - FirePropertyChangedEvent("LeftSpinnerIsVisible"); - } - } - }); - } - } - - /// - /// Select all jobs from header checkbox - /// - public CommandBase SelectAllJobs - { - get - { - return new CommandBase( - (commandArg) => - { - if (this.jobs != null && this.jobs.Count > 0) - { - foreach (var job in this.jobs) - { - job.IsChecked = bool.Parse(commandArg.ToString()); - } - } - }); - } - } - - /// - /// Refresh all pools - /// - public CommandBase RefreshPools - { - get - { - return new CommandBase( - (o) => AsyncOperationTracker.Instance.AddTrackedInternalOperation(this.GetDataAsync(dataProvider, jobSchedules: false, jobs: false, pools: true, certificates: false))); - } - } - - /// - /// Refresh all tasks - /// - public CommandBase RefreshTasks - { - get - { - return new CommandBase( - (item) => - { - var jobModel = ((JobModel)item); - if (jobModel != null) - { - AsyncOperationTracker.Instance.AddTrackedInternalOperation(jobModel.RefreshAsync(ModelRefreshType.Children)); - } - }); - } - } - - /// - /// Refresh all certificates - /// - public CommandBase RefreshCertificates - { - get - { - return new CommandBase( - (o) => AsyncOperationTracker.Instance.AddTrackedInternalOperation(this.GetDataAsync(dataProvider, jobSchedules: false, jobs: false, pools: false, certificates: true))); - } - } - - #endregion - - #region VM operations - - /// - /// Reboot the selected Compute Node - /// - public CommandBase RebootComputeNode - { - get - { - return new CommandBase( - (o) => - { - Messenger.Default.Register(this, (message) => - { - if (message.Confirmation == ComputeNodeRebootConfimation.Confirmed) - { - AsyncOperationTracker.Instance.AddTrackedInternalOperation(this.SelectedComputeNode.RebootAsync()); - } - - Messenger.Default.Unregister(this); - }); - - Messenger.Default.Send(new RebootComputeNodeMessage()); - } - ); - } - } - - /// - /// Reimage the selected Compute Node - /// - public CommandBase ReimageComputeNode - { - get - { - return new CommandBase( - (o) => - { - Messenger.Default.Register(this, (message) => - { - if (message.Confirmation == ComputeNodeReimageConfimation.Confirmed) - { - AsyncOperationTracker.Instance.AddTrackedInternalOperation(this.SelectedComputeNode.ReimageAsync()); - } - - Messenger.Default.Unregister(this); - }); - - Messenger.Default.Send(new ReimageComputeNodeMessage()); - } - ); - } - } - - /// - /// Disables scheduling on the selected Compute Node - /// - public CommandBase DisableSchedulingComputeNode - { - get - { - return new CommandBase( - (o) => - { - Messenger.Default.Register(this, (message) => - { - if (message.Confirmation == ComputeNodeDisableSchedulingConfimation.Confirmed) - { - AsyncOperationTracker.Instance.AddTrackedInternalOperation(this.SelectedComputeNode.DisableSchedulingAsync()); - } - - Messenger.Default.Unregister(this); - }); - - Messenger.Default.Send(new DisableSchedulingComputeNodeMessage()); - } - ); - } - } - - /// - /// Enables scheduling on the selected Compute Node - /// - public CommandBase EnableSchedulingComputeNode - { - get - { - return new CommandBase( - (o) => - { - AsyncOperationTracker.Instance.AddTrackedInternalOperation(this.SelectedComputeNode.EnableSchedulingAsync()); - - Messenger.Default.Send(new EnableSchedulingComputeNodeMessage()); - } - ); - } - } - - /// - /// Download RDP from the selected ComputeNode and prompt the user for a save file dialog - /// - public CommandBase DownloadRDP - { - get - { - return new CommandBase( - (o) => - { - AsyncOperationTracker.Instance.AddTrackedInternalOperation(this.DownloadRDPFileAsync(this.SelectedComputeNode)); - } - ); - } - } - - /// - /// Download RDP from the selected ComputeNode and open it. - /// - public CommandBase OpenRDP - { - get - { - return new CommandBase( - (o) => - { - AsyncOperationTracker.Instance.AddTrackedInternalOperation(this.DownloadRDPFileAsync(this.SelectedComputeNode, Path.GetTempPath())); - } - ); - } - } - - /// - /// Get SSH settngs for the selected ComputeNode - /// - public CommandBase GetSSH - { - get - { - return new CommandBase( - (o) => - { - var task = this.GetSSHSettingsAsync(this.SelectedComputeNode); - AsyncOperationTracker.Instance.AddTrackedInternalOperation(task); - task.ContinueWith(t => - { - var sshSettings = t.Result; - var sshCommand = $"ssh -p {sshSettings.Port} @{sshSettings.IPAddress}"; - Messenger.Default.Send(new GenericDialogMessage(sshCommand)); - }); - } - ); - } - } - - /// - /// Add a user to the selected compute node - /// - public CommandBase AddComputeNodeUser - { - get - { - return new CommandBase( - (o) => - { - ComputeNodeModel selectedComputeNode = (ComputeNodeModel)o; - Messenger.Default.Send(new ShowCreateComputeNodeUserWindow(selectedComputeNode.ParentPool.Id, selectedComputeNode.Id)); - } - ); - } - } - - public CommandBase EditUserOnComputeNode - { - get - { - return new CommandBase( - (o) => - { - Messenger.Default.Send(new GenericDialogMessage("TODO: Edit user on Compute Node")); - } - ); - } - } - - public CommandBase DeleteUserFromComputeNode - { - get - { - return new CommandBase( - (o) => - { - Messenger.Default.Send(new GenericDialogMessage("TODO: Delete user from Compute Node")); - } - ); - } - } - - #endregion - - #region File operations - - public CommandBase OpenTaskFile - { - get - { - return new CommandBase( - (o) => - { - try - { - AsyncOperationTracker.Instance.AddTrackedInternalOperation(this.DownloadFileAsync( - this.SelectedTask.SelectedTaskFile.Path, Path.GetTempPath(), false)); - } - catch (Exception e) - { - Messenger.Default.Send(new GenericDialogMessage(e.ToString())); - } - } - ); - } - } - - public CommandBase DownloadTaskFile - { - get - { - return new CommandBase( - (o) => - { - try - { - AsyncOperationTracker.Instance.AddTrackedInternalOperation(this.DownloadFileAsync( - this.SelectedTask.SelectedTaskFile.Path, isNodeFile: false)); - } - catch (Exception e) - { - Messenger.Default.Send(new GenericDialogMessage(e.ToString())); - } - - } - ); - } - } - - public CommandBase OpenNodeFile - { - get - { - return new CommandBase( - (o) => - { - AsyncOperationTracker.Instance.AddTrackedInternalOperation(this.DownloadFileAsync(this.SelectedNodeFile.Path, Path.GetTempPath())); - } - ); - } - } - - public CommandBase DownloadNodeFile - { - get - { - return new CommandBase( - (o) => - { - AsyncOperationTracker.Instance.AddTrackedInternalOperation(this.DownloadFileAsync(this.SelectedNodeFile.Path)); - } - ); - } - } - - #endregion - - #region item-specific commands - /// - /// Refresh a selected item that implements IRefreshableObject - /// - public CommandBase RefreshItem - { - get - { - return new CommandBase( - (item) => - { - var castItem = (item as ModelBase); - if (castItem != null) - { - castItem.RefreshAsync(ModelRefreshType.Children | ModelRefreshType.Basic).ContinueWith((t) => - { - var job = castItem as JobModel; - if (job != null) - { - FirePropertyChangedEvent("TasksTabTitle"); - } - - var pool = castItem as PoolModel; - if (pool != null) - { - FirePropertyChangedEvent("Pools"); - FirePropertyChangedEvent("ComputeNodesTabTitle"); - } - - //Nothing to do for compute nodes - }); - } - }); - } - } - - - /// - /// Terminate the selected item - /// - public CommandBase Terminate - { - get - { - return new CommandBase( - (item) => - { - var task = item as TaskModel; - if (task != null) - { - AsyncOperationTracker.Instance.AddTrackedInternalOperation(task.TerminateAsync()); - } - }); - } - } - - /// - /// Delete the selected item - /// - public CommandBase Delete - { - get - { - return new CommandBase( - (item) => - { - var castItem = (item as ModelBase); - if (castItem != null) - { - string objectType = string.Empty; - string objectName = string.Empty; - string diaglogMessageFormat = "Are you sure you want to delete {0} '{1}'?"; - var itemType = item.GetType(); - if (itemType == typeof(PoolModel)) - { - PoolModel pool = item as PoolModel; - objectType = "Pool"; - objectName = pool.Id; - - diaglogMessageFormat += "\n\nThis is a non-reversible operation which will remove all nodes and data on those nodes from your account"; - } - else if (itemType == typeof(TaskModel)) - { - TaskModel taskModel = item as TaskModel; - - objectType = "Task"; - objectName = taskModel.Id; - } - else if (itemType == typeof(JobModel)) - { - JobModel jobModel = item as JobModel; - - objectType = "Job"; - objectName = jobModel.Id; - } - else if (itemType == typeof(JobScheduleModel)) - { - JobScheduleModel jobScheduleModel = item as JobScheduleModel; - - objectType = "Job Schedule"; - objectName = jobScheduleModel.Id; - } - else if (itemType == typeof(CertificateModel)) - { - CertificateModel certificate = item as CertificateModel; - - objectType = "Certificate"; - objectName = certificate.Thumbprint; - } - - Messenger.Default.Register(this, (message) => - { - if (message.MessageBoxResult == MessageBoxResult.Yes) - { - if (itemType == typeof(PoolModel)) - { - PoolModel pool = item as PoolModel; - AsyncOperationTracker.Instance.AddTrackedInternalOperation(pool.DeleteAsync()); - } - else if (itemType == typeof(TaskModel)) - { - TaskModel taskModel = item as TaskModel; - AsyncOperationTracker.Instance.AddTrackedInternalOperation(taskModel.DeleteAsync()); - } - else if (itemType == typeof(CertificateModel)) - { - CertificateModel certificate = item as CertificateModel; - AsyncOperationTracker.Instance.AddTrackedInternalOperation(certificate.DeleteAsync()); - } - else if (itemType == typeof(JobScheduleModel)) - { - JobScheduleModel jobScedule = item as JobScheduleModel; - AsyncOperationTracker.Instance.AddTrackedInternalOperation(jobScedule.DeleteAsync()); - } - } - Messenger.Default.Unregister(this); - }); - Messenger.Default.Send(new LaunchMultibuttonDialogMessage() - { - Caption = "Confirm delete", - DialogMessage = string.Format(diaglogMessageFormat, objectType, objectName), - MessageBoxButton = MessageBoxButton.YesNo - }); - } - }); - } - } - - public CommandBase ResizePool - { - get - { - return new CommandBase( - (o) => - { - PoolModel pool = (PoolModel)o; - Messenger.Default.Send(new ShowResizePoolWindow( - pool.Id, - pool.CurrentDedicated, - pool.CurrentLowPriority, - pool.CurrentAutoScaleFormula)); - }); - } - } - - public CommandBase StopResizePool - { - get - { - return new CommandBase( - (o) => - { - PoolModel pool = (PoolModel)o; - AsyncOperationTracker.Instance.AddTrackedInternalOperation(pool.StopResizeAsync()); - }); - } - } - - #endregion - - public CommandBase ShowAboutDialog - { - get - { - return new CommandBase( - (o) => - { - Messenger.Default.Send(new ShowAboutWindow()); - } - ); - } - } - - #region Create operations - - public CommandBase CreatePool - { - get - { - return new CommandBase( - (o) => - { - // Call a new window to show the Create Pool UI - Messenger.Default.Send(new ShowCreatePoolWindow(this.cachedNodeAgentSkus)); - } - ); - } - } - - public CommandBase CreateJobSchedule - { - get - { - return new CommandBase( - (o) => - { - // Call a new window to show the Create Job Schedule UI - Messenger.Default.Send(new ShowCreateJobScheduleWindow()); - } - ); - } - } - - public CommandBase CreateJob - { - get - { - return new CommandBase( - (o) => - { - // Call a new window to show the Create Job UI - Messenger.Default.Send(new ShowCreateJobWindow()); - } - ); - } - } - - public CommandBase CreateCertificate - { - get - { - return new CommandBase( - (o) => - { - // Call a new window to show the Create Certificate UI - Messenger.Default.Send(new ShowCreateCertificateWindow()); - } - ); - } - } - - #endregion - - public CommandBase ShowHeatMap - { - get - { - return new CommandBase( - (o) => - { - PoolModel poolModel = (o as PoolModel); - string poolId = poolModel.Id; - - Task getPoolTask = dataProvider.Service.GetPoolAsync(poolId); - AsyncOperationTracker.Instance.AddTrackedOperation(new AsyncOperationModel( - getPoolTask, - new PoolOperation(PoolOperation.GetPool, poolId))); - getPoolTask.ContinueWith((asyncTask) => Messenger.Default.Send(new ShowHeatMapMessage(asyncTask.Result))); - } - ); - } - } - - public CommandBase Exit - { - get - { - return new CommandBase(x => Application.Current.Shutdown()); - } - } - - #region AsyncOperationTracker view commands and properties - - public IEnumerable AsyncOperations - { - get { return AsyncOperationTracker.Instance.AsyncOperations; } - } - - public AsyncOperationModel SelectedAsyncOperation { get; set; } - - public CommandBase ViewAsyncOperationDetails - { - get - { - return new CommandBase(o => - { - Messenger.Default.Send(new ShowAsyncOperationDetailWindow(this.SelectedAsyncOperation)); - }); - } - } - public CommandBase ClearAllAsyncOperations - { - get - { - return new CommandBase(o => - { - AsyncOperationTracker.Instance.Clear(); - }); - } - } - - #endregion - - #region Options specific commands and properties - - public CommandBase ViewOptionsDialog - { - get - { - return new CommandBase(o => - { - Messenger.Default.Send(new ShowOptionsDialogMessage()); - }); - } - } - - #endregion - - #region Private helper methods - - private void RegisterMessages() - { - Messenger.Default.Register(this, ProcessUpdateWaitSpinnerMessage); - - Messenger.Default.Register(this, - (message) => - { - switch (message.ItemToRefresh) - { - case RefreshTarget.Pools: - AsyncOperationTracker.Instance.AddTrackedInternalOperation(this.GetDataAsync(dataProvider, false, false, true, false)); - break; - case RefreshTarget.Jobs: - AsyncOperationTracker.Instance.AddTrackedInternalOperation(this.GetDataAsync(dataProvider, false, true, false, false)); - break; - case RefreshTarget.JobSchedules: - AsyncOperationTracker.Instance.AddTrackedInternalOperation(this.GetDataAsync(dataProvider, true, false, false, false)); - break; - case RefreshTarget.Certificates: - AsyncOperationTracker.Instance.AddTrackedInternalOperation(this.GetDataAsync(dataProvider, false, false, false, true)); - break; - } - } - ); - - Messenger.Default.Register(this, (message) => - { - ModelBase modelBase = message.Model; - - JobScheduleModel jobScheduleModel = modelBase as JobScheduleModel; - if (jobScheduleModel != null) - { - this.jobSchedules.Remove(jobScheduleModel); - FirePropertyChangedEvent("JobScheduleTabTitle"); - this.SelectedJobSchedule = null; - } - - PoolModel poolModel = modelBase as PoolModel; - if (poolModel != null) - { - this.pools.Remove(poolModel); - FirePropertyChangedEvent("PoolTabTitle"); - SelectedPool = null; - this.SelectedComputeNode = null; - } - - JobModel jobModel = modelBase as JobModel; - if (jobModel != null) - { - this.jobs.Remove(jobModel); - this.SelectedJob = null; - this.FirePropertyChangedEvent("JobTabTitle"); - this.FirePropertyChangedEvent("TasksTabTitle"); - } - - TaskModel taskModel = modelBase as TaskModel; - if (taskModel != null) - { - taskModel.ParentJob.Tasks.Remove(taskModel); - taskModel.ParentJob.UpdateTaskView(); - FirePropertyChangedEvent("TasksTabTitle"); - } - - ComputeNodeModel vmModel = modelBase as ComputeNodeModel; - if (vmModel != null) - { - vmModel.ParentPool.ComputeNodes.Remove(vmModel); - vmModel.ParentPool.UpdateNodeView(); - FirePropertyChangedEvent("ComputeNodesTabTitle"); - this.selectedComputeNode = null; - } - }); - } - - /// - /// Gets a specific set of data from the Batch service - /// - /// The provider to retrieve the data with - /// True if job schedule data should be retrieved - /// True if job data should be retrieved - /// True if pool data should be retrieved - /// True if certificates should be retrieved - /// - private async Task GetDataAsync(IDataProvider provider, bool jobSchedules, bool jobs, bool pools, bool certificates) - { - //Turn on the correct wait spinners - LeftSpinnerIsVisible = true; - UpperRightSpinnerIsVisible = false; - LowerRightSpinnerIsVisible = false; - - try - { - // - // Get all the job schedules - // - if (jobSchedules) - { - System.Threading.Tasks.Task> getJobSchedulesTask = provider.GetJobScheduleCollectionAsync(); - AsyncOperationTracker.Instance.AddTrackedOperation(new AsyncOperationModel( - getJobSchedulesTask, - new AccountOperation(AccountOperation.ListJobSchedules))); - - this.jobSchedules = new ObservableCollection(await getJobSchedulesTask); - this.jobScheduleCollection = CollectionViewSource.GetDefaultView(this.jobSchedules); - - this.JobSchedules.Refresh(); - FirePropertyChangedEvent("JobSchedules"); - FirePropertyChangedEvent("JobScheduleTabTitle"); - } - - this.SelectedJobSchedule = null; - - // - // Get all jobs - // - if (jobs) - { - System.Threading.Tasks.Task> getJobTask = provider.GetJobCollectionAsync(this.JobsSearchFilter); - AsyncOperationTracker.Instance.AddTrackedOperation(new AsyncOperationModel( - getJobTask, - new AccountOperation(AccountOperation.ListJobs))); - - this.jobs = new ObservableCollection(await getJobTask); - this.jobCollection = CollectionViewSource.GetDefaultView(this.jobs); - - this.Jobs.Refresh(); - FirePropertyChangedEvent("Jobs"); - FirePropertyChangedEvent("JobTabTitle"); - } - - this.SelectedJob = null; - - // - // Get all pools - // - if (pools) - { - System.Threading.Tasks.Task> getPoolsTask = provider.GetPoolCollectionAsync(); - AsyncOperationTracker.Instance.AddTrackedOperation(new AsyncOperationModel( - getPoolsTask, - new AccountOperation(AccountOperation.ListPools))); - - this.pools = new ObservableCollection(await getPoolsTask); - - Pools = CollectionViewSource.GetDefaultView(this.pools); - Pools.Refresh(); - FirePropertyChangedEvent("Pools"); - FirePropertyChangedEvent("PoolTabTitle"); - } - SelectedPool = null; - this.SelectedComputeNode = null; - - // - // Get all certificates - // - if (certificates) - { - System.Threading.Tasks.Task> getCertificatesTask = provider.GetCertificatesCollectionAsync(); - AsyncOperationTracker.Instance.AddTrackedOperation(new AsyncOperationModel( - getCertificatesTask, - new AccountOperation(AccountOperation.ListCertificates))); - - this.certificates = new ObservableCollection(await getCertificatesTask); - - Certificates = CollectionViewSource.GetDefaultView(this.certificates); - Certificates.Refresh(); - FirePropertyChangedEvent("Certificates"); - FirePropertyChangedEvent("CertificatesTabTitle"); - } - SelectedCertificate = null; - } - catch (Exception e) - { - Messenger.Default.Send(new GenericDialogMessage(e.ToString())); - } - finally - { - //Turn off the wait spinners - LowerRightSpinnerIsVisible = false; - UpperRightSpinnerIsVisible = false; - LeftSpinnerIsVisible = false; - } - } - - private void ProcessUpdateWaitSpinnerMessage(UpdateWaitSpinnerMessage message) - { - switch (message.PanelToChange) - { - case WaitSpinnerPanel.Left: - LeftSpinnerIsVisible = message.MakeSpinnerVisible; - break; - case WaitSpinnerPanel.UpperRight: - UpperRightSpinnerIsVisible = message.MakeSpinnerVisible; - break; - case WaitSpinnerPanel.LowerRight: - LowerRightSpinnerIsVisible = message.MakeSpinnerVisible; - break; - default: - throw new ArgumentOutOfRangeException(); - } - } - - private async System.Threading.Tasks.Task DownloadFileAsync(string file, string localDownloadTargetPath = null, bool isNodeFile = true) - { - string fileName = null; - try - { - bool? result; - - if (string.IsNullOrEmpty(localDownloadTargetPath)) - { - // Configure save file dialog box - Microsoft.Win32.SaveFileDialog saveFileDlg = new Microsoft.Win32.SaveFileDialog(); - saveFileDlg.FileName = Path.GetFileName(file); // Default file name - saveFileDlg.DefaultExt = ".txt"; // Default file extension. - saveFileDlg.Filter = "Text documents (.txt)|*.txt"; // Filter files by extension - - // Show save file dialog box - result = saveFileDlg.ShowDialog(); - if (result == true) - { - fileName = saveFileDlg.FileName; - } - } - else - { - fileName = Path.Combine(localDownloadTargetPath, Path.GetFileName(file)); - result = true; - } - - if (result == true) - { - // Save document - using (FileStream destStream = new FileStream(fileName, FileMode.Create)) - { - if (isNodeFile) - { - await this.SelectedComputeNode.DownloadFileAsync(file, destStream); - } - else - { - await this.SelectedTask.GetTaskFileAsync(file, destStream); - } - } - - // open text files - if (fileName.EndsWith(".txt", StringComparison.OrdinalIgnoreCase)) - { - Process.Start(fileName); - } - } - } - catch (Exception e) - { - if (!string.IsNullOrEmpty(fileName)) - { - if (File.Exists(fileName)) - { - File.Delete(fileName); //Delete the file if we have hit an exception - } - } - - Messenger.Default.Send(new GenericDialogMessage(e.ToString())); - } - } - - private async System.Threading.Tasks.Task DownloadRDPFileAsync(ComputeNodeModel computeNode, string localDownloadTargetPath = null) - { - string fileName = null; - bool? result; - if (string.IsNullOrEmpty(localDownloadTargetPath)) - { - // Configure save file dialog box - Microsoft.Win32.SaveFileDialog saveFileDlg = new Microsoft.Win32.SaveFileDialog(); - saveFileDlg.FileName = computeNode.Id; // Default file name - saveFileDlg.DefaultExt = ".rdp"; // Default file extension. - saveFileDlg.Filter = "RDP File (.rdp)|*.rdp"; // Filter files by extension - - // Show save file dialog box - result = saveFileDlg.ShowDialog(); - if (result == true) - { - fileName = saveFileDlg.FileName; - } - } - else - { - fileName = Path.Combine(localDownloadTargetPath, Path.GetFileName(computeNode.Id) + ".rdp"); - result = true; - } - - if (result == true) - { - // Save document - using (MemoryStream memoryStream = new MemoryStream()) - { - await computeNode.DownloadRDPAsync(memoryStream); - - memoryStream.Seek(0, SeekOrigin.Begin); - - using (FileStream fileStream = new FileStream(fileName, FileMode.Create)) - { - await memoryStream.CopyToAsync(fileStream); - } - } - - // Launch - // We don't ask for permission to launch here because the process seems - // to do that for us. The connection is always "untrusted" and, - // given security settings, it is likely to remain that way. - Process.Start(fileName); - } - } - - private async System.Threading.Tasks.Task GetSSHSettingsAsync(ComputeNodeModel computeNode) - { - return await computeNode.GetSSHSettingsAsync(); - } - - #endregion - } -} diff --git a/CSharp/BatchExplorer/ViewModels/OptionsViewModel.cs b/CSharp/BatchExplorer/ViewModels/OptionsViewModel.cs deleted file mode 100644 index 93b4876e..00000000 --- a/CSharp/BatchExplorer/ViewModels/OptionsViewModel.cs +++ /dev/null @@ -1,86 +0,0 @@ -//Copyright (c) Microsoft Corporation - -using GalaSoft.MvvmLight.Messaging; -using Microsoft.Azure.BatchExplorer.Helpers; -using Microsoft.Azure.BatchExplorer.Messages; -using Microsoft.Azure.BatchExplorer.Models; - -namespace Microsoft.Azure.BatchExplorer.ViewModels -{ - public class OptionsViewModel : EntityBase - { - #region Public UI Properties - - public int MaxTrackedOperations { get; set; } - public bool DisplayOperationHistory { get; set; } - public bool UseStatsDuringList { get; set; } - - public string UseStatsDuringListDescriptionString - { - get - { - return "Expand statistics during all list operations. This will return statistics information for all objects, at the cost of performance."; - } - } - - public string DisplayOperationHistoryDescriptionString - { - get - { - return "Display the operation history view at the bottom of the explorer."; - } - } - - public string MaxTrackedOperationsDescriptionString - { - get - { - return "The maximum number of operations which the operation history view will track."; - } - } - - #endregion - - public OptionsViewModel() - { - //Set the properties to their current values - this.MaxTrackedOperations = OptionsModel.Instance.MaxTrackedOperations; - this.DisplayOperationHistory = OptionsModel.Instance.DisplayOperationHistory; - this.UseStatsDuringList = OptionsModel.Instance.UseStatsDuringList; - } - - /// - /// Invoke this command when the confirmation button (at this time it is the one labeled submit) is pressed - /// - public CommandBase Confirm - { - get - { - return new CommandBase(o => - { - OptionsModel options = OptionsModel.Instance; - options.MaxTrackedOperations = this.MaxTrackedOperations; - options.DisplayOperationHistory = this.DisplayOperationHistory; - options.UseStatsDuringList = this.UseStatsDuringList; - - options.WriteOptions(); //Write the options file - - Messenger.Default.Send(new CloseGenericPopup()); - }); - } - } - /// - /// Invoke this command when the cancel button is pressed - /// - public CommandBase Cancel - { - get - { - return new CommandBase(o => - { - Messenger.Default.Send(new CloseGenericPopup()); - }); - } - } - } -} diff --git a/CSharp/BatchExplorer/ViewModels/ResizePoolViewModel.cs b/CSharp/BatchExplorer/ViewModels/ResizePoolViewModel.cs deleted file mode 100644 index f7939f70..00000000 --- a/CSharp/BatchExplorer/ViewModels/ResizePoolViewModel.cs +++ /dev/null @@ -1,333 +0,0 @@ -//Copyright (c) Microsoft Corporation - -using System; -using System.Collections.Generic; -using System.Threading.Tasks; -using GalaSoft.MvvmLight.Messaging; -using Microsoft.Azure.Batch.Common; -using Microsoft.Azure.BatchExplorer.Helpers; -using Microsoft.Azure.BatchExplorer.Messages; -using Microsoft.Azure.BatchExplorer.Models; - -namespace Microsoft.Azure.BatchExplorer.ViewModels -{ - public class ResizePoolViewModel : EntityBase - { - #region Services - private readonly IDataProvider batchService; - #endregion - - #region Public UI Properties - private string poolId; - public string PoolId - { - get - { - return this.poolId; - } - set - { - this.poolId = value; - this.FirePropertyChangedEvent("PoolId"); - } - } - - private int targetDedicated; - public int TargetDedicated - { - get - { - return this.targetDedicated; - } - set - { - this.targetDedicated = value; - this.FirePropertyChangedEvent("TargetDedicated"); - } - } - - private int targetLowPriority; - public int TargetLowPriority - { - get - { - return this.targetLowPriority; - } - set - { - this.targetLowPriority = value; - this.FirePropertyChangedEvent("TargetLowPriority"); - } - } - - private string autoScaleFormula; - public string AutoScaleFormula - { - get - { - return this.autoScaleFormula; - } - set - { - this.autoScaleFormula = value; - this.FirePropertyChangedEvent("AutoScaleFormula"); - } - } - - private TimeSpan? timeout; - public TimeSpan? Timeout - { - get - { - return this.timeout; - } - set - { - this.timeout = value; - this.FirePropertyChangedEvent("Timeout"); - } - } - - private string deallocationOptionString; - public string DeallocationOptionString - { - get - { - return this.deallocationOptionString; - } - set - { - this.deallocationOptionString = value; - this.FirePropertyChangedEvent("DeallocationOptionString"); - } - } - - private bool isAutoScale; - public bool IsAutoScale - { - get - { - return this.isAutoScale; - } - set - { - this.isAutoScale = value; - this.FirePropertyChangedEvent("IsAutoScale"); - } - } - - private static readonly List deallocationOptionValues; - - public List DeallocationOptionValues - { - get { return deallocationOptionValues; } - } - - #endregion - - static ResizePoolViewModel() - { - deallocationOptionValues = new List(); - deallocationOptionValues.Add(string.Empty); - deallocationOptionValues.AddRange(Enum.GetNames(typeof (ComputeNodeDeallocationOption))); - } - - public ResizePoolViewModel(IDataProvider batchService, string poolId, int? currentDedicated, int? currentLowPriority, string currentAutoScaleFormula) - { - this.batchService = batchService; - - this.PoolId = poolId; - this.TargetDedicated = currentDedicated ?? 0; - this.TargetLowPriority = currentLowPriority ?? 0; - this.DeallocationOptionString = null; - if (!string.IsNullOrEmpty(currentAutoScaleFormula)) - { - this.IsAutoScale = true; - } - - this.AutoScaleFormula = currentAutoScaleFormula ?? string.Format("$TargetDedicated={0};",currentDedicated ?? 1); - this.IsBusy = false; - } - - public CommandBase ResizePool - { - get - { - return new CommandBase( - async (o) => - { - this.IsBusy = true; - try - { - await this.ResizePoolAsync(); - } - finally - { - this.IsBusy = false; - } - } - ); - } - } - - public CommandBase EnableAutoScale - { - get - { - return new CommandBase( - async (o) => - { - this.IsBusy = true; - try - { - await this.EnableAutoScaleAsync(); - } - finally - { - this.IsBusy = false; - } - } - ); - } - } - - public CommandBase Evaluate - { - get - { - return new CommandBase( - async (o) => - { - this.IsBusy = true; - try - { - await this.EvaluateAsync(); - } - finally - { - this.IsBusy = false; - } - } - ); - } - } - - private async Task ResizePoolAsync() - { - try - { - ComputeNodeDeallocationOption? deallocationOption; - if (this.IsInputValid(out deallocationOption)) - { - Task asyncTask = this.batchService.ResizePoolAsync( - this.PoolId, - this.TargetDedicated, - this.TargetLowPriority, - this.Timeout, - deallocationOption); - - AsyncOperationTracker.Instance.AddTrackedOperation(new AsyncOperationModel( - asyncTask, - new PoolOperation(PoolOperation.Resize, this.poolId))); - - Messenger.Default.Send(new CloseGenericPopup()); - - await asyncTask; - } - } - catch (Exception e) - { - Messenger.Default.Send(new GenericDialogMessage(e.ToString())); - } - } - - private async Task EnableAutoScaleAsync() - { - try - { - if (this.IsAutoScale && IsInputValidForAutoScaling()) - { - Task asyncTask = this.batchService.EnableAutoScaleAsync(this.PoolId, this.AutoScaleFormula); - - AsyncOperationTracker.Instance.AddTrackedOperation(new AsyncOperationModel( - asyncTask, - new PoolOperation(PoolOperation.EnableAutoScale, this.poolId))); - - await asyncTask; - Messenger.Default.Send(new CloseGenericPopup()); - } - } - catch (Exception e) - { - Messenger.Default.Send(new GenericDialogMessage(e.ToString())); - } - } - - private async Task EvaluateAsync() - { - try - { - if (this.IsAutoScale && IsInputValidForAutoScaling()) - { - Task asyncTask = this.batchService.EvaluateAutoScaleFormulaAsync(this.PoolId, this.AutoScaleFormula); - - AsyncOperationTracker.Instance.AddTrackedOperation(new AsyncOperationModel( - asyncTask, - new PoolOperation(PoolOperation.EvaluateAutoScaleFormula, this.poolId))); - - string result = await asyncTask; - - Messenger.Default.Send(new GenericDialogMessage(result)); - } - } - catch (Exception e) - { - Messenger.Default.Send(new GenericDialogMessage(e.ToString())); - } - } - - private bool IsInputValidForAutoScaling() - { - if (string.IsNullOrWhiteSpace(this.AutoScaleFormula)) - { - Messenger.Default.Send(new GenericDialogMessage("Auto scale formula cannot be empty")); - return false; - } - - return true; - } - - private bool IsInputValid(out ComputeNodeDeallocationOption? deallocationOption) - { - deallocationOption = null; - - if (!string.IsNullOrEmpty(this.DeallocationOptionString)) - { - ComputeNodeDeallocationOption innerDeallocationOption; - bool parsedCorrectly = Enum.TryParse(this.DeallocationOptionString, out innerDeallocationOption); - if (parsedCorrectly) - { - deallocationOption = innerDeallocationOption; - } - else - { - Messenger.Default.Send(new GenericDialogMessage("Invalid value for Deallocation Option")); - return false; - } - } - - if (string.IsNullOrEmpty(this.PoolId)) - { - Messenger.Default.Send(new GenericDialogMessage("Invalid values for Pool Id")); - return false; - } - else if (this.TargetDedicated < 0) - { - Messenger.Default.Send(new GenericDialogMessage("Invalid value for TargetDedicated")); - return false; - } - - return true; - } - } -} diff --git a/CSharp/BatchExplorer/Views/AboutWindow.xaml b/CSharp/BatchExplorer/Views/AboutWindow.xaml deleted file mode 100644 index c377776f..00000000 --- a/CSharp/BatchExplorer/Views/AboutWindow.xaml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - diff --git a/CSharp/BatchExplorer/Views/AboutWindow.xaml.cs b/CSharp/BatchExplorer/Views/AboutWindow.xaml.cs deleted file mode 100644 index cb1cef67..00000000 --- a/CSharp/BatchExplorer/Views/AboutWindow.xaml.cs +++ /dev/null @@ -1,17 +0,0 @@ -//Copyright (c) Microsoft Corporation - -using System.Windows; - -namespace Microsoft.Azure.BatchExplorer.Views -{ - /// - /// Interaction logic for AboutWindow.xaml - /// - public partial class AboutWindow : Window - { - public AboutWindow() - { - InitializeComponent(); - } - } -} diff --git a/CSharp/BatchExplorer/Views/AccountManagementControl.xaml b/CSharp/BatchExplorer/Views/AccountManagementControl.xaml deleted file mode 100644 index f774d028..00000000 --- a/CSharp/BatchExplorer/Views/AccountManagementControl.xaml +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - - - - diff --git a/CSharp/BatchExplorer/Views/CreateControls/CreateComputeNodeUserControl.xaml.cs b/CSharp/BatchExplorer/Views/CreateControls/CreateComputeNodeUserControl.xaml.cs deleted file mode 100644 index 8664b9f7..00000000 --- a/CSharp/BatchExplorer/Views/CreateControls/CreateComputeNodeUserControl.xaml.cs +++ /dev/null @@ -1,23 +0,0 @@ -//Copyright (c) Microsoft Corporation - -using System.Windows.Controls; -using Microsoft.Azure.BatchExplorer.ViewModels; - -namespace Microsoft.Azure.BatchExplorer.Views.CreateControls -{ - /// - /// Interaction logic for CreateComputeNodeUserControl.xaml - /// - public partial class CreateComputeNodeUserControl : UserControl - { - private readonly CreateComputeNodeUserViewModel viewModel; - - public CreateComputeNodeUserControl(CreateComputeNodeUserViewModel viewModel) - { - InitializeComponent(); - - this.viewModel = viewModel; - this.DataContext = this.viewModel; - } - } -} diff --git a/CSharp/BatchExplorer/Views/CreateControls/CreateJobControl.xaml b/CSharp/BatchExplorer/Views/CreateControls/CreateJobControl.xaml deleted file mode 100644 index 1e983c2b..00000000 --- a/CSharp/BatchExplorer/Views/CreateControls/CreateJobControl.xaml +++ /dev/null @@ -1,456 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/CSharp/BatchExplorer/Views/CreateControls/CreatePoolControl.xaml.cs b/CSharp/BatchExplorer/Views/CreateControls/CreatePoolControl.xaml.cs deleted file mode 100644 index b47078c8..00000000 --- a/CSharp/BatchExplorer/Views/CreateControls/CreatePoolControl.xaml.cs +++ /dev/null @@ -1,23 +0,0 @@ -//Copyright (c) Microsoft Corporation - -using System.Windows.Controls; -using Microsoft.Azure.BatchExplorer.ViewModels; - -namespace Microsoft.Azure.BatchExplorer.Views.CreateControls -{ - /// - /// Interaction logic for CreatePoolControl.xaml - /// - public partial class CreatePoolControl : UserControl - { - private readonly CreatePoolViewModel viewModel; - - public CreatePoolControl(CreatePoolViewModel viewModel) - { - InitializeComponent(); - - this.viewModel = viewModel; - this.DataContext = this.viewModel; - } - } -} diff --git a/CSharp/BatchExplorer/Views/CreateControls/ResizePoolControl.xaml b/CSharp/BatchExplorer/Views/CreateControls/ResizePoolControl.xaml deleted file mode 100644 index 5c4fbe7c..00000000 --- a/CSharp/BatchExplorer/Views/CreateControls/ResizePoolControl.xaml +++ /dev/null @@ -1,175 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/CSharp/BatchExplorer/Views/MainView.xaml.cs b/CSharp/BatchExplorer/Views/MainView.xaml.cs deleted file mode 100644 index 63b192b8..00000000 --- a/CSharp/BatchExplorer/Views/MainView.xaml.cs +++ /dev/null @@ -1,475 +0,0 @@ -//Copyright (c) Microsoft Corporation - -namespace Microsoft.Azure.BatchExplorer.Views -{ - using System; - using System.IO; - using System.Windows; - using System.Windows.Controls; - using System.Windows.Input; - using GalaSoft.MvvmLight.Messaging; - using Microsoft.Azure.BatchExplorer.Messages; - using Microsoft.Azure.BatchExplorer.Models; - using Microsoft.Azure.BatchExplorer.ViewModels; - - /// - /// Interaction logic for MainView.xaml - /// - public partial class MainView : Window - { - private MainViewModel viewModel; - - private AboutWindow aboutWindow; - private GenericEmptyWindow genericEmptyWindow; - private GenericEmptyWindow genericPopupWindow; - private GenericEmptyWindow heatmapWindow; - - private GridLength asyncOperationTabHeight; - private const int MinWindowHeight = 100; - private const int MaxWindowHeight = 800; - private const int MinWindowWidth = 180; - private const int MaxWindowWidth = 800; - - public MainView() - { - try - { - this.viewModel = new MainViewModel(); - this.DataContext = this.viewModel; - InitializeComponent(); - - //Set the default grid height - asyncOperationTabHeight = new GridLength(1, GridUnitType.Star); - - //Add listener for the generic dialog message - Messenger.Default.Register(this, (m) => - { - Messenger.Default.Register(this, - (o) => - { - this.genericPopupWindow.Close(); - Messenger.Default.Unregister(this); - }); - - //Need to use dispatcher.Invoke because this message may be called via a non UI thread, and those threads - //Cannot create controls/windows. To work around this, creation of the window is run in the dispacter of the main view (this) - this.Dispatcher.Invoke(() => - { - this.genericPopupWindow = new GenericEmptyWindow(); - - this.genericPopupWindow.MinHeight = MinWindowHeight; - this.genericPopupWindow.MaxHeight = MaxWindowHeight; - this.genericPopupWindow.MinWidth = MinWindowWidth; - this.genericPopupWindow.MaxWidth = MaxWindowWidth; - this.genericPopupWindow.Title = "Message"; - this.genericPopupWindow.Owner = this; - this.genericPopupWindow.WindowStartupLocation = WindowStartupLocation.CenterOwner; - this.genericPopupWindow.Content = new GenericMessageControl(new GenericMessageViewModel(m.MessageString)); - this.genericPopupWindow.ResizeMode = System.Windows.ResizeMode.CanResizeWithGrip; - this.genericPopupWindow.SizeToContent = System.Windows.SizeToContent.WidthAndHeight; - this.genericPopupWindow.VerticalContentAlignment = System.Windows.VerticalAlignment.Top; - this.genericPopupWindow.HorizontalContentAlignment = System.Windows.HorizontalAlignment.Center; - this.IsEnabled = false; - this.genericPopupWindow.ShowDialog(); - this.IsEnabled = true; - this.genericPopupWindow = null; - }); - }); - //Add listener for the message to show the delete confirm dialog box - Messenger.Default.Register(this, (m) => - { - var result = - MessageBox.Show( - "Are you sure you want to delete this account?", - "Confirm Delete", - MessageBoxButton.YesNo); - - if (result == MessageBoxResult.Yes) - { - Messenger.Default.Send(new ConfirmAccountDeleteMessage()); - } - else - { - Messenger.Default.Send(new CloseGenericPopup()); - } - }); - - //Add a listener to trigger the showing of the account dialog box in edit mode - Messenger.Default.Register(this, - (m) => - { - //Make sure we close the popup afterward - Messenger.Default.Register(this, - (o) => - { - this.genericEmptyWindow.Close(); - Messenger.Default.Unregister(this); - }); - - this.genericEmptyWindow = new GenericEmptyWindow(); - this.genericEmptyWindow.Title = "Edit Account"; - this.genericEmptyWindow.Content = new AccountManagementControl(m.AccountDialogViewModel); - this.genericEmptyWindow.ResizeMode = ResizeMode.NoResize; - this.genericEmptyWindow.Owner = this; - this.genericEmptyWindow.SizeToContent = SizeToContent.WidthAndHeight; - this.IsEnabled = false; - this.genericEmptyWindow.ShowDialog(); - this.IsEnabled = true; - this.genericEmptyWindow = null; - }); - - //Add a listener to trigger the showing of the account dialog box in add mode - Messenger.Default.Register(this, - (m) => - { - //Make sure we close the popup afterward - Messenger.Default.Register(this, - (o) => - { - this.genericEmptyWindow.Close(); - Messenger.Default.Unregister(this); - }); - - - this.genericEmptyWindow = new GenericEmptyWindow(); - this.genericEmptyWindow.Title = "Add Account"; - this.genericEmptyWindow.Content = new AccountManagementControl(m.AccountDialogViewModel); - this.genericEmptyWindow.ResizeMode = ResizeMode.NoResize; - this.genericEmptyWindow.Owner = this; - this.genericEmptyWindow.SizeToContent = SizeToContent.WidthAndHeight; - this.IsEnabled = false; - this.genericEmptyWindow.ShowDialog(); - this.IsEnabled = true; - this.genericEmptyWindow = null; - }); - - //Add a listener to trigger the showing of a dialog box with multiple buttons - Messenger.Default.Register(this, (message) => - { - var result = MessageBox.Show(message.DialogMessage, message.Caption, message.MessageBoxButton, - message.MessageBoxImage); - Messenger.Default.Send(new MultibuttonDialogReturnMessage(result)); - }); - - Messenger.Default.Register(this, (message) => - { - MessageBoxResult result = MessageBox.Show("Are you sure you want to reboot this Compute Node?", "Compute Node Reboot", MessageBoxButton.YesNo); - ComputeNodeRebootConfimation confimation = ComputeNodeRebootConfimation.Cancelled; - - if (result == MessageBoxResult.Yes) - { - confimation = ComputeNodeRebootConfimation.Confirmed; - } - - Messenger.Default.Send(new RebootComputeNodeConfirmationMessage(confimation)); - }); - - Messenger.Default.Register(this, (message) => - { - MessageBoxResult result = MessageBox.Show("Are you sure you want to reimage this Compute Node?", "Compute Node Reimage", MessageBoxButton.YesNo); - ComputeNodeReimageConfimation confimation = ComputeNodeReimageConfimation.Cancelled; - - if (result == MessageBoxResult.Yes) - { - confimation = ComputeNodeReimageConfimation.Confirmed; - } - - Messenger.Default.Send(new ReimageComputeNodeConfirmationMessage(confimation)); - }); - - Messenger.Default.Register(this, (message) => - { - MessageBoxResult result = MessageBox.Show("Are you sure you want to reimage this Compute Node?", "Compute Node Reimage", MessageBoxButton.YesNo); - ComputeNodeReimageConfimation confimation = ComputeNodeReimageConfimation.Cancelled; - - if (result == MessageBoxResult.Yes) - { - confimation = ComputeNodeReimageConfimation.Confirmed; - } - - Messenger.Default.Send(new ReimageComputeNodeConfirmationMessage(confimation)); - }); - - Messenger.Default.Register(this, (message) => - { - MessageBoxResult result = MessageBox.Show("Are you sure you want to disable scheduling on this Compute Node?", "Compute Node Disable Scheduling", MessageBoxButton.YesNo); - ComputeNodeDisableSchedulingConfimation confimation = ComputeNodeDisableSchedulingConfimation.Cancelled; - - if (result == MessageBoxResult.Yes) - { - confimation = ComputeNodeDisableSchedulingConfimation.Confirmed; - } - - Messenger.Default.Send(new DisableSchedulingComputeNodeConfirmationMessage(confimation)); - }); - - Messenger.Default.Register(this, (message) => - { - this.aboutWindow = new AboutWindow(); - this.aboutWindow.Owner = this; - this.IsEnabled = false; - this.aboutWindow.ShowDialog(); - this.IsEnabled = true; - this.aboutWindow = null; - }); - - Messenger.Default.Register(this, (message) => - { - this.genericEmptyWindow = new GenericEmptyWindow(); - this.genericEmptyWindow.Title = "Create Pool"; - this.genericEmptyWindow.Content = new CreateControls.CreatePoolControl(new CreatePoolViewModel(MainViewModel.dataProvider, message.NodeAgentSkus)); - this.genericEmptyWindow.Owner = this; - this.genericEmptyWindow.SizeToContent = System.Windows.SizeToContent.WidthAndHeight; - this.IsEnabled = false; - this.genericEmptyWindow.ShowDialog(); - this.IsEnabled = true; - this.genericEmptyWindow = null; - }); - - Messenger.Default.Register(this, - (m) => - { - this.genericEmptyWindow = new GenericEmptyWindow(); - this.genericEmptyWindow.MinHeight = MinWindowHeight; - this.genericEmptyWindow.MaxHeight = MaxWindowHeight; - this.genericEmptyWindow.MinWidth = MinWindowWidth; - this.genericEmptyWindow.MaxWidth = MaxWindowWidth; - this.genericEmptyWindow.Title = "Operation Details"; - this.genericEmptyWindow.Content = new AsyncOperationDetailsControl(new AsyncOperationDetailsViewModel(m.AsyncOperation)); - this.genericEmptyWindow.Owner = this; - this.genericEmptyWindow.ResizeMode = System.Windows.ResizeMode.CanResizeWithGrip; - this.genericEmptyWindow.SizeToContent = System.Windows.SizeToContent.WidthAndHeight; - this.IsEnabled = false; - this.genericEmptyWindow.ShowDialog(); - this.IsEnabled = true; - this.genericEmptyWindow = null; - }); - - Messenger.Default.Register(this, - (m) => - { - //Make sure we close the popup afterward - Messenger.Default.Register(this, - (o) => - { - this.genericEmptyWindow.Close(); - Messenger.Default.Unregister(this); - }); - - this.genericEmptyWindow = new GenericEmptyWindow(); - this.genericEmptyWindow.Title = "Options"; - this.genericEmptyWindow.Content = new OptionsControl(new OptionsViewModel()); - this.genericEmptyWindow.Owner = this; - this.genericEmptyWindow.SizeToContent = SizeToContent.WidthAndHeight; - this.IsEnabled = false; - this.genericEmptyWindow.ShowDialog(); - this.IsEnabled = true; - this.genericEmptyWindow = null; - }); - - const int optionsRowLocation = 3; - //Check if we need to collapse the operation history display on start - if (!OptionsModel.Instance.DisplayOperationHistory) - { - //Store the current height and then hide the control and move the grid to auto - asyncOperationTabHeight = this.MainGrid.RowDefinitions[optionsRowLocation].Height; - this.AsyncOperationGrid.Visibility = Visibility.Collapsed; - this.MainGrid.RowDefinitions[optionsRowLocation].Height = GridLength.Auto; - } - - Messenger.Default.Register(this, - m => - { - if (m.Show) - { - this.AsyncOperationGrid.Visibility = Visibility.Visible; - this.MainGrid.RowDefinitions[optionsRowLocation].Height = asyncOperationTabHeight; - } - else - { - //Store the current height and then hide the control and move the grid to auto - asyncOperationTabHeight = this.MainGrid.RowDefinitions[optionsRowLocation].Height; - this.AsyncOperationGrid.Visibility = Visibility.Collapsed; - this.MainGrid.RowDefinitions[optionsRowLocation].Height = GridLength.Auto; - } - }); - - Messenger.Default.Register(this, (message) => - { - this.genericEmptyWindow = new GenericEmptyWindow(); - this.genericEmptyWindow.Title = "Create Job Schedule"; - this.genericEmptyWindow.Content = new CreateControls.CreateJobScheduleControl(new CreateJobScheduleViewModel(MainViewModel.dataProvider)); - this.genericEmptyWindow.Owner = this; - this.genericEmptyWindow.SizeToContent = System.Windows.SizeToContent.Height; - this.IsEnabled = false; - this.genericEmptyWindow.ShowDialog(); - this.IsEnabled = true; - this.genericEmptyWindow = null; - }); - - Messenger.Default.Register(this, (message) => - { - this.genericEmptyWindow = new GenericEmptyWindow(); - this.genericEmptyWindow.Title = "Create Job"; - this.genericEmptyWindow.Content = new CreateControls.CreateJobControl(new CreateJobViewModel(MainViewModel.dataProvider)); - this.genericEmptyWindow.Owner = this; - this.genericEmptyWindow.SizeToContent = System.Windows.SizeToContent.Height; - this.IsEnabled = false; - this.genericEmptyWindow.ShowDialog(); - this.IsEnabled = true; - this.genericEmptyWindow = null; - }); - - Messenger.Default.Register(this, message => - { - this.genericEmptyWindow = new GenericEmptyWindow(); - this.genericEmptyWindow.Title = "Add Certificate"; - this.genericEmptyWindow.Content = new CreateControls.CreateCertificateControl(new CreateCertificateViewModel(MainViewModel.dataProvider)); - this.genericEmptyWindow.Owner = this; - this.genericEmptyWindow.SizeToContent = System.Windows.SizeToContent.Height; - this.IsEnabled = false; - this.genericEmptyWindow.ShowDialog(); - this.IsEnabled = true; - this.genericEmptyWindow = null; - }); - - Messenger.Default.Register(this, (message) => - { - this.genericEmptyWindow = new GenericEmptyWindow(); - this.genericEmptyWindow.Title = "Add Task"; - this.genericEmptyWindow.Content = new CreateControls.AddTaskControl(new AddTaskViewModel(MainViewModel.dataProvider, message.JobId)); - this.genericEmptyWindow.Owner = this; - this.genericEmptyWindow.SizeToContent = System.Windows.SizeToContent.Height; - this.IsEnabled = false; - this.genericEmptyWindow.ShowDialog(); - this.IsEnabled = true; - this.genericEmptyWindow = null; - }); - - Messenger.Default.Register(this, (message) => - { - //Make sure we close the popup afterward - Messenger.Default.Register(this, - (o) => - { - this.genericEmptyWindow.Close(); - Messenger.Default.Unregister(this); - }); - - this.genericEmptyWindow = new GenericEmptyWindow(); - this.genericEmptyWindow.Title = "Create Compute Node User"; - this.genericEmptyWindow.Content = new CreateControls.CreateComputeNodeUserControl(new CreateComputeNodeUserViewModel(MainViewModel.dataProvider, message.PoolId, message.ComputeNodeId)); - this.genericEmptyWindow.Owner = this; - this.genericEmptyWindow.SizeToContent = System.Windows.SizeToContent.Height; - this.IsEnabled = false; - this.genericEmptyWindow.ShowDialog(); - this.IsEnabled = true; - this.genericEmptyWindow = null; - }); - - Messenger.Default.Register(this, (message) => - { - //Make sure we close the popup afterward - Messenger.Default.Register(this, - (o) => - { - this.genericEmptyWindow.Close(); - Messenger.Default.Unregister(this); - }); - - this.genericEmptyWindow = new GenericEmptyWindow(); - this.genericEmptyWindow.Title = "Resize Pool"; - this.genericEmptyWindow.Content = new CreateControls.ResizePoolControl(new ResizePoolViewModel( - MainViewModel.dataProvider, - message.PoolId, - message.CurrentDedicated, - message.CurrentLowPriority, - message.CurrentAutoScaleFormula)); - this.genericEmptyWindow.Owner = this; - this.genericEmptyWindow.SizeToContent = System.Windows.SizeToContent.WidthAndHeight; - this.IsEnabled = false; - this.genericEmptyWindow.ShowDialog(); - this.IsEnabled = true; - this.genericEmptyWindow = null; - }); - - Messenger.Default.Register(this, (message) => - { - //Need to use dispatcher.Invoke because this message may be called via a non UI thread, and those threads - //Cannot create controls/windows. To work around this, creation of the window is run in the dispacter of the main view (this) - this.Dispatcher.Invoke(() => - { - //Close the existing window if there is one - if (this.heatmapWindow != null) - { - this.heatmapWindow.Close(); - } - - HeatMapModel model = new HeatMapModel(message.Pool); - HeatMapControl control = new HeatMapControl(new HeatMapViewModel(model)); - - this.heatmapWindow = new GenericEmptyWindow(); - this.heatmapWindow.Title = "Heat map"; //TODO: All these strings should be defined in a constant class somewhere - this.heatmapWindow.SizeToContent = SizeToContent.WidthAndHeight; - this.heatmapWindow.Content = control; - this.heatmapWindow.Closed += (sender, args) => control.Cancel(); - this.heatmapWindow.Show(); - }); - }); - } - catch (Exception e) - { - // Record the exception before throwing - File.WriteAllText(Path.Combine(Path.GetTempPath(), "batchexplorerexception.txt"), e.ToString()); - throw; - } - } - - public void TreeViewCopyCommandBinding_Executed(object sender, ExecutedRoutedEventArgs e) - { - TreeView treeView = (TreeView)sender; - PropertyModel propertyModel = treeView.SelectedItem as PropertyModel; - SimplePropertyModel simplePropertyModel = propertyModel as SimplePropertyModel; - - string text = null; - - if (simplePropertyModel != null) - { - //TODO: This is bad to do? - text = string.Format("{0}: {1}", simplePropertyModel.PropertyName, simplePropertyModel.PropertyValue); - } - else if (propertyModel != null) - { - text = propertyModel.PropertyName; - } - else - { - throw new ArgumentException("sender"); - } - - Clipboard.SetText(text); - } - - public void TreeViewCopyCommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e) - { - TreeView treeView = (TreeView)sender; - SimplePropertyModel simplePropertyModel = treeView.SelectedItem as SimplePropertyModel; - - e.CanExecute = simplePropertyModel != null; - } - - private void SearchJobsTxtBox_GotFocus(object sender, RoutedEventArgs e) - { - this.SearchJobsTxtBox.Text = String.Empty; - } - - private void SearchJobsTxtBox_KeyUp(object sender, KeyEventArgs e) - { - this.viewModel.JobsSearchFilter = this.SearchJobsTxtBox.Text; - if (e.Key == Key.Enter && this.viewModel.IsAccountConnected) - { - Messenger.Default.Send(new RefreshMessage(RefreshTarget.Jobs)); - } - } - } -} diff --git a/CSharp/BatchExplorer/Views/OptionsControl.xaml b/CSharp/BatchExplorer/Views/OptionsControl.xaml deleted file mode 100644 index e29de2f2..00000000 --- a/CSharp/BatchExplorer/Views/OptionsControl.xaml +++ /dev/null @@ -1,84 +0,0 @@ - - - - - - - - - - - - - - -