Differential D18166 Diff 43699 src/applications/notification/config/PhabricatorNotificationServersConfigType.php
Changeset View
Changeset View
Standalone View
Standalone View
src/applications/notification/config/PhabricatorNotificationServersConfigType.php
- This file was moved from src/applications/notification/config/PhabricatorNotificationServersConfigOptionType.php.
<?php | <?php | ||||
final class PhabricatorNotificationServersConfigOptionType | final class PhabricatorNotificationServersConfigType | ||||
extends PhabricatorConfigJSONOptionType { | extends PhabricatorJSONConfigType { | ||||
public function validateOption(PhabricatorConfigOption $option, $value) { | const TYPEKEY = 'cluster.notifications'; | ||||
if (!is_array($value)) { | |||||
throw new Exception( | public function validateStoredValue( | ||||
pht( | PhabricatorConfigOption $option, | ||||
'Notification server configuration is not valid: value must be a '. | $value) { | ||||
'list of servers')); | |||||
} | |||||
foreach ($value as $index => $spec) { | foreach ($value as $index => $spec) { | ||||
if (!is_array($spec)) { | if (!is_array($spec)) { | ||||
throw new Exception( | throw $this->newException( | ||||
pht( | pht( | ||||
'Notification server configuration is not valid: each entry in '. | 'Notification server configuration is not valid: each entry in '. | ||||
'the list must be a dictionary describing a service, but '. | 'the list must be a dictionary describing a service, but '. | ||||
'the value with index "%s" is not a dictionary.', | 'the value with index "%s" is not a dictionary.', | ||||
$index)); | $index)); | ||||
} | } | ||||
} | } | ||||
$has_admin = false; | $has_admin = false; | ||||
$has_client = false; | $has_client = false; | ||||
$map = array(); | $map = array(); | ||||
foreach ($value as $index => $spec) { | foreach ($value as $index => $spec) { | ||||
try { | try { | ||||
PhutilTypeSpec::checkMap( | PhutilTypeSpec::checkMap( | ||||
$spec, | $spec, | ||||
array( | array( | ||||
'type' => 'string', | 'type' => 'string', | ||||
'host' => 'string', | 'host' => 'string', | ||||
'port' => 'int', | 'port' => 'int', | ||||
'protocol' => 'string', | 'protocol' => 'string', | ||||
'path' => 'optional string', | 'path' => 'optional string', | ||||
'disabled' => 'optional bool', | 'disabled' => 'optional bool', | ||||
)); | )); | ||||
} catch (Exception $ex) { | } catch (Exception $ex) { | ||||
throw new Exception( | throw $this->newException( | ||||
pht( | pht( | ||||
'Notification server configuration has an invalid service '. | 'Notification server configuration has an invalid service '. | ||||
'specification (at index "%s"): %s.', | 'specification (at index "%s"): %s.', | ||||
$index, | $index, | ||||
$ex->getMessage())); | $ex->getMessage())); | ||||
} | } | ||||
$type = $spec['type']; | $type = $spec['type']; | ||||
Show All 9 Lines | foreach ($value as $index => $spec) { | ||||
} | } | ||||
break; | break; | ||||
case 'client': | case 'client': | ||||
if (!$disabled) { | if (!$disabled) { | ||||
$has_client = true; | $has_client = true; | ||||
} | } | ||||
break; | break; | ||||
default: | default: | ||||
throw new Exception( | throw $this->newException( | ||||
pht( | pht( | ||||
'Notification server configuration describes an invalid '. | 'Notification server configuration describes an invalid '. | ||||
'host ("%s", at index "%s") with an unrecognized type ("%s"). '. | 'host ("%s", at index "%s") with an unrecognized type ("%s"). '. | ||||
'Valid types are "%s" or "%s".', | 'Valid types are "%s" or "%s".', | ||||
$host, | $host, | ||||
$index, | $index, | ||||
$type, | $type, | ||||
'admin', | 'admin', | ||||
'client')); | 'client')); | ||||
} | } | ||||
switch ($protocol) { | switch ($protocol) { | ||||
case 'http': | case 'http': | ||||
case 'https': | case 'https': | ||||
break; | break; | ||||
default: | default: | ||||
throw new Exception( | throw $this->newException( | ||||
pht( | pht( | ||||
'Notification server configuration describes an invalid '. | 'Notification server configuration describes an invalid '. | ||||
'host ("%s", at index "%s") with an invalid protocol ("%s"). '. | 'host ("%s", at index "%s") with an invalid protocol ("%s"). '. | ||||
'Valid protocols are "%s" or "%s".', | 'Valid protocols are "%s" or "%s".', | ||||
$host, | $host, | ||||
$index, | $index, | ||||
$protocol, | $protocol, | ||||
'http', | 'http', | ||||
'https')); | 'https')); | ||||
} | } | ||||
$path = idx($spec, 'path'); | $path = idx($spec, 'path'); | ||||
if ($type == 'admin' && strlen($path)) { | if ($type == 'admin' && strlen($path)) { | ||||
throw new Exception( | throw $this->newException( | ||||
pht( | pht( | ||||
'Notification server configuration describes an invalid host '. | 'Notification server configuration describes an invalid host '. | ||||
'("%s", at index "%s"). This is an "admin" service but it has a '. | '("%s", at index "%s"). This is an "admin" service but it has a '. | ||||
'"path" property. This property is only valid for "client" '. | '"path" property. This property is only valid for "client" '. | ||||
'services.')); | 'services.')); | ||||
} | } | ||||
// We can't guarantee that you didn't just give the same host two | // We can't guarantee that you didn't just give the same host two | ||||
// different names in DNS, but this check can catch silly copy/paste | // different names in DNS, but this check can catch silly copy/paste | ||||
// mistakes. | // mistakes. | ||||
$key = "{$host}:{$port}"; | $key = "{$host}:{$port}"; | ||||
if (isset($map[$key])) { | if (isset($map[$key])) { | ||||
throw new Exception( | throw $this->newException( | ||||
pht( | pht( | ||||
'Notification server configuration is invalid: it describes the '. | 'Notification server configuration is invalid: it describes the '. | ||||
'same host and port ("%s") multiple times. Each host and port '. | 'same host and port ("%s") multiple times. Each host and port '. | ||||
'combination should appear only once in the list.', | 'combination should appear only once in the list.', | ||||
$key)); | $key)); | ||||
} | } | ||||
$map[$key] = true; | $map[$key] = true; | ||||
} | } | ||||
if ($value) { | if ($value) { | ||||
if (!$has_admin) { | if (!$has_admin) { | ||||
throw new Exception( | throw $this->newException( | ||||
pht( | pht( | ||||
'Notification server configuration is invalid: it does not '. | 'Notification server configuration is invalid: it does not '. | ||||
'specify any enabled servers with type "admin". Notifications '. | 'specify any enabled servers with type "admin". Notifications '. | ||||
'require at least one active "admin" server.')); | 'require at least one active "admin" server.')); | ||||
} | } | ||||
if (!$has_client) { | if (!$has_client) { | ||||
throw new Exception( | throw $this->newException( | ||||
pht( | pht( | ||||
'Notification server configuration is invalid: it does not '. | 'Notification server configuration is invalid: it does not '. | ||||
'specify any enabled servers with type "client". Notifications '. | 'specify any enabled servers with type "client". Notifications '. | ||||
'require at least one active "client" server.')); | 'require at least one active "client" server.')); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
} | } |