Skip to content

Commit c52a06e

Browse files
author
Johannes Stelzer
committed
Add support for Spring Cloud Contexts /env endpoint.
This allows to (re-)set properties via POST-requests to the environment endpoint.
1 parent a374bb2 commit c52a06e

File tree

7 files changed

+179
-56
lines changed

7 files changed

+179
-56
lines changed

spring-boot-admin-server-ui/app/css/main.css

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ body {
1111
margin-bottom: 50px;
1212
}
1313

14-
1514
.center-block {
1615
display: block;
1716
margin-left: auto;
@@ -171,6 +170,12 @@ span.refresh {
171170
color: #f1f1f1;
172171
}
173172

173+
.accordion-group,
174+
.boxed {
175+
border: 1px solid #34302D;
176+
}
177+
178+
174179
.sortable {
175180
cursor: pointer;
176181
}

spring-boot-admin-server-ui/app/js/controller/apps/environmentCtrl.js

Lines changed: 83 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,93 @@
1717

1818
module.exports = function ($scope, application) {
1919
$scope.application = application;
20+
$scope.override = { values: [{key: '', value: '' }], error: null};
2021

21-
application.getEnv(application)
22-
.success(function (env) {
22+
var toArray = function(map) {
23+
var array = [];
24+
for (var key in map) {
25+
var value = map[key];
26+
if (value instanceof Object) {
27+
value = toArray(value);
28+
}
29+
var entry = {key: key, value: value};
30+
array.push(entry);
31+
}
32+
return array.length > 0 ? array : undefined;
33+
};
34+
35+
var collectKeys = function(envArray) {
36+
var allKeys = {};
37+
for (var i = 0; i < envArray.length; i++) {
38+
for (var j = 0; envArray[i].value && j < envArray[i].value.length; j++) {
39+
allKeys[envArray[i].value[j].key] = true;
40+
}
41+
}
42+
return Object.getOwnPropertyNames(allKeys);
43+
};
44+
45+
$scope.reload = function() {
46+
$scope.env = {};
47+
$scope.envArray = [];
48+
$scope.allKeys = [];
49+
50+
application.getEnv()
51+
.success(function (env) {
2352
$scope.env = env;
53+
$scope.envArray = toArray(env);
54+
$scope.allKeys = collectKeys($scope.envArray);
2455
})
2556
.error(function (error) {
2657
$scope.error = error;
2758
});
59+
};
60+
61+
$scope.reload();
62+
63+
var getValue = function(item) {
64+
if (item.key && $scope.allKeys.indexOf(item.key) >= 0) {
65+
application.getEnv(item.key).success(function(value) {
66+
item.value = value;
67+
});
68+
}
69+
};
70+
71+
$scope.onChangeOverrideItem = function(item) {
72+
getValue(item);
73+
74+
if ($scope.override.values[$scope.override.values.length - 1].key) {
75+
$scope.override.values.push({key: '', value: '' });
76+
}
77+
};
78+
79+
$scope.overrideValue = function() {
80+
var map = {};
81+
for (var i = 0; i < $scope.override.values.length; i++) {
82+
if ($scope.override.values[i].key) {
83+
map[$scope.override.values[i].key] = $scope.override.values[i].value;
84+
}
85+
}
86+
87+
$scope.override.error = null;
88+
application.setEnv(map).success(function () {
89+
$scope.override = { values: [{key: '', value: '' }], error: null};
90+
$scope.reload();
91+
})
92+
.error(function (error) {
93+
$scope.override.error = error;
94+
$scope.reload();
95+
});
96+
};
97+
98+
$scope.reset = function() {
99+
$scope.override.error = null;
100+
application.resetEnv().success(function () {
101+
$scope.reload();
102+
})
103+
.error(function (error) {
104+
$scope.override.error = error;
105+
$scope.reload();
106+
});
107+
108+
};
28109
};

spring-boot-admin-server-ui/app/js/filter/index.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,7 @@ var angular = require('angular');
44
var springBootAdmin = angular.module('springBootAdmin');
55

66
springBootAdmin.filter('timeInterval', require('./timeInterval'));
7-
87
springBootAdmin.filter('classNameLoggerOnly', require('./classNameLoggerOnly'));
98
springBootAdmin.filter('capitalize', require('./capitalize'));
109
springBootAdmin.filter('humanBytes', require('./humanBytes'));
1110
springBootAdmin.filter('joinArray', require('./joinArray'));
12-
springBootAdmin.filter('isEmpty', require('./isEmpty'));

spring-boot-admin-server-ui/app/js/filter/isEmpty.js

Lines changed: 0 additions & 28 deletions
This file was deleted.

spring-boot-admin-server-ui/app/js/service/application.js

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,23 @@ var angular = require('angular');
1818

1919
module.exports = function ($resource, $http) {
2020

21-
var isEndpointEnabled = function(endpoint, configprops) {
21+
var isEndpointPresent = function(endpoint, configprops) {
2222
if (configprops[endpoint]) {
23-
return configprops[endpoint].properties.enabled;
23+
return true;
24+
} else {
25+
return false;
2426
}
25-
return false;
2627
};
2728

2829
var getCapabilities = function(application) {
2930
application.capabilities = {};
3031
$http.get('api/applications/' + application.id + '/configprops').success(function(configprops) {
31-
application.capabilities.logfile = isEndpointEnabled('logfileEndpoint', configprops);
32-
application.capabilities.activiti = isEndpointEnabled('processEngineEndpoint', configprops);
32+
application.capabilities.logfile = isEndpointPresent('logfileEndpoint', configprops);
33+
application.capabilities.activiti = isEndpointPresent('processEngineEndpoint', configprops);
34+
application.capabilities.restart = isEndpointPresent('restartEndpoint', configprops);
35+
application.capabilities.refresh = isEndpointPresent('refreshEndpoint', configprops);
36+
application.capabilities.pause = isEndpointPresent('pauseEndpoint', configprops);
37+
application.capabilities.resume = isEndpointPresent('resumeEndpoint', configprops);
3338
});
3439
};
3540

@@ -67,8 +72,16 @@ module.exports = function ($resource, $http) {
6772
return $http.get('api/applications/' + this.id + '/metrics');
6873
};
6974

70-
Application.prototype.getEnv = function () {
71-
return $http.get('api/applications/' + this.id + '/env');
75+
Application.prototype.getEnv = function (key) {
76+
return $http.get('api/applications/' + this.id + '/env' + (key ? '/' + key : '' ));
77+
};
78+
79+
Application.prototype.setEnv = function (map) {
80+
return $http.post('api/applications/' + this.id + '/env', '', {params: map});
81+
};
82+
83+
Application.prototype.resetEnv = function () {
84+
return $http.post('api/applications/' + this.id + '/env/reset');
7285
};
7386

7487
Application.prototype.getThreadDump = function () {

spring-boot-admin-server-ui/app/views/apps/environment.html

Lines changed: 69 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,74 @@
33
<b>Error:</b> {{ error }}
44
</div>
55
<div class="row">
6-
<accordion close-others="false">
7-
<accordion-group is-open="true" ng-repeat="(envkey, envvalue) in env track by envkey" heading="{{envkey}}" ng-hide="envvalue | isEmpty">
8-
<small class="pull-right"><a href="{{ application.managementUrl }}/env">raw JSON</a></small>
9-
<table class="table table-striped">
10-
<col >
11-
<col width="62%">
12-
<tbody>
13-
<tr ng-repeat-end ng-repeat="(key, value) in envvalue" >
14-
<td style="word-break: break-all;" >{{ key }}</td>
15-
<td style="word-break: break-all;" >{{ value }}</td>
16-
</tr>
17-
</tbody>
18-
</table>
19-
</accordion-group>
20-
</accordion>
6+
<table class="table table-hover boxed">
7+
<thead><tr><th>Profiles <small class="pull-right"><small class="pull-right"><a href="{{ application.managementUrl }}/env">raw JSON</a></small></th></tr></thead>
8+
<tbody>
9+
<tr ng-repeat="profile in env.profiles" >
10+
<td style="word-break: break-all;" >{{ profile }}</td>
11+
</tr>
12+
<tr ng-hide="env.profiles" >
13+
<td style="word-break: break-all;" >No profiles active</td>
14+
</tr>
15+
</tbody>
16+
</table>
17+
</div>
18+
<div class="row" ng-show="application.capabilities.refresh">
19+
<table class="table table-hover boxed">
20+
<col width="38%">
21+
<col width="62%">
22+
<thead><tr><th colspan="2">Overriden properties</th></tr></thead>
23+
<tbody>
24+
<tr ng-repeat="(key, value) in env.manager track by key" >
25+
<td style="word-break: break-all;" >{{ key }}</td>
26+
<td style="word-break: break-all;" >{{ value }}</td>
27+
</tr>
28+
<tr ng-repeat="item in override.values">
29+
<td >
30+
<input type="text" class="input-xlarge" list="allkeys" placeholder="key" ng-model="item.key" ng-change="onChangeOverrideItem(item)"></input>
31+
<datalist id="allkeys">
32+
<option ng-repeat="key in allKeys | orderBy:'toString()' track by key">{{key}}</option>
33+
</datalist>
34+
</td>
35+
<td>
36+
<input type="text" class="input-xxlarge" placeholder="value" ng-model="item.value"></input>
37+
</td>
38+
</tr>
39+
<tr>
40+
</tbody>
41+
<tfoot>
42+
<tr>
43+
<td colspan="2">
44+
<div class="control-group pull-right">
45+
<button class="btn btn-warning" ng-click="overrideValue()">Overrride Values!</button>
46+
<button class="btn" ng-click="reset()">Reset Values!</button>
47+
</div>
48+
<div class="alert alert-error" ng-if="override.error">
49+
<b>Error:</b> {{ override.error }}
50+
</div>
51+
</td>
52+
</tr>
53+
</tfoot>
54+
</table>
55+
</div>
56+
<div class="row">
57+
<div>
58+
<div class="input-append">
59+
<input placeholder="Filter by name/value ..." class="input-xxlarge" type="search" ng-model="searchFilter" />
60+
<button class="btn" title="reload list" ng-click="reload()"><i class="icon-refresh"></i></button>
61+
</div>
62+
</div>
63+
<table class="table table-hover boxed" ng-repeat="item in envArray track by item.key" ng-show="item.key != 'profiles' && (item.value | filter:searchFilter).length > 0">
64+
<col width="38%">
65+
<col width="62%">
66+
<thead><tr><th colspan="2">{{item.key}}</th></tr></thead>
67+
<tbody>
68+
<tr ng-repeat="property in item.value | filter:searchFilter track by property.key" >
69+
<td style="word-break: break-all;" >{{ property.key }}</td>
70+
<td style="word-break: break-all;" >{{ property.value }}</td>
71+
</tr>
72+
</tbody>
73+
</table>
2174
</div>
2275
</div>
76+

spring-boot-admin-server-ui/app/views/apps/logging.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
<span title="filtered / total" class="add-on">{{ filteredLoggers.length }}/{{ loggers.length }}</span>
88
</div>
99
</form>
10-
<table class="table">
10+
<table class="table table-hover">
1111
<tbody>
1212
<tr ng-repeat="logger in (filteredLoggers = (loggers | classNameLoggerOnly:!showPackageLoggers | filter:filterLogger) ) | limitTo: limit track by logger.name">
1313
<td>

0 commit comments

Comments
 (0)