Commit a3152233 by Johannes Stelzer

Streamlined Rest-Endpoints and Restructured ngServices and -Resources

parent 340078ef
...@@ -61,7 +61,7 @@ springBootAdmin.config(function ($stateProvider, $urlRouterProvider) { ...@@ -61,7 +61,7 @@ springBootAdmin.config(function ($stateProvider, $urlRouterProvider) {
templateUrl: 'views/apps.html', templateUrl: 'views/apps.html',
resolve: { resolve: {
application: function ($stateParams, Application) { application: function ($stateParams, Application) {
return Application.query({ return Application.get({
id: $stateParams.id id: $stateParams.id
}) })
.$promise; .$promise;
......
...@@ -15,9 +15,9 @@ ...@@ -15,9 +15,9 @@
*/ */
'use strict'; 'use strict';
module.exports = function ($scope, application, ApplicationDetails) { module.exports = function ($scope, application) {
$scope.application = application; $scope.application = application;
ApplicationDetails.getEnv(application) application.getEnv()
.success(function (env) { .success(function (env) {
var separator = env.systemProperties['path.separator']; var separator = env.systemProperties['path.separator'];
$scope.classpath = env.systemProperties['java.class.path'].split(separator); $scope.classpath = env.systemProperties['java.class.path'].split(separator);
......
...@@ -15,9 +15,10 @@ ...@@ -15,9 +15,10 @@
*/ */
'use strict'; 'use strict';
module.exports = function ($scope, application, ApplicationDetails) { module.exports = function ($scope, application) {
$scope.application = application; $scope.application = application;
ApplicationDetails.getEnv(application)
application.getEnv(application)
.success(function (env) { .success(function (env) {
$scope.env = env; $scope.env = env;
}) })
......
...@@ -15,14 +15,14 @@ ...@@ -15,14 +15,14 @@
*/ */
'use strict'; 'use strict';
module.exports = function ($scope, application, ApplicationDetails, Abbreviator, MetricsHelper) { module.exports = function ($scope, application, Abbreviator, MetricsHelper) {
$scope.counters = []; $scope.counters = [];
$scope.countersMax = 0; $scope.countersMax = 0;
$scope.gauges = []; $scope.gauges = [];
$scope.gaugesMax = 0; $scope.gaugesMax = 0;
$scope.showRichGauges = false; $scope.showRichGauges = false;
ApplicationDetails.getMetrics(application) application.getMetrics()
.success(function (metrics) { .success(function (metrics) {
function merge(array, obj) { function merge(array, obj) {
for (var i = 0; i < array.length; i++) { for (var i = 0; i < array.length; i++) {
......
...@@ -15,9 +15,10 @@ ...@@ -15,9 +15,10 @@
*/ */
'use strict'; 'use strict';
module.exports = function ($scope, application, ApplicationDetails) { module.exports = function ($scope, application) {
$scope.application = application; $scope.application = application;
ApplicationDetails.getEnv(application)
application.getEnv()
.success(function (env) { .success(function (env) {
$scope.props = []; $scope.props = [];
for (var attr in env) { for (var attr in env) {
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
*/ */
'use strict'; 'use strict';
module.exports = function ($scope, $interval, application, ApplicationDetails, MetricsHelper) { module.exports = function ($scope, $interval, application, MetricsHelper) {
$scope.application = application; $scope.application = application;
var start = Date.now(); var start = Date.now();
...@@ -23,7 +23,7 @@ module.exports = function ($scope, $interval, application, ApplicationDetails, M ...@@ -23,7 +23,7 @@ module.exports = function ($scope, $interval, application, ApplicationDetails, M
$scope.ticks = Date.now() - start; $scope.ticks = Date.now() - start;
}, 1000); }, 1000);
ApplicationDetails.getInfo(application) application.getInfo()
.success(function (info) { .success(function (info) {
$scope.info = info; $scope.info = info;
}) })
...@@ -31,7 +31,7 @@ module.exports = function ($scope, $interval, application, ApplicationDetails, M ...@@ -31,7 +31,7 @@ module.exports = function ($scope, $interval, application, ApplicationDetails, M
$scope.error = error; $scope.error = error;
}); });
ApplicationDetails.getHealth(application) application.getHealth()
.success(function (health) { .success(function (health) {
$scope.health = health; $scope.health = health;
}) })
...@@ -39,7 +39,7 @@ module.exports = function ($scope, $interval, application, ApplicationDetails, M ...@@ -39,7 +39,7 @@ module.exports = function ($scope, $interval, application, ApplicationDetails, M
$scope.health = health; $scope.health = health;
}); });
ApplicationDetails.getMetrics(application) application.getMetrics()
.success(function (metrics) { .success(function (metrics) {
$scope.metrics = metrics; $scope.metrics = metrics;
$scope.metrics['mem.used'] = $scope.metrics.mem - $scope.metrics['mem.free']; $scope.metrics['mem.used'] = $scope.metrics.mem - $scope.metrics['mem.free'];
......
...@@ -15,9 +15,9 @@ ...@@ -15,9 +15,9 @@
*/ */
'use strict'; 'use strict';
module.exports = function ($scope, application, ApplicationThreads) { module.exports = function ($scope, application) {
$scope.dumpThreads = function () { $scope.dumpThreads = function () {
ApplicationThreads.getDump(application) application.getThreadDump()
.success(function (dump) { .success(function (dump) {
$scope.dump = dump; $scope.dump = dump;
......
...@@ -15,14 +15,14 @@ ...@@ -15,14 +15,14 @@
*/ */
'use strict'; 'use strict';
module.exports = function ($scope, application, ApplicationTrace, $interval) { module.exports = function ($scope, application, $interval) {
$scope.lastTraceTime = 0; $scope.lastTraceTime = 0;
$scope.traces = []; $scope.traces = [];
$scope.refresher = null; $scope.refresher = null;
$scope.refreshInterval = 5; $scope.refreshInterval = 5;
$scope.refresh = function () { $scope.refresh = function () {
ApplicationTrace.getTraces(application) application.getTraces()
.success(function (traces) { .success(function (traces) {
for (var i = 0; i < traces.length; i++) { for (var i = 0; i < traces.length; i++) {
if (traces[i].timestamp > $scope.lastTraceTime) { if (traces[i].timestamp > $scope.lastTraceTime) {
......
...@@ -5,12 +5,12 @@ var springBootAdmin = angular.module('springBootAdmin'); ...@@ -5,12 +5,12 @@ var springBootAdmin = angular.module('springBootAdmin');
springBootAdmin.controller('overviewCtrl', require('./overviewCtrl')); springBootAdmin.controller('overviewCtrl', require('./overviewCtrl'));
springBootAdmin.controller('appsCtrl', require('./appsCtrl')); springBootAdmin.controller('appsCtrl', require('./appsCtrl'));
springBootAdmin.controller('detailsCtrl', require('./detailsCtrl')); springBootAdmin.controller('detailsCtrl', require('./apps/detailsCtrl'));
springBootAdmin.controller('detailsMetricsCtrl', require('./detailsMetricsCtrl')); springBootAdmin.controller('detailsMetricsCtrl', require('./apps/details/metricsCtrl'));
springBootAdmin.controller('detailsEnvCtrl', require('./detailsEnvCtrl')); springBootAdmin.controller('detailsEnvCtrl', require('./apps/details/envCtrl'));
springBootAdmin.controller('detailsPropsCtrl', require('./detailsPropsCtrl')); springBootAdmin.controller('detailsPropsCtrl', require('./apps/details/propsCtrl'));
springBootAdmin.controller('detailsClasspathCtrl', require('./detailsClasspathCtrl')); springBootAdmin.controller('detailsClasspathCtrl', require('./apps/details/classpathCtrl'));
springBootAdmin.controller('loggingCtrl', require('./loggingCtrl')); springBootAdmin.controller('loggingCtrl', require('./apps/loggingCtrl'));
springBootAdmin.controller('jmxCtrl', require('./jmxCtrl')); springBootAdmin.controller('jmxCtrl', require('./apps/jmxCtrl'));
springBootAdmin.controller('threadsCtrl', require('./threadsCtrl')); springBootAdmin.controller('threadsCtrl', require('./apps/threadsCtrl'));
springBootAdmin.controller('traceCtrl', require('./traceCtrl')); springBootAdmin.controller('traceCtrl', require('./apps/traceCtrl'));
...@@ -15,10 +15,45 @@ ...@@ -15,10 +15,45 @@
*/ */
'use strict'; 'use strict';
module.exports = function ($scope, $location, $interval, $q, Applications, ApplicationOverview, module.exports = function ($scope, $location, $interval, $q, Application) {
Application) { var getInfo = function (app) {
return app.getInfo()
.success(function (response) {
app.version = response.version;
delete response.version;
app.info = response;
})
.error(function () {
app.version = '---';
});
};
var getHealth = function (app) {
return app.getHealth()
.success(function (response) {
app.status = response.status;
})
.error(function (response, httpStatus) {
if (httpStatus === 503) {
app.status = response.status;
} else if (httpStatus === 404 || httpStatus === 0) {
app.status = 'OFFLINE';
} else {
app.status = 'UNKNOWN';
}
});
};
var getLogfile = function (app) {
return app.hasLogfile()
.success(function () {
app.providesLogfile = true;
})
.error(function () {
app.providesLogfile = false;
});
};
$scope.loadData = function () { $scope.loadData = function () {
Applications.query(function (applications) { Application.query(function (applications) {
function refresh(app) { function refresh(app) {
//find application in known applications and copy state --> less flickering //find application in known applications and copy state --> less flickering
for (var j = 0; $scope.applications != null && j < $scope.applications for (var j = 0; $scope.applications != null && j < $scope.applications
...@@ -32,9 +67,7 @@ module.exports = function ($scope, $location, $interval, $q, Applications, Appli ...@@ -32,9 +67,7 @@ module.exports = function ($scope, $location, $interval, $q, Applications, Appli
} }
} }
app.refreshing = true; app.refreshing = true;
$q.all(ApplicationOverview.getInfo(app), $q.all(getInfo(app), getHealth(app), getLogfile(app))
ApplicationOverview.getHealth(app),
ApplicationOverview.getLogfile(app))
.finally(function () { .finally(function () {
app.refreshing = false; app.refreshing = false;
}); });
...@@ -46,12 +79,9 @@ module.exports = function ($scope, $location, $interval, $q, Applications, Appli ...@@ -46,12 +79,9 @@ module.exports = function ($scope, $location, $interval, $q, Applications, Appli
$scope.applications = applications; $scope.applications = applications;
}); });
}; };
$scope.loadData();
$scope.remove = function (application) { $scope.remove = function (application) {
Application.remove({ application.$remove(function () {
id: application.id
}, function () {
var index = $scope.applications.indexOf(application); var index = $scope.applications.indexOf(application);
if (index > -1) { if (index > -1) {
$scope.applications.splice(index, 1); $scope.applications.splice(index, 1);
...@@ -59,11 +89,6 @@ module.exports = function ($scope, $location, $interval, $q, Applications, Appli ...@@ -59,11 +89,6 @@ module.exports = function ($scope, $location, $interval, $q, Applications, Appli
}); });
}; };
// reload site every 30 seconds
$interval(function () {
$scope.loadData();
}, 30000);
$scope.order = { $scope.order = {
column: 'name', column: 'name',
descending: false descending: false
...@@ -85,4 +110,12 @@ module.exports = function ($scope, $location, $interval, $q, Applications, Appli ...@@ -85,4 +110,12 @@ module.exports = function ($scope, $location, $interval, $q, Applications, Appli
return ''; return '';
} }
}; };
//initial load
$scope.loadData();
// reload site every 30 seconds
$interval(function () {
$scope.loadData();
}, 30000);
}; };
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
*/ */
'use strict'; 'use strict';
module.exports = function() { module.exports = function () {
var units = { B: Math.pow(1024, 0) var units = { B: Math.pow(1024, 0)
, K: Math.pow(1024, 1) , K: Math.pow(1024, 1)
, M: Math.pow(1024, 2) , M: Math.pow(1024, 2)
......
...@@ -15,14 +15,49 @@ ...@@ -15,14 +15,49 @@
*/ */
'use strict'; 'use strict';
module.exports = function ($resource) { module.exports = function ($resource, $http, $rootScope) {
return $resource( var Application = $resource(
'api/application/:id', {}, { 'api/applications/:id', { id: '@id' }, {
query: { query: { method: 'GET', isArray: true },
method: 'GET' get: { method: 'GET' },
}, remove: { method: 'DELETE' }
remove: {
method: 'DELETE'
}
}); });
var AuthInterceptor = function (application) {
return function (data, status, headers) {
if (status === 401) {
$rootScope.$emit('application-auth-required', application, headers('WWW-Authenticate').split(' ')[0]);
}
};
};
Application.prototype.getHealth = function () {
return $http.get(this.url + '/health').error(new AuthInterceptor(this));
};
Application.prototype.getInfo = function () {
return $http.get(this.url + '/info').error(new AuthInterceptor(this));
};
Application.prototype.getMetrics = function () {
return $http.get(this.url + '/metrics').error(new AuthInterceptor(this));
};
Application.prototype.getEnv = function () {
return $http.get(this.url + '/env').error(new AuthInterceptor(this));
};
Application.prototype.getThreadDump = function () {
return $http.get(this.url + '/dump').error(new AuthInterceptor(this));
};
Application.prototype.getTraces = function () {
return $http.get(this.url + '/trace').error(new AuthInterceptor(this));
};
Application.prototype.hasLogfile = function () {
return $http.head(this.url + '/logfile').error(new AuthInterceptor(this));
};
return Application;
}; };
/*
* Copyright 2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
'use strict';
module.exports = function ($http) {
this.getInfo = function (app) {
return $http.get(app.url + '/info');
};
this.getMetrics = function (app) {
return $http.get(app.url + '/metrics');
};
this.getEnv = function (app) {
return $http.get(app.url + '/env');
};
this.getHealth = function (app) {
return $http.get(app.url + '/health');
};
};
/*
* Copyright 2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
'use strict';
module.exports = function ($http) {
this.getInfo = function (app) {
return $http.get(app.url + '/info')
.success(function (response) {
app.version = response.version;
delete response.version;
app.info = response;
})
.error(function () {
app.version = '---';
});
};
this.getHealth = function (app) {
return $http.get(app.url + '/health')
.success(function (response) {
app.status = response.status;
})
.error(function (response, httpStatus) {
if (httpStatus === 503) {
app.status = response.status;
} else if (httpStatus === 404 || httpStatus === 0) {
app.status = 'OFFLINE';
} else {
app.status = 'UNKNOWN';
}
});
};
this.getLogfile = function (app) {
return $http.head(app.url + '/logfile')
.success(function () {
app.providesLogfile = true;
})
.error(function () {
app.providesLogfile = false;
});
};
};
/*
* Copyright 2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
'use strict';
module.exports = function ($http) {
this.getDump = function (app) {
return $http.get(app.url + '/dump');
};
};
/*
* Copyright 2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
'use strict';
module.exports = function ($http) {
this.getTraces = function (app) {
return $http.get(app.url + '/trace');
};
};
/*
* Copyright 2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
'use strict';
module.exports = function ($resource) {
return $resource(
'api/applications', {}, {
query: {
method: 'GET',
isArray: true
}
});
};
...@@ -3,15 +3,10 @@ ...@@ -3,15 +3,10 @@
var angular = require('angular'); var angular = require('angular');
var springBootAdmin = angular.module('springBootAdmin'); var springBootAdmin = angular.module('springBootAdmin');
springBootAdmin.factory('Applications', require('./applications'));
springBootAdmin.factory('Application', require('./application')); springBootAdmin.factory('Application', require('./application'));
springBootAdmin.service('ApplicationOverview', require('./applicationOverview'));
springBootAdmin.service('ApplicationDetails', require('./applicationDetails'));
springBootAdmin.service('ApplicationLogging', require('./applicationLogging')); springBootAdmin.service('ApplicationLogging', require('./applicationLogging'));
springBootAdmin.service('ApplicationJMX', require('./applicationJmx')); springBootAdmin.service('ApplicationJMX', require('./applicationJmx'));
springBootAdmin.service('Abbreviator', require('./abbreviator')); springBootAdmin.service('Abbreviator', require('./abbreviator'));
springBootAdmin.service('jolokia', require('./jolokia')); springBootAdmin.service('jolokia', require('./jolokia'));
springBootAdmin.service('MetricsHelper', require('./metricsHelper')); springBootAdmin.service('MetricsHelper', require('./metricsHelper'));
springBootAdmin.service('ApplicationThreads', require('./applicationThreads'));
springBootAdmin.service('ApplicationTrace', require('./applicationTrace'));
...@@ -161,7 +161,11 @@ gulp.task('backend-server', shell.task([ ...@@ -161,7 +161,11 @@ gulp.task('backend-server', shell.task([
])); ]));
gulp.task('server', ['browserify', 'copy'], function () { gulp.task('server', ['browserify', 'copy'], function () {
if (argv.nobackend === true) {
process.stdout.write('Running UI only\n');
} else {
gulp.start('backend-server'); gulp.start('backend-server');
}
connect.server({ connect.server({
root: target('/dist'), root: target('/dist'),
livereload: liveReload, livereload: liveReload,
......
...@@ -36,6 +36,7 @@ import de.codecentric.boot.admin.registry.ApplicationRegistryConflictException; ...@@ -36,6 +36,7 @@ import de.codecentric.boot.admin.registry.ApplicationRegistryConflictException;
* REST controller for controlling registration of managed applications. * REST controller for controlling registration of managed applications.
*/ */
@RestController @RestController
@RequestMapping(value = "/api/applications")
public class RegistryController { public class RegistryController {
private static final Logger LOGGER = LoggerFactory.getLogger(RegistryController.class); private static final Logger LOGGER = LoggerFactory.getLogger(RegistryController.class);
...@@ -52,7 +53,7 @@ public class RegistryController { ...@@ -52,7 +53,7 @@ public class RegistryController {
* @param app The application infos. * @param app The application infos.
* @return The registered application. * @return The registered application.
*/ */
@RequestMapping(value = "/api/applications", method = RequestMethod.POST) @RequestMapping(method = RequestMethod.POST)
public ResponseEntity<Application> register(@RequestBody Application app) { public ResponseEntity<Application> register(@RequestBody Application app) {
LOGGER.debug("Register application {}", app.toString()); LOGGER.debug("Register application {}", app.toString());
try { try {
...@@ -64,12 +65,28 @@ public class RegistryController { ...@@ -64,12 +65,28 @@ public class RegistryController {
} }
/** /**
* List all registered applications with name
*
* @return List.
*/
@RequestMapping(method = RequestMethod.GET)
public Collection<Application> applications(@RequestParam(value = "name", required = false) String name) {
LOGGER.debug("Deliver registered applications with name= {}", name);
if (name == null || name.isEmpty()) {
return registry.getApplications();
}
else {
return registry.getApplicationsByName(name);
}
}
/**
* Get a single application out of the registry. * Get a single application out of the registry.
* *
* @param id The application identifier. * @param id The application identifier.
* @return The registered application. * @return The registered application.
*/ */
@RequestMapping(value = "/api/application/{id}", method = RequestMethod.GET) @RequestMapping(value = "/{id}", method = RequestMethod.GET)
public ResponseEntity<Application> get(@PathVariable String id) { public ResponseEntity<Application> get(@PathVariable String id) {
LOGGER.debug("Deliver registered application with ID '{}'", id); LOGGER.debug("Deliver registered application with ID '{}'", id);
Application application = registry.getApplication(id); Application application = registry.getApplication(id);
...@@ -85,7 +102,7 @@ public class RegistryController { ...@@ -85,7 +102,7 @@ public class RegistryController {
* *
* @param id The application id. * @param id The application id.
*/ */
@RequestMapping(value = "/api/application/{id}", method = RequestMethod.DELETE) @RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
public ResponseEntity<Application> unregister(@PathVariable String id) { public ResponseEntity<Application> unregister(@PathVariable String id) {
LOGGER.debug("Unregister application with ID '{}'", id); LOGGER.debug("Unregister application with ID '{}'", id);
Application app = registry.unregister(id); Application app = registry.unregister(id);
...@@ -96,18 +113,4 @@ public class RegistryController { ...@@ -96,18 +113,4 @@ public class RegistryController {
} }
} }
/**
* List all registered applications with name
*
* @return List.
*/
@RequestMapping(value = "/api/applications", method = RequestMethod.GET)
public Collection<Application> applications(@RequestParam(value = "name", required = false) String name) {
LOGGER.debug("Deliver registered applications with name= {}", name);
if (name == null || name.isEmpty()) {
return registry.getApplications();
} else {
return registry.getApplicationsByName(name);
}
}
} }
...@@ -26,7 +26,6 @@ import java.util.Collections; ...@@ -26,7 +26,6 @@ import java.util.Collections;
import org.junit.After; import org.junit.After;
import org.junit.Before; import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
...@@ -110,7 +109,7 @@ public class AdminApplicationHazelcastTest { ...@@ -110,7 +109,7 @@ public class AdminApplicationHazelcastTest {
private ResponseEntity<Application> getApp(String id, EmbeddedWebApplicationContext context) { private ResponseEntity<Application> getApp(String id, EmbeddedWebApplicationContext context) {
int port = context.getEmbeddedServletContainer().getPort(); int port = context.getEmbeddedServletContainer().getPort();
ResponseEntity<Application> getResponse = template.getForEntity("http://localhost:" + port ResponseEntity<Application> getResponse = template.getForEntity("http://localhost:" + port
+ "/api/application/" + id, Application.class); + "/api/applications/" + id, Application.class);
return getResponse; return getResponse;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment