{"action":"created","comment":{"url":"https://api.github.com/repos/mesosphere/marathon/pulls/comments/89800152","pull_request_review_id":10334080,"id":89800152,"diff_hunk":"@@ -367,6 +374,129 @@ class MigrationTo0_16(groupRepository: GroupRepository, appRepository: AppReposi\n   }\n }\n \n+class MigrationTo1_1(groupRepository: GroupRepository, appRepository: AppRepository, conf: MarathonConf) {\n+  private[this] val log = LoggerFactory.getLogger(getClass)\n+\n+  def migrate(): Future[Unit] = {\n+    log.info(\"Start 1.1 migration\")\n+\n+    //        We can have 3 cases here:\n+    //          1. App has one entry at the wrong place and must be moved:\n+    //\n+    //              Group( id = /, apps = [“/foo/bla”] )\n+    //              —>\n+    //              Group ( id = / ,\n+    //                Group( id = /foo, apps = [”/foo/bla”] )\n+    //\n+    //          2. App has 2 entries but both entries has the same version so the wrong one can be deleted:\n+    //\n+    //            Group( id = /, apps = [“/foo/bla, version = 1\"],\n+    //              Group( id = /foo, apps = [“/foo/bla, version = 1\"])\n+    //            —>\n+    //            Group ( id = / ,\n+    //              Group( id = /foo, apps = [“/foo/bla, version = 1\"] )\n+    //\n+    //          3. App has 2 entries with different versions. At this point we can either fail the migration or keep one of\n+    //             the versions. After some discussion we decided to keep the latest version.\n+    //             CAUTION: this migration can potentially result in data loss:\n+    //\n+    //            Group( id = /, apps = [“/foo/bla, version = 1\"],\n+    //              Group( id = /foo, apps = [“/foo/bla, version = 2\"])\n+    //            —>\n+    //            Group ( id = / ,\n+    //              Group( id = /foo, apps = [“/foo/bla, version = 2\"] )\n+\n+    val id = groupRepository.zkRootName\n+\n+    for {\n+      updatedGroups <- updateGroups(id)             // Update root and it's versions\n+      _ = log.info(s\"Updated groups: $updatedGroups\")\n+      _ <- storeGroups(id, updatedGroups)           // Store updated groups\n+      _ <- updateApps()                             // Update apps from the root group\n+    } yield log.info(\"Finished 1.1 migration\")\n+  }\n+\n+  def updateGroups(id: String): Future[Iterable[Group]] = {\n+    groupRepository.listVersions(id).flatMap { versions =>\n+      val fs = versions.map(version =>\n+        groupRepository.group(id, version).map {\n+          case Some(group) =>\n+            log.debug(s\"Loaded group: $group\")\n+            val updated = validateGroup(updateGroup(group))\n+            log.debug(s\"Updated group: $updated\")\n+            updated\n+          case None => throw new MigrationFailedException(s\"Group $id:$version not found\")\n+        }\n+      )\n+      Future.sequence(fs)\n+    }\n+  }\n+\n+  def storeGroups(id: String, updatedGroups: Iterable[Group]): Future[Iterable[Group]] = {\n+    val storedGroups = updatedGroups.map { group =>\n+      groupRepository.store(id, group)\n+    }\n+    Future.sequence(storedGroups)\n+  }\n+\n+  def updateApps(): Future[Set[AppDefinition]] = {\n+    val rootGroupFuture = groupRepository.rootGroup().map(_.getOrElse(Group.empty))\n+\n+    rootGroupFuture.flatMap{ rootGroup =>\n+      val apps = rootGroup.transitiveApps\n+      Future.sequence(apps.map(appRepository.store(_)) )\n+    }\n+  }\n+\n+  def updateGroup(group: Group): Group = {\n+    // get all apps including duplicates with different versions\n+    val apps = allApps(group)\n+    // remove all apps, keeping the empty groups\n+    val empty = removeAllApps(group)\n+    // update the groups with the apps while keeping the oldest app version\n+    val updated = apps.foldLeft(empty) { (group, app) =>\n+      log.debug(s\"Migrating $app\")\n+      group.updateApp(app.id, _.fold(app) { that => if (that.version.compare(app.version) > 0) that else app }, app.version)\n+    }\n+    log.debug(s\"Resulting root group: $updated\")\n+    updated\n+  }\n+\n+  import mesosphere.marathon.ValidationFailedException\n+\n+  implicit private val validator = Group.validRootGroup(conf.maxApps.get)\n+\n+  def validateGroup(group: Group): Group = {\n+    // Try-catch to log the reason for failed validation\n+    try {\n+      Validation.validateOrThrow(group)\n+    }\n+    catch {\n+      case e @ ValidationFailedException(f, t) =>\n+        log.error(s\"Validation failed for $f, because: $t\")\n+        throw e\n+      case e: Exception => throw e\n+    }\n+    group\n+  }\n+\n+  def allApps(group: Group): Iterable[AppDefinition] = {","path":"src/main/scala/mesosphere/marathon/state/Migration.scala","position":137,"original_position":135,"commit_id":"b68abed17df1b040a51b866b7664f3e37a0b0fec","original_commit_id":"a343beecd5e6b3ae778f5fd362ea1e9ecba4962a","user":{"login":"zen-dog","id":7558454,"avatar_url":"https://avatars.githubusercontent.com/u/7558454?v=3","gravatar_id":"","url":"https://api.github.com/users/zen-dog","html_url":"https://github.com/zen-dog","followers_url":"https://api.github.com/users/zen-dog/followers","following_url":"https://api.github.com/users/zen-dog/following{/other_user}","gists_url":"https://api.github.com/users/zen-dog/gists{/gist_id}","starred_url":"https://api.github.com/users/zen-dog/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zen-dog/subscriptions","organizations_url":"https://api.github.com/users/zen-dog/orgs","repos_url":"https://api.github.com/users/zen-dog/repos","events_url":"https://api.github.com/users/zen-dog/events{/privacy}","received_events_url":"https://api.github.com/users/zen-dog/received_events","type":"User","site_admin":false},"body":"`transitiveApps` will eliminate different app versions (it's a `Set`)","created_at":"2016-11-28T15:13:13Z","updated_at":"2016-11-28T15:13:13Z","html_url":"https://github.com/mesosphere/marathon/pull/4711#discussion_r89800152","pull_request_url":"https://api.github.com/repos/mesosphere/marathon/pulls/4711","_links":{"self":{"href":"https://api.github.com/repos/mesosphere/marathon/pulls/comments/89800152"},"html":{"href":"https://github.com/mesosphere/marathon/pull/4711#discussion_r89800152"},"pull_request":{"href":"https://api.github.com/repos/mesosphere/marathon/pulls/4711"}}},"pull_request":{"url":"https://api.github.com/repos/mesosphere/marathon/pulls/4711","id":95458610,"html_url":"https://github.com/mesosphere/marathon/pull/4711","diff_url":"https://github.com/mesosphere/marathon/pull/4711.diff","patch_url":"https://github.com/mesosphere/marathon/pull/4711.patch","issue_url":"https://api.github.com/repos/mesosphere/marathon/issues/4711","number":4711,"state":"open","locked":false,"title":"Added a MigrationTo1_1 class to handle broken app groups","user":{"login":"zen-dog","id":7558454,"avatar_url":"https://avatars.githubusercontent.com/u/7558454?v=3","gravatar_id":"","url":"https://api.github.com/users/zen-dog","html_url":"https://github.com/zen-dog","followers_url":"https://api.github.com/users/zen-dog/followers","following_url":"https://api.github.com/users/zen-dog/following{/other_user}","gists_url":"https://api.github.com/users/zen-dog/gists{/gist_id}","starred_url":"https://api.github.com/users/zen-dog/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zen-dog/subscriptions","organizations_url":"https://api.github.com/users/zen-dog/orgs","repos_url":"https://api.github.com/users/zen-dog/repos","events_url":"https://api.github.com/users/zen-dog/events{/privacy}","received_events_url":"https://api.github.com/users/zen-dog/received_events","type":"User","site_admin":false},"body":"Migration to 1.1:\r\n- loads root group from the group repository\r\n- filters out multiple app entries with the same version\r\n- filters out multiple app entries with different version by keeping the oldest\r\n- rebuilds the root group and stores it in the group repository\r\n\r\nFixes: DCOS-11627","created_at":"2016-11-28T08:55:32Z","updated_at":"2016-11-28T15:13:13Z","closed_at":null,"merged_at":null,"merge_commit_sha":"14b3c33fe5ec0857c3ab9204673b7737ea19d749","assignee":{"login":"aquamatthias","id":330485,"avatar_url":"https://avatars.githubusercontent.com/u/330485?v=3","gravatar_id":"","url":"https://api.github.com/users/aquamatthias","html_url":"https://github.com/aquamatthias","followers_url":"https://api.github.com/users/aquamatthias/followers","following_url":"https://api.github.com/users/aquamatthias/following{/other_user}","gists_url":"https://api.github.com/users/aquamatthias/gists{/gist_id}","starred_url":"https://api.github.com/users/aquamatthias/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/aquamatthias/subscriptions","organizations_url":"https://api.github.com/users/aquamatthias/orgs","repos_url":"https://api.github.com/users/aquamatthias/repos","events_url":"https://api.github.com/users/aquamatthias/events{/privacy}","received_events_url":"https://api.github.com/users/aquamatthias/received_events","type":"User","site_admin":false},"assignees":[{"login":"aquamatthias","id":330485,"avatar_url":"https://avatars.githubusercontent.com/u/330485?v=3","gravatar_id":"","url":"https://api.github.com/users/aquamatthias","html_url":"https://github.com/aquamatthias","followers_url":"https://api.github.com/users/aquamatthias/followers","following_url":"https://api.github.com/users/aquamatthias/following{/other_user}","gists_url":"https://api.github.com/users/aquamatthias/gists{/gist_id}","starred_url":"https://api.github.com/users/aquamatthias/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/aquamatthias/subscriptions","organizations_url":"https://api.github.com/users/aquamatthias/orgs","repos_url":"https://api.github.com/users/aquamatthias/repos","events_url":"https://api.github.com/users/aquamatthias/events{/privacy}","received_events_url":"https://api.github.com/users/aquamatthias/received_events","type":"User","site_admin":false},{"login":"jasongilanfarr","id":794214,"avatar_url":"https://avatars.githubusercontent.com/u/794214?v=3","gravatar_id":"","url":"https://api.github.com/users/jasongilanfarr","html_url":"https://github.com/jasongilanfarr","followers_url":"https://api.github.com/users/jasongilanfarr/followers","following_url":"https://api.github.com/users/jasongilanfarr/following{/other_user}","gists_url":"https://api.github.com/users/jasongilanfarr/gists{/gist_id}","starred_url":"https://api.github.com/users/jasongilanfarr/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jasongilanfarr/subscriptions","organizations_url":"https://api.github.com/users/jasongilanfarr/orgs","repos_url":"https://api.github.com/users/jasongilanfarr/repos","events_url":"https://api.github.com/users/jasongilanfarr/events{/privacy}","received_events_url":"https://api.github.com/users/jasongilanfarr/received_events","type":"User","site_admin":false}],"milestone":null,"commits_url":"https://api.github.com/repos/mesosphere/marathon/pulls/4711/commits","review_comments_url":"https://api.github.com/repos/mesosphere/marathon/pulls/4711/comments","review_comment_url":"https://api.github.com/repos/mesosphere/marathon/pulls/comments{/number}","comments_url":"https://api.github.com/repos/mesosphere/marathon/issues/4711/comments","statuses_url":"https://api.github.com/repos/mesosphere/marathon/statuses/b68abed17df1b040a51b866b7664f3e37a0b0fec","head":{"label":"mesosphere:ad/dcos-11627-1.1","ref":"ad/dcos-11627-1.1","sha":"b68abed17df1b040a51b866b7664f3e37a0b0fec","user":{"login":"mesosphere","id":3458585,"avatar_url":"https://avatars.githubusercontent.com/u/3458585?v=3","gravatar_id":"","url":"https://api.github.com/users/mesosphere","html_url":"https://github.com/mesosphere","followers_url":"https://api.github.com/users/mesosphere/followers","following_url":"https://api.github.com/users/mesosphere/following{/other_user}","gists_url":"https://api.github.com/users/mesosphere/gists{/gist_id}","starred_url":"https://api.github.com/users/mesosphere/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mesosphere/subscriptions","organizations_url":"https://api.github.com/users/mesosphere/orgs","repos_url":"https://api.github.com/users/mesosphere/repos","events_url":"https://api.github.com/users/mesosphere/events{/privacy}","received_events_url":"https://api.github.com/users/mesosphere/received_events","type":"Organization","site_admin":false},"repo":{"id":10941409,"name":"marathon","full_name":"mesosphere/marathon","owner":{"login":"mesosphere","id":3458585,"avatar_url":"https://avatars.githubusercontent.com/u/3458585?v=3","gravatar_id":"","url":"https://api.github.com/users/mesosphere","html_url":"https://github.com/mesosphere","followers_url":"https://api.github.com/users/mesosphere/followers","following_url":"https://api.github.com/users/mesosphere/following{/other_user}","gists_url":"https://api.github.com/users/mesosphere/gists{/gist_id}","starred_url":"https://api.github.com/users/mesosphere/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mesosphere/subscriptions","organizations_url":"https://api.github.com/users/mesosphere/orgs","repos_url":"https://api.github.com/users/mesosphere/repos","events_url":"https://api.github.com/users/mesosphere/events{/privacy}","received_events_url":"https://api.github.com/users/mesosphere/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/mesosphere/marathon","description":"Deploy and manage containers (including Docker) on top of Apache Mesos at scale.","fork":false,"url":"https://api.github.com/repos/mesosphere/marathon","forks_url":"https://api.github.com/repos/mesosphere/marathon/forks","keys_url":"https://api.github.com/repos/mesosphere/marathon/keys{/key_id}","collaborators_url":"https://api.github.com/repos/mesosphere/marathon/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/mesosphere/marathon/teams","hooks_url":"https://api.github.com/repos/mesosphere/marathon/hooks","issue_events_url":"https://api.github.com/repos/mesosphere/marathon/issues/events{/number}","events_url":"https://api.github.com/repos/mesosphere/marathon/events","assignees_url":"https://api.github.com/repos/mesosphere/marathon/assignees{/user}","branches_url":"https://api.github.com/repos/mesosphere/marathon/branches{/branch}","tags_url":"https://api.github.com/repos/mesosphere/marathon/tags","blobs_url":"https://api.github.com/repos/mesosphere/marathon/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/mesosphere/marathon/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/mesosphere/marathon/git/refs{/sha}","trees_url":"https://api.github.com/repos/mesosphere/marathon/git/trees{/sha}","statuses_url":"https://api.github.com/repos/mesosphere/marathon/statuses/{sha}","languages_url":"https://api.github.com/repos/mesosphere/marathon/languages","stargazers_url":"https://api.github.com/repos/mesosphere/marathon/stargazers","contributors_url":"https://api.github.com/repos/mesosphere/marathon/contributors","subscribers_url":"https://api.github.com/repos/mesosphere/marathon/subscribers","subscription_url":"https://api.github.com/repos/mesosphere/marathon/subscription","commits_url":"https://api.github.com/repos/mesosphere/marathon/commits{/sha}","git_commits_url":"https://api.github.com/repos/mesosphere/marathon/git/commits{/sha}","comments_url":"https://api.github.com/repos/mesosphere/marathon/comments{/number}","issue_comment_url":"https://api.github.com/repos/mesosphere/marathon/issues/comments{/number}","contents_url":"https://api.github.com/repos/mesosphere/marathon/contents/{+path}","compare_url":"https://api.github.com/repos/mesosphere/marathon/compare/{base}...{head}","merges_url":"https://api.github.com/repos/mesosphere/marathon/merges","archive_url":"https://api.github.com/repos/mesosphere/marathon/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/mesosphere/marathon/downloads","issues_url":"https://api.github.com/repos/mesosphere/marathon/issues{/number}","pulls_url":"https://api.github.com/repos/mesosphere/marathon/pulls{/number}","milestones_url":"https://api.github.com/repos/mesosphere/marathon/milestones{/number}","notifications_url":"https://api.github.com/repos/mesosphere/marathon/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/mesosphere/marathon/labels{/name}","releases_url":"https://api.github.com/repos/mesosphere/marathon/releases{/id}","deployments_url":"https://api.github.com/repos/mesosphere/marathon/deployments","created_at":"2013-06-25T14:56:34Z","updated_at":"2016-11-28T04:23:36Z","pushed_at":"2016-11-28T15:12:18Z","git_url":"git://github.com/mesosphere/marathon.git","ssh_url":"git@github.com:mesosphere/marathon.git","clone_url":"https://github.com/mesosphere/marathon.git","svn_url":"https://github.com/mesosphere/marathon","homepage":"https://mesosphere.github.io/marathon/","size":37984,"stargazers_count":2927,"watchers_count":2927,"language":"Scala","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":true,"forks_count":654,"mirror_url":null,"open_issues_count":624,"forks":654,"open_issues":624,"watchers":2927,"default_branch":"master"}},"base":{"label":"mesosphere:releases/1.1","ref":"releases/1.1","sha":"81d61e023a019e1a1bc44ccd0f1194e783aefc76","user":{"login":"mesosphere","id":3458585,"avatar_url":"https://avatars.githubusercontent.com/u/3458585?v=3","gravatar_id":"","url":"https://api.github.com/users/mesosphere","html_url":"https://github.com/mesosphere","followers_url":"https://api.github.com/users/mesosphere/followers","following_url":"https://api.github.com/users/mesosphere/following{/other_user}","gists_url":"https://api.github.com/users/mesosphere/gists{/gist_id}","starred_url":"https://api.github.com/users/mesosphere/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mesosphere/subscriptions","organizations_url":"https://api.github.com/users/mesosphere/orgs","repos_url":"https://api.github.com/users/mesosphere/repos","events_url":"https://api.github.com/users/mesosphere/events{/privacy}","received_events_url":"https://api.github.com/users/mesosphere/received_events","type":"Organization","site_admin":false},"repo":{"id":10941409,"name":"marathon","full_name":"mesosphere/marathon","owner":{"login":"mesosphere","id":3458585,"avatar_url":"https://avatars.githubusercontent.com/u/3458585?v=3","gravatar_id":"","url":"https://api.github.com/users/mesosphere","html_url":"https://github.com/mesosphere","followers_url":"https://api.github.com/users/mesosphere/followers","following_url":"https://api.github.com/users/mesosphere/following{/other_user}","gists_url":"https://api.github.com/users/mesosphere/gists{/gist_id}","starred_url":"https://api.github.com/users/mesosphere/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mesosphere/subscriptions","organizations_url":"https://api.github.com/users/mesosphere/orgs","repos_url":"https://api.github.com/users/mesosphere/repos","events_url":"https://api.github.com/users/mesosphere/events{/privacy}","received_events_url":"https://api.github.com/users/mesosphere/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/mesosphere/marathon","description":"Deploy and manage containers (including Docker) on top of Apache Mesos at scale.","fork":false,"url":"https://api.github.com/repos/mesosphere/marathon","forks_url":"https://api.github.com/repos/mesosphere/marathon/forks","keys_url":"https://api.github.com/repos/mesosphere/marathon/keys{/key_id}","collaborators_url":"https://api.github.com/repos/mesosphere/marathon/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/mesosphere/marathon/teams","hooks_url":"https://api.github.com/repos/mesosphere/marathon/hooks","issue_events_url":"https://api.github.com/repos/mesosphere/marathon/issues/events{/number}","events_url":"https://api.github.com/repos/mesosphere/marathon/events","assignees_url":"https://api.github.com/repos/mesosphere/marathon/assignees{/user}","branches_url":"https://api.github.com/repos/mesosphere/marathon/branches{/branch}","tags_url":"https://api.github.com/repos/mesosphere/marathon/tags","blobs_url":"https://api.github.com/repos/mesosphere/marathon/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/mesosphere/marathon/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/mesosphere/marathon/git/refs{/sha}","trees_url":"https://api.github.com/repos/mesosphere/marathon/git/trees{/sha}","statuses_url":"https://api.github.com/repos/mesosphere/marathon/statuses/{sha}","languages_url":"https://api.github.com/repos/mesosphere/marathon/languages","stargazers_url":"https://api.github.com/repos/mesosphere/marathon/stargazers","contributors_url":"https://api.github.com/repos/mesosphere/marathon/contributors","subscribers_url":"https://api.github.com/repos/mesosphere/marathon/subscribers","subscription_url":"https://api.github.com/repos/mesosphere/marathon/subscription","commits_url":"https://api.github.com/repos/mesosphere/marathon/commits{/sha}","git_commits_url":"https://api.github.com/repos/mesosphere/marathon/git/commits{/sha}","comments_url":"https://api.github.com/repos/mesosphere/marathon/comments{/number}","issue_comment_url":"https://api.github.com/repos/mesosphere/marathon/issues/comments{/number}","contents_url":"https://api.github.com/repos/mesosphere/marathon/contents/{+path}","compare_url":"https://api.github.com/repos/mesosphere/marathon/compare/{base}...{head}","merges_url":"https://api.github.com/repos/mesosphere/marathon/merges","archive_url":"https://api.github.com/repos/mesosphere/marathon/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/mesosphere/marathon/downloads","issues_url":"https://api.github.com/repos/mesosphere/marathon/issues{/number}","pulls_url":"https://api.github.com/repos/mesosphere/marathon/pulls{/number}","milestones_url":"https://api.github.com/repos/mesosphere/marathon/milestones{/number}","notifications_url":"https://api.github.com/repos/mesosphere/marathon/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/mesosphere/marathon/labels{/name}","releases_url":"https://api.github.com/repos/mesosphere/marathon/releases{/id}","deployments_url":"https://api.github.com/repos/mesosphere/marathon/deployments","created_at":"2013-06-25T14:56:34Z","updated_at":"2016-11-28T04:23:36Z","pushed_at":"2016-11-28T15:12:18Z","git_url":"git://github.com/mesosphere/marathon.git","ssh_url":"git@github.com:mesosphere/marathon.git","clone_url":"https://github.com/mesosphere/marathon.git","svn_url":"https://github.com/mesosphere/marathon","homepage":"https://mesosphere.github.io/marathon/","size":37984,"stargazers_count":2927,"watchers_count":2927,"language":"Scala","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":true,"forks_count":654,"mirror_url":null,"open_issues_count":624,"forks":654,"open_issues":624,"watchers":2927,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/mesosphere/marathon/pulls/4711"},"html":{"href":"https://github.com/mesosphere/marathon/pull/4711"},"issue":{"href":"https://api.github.com/repos/mesosphere/marathon/issues/4711"},"comments":{"href":"https://api.github.com/repos/mesosphere/marathon/issues/4711/comments"},"review_comments":{"href":"https://api.github.com/repos/mesosphere/marathon/pulls/4711/comments"},"review_comment":{"href":"https://api.github.com/repos/mesosphere/marathon/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/mesosphere/marathon/pulls/4711/commits"},"statuses":{"href":"https://api.github.com/repos/mesosphere/marathon/statuses/b68abed17df1b040a51b866b7664f3e37a0b0fec"}}}}
{"actor":{"display_login":"zen-dog"}}