{"action":"created","comment":{"url":"https://api.github.com/repos/vespa-engine/vespa/pulls/comments/236304492","pull_request_review_id":178351698,"id":236304492,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDIzNjMwNDQ5Mg==","diff_hunk":"@@ -0,0 +1,70 @@\n+// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.\n+package com.yahoo.vespa.flags;\n+\n+import java.util.function.Function;\n+\n+/**\n+ * A FeatureFlag defaults to false (but see {@link #defaultToTrue()}).\n+ *\n+ * @author hakonhall\n+ */\n+public class FeatureFlag implements Flag {\n+    private final boolean defaultValue;\n+    private final FlagId id;\n+    private final FlagSource source;\n+\n+    public static Function<FlagSource, FeatureFlag> createUnbound(String flagId, boolean defaultValue) {\n+        return createUnbound(new FlagId(flagId), defaultValue);\n+    }\n+\n+    public static Function<FlagSource, FeatureFlag> createUnbound(FlagId id, boolean defaultValue) {\n+        return source -> new FeatureFlag(id, defaultValue, source);\n+    }\n+\n+    public FeatureFlag(String flagId, FlagSource source) {\n+        this(new FlagId(flagId), source);\n+    }\n+\n+    public FeatureFlag(FlagId id, FlagSource source) {\n+        this(id, false, source);\n+    }\n+\n+    private FeatureFlag(FlagId id, boolean defaultValue, FlagSource source) {\n+        this.id = id;\n+        this.defaultValue = defaultValue;\n+        this.source = source;\n+    }\n+\n+    public FeatureFlag defaultToTrue() {","path":"flags/src/main/java/com/yahoo/vespa/flags/FeatureFlag.java","position":38,"original_position":38,"commit_id":"c537b48e6bd2d752f2892a9899dd1d36ae58e82b","original_commit_id":"c537b48e6bd2d752f2892a9899dd1d36ae58e82b","user":{"login":"hakonhall","id":19857821,"node_id":"MDQ6VXNlcjE5ODU3ODIx","avatar_url":"https://avatars0.githubusercontent.com/u/19857821?v=4","gravatar_id":"","url":"https://api.github.com/users/hakonhall","html_url":"https://github.com/hakonhall","followers_url":"https://api.github.com/users/hakonhall/followers","following_url":"https://api.github.com/users/hakonhall/following{/other_user}","gists_url":"https://api.github.com/users/hakonhall/gists{/gist_id}","starred_url":"https://api.github.com/users/hakonhall/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/hakonhall/subscriptions","organizations_url":"https://api.github.com/users/hakonhall/orgs","repos_url":"https://api.github.com/users/hakonhall/repos","events_url":"https://api.github.com/users/hakonhall/events{/privacy}","received_events_url":"https://api.github.com/users/hakonhall/received_events","type":"User","site_admin":false},"body":"Fixed","created_at":"2018-11-26T15:39:33Z","updated_at":"2018-11-26T15:39:33Z","html_url":"https://github.com/vespa-engine/vespa/pull/7760#discussion_r236304492","pull_request_url":"https://api.github.com/repos/vespa-engine/vespa/pulls/7760","author_association":"MEMBER","_links":{"self":{"href":"https://api.github.com/repos/vespa-engine/vespa/pulls/comments/236304492"},"html":{"href":"https://github.com/vespa-engine/vespa/pull/7760#discussion_r236304492"},"pull_request":{"href":"https://api.github.com/repos/vespa-engine/vespa/pulls/7760"}},"in_reply_to_id":236283971},"pull_request":{"url":"https://api.github.com/repos/vespa-engine/vespa/pulls/7760","id":233251127,"node_id":"MDExOlB1bGxSZXF1ZXN0MjMzMjUxMTI3","html_url":"https://github.com/vespa-engine/vespa/pull/7760","diff_url":"https://github.com/vespa-engine/vespa/pull/7760.diff","patch_url":"https://github.com/vespa-engine/vespa/pull/7760.patch","issue_url":"https://api.github.com/repos/vespa-engine/vespa/issues/7760","number":7760,"state":"open","locked":false,"title":"Add flags module","user":{"login":"hakonhall","id":19857821,"node_id":"MDQ6VXNlcjE5ODU3ODIx","avatar_url":"https://avatars0.githubusercontent.com/u/19857821?v=4","gravatar_id":"","url":"https://api.github.com/users/hakonhall","html_url":"https://github.com/hakonhall","followers_url":"https://api.github.com/users/hakonhall/followers","following_url":"https://api.github.com/users/hakonhall/following{/other_user}","gists_url":"https://api.github.com/users/hakonhall/gists{/gist_id}","starred_url":"https://api.github.com/users/hakonhall/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/hakonhall/subscriptions","organizations_url":"https://api.github.com/users/hakonhall/orgs","repos_url":"https://api.github.com/users/hakonhall/repos","events_url":"https://api.github.com/users/hakonhall/events{/privacy}","received_events_url":"https://api.github.com/users/hakonhall/received_events","type":"User","site_admin":false},"body":"FileFlagSource reads flags from files in /etc/vespa/flags and is a component\nthat can be injected in host admin, config server, etc. A flag named foo\ncorresponds to filename foo.\n\nIn general a FlagSource manages:\n - Feature flags: A feature is either set (true/enabled) or otherwise false.\n   Touching a file foo means the feature flag foo is set (true).\n - Value flags: Either a String or empty if not set. The String corresponds to\n   the file content.\n\nThe plan is to make the config server another source of flags. A unified\nFlagSource can merge the two sources with some priority and used in e.g. parts\nof node-admin. In other parts one would only have access to the file source.\n\nDefines various flag facades:\n - FeatureFlag: Used to test whether a feature has been enabled or not.\n - IntFlag\n - JacksonFlag: Deserializes JSON to Jackson class, or return default if unset.\n - LongFlag\n - OptionalJacksonFlag: Deserializes JSON to Jackson class, or empty if unset.\n - OptionalStringFlag\n - StringFlag\n\nThis is part of removing some of the last Chef recipes. Some minor tweaks have\nbeen necessary as part of this and are included in this PR (test whether a\nsystemd service exists, task-friendly file deletion, allow capitalized letters\nin YUM package name).","created_at":"2018-11-23T17:03:06Z","updated_at":"2018-11-26T15:39:33Z","closed_at":null,"merged_at":null,"merge_commit_sha":"153ec7f8ff8576bdef39d02f2e7d3ac6b4aaa088","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/vespa-engine/vespa/pulls/7760/commits","review_comments_url":"https://api.github.com/repos/vespa-engine/vespa/pulls/7760/comments","review_comment_url":"https://api.github.com/repos/vespa-engine/vespa/pulls/comments{/number}","comments_url":"https://api.github.com/repos/vespa-engine/vespa/issues/7760/comments","statuses_url":"https://api.github.com/repos/vespa-engine/vespa/statuses/c537b48e6bd2d752f2892a9899dd1d36ae58e82b","head":{"label":"vespa-engine:hakonhall/new-flags-module","ref":"hakonhall/new-flags-module","sha":"c537b48e6bd2d752f2892a9899dd1d36ae58e82b","user":{"login":"vespa-engine","id":29299694,"node_id":"MDEyOk9yZ2FuaXphdGlvbjI5Mjk5Njk0","avatar_url":"https://avatars1.githubusercontent.com/u/29299694?v=4","gravatar_id":"","url":"https://api.github.com/users/vespa-engine","html_url":"https://github.com/vespa-engine","followers_url":"https://api.github.com/users/vespa-engine/followers","following_url":"https://api.github.com/users/vespa-engine/following{/other_user}","gists_url":"https://api.github.com/users/vespa-engine/gists{/gist_id}","starred_url":"https://api.github.com/users/vespa-engine/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/vespa-engine/subscriptions","organizations_url":"https://api.github.com/users/vespa-engine/orgs","repos_url":"https://api.github.com/users/vespa-engine/repos","events_url":"https://api.github.com/users/vespa-engine/events{/privacy}","received_events_url":"https://api.github.com/users/vespa-engine/received_events","type":"Organization","site_admin":false},"repo":{"id":60377070,"node_id":"MDEwOlJlcG9zaXRvcnk2MDM3NzA3MA==","name":"vespa","full_name":"vespa-engine/vespa","private":false,"owner":{"login":"vespa-engine","id":29299694,"node_id":"MDEyOk9yZ2FuaXphdGlvbjI5Mjk5Njk0","avatar_url":"https://avatars1.githubusercontent.com/u/29299694?v=4","gravatar_id":"","url":"https://api.github.com/users/vespa-engine","html_url":"https://github.com/vespa-engine","followers_url":"https://api.github.com/users/vespa-engine/followers","following_url":"https://api.github.com/users/vespa-engine/following{/other_user}","gists_url":"https://api.github.com/users/vespa-engine/gists{/gist_id}","starred_url":"https://api.github.com/users/vespa-engine/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/vespa-engine/subscriptions","organizations_url":"https://api.github.com/users/vespa-engine/orgs","repos_url":"https://api.github.com/users/vespa-engine/repos","events_url":"https://api.github.com/users/vespa-engine/events{/privacy}","received_events_url":"https://api.github.com/users/vespa-engine/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/vespa-engine/vespa","description":"Vespa - the open big data serving engine","fork":false,"url":"https://api.github.com/repos/vespa-engine/vespa","forks_url":"https://api.github.com/repos/vespa-engine/vespa/forks","keys_url":"https://api.github.com/repos/vespa-engine/vespa/keys{/key_id}","collaborators_url":"https://api.github.com/repos/vespa-engine/vespa/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/vespa-engine/vespa/teams","hooks_url":"https://api.github.com/repos/vespa-engine/vespa/hooks","issue_events_url":"https://api.github.com/repos/vespa-engine/vespa/issues/events{/number}","events_url":"https://api.github.com/repos/vespa-engine/vespa/events","assignees_url":"https://api.github.com/repos/vespa-engine/vespa/assignees{/user}","branches_url":"https://api.github.com/repos/vespa-engine/vespa/branches{/branch}","tags_url":"https://api.github.com/repos/vespa-engine/vespa/tags","blobs_url":"https://api.github.com/repos/vespa-engine/vespa/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/vespa-engine/vespa/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/vespa-engine/vespa/git/refs{/sha}","trees_url":"https://api.github.com/repos/vespa-engine/vespa/git/trees{/sha}","statuses_url":"https://api.github.com/repos/vespa-engine/vespa/statuses/{sha}","languages_url":"https://api.github.com/repos/vespa-engine/vespa/languages","stargazers_url":"https://api.github.com/repos/vespa-engine/vespa/stargazers","contributors_url":"https://api.github.com/repos/vespa-engine/vespa/contributors","subscribers_url":"https://api.github.com/repos/vespa-engine/vespa/subscribers","subscription_url":"https://api.github.com/repos/vespa-engine/vespa/subscription","commits_url":"https://api.github.com/repos/vespa-engine/vespa/commits{/sha}","git_commits_url":"https://api.github.com/repos/vespa-engine/vespa/git/commits{/sha}","comments_url":"https://api.github.com/repos/vespa-engine/vespa/comments{/number}","issue_comment_url":"https://api.github.com/repos/vespa-engine/vespa/issues/comments{/number}","contents_url":"https://api.github.com/repos/vespa-engine/vespa/contents/{+path}","compare_url":"https://api.github.com/repos/vespa-engine/vespa/compare/{base}...{head}","merges_url":"https://api.github.com/repos/vespa-engine/vespa/merges","archive_url":"https://api.github.com/repos/vespa-engine/vespa/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/vespa-engine/vespa/downloads","issues_url":"https://api.github.com/repos/vespa-engine/vespa/issues{/number}","pulls_url":"https://api.github.com/repos/vespa-engine/vespa/pulls{/number}","milestones_url":"https://api.github.com/repos/vespa-engine/vespa/milestones{/number}","notifications_url":"https://api.github.com/repos/vespa-engine/vespa/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/vespa-engine/vespa/labels{/name}","releases_url":"https://api.github.com/repos/vespa-engine/vespa/releases{/id}","deployments_url":"https://api.github.com/repos/vespa-engine/vespa/deployments","created_at":"2016-06-03T20:54:20Z","updated_at":"2018-11-26T15:25:59Z","pushed_at":"2018-11-26T15:26:03Z","git_url":"git://github.com/vespa-engine/vespa.git","ssh_url":"git@github.com:vespa-engine/vespa.git","clone_url":"https://github.com/vespa-engine/vespa.git","svn_url":"https://github.com/vespa-engine/vespa","homepage":"http://vespa.ai/","size":82942,"stargazers_count":2645,"watchers_count":2645,"language":"Java","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":318,"mirror_url":null,"archived":false,"open_issues_count":60,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0","node_id":"MDc6TGljZW5zZTI="},"forks":318,"open_issues":60,"watchers":2645,"default_branch":"master"}},"base":{"label":"vespa-engine:master","ref":"master","sha":"4ef1c3ab2a6617f7740d36300bf4e129a41dc8d3","user":{"login":"vespa-engine","id":29299694,"node_id":"MDEyOk9yZ2FuaXphdGlvbjI5Mjk5Njk0","avatar_url":"https://avatars1.githubusercontent.com/u/29299694?v=4","gravatar_id":"","url":"https://api.github.com/users/vespa-engine","html_url":"https://github.com/vespa-engine","followers_url":"https://api.github.com/users/vespa-engine/followers","following_url":"https://api.github.com/users/vespa-engine/following{/other_user}","gists_url":"https://api.github.com/users/vespa-engine/gists{/gist_id}","starred_url":"https://api.github.com/users/vespa-engine/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/vespa-engine/subscriptions","organizations_url":"https://api.github.com/users/vespa-engine/orgs","repos_url":"https://api.github.com/users/vespa-engine/repos","events_url":"https://api.github.com/users/vespa-engine/events{/privacy}","received_events_url":"https://api.github.com/users/vespa-engine/received_events","type":"Organization","site_admin":false},"repo":{"id":60377070,"node_id":"MDEwOlJlcG9zaXRvcnk2MDM3NzA3MA==","name":"vespa","full_name":"vespa-engine/vespa","private":false,"owner":{"login":"vespa-engine","id":29299694,"node_id":"MDEyOk9yZ2FuaXphdGlvbjI5Mjk5Njk0","avatar_url":"https://avatars1.githubusercontent.com/u/29299694?v=4","gravatar_id":"","url":"https://api.github.com/users/vespa-engine","html_url":"https://github.com/vespa-engine","followers_url":"https://api.github.com/users/vespa-engine/followers","following_url":"https://api.github.com/users/vespa-engine/following{/other_user}","gists_url":"https://api.github.com/users/vespa-engine/gists{/gist_id}","starred_url":"https://api.github.com/users/vespa-engine/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/vespa-engine/subscriptions","organizations_url":"https://api.github.com/users/vespa-engine/orgs","repos_url":"https://api.github.com/users/vespa-engine/repos","events_url":"https://api.github.com/users/vespa-engine/events{/privacy}","received_events_url":"https://api.github.com/users/vespa-engine/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/vespa-engine/vespa","description":"Vespa - the open big data serving engine","fork":false,"url":"https://api.github.com/repos/vespa-engine/vespa","forks_url":"https://api.github.com/repos/vespa-engine/vespa/forks","keys_url":"https://api.github.com/repos/vespa-engine/vespa/keys{/key_id}","collaborators_url":"https://api.github.com/repos/vespa-engine/vespa/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/vespa-engine/vespa/teams","hooks_url":"https://api.github.com/repos/vespa-engine/vespa/hooks","issue_events_url":"https://api.github.com/repos/vespa-engine/vespa/issues/events{/number}","events_url":"https://api.github.com/repos/vespa-engine/vespa/events","assignees_url":"https://api.github.com/repos/vespa-engine/vespa/assignees{/user}","branches_url":"https://api.github.com/repos/vespa-engine/vespa/branches{/branch}","tags_url":"https://api.github.com/repos/vespa-engine/vespa/tags","blobs_url":"https://api.github.com/repos/vespa-engine/vespa/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/vespa-engine/vespa/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/vespa-engine/vespa/git/refs{/sha}","trees_url":"https://api.github.com/repos/vespa-engine/vespa/git/trees{/sha}","statuses_url":"https://api.github.com/repos/vespa-engine/vespa/statuses/{sha}","languages_url":"https://api.github.com/repos/vespa-engine/vespa/languages","stargazers_url":"https://api.github.com/repos/vespa-engine/vespa/stargazers","contributors_url":"https://api.github.com/repos/vespa-engine/vespa/contributors","subscribers_url":"https://api.github.com/repos/vespa-engine/vespa/subscribers","subscription_url":"https://api.github.com/repos/vespa-engine/vespa/subscription","commits_url":"https://api.github.com/repos/vespa-engine/vespa/commits{/sha}","git_commits_url":"https://api.github.com/repos/vespa-engine/vespa/git/commits{/sha}","comments_url":"https://api.github.com/repos/vespa-engine/vespa/comments{/number}","issue_comment_url":"https://api.github.com/repos/vespa-engine/vespa/issues/comments{/number}","contents_url":"https://api.github.com/repos/vespa-engine/vespa/contents/{+path}","compare_url":"https://api.github.com/repos/vespa-engine/vespa/compare/{base}...{head}","merges_url":"https://api.github.com/repos/vespa-engine/vespa/merges","archive_url":"https://api.github.com/repos/vespa-engine/vespa/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/vespa-engine/vespa/downloads","issues_url":"https://api.github.com/repos/vespa-engine/vespa/issues{/number}","pulls_url":"https://api.github.com/repos/vespa-engine/vespa/pulls{/number}","milestones_url":"https://api.github.com/repos/vespa-engine/vespa/milestones{/number}","notifications_url":"https://api.github.com/repos/vespa-engine/vespa/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/vespa-engine/vespa/labels{/name}","releases_url":"https://api.github.com/repos/vespa-engine/vespa/releases{/id}","deployments_url":"https://api.github.com/repos/vespa-engine/vespa/deployments","created_at":"2016-06-03T20:54:20Z","updated_at":"2018-11-26T15:25:59Z","pushed_at":"2018-11-26T15:26:03Z","git_url":"git://github.com/vespa-engine/vespa.git","ssh_url":"git@github.com:vespa-engine/vespa.git","clone_url":"https://github.com/vespa-engine/vespa.git","svn_url":"https://github.com/vespa-engine/vespa","homepage":"http://vespa.ai/","size":82942,"stargazers_count":2645,"watchers_count":2645,"language":"Java","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":318,"mirror_url":null,"archived":false,"open_issues_count":60,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0","node_id":"MDc6TGljZW5zZTI="},"forks":318,"open_issues":60,"watchers":2645,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/vespa-engine/vespa/pulls/7760"},"html":{"href":"https://github.com/vespa-engine/vespa/pull/7760"},"issue":{"href":"https://api.github.com/repos/vespa-engine/vespa/issues/7760"},"comments":{"href":"https://api.github.com/repos/vespa-engine/vespa/issues/7760/comments"},"review_comments":{"href":"https://api.github.com/repos/vespa-engine/vespa/pulls/7760/comments"},"review_comment":{"href":"https://api.github.com/repos/vespa-engine/vespa/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/vespa-engine/vespa/pulls/7760/commits"},"statuses":{"href":"https://api.github.com/repos/vespa-engine/vespa/statuses/c537b48e6bd2d752f2892a9899dd1d36ae58e82b"}},"author_association":"MEMBER"}}
{"actor":{"display_login":"hakonhall"}}