Skip to content

Commit

Permalink
Merge pull request #9902 from RocketChat/apps-multi-instance-enablement
Browse files Browse the repository at this point in the history
[OTHER] Fix Apps not working on multi-instance deployments
  • Loading branch information
rodrigok authored Feb 26, 2018
2 parents 273cdbc + 2822ad3 commit b0d9e15
Show file tree
Hide file tree
Showing 16 changed files with 306 additions and 66 deletions.
4 changes: 0 additions & 4 deletions packages/rocketchat-apps/client/admin/appInstall.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ Template.appInstall.onCreated(function() {

// Allow passing in a url as a query param to show installation of
if (FlowRouter.getQueryParam('url')) {
console.log('Url:', FlowRouter.getQueryParam('url'));
instance.appUrl.set(FlowRouter.getQueryParam('url'));
FlowRouter.setQueryParams({ url: null });
}
Expand All @@ -36,11 +35,8 @@ Template.appInstall.events({

// Handle url installations
if (url) {
console.log('Installing via url.');
t.isInstalling.set(true);
RocketChat.API.post('apps', { url }).then((result) => {
console.log('result', result);

FlowRouter.go(`/admin/apps/${ result.app.id }`);
}).catch((err) => {
console.warn('err', err);
Expand Down
51 changes: 43 additions & 8 deletions packages/rocketchat-apps/client/admin/appManage.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import _ from 'underscore';
import s from 'underscore.string';

import { AppEvents } from '../communication';

Template.appManage.onCreated(function() {
const instance = this;
this.id = new ReactiveVar(FlowRouter.getParam('appId'));
Expand All @@ -13,24 +15,58 @@ Template.appManage.onCreated(function() {

const id = this.id.get();

function _morphSettings(settings) {
Object.keys(settings).forEach((k) => {
settings[k].i18nPlaceholder = settings[k].i18nPlaceholder || ' ';
settings[k].value = settings[k].value || settings[k].packageValue;
settings[k].oldValue = settings[k].value;
});

instance.settings.set(settings);
}

Promise.all([
RocketChat.API.get(`apps/${ id }`),
RocketChat.API.get(`apps/${ id }/settings`)
]).then((results) => {
instance.app.set(results[0].app);
_morphSettings(results[1].settings);

Object.keys(results[1].settings).forEach((k) => {
results[1].settings[k].i18nPlaceholder = results[1].settings[k].i18nPlaceholder || ' ';
results[1].settings[k].value = results[1].settings[k].value || results[1].settings[k].packageValue;
results[1].settings[k].oldValue = results[1].settings[k].value;
});

instance.settings.set(results[1].settings);
this.ready.set(true);
}).catch((e) => {
instance.hasError.set(true);
instance.theError.set(e.message);
});

instance.onStatusChanged = function _onStatusChanged({ appId, status }) {
if (appId !== id) {
return;
}

const app = instance.app.get();
app.status = status;
instance.app.set(app);
};

instance.onSettingUpdated = function _onSettingUpdated({ appId }) {
if (appId !== id) {
return;
}

RocketChat.API.get(`apps/${ id }/settings`).then((result) => {
_morphSettings(result.settings);
});
};

window.Apps.getWsListener().registerListener(AppEvents.APP_STATUS_CHANGE, instance.onStatusChanged);
window.Apps.getWsListener().registerListener(AppEvents.APP_SETTING_UPDATED, instance.onSettingUpdated);
});

Template.apps.onDestroyed(function() {
const instance = this;

window.Apps.getWsListener().unregisterListener(AppEvents.APP_STATUS_CHANGE, instance.onStatusChanged);
window.Apps.getWsListener().unregisterListener(AppEvents.APP_SETTING_UPDATED, instance.onSettingUpdated);
});

Template.appManage.helpers({
Expand Down Expand Up @@ -173,7 +209,6 @@ Template.appManage.events({

'change .input-monitor, keyup .input-monitor': _.throttle(function(e, t) {
let value = s.trim($(e.target).val());
console.log(value);
switch (this.type) {
case 'int':
value = parseInt(value);
Expand Down
35 changes: 35 additions & 0 deletions packages/rocketchat-apps/client/admin/apps.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { AppEvents } from '../communication';

Template.apps.onCreated(function() {
const instance = this;
this.ready = new ReactiveVar(false);
Expand All @@ -7,6 +9,39 @@ Template.apps.onCreated(function() {
instance.apps.set(result.apps);
instance.ready.set(true);
});

instance.onAppAdded = function _appOnAppAdded(appId) {
RocketChat.API.get(`apps/${ appId }`).then((result) => {
const apps = instance.apps.get();
apps.push(result.app);
instance.apps.set(apps);
});
};

instance.onAppRemoved = function _appOnAppRemoved(appId) {
const apps = instance.apps.get();

let index = -1;
apps.find((item, i) => {
if (item.id === appId) {
index = i;
return true;
}
});

apps.splice(index, 1);
instance.apps.set(apps);
};

window.Apps.getWsListener().registerListener(AppEvents.APP_ADDED, instance.onAppAdded);
window.Apps.getWsListener().registerListener(AppEvents.APP_REMOVED, instance.onAppAdded);
});

Template.apps.onDestroyed(function() {
const instance = this;

window.Apps.getWsListener().unregisterListener(AppEvents.APP_ADDED, instance.onAppAdded);
window.Apps.getWsListener().unregisterListener(AppEvents.APP_REMOVED, instance.onAppAdded);
});

Template.apps.helpers({
Expand Down
4 changes: 2 additions & 2 deletions packages/rocketchat-apps/client/communication/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
import { AppWebsocketReceiver } from './websockets';
import { AppWebsocketReceiver, AppEvents } from './websockets';

export { AppWebsocketReceiver };
export { AppWebsocketReceiver, AppEvents };
58 changes: 53 additions & 5 deletions packages/rocketchat-apps/client/communication/websockets.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,67 @@
export const AppEvents = Object.freeze({
APP_ADDED: 'app/added',
APP_REMOVED: 'app/removed',
APP_UPDATED: 'app/updated',
APP_STATUS_CHANGE: 'app/statusUpdate',
APP_SETTING_UPDATED: 'app/settingUpdated',
COMMAND_ADDED: 'command/added',
COMMAND_DISABLED: 'command/disabled',
COMMAND_UPDATED: 'command/updated',
COMMAND_REMOVED: 'command/removed'
});

export class AppWebsocketReceiver {
constructor(orch) {
this.orch = orch;
this.streamer = new Meteor.Streamer('apps');

this.streamer.on('app/added', this.onAppAdded.bind(this));
this.streamer.on('command/added', this.onCommandAdded.bind(this));
this.streamer.on('command/disabled', this.onCommandDisabled.bind(this));
this.streamer.on('command/updated', this.onCommandUpdated.bind(this));
this.streamer.on('command/removed', this.onCommandDisabled.bind(this));
this.streamer.on(AppEvents.APP_ADDED, this.onAppAdded.bind(this));
this.streamer.on(AppEvents.APP_REMOVED, this.onAppRemoved.bind(this));
this.streamer.on(AppEvents.APP_UPDATED, this.onAppUpdated.bind(this));
this.streamer.on(AppEvents.APP_STATUS_CHANGE, this.onAppStatusUpdated.bind(this));
this.streamer.on(AppEvents.APP_SETTING_UPDATED, this.onAppSettingUpdated.bind(this));
this.streamer.on(AppEvents.COMMAND_ADDED, this.onCommandAdded.bind(this));
this.streamer.on(AppEvents.COMMAND_DISABLED, this.onCommandDisabled.bind(this));
this.streamer.on(AppEvents.COMMAND_UPDATED, this.onCommandUpdated.bind(this));
this.streamer.on(AppEvents.COMMAND_REMOVED, this.onCommandDisabled.bind(this));

this.listeners = {};

Object.keys(AppEvents).forEach((v) => {
this.listeners[AppEvents[v]] = [];
});
}

registerListener(event, listener) {
this.listeners[event].push(listener);
}

unregisterListener(event, listener) {
this.listeners[event].splice(this.listeners[event].indexOf(listener), 1);
}

onAppAdded(appId) {
RocketChat.API.get(`apps/${ appId }/languages`).then((result) => {
this.orch.parseAndLoadLanguages(result.languages);
});

this.listeners[AppEvents.APP_ADDED].forEach((listener) => listener(appId));
}

onAppRemoved(appId) {
this.listeners[AppEvents.APP_REMOVED].forEach((listener) => listener(appId));
}

onAppUpdated(appId) {
this.listeners[AppEvents.APP_UPDATED].forEach((listener) => listener(appId));
}

onAppStatusUpdated({ appId, status }) {
this.listeners[AppEvents.APP_STATUS_CHANGE].forEach((listener) => listener({ appId, status }));
}

onAppSettingUpdated({ appId }) {
this.listeners[AppEvents.APP_SETTING_UPDATED].forEach((listener) => listener({ appId }));
}

onCommandAdded(command) {
Expand Down
2 changes: 1 addition & 1 deletion packages/rocketchat-apps/package.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,6 @@ Package.onUse(function(api) {

Npm.depends({
'busboy': '0.2.13',
'@rocket.chat/apps-engine': '0.3.5',
'@rocket.chat/apps-engine': '0.4.0',
'@rocket.chat/apps-ts-definition': '0.7.6'
});
30 changes: 8 additions & 22 deletions packages/rocketchat-apps/server/bridges/activation.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,33 +3,19 @@ export class AppActivationBridge {
this.orch = orch;
}

appEnabled(app) {
console.log(`The App ${ app.getName() } (${ app.getID() }) has been enabled.`);
appAdded(app) {
this.orch.getNotifier().appAdded(app.getID());
}

appDisabled(app) {
console.log(`The App ${ app.getName() } (${ app.getID() }) has been disabled.`);
}

appLoaded(app, enabled) {
console.log(`The App ${ app.getName() } (${ app.getID() }) has been loaded and enabled? ${ enabled }`);

if (enabled) {
this.orch.getNotifier().appAdded(app.getID());
}
}

appUpdated(app, enabled) {
console.log(`The App ${ app.getName() } (${ app.getID() }) has been updated and enabled? ${ enabled }`);

if (enabled) {
this.orch.getNotifier().appUpdated(app.getID());
}
appUpdated(app) {
this.orch.getNotifier().appUpdated(app.getID());
}

appRemoved(app) {
console.log(`The App ${ app.getName() } (${ app.getID() }) has been removed.`);

this.orch.getNotifier().appRemoved(app.getID());
}

appStatusChanged(app, status) {
this.orch.getNotifier().appStatusUpdated(app.getID(), status);
}
}
6 changes: 6 additions & 0 deletions packages/rocketchat-apps/server/bridges/bridges.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { AppBridges } from '@rocket.chat/apps-engine/server/bridges';

import { AppActivationBridge } from './activation';
import { AppDetailChangesBridge } from './details';
import { AppCommandsBridge } from './commands';
import { AppEnvironmentalVariableBridge } from './environmental';
import { AppHttpBridge } from './http';
Expand All @@ -16,6 +17,7 @@ export class RealAppBridges extends AppBridges {

this._actBridge = new AppActivationBridge(orch);
this._cmdBridge = new AppCommandsBridge(orch);
this._detBridge = new AppDetailChangesBridge(orch);
this._envBridge = new AppEnvironmentalVariableBridge(orch);
this._httpBridge = new AppHttpBridge();
this._msgBridge = new AppMessageBridge(orch);
Expand Down Expand Up @@ -49,6 +51,10 @@ export class RealAppBridges extends AppBridges {
return this._actBridge;
}

getAppDetailChangesBridge() {
return this._detBridge;
}

getRoomBridge() {
return this._roomBridge;
}
Expand Down
13 changes: 13 additions & 0 deletions packages/rocketchat-apps/server/bridges/details.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
export class AppDetailChangesBridge {
constructor(orch) {
this.orch = orch;
}

onAppSettingsChange(appId, setting) {
try {
this.orch.getNotifier().appSettingsChange(appId, setting);
} catch (e) {
console.warn('failed to notify about the setting change.', appId);
}
}
}
6 changes: 4 additions & 2 deletions packages/rocketchat-apps/server/communication/index.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { AppMethods} from './methods';
import { AppsRestApi } from './rest';
import { AppWebsocketNotifier } from './websockets';
import { AppEvents, AppServerNotifier, AppServerListener } from './websockets';

export {
AppMethods,
AppsRestApi,
AppWebsocketNotifier
AppEvents,
AppServerNotifier,
AppServerListener
};
2 changes: 1 addition & 1 deletion packages/rocketchat-apps/server/communication/rest.js
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ export class AppsRestApi {
}
});

this.api.addRoute(':id/languages', { authRequired: true }, {
this.api.addRoute(':id/languages', { authRequired: false }, {
get() {
console.log(`Getting ${ this.urlParams.id }'s languages..`);
const prl = manager.getOneById(this.urlParams.id);
Expand Down
Loading

0 comments on commit b0d9e15

Please sign in to comment.