{"action":"created","comment":{"url":"https://api.github.com/repos/linkedin/gobblin/pulls/comments/40747040","id":40747040,"diff_hunk":"@@ -0,0 +1,453 @@\n+/*\n+ * Copyright (C) 2014-2015 LinkedIn Corp. All rights reserved.\n+ *\n+ * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use\n+ * this file except in compliance with the License. You may obtain a copy of the\n+ * License at  http://www.apache.org/licenses/LICENSE-2.0\n+ *\n+ * Unless required by applicable law or agreed to in writing, software distributed\n+ * under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\n+ * CONDITIONS OF ANY KIND, either express or implied.\n+ */\n+\n+package gobblin.yarn;\n+\n+import java.net.URI;\n+import java.util.List;\n+import java.util.Map;\n+import java.util.UUID;\n+import java.util.concurrent.ScheduledExecutorService;\n+import java.util.concurrent.ScheduledThreadPoolExecutor;\n+import java.util.concurrent.TimeUnit;\n+import java.util.concurrent.TimeoutException;\n+\n+import org.apache.commons.cli.CommandLine;\n+import org.apache.commons.cli.DefaultParser;\n+import org.apache.commons.cli.HelpFormatter;\n+import org.apache.commons.cli.Options;\n+import org.apache.commons.cli.ParseException;\n+import org.apache.hadoop.conf.Configuration;\n+import org.apache.hadoop.fs.FileSystem;\n+import org.apache.hadoop.fs.Path;\n+import org.apache.hadoop.security.UserGroupInformation;\n+import org.apache.hadoop.yarn.api.ApplicationConstants;\n+import org.apache.hadoop.yarn.api.records.ApplicationAttemptId;\n+import org.apache.hadoop.yarn.api.records.ContainerId;\n+import org.apache.hadoop.yarn.util.ConverterUtils;\n+import org.apache.helix.Criteria;\n+import org.apache.helix.HelixDataAccessor;\n+import org.apache.helix.HelixManager;\n+import org.apache.helix.HelixManagerFactory;\n+import org.apache.helix.HelixProperty;\n+import org.apache.helix.InstanceType;\n+import org.apache.helix.LiveInstanceChangeListener;\n+import org.apache.helix.NotificationContext;\n+import org.apache.helix.messaging.handling.HelixTaskResult;\n+import org.apache.helix.messaging.handling.MessageHandler;\n+import org.apache.helix.messaging.handling.MessageHandlerFactory;\n+import org.apache.helix.model.LiveInstance;\n+import org.apache.helix.model.Message;\n+import org.slf4j.Logger;\n+import org.slf4j.LoggerFactory;\n+\n+import com.codahale.metrics.JmxReporter;\n+import com.codahale.metrics.Metric;\n+import com.codahale.metrics.MetricRegistry;\n+import com.codahale.metrics.MetricSet;\n+import com.codahale.metrics.jvm.FileDescriptorRatioGauge;\n+import com.codahale.metrics.jvm.GarbageCollectorMetricSet;\n+import com.codahale.metrics.jvm.MemoryUsageGaugeSet;\n+import com.codahale.metrics.jvm.ThreadStatesGaugeSet;\n+\n+import com.google.common.base.Optional;\n+import com.google.common.base.Strings;\n+import com.google.common.base.Throwables;\n+import com.google.common.collect.Lists;\n+import com.google.common.eventbus.EventBus;\n+import com.google.common.eventbus.Subscribe;\n+import com.google.common.util.concurrent.MoreExecutors;\n+import com.google.common.util.concurrent.Service;\n+import com.google.common.util.concurrent.ServiceManager;\n+\n+import com.typesafe.config.Config;\n+import com.typesafe.config.ConfigFactory;\n+\n+import gobblin.configuration.ConfigurationKeys;\n+import gobblin.yarn.event.ApplicationMasterShutdownRequest;\n+import gobblin.yarn.event.DelegationTokenUpdatedEvent;\n+\n+\n+/**\n+ * The Yarn ApplicationMaster class for Gobblin.\n+ *\n+ * <p>\n+ *   This class runs the {@link GobblinHelixJobScheduler} for scheduling and running Gobblin jobs,\n+ *   and the {@link YarnService} for all Yarn-related stuffs like ApplicationMaster registration\n+ *   and un-registration and Yarn container provisioning. This class serves as the Helix controller\n+ *   and it uses a {@link HelixManager} to work with Helix.\n+ * </p>\n+ *\n+ * @author ynli\n+ */\n+public class GobblinApplicationMaster {\n+\n+  private static final Logger LOGGER = LoggerFactory.getLogger(GobblinApplicationMaster.class);\n+\n+  private final ServiceManager serviceManager;\n+\n+  private final EventBus eventBus;\n+\n+  private final HelixManager helixManager;\n+\n+  private final MetricRegistry metricRegistry = new MetricRegistry();\n+  private final JmxReporter jmxReporter = JmxReporter.forRegistry(this.metricRegistry)\n+      .convertRatesTo(TimeUnit.SECONDS)\n+      .convertDurationsTo(TimeUnit.MILLISECONDS)\n+      .build();\n+\n+  private volatile boolean stopInProgress = false;\n+  private volatile boolean isStopped = false;\n+\n+  public GobblinApplicationMaster(String applicationName, Config config) throws Exception {\n+    // An EventBus used for communications between services running in the ApplicationMaster\n+    this.eventBus = new EventBus(GobblinApplicationMaster.class.getSimpleName());\n+    this.eventBus.register(this);\n+\n+    ContainerId containerId =\n+        ConverterUtils.toContainerId(System.getenv().get(ApplicationConstants.Environment.CONTAINER_ID.key()));\n+    ApplicationAttemptId applicationAttemptIdId = containerId.getApplicationAttemptId();\n+\n+    String zkConnectionString = config.getString(ConfigurationConstants.ZK_CONNECTION_STRING_KEY);\n+    LOGGER.info(\"Using ZooKeeper connection string: \" + zkConnectionString);\n+\n+    // This will create and register a Helix controller in ZooKeeper\n+    this.helixManager = HelixManagerFactory.getZKHelixManager(\n+        config.getString(ConfigurationConstants.HELIX_CLUSTER_NAME_KEY),\n+        YarnHelixUtils.getParticipantIdStr(YarnHelixUtils.getHostname(), containerId), InstanceType.CONTROLLER,\n+        zkConnectionString);\n+\n+    FileSystem fs = config.hasPath(ConfigurationKeys.FS_URI_KEY) ?\n+        FileSystem.get(URI.create(config.getString(ConfigurationKeys.FS_URI_KEY)), new Configuration()) :\n+        FileSystem.get(new Configuration());\n+    Path appWorkDir = YarnHelixUtils.getAppWorkDirPath(fs, applicationName, applicationAttemptIdId.getApplicationId());\n+\n+    List<Service> services = Lists.newArrayList();\n+    if (UserGroupInformation.isSecurityEnabled()) {\n+      LOGGER.info(\"Adding YarnContainerSecurityManager since security is enabled\");\n+      services.add(new YarnContainerSecurityManager(config, fs, this.eventBus));\n+    }\n+    services.add(\n+        new YarnService(config, applicationName, applicationAttemptIdId.getApplicationId(), fs, this.eventBus,\n+            Strings.nullToEmpty(config.getString(ConfigurationConstants.CONTAINER_JVM_ARGS_KEY))));\n+    services.add(\n+        new GobblinHelixJobScheduler(YarnHelixUtils.configToProperties(config), this.helixManager, this.eventBus,\n+            appWorkDir));\n+    services.add(new JobConfigurationManager(this.eventBus,\n+        config.hasPath(ConfigurationConstants.JOB_CONF_PACKAGE_PATH_KEY) ? Optional\n+            .of(config.getString(ConfigurationConstants.JOB_CONF_PACKAGE_PATH_KEY)) : Optional.<String>absent()));\n+\n+    this.serviceManager = new ServiceManager(services);\n+  }\n+\n+  /**\n+   * Start the ApplicationMaster.\n+   */\n+  public void start() {\n+    LOGGER.info(\"Starting the Gobblin Yarn ApplicationMaster\");\n+\n+    // Add a shutdown hook so the task scheduler gets properly shutdown\n+    addShutdownHook();\n+\n+    try {\n+      this.helixManager.connect();\n+      this.helixManager.addLiveInstanceChangeListener(new GobblinLiveInstanceChangeListener());\n+      this.helixManager.getMessagingService().registerMessageHandlerFactory(\n+          Message.MessageType.SHUTDOWN.toString(), new ControllerShutdownMessageHandlerFactory());\n+      this.helixManager.getMessagingService().registerMessageHandlerFactory(\n+          Message.MessageType.USER_DEFINE_MSG.toString(), new ControllerUserDefinedMessageHandlerFactory()\n+      );\n+    } catch (Exception e) {\n+      LOGGER.error(\"HelixManager failed to connect\", e);\n+      throw Throwables.propagate(e);\n+    }\n+\n+    // Register JVM metrics to collect and report\n+    registerJvmMetrics();\n+\n+    // Start metric reporting\n+    this.jmxReporter.start();\n+\n+    // Start all the services running in the ApplicationMaster\n+    this.serviceManager.startAsync();\n+    this.serviceManager.awaitHealthy();\n+  }\n+\n+  /**\n+   * Stop the ApplicationMaster.\n+   */\n+  public synchronized void stop() {\n+    if (this.isStopped || this.stopInProgress) {\n+      return;\n+    }\n+\n+    this.stopInProgress = true;\n+\n+    LOGGER.info(\"Stopping the Gobblin Yarn ApplicationMaster\");\n+\n+    // Send a shutdown request to the containers as a second guard in case Yarn could not stop the containers\n+    sendShutdownRequest();\n+\n+    try {\n+      // Give the services 5 minutes to stop to ensure that we are responsive to shutdown requests\n+      this.serviceManager.stopAsync().awaitStopped(5, TimeUnit.MINUTES);\n+    } catch (TimeoutException te) {\n+      LOGGER.error(\"Timeout in stopping the service manager\", te);\n+    } finally {\n+      // Stop metric reporting\n+      this.jmxReporter.stop();\n+\n+      if (this.helixManager.isConnected()) {\n+        this.helixManager.disconnect();\n+      }\n+    }\n+\n+    this.isStopped = true;\n+  }\n+\n+  @SuppressWarnings(\"unused\")","path":"gobblin-yarn/src/main/java/gobblin/yarn/GobblinApplicationMaster.java","position":217,"original_position":217,"commit_id":"f501adeb3cf90da2afac2b3da88f18a668a1788e","original_commit_id":"3357a5aa6592d3f247b62ca8cefc3d326ef03cf8","user":{"login":"liyinan926","id":3709137,"avatar_url":"https://avatars.githubusercontent.com/u/3709137?v=3","gravatar_id":"","url":"https://api.github.com/users/liyinan926","html_url":"https://github.com/liyinan926","followers_url":"https://api.github.com/users/liyinan926/followers","following_url":"https://api.github.com/users/liyinan926/following{/other_user}","gists_url":"https://api.github.com/users/liyinan926/gists{/gist_id}","starred_url":"https://api.github.com/users/liyinan926/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/liyinan926/subscriptions","organizations_url":"https://api.github.com/users/liyinan926/orgs","repos_url":"https://api.github.com/users/liyinan926/repos","events_url":"https://api.github.com/users/liyinan926/events{/privacy}","received_events_url":"https://api.github.com/users/liyinan926/received_events","type":"User","site_admin":false},"body":"Yes, it shows warning in IDEA.","created_at":"2015-09-30T00:18:45Z","updated_at":"2015-09-30T00:18:45Z","html_url":"https://github.com/linkedin/gobblin/pull/339#discussion_r40747040","pull_request_url":"https://api.github.com/repos/linkedin/gobblin/pulls/339","_links":{"self":{"href":"https://api.github.com/repos/linkedin/gobblin/pulls/comments/40747040"},"html":{"href":"https://github.com/linkedin/gobblin/pull/339#discussion_r40747040"},"pull_request":{"href":"https://api.github.com/repos/linkedin/gobblin/pulls/339"}}},"pull_request":{"url":"https://api.github.com/repos/linkedin/gobblin/pulls/339","id":45729701,"html_url":"https://github.com/linkedin/gobblin/pull/339","diff_url":"https://github.com/linkedin/gobblin/pull/339.diff","patch_url":"https://github.com/linkedin/gobblin/pull/339.patch","issue_url":"https://api.github.com/repos/linkedin/gobblin/issues/339","number":339,"state":"open","locked":false,"title":"Gobblin on Yarn POC preview","user":{"login":"liyinan926","id":3709137,"avatar_url":"https://avatars.githubusercontent.com/u/3709137?v=3","gravatar_id":"","url":"https://api.github.com/users/liyinan926","html_url":"https://github.com/liyinan926","followers_url":"https://api.github.com/users/liyinan926/followers","following_url":"https://api.github.com/users/liyinan926/following{/other_user}","gists_url":"https://api.github.com/users/liyinan926/gists{/gist_id}","starred_url":"https://api.github.com/users/liyinan926/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/liyinan926/subscriptions","organizations_url":"https://api.github.com/users/liyinan926/orgs","repos_url":"https://api.github.com/users/liyinan926/repos","events_url":"https://api.github.com/users/liyinan926/events{/privacy}","received_events_url":"https://api.github.com/users/liyinan926/received_events","type":"User","site_admin":false},"body":"This is a preview PR for the Gobblin on Yarn POC. I am still testing this and particularly the part that handles security/authentication so this probably will be updated as I find and fix issues. I will schedule a meeting to go over this PR later this week. ","created_at":"2015-09-22T23:25:36Z","updated_at":"2015-09-30T00:18:45Z","closed_at":null,"merged_at":null,"merge_commit_sha":"87f46f1843e5374d009e2ff3953d1f413681bf4f","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/linkedin/gobblin/pulls/339/commits","review_comments_url":"https://api.github.com/repos/linkedin/gobblin/pulls/339/comments","review_comment_url":"https://api.github.com/repos/linkedin/gobblin/pulls/comments{/number}","comments_url":"https://api.github.com/repos/linkedin/gobblin/issues/339/comments","statuses_url":"https://api.github.com/repos/linkedin/gobblin/statuses/f501adeb3cf90da2afac2b3da88f18a668a1788e","head":{"label":"liyinan926:gobblin-yarn","ref":"gobblin-yarn","sha":"f501adeb3cf90da2afac2b3da88f18a668a1788e","user":{"login":"liyinan926","id":3709137,"avatar_url":"https://avatars.githubusercontent.com/u/3709137?v=3","gravatar_id":"","url":"https://api.github.com/users/liyinan926","html_url":"https://github.com/liyinan926","followers_url":"https://api.github.com/users/liyinan926/followers","following_url":"https://api.github.com/users/liyinan926/following{/other_user}","gists_url":"https://api.github.com/users/liyinan926/gists{/gist_id}","starred_url":"https://api.github.com/users/liyinan926/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/liyinan926/subscriptions","organizations_url":"https://api.github.com/users/liyinan926/orgs","repos_url":"https://api.github.com/users/liyinan926/repos","events_url":"https://api.github.com/users/liyinan926/events{/privacy}","received_events_url":"https://api.github.com/users/liyinan926/received_events","type":"User","site_admin":false},"repo":{"id":31117112,"name":"gobblin","full_name":"liyinan926/gobblin","owner":{"login":"liyinan926","id":3709137,"avatar_url":"https://avatars.githubusercontent.com/u/3709137?v=3","gravatar_id":"","url":"https://api.github.com/users/liyinan926","html_url":"https://github.com/liyinan926","followers_url":"https://api.github.com/users/liyinan926/followers","following_url":"https://api.github.com/users/liyinan926/following{/other_user}","gists_url":"https://api.github.com/users/liyinan926/gists{/gist_id}","starred_url":"https://api.github.com/users/liyinan926/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/liyinan926/subscriptions","organizations_url":"https://api.github.com/users/liyinan926/orgs","repos_url":"https://api.github.com/users/liyinan926/repos","events_url":"https://api.github.com/users/liyinan926/events{/privacy}","received_events_url":"https://api.github.com/users/liyinan926/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/liyinan926/gobblin","description":"","fork":true,"url":"https://api.github.com/repos/liyinan926/gobblin","forks_url":"https://api.github.com/repos/liyinan926/gobblin/forks","keys_url":"https://api.github.com/repos/liyinan926/gobblin/keys{/key_id}","collaborators_url":"https://api.github.com/repos/liyinan926/gobblin/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/liyinan926/gobblin/teams","hooks_url":"https://api.github.com/repos/liyinan926/gobblin/hooks","issue_events_url":"https://api.github.com/repos/liyinan926/gobblin/issues/events{/number}","events_url":"https://api.github.com/repos/liyinan926/gobblin/events","assignees_url":"https://api.github.com/repos/liyinan926/gobblin/assignees{/user}","branches_url":"https://api.github.com/repos/liyinan926/gobblin/branches{/branch}","tags_url":"https://api.github.com/repos/liyinan926/gobblin/tags","blobs_url":"https://api.github.com/repos/liyinan926/gobblin/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/liyinan926/gobblin/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/liyinan926/gobblin/git/refs{/sha}","trees_url":"https://api.github.com/repos/liyinan926/gobblin/git/trees{/sha}","statuses_url":"https://api.github.com/repos/liyinan926/gobblin/statuses/{sha}","languages_url":"https://api.github.com/repos/liyinan926/gobblin/languages","stargazers_url":"https://api.github.com/repos/liyinan926/gobblin/stargazers","contributors_url":"https://api.github.com/repos/liyinan926/gobblin/contributors","subscribers_url":"https://api.github.com/repos/liyinan926/gobblin/subscribers","subscription_url":"https://api.github.com/repos/liyinan926/gobblin/subscription","commits_url":"https://api.github.com/repos/liyinan926/gobblin/commits{/sha}","git_commits_url":"https://api.github.com/repos/liyinan926/gobblin/git/commits{/sha}","comments_url":"https://api.github.com/repos/liyinan926/gobblin/comments{/number}","issue_comment_url":"https://api.github.com/repos/liyinan926/gobblin/issues/comments{/number}","contents_url":"https://api.github.com/repos/liyinan926/gobblin/contents/{+path}","compare_url":"https://api.github.com/repos/liyinan926/gobblin/compare/{base}...{head}","merges_url":"https://api.github.com/repos/liyinan926/gobblin/merges","archive_url":"https://api.github.com/repos/liyinan926/gobblin/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/liyinan926/gobblin/downloads","issues_url":"https://api.github.com/repos/liyinan926/gobblin/issues{/number}","pulls_url":"https://api.github.com/repos/liyinan926/gobblin/pulls{/number}","milestones_url":"https://api.github.com/repos/liyinan926/gobblin/milestones{/number}","notifications_url":"https://api.github.com/repos/liyinan926/gobblin/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/liyinan926/gobblin/labels{/name}","releases_url":"https://api.github.com/repos/liyinan926/gobblin/releases{/id}","created_at":"2015-02-21T06:07:55Z","updated_at":"2015-05-05T00:31:33Z","pushed_at":"2015-09-29T23:12:40Z","git_url":"git://github.com/liyinan926/gobblin.git","ssh_url":"git@github.com:liyinan926/gobblin.git","clone_url":"https://github.com/liyinan926/gobblin.git","svn_url":"https://github.com/liyinan926/gobblin","homepage":null,"size":80555,"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":"linkedin:master","ref":"master","sha":"2e2ce19e9bc8a2f7cb8ec087e1f8776ab192ca0d","user":{"login":"linkedin","id":357098,"avatar_url":"https://avatars.githubusercontent.com/u/357098?v=3","gravatar_id":"","url":"https://api.github.com/users/linkedin","html_url":"https://github.com/linkedin","followers_url":"https://api.github.com/users/linkedin/followers","following_url":"https://api.github.com/users/linkedin/following{/other_user}","gists_url":"https://api.github.com/users/linkedin/gists{/gist_id}","starred_url":"https://api.github.com/users/linkedin/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/linkedin/subscriptions","organizations_url":"https://api.github.com/users/linkedin/orgs","repos_url":"https://api.github.com/users/linkedin/repos","events_url":"https://api.github.com/users/linkedin/events{/privacy}","received_events_url":"https://api.github.com/users/linkedin/received_events","type":"Organization","site_admin":false},"repo":{"id":27392543,"name":"gobblin","full_name":"linkedin/gobblin","owner":{"login":"linkedin","id":357098,"avatar_url":"https://avatars.githubusercontent.com/u/357098?v=3","gravatar_id":"","url":"https://api.github.com/users/linkedin","html_url":"https://github.com/linkedin","followers_url":"https://api.github.com/users/linkedin/followers","following_url":"https://api.github.com/users/linkedin/following{/other_user}","gists_url":"https://api.github.com/users/linkedin/gists{/gist_id}","starred_url":"https://api.github.com/users/linkedin/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/linkedin/subscriptions","organizations_url":"https://api.github.com/users/linkedin/orgs","repos_url":"https://api.github.com/users/linkedin/repos","events_url":"https://api.github.com/users/linkedin/events{/privacy}","received_events_url":"https://api.github.com/users/linkedin/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/linkedin/gobblin","description":"Universal data ingestion framework for Hadoop.","fork":false,"url":"https://api.github.com/repos/linkedin/gobblin","forks_url":"https://api.github.com/repos/linkedin/gobblin/forks","keys_url":"https://api.github.com/repos/linkedin/gobblin/keys{/key_id}","collaborators_url":"https://api.github.com/repos/linkedin/gobblin/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/linkedin/gobblin/teams","hooks_url":"https://api.github.com/repos/linkedin/gobblin/hooks","issue_events_url":"https://api.github.com/repos/linkedin/gobblin/issues/events{/number}","events_url":"https://api.github.com/repos/linkedin/gobblin/events","assignees_url":"https://api.github.com/repos/linkedin/gobblin/assignees{/user}","branches_url":"https://api.github.com/repos/linkedin/gobblin/branches{/branch}","tags_url":"https://api.github.com/repos/linkedin/gobblin/tags","blobs_url":"https://api.github.com/repos/linkedin/gobblin/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/linkedin/gobblin/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/linkedin/gobblin/git/refs{/sha}","trees_url":"https://api.github.com/repos/linkedin/gobblin/git/trees{/sha}","statuses_url":"https://api.github.com/repos/linkedin/gobblin/statuses/{sha}","languages_url":"https://api.github.com/repos/linkedin/gobblin/languages","stargazers_url":"https://api.github.com/repos/linkedin/gobblin/stargazers","contributors_url":"https://api.github.com/repos/linkedin/gobblin/contributors","subscribers_url":"https://api.github.com/repos/linkedin/gobblin/subscribers","subscription_url":"https://api.github.com/repos/linkedin/gobblin/subscription","commits_url":"https://api.github.com/repos/linkedin/gobblin/commits{/sha}","git_commits_url":"https://api.github.com/repos/linkedin/gobblin/git/commits{/sha}","comments_url":"https://api.github.com/repos/linkedin/gobblin/comments{/number}","issue_comment_url":"https://api.github.com/repos/linkedin/gobblin/issues/comments{/number}","contents_url":"https://api.github.com/repos/linkedin/gobblin/contents/{+path}","compare_url":"https://api.github.com/repos/linkedin/gobblin/compare/{base}...{head}","merges_url":"https://api.github.com/repos/linkedin/gobblin/merges","archive_url":"https://api.github.com/repos/linkedin/gobblin/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/linkedin/gobblin/downloads","issues_url":"https://api.github.com/repos/linkedin/gobblin/issues{/number}","pulls_url":"https://api.github.com/repos/linkedin/gobblin/pulls{/number}","milestones_url":"https://api.github.com/repos/linkedin/gobblin/milestones{/number}","notifications_url":"https://api.github.com/repos/linkedin/gobblin/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/linkedin/gobblin/labels{/name}","releases_url":"https://api.github.com/repos/linkedin/gobblin/releases{/id}","created_at":"2014-12-01T18:10:50Z","updated_at":"2015-09-29T11:05:57Z","pushed_at":"2015-09-29T23:12:41Z","git_url":"git://github.com/linkedin/gobblin.git","ssh_url":"git@github.com:linkedin/gobblin.git","clone_url":"https://github.com/linkedin/gobblin.git","svn_url":"https://github.com/linkedin/gobblin","homepage":"https://github.com/linkedin/gobblin/wiki","size":161379,"stargazers_count":197,"watchers_count":197,"language":"Java","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":68,"mirror_url":null,"open_issues_count":11,"forks":68,"open_issues":11,"watchers":197,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/linkedin/gobblin/pulls/339"},"html":{"href":"https://github.com/linkedin/gobblin/pull/339"},"issue":{"href":"https://api.github.com/repos/linkedin/gobblin/issues/339"},"comments":{"href":"https://api.github.com/repos/linkedin/gobblin/issues/339/comments"},"review_comments":{"href":"https://api.github.com/repos/linkedin/gobblin/pulls/339/comments"},"review_comment":{"href":"https://api.github.com/repos/linkedin/gobblin/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/linkedin/gobblin/pulls/339/commits"},"statuses":{"href":"https://api.github.com/repos/linkedin/gobblin/statuses/f501adeb3cf90da2afac2b3da88f18a668a1788e"}}}}