# HG changeset patch # User Andrew Azores # Date 1506081119 14400 # Node ID 0e10eacbeeb717ee0a823bb58956b073f433822a # Parent 362ef36b1cefc682a386dcc68f71746cf0f02259 Add byteman subview to jvm-info Reviewed-by: jerboaa Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2017-September/025146.html diff -r 362ef36b1cef -r 0e10eacbeeb7 mock-api/endpoints/jvm-byteman.endpoint.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mock-api/endpoints/jvm-byteman.endpoint.js Fri Sep 22 07:51:59 2017 -0400 @@ -0,0 +1,44 @@ +function jvmByteman (server) { + // web-gateway + var _ = require('lodash'); + server.init('jvmByteman'); + server.app.get('/jvm-byteman/0.0.1/status/jvms/:jvmId', function (req, res) { + server.logRequest('jvm-byteman', req); + + var jvmId = req.params.jvmId; + + var response = []; + var data = { + agentId: 'foo-agentId', + jvmId: jvmId, + timeStamp: { $numberLong: Date.now().toString() }, + rule: '', + listenPort: 9999 + }; + response.push(data); + + res.setHeader('Content-Type', 'application/json'); + res.send(JSON.stringify( + { + response: response + } + )); + }); + + // command channel + server.init('byteman-command'); + server.app.ws('/commands/v1/actions/byteman/systems/:systemId/agents/:agentId/jvms/:jvmId/sequence/:seqId', function (ws, req) { + server.logRequest('byteman-command', req); + ws.on('message', function (msg) { + ws.send(JSON.stringify( + { + payload: { + respType: 'OK' + } + } + )); + }); + }); +} + +module.exports = jvmByteman; diff -r 362ef36b1cef -r 0e10eacbeeb7 src/app/components/jvm-info/byteman/byteman.component.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/app/components/jvm-info/byteman/byteman.component.js Fri Sep 22 07:51:59 2017 -0400 @@ -0,0 +1,36 @@ +/** + * Copyright 2012-2017 Red Hat, Inc. + * + * Thermostat is distributed under the GNU General Public License, + * version 2 or any later version (with a special exception described + * below, commonly known as the "Classpath Exception"). + * + * A copy of GNU General Public License (GPL) is included in this + * distribution, in the file COPYING. + * + * Linking Thermostat code with other modules is making a combined work + * based on Thermostat. Thus, the terms and conditions of the GPL + * cover the whole combination. + * + * As a special exception, the copyright holders of Thermostat give you + * permission to link this code with independent modules to produce an + * executable, regardless of the license terms of these independent + * modules, and to copy and distribute the resulting executable under + * terms of your choice, provided that you also meet, for each linked + * independent module, the terms and conditions of the license of that + * module. An independent module is a module which is not derived from + * or based on Thermostat code. If you modify Thermostat, you may + * extend this exception to your version of the software, but you are + * not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + */ + +import BytemanController from './byteman.controller.js'; + +export default angular + .module('byteman', [BytemanController]) + .component('byteman', { + controller: 'BytemanController', + template: require('./byteman.html') + }) + .name; diff -r 362ef36b1cef -r 0e10eacbeeb7 src/app/components/jvm-info/byteman/byteman.controller.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/app/components/jvm-info/byteman/byteman.controller.js Fri Sep 22 07:51:59 2017 -0400 @@ -0,0 +1,96 @@ +/** + * Copyright 2012-2017 Red Hat, Inc. + * + * Thermostat is distributed under the GNU General Public License, + * version 2 or any later version (with a special exception described + * below, commonly known as the "Classpath Exception"). + * + * A copy of GNU General Public License (GPL) is included in this + * distribution, in the file COPYING. + * + * Linking Thermostat code with other modules is making a combined work + * based on Thermostat. Thus, the terms and conditions of the GPL + * cover the whole combination. + * + * As a special exception, the copyright holders of Thermostat give you + * permission to link this code with independent modules to produce an + * executable, regardless of the license terms of these independent + * modules, and to copy and distribute the resulting executable under + * terms of your choice, provided that you also meet, for each linked + * independent module, the terms and conditions of the license of that + * module. An independent module is a module which is not derived from + * or based on Thermostat code. If you modify Thermostat, you may + * extend this exception to your version of the software, but you are + * not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + */ + +import service from './byteman.service.js'; + +class BytemanController { + constructor ($stateParams, $translate, bytemanService) { + 'ngInject'; + this.jvmId = $stateParams.jvmId; + this.systemId = $stateParams.systemId; + this._translate = $translate; + this._svc = bytemanService; + + this.loadedRule = ''; + } + + $onInit () { + this._updateRules(); + } + + $onDestroy () { + } + + _updateRules () { + return this._svc.getLoadedRules(this.jvmId) + .then(res => { + this.loadedRule = res; + this._clearInput(); + }); + } + + _clearInput () { + this.ruleText = ''; + } + + refresh () { + return this._updateRules(); + } + + unload () { + if (!this.loadedRule) { + return; + } + return this._svc.unloadRules(this.systemId, this.jvmId) + .then(() => this._updateRules()); + } + + push () { + return this._svc.loadRule(this.systemId, this.jvmId, this.ruleText) + .then(() => this._updateRules()); + } + + pull () { + return this._svc.getLoadedRules(this.jvmId) + .then(res => { + this.loadedRule = res; + if (res) { + this.ruleText = res; + } + }); + } + + generateTemplate () { + return this._translate('byteman.RULE_TEMPLATE') + .then(res => this.ruleText = res); + } +} + +export default angular + .module('byteman.controller', [service]) + .controller('BytemanController', BytemanController) + .name; diff -r 362ef36b1cef -r 0e10eacbeeb7 src/app/components/jvm-info/byteman/byteman.controller.spec.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/app/components/jvm-info/byteman/byteman.controller.spec.js Fri Sep 22 07:51:59 2017 -0400 @@ -0,0 +1,183 @@ +/** + * Copyright 2012-2017 Red Hat, Inc. + * + * Thermostat is distributed under the GNU General Public License, + * version 2 or any later version (with a special exception described + * below, commonly known as the "Classpath Exception"). + * + * A copy of GNU General Public License (GPL) is included in this + * distribution, in the file COPYING. + * + * Linking Thermostat code with other modules is making a combined work + * based on Thermostat. Thus, the terms and conditions of the GPL + * cover the whole combination. + * + * As a special exception, the copyright holders of Thermostat give you + * permission to link this code with independent modules to produce an + * executable, regardless of the license terms of these independent + * modules, and to copy and distribute the resulting executable under + * terms of your choice, provided that you also meet, for each linked + * independent module, the terms and conditions of the license of that + * module. An independent module is a module which is not derived from + * or based on Thermostat code. If you modify Thermostat, you may + * extend this exception to your version of the software, but you are + * not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + */ + +import controllerModule from './byteman.controller.js'; + +describe('BytemanController', () => { + + let ctrl, stateParams, translate, svc; + beforeEach(() => { + angular.mock.module(controllerModule); + + stateParams = { + jvmId: 'foo-jvmId', + systemId: 'foo-systemId' + }; + + translate = sinon.stub(); + translate.then = sinon.stub(); + translate.returns({ then: translate.then }); + + svc = { + getLoadedRules: sinon.stub(), + loadRule: sinon.stub(), + unloadRules: sinon.stub() + }; + + angular.mock.inject($controller => { + 'ngInject'; + ctrl = $controller('BytemanController', { + $stateParams: stateParams, + $translate: translate, + bytemanService: svc + }); + }); + }); + + describe('$onInit ()', () => { + it('should load injected rules', () => { + svc.getLoadedRules.should.not.be.called(); + svc.getLoadedRules.returns({ + then: sinon.stub().yields('fake rule') + }); + + ctrl.$onInit(); + + svc.getLoadedRules.should.be.calledOnce(); + svc.getLoadedRules.should.be.calledWith(stateParams.jvmId); + ctrl.loadedRule.should.equal('fake rule'); + }); + }); + + describe('_clearInput ()', () => { + it('should reset ruleText property to the empty string', () => { + ctrl.ruleText = 'foo'; + ctrl._clearInput(); + ctrl.ruleText.should.equal(''); + }); + }); + + describe('refresh ()', () => { + it('should load injected rules', () => { + svc.getLoadedRules.should.not.be.called(); + svc.getLoadedRules.returns({ + then: sinon.stub().yields('fake rule') + }); + + ctrl.refresh(); + + svc.getLoadedRules.should.be.calledOnce(); + svc.getLoadedRules.should.be.calledWith(stateParams.jvmId); + ctrl.loadedRule.should.equal('fake rule'); + }); + }); + + describe('unload ()', () => { + it('should do nothing if no loaded rule', () => { + svc.unloadRules.should.not.be.called(); + ctrl.unload(); + svc.unloadRules.should.not.be.called(); + }); + + it('should unload rules', () => { + svc.getLoadedRules.should.not.be.called(); + svc.getLoadedRules.returns({ + then: sinon.stub().yields('fake rule') + }); + ctrl.refresh(); + + svc.getLoadedRules.returns({ + then: sinon.stub().yields('') + }); + svc.unloadRules.returns({ + then: sinon.stub().yields() + }); + ctrl.unload(); + ctrl.loadedRule.should.equal(''); + }); + }); + + describe('push ()', () => { + it('should send local rule text to service', () => { + const injectedRule = 'injected rule'; + ctrl.ruleText = injectedRule; + svc.loadRule.returns({ + then: sinon.stub().yields() + }); + svc.getLoadedRules.returns({ + then: sinon.stub().yields(injectedRule) + }); + + ctrl.push(); + + svc.loadRule.should.be.calledOnce(); + svc.loadRule.should.be.calledWith(stateParams.systemId, stateParams.jvmId, injectedRule); + ctrl.loadedRule.should.equal(injectedRule); + }); + }); + + describe('pull ()', () => { + it('should pull injected rule into editor', () => { + const loadedRule = 'loaded rule'; + svc.getLoadedRules.returns({ + then: sinon.stub().yields(loadedRule) + }); + + ctrl.pull(); + + svc.getLoadedRules.should.be.calledOnce(); + svc.getLoadedRules.should.be.calledWith(stateParams.jvmId); + + ctrl.loadedRule.should.equal(loadedRule); + ctrl.ruleText.should.equal(loadedRule); + }); + + it('should not clobber rule text if no remotely injected rules', () => { + svc.getLoadedRules.returns({ + then: sinon.stub().yields() + }); + + ctrl.ruleText = 'locally edited rule'; + ctrl.pull(); + + svc.getLoadedRules.should.be.calledOnce(); + svc.getLoadedRules.should.be.calledWith(stateParams.jvmId); + + should(ctrl.loadedRule).be.undefined(); + ctrl.ruleText.should.equal('locally edited rule'); + }); + }); + + describe('generateTemplate ()', () => { + it('should set rule text from translate service', () => { + translate.then.yields('rule template'); + ctrl.generateTemplate(); + ctrl.ruleText.should.equal('rule template'); + }); + }); + +}); diff -r 362ef36b1cef -r 0e10eacbeeb7 src/app/components/jvm-info/byteman/byteman.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/app/components/jvm-info/byteman/byteman.html Fri Sep 22 07:51:59 2017 -0400 @@ -0,0 +1,40 @@ +
+
+ +
+
+ + +
+
+ +
+ +
+ +