{"action":"created","comment":{"url":"https://api.github.com/repos/apache/beam/pulls/comments/100634192","pull_request_review_id":21352575,"id":100634192,"diff_hunk":"@@ -0,0 +1,681 @@\n+/*\n+ * Licensed to the Apache Software Foundation (ASF) under one\n+ * or more contributor license agreements.  See the NOTICE file\n+ * distributed with this work for additional information\n+ * regarding copyright ownership.  The ASF licenses this file\n+ * to you under the Apache License, Version 2.0 (the\n+ * \"License\"); you may not use this file except in compliance\n+ * with the License.  You may obtain a copy of the License at\n+ *\n+ *     http://www.apache.org/licenses/LICENSE-2.0\n+ *\n+ * Unless required by applicable law or agreed to in writing, software\n+ * distributed under the License is distributed on an \"AS IS\" BASIS,\n+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n+ * See the License for the specific language governing permissions and\n+ * limitations under the License.\n+ */\n+package org.apache.beam.sdk.io.hbase;\n+\n+import static com.google.common.base.Preconditions.checkArgument;\n+import static com.google.common.base.Preconditions.checkNotNull;\n+\n+import com.google.protobuf.ByteString;\n+\n+import java.io.IOException;\n+import java.util.ArrayList;\n+import java.util.Collection;\n+import java.util.Collections;\n+import java.util.Iterator;\n+import java.util.List;\n+import java.util.NoSuchElementException;\n+import java.util.Set;\n+import java.util.TreeSet;\n+import javax.annotation.Nullable;\n+\n+import org.apache.beam.sdk.annotations.Experimental;\n+import org.apache.beam.sdk.coders.ByteStringCoder;\n+import org.apache.beam.sdk.coders.Coder;\n+import org.apache.beam.sdk.coders.IterableCoder;\n+import org.apache.beam.sdk.coders.KvCoder;\n+import org.apache.beam.sdk.io.BoundedSource;\n+import org.apache.beam.sdk.io.hbase.coders.HBaseMutationCoder;\n+import org.apache.beam.sdk.io.hbase.coders.HBaseResultCoder;\n+import org.apache.beam.sdk.io.hbase.coders.SerializableConfiguration;\n+import org.apache.beam.sdk.io.hbase.coders.SerializableScan;\n+import org.apache.beam.sdk.io.range.ByteKeyRange;\n+import org.apache.beam.sdk.options.PipelineOptions;\n+import org.apache.beam.sdk.transforms.DoFn;\n+import org.apache.beam.sdk.transforms.PTransform;\n+import org.apache.beam.sdk.transforms.ParDo;\n+import org.apache.beam.sdk.transforms.display.DisplayData;\n+import org.apache.beam.sdk.values.KV;\n+import org.apache.beam.sdk.values.PBegin;\n+import org.apache.beam.sdk.values.PCollection;\n+import org.apache.beam.sdk.values.PDone;\n+import org.apache.hadoop.conf.Configuration;\n+\n+import org.apache.hadoop.hbase.ClusterStatus;\n+import org.apache.hadoop.hbase.HRegionLocation;\n+import org.apache.hadoop.hbase.RegionLoad;\n+import org.apache.hadoop.hbase.ServerLoad;\n+import org.apache.hadoop.hbase.ServerName;\n+import org.apache.hadoop.hbase.TableName;\n+import org.apache.hadoop.hbase.client.Admin;\n+import org.apache.hadoop.hbase.client.BufferedMutator;\n+import org.apache.hadoop.hbase.client.BufferedMutatorParams;\n+import org.apache.hadoop.hbase.client.Connection;\n+import org.apache.hadoop.hbase.client.ConnectionFactory;\n+import org.apache.hadoop.hbase.client.Mutation;\n+import org.apache.hadoop.hbase.client.RegionLocator;\n+import org.apache.hadoop.hbase.client.Result;\n+import org.apache.hadoop.hbase.client.ResultScanner;\n+import org.apache.hadoop.hbase.client.Scan;\n+import org.apache.hadoop.hbase.client.Table;\n+import org.apache.hadoop.hbase.filter.Filter;\n+import org.apache.hadoop.hbase.util.Bytes;\n+import org.slf4j.Logger;\n+import org.slf4j.LoggerFactory;\n+\n+/**\n+ * A bounded source and sink for HBase.\n+ *\n+ * <p>For more information, see the online documentation at\n+ * <a href=\"https://hbase.apache.org/\">HBase</a>.\n+ *\n+ * <h3>Reading from HBase</h3>\n+ *\n+ * <p>The HBase source returns a set of rows from a single table, returning a\n+ * {@code PCollection<Result>}.\n+ *\n+ * <p>To configure a HBase source, you must supply a table id and a {@link Configuration}\n+ * to identify the HBase instance. By default, {@link HBaseIO.Read} will read all rows in the\n+ * table. The row range to be read can optionally be restricted using with a {@link Scan} object\n+ * or using the {@link HBaseIO.Read#withKeyRange}, and a {@link Filter} using\n+ * {@link HBaseIO.Read#withFilter}, for example:\n+ *\n+ * <pre>{@code\n+ * // Scan the entire table.\n+ * p.apply(\"read\",\n+ *     HBaseIO.read()\n+ *         .withConfiguration(configuration)\n+ *         .withTableId(\"table\"));\n+ *\n+ * // Filter data using a HBaseIO Scan\n+ * Scan scan = ...\n+ * p.apply(\"read\",\n+ *     HBaseIO.read()\n+ *         .withConfiguration(configuration)\n+ *         .withTableId(\"table\"))\n+ *         .withScan(scan));\n+ *\n+ * // Scan a prefix of the table.\n+ * ByteKeyRange keyRange = ...;\n+ * p.apply(\"read\",\n+ *     HBaseIO.read()\n+ *         .withConfiguration(configuration)\n+ *         .withTableId(\"table\")\n+ *         .withKeyRange(keyRange));\n+ *\n+ * // Scan a subset of rows that match the specified row filter.\n+ * p.apply(\"filtered read\",\n+ *     HBaseIO.read()\n+ *         .withConfiguration(configuration)\n+ *         .withTableId(\"table\")\n+ *         .withFilter(filter));\n+ * }</pre>\n+ *\n+ * <h3>Writing to HBase</h3>\n+ *\n+ * <p>The HBase sink executes a set of row mutations on a single table. It takes as input a\n+ * {@link PCollection PCollection&lt;KV&lt;ByteString, Iterable&lt;Mutation&gt;&gt;&gt;}, where the\n+ * {@link ByteString} is the key of the row being mutated, and each {@link Mutation} represents an\n+ * idempotent transformation to that row.\n+ *\n+ * <p>To configure a HBase sink, you must supply a table id and a {@link Configuration}\n+ * to identify the HBase instance, for example:\n+ *\n+ * <pre>{@code\n+ * Configuration configuration = ...\n+ * PCollection<KV<ByteString, Iterable<Mutation>>> data = ...;\n+ * data.setCoder(HBaseIO.WRITE_CODER)\n+ *\n+ * data.apply(\"write\",\n+ *     HBaseIO.write()\n+ *         .withConfiguration(configuration)\n+ *         .withTableId(\"table\"));\n+ * }</pre>\n+ *\n+ * <h3>Experimental</h3>\n+ *\n+ * <p>The design of the API for HBaseIO is currently related to the BigTableIO one,\n+ * it can evolve or be different in some aspects, but the idea is that users can easily migrate\n+ * from one to the other</p>.\n+ */\n+@Experimental\n+public class HBaseIO {\n+    private static final Logger LOG = LoggerFactory.getLogger(HBaseIO.class);\n+\n+    /** Disallow construction of utility class. */\n+    private HBaseIO() {\n+    }\n+\n+    /**\n+     * Creates an uninitialized {@link HBaseIO.Read}. Before use, the {@code Read} must be\n+     * initialized with a\n+     * {@link HBaseIO.Read#withConfiguration(Configuration)} that specifies\n+     * the HBase instance, and a {@link HBaseIO.Read#withTableId tableId} that\n+     * specifies which table to read. A {@link Filter} may also optionally be specified using\n+     * {@link HBaseIO.Read#withFilter}.\n+     */\n+    @Experimental\n+    public static Read read() {\n+        return new Read(null, \"\", new SerializableScan(new Scan()));\n+    }\n+\n+    /**\n+     * A {@link PTransform} that reads from HBase. See the class-level Javadoc on\n+     * {@link HBaseIO} for more information.\n+     *\n+     * @see HBaseIO\n+     */\n+    public static class Read extends PTransform<PBegin, PCollection<Result>> {\n+        /**\n+         * Returns a new {@link HBaseIO.Read} that will read from the HBase instance\n+         * indicated by the given configuration.\n+         */\n+        public Read withConfiguration(Configuration configuration) {\n+            checkNotNull(configuration, \"conf\");\n+            return new Read(new SerializableConfiguration(configuration),\n+                    tableId, serializableScan);\n+        }\n+\n+        /**\n+         * Returns a new {@link HBaseIO.Read} that will read from the specified table.\n+         *\n+         * <p>Does not modify this object.\n+         */\n+        public Read withTableId(String tableId) {\n+            checkNotNull(tableId, \"tableId\");\n+            return new Read(serializableConfiguration, tableId, serializableScan);\n+        }\n+\n+        /**\n+         * Returns a new {@link HBaseIO.Read} that will filter the rows read from HBase\n+         * using the given scan.\n+         *\n+         * <p>Does not modify this object.\n+         */\n+        public Read withScan(Scan scan) {\n+            checkNotNull(scan, \"scan\");\n+            return new Read(serializableConfiguration, tableId, new SerializableScan(scan));\n+        }\n+\n+        /**\n+         * Returns a new {@link HBaseIO.Read} that will filter the rows read from HBase\n+         * using the given row filter.\n+         *\n+         * <p>Does not modify this object.\n+         */\n+        public Read withFilter(Filter filter) {\n+            checkNotNull(filter, \"filter\");\n+            return withScan(serializableScan.getScan().setFilter(filter));\n+        }\n+\n+        /**\n+         * Returns a new {@link HBaseIO.Read} that will read only rows in the specified range.\n+         *\n+         * <p>Does not modify this object.\n+         */\n+        public Read withKeyRange(ByteKeyRange keyRange) {\n+            checkNotNull(keyRange, \"keyRange\");\n+            byte[] startRow = keyRange.getStartKey().getBytes();\n+            byte[] stopRow = keyRange.getEndKey().getBytes();\n+            return withKeyRange(startRow, stopRow);\n+        }\n+\n+        /**\n+         * Returns a new {@link HBaseIO.Read} that will read only rows in the specified range.\n+         *\n+         * <p>Does not modify this object.\n+         */\n+        public Read withKeyRange(byte[] startRow, byte[] stopRow) {\n+            checkNotNull(startRow, \"startRow\");\n+            checkNotNull(stopRow, \"stopRow\");\n+            return withScan(serializableScan.getScan().setStartRow(startRow).setStopRow(stopRow));\n+        }\n+\n+        private Read(SerializableConfiguration serializableConfiguration, String tableId,\n+                     SerializableScan serializableScan) {\n+            this.serializableConfiguration = serializableConfiguration;\n+            this.tableId = tableId;\n+            this.serializableScan = serializableScan;\n+        }\n+\n+        @Override\n+        public PCollection<Result> expand(PBegin input) {\n+            HBaseSource source = new HBaseSource(this, null);\n+            return input.getPipeline().apply(org.apache.beam.sdk.io.Read.from(source));\n+        }\n+\n+        @Override\n+        public void validate(PBegin input) {\n+            checkArgument(serializableConfiguration != null,\n+                    \"Configuration not provided\");\n+            checkArgument(!tableId.isEmpty(), \"Table ID not specified\");\n+            try {\n+                Connection connection =\n+                        ConnectionFactory.createConnection(\n+                                serializableConfiguration.getConfiguration());\n+                Admin admin = connection.getAdmin();\n+                checkArgument(admin.tableExists(TableName.valueOf(tableId)),\n+                        \"Table %s does not exist\", tableId);","path":"sdks/java/io/hbase/src/main/java/org/apache/beam/sdk/io/hbase/HBaseIO.java","position":272,"original_position":272,"commit_id":"8c1d79fa6c647a8c39fcaf64512ebfcd16cf5edb","original_commit_id":"2505d0b5a95d91479c33f6c4e42f2baf4208714d","user":{"login":"iemejia","id":79476,"avatar_url":"https://avatars.githubusercontent.com/u/79476?v=3","gravatar_id":"","url":"https://api.github.com/users/iemejia","html_url":"https://github.com/iemejia","followers_url":"https://api.github.com/users/iemejia/followers","following_url":"https://api.github.com/users/iemejia/following{/other_user}","gists_url":"https://api.github.com/users/iemejia/gists{/gist_id}","starred_url":"https://api.github.com/users/iemejia/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/iemejia/subscriptions","organizations_url":"https://api.github.com/users/iemejia/orgs","repos_url":"https://api.github.com/users/iemejia/repos","events_url":"https://api.github.com/users/iemejia/events{/privacy}","received_events_url":"https://api.github.com/users/iemejia/received_events","type":"User","site_admin":false},"body":"ok","created_at":"2017-02-10T22:06:48Z","updated_at":"2017-02-10T22:06:48Z","html_url":"https://github.com/apache/beam/pull/1961#discussion_r100634192","pull_request_url":"https://api.github.com/repos/apache/beam/pulls/1961","_links":{"self":{"href":"https://api.github.com/repos/apache/beam/pulls/comments/100634192"},"html":{"href":"https://github.com/apache/beam/pull/1961#discussion_r100634192"},"pull_request":{"href":"https://api.github.com/repos/apache/beam/pulls/1961"}}},"pull_request":{"url":"https://api.github.com/repos/apache/beam/pulls/1961","id":105453241,"html_url":"https://github.com/apache/beam/pull/1961","diff_url":"https://github.com/apache/beam/pull/1961.diff","patch_url":"https://github.com/apache/beam/pull/1961.patch","issue_url":"https://api.github.com/repos/apache/beam/issues/1961","number":1961,"state":"open","locked":false,"title":"[BEAM-1157] Add HBaseIO","user":{"login":"iemejia","id":79476,"avatar_url":"https://avatars.githubusercontent.com/u/79476?v=3","gravatar_id":"","url":"https://api.github.com/users/iemejia","html_url":"https://github.com/iemejia","followers_url":"https://api.github.com/users/iemejia/followers","following_url":"https://api.github.com/users/iemejia/following{/other_user}","gists_url":"https://api.github.com/users/iemejia/gists{/gist_id}","starred_url":"https://api.github.com/users/iemejia/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/iemejia/subscriptions","organizations_url":"https://api.github.com/users/iemejia/orgs","repos_url":"https://api.github.com/users/iemejia/repos","events_url":"https://api.github.com/users/iemejia/events{/privacy}","received_events_url":"https://api.github.com/users/iemejia/received_events","type":"User","site_admin":false},"body":"Be sure to do all of the following to help us incorporate your contribution\r\nquickly and easily:\r\n\r\n - [X] Make sure the PR title is formatted like:\r\n   `[BEAM-<Jira issue #>] Description of pull request`\r\n - [X] Make sure tests pass via `mvn clean verify`. (Even better, enable\r\n       Travis-CI on your fork and ensure the whole test matrix passes).\r\n - [X] Replace `<Jira issue #>` in the title with the actual Jira issue\r\n       number, if there is one.\r\n - [ ] If this contribution is large, please file an Apache\r\n       [Individual Contributor License Agreement](https://www.apache.org/licenses/icla.txt).\r\n\r\n---\r\n","created_at":"2017-02-09T15:46:01Z","updated_at":"2017-02-10T22:06:48Z","closed_at":null,"merged_at":null,"merge_commit_sha":"461b02572014652c563a950af24be6be7b2ff48d","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/apache/beam/pulls/1961/commits","review_comments_url":"https://api.github.com/repos/apache/beam/pulls/1961/comments","review_comment_url":"https://api.github.com/repos/apache/beam/pulls/comments{/number}","comments_url":"https://api.github.com/repos/apache/beam/issues/1961/comments","statuses_url":"https://api.github.com/repos/apache/beam/statuses/8c1d79fa6c647a8c39fcaf64512ebfcd16cf5edb","head":{"label":"iemejia:BEAM-1157-HBaseIO","ref":"BEAM-1157-HBaseIO","sha":"8c1d79fa6c647a8c39fcaf64512ebfcd16cf5edb","user":{"login":"iemejia","id":79476,"avatar_url":"https://avatars.githubusercontent.com/u/79476?v=3","gravatar_id":"","url":"https://api.github.com/users/iemejia","html_url":"https://github.com/iemejia","followers_url":"https://api.github.com/users/iemejia/followers","following_url":"https://api.github.com/users/iemejia/following{/other_user}","gists_url":"https://api.github.com/users/iemejia/gists{/gist_id}","starred_url":"https://api.github.com/users/iemejia/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/iemejia/subscriptions","organizations_url":"https://api.github.com/users/iemejia/orgs","repos_url":"https://api.github.com/users/iemejia/repos","events_url":"https://api.github.com/users/iemejia/events{/privacy}","received_events_url":"https://api.github.com/users/iemejia/received_events","type":"User","site_admin":false},"repo":{"id":58313008,"name":"beam","full_name":"iemejia/beam","owner":{"login":"iemejia","id":79476,"avatar_url":"https://avatars.githubusercontent.com/u/79476?v=3","gravatar_id":"","url":"https://api.github.com/users/iemejia","html_url":"https://github.com/iemejia","followers_url":"https://api.github.com/users/iemejia/followers","following_url":"https://api.github.com/users/iemejia/following{/other_user}","gists_url":"https://api.github.com/users/iemejia/gists{/gist_id}","starred_url":"https://api.github.com/users/iemejia/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/iemejia/subscriptions","organizations_url":"https://api.github.com/users/iemejia/orgs","repos_url":"https://api.github.com/users/iemejia/repos","events_url":"https://api.github.com/users/iemejia/events{/privacy}","received_events_url":"https://api.github.com/users/iemejia/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/iemejia/beam","description":"Mirror of Apache Beam (Incubating)","fork":true,"url":"https://api.github.com/repos/iemejia/beam","forks_url":"https://api.github.com/repos/iemejia/beam/forks","keys_url":"https://api.github.com/repos/iemejia/beam/keys{/key_id}","collaborators_url":"https://api.github.com/repos/iemejia/beam/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/iemejia/beam/teams","hooks_url":"https://api.github.com/repos/iemejia/beam/hooks","issue_events_url":"https://api.github.com/repos/iemejia/beam/issues/events{/number}","events_url":"https://api.github.com/repos/iemejia/beam/events","assignees_url":"https://api.github.com/repos/iemejia/beam/assignees{/user}","branches_url":"https://api.github.com/repos/iemejia/beam/branches{/branch}","tags_url":"https://api.github.com/repos/iemejia/beam/tags","blobs_url":"https://api.github.com/repos/iemejia/beam/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/iemejia/beam/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/iemejia/beam/git/refs{/sha}","trees_url":"https://api.github.com/repos/iemejia/beam/git/trees{/sha}","statuses_url":"https://api.github.com/repos/iemejia/beam/statuses/{sha}","languages_url":"https://api.github.com/repos/iemejia/beam/languages","stargazers_url":"https://api.github.com/repos/iemejia/beam/stargazers","contributors_url":"https://api.github.com/repos/iemejia/beam/contributors","subscribers_url":"https://api.github.com/repos/iemejia/beam/subscribers","subscription_url":"https://api.github.com/repos/iemejia/beam/subscription","commits_url":"https://api.github.com/repos/iemejia/beam/commits{/sha}","git_commits_url":"https://api.github.com/repos/iemejia/beam/git/commits{/sha}","comments_url":"https://api.github.com/repos/iemejia/beam/comments{/number}","issue_comment_url":"https://api.github.com/repos/iemejia/beam/issues/comments{/number}","contents_url":"https://api.github.com/repos/iemejia/beam/contents/{+path}","compare_url":"https://api.github.com/repos/iemejia/beam/compare/{base}...{head}","merges_url":"https://api.github.com/repos/iemejia/beam/merges","archive_url":"https://api.github.com/repos/iemejia/beam/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/iemejia/beam/downloads","issues_url":"https://api.github.com/repos/iemejia/beam/issues{/number}","pulls_url":"https://api.github.com/repos/iemejia/beam/pulls{/number}","milestones_url":"https://api.github.com/repos/iemejia/beam/milestones{/number}","notifications_url":"https://api.github.com/repos/iemejia/beam/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/iemejia/beam/labels{/name}","releases_url":"https://api.github.com/repos/iemejia/beam/releases{/id}","deployments_url":"https://api.github.com/repos/iemejia/beam/deployments","created_at":"2016-05-08T13:21:00Z","updated_at":"2016-12-28T09:58:55Z","pushed_at":"2017-02-10T22:03:58Z","git_url":"git://github.com/iemejia/beam.git","ssh_url":"git@github.com:iemejia/beam.git","clone_url":"https://github.com/iemejia/beam.git","svn_url":"https://github.com/iemejia/beam","homepage":null,"size":27519,"stargazers_count":0,"watchers_count":0,"language":"Java","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":1,"mirror_url":null,"open_issues_count":0,"forks":1,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"apache:master","ref":"master","sha":"caaa64dc6c3f92be7a53349e9d58a5630db855a5","user":{"login":"apache","id":47359,"avatar_url":"https://avatars.githubusercontent.com/u/47359?v=3","gravatar_id":"","url":"https://api.github.com/users/apache","html_url":"https://github.com/apache","followers_url":"https://api.github.com/users/apache/followers","following_url":"https://api.github.com/users/apache/following{/other_user}","gists_url":"https://api.github.com/users/apache/gists{/gist_id}","starred_url":"https://api.github.com/users/apache/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/apache/subscriptions","organizations_url":"https://api.github.com/users/apache/orgs","repos_url":"https://api.github.com/users/apache/repos","events_url":"https://api.github.com/users/apache/events{/privacy}","received_events_url":"https://api.github.com/users/apache/received_events","type":"Organization","site_admin":false},"repo":{"id":50904245,"name":"beam","full_name":"apache/beam","owner":{"login":"apache","id":47359,"avatar_url":"https://avatars.githubusercontent.com/u/47359?v=3","gravatar_id":"","url":"https://api.github.com/users/apache","html_url":"https://github.com/apache","followers_url":"https://api.github.com/users/apache/followers","following_url":"https://api.github.com/users/apache/following{/other_user}","gists_url":"https://api.github.com/users/apache/gists{/gist_id}","starred_url":"https://api.github.com/users/apache/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/apache/subscriptions","organizations_url":"https://api.github.com/users/apache/orgs","repos_url":"https://api.github.com/users/apache/repos","events_url":"https://api.github.com/users/apache/events{/privacy}","received_events_url":"https://api.github.com/users/apache/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/apache/beam","description":"Mirror of Apache Beam","fork":false,"url":"https://api.github.com/repos/apache/beam","forks_url":"https://api.github.com/repos/apache/beam/forks","keys_url":"https://api.github.com/repos/apache/beam/keys{/key_id}","collaborators_url":"https://api.github.com/repos/apache/beam/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/apache/beam/teams","hooks_url":"https://api.github.com/repos/apache/beam/hooks","issue_events_url":"https://api.github.com/repos/apache/beam/issues/events{/number}","events_url":"https://api.github.com/repos/apache/beam/events","assignees_url":"https://api.github.com/repos/apache/beam/assignees{/user}","branches_url":"https://api.github.com/repos/apache/beam/branches{/branch}","tags_url":"https://api.github.com/repos/apache/beam/tags","blobs_url":"https://api.github.com/repos/apache/beam/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/apache/beam/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/apache/beam/git/refs{/sha}","trees_url":"https://api.github.com/repos/apache/beam/git/trees{/sha}","statuses_url":"https://api.github.com/repos/apache/beam/statuses/{sha}","languages_url":"https://api.github.com/repos/apache/beam/languages","stargazers_url":"https://api.github.com/repos/apache/beam/stargazers","contributors_url":"https://api.github.com/repos/apache/beam/contributors","subscribers_url":"https://api.github.com/repos/apache/beam/subscribers","subscription_url":"https://api.github.com/repos/apache/beam/subscription","commits_url":"https://api.github.com/repos/apache/beam/commits{/sha}","git_commits_url":"https://api.github.com/repos/apache/beam/git/commits{/sha}","comments_url":"https://api.github.com/repos/apache/beam/comments{/number}","issue_comment_url":"https://api.github.com/repos/apache/beam/issues/comments{/number}","contents_url":"https://api.github.com/repos/apache/beam/contents/{+path}","compare_url":"https://api.github.com/repos/apache/beam/compare/{base}...{head}","merges_url":"https://api.github.com/repos/apache/beam/merges","archive_url":"https://api.github.com/repos/apache/beam/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/apache/beam/downloads","issues_url":"https://api.github.com/repos/apache/beam/issues{/number}","pulls_url":"https://api.github.com/repos/apache/beam/pulls{/number}","milestones_url":"https://api.github.com/repos/apache/beam/milestones{/number}","notifications_url":"https://api.github.com/repos/apache/beam/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/apache/beam/labels{/name}","releases_url":"https://api.github.com/repos/apache/beam/releases{/id}","deployments_url":"https://api.github.com/repos/apache/beam/deployments","created_at":"2016-02-02T08:00:06Z","updated_at":"2017-02-10T15:31:56Z","pushed_at":"2017-02-10T21:59:24Z","git_url":"git://github.com/apache/beam.git","ssh_url":"git@github.com:apache/beam.git","clone_url":"https://github.com/apache/beam.git","svn_url":"https://github.com/apache/beam","homepage":"","size":27593,"stargazers_count":850,"watchers_count":850,"language":"Java","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":445,"mirror_url":"git://git.apache.org/beam.git","open_issues_count":57,"forks":445,"open_issues":57,"watchers":850,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/apache/beam/pulls/1961"},"html":{"href":"https://github.com/apache/beam/pull/1961"},"issue":{"href":"https://api.github.com/repos/apache/beam/issues/1961"},"comments":{"href":"https://api.github.com/repos/apache/beam/issues/1961/comments"},"review_comments":{"href":"https://api.github.com/repos/apache/beam/pulls/1961/comments"},"review_comment":{"href":"https://api.github.com/repos/apache/beam/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/apache/beam/pulls/1961/commits"},"statuses":{"href":"https://api.github.com/repos/apache/beam/statuses/8c1d79fa6c647a8c39fcaf64512ebfcd16cf5edb"}}}}
{"actor":{"display_login":"iemejia"}}