1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-09-19 16:58:48 +02:00

Add a server status page for notification server

Summary:
  - Add a /notification/status/ page which shows server status.
  - Remove various test controllers and routes.
  - Make the "no notifications" message look better.
  - Move port/URI configuration to config file.

Test Plan: Started server, hit /notification/status/, saw server status.

Reviewers: allenjohnashton, ddfisher, keebuhm, jungejason

Reviewed By: jungejason

CC: aran

Maniphest Tasks: T944

Differential Revision: https://secure.phabricator.com/D2756
This commit is contained in:
epriestley 2012-06-17 11:35:18 -07:00
parent cdd3683ed7
commit 513abf00cf
11 changed files with 169 additions and 198 deletions

View file

@ -186,9 +186,20 @@ return array(
// extend AphrontMySQLDatabaseConnectionBase.
'mysql.implementation' => 'AphrontMySQLDatabaseConnection',
// -- Notifications ----//
// -- Notifications --------------------------------------------------------- //
'notification.enabled' => false,
// Client port for the realtime server to listen on, and for realtime clients
// to connect to. Use "localhost" if you are running the notification server
// on the same host as the web server.
'notification.client-uri' => 'http://localhost:22280/',
// URI and port for the notification root server.
'notification.server-uri' => 'http://localhost:22281/',
// -- Email ----------------------------------------------------------------- //
// Some Phabricator tools send email notifications, e.g. when Differential

View file

@ -2311,7 +2311,7 @@ celerity_register_resource_map(array(
),
'phabricator-standard-page-view' =>
array(
'uri' => '/res/fe757493/rsrc/css/application/base/standard-page-view.css',
'uri' => '/res/4e1958d0/rsrc/css/application/base/standard-page-view.css',
'type' => 'css',
'requires' =>
array(
@ -2566,7 +2566,7 @@ celerity_register_resource_map(array(
), array(
'packages' =>
array(
'59b02d20' =>
'0ba8269e' =>
array(
'name' => 'core.pkg.css',
'symbols' =>
@ -2595,7 +2595,7 @@ celerity_register_resource_map(array(
21 => 'phabricator-flag-css',
22 => 'aphront-error-view-css',
),
'uri' => '/res/pkg/59b02d20/core.pkg.css',
'uri' => '/res/pkg/0ba8269e/core.pkg.css',
'type' => 'css',
),
'0c96375e' =>
@ -2762,20 +2762,20 @@ celerity_register_resource_map(array(
'reverse' =>
array(
'aphront-attached-file-view-css' => '7839ae2d',
'aphront-crumbs-view-css' => '59b02d20',
'aphront-dialog-view-css' => '59b02d20',
'aphront-error-view-css' => '59b02d20',
'aphront-form-view-css' => '59b02d20',
'aphront-crumbs-view-css' => '0ba8269e',
'aphront-dialog-view-css' => '0ba8269e',
'aphront-error-view-css' => '0ba8269e',
'aphront-form-view-css' => '0ba8269e',
'aphront-headsup-action-list-view-css' => '32f461a4',
'aphront-headsup-view-css' => '59b02d20',
'aphront-list-filter-view-css' => '59b02d20',
'aphront-pager-view-css' => '59b02d20',
'aphront-panel-view-css' => '59b02d20',
'aphront-side-nav-view-css' => '59b02d20',
'aphront-table-view-css' => '59b02d20',
'aphront-tokenizer-control-css' => '59b02d20',
'aphront-tooltip-css' => '59b02d20',
'aphront-typeahead-control-css' => '59b02d20',
'aphront-headsup-view-css' => '0ba8269e',
'aphront-list-filter-view-css' => '0ba8269e',
'aphront-pager-view-css' => '0ba8269e',
'aphront-panel-view-css' => '0ba8269e',
'aphront-side-nav-view-css' => '0ba8269e',
'aphront-table-view-css' => '0ba8269e',
'aphront-tokenizer-control-css' => '0ba8269e',
'aphront-tooltip-css' => '0ba8269e',
'aphront-typeahead-control-css' => '0ba8269e',
'differential-changeset-view-css' => '32f461a4',
'differential-core-view-css' => '32f461a4',
'differential-inline-comment-editor' => '1662d764',
@ -2841,15 +2841,15 @@ celerity_register_resource_map(array(
'javelin-workflow' => '0c96375e',
'maniphest-task-summary-css' => '7839ae2d',
'maniphest-transaction-detail-css' => '7839ae2d',
'phabricator-app-buttons-css' => '59b02d20',
'phabricator-app-buttons-css' => '0ba8269e',
'phabricator-content-source-view-css' => '32f461a4',
'phabricator-core-buttons-css' => '59b02d20',
'phabricator-core-css' => '59b02d20',
'phabricator-directory-css' => '59b02d20',
'phabricator-core-buttons-css' => '0ba8269e',
'phabricator-core-css' => '0ba8269e',
'phabricator-directory-css' => '0ba8269e',
'phabricator-drag-and-drop-file-upload' => '1662d764',
'phabricator-dropdown-menu' => '0c96375e',
'phabricator-flag-css' => '59b02d20',
'phabricator-jump-nav' => '59b02d20',
'phabricator-flag-css' => '0ba8269e',
'phabricator-jump-nav' => '0ba8269e',
'phabricator-keyboard-shortcut' => '0c96375e',
'phabricator-keyboard-shortcut-manager' => '0c96375e',
'phabricator-menu-item' => '0c96375e',
@ -2857,11 +2857,11 @@ celerity_register_resource_map(array(
'phabricator-paste-file-upload' => '0c96375e',
'phabricator-prefab' => '0c96375e',
'phabricator-project-tag-css' => '7839ae2d',
'phabricator-remarkup-css' => '59b02d20',
'phabricator-remarkup-css' => '0ba8269e',
'phabricator-shaped-request' => '1662d764',
'phabricator-standard-page-view' => '59b02d20',
'phabricator-standard-page-view' => '0ba8269e',
'phabricator-tooltip' => '0c96375e',
'phabricator-transaction-view-css' => '59b02d20',
'syntax-highlighting-css' => '59b02d20',
'phabricator-transaction-view-css' => '0ba8269e',
'syntax-highlighting-css' => '0ba8269e',
),
));

View file

@ -534,7 +534,6 @@ phutil_register_library_map(array(
'PackageModifyMail' => 'applications/owners/mail/PackageModifyMail.php',
'Phabricator404Controller' => 'applications/base/controller/Phabricator404Controller.php',
'PhabricatorAccessLog' => 'infrastructure/PhabricatorAccessLog.php',
'PhabricatorAphlictTestPageController' => 'applications/notifications/controller/PhabricatorAphlictTestPageController.php',
'PhabricatorAuditActionConstants' => 'applications/audit/constants/PhabricatorAuditActionConstants.php',
'PhabricatorAuditAddCommentController' => 'applications/audit/controller/PhabricatorAuditAddCommentController.php',
'PhabricatorAuditComment' => 'applications/audit/storage/PhabricatorAuditComment.php',
@ -747,10 +746,9 @@ phutil_register_library_map(array(
'PhabricatorNotificationIndividualController' => 'applications/notification/controller/PhabricatorNotificationIndividualController.php',
'PhabricatorNotificationPanelController' => 'applications/notification/controller/PhabricatorNotificationPanelController.php',
'PhabricatorNotificationQuery' => 'applications/notification/PhabricatorNotificationQuery.php',
'PhabricatorNotificationStatusController' => 'applications/notification/controller/PhabricatorNotificationStatusController.php',
'PhabricatorNotificationStoryView' => 'applications/notification/view/PhabricatorNotificationStoryView.php',
'PhabricatorNotificationTestController' => 'applications/notification/controller/PhabricatorNotificationTestController.php',
'PhabricatorNotificationView' => 'applications/notification/view/PhabricatorNotificationView.php',
'PhabricatorNotificationsController' => 'applications/notifications/controller/PhabricatorNotificationsController.php',
'PhabricatorOAuthClientAuthorization' => 'applications/oauthserver/storage/PhabricatorOAuthClientAuthorization.php',
'PhabricatorOAuthClientAuthorizationBaseController' => 'applications/oauthserver/controller/clientauthorization/PhabricatorOAuthClientAuthorizationBaseController.php',
'PhabricatorOAuthClientAuthorizationDeleteController' => 'applications/oauthserver/controller/clientauthorization/PhabricatorOAuthClientAuthorizationDeleteController.php',
@ -1538,7 +1536,6 @@ phutil_register_library_map(array(
'PackageDeleteMail' => 'PackageMail',
'PackageModifyMail' => 'PackageMail',
'Phabricator404Controller' => 'PhabricatorController',
'PhabricatorAphlictTestPageController' => 'PhabricatorNotificationsController',
'PhabricatorAuditAddCommentController' => 'PhabricatorAuditController',
'PhabricatorAuditComment' => 'PhabricatorAuditDAO',
'PhabricatorAuditCommitListView' => 'AphrontView',
@ -1719,10 +1716,9 @@ phutil_register_library_map(array(
'PhabricatorNotificationController' => 'PhabricatorController',
'PhabricatorNotificationIndividualController' => 'PhabricatorNotificationController',
'PhabricatorNotificationPanelController' => 'PhabricatorNotificationController',
'PhabricatorNotificationStatusController' => 'PhabricatorNotificationController',
'PhabricatorNotificationStoryView' => 'PhabricatorNotificationView',
'PhabricatorNotificationTestController' => 'PhabricatorNotificationController',
'PhabricatorNotificationView' => 'AphrontView',
'PhabricatorNotificationsController' => 'PhabricatorController',
'PhabricatorOAuthClientAuthorization' => 'PhabricatorOAuthServerDAO',
'PhabricatorOAuthClientAuthorizationBaseController' => 'PhabricatorOAuthServerController',
'PhabricatorOAuthClientAuthorizationDeleteController' => 'PhabricatorOAuthClientAuthorizationBaseController',

View file

@ -426,10 +426,12 @@ class AphrontDefaultApplicationConfiguration
'PhabricatorChatLogChannelLogController',
),
'/notification/test/' => 'PhabricatorNotificationTestController',
'/notification/panel/' => 'PhabricatorNotificationPanelController',
'/notification/individual/'
=> 'PhabricatorNotificationIndividualController',
'/notification/' => array(
'panel/' => 'PhabricatorNotificationPanelController',
'individual/' => 'PhabricatorNotificationIndividualController',
'status/' => 'PhabricatorNotificationStatusController',
),
'/flag/' => array(
'' => 'PhabricatorFlagListController',
'view/(?P<view>[^/]+)/' => 'PhabricatorFlagListController',

View file

@ -30,21 +30,27 @@ final class PhabricatorNotificationPanelController
$stories = $query->execute();
$builder = new PhabricatorNotificationBuilder($stories);
$notifications_view = $builder->buildView();
$num_unconsumed = 0;
foreach ($stories as $story) {
if (!$story->getHasViewed()) {
$num_unconsumed++;
if ($stories) {
$builder = new PhabricatorNotificationBuilder($stories);
$notifications_view = $builder->buildView();
foreach ($stories as $story) {
if (!$story->getHasViewed()) {
$num_unconsumed++;
}
}
$content = $notifications_view->render();
} else {
$content =
'<div class="phabricator-notification no-notifications">'.
'You have no notifications.'.
'</div>';
}
$json = array(
"content" => $stories ?
$notifications_view->render() :
"<b>You currently have no notifications<b>",
"number" => $num_unconsumed,
'content' => $content,
'number' => $num_unconsumed,
);
return id(new AphrontAjaxResponse())->setContent($json);

View file

@ -0,0 +1,94 @@
<?php
/*
* Copyright 2012 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
final class PhabricatorNotificationStatusController
extends PhabricatorNotificationController {
public function processRequest() {
$uri = PhabricatorEnv::getEnvConfig('notification.server-uri');
$uri = new PhutilURI($uri);
$uri->setPath('/status/');
$future = id(new HTTPSFuture($uri))
->setTimeout(3);
try {
list($body) = $future->resolvex();
$body = json_decode($body, true);
if (!is_array($body)) {
throw new Exception("Expected JSON response from server!");
}
$status = $this->renderServerStatus($body);
} catch (Exception $ex) {
$status = new AphrontErrorView();
$status->setTitle("Notification Server Issue");
$status->appendChild(
'Unable to determine server status. This probably means the server '.
'is not in great shape. The specific issue encountered was:'.
'<br />'.
'<br />'.
'<strong>'.phutil_escape_html(get_class($ex)).'</strong> '.
nl2br(phutil_escape_html($ex->getMessage())));
}
return $this->buildStandardPageResponse(
$status,
array(
'title' => 'Aphlict Server Status',
));
}
private function renderServerStatus(array $status) {
$rows = array();
foreach ($status as $key => $value) {
$label = phutil_escape_html($key);
switch ($key) {
case 'uptime':
$value /= 1000;
$value = phabricator_format_relative_time_detailed($value);
break;
case 'log':
$value = phutil_escape_html($value);
break;
default:
$value = phutil_escape_html(number_format($value));
break;
}
$rows[] = array($label, $value);
}
$table = new AphrontTableView($rows);
$table->setColumnClasses(
array(
'header',
'wide',
));
$panel = new AphrontPanelView();
$panel->setHeader('Server Status');
$panel->appendChild($table);
return $panel;
}
}

View file

@ -1,53 +0,0 @@
<?php
/*
* Copyright 2012 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
final class PhabricatorNotificationTestController
extends PhabricatorNotificationController {
public function processRequest() {
$request = $this->getRequest();
$user = $request->getUser();
$query = new PhabricatorNotificationQuery();
$query->setUserPHID($user->getPHID());
$stories = $query->execute();
$builder = new PhabricatorNotificationBuilder($stories);
$notifications_view = $builder->buildView();
$num_unconsumed = 0;
foreach ($stories as $story) {
if (!$story->getHasViewed()) {
$num_unconsumed++;
}
}
$json = array(
$notifications_view->render()
);
return $this->buildStandardPageResponse(
$json,
array('title' => 'Notification Test Page'));
}
}

View file

@ -1,56 +0,0 @@
<?php
/*
* Copyright 2012 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
final class PhabricatorAphlictTestPageController
extends PhabricatorNotificationsController {
public function processRequest() {
$instructions = '<h1>Check Your Javascript Console!</h1>';
$object_id = 'aphlictswfobject';
$content = phutil_render_tag(
'object',
array(
'classid' => 'clsid:d27cdb6e-ae6d-11cf-96b8-444553540000',
),
'<param name="movie" value="/rsrc/swf/aphlict.swf" />'.
'<param name="allowScriptAccess" value="always" />'.
'<embed src="/rsrc/swf/aphlict.swf" id="'.$object_id.'"></embed>');
Javelin::initBehavior(
'aphlict-listen',
array(
'id' => $object_id,
'server' => '127.0.0.1',
'port' => 22280,
));
return $this->buildStandardPageResponse(
array(
$instructions,
$content,
),
array(
'title' => 'Aphlict Test Page',
));
}
}

View file

@ -1,37 +0,0 @@
<?php
/*
* Copyright 2012 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
abstract class PhabricatorNotificationsController
extends PhabricatorController {
public function buildStandardPageResponse($view, array $data) {
$page = $this->buildStandardPageView();
$page->setApplicationName('Notifications');
$page->setBaseURI('/notifications/');
$page->setTitle(idx($data, 'title'));
$page->setGlyph('!');
$page->appendChild($view);
$response = new AphrontWebpageResponse();
return $response->setContent($page->render());
}
}

View file

@ -391,16 +391,20 @@ final class PhabricatorStandardPageView extends AphrontPageView {
$aphlict_object_id = 'aphlictswfobject';
$server_uri = new PhutilURI(PhabricatorEnv::getURI(''));
$server_domain = $server_uri->getDomain();
$client_uri = PhabricatorEnv::getEnvConfig('notification.client-uri');
$client_uri = new PhutilURI($client_uri);
if ($client_uri->getDomain() == 'localhost') {
$this_host = new PhutilURI($this->getRequest()->getHost());
$client_uri->setDomain($this_host->getDomain());
}
Javelin::initBehavior(
'aphlict-listen',
array(
'id' => $aphlict_object_id,
'server' => $server_domain,
'port' => 22280,
'pageObjects' => $this->pageObjects,
'server' => $client_uri->getDomain(),
'port' => $client_uri->getPort(),
'pageObjects' => $this->pageObjects,
));
Javelin::initBehavior('aphlict-dropdown', array());

View file

@ -303,6 +303,10 @@ a.handle-disabled {
padding: 6px 6px;
}
.no-notifications {
color: #999999;
}
.phabricator-notification-unread {
background: #aacfef;
}