diff --git a/src/ServicePulse.Host/ServicePulse.Host.csproj b/src/ServicePulse.Host/ServicePulse.Host.csproj index 0bf42007f1..6ee0881f13 100644 --- a/src/ServicePulse.Host/ServicePulse.Host.csproj +++ b/src/ServicePulse.Host/ServicePulse.Host.csproj @@ -83,6 +83,7 @@ + diff --git a/src/ServicePulse.Host/app/index.html b/src/ServicePulse.Host/app/index.html index 8711f40fba..4929375206 100644 --- a/src/ServicePulse.Host/app/index.html +++ b/src/ServicePulse.Host/app/index.html @@ -132,6 +132,6 @@

Warning!

- + \ No newline at end of file diff --git a/src/ServicePulse.Host/app/js/configuration/configuration.controller.js b/src/ServicePulse.Host/app/js/configuration/configuration.controller.js index ce3929e7e7..3d9b8fa846 100644 --- a/src/ServicePulse.Host/app/js/configuration/configuration.controller.js +++ b/src/ServicePulse.Host/app/js/configuration/configuration.controller.js @@ -1,26 +1,71 @@ -; (function (window, angular, undefined) { +; (function (window, angular, $, undefined) { 'use strict'; - function controller($scope, serviceControlService) { + function createWorkflowState(optionalStatus, optionalMessage) { + return { + status: optionalStatus || 'working', + message: optionalMessage || 'working' + }; + } + + function controller( + $scope, + $window, + $timeout, + configurationService) { + + $scope.model = { endpoints: [] }; + + + function autoGetEndPoints() { + configurationService.getData() + .then(function (response) { + if (response.data.length > 0) { + // need a map in some ui state for controlling animations + var endPoints = response.data.map(function (obj) { + var nObj = obj; + nObj.workflow_state = createWorkflowState('ready', ''); + return nObj; + }); - $scope.model = { endpoints: [], changes: {} }; + $scope.model.endpoints = endPoints; + } - $scope.update = function (id) { - var newState = $scope.model.changes[id]; + + }); + }; + + $scope.update = function (id, monitor) { + + var result = $.grep($scope.model.endpoints, function (e) { return e.id === id; })[0]; + result.workflow_state = createWorkflowState('working', 'Updating'); - serviceControlService.updateEndpoint(id, { "monitor_heartbeat": newState }); + + configurationService.update(id, monitor, 'Updating', 'Update Failed') + .then(function (message) { + result.workflow_state = createWorkflowState('ready', message); + result.monitor_heartbeat = monitor; + }, function (message) { + result.workflow_state = createWorkflowState('error', message); + }) + .finally(function () { + + }); }; - serviceControlService.getEndpoints() - .then(function (response) { - $scope.model.endpoints = response; - }); + + autoGetEndPoints(); + }; - controller.$inject = ['$scope', 'serviceControlService']; + controller.$inject = [ + '$scope', + '$window', + '$interval', + 'configurationService']; angular.module('configuration') .controller('ConfigurationCtrl', controller); -} (window, window.angular)); +} (window, window.angular, window.jQuery)); diff --git a/src/ServicePulse.Host/app/js/configuration/configuration.html b/src/ServicePulse.Host/app/js/configuration/configuration.html index b246dd0b8e..44fb68e113 100644 --- a/src/ServicePulse.Host/app/js/configuration/configuration.html +++ b/src/ServicePulse.Host/app/js/configuration/configuration.html @@ -19,14 +19,25 @@

Endpoints Configuration< Name Host Latest Heartbeat + Enabled Monitor - + {{e.name}} {{e.host_display_name}} N/A - + + +
+ {{e.workflow_state.message}} +
+ +
+ +
+ + diff --git a/src/ServicePulse.Host/app/js/configuration/configuration.module.js b/src/ServicePulse.Host/app/js/configuration/configuration.module.js index f9ef7435cf..e0501b90d1 100644 --- a/src/ServicePulse.Host/app/js/configuration/configuration.module.js +++ b/src/ServicePulse.Host/app/js/configuration/configuration.module.js @@ -1,7 +1,7 @@ ; (function (window, angular, undefined) { 'use strict'; - angular.module('configuration', []); + angular.module('configuration', ['ui.bootstrap']); } (window, window.angular)); diff --git a/src/ServicePulse.Host/app/js/configuration/configuration.service.js b/src/ServicePulse.Host/app/js/configuration/configuration.service.js new file mode 100644 index 0000000000..2c13675b44 --- /dev/null +++ b/src/ServicePulse.Host/app/js/configuration/configuration.service.js @@ -0,0 +1,60 @@ +; +(function (window, angular, undefined) { + 'use strict'; + + function Service($http, $q, scConfig, uri) { + + function patchPromise(url, data, success, error) { + + var defer = $q.defer(); + + success = success || 'success'; + error = error || 'error'; + + $http({ + url: url, + data: data, + method: 'PATCH' + }) + .success(function (response) { + defer.resolve(success + ':' + response); + }) + .error(function (response, status, headers, config) { + if (status === '304') { + defer.resolve(success + ':' + response); + } else { + defer.reject(error + ':' + response); + } + }); + + return defer.promise; + } + + function getData() { + var url = uri.join(scConfig.service_control_url, 'endpoints'); + return $http.get(url).then(function (response) { + return { + data: response.data + }; + }); + } + + var service = { + getData: getData, + update: function (id, newState, success, error) { + var url = uri.join(scConfig.service_control_url, 'endpoints', id); + return patchPromise(url, { "monitor_heartbeat": newState }, success, error); + } + }; + + return service; + + } + + Service.$inject = ['$http', '$q', 'scConfig', 'uri']; + + angular.module('configuration') + .factory('configurationService', Service); + + +}(window, window.angular)); \ No newline at end of file diff --git a/src/ServicePulse.Host/app/js/failed_messages/failedMessages.html b/src/ServicePulse.Host/app/js/failed_messages/failedMessages.html index ef5e4988ff..12c6e185f9 100644 --- a/src/ServicePulse.Host/app/js/failed_messages/failedMessages.html +++ b/src/ServicePulse.Host/app/js/failed_messages/failedMessages.html @@ -94,7 +94,7 @@

Loading...

We are still grouping your failed messages, it shouldn't be
- +
@@ -144,50 +144,53 @@

-
+
-
- -
-
{{row.message_type || 'Message Type Unknown - missing metadata EnclosedMessageTypes'}}
-
- - -
-
-
-
-
{{ row.exception.message }}
-
{{ row.exception.stack_trace }}
- - - - - - - -
{{header.key}}
{{header.value}}
-
{{row.headersUnavailable}}
-
{{row.messageBody}}
-
{{row.bodyUnavailable}}
-
-
in {{row.receiving_endpoint.name}} on {{row.receiving_endpoint.host}}
-
-
-
- Retried - Archived - Repeated Failure +
+ + +
+
{{row.message_type || 'Message Type Unknown - missing metadata EnclosedMessageTypes'}}
+
+ + +
+
+
+
+
{{ row.exception.message }}
+
{{ row.exception.stack_trace }}
+ + + + + + + +
{{header.key}}
{{header.value}}
+
{{row.headersUnavailable}}
+
{{row.messageBody}}
+
{{row.bodyUnavailable}}
+
+
in {{row.receiving_endpoint.name}} on {{row.receiving_endpoint.host}}
+
+
+
+ Retried + Archived + Repeated Failure +
+
diff --git a/src/ServicePulse.Host/app/js/services/services.service-control.js b/src/ServicePulse.Host/app/js/services/services.service-control.js index 6d66c0076c..46d5891491 100644 --- a/src/ServicePulse.Host/app/js/services/services.service-control.js +++ b/src/ServicePulse.Host/app/js/services/services.service-control.js @@ -1,4 +1,5 @@ -; (function (window, angular, $, undefined) { +; +(function(window, angular, $, undefined) { 'use strict'; @@ -6,7 +7,7 @@ function getVersion() { var url = uri.join(scConfig.service_control_url); - return $http.get(url).then(function (response) { + return $http.get(url).then(function(response) { return response.headers('X-Particular-Version'); }); }; @@ -23,14 +24,14 @@ function getEventLogItems() { var url = uri.join(scConfig.service_control_url, 'eventlogitems'); - return $http.get(url).then(function (response) { + return $http.get(url).then(function(response) { return response.data; }); }; function getFailedMessages(sortBy, page) { var url = uri.join(scConfig.service_control_url, 'errors?status=unresolved&page=' + page + '&sort=' + sortBy); - return $http.get(url).then(function (response) { + return $http.get(url).then(function(response) { return { data: response.data, total: response.headers('Total-Count') @@ -39,8 +40,8 @@ }; function getExceptionGroups() { - var url = uri.join(scConfig.service_control_url, 'recoverability','groups'); - return $http.get(url).then(function (response) { + var url = uri.join(scConfig.service_control_url, 'recoverability', 'groups'); + return $http.get(url).then(function(response) { return { data: response.data }; @@ -48,8 +49,8 @@ }; function getFailedMessagesForExceptionGroup(groupId, sortBy, page) { - var url = uri.join(scConfig.service_control_url, 'recoverability','groups',groupId,'errors?page=' + page + '&sort=' + sortBy); - return $http.get(url).then(function (response) { + var url = uri.join(scConfig.service_control_url, 'recoverability', 'groups', groupId, 'errors?page=' + page + '&sort=' + sortBy); + return $http.get(url).then(function(response) { return { data: response.data, total: response.headers('Total-Count') @@ -58,8 +59,8 @@ }; function getMessageBody(messageId) { - var url = uri.join(scConfig.service_control_url, 'messages',messageId,'body' ); - return $http.get(url).then(function (response) { + var url = uri.join(scConfig.service_control_url, 'messages', messageId, 'body'); + return $http.get(url).then(function(response) { return { data: response.data }; @@ -67,8 +68,8 @@ }; function getMessageHeaders(messageId) { - var url = uri.join(scConfig.service_control_url, 'messages','search',messageId ); - return $http.get(url).then(function (response) { + var url = uri.join(scConfig.service_control_url, 'messages', 'search', messageId); + return $http.get(url).then(function(response) { return { data: response.data }; @@ -76,22 +77,22 @@ }; function getTotalFailedMessages() { - var url = uri.join(scConfig.service_control_url, 'errors?status=unresolved' ); - return $http.get(url).then(function (response) { + var url = uri.join(scConfig.service_control_url, 'errors?status=unresolved'); + return $http.get(url).then(function(response) { return response.headers('Total-Count'); }); }; function getTotalFailingCustomChecks() { - var url = uri.join(scConfig.service_control_url, 'customchecks?status=unresolved' ); - return $http.get(url).then(function (response) { + var url = uri.join(scConfig.service_control_url, 'customchecks?status=unresolved'); + return $http.get(url).then(function(response) { return response.headers('Total-Count'); }); }; function getFailingCustomChecks(page) { - var url = uri.join(scConfig.service_control_url, 'customchecks?status=fail&page=' + page ); - return $http.get(url).then(function (response) { + var url = uri.join(scConfig.service_control_url, 'customchecks?status=fail&page=' + page); + return $http.get(url).then(function(response) { return { data: response.data, total: response.headers('Total-Count') @@ -100,8 +101,8 @@ }; function getFailedMessageStats() { - var url = uri.join(scConfig.service_control_url, 'errors','summary' ); - return $http.get(url).then(function (response) { + var url = uri.join(scConfig.service_control_url, 'errors', 'summary'); + return $http.get(url).then(function(response) { return response.data; }); }; @@ -110,10 +111,10 @@ var url = uri.join(scConfig.service_control_url, 'customchecks', customCheck.id); $http.delete(url) - .success(function () { + .success(function() { notifications.pushForCurrentRoute('"{{item.custom_check_id}}" custom check muted', 'info', { item: customCheck }); }) - .error(function () { + .error(function() { notifications.pushForCurrentRoute('Failed to mute "{{item.custom_check_id}}" custom check', 'danger', { item: customCheck }); }); }; @@ -121,21 +122,21 @@ function retryAllFailedMessages() { var url = uri.join(scConfig.service_control_url, 'errors', 'retry', 'all'); $http.post(url) - .success(function () { - // notifications.pushForCurrentRoute('Retrying all messages...', 'info'); + .success(function() { + notifications.pushForCurrentRoute('Retrying all messages...', 'info'); }) - .error(function () { + .error(function() { notifications.pushForCurrentRoute('Retrying all messages failed', 'danger'); }); }; function retryFailedMessages(selectedMessages) { - var url = uri.join(scConfig.service_control_url, 'errors', 'retry', selectedMessages); - $http.post(url) - .success(function () { - // notifications.pushForCurrentRoute('Retrying {{num}} messages...', 'info', { num: selectedMessages.length }); + var url = uri.join(scConfig.service_control_url, 'errors', 'retry'); + $http.post(url, selectedMessages) + .success(function() { + notifications.pushForCurrentRoute('Retrying {{num}} messages...', 'info', { num: selectedMessages.length }); }) - .error(function () { + .error(function() { notifications.pushForCurrentRoute('Retrying messages failed', 'danger'); }); }; @@ -148,10 +149,10 @@ data: selectedMessages, method: 'PATCH' }) - .success(function () { - // notifications.pushForCurrentRoute('Archiving {{num}} messages...', 'info', { num: selectedMessages.length }); + .success(function() { + notifications.pushForCurrentRoute('Archiving {{num}} messages...', 'info', { num: selectedMessages.length }); }) - .error(function () { + .error(function() { notifications.pushForCurrentRoute('Archiving messages failed', 'danger'); }); }; @@ -159,10 +160,10 @@ function archiveExceptionGroup(id, successText) { var url = uri.join(scConfig.service_control_url, 'recoverability', 'groups', id, 'errors', 'archive'); $http.post(url) - .success(function () { + .success(function() { // notifications.pushForCurrentRoute(successText, 'info'); }) - .error(function () { + .error(function() { notifications.pushForCurrentRoute('Archiving messages failed', 'danger'); }); }; @@ -171,52 +172,17 @@ var url = uri.join(scConfig.service_control_url, 'recoverability', 'groups', id, 'errors', 'retry'); $http.post(url) - .success(function () { + .success(function() { // notifications.pushForCurrentRoute(successText, 'info'); }) - .error(function () { + .error(function() { notifications.pushForCurrentRoute('Retrying messages failed', 'danger'); }); }; function getHeartbeatStats() { var url = uri.join(scConfig.service_control_url, 'heartbeats', 'stats'); - return $http.get(url).then(function (response) { - return response.data; - }); - }; - - - function removeEndpoint(endpoint) { - var url = uri.join(scConfig.service_control_url, 'heartbeats', endpoint.id); - $http.delete(url) - .success(function () { - // notifications.pushForCurrentRoute('{{item.originating_endpoint.name}}@{{item.originating_endpoint.machine}} endpoint removed', 'info', { item: endpoint }); - }) - .error(function () { - notifications.pushForCurrentRoute('Failed to remove {{item.originating_endpoint.name}}@{{item.originating_endpoint.machine}} endpoint', 'danger', { item: endpoint }); - }); - }; - - function updateEndpoint(id, data) { - var url = uri.join(scConfig.service_control_url, 'endpoints', id); - - return $http({ - url: url, - data: data, - method: "PATCH", - }) - .success(function () { - // notifications.pushForCurrentRoute('Endpoint updated', 'info'); - }) - .error(function () { - notifications.pushForCurrentRoute('Failed to update endpoint', 'danger'); - }); - }; - - function getEndpoints() { - var url = uri.join(scConfig.service_control_url, 'endpoints'); - return $http.get(url).then(function (response) { + return $http.get(url).then(function(response) { return response.data; }); }; @@ -224,11 +190,11 @@ function getEndpointsWithSla() { return this .getEndpoints() - .then(function (endpoints) { + .then(function(endpoints) { var results = []; - endpoints.forEach(function (item) { + endpoints.forEach(function(item) { var url = uri.join(scConfig.service_control_url, 'endpoints', item.name, 'sla'); - $http.get(url).then(function (response) { + $http.get(url).then(function(response) { angular.extend(item, { sla: response.data.current }); results.push(item); }); @@ -258,11 +224,9 @@ archiveFailedMessages: archiveFailedMessages, archiveExceptionGroup: archiveExceptionGroup, retryExceptionGroup: retryExceptionGroup, - getHeartbeatStats: getHeartbeatStats, - removeEndpoint: removeEndpoint, - updateEndpoint: updateEndpoint, - getEndpoints: getEndpoints, - getEndpointsWithSla: getEndpointsWithSla + getHeartbeatStats: getHeartbeatStats + + }; @@ -276,4 +240,4 @@ angular.module('services.serviceControlService', []) .service('serviceControlService', Service); -} (window, window.angular, window.jQuery)); \ No newline at end of file +}(window, window.angular, window.jQuery)); \ No newline at end of file diff --git a/src/ServicePulse.Host/app/js/services/services.uri.js b/src/ServicePulse.Host/app/js/services/services.uri.js index 412b4327d1..233fcc13bc 100644 --- a/src/ServicePulse.Host/app/js/services/services.uri.js +++ b/src/ServicePulse.Host/app/js/services/services.uri.js @@ -8,7 +8,7 @@ // Split the inputs into a list of path commands. var parts = []; for (var i = 0; i < arguments.length; i++) { - parts = parts.concat(arguments[i].replace(/\/$/, '')); + parts = parts.concat(('' + arguments[i]).replace(/\/$/, '')); } // Turn back into a single string path.