{"action":"created","comment":{"url":"https://api.github.com/repos/eclipse/che/pulls/comments/92807705","pull_request_review_id":13329336,"id":92807705,"diff_hunk":"@@ -310,13 +314,67 @@ public WorkspaceImpl updateWorkspace(String id, Workspace update) throws Conflic\n         requireNonNull(id, \"Required non-null workspace id\");\n         requireNonNull(update, \"Required non-null workspace update\");\n         final WorkspaceImpl workspace = workspaceDao.get(id);\n+        updateWorkspaceSnapshots(id, workspace, update);\n         workspace.setConfig(new WorkspaceConfigImpl(update.getConfig()));\n         update.getAttributes().put(UPDATED_ATTRIBUTE_NAME, Long.toString(currentTimeMillis()));\n         workspace.setAttributes(update.getAttributes());\n         return normalizeState(workspaceDao.update(workspace));\n     }\n \n     /**\n+     * Updates workspace snapshots corresponding to update environments.\n+     * Snapshots are deleted on any environment update except rename.\n+     * Also they will be deleted if it is impossible to find one correspondence between old and new environment,\n+     * but if in current and in update configuration the same environment is present, it supposed as untouched.\n+     *\n+     * @param workspaceId\n+     *         id of workspace under update\n+     * @param current\n+     *         current workspace configuration\n+     * @param update\n+     *         new workspace configuration\n+     */\n+    private void updateWorkspaceSnapshots(String workspaceId, Workspace current, Workspace update) {\n+        // this is needed to convert DTO into EnvironmentImpl object, otherwise equals will fail\n+        final Map<String, Environment> updateEnvironments = update.getConfig()\n+                                                                  .getEnvironments()\n+                                                                  .entrySet()\n+                                                                  .stream()\n+                                                                  .collect(Collectors.toMap(Map.Entry::getKey,\n+                                                                                            env -> new EnvironmentImpl(env.getValue())));\n+\n+        final Map <String, Environment> currentDiff = Sets.difference(current.getConfig().getEnvironments().entrySet(),\n+                                                                      updateEnvironments.entrySet())\n+                                                          .stream()\n+                                                          .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));\n+        final Map <String, Environment> updateDiff = Sets.difference(updateEnvironments.entrySet(),\n+                                                                     current.getConfig().getEnvironments().entrySet())\n+                                                         .stream()\n+                                                         .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));\n+\n+        for (Map.Entry<String, Environment> env : currentDiff.entrySet()) {\n+            Environment envValue = env.getValue();\n+            if (Collections.frequency(currentDiff.values(), envValue) == 1 &&\n+                Collections.frequency(updateDiff.values(), envValue) == 1 &&\n+                !updateDiff.containsKey(env.getKey())) {\n+                try {\n+                    updateEnvironmentSnapshots(workspaceId, env.getKey(), updateDiff.entrySet()\n+                                                                                    .stream()\n+                                                                                    .filter(e -> e.getValue().equals(envValue))\n+                                                                                    .findAny()\n+                                                                                    .orElse(null) // should never happens\n+                                                                                    .getKey());\n+                } catch (ConflictException | SnapshotException | NotFoundException err) {\n+                    LOG.error(\"Failed to update snapshots of '%s' environment in '%s' workspace.\", env.getKey(), workspaceId, err);\n+                    safeRemoveEnvironmentSnapshots(workspaceId, env.getKey());","path":"wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/workspace/server/WorkspaceManager.java","position":85,"original_position":85,"commit_id":"e8322f43ff724e431d8cd4ea5930b35cbf2b1d15","original_commit_id":"e8322f43ff724e431d8cd4ea5930b35cbf2b1d15","user":{"login":"evoevodin","id":4053805,"avatar_url":"https://avatars.githubusercontent.com/u/4053805?v=3","gravatar_id":"","url":"https://api.github.com/users/evoevodin","html_url":"https://github.com/evoevodin","followers_url":"https://api.github.com/users/evoevodin/followers","following_url":"https://api.github.com/users/evoevodin/following{/other_user}","gists_url":"https://api.github.com/users/evoevodin/gists{/gist_id}","starred_url":"https://api.github.com/users/evoevodin/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/evoevodin/subscriptions","organizations_url":"https://api.github.com/users/evoevodin/orgs","repos_url":"https://api.github.com/users/evoevodin/repos","events_url":"https://api.github.com/users/evoevodin/events{/privacy}","received_events_url":"https://api.github.com/users/evoevodin/received_events","type":"User","site_admin":false},"body":"i wouldn't use _safe_ for such kind of method it's usually called called _actionQuietly_ or just _action_.","created_at":"2016-12-16T13:01:54Z","updated_at":"2016-12-16T13:01:54Z","html_url":"https://github.com/eclipse/che/pull/2613#discussion_r92807705","pull_request_url":"https://api.github.com/repos/eclipse/che/pulls/2613","_links":{"self":{"href":"https://api.github.com/repos/eclipse/che/pulls/comments/92807705"},"html":{"href":"https://github.com/eclipse/che/pull/2613#discussion_r92807705"},"pull_request":{"href":"https://api.github.com/repos/eclipse/che/pulls/2613"}}},"pull_request":{"url":"https://api.github.com/repos/eclipse/che/pulls/2613","id":86930327,"html_url":"https://github.com/eclipse/che/pull/2613","diff_url":"https://github.com/eclipse/che/pull/2613.diff","patch_url":"https://github.com/eclipse/che/pull/2613.patch","issue_url":"https://api.github.com/repos/eclipse/che/issues/2613","number":2613,"state":"open","locked":false,"title":"CHE-3017: Improve updating of environments","user":{"login":"mmorhun","id":15607393,"avatar_url":"https://avatars.githubusercontent.com/u/15607393?v=3","gravatar_id":"","url":"https://api.github.com/users/mmorhun","html_url":"https://github.com/mmorhun","followers_url":"https://api.github.com/users/mmorhun/followers","following_url":"https://api.github.com/users/mmorhun/following{/other_user}","gists_url":"https://api.github.com/users/mmorhun/gists{/gist_id}","starred_url":"https://api.github.com/users/mmorhun/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mmorhun/subscriptions","organizations_url":"https://api.github.com/users/mmorhun/orgs","repos_url":"https://api.github.com/users/mmorhun/repos","events_url":"https://api.github.com/users/mmorhun/events{/privacy}","received_events_url":"https://api.github.com/users/mmorhun/received_events","type":"User","site_admin":false},"body":"### What does this PR do?\r\nHandles environment snapshots on environments update.\r\nAdds ability to rename specified environment. \r\nFixes bug, when workspace with snapshot fails to start after renaming of environment.\r\n\r\n### What issues does this PR fix or reference?\r\n#3017 \r\n#2528\r\n\r\n### Previous behavior\r\nOn workspace update new configs of environments just overwrites old ones.\r\nWorkspace with snapshot fails to start after renaming of the environment.\r\n\r\n### New behavior\r\nUpdates snapshots on environments rename.\r\nRemoves / updates snapshots on environment update.\r\nAlways deletes snapshots on environment deletion.\r\nAdds ability to rename specified environment.\r\nWorkspace with snapshots can start after renaming of environment.\r\n\r\nNew tests have been written.\r\n","created_at":"2016-09-27T13:31:59Z","updated_at":"2016-12-16T13:01:54Z","closed_at":null,"merged_at":null,"merge_commit_sha":"fb5597dcdf15586ce5b9756009eadf7842230d53","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/eclipse/che/pulls/2613/commits","review_comments_url":"https://api.github.com/repos/eclipse/che/pulls/2613/comments","review_comment_url":"https://api.github.com/repos/eclipse/che/pulls/comments{/number}","comments_url":"https://api.github.com/repos/eclipse/che/issues/2613/comments","statuses_url":"https://api.github.com/repos/eclipse/che/statuses/e8322f43ff724e431d8cd4ea5930b35cbf2b1d15","head":{"label":"eclipse:CHE-2528","ref":"CHE-2528","sha":"e8322f43ff724e431d8cd4ea5930b35cbf2b1d15","user":{"login":"eclipse","id":56974,"avatar_url":"https://avatars.githubusercontent.com/u/56974?v=3","gravatar_id":"","url":"https://api.github.com/users/eclipse","html_url":"https://github.com/eclipse","followers_url":"https://api.github.com/users/eclipse/followers","following_url":"https://api.github.com/users/eclipse/following{/other_user}","gists_url":"https://api.github.com/users/eclipse/gists{/gist_id}","starred_url":"https://api.github.com/users/eclipse/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/eclipse/subscriptions","organizations_url":"https://api.github.com/users/eclipse/orgs","repos_url":"https://api.github.com/users/eclipse/repos","events_url":"https://api.github.com/users/eclipse/events{/privacy}","received_events_url":"https://api.github.com/users/eclipse/received_events","type":"Organization","site_admin":false},"repo":{"id":32935745,"name":"che","full_name":"eclipse/che","owner":{"login":"eclipse","id":56974,"avatar_url":"https://avatars.githubusercontent.com/u/56974?v=3","gravatar_id":"","url":"https://api.github.com/users/eclipse","html_url":"https://github.com/eclipse","followers_url":"https://api.github.com/users/eclipse/followers","following_url":"https://api.github.com/users/eclipse/following{/other_user}","gists_url":"https://api.github.com/users/eclipse/gists{/gist_id}","starred_url":"https://api.github.com/users/eclipse/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/eclipse/subscriptions","organizations_url":"https://api.github.com/users/eclipse/orgs","repos_url":"https://api.github.com/users/eclipse/repos","events_url":"https://api.github.com/users/eclipse/events{/privacy}","received_events_url":"https://api.github.com/users/eclipse/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/eclipse/che","description":"Eclipse Che: Next-generation Eclipse IDE.  Open source workspace server and cloud IDE.","fork":false,"url":"https://api.github.com/repos/eclipse/che","forks_url":"https://api.github.com/repos/eclipse/che/forks","keys_url":"https://api.github.com/repos/eclipse/che/keys{/key_id}","collaborators_url":"https://api.github.com/repos/eclipse/che/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/eclipse/che/teams","hooks_url":"https://api.github.com/repos/eclipse/che/hooks","issue_events_url":"https://api.github.com/repos/eclipse/che/issues/events{/number}","events_url":"https://api.github.com/repos/eclipse/che/events","assignees_url":"https://api.github.com/repos/eclipse/che/assignees{/user}","branches_url":"https://api.github.com/repos/eclipse/che/branches{/branch}","tags_url":"https://api.github.com/repos/eclipse/che/tags","blobs_url":"https://api.github.com/repos/eclipse/che/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/eclipse/che/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/eclipse/che/git/refs{/sha}","trees_url":"https://api.github.com/repos/eclipse/che/git/trees{/sha}","statuses_url":"https://api.github.com/repos/eclipse/che/statuses/{sha}","languages_url":"https://api.github.com/repos/eclipse/che/languages","stargazers_url":"https://api.github.com/repos/eclipse/che/stargazers","contributors_url":"https://api.github.com/repos/eclipse/che/contributors","subscribers_url":"https://api.github.com/repos/eclipse/che/subscribers","subscription_url":"https://api.github.com/repos/eclipse/che/subscription","commits_url":"https://api.github.com/repos/eclipse/che/commits{/sha}","git_commits_url":"https://api.github.com/repos/eclipse/che/git/commits{/sha}","comments_url":"https://api.github.com/repos/eclipse/che/comments{/number}","issue_comment_url":"https://api.github.com/repos/eclipse/che/issues/comments{/number}","contents_url":"https://api.github.com/repos/eclipse/che/contents/{+path}","compare_url":"https://api.github.com/repos/eclipse/che/compare/{base}...{head}","merges_url":"https://api.github.com/repos/eclipse/che/merges","archive_url":"https://api.github.com/repos/eclipse/che/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/eclipse/che/downloads","issues_url":"https://api.github.com/repos/eclipse/che/issues{/number}","pulls_url":"https://api.github.com/repos/eclipse/che/pulls{/number}","milestones_url":"https://api.github.com/repos/eclipse/che/milestones{/number}","notifications_url":"https://api.github.com/repos/eclipse/che/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/eclipse/che/labels{/name}","releases_url":"https://api.github.com/repos/eclipse/che/releases{/id}","deployments_url":"https://api.github.com/repos/eclipse/che/deployments","created_at":"2015-03-26T15:31:01Z","updated_at":"2016-12-16T08:22:38Z","pushed_at":"2016-12-16T12:55:22Z","git_url":"git://github.com/eclipse/che.git","ssh_url":"git@github.com:eclipse/che.git","clone_url":"https://github.com/eclipse/che.git","svn_url":"https://github.com/eclipse/che","homepage":"http://eclipse.org/che","size":38135,"stargazers_count":3486,"watchers_count":3486,"language":"Java","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":584,"mirror_url":null,"open_issues_count":391,"forks":584,"open_issues":391,"watchers":3486,"default_branch":"master"}},"base":{"label":"eclipse:master","ref":"master","sha":"7c794edce9cd8a0ae224b2e3b1fee2e462ff5dc0","user":{"login":"eclipse","id":56974,"avatar_url":"https://avatars.githubusercontent.com/u/56974?v=3","gravatar_id":"","url":"https://api.github.com/users/eclipse","html_url":"https://github.com/eclipse","followers_url":"https://api.github.com/users/eclipse/followers","following_url":"https://api.github.com/users/eclipse/following{/other_user}","gists_url":"https://api.github.com/users/eclipse/gists{/gist_id}","starred_url":"https://api.github.com/users/eclipse/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/eclipse/subscriptions","organizations_url":"https://api.github.com/users/eclipse/orgs","repos_url":"https://api.github.com/users/eclipse/repos","events_url":"https://api.github.com/users/eclipse/events{/privacy}","received_events_url":"https://api.github.com/users/eclipse/received_events","type":"Organization","site_admin":false},"repo":{"id":32935745,"name":"che","full_name":"eclipse/che","owner":{"login":"eclipse","id":56974,"avatar_url":"https://avatars.githubusercontent.com/u/56974?v=3","gravatar_id":"","url":"https://api.github.com/users/eclipse","html_url":"https://github.com/eclipse","followers_url":"https://api.github.com/users/eclipse/followers","following_url":"https://api.github.com/users/eclipse/following{/other_user}","gists_url":"https://api.github.com/users/eclipse/gists{/gist_id}","starred_url":"https://api.github.com/users/eclipse/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/eclipse/subscriptions","organizations_url":"https://api.github.com/users/eclipse/orgs","repos_url":"https://api.github.com/users/eclipse/repos","events_url":"https://api.github.com/users/eclipse/events{/privacy}","received_events_url":"https://api.github.com/users/eclipse/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/eclipse/che","description":"Eclipse Che: Next-generation Eclipse IDE.  Open source workspace server and cloud IDE.","fork":false,"url":"https://api.github.com/repos/eclipse/che","forks_url":"https://api.github.com/repos/eclipse/che/forks","keys_url":"https://api.github.com/repos/eclipse/che/keys{/key_id}","collaborators_url":"https://api.github.com/repos/eclipse/che/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/eclipse/che/teams","hooks_url":"https://api.github.com/repos/eclipse/che/hooks","issue_events_url":"https://api.github.com/repos/eclipse/che/issues/events{/number}","events_url":"https://api.github.com/repos/eclipse/che/events","assignees_url":"https://api.github.com/repos/eclipse/che/assignees{/user}","branches_url":"https://api.github.com/repos/eclipse/che/branches{/branch}","tags_url":"https://api.github.com/repos/eclipse/che/tags","blobs_url":"https://api.github.com/repos/eclipse/che/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/eclipse/che/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/eclipse/che/git/refs{/sha}","trees_url":"https://api.github.com/repos/eclipse/che/git/trees{/sha}","statuses_url":"https://api.github.com/repos/eclipse/che/statuses/{sha}","languages_url":"https://api.github.com/repos/eclipse/che/languages","stargazers_url":"https://api.github.com/repos/eclipse/che/stargazers","contributors_url":"https://api.github.com/repos/eclipse/che/contributors","subscribers_url":"https://api.github.com/repos/eclipse/che/subscribers","subscription_url":"https://api.github.com/repos/eclipse/che/subscription","commits_url":"https://api.github.com/repos/eclipse/che/commits{/sha}","git_commits_url":"https://api.github.com/repos/eclipse/che/git/commits{/sha}","comments_url":"https://api.github.com/repos/eclipse/che/comments{/number}","issue_comment_url":"https://api.github.com/repos/eclipse/che/issues/comments{/number}","contents_url":"https://api.github.com/repos/eclipse/che/contents/{+path}","compare_url":"https://api.github.com/repos/eclipse/che/compare/{base}...{head}","merges_url":"https://api.github.com/repos/eclipse/che/merges","archive_url":"https://api.github.com/repos/eclipse/che/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/eclipse/che/downloads","issues_url":"https://api.github.com/repos/eclipse/che/issues{/number}","pulls_url":"https://api.github.com/repos/eclipse/che/pulls{/number}","milestones_url":"https://api.github.com/repos/eclipse/che/milestones{/number}","notifications_url":"https://api.github.com/repos/eclipse/che/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/eclipse/che/labels{/name}","releases_url":"https://api.github.com/repos/eclipse/che/releases{/id}","deployments_url":"https://api.github.com/repos/eclipse/che/deployments","created_at":"2015-03-26T15:31:01Z","updated_at":"2016-12-16T08:22:38Z","pushed_at":"2016-12-16T12:55:22Z","git_url":"git://github.com/eclipse/che.git","ssh_url":"git@github.com:eclipse/che.git","clone_url":"https://github.com/eclipse/che.git","svn_url":"https://github.com/eclipse/che","homepage":"http://eclipse.org/che","size":38135,"stargazers_count":3486,"watchers_count":3486,"language":"Java","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":584,"mirror_url":null,"open_issues_count":391,"forks":584,"open_issues":391,"watchers":3486,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/eclipse/che/pulls/2613"},"html":{"href":"https://github.com/eclipse/che/pull/2613"},"issue":{"href":"https://api.github.com/repos/eclipse/che/issues/2613"},"comments":{"href":"https://api.github.com/repos/eclipse/che/issues/2613/comments"},"review_comments":{"href":"https://api.github.com/repos/eclipse/che/pulls/2613/comments"},"review_comment":{"href":"https://api.github.com/repos/eclipse/che/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/eclipse/che/pulls/2613/commits"},"statuses":{"href":"https://api.github.com/repos/eclipse/che/statuses/e8322f43ff724e431d8cd4ea5930b35cbf2b1d15"}}}}
{"actor":{"display_login":"evoevodin"}}