{"action":"created","comment":{"url":"https://api.github.com/repos/druid-io/druid/pulls/comments/43274313","id":43274313,"diff_hunk":"@@ -0,0 +1,286 @@\n+/*\n+ * Licensed to Metamarkets Group Inc. (Metamarkets) under one\n+ * or more contributor license agreements.  See the NOTICE file\n+ * distributed with this work for additional information\n+ * regarding copyright ownership.  Metamarkets 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,\n+ * software distributed under the License is distributed on an\n+ * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n+ * KIND, either express or implied.  See the License for the\n+ * specific language governing permissions and limitations\n+ * under the License.\n+ */\n+\n+package io.druid.segment.loading;\n+\n+import com.fasterxml.jackson.databind.ObjectMapper;\n+import com.fasterxml.jackson.databind.jsontype.NamedType;\n+import com.google.common.collect.ImmutableList;\n+import com.google.common.collect.ImmutableMap;\n+import io.druid.jackson.DefaultObjectMapper;\n+import io.druid.storage.hdfs.HdfsDataSegmentFinder;\n+import io.druid.timeline.DataSegment;\n+import io.druid.timeline.partition.NumberedShardSpec;\n+import org.apache.commons.io.IOUtils;\n+import org.apache.hadoop.conf.Configuration;\n+import org.apache.hadoop.fs.FSDataInputStream;\n+import org.apache.hadoop.fs.FSDataOutputStream;\n+import org.apache.hadoop.fs.FileSystem;\n+import org.apache.hadoop.fs.Path;\n+import org.apache.hadoop.hdfs.MiniDFSCluster;\n+import org.joda.time.Interval;\n+import org.junit.AfterClass;\n+import org.junit.Assert;\n+import org.junit.Before;\n+import org.junit.BeforeClass;\n+import org.junit.Test;\n+\n+import java.io.File;\n+import java.io.IOException;\n+import java.net.URI;\n+import java.util.Map;\n+import java.util.Set;\n+\n+/**\n+ */\n+public class HdfsDataSegmentFinderTest\n+{\n+\n+  private static final ObjectMapper mapper = new DefaultObjectMapper();\n+  private static final String DESCRIPTOR_JSON = \"descriptor.json\";\n+  private static final String INDEX_ZIP = \"index.zip\";\n+  private static final DataSegment SEGMENT_1 = DataSegment.builder()\n+                                                          .dataSource(\"wikipedia\")\n+                                                          .interval(\n+                                                              new Interval(\n+                                                                  \"2013-08-31T00:00:00.000Z/2013-09-01T00:00:00.000Z\"\n+                                                              )\n+                                                          )\n+                                                          .version(\"2015-10-21T22:07:57.074Z\")\n+                                                          .loadSpec(\n+                                                              ImmutableMap.<String, Object>of(\n+                                                                  \"type\",\n+                                                                  \"hdfs\",\n+                                                                  \"path\",\n+                                                                  \"hdfs://abc.com:1234/somewhere/index.zip\"\n+                                                              )\n+                                                          )\n+                                                          .dimensions(ImmutableList.of(\"language\", \"page\"))\n+                                                          .metrics(ImmutableList.of(\"count\"))\n+                                                          .build();\n+\n+  private static final DataSegment SEGMENT_2 = DataSegment.builder(SEGMENT_1)\n+                                                          .interval(\n+                                                              new Interval(\n+                                                                  \"2013-09-01T00:00:00.000Z/2013-09-02T00:00:00.000Z\"\n+                                                              )\n+                                                          )\n+                                                          .build();\n+\n+  private static final DataSegment SEGMENT_3 = DataSegment.builder(SEGMENT_1)\n+                                                          .interval(\n+                                                              new Interval(\n+                                                                  \"2013-09-02T00:00:00.000Z/2013-09-03T00:00:00.000Z\"\n+                                                              )\n+                                                          )\n+                                                          .version(\"2015-10-22T22:07:57.074Z\")\n+                                                          .build();\n+\n+  private static final DataSegment SEGMENT_4_0 = DataSegment.builder(SEGMENT_1)\n+                                                            .interval(\n+                                                                new Interval(\n+                                                                    \"2013-09-02T00:00:00.000Z/2013-09-03T00:00:00.000Z\"\n+                                                                )\n+                                                            )\n+                                                            .shardSpec(new NumberedShardSpec(0, 2))\n+                                                            .build();\n+\n+  private static final DataSegment SEGMENT_4_1 = DataSegment.builder(SEGMENT_1)\n+                                                            .interval(\n+                                                                new Interval(\n+                                                                    \"2013-09-02T00:00:00.000Z/2013-09-03T00:00:00.000Z\"\n+                                                                )\n+                                                            )\n+                                                            .shardSpec(new NumberedShardSpec(1, 2))\n+                                                            .build();\n+\n+  private static MiniDFSCluster miniCluster;\n+  private static File hdfsTmpDir;\n+  private static URI uriBase;\n+  private static Configuration conf;\n+  private static FileSystem fs;\n+\n+  private Path dataSourceDir;\n+  private Path descriptor1;\n+  private Path descriptor2;\n+  private Path descriptor3;\n+  private Path descriptor4_0;\n+  private Path descriptor4_1;\n+  private Path indexZip1;\n+  private Path indexZip2;\n+  private Path indexZip3;\n+  private Path indexZip4_0;\n+  private Path indexZip4_1;\n+\n+  @BeforeClass\n+  public static void setupStatic() throws IOException\n+  {\n+    mapper.registerSubtypes(new NamedType(NumberedShardSpec.class, \"numbered\"));\n+\n+    hdfsTmpDir = File.createTempFile(\"hdfsDataSource\", \"dir\");\n+    hdfsTmpDir.deleteOnExit();\n+    if (!hdfsTmpDir.delete()) {\n+      throw new IOException(String.format(\"Unable to delete hdfsTmpDir [%s]\", hdfsTmpDir.getAbsolutePath()));\n+    }\n+    conf = new Configuration(true);\n+    conf.set(MiniDFSCluster.HDFS_MINIDFS_BASEDIR, hdfsTmpDir.getAbsolutePath());\n+    miniCluster = new MiniDFSCluster.Builder(conf).build();\n+    uriBase = miniCluster.getURI();\n+    fs = miniCluster.getFileSystem();\n+  }\n+\n+  @AfterClass\n+  public static void tearDownStatic()\n+  {\n+    if (miniCluster != null) {\n+      miniCluster.shutdown(true);\n+    }\n+  }\n+\n+  @Before\n+  public void setUp() throws IOException\n+  {\n+    dataSourceDir = new Path(new Path(uriBase), \"/usr/dataSource\");\n+    descriptor1 = new Path(dataSourceDir, \"interval1/v1/0/\" + DESCRIPTOR_JSON);\n+    descriptor2 = new Path(dataSourceDir, \"interval2/v1/0/\" + DESCRIPTOR_JSON);\n+    descriptor3 = new Path(dataSourceDir, \"interval3/v2/0/\" + DESCRIPTOR_JSON);\n+    descriptor4_0 = new Path(dataSourceDir, \"interval4/v1/0/\" + DESCRIPTOR_JSON);\n+    descriptor4_1 = new Path(dataSourceDir, \"interval4/v1/1/\" + DESCRIPTOR_JSON);\n+    indexZip1 = new Path(descriptor1.getParent(), INDEX_ZIP);\n+    indexZip2 = new Path(descriptor2.getParent(), INDEX_ZIP);\n+    indexZip3 = new Path(descriptor3.getParent(), INDEX_ZIP);\n+    indexZip4_0 = new Path(descriptor4_0.getParent(), INDEX_ZIP);\n+    indexZip4_1 = new Path(descriptor4_1.getParent(), INDEX_ZIP);\n+\n+    mapper.writeValue(fs.create(descriptor1), SEGMENT_1);\n+    mapper.writeValue(fs.create(descriptor2), SEGMENT_2);\n+    mapper.writeValue(fs.create(descriptor3), SEGMENT_3);\n+    mapper.writeValue(fs.create(descriptor4_0), SEGMENT_4_0);\n+    mapper.writeValue(fs.create(descriptor4_1), SEGMENT_4_1);\n+\n+    create(indexZip1);\n+    create(indexZip2);\n+    create(indexZip3);\n+    create(indexZip4_0);\n+    create(indexZip4_1);\n+  }\n+\n+  private void create(Path indexZip1) throws IOException\n+  {\n+    try (FSDataOutputStream os = fs.create(indexZip1)) {\n+    }\n+  }\n+\n+  @Test\n+  public void testFindSegments() throws Exception\n+  {\n+    final HdfsDataSegmentFinder hdfsDataSegmentFinder = new HdfsDataSegmentFinder(conf, mapper);\n+\n+    final Set<DataSegment> segments = hdfsDataSegmentFinder.findSegments(dataSourceDir.toString(), false);\n+\n+    Assert.assertEquals(5, segments.size());\n+\n+    DataSegment updatedSegment1 = null;\n+    DataSegment updatedSegment2 = null;\n+    DataSegment updatedSegment3 = null;\n+    DataSegment updatedSegment4_0 = null;\n+    DataSegment updatedSegment4_1 = null;\n+    for (DataSegment dataSegment : segments) {\n+      if (dataSegment.getIdentifier().equals(SEGMENT_1.getIdentifier())) {\n+        updatedSegment1 = dataSegment;\n+      } else if (dataSegment.getIdentifier().equals(SEGMENT_2.getIdentifier())) {\n+        updatedSegment2 = dataSegment;\n+      } else if (dataSegment.getIdentifier().equals(SEGMENT_3.getIdentifier())) {\n+        updatedSegment3 = dataSegment;\n+      } else if (dataSegment.getIdentifier().equals(SEGMENT_4_0.getIdentifier())) {\n+        updatedSegment4_0 = dataSegment;\n+      } else if (dataSegment.getIdentifier().equals(SEGMENT_4_1.getIdentifier())) {\n+        updatedSegment4_1 = dataSegment;\n+      } else {\n+        Assert.fail(\"Unexpected segment\");\n+      }\n+    }\n+\n+    Assert.assertEquals(descriptor1.toString(), getDescriptorPath(updatedSegment1));\n+    Assert.assertEquals(descriptor2.toString(), getDescriptorPath(updatedSegment2));\n+    Assert.assertEquals(descriptor3.toString(), getDescriptorPath(updatedSegment3));\n+    Assert.assertEquals(descriptor4_0.toString(), getDescriptorPath(updatedSegment4_0));\n+    Assert.assertEquals(descriptor4_1.toString(), getDescriptorPath(updatedSegment4_1));\n+\n+    final String serializedSegment1 = mapper.writeValueAsString(updatedSegment1);\n+    final String serializedSegment2 = mapper.writeValueAsString(updatedSegment2);\n+    final String serializedSegment3 = mapper.writeValueAsString(updatedSegment3);\n+    final String serializedSegment4_0 = mapper.writeValueAsString(updatedSegment4_0);\n+    final String serializedSegment4_1 = mapper.writeValueAsString(updatedSegment4_1);\n+\n+    // since updateDescriptor was not enabled, descriptor.json still has stale information\n+    Assert.assertNotEquals(serializedSegment1, readContent(descriptor1));\n+    Assert.assertNotEquals(serializedSegment2, readContent(descriptor2));\n+    Assert.assertNotEquals(serializedSegment3, readContent(descriptor3));\n+    Assert.assertNotEquals(serializedSegment4_0, readContent(descriptor4_0));\n+    Assert.assertNotEquals(serializedSegment4_1, readContent(descriptor4_1));","path":"extensions/hdfs-storage/src/test/java/io/druid/segment/loading/HdfsDataSegmentFinderTest.java","position":237,"original_position":237,"commit_id":"293e6e024b5d6d8a48255938267c4e73fe1393f9","original_commit_id":"293e6e024b5d6d8a48255938267c4e73fe1393f9","user":{"login":"guobingkun","id":11789051,"avatar_url":"https://avatars.githubusercontent.com/u/11789051?v=3","gravatar_id":"","url":"https://api.github.com/users/guobingkun","html_url":"https://github.com/guobingkun","followers_url":"https://api.github.com/users/guobingkun/followers","following_url":"https://api.github.com/users/guobingkun/following{/other_user}","gists_url":"https://api.github.com/users/guobingkun/gists{/gist_id}","starred_url":"https://api.github.com/users/guobingkun/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/guobingkun/subscriptions","organizations_url":"https://api.github.com/users/guobingkun/orgs","repos_url":"https://api.github.com/users/guobingkun/repos","events_url":"https://api.github.com/users/guobingkun/events{/privacy}","received_events_url":"https://api.github.com/users/guobingkun/received_events","type":"User","site_admin":false},"body":"I was comparing DataSegment, but then found the implementation of ```equals()``` in DataSegment only compared identifier, so it will return true as long as two segments have the same identifier.","created_at":"2015-10-28T15:49:28Z","updated_at":"2015-10-28T15:49:28Z","html_url":"https://github.com/druid-io/druid/pull/1861#discussion_r43274313","pull_request_url":"https://api.github.com/repos/druid-io/druid/pulls/1861","_links":{"self":{"href":"https://api.github.com/repos/druid-io/druid/pulls/comments/43274313"},"html":{"href":"https://github.com/druid-io/druid/pull/1861#discussion_r43274313"},"pull_request":{"href":"https://api.github.com/repos/druid-io/druid/pulls/1861"}}},"pull_request":{"url":"https://api.github.com/repos/druid-io/druid/pulls/1861","id":48777048,"html_url":"https://github.com/druid-io/druid/pull/1861","diff_url":"https://github.com/druid-io/druid/pull/1861.diff","patch_url":"https://github.com/druid-io/druid/pull/1861.patch","issue_url":"https://api.github.com/repos/druid-io/druid/issues/1861","number":1861,"state":"open","locked":false,"title":"insert-segment tool","user":{"login":"guobingkun","id":11789051,"avatar_url":"https://avatars.githubusercontent.com/u/11789051?v=3","gravatar_id":"","url":"https://api.github.com/users/guobingkun","html_url":"https://github.com/guobingkun","followers_url":"https://api.github.com/users/guobingkun/followers","following_url":"https://api.github.com/users/guobingkun/following{/other_user}","gists_url":"https://api.github.com/users/guobingkun/gists{/gist_id}","starred_url":"https://api.github.com/users/guobingkun/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/guobingkun/subscriptions","organizations_url":"https://api.github.com/users/guobingkun/orgs","repos_url":"https://api.github.com/users/guobingkun/repos","events_url":"https://api.github.com/users/guobingkun/events{/privacy}","received_events_url":"https://api.github.com/users/guobingkun/received_events","type":"User","site_admin":false},"body":"This tool can be used to load segments into Druid by inserting the segment's payload into metadata storage. People can use it to migrate segments to different deep storages.\r\n\r\nUsage example:\r\n```java -Ddruid.extensions.loadList=[\\\"mysql-metadata-storage\\\",\\\"druid-hdfs-storage\\\"] -cp $CLASSPATH io.druid.cli.Main tools insert-segment --workingDir hdfs://tmp/druid/localStorage/wikipedia/```\r\n\r\nSuppose under wikipedia, it looks like this,\r\n```\r\n├── 2013-08-31T00:00:00.000Z_2013-09-01T00:00:00.000Z\r\n│   └── 2015-10-21T22:07:57.074Z\r\n│       └── 0\r\n│           ├── descriptor.json\r\n│           └── index.zip\r\n├── 2013-09-01T00:00:00.000Z_2013-09-02T00:00:00.000Z\r\n│   └── 2015-10-21T22:07:57.074Z\r\n│       └── 0\r\n│           ├── descriptor.json\r\n│           └── index.zip\r\n├── 2013-09-02T00:00:00.000Z_2013-09-03T00:00:00.000Z\r\n│   └── 2015-10-21T22:07:57.074Z\r\n│       └── 0\r\n│           ├── descriptor.json\r\n│           └── index.zip\r\n└── 2013-09-03T00:00:00.000Z_2013-09-04T00:00:00.000Z\r\n    └── 2015-10-21T22:07:57.074Z\r\n        └── 0\r\n            ├── descriptor.json\r\n            └── index.zip\r\n```\r\n\r\nThen these 4 segments will be found and inserted into metadata storage, each segment's loadSpec will be updated with the location from where it was found.\r\n\r\nThis PR depends on https://github.com/druid-io/druid-api/pull/62\r\nDataSegmentFinder is used so that this tool can work on different deep storages. \r\nAn HDFS version is implemented in this PR.","created_at":"2015-10-26T18:17:50Z","updated_at":"2015-10-28T15:49:28Z","closed_at":null,"merged_at":null,"merge_commit_sha":"b83fa20de6e315fb46d3201a037968415238222a","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/druid-io/druid/pulls/1861/commits","review_comments_url":"https://api.github.com/repos/druid-io/druid/pulls/1861/comments","review_comment_url":"https://api.github.com/repos/druid-io/druid/pulls/comments{/number}","comments_url":"https://api.github.com/repos/druid-io/druid/issues/1861/comments","statuses_url":"https://api.github.com/repos/druid-io/druid/statuses/293e6e024b5d6d8a48255938267c4e73fe1393f9","head":{"label":"guobingkun:insert_segment_tool","ref":"insert_segment_tool","sha":"293e6e024b5d6d8a48255938267c4e73fe1393f9","user":{"login":"guobingkun","id":11789051,"avatar_url":"https://avatars.githubusercontent.com/u/11789051?v=3","gravatar_id":"","url":"https://api.github.com/users/guobingkun","html_url":"https://github.com/guobingkun","followers_url":"https://api.github.com/users/guobingkun/followers","following_url":"https://api.github.com/users/guobingkun/following{/other_user}","gists_url":"https://api.github.com/users/guobingkun/gists{/gist_id}","starred_url":"https://api.github.com/users/guobingkun/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/guobingkun/subscriptions","organizations_url":"https://api.github.com/users/guobingkun/orgs","repos_url":"https://api.github.com/users/guobingkun/repos","events_url":"https://api.github.com/users/guobingkun/events{/privacy}","received_events_url":"https://api.github.com/users/guobingkun/received_events","type":"User","site_admin":false},"repo":{"id":33376574,"name":"druid","full_name":"guobingkun/druid","owner":{"login":"guobingkun","id":11789051,"avatar_url":"https://avatars.githubusercontent.com/u/11789051?v=3","gravatar_id":"","url":"https://api.github.com/users/guobingkun","html_url":"https://github.com/guobingkun","followers_url":"https://api.github.com/users/guobingkun/followers","following_url":"https://api.github.com/users/guobingkun/following{/other_user}","gists_url":"https://api.github.com/users/guobingkun/gists{/gist_id}","starred_url":"https://api.github.com/users/guobingkun/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/guobingkun/subscriptions","organizations_url":"https://api.github.com/users/guobingkun/orgs","repos_url":"https://api.github.com/users/guobingkun/repos","events_url":"https://api.github.com/users/guobingkun/events{/privacy}","received_events_url":"https://api.github.com/users/guobingkun/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/guobingkun/druid","description":"Real²time Exploratory Analytics on Large Datasets","fork":true,"url":"https://api.github.com/repos/guobingkun/druid","forks_url":"https://api.github.com/repos/guobingkun/druid/forks","keys_url":"https://api.github.com/repos/guobingkun/druid/keys{/key_id}","collaborators_url":"https://api.github.com/repos/guobingkun/druid/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/guobingkun/druid/teams","hooks_url":"https://api.github.com/repos/guobingkun/druid/hooks","issue_events_url":"https://api.github.com/repos/guobingkun/druid/issues/events{/number}","events_url":"https://api.github.com/repos/guobingkun/druid/events","assignees_url":"https://api.github.com/repos/guobingkun/druid/assignees{/user}","branches_url":"https://api.github.com/repos/guobingkun/druid/branches{/branch}","tags_url":"https://api.github.com/repos/guobingkun/druid/tags","blobs_url":"https://api.github.com/repos/guobingkun/druid/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/guobingkun/druid/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/guobingkun/druid/git/refs{/sha}","trees_url":"https://api.github.com/repos/guobingkun/druid/git/trees{/sha}","statuses_url":"https://api.github.com/repos/guobingkun/druid/statuses/{sha}","languages_url":"https://api.github.com/repos/guobingkun/druid/languages","stargazers_url":"https://api.github.com/repos/guobingkun/druid/stargazers","contributors_url":"https://api.github.com/repos/guobingkun/druid/contributors","subscribers_url":"https://api.github.com/repos/guobingkun/druid/subscribers","subscription_url":"https://api.github.com/repos/guobingkun/druid/subscription","commits_url":"https://api.github.com/repos/guobingkun/druid/commits{/sha}","git_commits_url":"https://api.github.com/repos/guobingkun/druid/git/commits{/sha}","comments_url":"https://api.github.com/repos/guobingkun/druid/comments{/number}","issue_comment_url":"https://api.github.com/repos/guobingkun/druid/issues/comments{/number}","contents_url":"https://api.github.com/repos/guobingkun/druid/contents/{+path}","compare_url":"https://api.github.com/repos/guobingkun/druid/compare/{base}...{head}","merges_url":"https://api.github.com/repos/guobingkun/druid/merges","archive_url":"https://api.github.com/repos/guobingkun/druid/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/guobingkun/druid/downloads","issues_url":"https://api.github.com/repos/guobingkun/druid/issues{/number}","pulls_url":"https://api.github.com/repos/guobingkun/druid/pulls{/number}","milestones_url":"https://api.github.com/repos/guobingkun/druid/milestones{/number}","notifications_url":"https://api.github.com/repos/guobingkun/druid/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/guobingkun/druid/labels{/name}","releases_url":"https://api.github.com/repos/guobingkun/druid/releases{/id}","created_at":"2015-04-03T18:24:06Z","updated_at":"2015-05-07T19:33:13Z","pushed_at":"2015-10-28T15:18:47Z","git_url":"git://github.com/guobingkun/druid.git","ssh_url":"git@github.com:guobingkun/druid.git","clone_url":"https://github.com/guobingkun/druid.git","svn_url":"https://github.com/guobingkun/druid","homepage":"http://druid.io","size":99242,"stargazers_count":0,"watchers_count":0,"language":"Java","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"druid-io:master","ref":"master","sha":"7e1cde25b675033e33cec1f3fd0083dd106a51cc","user":{"login":"druid-io","id":4203474,"avatar_url":"https://avatars.githubusercontent.com/u/4203474?v=3","gravatar_id":"","url":"https://api.github.com/users/druid-io","html_url":"https://github.com/druid-io","followers_url":"https://api.github.com/users/druid-io/followers","following_url":"https://api.github.com/users/druid-io/following{/other_user}","gists_url":"https://api.github.com/users/druid-io/gists{/gist_id}","starred_url":"https://api.github.com/users/druid-io/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/druid-io/subscriptions","organizations_url":"https://api.github.com/users/druid-io/orgs","repos_url":"https://api.github.com/users/druid-io/repos","events_url":"https://api.github.com/users/druid-io/events{/privacy}","received_events_url":"https://api.github.com/users/druid-io/received_events","type":"Organization","site_admin":false},"repo":{"id":6358188,"name":"druid","full_name":"druid-io/druid","owner":{"login":"druid-io","id":4203474,"avatar_url":"https://avatars.githubusercontent.com/u/4203474?v=3","gravatar_id":"","url":"https://api.github.com/users/druid-io","html_url":"https://github.com/druid-io","followers_url":"https://api.github.com/users/druid-io/followers","following_url":"https://api.github.com/users/druid-io/following{/other_user}","gists_url":"https://api.github.com/users/druid-io/gists{/gist_id}","starred_url":"https://api.github.com/users/druid-io/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/druid-io/subscriptions","organizations_url":"https://api.github.com/users/druid-io/orgs","repos_url":"https://api.github.com/users/druid-io/repos","events_url":"https://api.github.com/users/druid-io/events{/privacy}","received_events_url":"https://api.github.com/users/druid-io/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/druid-io/druid","description":"Column oriented distributed data store ideal for powering interactive applications","fork":false,"url":"https://api.github.com/repos/druid-io/druid","forks_url":"https://api.github.com/repos/druid-io/druid/forks","keys_url":"https://api.github.com/repos/druid-io/druid/keys{/key_id}","collaborators_url":"https://api.github.com/repos/druid-io/druid/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/druid-io/druid/teams","hooks_url":"https://api.github.com/repos/druid-io/druid/hooks","issue_events_url":"https://api.github.com/repos/druid-io/druid/issues/events{/number}","events_url":"https://api.github.com/repos/druid-io/druid/events","assignees_url":"https://api.github.com/repos/druid-io/druid/assignees{/user}","branches_url":"https://api.github.com/repos/druid-io/druid/branches{/branch}","tags_url":"https://api.github.com/repos/druid-io/druid/tags","blobs_url":"https://api.github.com/repos/druid-io/druid/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/druid-io/druid/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/druid-io/druid/git/refs{/sha}","trees_url":"https://api.github.com/repos/druid-io/druid/git/trees{/sha}","statuses_url":"https://api.github.com/repos/druid-io/druid/statuses/{sha}","languages_url":"https://api.github.com/repos/druid-io/druid/languages","stargazers_url":"https://api.github.com/repos/druid-io/druid/stargazers","contributors_url":"https://api.github.com/repos/druid-io/druid/contributors","subscribers_url":"https://api.github.com/repos/druid-io/druid/subscribers","subscription_url":"https://api.github.com/repos/druid-io/druid/subscription","commits_url":"https://api.github.com/repos/druid-io/druid/commits{/sha}","git_commits_url":"https://api.github.com/repos/druid-io/druid/git/commits{/sha}","comments_url":"https://api.github.com/repos/druid-io/druid/comments{/number}","issue_comment_url":"https://api.github.com/repos/druid-io/druid/issues/comments{/number}","contents_url":"https://api.github.com/repos/druid-io/druid/contents/{+path}","compare_url":"https://api.github.com/repos/druid-io/druid/compare/{base}...{head}","merges_url":"https://api.github.com/repos/druid-io/druid/merges","archive_url":"https://api.github.com/repos/druid-io/druid/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/druid-io/druid/downloads","issues_url":"https://api.github.com/repos/druid-io/druid/issues{/number}","pulls_url":"https://api.github.com/repos/druid-io/druid/pulls{/number}","milestones_url":"https://api.github.com/repos/druid-io/druid/milestones{/number}","notifications_url":"https://api.github.com/repos/druid-io/druid/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/druid-io/druid/labels{/name}","releases_url":"https://api.github.com/repos/druid-io/druid/releases{/id}","created_at":"2012-10-23T19:08:07Z","updated_at":"2015-10-28T11:40:32Z","pushed_at":"2015-10-28T15:11:21Z","git_url":"git://github.com/druid-io/druid.git","ssh_url":"git@github.com:druid-io/druid.git","clone_url":"https://github.com/druid-io/druid.git","svn_url":"https://github.com/druid-io/druid","homepage":"http://druid.io","size":182145,"stargazers_count":2106,"watchers_count":2106,"language":"Java","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":477,"mirror_url":null,"open_issues_count":204,"forks":477,"open_issues":204,"watchers":2106,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/druid-io/druid/pulls/1861"},"html":{"href":"https://github.com/druid-io/druid/pull/1861"},"issue":{"href":"https://api.github.com/repos/druid-io/druid/issues/1861"},"comments":{"href":"https://api.github.com/repos/druid-io/druid/issues/1861/comments"},"review_comments":{"href":"https://api.github.com/repos/druid-io/druid/pulls/1861/comments"},"review_comment":{"href":"https://api.github.com/repos/druid-io/druid/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/druid-io/druid/pulls/1861/commits"},"statuses":{"href":"https://api.github.com/repos/druid-io/druid/statuses/293e6e024b5d6d8a48255938267c4e73fe1393f9"}}}}