Commit 7b3d2ac4 authored by Sebastian Kummer's avatar Sebastian Kummer

Merge pull request #89 in ZP/z-push from...

Merge pull request #89 in ZP/z-push from feature/ZP-735-add-option-to-delete-hierarchy-cache to develop

* commit 'e12c6cc5':
  ZP-735 Clearify the device switch and that this is the folder hierarchy.
  ZP-735 Add option to resync only the hierarchy of a specific user, device or all. When forcing resync, delete first all states of synchronized folders and afterwards the hierarchy, so the necessary information is still available. Reset contentData & ignoredMessages of the device ONLY when removing the hierarchy synckey, not when setting a new one.

(cherry picked from commit d1dfee9c)
parent 1568e15f
...@@ -542,7 +542,7 @@ class ASDevice extends StateObject { ...@@ -542,7 +542,7 @@ class ASDevice extends StateObject {
if ($folderid === false) { if ($folderid === false) {
$this->hierarchyUuid = $uuid; $this->hierarchyUuid = $uuid;
// when unsetting the hierarchycache, also remove saved contentdata and ignoredmessages // when unsetting the hierarchycache, also remove saved contentdata and ignoredmessages
if ($folderid === false) { if ($folderid === false && $uuid === false) {
$this->contentData = array(); $this->contentData = array();
$this->ignoredMessageIds = array(); $this->ignoredMessageIds = array();
$this->ignoredMessages = array(); $this->ignoredMessages = array();
...@@ -688,4 +688,4 @@ class ASDevice extends StateObject { ...@@ -688,4 +688,4 @@ class ASDevice extends StateObject {
} }
?> ?>
\ No newline at end of file
...@@ -557,13 +557,13 @@ class DeviceManager { ...@@ -557,13 +557,13 @@ class DeviceManager {
public function ForceFullResync() { public function ForceFullResync() {
ZLog::Write(LOGLEVEL_INFO, "Full device resync requested"); ZLog::Write(LOGLEVEL_INFO, "Full device resync requested");
// delete hierarchy states
StateManager::UnLinkState($this->device, false);
// delete all other uuids // delete all other uuids
foreach ($this->device->GetAllFolderIds() as $folderid) foreach ($this->device->GetAllFolderIds() as $folderid)
$uuid = StateManager::UnLinkState($this->device, $folderid); $uuid = StateManager::UnLinkState($this->device, $folderid);
// delete hierarchy states
StateManager::UnLinkState($this->device, false);
return true; return true;
} }
...@@ -748,7 +748,7 @@ class DeviceManager { ...@@ -748,7 +748,7 @@ class DeviceManager {
} }
/** /**
* Returns the User Agent. This data is consolidated with data from Request::GetUserAgent() * Returns the User Agent. This data is consolidated with data from Request::GetUserAgent()
* and the data saved in the ASDevice. * and the data saved in the ASDevice.
* *
* @access public * @access public
...@@ -887,4 +887,4 @@ class DeviceManager { ...@@ -887,4 +887,4 @@ class DeviceManager {
} }
} }
?> ?>
\ No newline at end of file
...@@ -429,6 +429,38 @@ class ZPushAdmin { ...@@ -429,6 +429,38 @@ class ZPushAdmin {
return true; return true;
} }
/**
* Removes the hierarchydata of a device of a user so it will be re-synchronizated.
*
* @param string $user user of the device
* @param string $devid device id which should be wiped
*
* @return boolean
* @access public
*/
static public function ResyncHierarchy($user, $devid) {
// load device data
$device = new ASDevice($devid, ASDevice::UNDEFINED, $user, ASDevice::UNDEFINED);
try {
$device->SetData(ZPush::GetStateMachine()->GetState($devid, IStateMachine::DEVICEDATA), false);
if ($device->IsNewDevice()) {
ZLog::Write(LOGLEVEL_ERROR, sprintf("ZPushAdmin::ResyncHierarchy(): data of user '%s' not synchronized on device '%s'. Aborting.",$user, $devid));
return false;
}
// remove hierarchcache, but don't update the device, as the folder states are invalidated
StateManager::UnLinkState($device, false, false);
ZLog::Write(LOGLEVEL_DEBUG, sprintf("ZPushAdmin::ResyncHierarchy(): deleted hierarchy states of device '%s' of user '%s'", $devid, $user));
}
catch (StateNotFoundException $e) {
ZLog::Write(LOGLEVEL_ERROR, sprintf("ZPushAdmin::ResyncHierarchy(): state for device '%s' of user '%s' can not be found or saved", $devid, $user));
return false;
}
return true;
}
/** /**
* Clears loop detection data * Clears loop detection data
* *
...@@ -619,4 +651,4 @@ class ZPushAdmin { ...@@ -619,4 +651,4 @@ class ZPushAdmin {
} }
?> ?>
\ No newline at end of file
...@@ -140,12 +140,14 @@ class ZPushAdminCLI { ...@@ -140,12 +140,14 @@ class ZPushAdminCLI {
const COMMAND_SHOWLASTSYNC = 8; const COMMAND_SHOWLASTSYNC = 8;
const COMMAND_RESYNCFOLDER = 9; const COMMAND_RESYNCFOLDER = 9;
const COMMAND_FIXSTATES = 10; const COMMAND_FIXSTATES = 10;
const COMMAND_RESYNCHIERARCHY = 11;
const TYPE_OPTION_EMAIL = "email"; const TYPE_OPTION_EMAIL = "email";
const TYPE_OPTION_CALENDAR = "calendar"; const TYPE_OPTION_CALENDAR = "calendar";
const TYPE_OPTION_CONTACT = "contact"; const TYPE_OPTION_CONTACT = "contact";
const TYPE_OPTION_TASK = "task"; const TYPE_OPTION_TASK = "task";
const TYPE_OPTION_NOTE = "note"; const TYPE_OPTION_NOTE = "note";
const TYPE_OPTION_HIERARCHY = "hierarchy";
static private $command; static private $command;
static private $user = false; static private $user = false;
...@@ -164,24 +166,25 @@ class ZPushAdminCLI { ...@@ -164,24 +166,25 @@ class ZPushAdminCLI {
return "Usage:\n\tz-push-admin.php -a ACTION [options]\n\n" . return "Usage:\n\tz-push-admin.php -a ACTION [options]\n\n" .
"Parameters:\n\t-a list/wipe/remove/resync/clearloop\n\t[-u] username\n\t[-d] deviceid\n\n" . "Parameters:\n\t-a list/wipe/remove/resync/clearloop\n\t[-u] username\n\t[-d] deviceid\n\n" .
"Actions:\n" . "Actions:\n" .
"\tlist\t\t\t\t Lists all devices and synchronized users\n" . "\tlist\t\t\t\t\t Lists all devices and synchronized users\n" .
"\tlist -u USER\t\t\t Lists all devices of user USER\n" . "\tlist -u USER\t\t\t\t Lists all devices of user USER\n" .
"\tlist -d DEVICE\t\t\t Lists all users of device DEVICE\n" . "\tlist -d DEVICE\t\t\t\t Lists all users of device DEVICE\n" .
"\tlastsync\t\t\t Lists all devices and synchronized users and the last synchronization time\n" . "\tlastsync\t\t\t\t Lists all devices and synchronized users and the last synchronization time\n" .
"\twipe -u USER\t\t\t Remote wipes all devices of user USER\n" . "\twipe -u USER\t\t\t\t Remote wipes all devices of user USER\n" .
"\twipe -d DEVICE\t\t\t Remote wipes device DEVICE\n" . "\twipe -d DEVICE\t\t\t\t Remote wipes device DEVICE\n" .
"\twipe -u USER -d DEVICE\t\t Remote wipes device DEVICE of user USER\n" . "\twipe -u USER -d DEVICE\t\t\t Remote wipes device DEVICE of user USER\n" .
"\tremove -u USER\t\t\t Removes all state data of all devices of user USER\n" . "\tremove -u USER\t\t\t\t Removes all state data of all devices of user USER\n" .
"\tremove -d DEVICE\t\t Removes all state data of all users synchronized on device DEVICE\n" . "\tremove -d DEVICE\t\t\t Removes all state data of all users synchronized on device DEVICE\n" .
"\tremove -u USER -d DEVICE\t Removes all related state data of device DEVICE of user USER\n" . "\tremove -u USER -d DEVICE\t\t Removes all related state data of device DEVICE of user USER\n" .
"\tresync -u USER -d DEVICE\t Resynchronizes all data of device DEVICE of user USER\n" . "\tresync -u USER -d DEVICE\t\t Resynchronizes all data of device DEVICE of user USER\n" .
"\tresync -t TYPE \t\t\t Resynchronizes all folders of type $types for all devices and users.\n" . "\tresync -t TYPE \t\t\t\t Resynchronizes all folders of type $types for all devices and users.\n" .
"\tresync -t TYPE -u USER \t\t Resynchronizes all folders of type $types for the user USER.\n" . "\tresync -t TYPE -u USER \t\t\t Resynchronizes all folders of type $types for the user USER.\n" .
"\tresync -t TYPE -u USER -d DEVICE Resynchronizes all folders of type $types for a specified device and user.\n" . "\tresync -t TYPE -u USER -d DEVICE\t Resynchronizes all folders of type $types for a specified device and user.\n" .
"\tresync -t FOLDERID -u USER\t Resynchronize the specified folder id only. The USER should be specified for better performance.\n" . "\tresync -t FOLDERID -u USER\t\t Resynchronize the specified folder id only. The USER should be specified for better performance.\n" .
"\tclearloop\t\t\t Clears system wide loop detection data\n" . "\tresync -t hierarchy -u USER -d DEVICE\t Resynchronize the folder hierarchy data for an optional USER and optional DEVICE.\n" .
"\tclearloop -d DEVICE -u USER\t Clears all loop detection data of a device DEVICE and an optional user USER\n" . "\tclearloop\t\t\t\t Clears system wide loop detection data\n" .
"\tfixstates\t\t\t Checks the states for integrity and fixes potential issues\n" . "\tclearloop -d DEVICE -u USER\t\t Clears all loop detection data of a device DEVICE and an optional user USER\n" .
"\tfixstates\t\t\t\t Checks the states for integrity and fixes potential issues\n" .
"\n"; "\n";
} }
...@@ -243,9 +246,10 @@ class ZPushAdminCLI { ...@@ -243,9 +246,10 @@ class ZPushAdminCLI {
self::$type !== self::TYPE_OPTION_CONTACT && self::$type !== self::TYPE_OPTION_CONTACT &&
self::$type !== self::TYPE_OPTION_TASK && self::$type !== self::TYPE_OPTION_TASK &&
self::$type !== self::TYPE_OPTION_NOTE && self::$type !== self::TYPE_OPTION_NOTE &&
self::$type !== self::TYPE_OPTION_HIERARCHY &&
strlen(self::$type) !== 44) { strlen(self::$type) !== 44) {
self::$errormessage = "Wrong 'type'. Possible values are: ". self::$errormessage = "Wrong 'type'. Possible values are: ".
"'".self::TYPE_OPTION_EMAIL."', '".self::TYPE_OPTION_CALENDAR."', '".self::TYPE_OPTION_CONTACT."', '".self::TYPE_OPTION_TASK."', '".self::TYPE_OPTION_NOTE."' ". "'".self::TYPE_OPTION_EMAIL."', '".self::TYPE_OPTION_CALENDAR."', '".self::TYPE_OPTION_CONTACT."', '".self::TYPE_OPTION_TASK."', '".self::TYPE_OPTION_NOTE."', ".self::TYPE_OPTION_HIERARCHY."' ".
"or a 44 byte long folder id (as hex)."; "or a 44 byte long folder id (as hex).";
return; return;
} }
...@@ -300,6 +304,9 @@ class ZPushAdminCLI { ...@@ -300,6 +304,9 @@ class ZPushAdminCLI {
else else
self::$command = self::COMMAND_RESYNCDEVICE; self::$command = self::COMMAND_RESYNCDEVICE;
} }
else if (self::$type === self::TYPE_OPTION_HIERARCHY) {
self::$command = self::COMMAND_RESYNCHIERARCHY;
}
else { else {
self::$command = self::COMMAND_RESYNCFOLDER; self::$command = self::COMMAND_RESYNCFOLDER;
} }
...@@ -410,6 +417,18 @@ class ZPushAdminCLI { ...@@ -410,6 +417,18 @@ class ZPushAdminCLI {
self::CommandResyncFolder(); self::CommandResyncFolder();
break; break;
case self::COMMAND_RESYNCHIERARCHY:
if (self::$device == false && self::$user == false) {
echo "Are you sure you want to re-synchronize the hierarchy of all devices and users [y/N]: ";
$confirm = strtolower(trim(fgets(STDIN)));
if ( !($confirm === 'y' || $confirm === 'yes')) {
echo "Aborted!\n";
exit(1);
}
}
self::CommandResyncHierarchy();
break;
case self::COMMAND_CLEARLOOP: case self::COMMAND_CLEARLOOP:
self::CommandClearLoopDetectionData(); self::CommandClearLoopDetectionData();
break; break;
...@@ -588,6 +607,36 @@ class ZPushAdminCLI { ...@@ -588,6 +607,36 @@ class ZPushAdminCLI {
} }
/**
* Command "Resync hierarchy"
* Resyncs a folder type of a specific device/user or of all users
*
* @return
* @access public
*/
static public function CommandResyncHierarchy() {
// if no device is specified, search for all devices of a user. If user is not set, all devices are returned.
if (self::$device === false) {
$devicelist = ZPushAdmin::ListDevices(self::$user);
if (empty($devicelist)) {
echo "\tno devices/users found\n";
return true;
}
}
else
$devicelist = array(self::$device);
foreach ($devicelist as $deviceId) {
$users = ZPushAdmin::ListUsers($deviceId);
foreach ($users as $user) {
if (self::$user && self::$user != $user)
continue;
self::resyncHierarchy($deviceId, $user);
}
}
}
/** /**
* Command to clear the loop detection data * Command to clear the loop detection data
* Mobiles may enter loop detection (one-by-one synchring due to timeouts / erros). * Mobiles may enter loop detection (one-by-one synchring due to timeouts / erros).
...@@ -670,6 +719,20 @@ class ZPushAdminCLI { ...@@ -670,6 +719,20 @@ class ZPushAdminCLI {
echo sprintf("Resync of %d folders of type %s on device '%s' of user '%s': %s\n", count($folders), $type, $deviceId, $user, ($stat)?'Requested':ZLog::GetLastMessage(LOGLEVEL_ERROR)); echo sprintf("Resync of %d folders of type %s on device '%s' of user '%s': %s\n", count($folders), $type, $deviceId, $user, ($stat)?'Requested':ZLog::GetLastMessage(LOGLEVEL_ERROR));
} }
/**
* Resynchronizes the hierarchy of a device & user
*
* @param string $deviceId the id of the device
* @param string $user the user
*
* @return
* @access private
*/
static private function resyncHierarchy($deviceId, $user) {
$stat = ZPushAdmin::ResyncHierarchy($user, $deviceId);
echo sprintf("Removing hierarchy information for resync on device '%s' of user '%s': %s\n", $deviceId, $user, ($stat)?'Requested':ZLog::GetLastMessage(LOGLEVEL_ERROR));
}
/** /**
* Fixes the states for potential issues * Fixes the states for potential issues
* *
...@@ -872,4 +935,4 @@ class ZPushAdminCLI { ...@@ -872,4 +935,4 @@ class ZPushAdminCLI {
} }
?> ?>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment