Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
06/26/15 18:02:03 (9 years ago)
Author:
dglaser
Message:

#2388:

HeuristicLab.Services.WebApp.Statistics-3.3:

  • added groups page
  • improved jobs, clients and users pages

HeuristicLab.Services.WebApp-3.3:

  • merged from trunk
Location:
branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3
Files:
10 added
17 edited

Legend:

Unmodified
Added
Removed
  • branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/HeuristicLab.Services.WebApp.Statistics-3.3.csproj

    r12516 r12525  
    146146    <Compile Include="WebApi\DataTransfer\ClientPage.cs" />
    147147    <Compile Include="WebApi\DataTransfer\ClientStatus.cs" />
     148    <Compile Include="WebApi\DataTransfer\Group.cs" />
     149    <Compile Include="WebApi\DataTransfer\GroupDetails.cs" />
     150    <Compile Include="WebApi\DataTransfer\GroupPage.cs" />
    148151    <Compile Include="WebApi\DataTransfer\Integer.cs" />
    149152    <Compile Include="WebApi\DataTransfer\Job.cs" />
     
    154157    <Compile Include="WebApi\DataTransfer\TaskStateCount.cs" />
    155158    <Compile Include="WebApi\DataTransfer\User.cs" />
     159    <Compile Include="WebApi\GroupController.cs" />
    156160    <Compile Include="WebApi\JavascriptUtils.cs" />
    157161    <Compile Include="WebApi\JobController.cs" />
     
    172176      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    173177    </Content>
     178    <Content Include="WebApp\groups\details\groupDetailsCtrl.js">
     179      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
     180    </Content>
     181    <Content Include="WebApp\groups\groupsCtrl.js">
     182      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
     183    </Content>
    174184    <Content Include="WebApp\jobs\details\jobDetailsCtrl.js">
    175185      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
     
    182192    </Content>
    183193    <Content Include="WebApp\services\clientService.js">
     194      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
     195    </Content>
     196    <Content Include="WebApp\services\groupService.js">
    184197      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    185198    </Content>
     
    224237    </None>
    225238    <None Include="WebApp\clients\details\clientTaskDetailsDialog.cshtml">
     239      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
     240    </None>
     241    <Content Include="WebApp\groups\groups.cshtml">
     242      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
     243    </Content>
     244    <None Include="WebApp\groups\details\groupDetails.cshtml">
    226245      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    227246    </None>
  • branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApi/ClientController.cs

    r12516 r12525  
    8686                    State = clientInfo.SlaveState.ToString(),
    8787                    LastUpdate = clientInfo.Time,
     88                    GroupId = client.ResourceGroupId,
     89                    GroupName = client.GroupName,
    8890                    UpTime = offline ? 0 : upTime,
    8991                    TotalUnavailableTime = timeData != null ? timeData.TotalUnavailableTime : 0,
     
    124126                         CpuUtilization = offline ? 0 : clientInfo.CpuUtilization,
    125127                         State = clientInfo.SlaveState.ToString(),
     128                         GroupId = client.ResourceGroupId,
     129                         GroupName = client.GroupName
    126130                       });
    127131          return new DT.ClientPage {
     
    186190    }
    187191
     192    public DT.ClientPage GetClientsByGroupId(Guid id, int page, int size, bool expired = false) {
     193      using (var pm = PersistenceManager) {
     194        var dimClientDao = pm.DimClientDao;
     195        var factClientInfoDao = pm.FactClientInfoDao;
     196        return pm.UseTransaction(() => {
     197          var clients = expired ? dimClientDao.GetExpiredClients() : dimClientDao.GetActiveClients();
     198          clients = clients.Where(x => x.ResourceGroupId == id);
     199          var query = (from client in clients
     200                       join info in factClientInfoDao.GetAll()
     201                         on client.Id equals info.ClientId into clientInfoJoin
     202                       from clientInfo in clientInfoJoin.OrderByDescending(x => x.Time).Take(1)
     203                       let offline = (expired || clientInfo.SlaveState == SlaveState.Offline)
     204                       select new DT.Client {
     205                         Id = client.Id,
     206                         Name = client.Name,
     207                         TotalCores = clientInfo.NumTotalCores,
     208                         UsedCores = offline ? 0 : clientInfo.NumUsedCores,
     209                         TotalMemory = clientInfo.TotalMemory,
     210                         UsedMemory = offline ? 0 : clientInfo.UsedMemory,
     211                         CpuUtilization = offline ? 0 : clientInfo.CpuUtilization,
     212                         State = clientInfo.SlaveState.ToString(),
     213                         GroupId = client.ResourceGroupId,
     214                         GroupName = client.GroupName
     215                       });
     216          return new DT.ClientPage {
     217            TotalClients = query.Count(),
     218            Clients = query.Skip((page - 1) * size)
     219              .Take(size)
     220              .ToList()
     221          };
     222        });
     223      }
     224    }
     225
     226    public IEnumerable<DT.ClientStatus> GetClientHistoryByGroupId(Guid id, DateTime start, DateTime end) {
     227      TimeSpan ts = end - start;
     228      int increment = 1;
     229      double totalMinutes = ts.TotalMinutes;
     230      while (totalMinutes > 5761) {
     231        totalMinutes -= 5761;
     232        increment += 5;
     233      }
     234      using (var pm = PersistenceManager) {
     235        var factClientInfo = pm.FactClientInfoDao;
     236        var dimClientDao = pm.DimClientDao;
     237        var clientInfos = factClientInfo.GetAll()
     238          .Where(x => x.Time >= start && x.Time <= end)
     239          .OrderBy(x => x.Time)
     240          .Join(dimClientDao.GetAll(),
     241            fact => fact.ClientId,
     242            client => client.Id,
     243            (fact, client) => new {
     244              client.ResourceGroupId,
     245              fact.Time,
     246              fact.CpuUtilization,
     247              fact.NumTotalCores,
     248              fact.NumUsedCores,
     249              fact.TotalMemory,
     250              fact.UsedMemory
     251            })
     252          .Where(x => x.ResourceGroupId == id)
     253          .ToList();
     254        var clientStatus = new DT.ClientStatus {
     255          CpuUtilization = 0,
     256          TotalCores = 0,
     257          UsedCores = 0,
     258          TotalMemory = 0,
     259          UsedMemory = 0
     260        };
     261        int i = 1;
     262        foreach (var clientInfo in clientInfos) {
     263          clientStatus.CpuUtilization += clientInfo.CpuUtilization;
     264          clientStatus.TotalCores += clientInfo.NumTotalCores;
     265          clientStatus.UsedCores += clientInfo.NumUsedCores;
     266          clientStatus.TotalMemory += clientInfo.TotalMemory;
     267          clientStatus.UsedMemory += clientInfo.UsedMemory;
     268          if (i >= increment) {
     269            clientStatus.Timestamp = JavascriptUtils.ToTimestamp(clientInfo.Time);
     270            clientStatus.CpuUtilization /= i;
     271            clientStatus.TotalCores /= i;
     272            clientStatus.UsedCores /= i;
     273            clientStatus.TotalMemory /= i;
     274            clientStatus.UsedMemory /= i;
     275            yield return clientStatus;
     276            clientStatus = new DT.ClientStatus {
     277              CpuUtilization = 0,
     278              TotalCores = 0,
     279              UsedCores = 0,
     280              TotalMemory = 0,
     281              UsedMemory = 0
     282            };
     283            i = 1;
     284          } else {
     285            ++i;
     286          }
     287        }
     288      }
     289    }
    188290  }
    189291}
  • branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApi/DataTransfer/Client.cs

    r12516 r12525  
    3333    public string State { get; set; }
    3434    public DateTime LastUpdate { get; set; }
     35    public Guid? GroupId { get; set; }
     36    public string GroupName { get; set; }
    3537  }
    3638}
  • branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApi/DataTransfer/ClientDetails.cs

    r12516 r12525  
    3434    public string State { get; set; }
    3535    public DateTime LastUpdate { get; set; }
     36    public Guid? GroupId { get; set; }
     37    public string GroupName { get; set; }
    3638    public long UpTime { get; set; }
    3739    public long TotalUnavailableTime { get; set; }
  • branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApi/JobController.cs

    r12516 r12525  
    135135    }
    136136
     137    [Authorize(Roles = HiveRoles.Administrator)]
     138    public IEnumerable<DT.Job> GetAllActiveJobsFromAllUsers() {
     139      using (var pm = PersistenceManager) {
     140        var dimJobDao = pm.DimJobDao;
     141        return pm.UseTransaction(() => {
     142          return dimJobDao.GetAll()
     143            .Where(x => x.DateCompleted == null)
     144            .OrderByDescending(x => x.DateCreated)
     145            .Select(x => ConvertToDT(x))
     146            .ToList();
     147        });
     148      }
     149    }
     150
    137151    private DT.Job ConvertToDT(DA.DimJob job) {
    138152      return new DT.Job {
  • branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApi/TaskController.cs

    r12516 r12525  
    143143                       Exception = isAdministrator ? factTask.Exception : string.Empty
    144144                     })
    145                   .OrderByDescending(x => x.EndTime)
     145                  .OrderByDescending(x => x.EndTime ?? DateTime.MaxValue)
    146146                  .Skip((page - 1) * size)
    147147                  .Take(size)
  • branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/clients/clients.cshtml

    r12516 r12525  
    1414    <li class="active">
    1515        <a ng-href="#/statistics/clients">Clients</a>
     16    </li>
     17    <li>
     18        <a ng-href="#/statistics/groups">Groups</a>
    1619    </li>
    1720    </ul>
     
    3134                            <th>#</th>
    3235                            <th>Client Name</th>
     36                            <th>Group Name</th>
    3337                            <th>Cores</th>
    3438                            <th>Cpu Utilization</th>
     
    4044                            <td>{{($index + 1)+((curClientsPage-1)*(clientsPageSize))}}</td>
    4145                            <td>{{client.Name}}</td>
     46                            <td>
     47                                <a ng-show="client.GroupName" ng-href="#/statistics/groups/{{client.GroupId}}">{{client.GroupName}}</a>
     48                                <span ng-hide="client.GroupName">No Group</span>
     49                            </td>
    4250                            <td>{{client.UsedCores}} / {{client.TotalCores}}</td>
    4351                            <td>{{client.CpuUtilization | number: 2}} %</td>
  • branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/clients/details/clientDetails.cshtml

    r12516 r12525  
    1414            <a ng-href="#/statistics/clients">Clients</a>
    1515        </li>
     16        <li>
     17            <a ng-href="#/statistics/groups">Groups</a>
     18        </li>
    1619    </ul>
    1720</header>
     
    3437                                <tr>
    3538                                    <td class="text-left">Group:</td>
    36                                     <td ng-show="client.GroupName">{{client.GroupName}}</td>
     39                                    <td ng-show="client.GroupName"><a ng-href="#/statistics/groups/{{client.GroupId}}">{{client.GroupName}}</a></td>
    3740                                    <td ng-hide="client.GroupName">None</td>
    3841                                </tr>
     
    253256 <div class="default-filter-header text-center">
    254257     <form class="form-inline">
    255          <div class="form-group">
     258         <div class="form-group" style="margin-left: 5px; margin-right: 5px;">
    256259             <label for="fromDate">From:&nbsp;</label>
    257260             <div class="input-group">
     
    262265             </div>
    263266         </div>
    264          <div class="form-group">
    265              <label for="fromDate">&nbsp;&nbsp;To:&nbsp;</label>
     267         <div class="form-group" style="margin-left: 5px; margin-right: 5px;">
     268             <label for="fromDate">To:&nbsp;</label>
    266269             <div class="input-group">
    267                  <input id="fromDate" type="text" class="form-control" datepicker-popup="dd.MM.yyyy" ng-model="toDate" is-open="toIsOpen" datepicker-options="dateOptions" ng-required="true" close-text="Close"/>
     270                 <input id="fromDate" type="text" class="form-control" datepicker-popup="dd.MM.yyyy" ng-model="toDate" is-open="toIsOpen" datepicker-options="dateOptions" ng-required="true" close-text="Close" />
    268271                 <span class="input-group-btn">
    269272                     <button type="button" class="btn btn-default" ng-click="openToDateSelection($event)"><i class="glyphicon glyphicon-calendar"></i></button>
     
    271274             </div>
    272275         </div>
    273          <div class="btn-group">
    274              <label class="btn btn-default" ng-click="updateCharts()">
     276         <div class="form-group" style="margin-left: 5px; margin-right: 5px;">
     277             <button type="button" class="btn btn-default" ng-click="updateCharts()">
    275278                 Apply
    276              </label>
     279             </button>
    277280         </div>
    278281     </form>
  • branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/jobs/details/jobDetails.cshtml

    r12516 r12525  
    1313        <li>
    1414            <a ng-href="#/statistics/clients">Clients</a>
     15        </li>
     16        <li>
     17            <a ng-href="#/statistics/groups">Groups</a>
    1518        </li>
    1619    </ul>
     
    97100                        <div class="col-md-2"></div>
    98101                        </div>
    99                 </div>
     102                    </div>
    100103
    101104            </div>
  • branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/jobs/details/jobDetailsCtrl.js

    r12516 r12525  
    1414                    if (isDefined($scope.job.DateCompleted)) {
    1515                        $scope.job.DateCompleted = CSharpDateToString($scope.job.DateCompleted);
     16                    } else {
     17                        $scope.job.DateCompleted = 'Not completed yet';
    1618                    }
    1719                    $scope.job.CalculatingWaitingRatio = ($scope.job.TotalCalculatingTime / $scope.job.TotalWaitingTime);
  • branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/jobs/jobs.cshtml

    r12516 r12525  
    1313        <li>
    1414            <a ng-href="#/statistics/clients">Clients</a>
     15        </li>
     16        <li>
     17            <a ng-href="#/statistics/groups">Groups</a>
    1518        </li>
    1619    </ul>
     
    5457        </div>
    5558    </div>
    56 
     59    @if (Request.IsAuthenticated && User.IsInRole(HiveRoles.Administrator)) {
     60        <div class="row">
     61            <div class="col-lg-12">
     62                <div class="panel panel-default">
     63                    <div class="panel-heading">
     64                        <h3 class="panel-title">Current Active Jobs</h3>
     65                    </div>
     66                    <div class="panel-body">
     67                        <table class="table table-hover table-condensed">
     68                            <thead>
     69                                <tr>
     70                                    <th>#</th>
     71                                    <th>Job Name</th>
     72                                    <th>User Name</th>
     73                                    <th>Date Created</th>
     74                                    <th>Progress</th>
     75                                    <th></th>
     76                                </tr>
     77                            </thead>
     78                            <tr ng-repeat="job in allUsersJobs">
     79                                <td>{{$index + 1}}</td>
     80                                <td>{{job.Name}}</td>
     81                                <td>
     82                                    <a ng-href="#/statistics/users/{{job.UserId}}" ng-show="job.UserName">{{job.UserName}}</a>
     83                                </td>
     84                                <td>{{job.DateCreated}}</td>
     85                                <td>
     86                                    <progressbar class="progress active" max="job.TotalTasks" value="job.CompletedTasks" type="success"><i style="color:black; white-space:nowrap;">{{job.CompletedTasks}} / {{job.TotalTasks}}</i></progressbar>
     87                                </td>
     88                                <td>
     89                                    <a ng-href="#/statistics/jobs/{{job.Id}}">Details</a>
     90                                </td>
     91                            </tr>
     92                            <tr ng-hide="allUsersJobs.length">
     93                                <td colspan="6" class="text-center">No active jobs found!</td>
     94                            </tr>
     95                        </table>
     96                    </div>
     97                </div>
     98            </div>
     99        </div>
     100    }
    57101    <div class="row">
    58102        <div class="col-lg-12">
  • branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/jobs/jobsCtrl.js

    r12516 r12525  
    33    module.controller('app.statistics.jobsCtrl',
    44        ['$scope', '$interval', 'app.statistics.jobService', function ($scope, $interval, jobService) {
     5            var first = true;
     6            $scope.isAdministrator = false;
    57            $scope.interval = defaultPageUpdateInterval;
    68            $scope.completedJobCurPage = 1;
     
    3032            };
    3133
     34            var getAllActiveJobsFromAllUsers = function () {
     35                jobService.getAllActiveJobsFromAllUsers({}, function (jobs) {
     36                    $scope.isAdministrator = true;
     37                    $scope.allUsersJobs = jobs;
     38                    var length = $scope.allUsersJobs.length;
     39                    for (var i = 0; i < length; ++i) {
     40                        $scope.allUsersJobs[i].DateCreated = CSharpDateToString($scope.allUsersJobs[i].DateCreated);
     41                    }
     42                });
     43            };
     44
    3245            $scope.changeCompletedJobPage = function () {
    3346                update();
     
    3649            var update = function () {
    3750                getAllJobs();
     51                if (first || $scope.isAdministrator) {
     52                    getAllActiveJobsFromAllUsers();
     53                }
    3854                getCompletedJobs();
    3955            };
     56
    4057
    4158            $scope.updateInterval = $interval(update, $scope.interval);
     
    4562            });
    4663            update(); // init page
     64            first = false;
    4765        }]
    4866    );
  • branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/services/clientService.js

    r12516 r12525  
    77                getClientDetails: { method: 'GET', params: { action: 'GetClientDetails' } },
    88                getClients: { method: 'GET', params: { action: 'GetClients' } },
    9                 getClientHistory: { method: 'GET', params: { action: 'GetClientHistory' }, isArray: true }
     9                getClientsByGroupId: { method: 'GET', params: { action: 'GetClientsByGroupId' } },
     10                getClientHistory: { method: 'GET', params: { action: 'GetClientHistory' }, isArray: true },
     11                getClientHistoryByGroupId: { method: 'GET', params: { action: 'GetClientHistoryByGroupId' }, isArray: true }
    1012            });
    1113        }]
  • branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/services/jobService.js

    r12516 r12525  
    1010                getJobsByUserId: { method: 'GET', params: { action: 'GetJobsByUserId' } },
    1111                getAllJobsByUserId: { method: 'GET', params: { action: 'GetAllJobsByUserId'}, isArray: true },
    12                 getJobTasksStatesByJobId: { method: 'GET', params: { action: 'GetJobTasksStatesByJobId' }, isArray: true }
     12                getJobTasksStatesByJobId: { method: 'GET', params: { action: 'GetJobTasksStatesByJobId' }, isArray: true },
     13                getAllActiveJobsFromAllUsers: { method: 'GET', params: { action: 'GetAllActiveJobsFromAllUsers' }, isArray: true }
    1314            });
    1415        }]
  • branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/users/details/userDetails.cshtml

    r12516 r12525  
    1212        <li>
    1313            <a ng-href="#/statistics/clients">Clients</a>
     14        </li>
     15        <li>
     16            <a ng-href="#/statistics/groups">Groups</a>
    1417        </li>
    1518    </ul>
  • branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/users/users.cshtml

    r12516 r12525  
    1212        <li>
    1313            <a ng-href="#/statistics/clients">Clients</a>
     14        </li>
     15        <li>
     16            <a ng-href="#/statistics/groups">Groups</a>
    1417        </li>
    1518    </ul>
  • branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/statistics.js

    r12516 r12525  
    1010        'WebApp/services/userService.js',
    1111        'WebApp/services/clientService.js',
     12        'WebApp/services/groupService.js',
    1213        'WebApp/jobs/jobsCtrl.js',
    1314        'WebApp/jobs/details/jobDetailsCtrl.js',
     
    1718        'WebApp/clients/details/clientTaskDetailsDialogCtrl.js',
    1819        'WebApp/users/usersCtrl.js',
    19         'WebApp/users/details/userDetailsCtrl.js'
     20        'WebApp/users/details/userDetailsCtrl.js',
     21        'WebApp/groups/groupsCtrl.js',
     22        'WebApp/groups/details/groupDetailsCtrl.js'
    2023    ];
    2124    plugin.view = 'WebApp/jobs/jobs.cshtml';
     
    2730        new Route('clients/:id', 'WebApp/clients/details/clientDetails.cshtml', 'app.statistics.clientDetailsCtrl'),
    2831        new Route('users', 'WebApp/users/users.cshtml', 'app.statistics.usersCtrl'),
    29         new Route('users/:id', 'WebApp/users/details/userDetails.cshtml', 'app.statistics.userDetailsCtrl')
     32        new Route('users/:id', 'WebApp/users/details/userDetails.cshtml', 'app.statistics.userDetailsCtrl'),
     33        new Route('groups', 'WebApp/groups/groups.cshtml', 'app.statistics.groupsCtrl'),
     34        new Route('groups/:id', 'WebApp/groups/details/groupDetails.cshtml', 'app.statistics.groupDetailsCtrl')
    3035    ];
    3136    var menu = app.getMenu();
     
    3338    section.addEntry({
    3439        name: 'Statistics',
    35         route: '#/statistics/jobs',
     40        route: '#/statistics',
    3641        icon: 'glyphicon glyphicon-stats',
    3742        entries: []
Note: See TracChangeset for help on using the changeset viewer.