{"action":"created","comment":{"url":"https://api.github.com/repos/druid-io/druid/pulls/comments/30620572","id":30620572,"diff_hunk":"@@ -0,0 +1,168 @@\n+package io.druid.indexer.hadoop;\n+\n+\n+import com.fasterxml.jackson.databind.ObjectMapper;\n+import com.google.common.base.Function;\n+import com.google.common.base.Predicate;\n+import com.google.common.collect.Iterables;\n+import com.google.common.collect.Lists;\n+import com.google.common.io.Files;\n+import com.metamx.common.ISE;\n+import io.druid.data.input.MapBasedInputRow;\n+import io.druid.data.input.MapBasedRow;\n+import io.druid.query.filter.DimFilter;\n+import io.druid.segment.IndexIO;\n+import io.druid.segment.QueryableIndex;\n+import io.druid.segment.QueryableIndexStorageAdapter;\n+import io.druid.segment.StorageAdapter;\n+import io.druid.segment.column.ValueType;\n+import io.druid.segment.realtime.firehose.IngestSegmentFirehose;\n+import io.druid.segment.serde.ComplexMetricSerde;\n+import io.druid.segment.serde.ComplexMetrics;\n+import io.druid.utils.CompressionUtils;\n+import org.apache.hadoop.conf.Configuration;\n+import org.apache.hadoop.fs.FSDataInputStream;\n+import org.apache.hadoop.fs.FileSystem;\n+import org.apache.hadoop.fs.Path;\n+import org.apache.hadoop.io.NullWritable;\n+import org.apache.hadoop.mapreduce.InputSplit;\n+import org.apache.hadoop.mapreduce.RecordReader;\n+import org.apache.hadoop.mapreduce.TaskAttemptContext;\n+import org.slf4j.Logger;\n+import org.slf4j.LoggerFactory;\n+\n+import javax.annotation.Nullable;\n+import java.io.File;\n+import java.io.IOException;\n+import java.util.List;\n+import java.util.Map;\n+\n+public class DatasourceRecordReader extends RecordReader<NullWritable, HadoopWritableInputRow>\n+{\n+\n+  private static final Logger logger = LoggerFactory.getLogger(DatasourceRecordReader.class);\n+\n+  private SegmentLoadSpec spec;\n+  private Iterable<Metric> complexMetrics;\n+\n+  private IngestSegmentFirehose rowYielder;\n+\n+  private MapBasedRow currRow;\n+\n+  @Override\n+  public void initialize(InputSplit split, TaskAttemptContext context) throws IOException, InterruptedException\n+  {\n+    spec = readSegmentJobSpec(context.getConfiguration(), new ObjectMapper());\n+\n+    final List<String> dimensions = spec.getDimensions();\n+    final List<String> metrics = Lists.transform(\n+        spec.getMetrics(),\n+        new Function<Metric, String>()\n+        {\n+          @Nullable\n+          @Override\n+          public String apply(Metric input)\n+          {\n+            return input.getName();\n+          }\n+        }\n+    );\n+\n+    complexMetrics = Iterables.filter(\n+        spec.getMetrics(), new Predicate<Metric>()\n+        {\n+          @Override\n+          public boolean apply(@Nullable Metric input)\n+          {\n+            return input.getType() == ValueType.COMPLEX;\n+          }\n+        }\n+    );\n+    final DimFilter filter = spec.getFilter();\n+\n+    String hdfsPath = ((DatasourceInputSplit) split).getPath();\n+    logger.info(\"Reading segment from \" + hdfsPath);\n+\n+    File segmentDir = Files.createTempDir();\n+    logger.info(\"segment dir: \" + segmentDir);\n+\n+    FileSystem fs = FileSystem.get(context.getConfiguration());\n+    getSegmentFiles(hdfsPath, segmentDir, fs);\n+    logger.info(\"finished getting segment files\");\n+\n+    QueryableIndex index = IndexIO.loadIndex(segmentDir);\n+    StorageAdapter adapter = new QueryableIndexStorageAdapter(index);\n+    List<StorageAdapter> adapters = Lists.newArrayList(adapter);\n+    rowYielder = new IngestSegmentFirehose(adapters, dimensions, metrics, filter, spec.getInterval(), spec.getGranularity());\n+  }\n+\n+  @Override\n+  public boolean nextKeyValue() throws IOException, InterruptedException\n+  {\n+    if (rowYielder.hasMore()) {\n+      currRow = (MapBasedRow)rowYielder.nextRow();\n+      return true;\n+    } else {\n+      return false;\n+    }\n+  }\n+\n+  @Override\n+  public NullWritable getCurrentKey() throws IOException, InterruptedException\n+  {\n+    return NullWritable.get();\n+  }\n+\n+  @Override\n+  public HadoopWritableInputRow getCurrentValue() throws IOException, InterruptedException\n+  {\n+    Map<String, Object> event = currRow.getEvent();\n+    for(Metric m : complexMetrics) {\n+      if(event.containsKey(m.getName())) {\n+        ComplexMetricSerde serde = ComplexMetrics.getSerdeForType(m.getComplexTypeName());\n+        if (serde == null) {\n+          throw new ISE(\"Unknown type[%s]\", m.getComplexTypeName());\n+        }\n+        event.put(m.getName(), serde.getObjectStrategy().toBytes(event.get(m.getName())));\n+      }\n+    }\n+    return new MapBasedHadoopWritableInputRow(new MapBasedInputRow(currRow.getTimestamp(), spec.getDimensions(), event));\n+  }\n+\n+  @Override\n+  public float getProgress() throws IOException, InterruptedException\n+  {\n+    // TODO can we make this more meaningful?\n+    return 0;\n+  }\n+\n+  @Override\n+  public void close() throws IOException\n+  {\n+    //TODO: may be delete the copied data even if its in a temp space or maybe make temp directory\n+    //also configurable\n+  }\n+\n+  private void getSegmentFiles(String pathStr, File dir, FileSystem fs) throws IOException\n+  {\n+    if (!dir.exists() && !dir.mkdirs()) {\n+      throw new IOException(dir + \" does not exist and creation failed\");\n+    }\n+    final Path path = new Path(pathStr);\n+    try (FSDataInputStream in = fs.open(path)) {\n+      CompressionUtils.unzip(in, dir);","path":"indexing-hadoop/src/main/java/io/druid/indexer/hadoop/DatasourceRecordReader.java","position":153,"original_position":153,"commit_id":"95e60d0e853b921e373d2ab678c36c2317a6f064","original_commit_id":"95e60d0e853b921e373d2ab678c36c2317a6f064","user":{"login":"drcrallen","id":8213081,"avatar_url":"https://avatars.githubusercontent.com/u/8213081?v=3","gravatar_id":"","url":"https://api.github.com/users/drcrallen","html_url":"https://github.com/drcrallen","followers_url":"https://api.github.com/users/drcrallen/followers","following_url":"https://api.github.com/users/drcrallen/following{/other_user}","gists_url":"https://api.github.com/users/drcrallen/gists{/gist_id}","starred_url":"https://api.github.com/users/drcrallen/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/drcrallen/subscriptions","organizations_url":"https://api.github.com/users/drcrallen/orgs","repos_url":"https://api.github.com/users/drcrallen/repos","events_url":"https://api.github.com/users/drcrallen/events{/privacy}","received_events_url":"https://api.github.com/users/drcrallen/received_events","type":"User","site_admin":false},"body":"This causes guava problems :(","created_at":"2015-05-19T16:53:57Z","updated_at":"2015-05-19T16:53:57Z","html_url":"https://github.com/druid-io/druid/pull/1374#discussion_r30620572","pull_request_url":"https://api.github.com/repos/druid-io/druid/pulls/1374","_links":{"self":{"href":"https://api.github.com/repos/druid-io/druid/pulls/comments/30620572"},"html":{"href":"https://github.com/druid-io/druid/pull/1374#discussion_r30620572"},"pull_request":{"href":"https://api.github.com/repos/druid-io/druid/pulls/1374"}}},"pull_request":{"url":"https://api.github.com/repos/druid-io/druid/pulls/1374","id":35664560,"html_url":"https://github.com/druid-io/druid/pull/1374","diff_url":"https://github.com/druid-io/druid/pull/1374.diff","patch_url":"https://github.com/druid-io/druid/pull/1374.patch","issue_url":"https://api.github.com/repos/druid-io/druid/issues/1374","number":1374,"state":"open","locked":false,"title":"[Initial Review] Feature for batch re-ingesion and delta ingestion","user":{"login":"himanshug","id":246308,"avatar_url":"https://avatars.githubusercontent.com/u/246308?v=3","gravatar_id":"","url":"https://api.github.com/users/himanshug","html_url":"https://github.com/himanshug","followers_url":"https://api.github.com/users/himanshug/followers","following_url":"https://api.github.com/users/himanshug/following{/other_user}","gists_url":"https://api.github.com/users/himanshug/gists{/gist_id}","starred_url":"https://api.github.com/users/himanshug/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/himanshug/subscriptions","organizations_url":"https://api.github.com/users/himanshug/orgs","repos_url":"https://api.github.com/users/himanshug/repos","events_url":"https://api.github.com/users/himanshug/events{/privacy}","received_events_url":"https://api.github.com/users/himanshug/received_events","type":"User","site_admin":false},"body":"First-cut code to show the low level design/implementation details for the proposal of adding a DatasourceInputFormat  that can be used to batch re-ingest data back to druid from existing Datasource (something like IngestSegmentFirehose) segments.\r\nAlso, provided changes to allow specifying multiple PathSpec in the batch ingestion so that you can combine both DatasourcePathSpec and StaticPathSpec in the same ingestion to add late arriving data to existing ingested interval.\r\n\r\nNote that, this code is to show the design approach and not working/tested. I will make it prettier, working, unit-tested once ppl agree with the overall approach.\r\n\r\noriginal proposal discussion: https://groups.google.com/forum/?utm_medium=email&utm_source=footer#!msg/druid-development/EXYAPcV6pk4/Nu1uRGKEctAJ\r\n\r\nAfter we're done, here is what you would configure in your batch ingestion spec...\r\n\r\n(1) Re-ingestion or Re-indexing Usecase --\r\n```\r\n{\r\n  \"dataSchema\" : {\r\n    \"dataSource\" : \"wikipedia\",\r\n    \"parser\" : {\r\n      \"type\" : \"noop\" //NoopInputRowParser.java will be added to druid-api/, that does nothing\r\n      }\r\n    },\r\n    \"metricsSpec\" : [..],\r\n    \"granularitySpec\" : {..}\r\n  },\r\n  \"ioConfig\" : {\r\n    \"type\" : \"hadoop\",\r\n    \"inputSpec\" : {\r\n      \"type\" : \"datasourcePathSpec\",\r\n      \"dataSource\" : \"mydatasource\",\r\n      \"interval\" : \"2013/2015\",\r\n      \"dimensions\" : [... list of dimensions ..],\r\n      \"metrics\" : [\r\n         {\"name\": \"m1\", \"type\": \"FLOAT\"},\r\n         {\"name\": \"m2\", \"type\": \"COMPLEX\", \"complexTypeName\": \"hyperUnique\"}\r\n      ]\r\n    },\r\n    ...\r\n    ...\r\n}\r\n```\r\n(2) Delta ingestion use case to add late data in pre-indexed interval.\r\n\r\n```\r\n{\r\n  \"dataSchema\" : {\r\n    \"dataSource\" : \"wikipedia\",\r\n    \"parser\" : {\r\n      \"type\" : \"string\",\r\n      \"parseSpec\" : {\r\n        \"format\" : \"json\",\r\n        ...\r\n      }\r\n    },\r\n    \"metricsSpec\" : [..],\r\n    \"granularitySpec\" : {..}\r\n  },\r\n  \"ioConfig\" : {\r\n    \"type\" : \"hadoop\",\r\n    \"inputSpec\" : {\r\n      \"type\": \"multi\",\r\n      \"childPathSpecs\": [\r\n      {\r\n        \"type\" : \"datasourcePathSpec\",\r\n        \"dataSource\" : \"mydatasource\",\r\n        \"interval\" : \"2013/2015\",\r\n        \"dimensions\" : [... list of dimensions ..],\r\n        \"metrics\" : [\r\n           {\"name\": \"m1\", \"type\": \"FLOAT\"},\r\n           {\"name\": \"m2\", \"type\": \"COMPLEX\", \"complexTypeName\": \"hyperUnique\"}\r\n         ]\r\n      },\r\n      {\r\n         \"type\" : \"static\",\r\n         \"paths\" : \"/path/to/late/data\"\r\n      }\r\n     ]\r\n    },\r\n    ...\r\n    ...\r\n}\r\n\r\n```","created_at":"2015-05-18T19:18:19Z","updated_at":"2015-05-19T16:53:57Z","closed_at":null,"merged_at":null,"merge_commit_sha":"deace09eab656081cfc2112d133cede975f857f6","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/druid-io/druid/pulls/1374/commits","review_comments_url":"https://api.github.com/repos/druid-io/druid/pulls/1374/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/1374/comments","statuses_url":"https://api.github.com/repos/druid-io/druid/statuses/95e60d0e853b921e373d2ab678c36c2317a6f064","head":{"label":"himanshug:batch_delta_ingestion3","ref":"batch_delta_ingestion3","sha":"95e60d0e853b921e373d2ab678c36c2317a6f064","user":{"login":"himanshug","id":246308,"avatar_url":"https://avatars.githubusercontent.com/u/246308?v=3","gravatar_id":"","url":"https://api.github.com/users/himanshug","html_url":"https://github.com/himanshug","followers_url":"https://api.github.com/users/himanshug/followers","following_url":"https://api.github.com/users/himanshug/following{/other_user}","gists_url":"https://api.github.com/users/himanshug/gists{/gist_id}","starred_url":"https://api.github.com/users/himanshug/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/himanshug/subscriptions","organizations_url":"https://api.github.com/users/himanshug/orgs","repos_url":"https://api.github.com/users/himanshug/repos","events_url":"https://api.github.com/users/himanshug/events{/privacy}","received_events_url":"https://api.github.com/users/himanshug/received_events","type":"User","site_admin":false},"repo":{"id":23076411,"name":"druid","full_name":"himanshug/druid","owner":{"login":"himanshug","id":246308,"avatar_url":"https://avatars.githubusercontent.com/u/246308?v=3","gravatar_id":"","url":"https://api.github.com/users/himanshug","html_url":"https://github.com/himanshug","followers_url":"https://api.github.com/users/himanshug/followers","following_url":"https://api.github.com/users/himanshug/following{/other_user}","gists_url":"https://api.github.com/users/himanshug/gists{/gist_id}","starred_url":"https://api.github.com/users/himanshug/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/himanshug/subscriptions","organizations_url":"https://api.github.com/users/himanshug/orgs","repos_url":"https://api.github.com/users/himanshug/repos","events_url":"https://api.github.com/users/himanshug/events{/privacy}","received_events_url":"https://api.github.com/users/himanshug/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/himanshug/druid","description":"Real²time Exploratory Analytics on Large Datasets","fork":true,"url":"https://api.github.com/repos/himanshug/druid","forks_url":"https://api.github.com/repos/himanshug/druid/forks","keys_url":"https://api.github.com/repos/himanshug/druid/keys{/key_id}","collaborators_url":"https://api.github.com/repos/himanshug/druid/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/himanshug/druid/teams","hooks_url":"https://api.github.com/repos/himanshug/druid/hooks","issue_events_url":"https://api.github.com/repos/himanshug/druid/issues/events{/number}","events_url":"https://api.github.com/repos/himanshug/druid/events","assignees_url":"https://api.github.com/repos/himanshug/druid/assignees{/user}","branches_url":"https://api.github.com/repos/himanshug/druid/branches{/branch}","tags_url":"https://api.github.com/repos/himanshug/druid/tags","blobs_url":"https://api.github.com/repos/himanshug/druid/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/himanshug/druid/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/himanshug/druid/git/refs{/sha}","trees_url":"https://api.github.com/repos/himanshug/druid/git/trees{/sha}","statuses_url":"https://api.github.com/repos/himanshug/druid/statuses/{sha}","languages_url":"https://api.github.com/repos/himanshug/druid/languages","stargazers_url":"https://api.github.com/repos/himanshug/druid/stargazers","contributors_url":"https://api.github.com/repos/himanshug/druid/contributors","subscribers_url":"https://api.github.com/repos/himanshug/druid/subscribers","subscription_url":"https://api.github.com/repos/himanshug/druid/subscription","commits_url":"https://api.github.com/repos/himanshug/druid/commits{/sha}","git_commits_url":"https://api.github.com/repos/himanshug/druid/git/commits{/sha}","comments_url":"https://api.github.com/repos/himanshug/druid/comments{/number}","issue_comment_url":"https://api.github.com/repos/himanshug/druid/issues/comments{/number}","contents_url":"https://api.github.com/repos/himanshug/druid/contents/{+path}","compare_url":"https://api.github.com/repos/himanshug/druid/compare/{base}...{head}","merges_url":"https://api.github.com/repos/himanshug/druid/merges","archive_url":"https://api.github.com/repos/himanshug/druid/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/himanshug/druid/downloads","issues_url":"https://api.github.com/repos/himanshug/druid/issues{/number}","pulls_url":"https://api.github.com/repos/himanshug/druid/pulls{/number}","milestones_url":"https://api.github.com/repos/himanshug/druid/milestones{/number}","notifications_url":"https://api.github.com/repos/himanshug/druid/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/himanshug/druid/labels{/name}","releases_url":"https://api.github.com/repos/himanshug/druid/releases{/id}","created_at":"2014-08-18T15:28:53Z","updated_at":"2015-02-23T20:08:38Z","pushed_at":"2015-05-18T18:50:10Z","git_url":"git://github.com/himanshug/druid.git","ssh_url":"git@github.com:himanshug/druid.git","clone_url":"https://github.com/himanshug/druid.git","svn_url":"https://github.com/himanshug/druid","homepage":"http://druid.io","size":91906,"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":"e6d22565adbca83665049e9a274b7ae3ba476d8e","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":"Real²time Exploratory Analytics on Large Datasets","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-05-18T13:40:11Z","pushed_at":"2015-05-19T16:37:27Z","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":174231,"stargazers_count":1733,"watchers_count":1733,"language":"Java","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":374,"mirror_url":null,"open_issues_count":148,"forks":374,"open_issues":148,"watchers":1733,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/druid-io/druid/pulls/1374"},"html":{"href":"https://github.com/druid-io/druid/pull/1374"},"issue":{"href":"https://api.github.com/repos/druid-io/druid/issues/1374"},"comments":{"href":"https://api.github.com/repos/druid-io/druid/issues/1374/comments"},"review_comments":{"href":"https://api.github.com/repos/druid-io/druid/pulls/1374/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/1374/commits"},"statuses":{"href":"https://api.github.com/repos/druid-io/druid/statuses/95e60d0e853b921e373d2ab678c36c2317a6f064"}}}}