Skip to content

Commit 2846a07

Browse files
thomaszubThomas Zub
andauthored
feat: enable JXM writes and operations for all instances (#2014)
Co-authored-by: Thomas Zub <[email protected]>
1 parent edb131f commit 2846a07

File tree

7 files changed

+82
-10
lines changed

7 files changed

+82
-10
lines changed

spring-boot-admin-samples/spring-boot-admin-sample-servlet/pom.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,10 @@
6868
<groupId>org.hsqldb</groupId>
6969
<artifactId>hsqldb</artifactId>
7070
</dependency>
71+
<dependency>
72+
<groupId>org.jolokia</groupId>
73+
<artifactId>jolokia-core</artifactId>
74+
</dependency>
7175
<!-- Test -->
7276
<dependency>
7377
<groupId>org.springframework.boot</groupId>

spring-boot-admin-server-ui/src/main/frontend/i18n/i18n.de.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
"failed": "Fehlgeschlagen",
2525
"float": "Float",
2626
"hours": "{count} Stunde | {count} Stunden",
27+
"instance": "Instanz",
2728
"instances": "Instanzen",
2829
"integer": "Integer",
2930
"milliseconds": "Millisekunden",

spring-boot-admin-server-ui/src/main/frontend/services/application.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,31 @@ class Application {
134134
return this.axios.post(uri`actuator/restart`);
135135
}
136136

137+
async writeMBeanAttribute(domain, mBean, attribute, value) {
138+
const body = {
139+
type: 'write',
140+
mbean: `${domain}:${mBean}`,
141+
attribute,
142+
value
143+
};
144+
return this.axios.post(uri`actuator/jolokia`, body, {
145+
headers: {'Accept': 'application/json', 'Content-Type': 'application/json'}
146+
});
147+
}
148+
149+
async invokeMBeanOperation(domain, mBean, operation, args) {
150+
const body = {
151+
type: 'exec',
152+
mbean: `${domain}:${mBean}`,
153+
operation,
154+
'arguments': args
155+
};
156+
return this.axios.post(uri`actuator/jolokia`, body, {
157+
headers: {'Accept': 'application/json', 'Content-Type': 'application/json'}
158+
});
159+
}
160+
161+
137162
static _transformResponse(data) {
138163
if (!data) {
139164
return data;

spring-boot-admin-server-ui/src/main/frontend/views/instances/jolokia/index.vue

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,10 @@
6161

6262
<div v-if="mBean === selectedMBean" class="card-content">
6363
<m-bean-attributes v-if="selected.view === 'attributes'" :domain="selectedDomain.domain"
64-
:instance="instance" :m-bean="mBean"
64+
:application="application" :instance="instance" :m-bean="mBean"
6565
/>
6666
<m-bean-operations v-if="selected.view === 'operations'" :domain="selectedDomain.domain"
67-
:instance="instance" :m-bean="mBean"
67+
:application="application" :instance="instance" :m-bean="mBean"
6868
/>
6969
</div>
7070
</div>
@@ -88,6 +88,7 @@
8888

8989
<script>
9090
import sticksBelow from '@/directives/sticks-below';
91+
import Application from '@/services/application';
9192
import Instance from '@/services/instance';
9293
import flatMap from 'lodash/flatMap';
9394
import fromPairs from 'lodash/fromPairs';
@@ -135,6 +136,10 @@ export class MBean {
135136
136137
export default {
137138
props: {
139+
application: {
140+
type: Application,
141+
required: true
142+
},
138143
instance: {
139144
type: Instance,
140145
required: true

spring-boot-admin-server-ui/src/main/frontend/views/instances/jolokia/m-bean-attributes.vue

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@
1616

1717
<template>
1818
<div>
19+
<div class="field is-grouped control" v-if="application.instances.length > 1">
20+
<sba-toggle-scope-button :instance-count="application.instances.length" v-model="scope" />
21+
</div>
22+
1923
<sba-alert v-if="error" :error="error" :title="$t('instances.jolokia.mbean.fetch_failed')" />
2024

2125
<m-bean-attribute v-for="(attribute, name) in mBean.attr" :key="`attr-${name}`"
@@ -26,9 +30,11 @@
2630
</template>
2731

2832
<script>
33+
import Application from '@/services/application';
2934
import Instance from '@/services/instance';
3035
import {MBean} from './index';
3136
import mBeanAttribute from './m-bean-attribute';
37+
import SbaToggleScopeButton from '@/components/sba-toggle-scope-button';
3238
3339
export default {
3440
props: {
@@ -43,12 +49,17 @@ export default {
4349
instance: {
4450
type: Instance,
4551
required: true
52+
},
53+
application: {
54+
type: Application,
55+
required: true
4656
}
4757
},
48-
components: {mBeanAttribute},
58+
components: {mBeanAttribute, SbaToggleScopeButton},
4959
data: () => ({
5060
attributeValues: null,
51-
error: null
61+
error: null,
62+
scope: 'instance'
5263
}),
5364
computed: {},
5465
methods: {
@@ -63,7 +74,8 @@ export default {
6374
},
6475
async writeAttribute(attribute, value) {
6576
try {
66-
await this.instance.writeMBeanAttribute(this.domain, this.mBean.descriptor.raw, attribute, value);
77+
const target = (this.scope === 'instance') ? this.instance : this.application;
78+
await target.writeMBeanAttribute(this.domain, this.mBean.descriptor.raw, attribute, value);
6779
} finally {
6880
await this.readAttributes();
6981
}

spring-boot-admin-server-ui/src/main/frontend/views/instances/jolokia/m-bean-operation-invocation.vue

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -168,8 +168,8 @@
168168
this.state = 'executing';
169169
try {
170170
const result = await this.onExecute(this.args);
171-
if (result.data.status < 400) {
172-
this.result = result.data.value;
171+
if (result.status < 400) {
172+
this.result = this.parseValue(result.data);
173173
this.state = 'completed';
174174
} else {
175175
const error = new Error(`Execution failed: ${result.data.error}`);
@@ -188,6 +188,19 @@
188188
if (event.keyCode === 27) {
189189
this.abort()
190190
}
191+
},
192+
parseValue(data) {
193+
if (Array.isArray(data)) {
194+
return data.map(elem => {
195+
const parsedBody = JSON.parse(elem['body']);
196+
return {
197+
instanceId: elem['instanceId'],
198+
value: parsedBody['value']
199+
};
200+
});
201+
} else {
202+
return data.value;
203+
}
191204
}
192205
},
193206
created() {

spring-boot-admin-server-ui/src/main/frontend/views/instances/jolokia/m-bean-operations.vue

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@
1616

1717
<template>
1818
<div>
19+
<div class="field is-grouped control" v-if="application.instances.length > 1">
20+
<sba-toggle-scope-button :instance-count="application.instances.length" v-model="scope" />
21+
</div>
22+
1923
<mBeanOperation v-for="(operation, name) in mBean.op" :key="`op-${name}`"
2024
:name="name" :descriptor="operation" @click="invoke(name, operation)"
2125
/>
@@ -26,10 +30,12 @@
2630
</template>
2731

2832
<script>
33+
import Application from '@/services/application';
2934
import Instance from '@/services/instance';
3035
import {MBean} from './index';
3136
import mBeanOperation from './m-bean-operation';
3237
import mBeanOperationInvocation from './m-bean-operation-invocation';
38+
import SbaToggleScopeButton from '@/components/sba-toggle-scope-button';
3339
3440
export default {
3541
props: {
@@ -41,14 +47,19 @@
4147
type: MBean,
4248
required: true
4349
},
50+
application: {
51+
type: Application,
52+
required: true
53+
},
4454
instance: {
4555
type: Instance,
4656
required: true
4757
}
4858
},
49-
components: {mBeanOperation, mBeanOperationInvocation},
59+
components: {mBeanOperation, mBeanOperationInvocation, SbaToggleScopeButton},
5060
data: () => ({
51-
invocation: null
61+
invocation: null,
62+
scope: 'instance'
5263
}),
5364
methods: {
5465
closeInvocation() {
@@ -58,7 +69,8 @@
5869
this.invocation = {name, descriptor};
5970
},
6071
execute(args) {
61-
return this.instance.invokeMBeanOperation(this.domain, this.mBean.descriptor.raw, this.invocation.name, args);
72+
const target = (this.scope === 'instance') ? this.instance : this.application;
73+
return target.invokeMBeanOperation(this.domain, this.mBean.descriptor.raw, this.invocation.name, args);
6274
}
6375
}
6476
}

0 commit comments

Comments
 (0)