diff --git a/appinfo/routes.php b/appinfo/routes.php
index 91d2eec4dd3..49651fe46a7 100644
--- a/appinfo/routes.php
+++ b/appinfo/routes.php
@@ -395,6 +395,15 @@
'token' => '^[a-z0-9]{4,30}$',
],
],
+ [
+ 'name' => 'Matterbridge#getBridgeProcessState',
+ 'url' => '/api/{apiVersion}/bridge/{token}/process',
+ 'verb' => 'GET',
+ 'requirements' => [
+ 'apiVersion' => 'v1',
+ 'token' => '^[a-z0-9]{4,30}$',
+ ],
+ ],
[
'name' => 'Matterbridge#editBridgeOfRoom',
'url' => '/api/{apiVersion}/bridge/{token}',
diff --git a/lib/Controller/MatterbridgeController.php b/lib/Controller/MatterbridgeController.php
index 70489752c0e..cea3f4f2cdd 100644
--- a/lib/Controller/MatterbridgeController.php
+++ b/lib/Controller/MatterbridgeController.php
@@ -60,11 +60,27 @@ public function __construct(string $appName,
* @return DataResponse
*/
public function getBridgeOfRoom(): DataResponse {
- $this->bridgeManager->checkBridge($this->room);
+ $pid = $this->bridgeManager->checkBridge($this->room);
+ $logContent = $this->bridgeManager->getBridgeLog($this->room);
$bridge = $this->bridgeManager->getBridgeOfRoom($this->room);
+ $bridge['running'] = ($pid !== 0);
+ $bridge['log'] = $logContent;
return new DataResponse($bridge);
}
+ /**
+ * Get bridge process information
+ *
+ * @NoAdminRequired
+ * @RequireLoggedInModeratorParticipant
+ *
+ * @return DataResponse
+ */
+ public function getBridgeProcessState(): DataResponse {
+ $result = $this->bridgeManager->getBridgeProcessState($this->room);
+ return new DataResponse($result);
+ }
+
/**
* Edit bridge information of one room
*
@@ -77,11 +93,11 @@ public function getBridgeOfRoom(): DataResponse {
*/
public function editBridgeOfRoom(bool $enabled, array $parts = []): DataResponse {
try {
- $success = $this->bridgeManager->editBridgeOfRoom($this->room, $enabled, $parts);
+ $state = $this->bridgeManager->editBridgeOfRoom($this->room, $enabled, $parts);
} catch (ImpossibleToKillException $e) {
return new DataResponse(['error' => $e->getMessage()], Http::STATUS_NOT_ACCEPTABLE);
}
- return new DataResponse($success);
+ return new DataResponse($state);
}
/**
diff --git a/lib/MatterbridgeManager.php b/lib/MatterbridgeManager.php
index bab70dbdf33..5714799eeb5 100644
--- a/lib/MatterbridgeManager.php
+++ b/lib/MatterbridgeManager.php
@@ -92,15 +92,45 @@ public function getBridgeOfRoom(Room $room): array {
return $this->getBridgeFromDb($room);
}
+ /**
+ * Get bridge process information for a specific room
+ *
+ * @param Room $room the room
+ * @return array process state and log
+ */
+ public function getBridgeProcessState(Room $room): array {
+ $bridge = $this->getBridgeFromDb($room);
+
+ $logContent = $this->getBridgeLog($room);
+
+ $pid = $this->checkBridgeProcess($room, $bridge, false);
+ return [
+ 'running' => ($pid !== 0),
+ 'log' => $logContent
+ ];
+ }
+
+ /**
+ * Get bridge log file content
+ *
+ * @param Room $room the room
+ * @return string log file content
+ */
+ public function getBridgeLog(Room $room): string {
+ $outputPath = sprintf('/tmp/bridge-%s.log', $room->getToken());
+ $logContent = file_get_contents($outputPath);
+ return $logContent !== false ? $logContent : '';
+ }
+
/**
* Edit bridge information for a room
*
* @param Room $room the room
* @param bool $enabled desired state of the bridge
* @param array $parts parts of the bridge (what it connects to)
- * @return bool success
+ * @return array bridge state
*/
- public function editBridgeOfRoom(Room $room, bool $enabled, array $parts = []): bool {
+ public function editBridgeOfRoom(Room $room, bool $enabled, array $parts = []): array {
$currentBridge = $this->getBridgeOfRoom($room);
$newBridge = [
'enabled' => $enabled,
@@ -118,7 +148,11 @@ public function editBridgeOfRoom(Room $room, bool $enabled, array $parts = []):
// save config
$this->saveBridgeToDb($room, $newBridge);
- return true;
+ $logContent = $this->getBridgeLog($room);
+ return [
+ 'running' => ($pid !== 0),
+ 'log' => $logContent
+ ];
}
/**
@@ -153,8 +187,9 @@ public function checkAllBridges(): void {
/**
* For one room, check mattermost process respects desired state
* @param Room $room the room
+ * @return int the bridge process ID
*/
- public function checkBridge(Room $room): void {
+ public function checkBridge(Room $room): int {
$bridge = $this->getBridgeOfRoom($room);
$pid = $this->checkBridgeProcess($room, $bridge);
if ($pid !== $bridge['pid']) {
@@ -162,6 +197,7 @@ public function checkBridge(Room $room): void {
$bridge['pid'] = $pid;
$this->saveBridgeToDb($room, $bridge);
}
+ return $pid;
}
private function getDataFolder(): ISimpleFolder {
@@ -437,43 +473,48 @@ private function cleanUrl(string $url): string {
*
* @param Room $room the room
* @param array $bridge bridge information
+ * @param $relaunch whether to launch the process if it's down but bridge is enabled
* @return int the corresponding matterbridge process ID, 0 if none
*/
- private function checkBridgeProcess(Room $room, array $bridge): int {
+ private function checkBridgeProcess(Room $room, array $bridge, bool $relaunch = true): int {
$pid = 0;
if (isset($bridge['pid']) && intval($bridge['pid']) !== 0) {
// config : there is a PID stored
- $pid = intval($bridge['pid']);
- $isRunning = $this->isRunning($pid);
+ $isRunning = $this->isRunning($bridge['pid']);
// if bridge running and enabled is false : kill it
if ($isRunning) {
if ($bridge['enabled']) {
$this->logger->info('Process running AND bridge enabled in config : doing nothing');
+ $pid = $bridge['pid'];
} else {
- $this->logger->info('Process running AND bridge disabled in config : KILL ' . $pid);
- $killed = $this->killPid($pid);
+ $this->logger->info('Process running AND bridge disabled in config : KILL ' . $bridge['pid']);
+ $killed = $this->killPid($bridge['pid']);
if ($killed) {
$pid = 0;
} else {
- $this->logger->info('Impossible to kill ' . $pid);
- throw new ImpossibleToKillException('Impossible to kill bridge process [' . $pid . ']');
+ $this->logger->info('Impossible to kill ' . $bridge['pid']);
+ throw new ImpossibleToKillException('Impossible to kill bridge process [' . $bridge['pid'] . ']');
}
}
} else {
// no process found
if ($bridge['enabled']) {
- $this->logger->info('Process not found AND bridge enabled in config : relaunching');
- $pid = $this->launchMatterbridge($room);
+ if ($relaunch) {
+ $this->logger->info('Process not found AND bridge enabled in config : relaunching');
+ $pid = $this->launchMatterbridge($room);
+ }
} else {
$this->logger->info('Process not found AND bridge disabled in config : doing nothing');
}
}
} elseif ($bridge['enabled']) {
- // config : no PID stored
- // config : enabled => launch it
- $pid = $this->launchMatterbridge($room);
- $this->logger->info('Launch process, PID is '.$pid);
+ if ($relaunch) {
+ // config : no PID stored
+ // config : enabled => launch it
+ $pid = $this->launchMatterbridge($room);
+ $this->logger->info('Launch process, PID is '.$pid);
+ }
} else {
$this->logger->info('No PID defined in config AND bridge disabled in config : doing nothing');
}
diff --git a/src/components/RightSidebar/Matterbridge/MatterbridgeSettings.vue b/src/components/RightSidebar/Matterbridge/MatterbridgeSettings.vue
index 6c699736239..c882985d4da 100644
--- a/src/components/RightSidebar/Matterbridge/MatterbridgeSettings.vue
+++ b/src/components/RightSidebar/Matterbridge/MatterbridgeSettings.vue
@@ -40,7 +40,17 @@
:checked="enabled"
@update:checked="onEnabled">
{{ t('spreed', 'Enabled') }}
+ ({{ processStateText }})
+
+
+
+
+
+
this.getBridgeProcessState(token), 60000)
+ },
clickAddPart() {
const typeKey = this.selectedType.type
const type = this.types[typeKey]
@@ -460,17 +490,17 @@ export default {
this.onSave()
},
onSave() {
- console.debug(this.parts)
this.editBridge(this.token, this.enabled, this.parts)
},
async getBridge(token) {
this.loading = true
try {
const result = await getBridge(token)
- console.debug(result)
const bridge = result.data.ocs.data
this.enabled = bridge.enabled
this.parts = bridge.parts
+ this.processLog = bridge.log
+ this.processRunning = bridge.running
} catch (exception) {
console.debug(exception)
}
@@ -479,13 +509,32 @@ export default {
async editBridge() {
this.loading = true
try {
- await editBridge(this.token, this.enabled, this.parts)
+ const result = await editBridge(this.token, this.enabled, this.parts)
+ this.processLog = result.data.ocs.data.log
+ this.processRunning = result.data.ocs.data.running
showSuccess(t('spreed', 'Bridge saved'))
} catch (exception) {
console.debug(exception)
}
this.loading = false
},
+ async getBridgeProcessState(token) {
+ try {
+ const result = await getBridgeProcessState(token)
+ this.processLog = result.data.ocs.data.log
+ this.processRunning = result.data.ocs.data.running
+ console.debug(result.data.ocs.data.log)
+ } catch (exception) {
+ console.debug(exception)
+ }
+ },
+ showLogContent() {
+ this.getBridgeProcessState(this.token)
+ this.logModal = true
+ },
+ closeLogModal() {
+ this.logModal = false
+ },
},
}
@@ -514,6 +563,7 @@ export default {
}
.basic-settings {
+ button,
.multiselect {
width: calc(100% - 40px);
margin-left: 40px;
@@ -523,4 +573,9 @@ export default {
ul {
margin-bottom: 64px;
}
+
+.log-content {
+ width: 600px;
+ height: 400px;
+}
diff --git a/src/services/matterbridgeService.js b/src/services/matterbridgeService.js
index 4811ba83481..9b4dd125dbf 100644
--- a/src/services/matterbridgeService.js
+++ b/src/services/matterbridgeService.js
@@ -50,6 +50,15 @@ const getBridge = async function(token) {
return response
}
+/**
+ * Get the bridge binary state for a room
+ * @param {token} token the conversation token.
+ */
+const getBridgeProcessState = async function(token) {
+ const response = await axios.get(generateOcsUrl('apps/spreed/api/v1', 2) + `bridge/${token}/process`)
+ return response
+}
+
/**
* Ask to stop all bridges (and kill all related processes)
*/
@@ -71,6 +80,7 @@ const getMatterbridgeVersion = async function() {
export {
editBridge,
getBridge,
+ getBridgeProcessState,
stopAllBridges,
getMatterbridgeVersion,
enableMatterbridgeApp,