{"action":"created","comment":{"url":"https://api.github.com/repos/codice/ddf/pulls/comments/223416972","pull_request_review_id":162524832,"id":223416972,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDIyMzQxNjk3Mg==","diff_hunk":"@@ -13,110 +13,605 @@\n  */\n package ddf.catalog.util.impl;\n \n-import ddf.catalog.CatalogFramework;\n+import static org.apache.commons.lang.Validate.notNull;\n+\n+import com.google.common.annotations.VisibleForTesting;\n+import com.google.common.base.Objects;\n+import com.google.common.cache.Cache;\n+import com.google.common.cache.CacheBuilder;\n+import com.google.common.util.concurrent.Futures;\n+import com.google.common.util.concurrent.MoreExecutors;\n+import ddf.catalog.source.CatalogProvider;\n+import ddf.catalog.source.CatalogStore;\n+import ddf.catalog.source.ConnectedSource;\n+import ddf.catalog.source.FederatedSource;\n import ddf.catalog.source.Source;\n+import ddf.catalog.source.SourceMonitor;\n+import java.util.Collection;\n+import java.util.Collections;\n+import java.util.List;\n import java.util.Map;\n import java.util.Optional;\n+import java.util.Set;\n+import java.util.concurrent.Callable;\n+import java.util.concurrent.CancellationException;\n+import java.util.concurrent.ExecutionException;\n+import java.util.concurrent.ExecutorService;\n import java.util.concurrent.Executors;\n+import java.util.concurrent.Future;\n import java.util.concurrent.ScheduledExecutorService;\n-import java.util.concurrent.ScheduledFuture;\n+import java.util.concurrent.ThreadFactory;\n import java.util.concurrent.TimeUnit;\n+import java.util.concurrent.TimeoutException;\n+import java.util.stream.Collectors;\n+import java.util.stream.Stream;\n+import javax.annotation.Nullable;\n+import org.apache.commons.lang.StringUtils;\n import org.codice.ddf.platform.util.StandardThreadFactoryBuilder;\n+import org.osgi.framework.Bundle;\n+import org.osgi.framework.BundleContext;\n+import org.osgi.framework.FrameworkUtil;\n+import org.osgi.framework.ServiceEvent;\n+import org.osgi.framework.ServiceReference;\n+import org.osgi.framework.hooks.service.EventListenerHook;\n+import org.osgi.framework.hooks.service.ListenerHook;\n import org.slf4j.Logger;\n import org.slf4j.LoggerFactory;\n \n /**\n- * The SourcePoller is the scheduler of the task to poll all configured sources at a fixed interval\n- * to determine their availability. It is created by the CatalogFramework's blueprint.\n+ * The {@link SourcePoller} checks the availability of all configured {@link Source}s provides a\n+ * non-blocking solution to check whether a {@link Source} is available. The {@link SourcePoller}\n+ * can be scheduled to execute at a configured rate, i.e., the polling interval.\n+ *\n+ * <p>This class maintains a list of all of the {@link Source}s and their last known availability.\n+ * {@link Source}s are added to this list when they are created or destroyed, and {@link Source}\n+ * availability is re-checked when the {@link Source} is modified. A cached map is maintained of all\n+ * the {@link Source}s and their last known availability, i.e., {@link SourceStatus}.\n  *\n- * <p>An isAvailable() method is included in this class so that the caller, nominally the\n- * CatalogFramework, can retrieve the cached availability of a specific source, or have it polled on\n- * demand if there is no availability status cached.\n+ * @see Source#isAvailable()\n+ * @see Source#isAvailable(SourceMonitor)\n+ * @see ddf.catalog.CatalogFramework#getSourceInfo(ddf.catalog.operation.SourceInfoRequest)\n  */\n-public class SourcePoller {\n+public class SourcePoller implements EventListenerHook {\n+\n   private static final Logger LOGGER = LoggerFactory.getLogger(SourcePoller.class);\n \n-  private static final int INITIAL_DELAY = 0;\n+  private static final int EXECUTOR_SERVICE_TERMINATION_TIMEOUT = 5;\n+\n+  private static final TimeUnit EXECUTOR_SERVICE_TERMINATION_TIMEOUT_TIME_UNIT = TimeUnit.SECONDS;\n+\n+  private static final long DEFAULT_AVAILABILITY_CHECK_TIMEOUT = 1;\n+\n+  private static final TimeUnit AVAILABILITY_CHECK_TIMEOUT_TIME_UNIT = TimeUnit.MINUTES;\n+\n+  private long availabilityCheckTimeout = DEFAULT_AVAILABILITY_CHECK_TIMEOUT;\n \n-  private int interval = 1;\n+  private List<ConnectedSource> connectedSources = Collections.emptyList();\n \n-  private ScheduledExecutorService scheduler;\n+  private List<FederatedSource> federatedSources = Collections.emptyList();\n \n-  private ScheduledFuture<?> handle;\n+  private List<CatalogProvider> catalogProviders = Collections.emptyList();\n \n-  private SourcePollerRunner runner;\n+  private List<CatalogStore> catalogStores = Collections.emptyList();\n+\n+  private final ExecutorService sourceAvailabilityChecksThreadPool;\n+\n+  private final Cache<SourceKey, CachedSourceAvailability> cache;\n+\n+  @Nullable private ExecutorService pollingExecutorService;\n+\n+  /** Does not start polling */\n+  public SourcePoller() {\n+    final ThreadFactory threadFactory =","path":"catalog/core/catalog-core-api-impl/src/main/java/ddf/catalog/util/impl/SourcePoller.java","position":106,"original_position":106,"commit_id":"3c47d628300c4b4662830b35f290fc5dced37dea","original_commit_id":"3c47d628300c4b4662830b35f290fc5dced37dea","user":{"login":"clockard","id":5248090,"node_id":"MDQ6VXNlcjUyNDgwOTA=","avatar_url":"https://avatars1.githubusercontent.com/u/5248090?v=4","gravatar_id":"","url":"https://api.github.com/users/clockard","html_url":"https://github.com/clockard","followers_url":"https://api.github.com/users/clockard/followers","following_url":"https://api.github.com/users/clockard/following{/other_user}","gists_url":"https://api.github.com/users/clockard/gists{/gist_id}","starred_url":"https://api.github.com/users/clockard/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/clockard/subscriptions","organizations_url":"https://api.github.com/users/clockard/orgs","repos_url":"https://api.github.com/users/clockard/repos","events_url":"https://api.github.com/users/clockard/events{/privacy}","received_events_url":"https://api.github.com/users/clockard/received_events","type":"User","site_admin":false},"body":"I think we usually pass in executors/threads via blueprint. This will also make it easier to test.","created_at":"2018-10-08T16:00:04Z","updated_at":"2018-10-08T16:51:31Z","html_url":"https://github.com/codice/ddf/pull/3858#discussion_r223416972","pull_request_url":"https://api.github.com/repos/codice/ddf/pulls/3858","author_association":"CONTRIBUTOR","_links":{"self":{"href":"https://api.github.com/repos/codice/ddf/pulls/comments/223416972"},"html":{"href":"https://github.com/codice/ddf/pull/3858#discussion_r223416972"},"pull_request":{"href":"https://api.github.com/repos/codice/ddf/pulls/3858"}}},"pull_request":{"url":"https://api.github.com/repos/codice/ddf/pulls/3858","id":220997412,"node_id":"MDExOlB1bGxSZXF1ZXN0MjIwOTk3NDEy","html_url":"https://github.com/codice/ddf/pull/3858","diff_url":"https://github.com/codice/ddf/pull/3858.diff","patch_url":"https://github.com/codice/ddf/pull/3858.patch","issue_url":"https://api.github.com/repos/codice/ddf/issues/3858","number":3858,"state":"open","locked":false,"title":"[WIP] [2.13.x] DDF-1366 Re-implemented the SourcePoller","user":{"login":"emmberk","id":8041246,"node_id":"MDQ6VXNlcjgwNDEyNDY=","avatar_url":"https://avatars3.githubusercontent.com/u/8041246?v=4","gravatar_id":"","url":"https://api.github.com/users/emmberk","html_url":"https://github.com/emmberk","followers_url":"https://api.github.com/users/emmberk/followers","following_url":"https://api.github.com/users/emmberk/following{/other_user}","gists_url":"https://api.github.com/users/emmberk/gists{/gist_id}","starred_url":"https://api.github.com/users/emmberk/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/emmberk/subscriptions","organizations_url":"https://api.github.com/users/emmberk/orgs","repos_url":"https://api.github.com/users/emmberk/repos","events_url":"https://api.github.com/users/emmberk/events{/privacy}","received_events_url":"https://api.github.com/users/emmberk/received_events","type":"User","site_admin":false},"body":"# This is a WIP PR. Do not merge.\r\nThese changes can be built and tested, but there are still some TODOs and the unit tests are not complete. \r\n#### What does this PR do?\r\nThis PR re-implements the SourcePoller to fix some issues where the SourcePoller was returning reporting availabilities and was not recoverable without restarting. This PR also improves the SourcePoller so that the CatalogFramework#getSourceInfo can return lastAvailabilityDates. This is necessary so that the Sources tab in the Admin Console can use the SourcePoller.\r\n\r\nhttps://github.com/codice/ddf/pull/3830 is related (2.13.x) PR to update the Sources tab in the Admin Console to use the SourcePoller instead of querying sources directly. https://github.com/codice/ddf/pull/3799 is a related (master) PR to update some javadoc.\r\n\r\nDifferences/improvements from the current SourcePoller:\r\n\r\n- The cache does not keep any reference to the Sources. (See [DDF-12789](https://codice.atlassian.net/browse/DDF-2789)). At every poll interval, all of the registered Sources are gathered regardless of what is currently in the cache.\r\n- The SourcePoller and SourcePollerRunner are combined. I may decide to break these back up if cache expiration is not needed.\r\n- The SourcePoller reports more specific availabilities including TIMEOUT/EXCEPTION, if the availability has not yet been checked, and the time that the availability was last checked.\r\n- The SourcePoller no longer caches other Source details, like content types. It only caches the availability.\r\n\r\n#### Who is reviewing it? \r\n@peterhuffer @kcover @mdang8 @pvargas @clockard @coyotesqrl @lessarderic @stustison @pklinef \r\n<!--#### Select relevant component teams: \r\n@codice/build \r\n@codice/continuous-integration \r\n@codice/core-apis \r\n@codice/data \r\n@codice/docs \r\n@codice/io \r\n@codice/ogc \r\n@codice/security \r\n@codice/solr \r\n@codice/test \r\n@codice/ui \r\n@codice/website \r\n-->\r\n#### Ask 2 committers to review/merge the PR and tag them here.\r\nThis is a WIP PR. No comitters are needed yet.\r\n<!--\r\nIf you don't know who to ask, you can request reviews in https://groups.google.com/forum/#!forum/ddf-developers .\r\n(please choose ONLY two committers from below, delete the rest)\r\n-->\r\n<!--#### How should this be tested?\r\n(List steps with links to updated documentation)-->\r\n#### What are the relevant tickets?\r\n[DDF-1366](https://codice.atlassian.net/browse/DDF-1366)\r\n#### Checklist:\r\n- [ ] Documentation Updated\r\n- [ ] Update / Add Unit Tests\r\n- [ ] Update / Add Integration Tests\r\n\r\n#### Notes on Review Process\r\nPlease see [Notes on Review Process](https://codice.atlassian.net/wiki/spaces/DDF/pages/71946981/Pull+Request+Guidelines) for further guidance on requirements for merging and abbreviated reviews. \r\n\r\n#### Review Comment Legend:\r\n- ✏️ (Pencil) This comment is a nitpick or style suggestion, no action required for approval. This comment should provide a suggestion either as an in line code snippet or a gist. \r\n- ❓ (Question Mark) This comment is to gain a clearer understanding of design or code choices, clarification is required but action may not be necessary for approval.\r\n- ❗ (Exclamation Mark) This comment is critical and requires clarification or action before approval.\r\n","created_at":"2018-10-08T03:41:47Z","updated_at":"2018-10-08T16:51:31Z","closed_at":null,"merged_at":null,"merge_commit_sha":"20fe7df2fd12c647b04bc9ce27acb9c4bb49ec77","assignee":{"login":"pklinef","id":700518,"node_id":"MDQ6VXNlcjcwMDUxOA==","avatar_url":"https://avatars1.githubusercontent.com/u/700518?v=4","gravatar_id":"","url":"https://api.github.com/users/pklinef","html_url":"https://github.com/pklinef","followers_url":"https://api.github.com/users/pklinef/followers","following_url":"https://api.github.com/users/pklinef/following{/other_user}","gists_url":"https://api.github.com/users/pklinef/gists{/gist_id}","starred_url":"https://api.github.com/users/pklinef/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pklinef/subscriptions","organizations_url":"https://api.github.com/users/pklinef/orgs","repos_url":"https://api.github.com/users/pklinef/repos","events_url":"https://api.github.com/users/pklinef/events{/privacy}","received_events_url":"https://api.github.com/users/pklinef/received_events","type":"User","site_admin":false},"assignees":[{"login":"pklinef","id":700518,"node_id":"MDQ6VXNlcjcwMDUxOA==","avatar_url":"https://avatars1.githubusercontent.com/u/700518?v=4","gravatar_id":"","url":"https://api.github.com/users/pklinef","html_url":"https://github.com/pklinef","followers_url":"https://api.github.com/users/pklinef/followers","following_url":"https://api.github.com/users/pklinef/following{/other_user}","gists_url":"https://api.github.com/users/pklinef/gists{/gist_id}","starred_url":"https://api.github.com/users/pklinef/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pklinef/subscriptions","organizations_url":"https://api.github.com/users/pklinef/orgs","repos_url":"https://api.github.com/users/pklinef/repos","events_url":"https://api.github.com/users/pklinef/events{/privacy}","received_events_url":"https://api.github.com/users/pklinef/received_events","type":"User","site_admin":false},{"login":"coyotesqrl","id":1469860,"node_id":"MDQ6VXNlcjE0Njk4NjA=","avatar_url":"https://avatars2.githubusercontent.com/u/1469860?v=4","gravatar_id":"","url":"https://api.github.com/users/coyotesqrl","html_url":"https://github.com/coyotesqrl","followers_url":"https://api.github.com/users/coyotesqrl/followers","following_url":"https://api.github.com/users/coyotesqrl/following{/other_user}","gists_url":"https://api.github.com/users/coyotesqrl/gists{/gist_id}","starred_url":"https://api.github.com/users/coyotesqrl/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/coyotesqrl/subscriptions","organizations_url":"https://api.github.com/users/coyotesqrl/orgs","repos_url":"https://api.github.com/users/coyotesqrl/repos","events_url":"https://api.github.com/users/coyotesqrl/events{/privacy}","received_events_url":"https://api.github.com/users/coyotesqrl/received_events","type":"User","site_admin":false},{"login":"clockard","id":5248090,"node_id":"MDQ6VXNlcjUyNDgwOTA=","avatar_url":"https://avatars1.githubusercontent.com/u/5248090?v=4","gravatar_id":"","url":"https://api.github.com/users/clockard","html_url":"https://github.com/clockard","followers_url":"https://api.github.com/users/clockard/followers","following_url":"https://api.github.com/users/clockard/following{/other_user}","gists_url":"https://api.github.com/users/clockard/gists{/gist_id}","starred_url":"https://api.github.com/users/clockard/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/clockard/subscriptions","organizations_url":"https://api.github.com/users/clockard/orgs","repos_url":"https://api.github.com/users/clockard/repos","events_url":"https://api.github.com/users/clockard/events{/privacy}","received_events_url":"https://api.github.com/users/clockard/received_events","type":"User","site_admin":false},{"login":"lessarderic","id":11377558,"node_id":"MDQ6VXNlcjExMzc3NTU4","avatar_url":"https://avatars1.githubusercontent.com/u/11377558?v=4","gravatar_id":"","url":"https://api.github.com/users/lessarderic","html_url":"https://github.com/lessarderic","followers_url":"https://api.github.com/users/lessarderic/followers","following_url":"https://api.github.com/users/lessarderic/following{/other_user}","gists_url":"https://api.github.com/users/lessarderic/gists{/gist_id}","starred_url":"https://api.github.com/users/lessarderic/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lessarderic/subscriptions","organizations_url":"https://api.github.com/users/lessarderic/orgs","repos_url":"https://api.github.com/users/lessarderic/repos","events_url":"https://api.github.com/users/lessarderic/events{/privacy}","received_events_url":"https://api.github.com/users/lessarderic/received_events","type":"User","site_admin":false}],"requested_reviewers":[{"login":"stustison","id":4391679,"node_id":"MDQ6VXNlcjQzOTE2Nzk=","avatar_url":"https://avatars0.githubusercontent.com/u/4391679?v=4","gravatar_id":"","url":"https://api.github.com/users/stustison","html_url":"https://github.com/stustison","followers_url":"https://api.github.com/users/stustison/followers","following_url":"https://api.github.com/users/stustison/following{/other_user}","gists_url":"https://api.github.com/users/stustison/gists{/gist_id}","starred_url":"https://api.github.com/users/stustison/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/stustison/subscriptions","organizations_url":"https://api.github.com/users/stustison/orgs","repos_url":"https://api.github.com/users/stustison/repos","events_url":"https://api.github.com/users/stustison/events{/privacy}","received_events_url":"https://api.github.com/users/stustison/received_events","type":"User","site_admin":false},{"login":"ricklarsen","id":10619999,"node_id":"MDQ6VXNlcjEwNjE5OTk5","avatar_url":"https://avatars2.githubusercontent.com/u/10619999?v=4","gravatar_id":"","url":"https://api.github.com/users/ricklarsen","html_url":"https://github.com/ricklarsen","followers_url":"https://api.github.com/users/ricklarsen/followers","following_url":"https://api.github.com/users/ricklarsen/following{/other_user}","gists_url":"https://api.github.com/users/ricklarsen/gists{/gist_id}","starred_url":"https://api.github.com/users/ricklarsen/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ricklarsen/subscriptions","organizations_url":"https://api.github.com/users/ricklarsen/orgs","repos_url":"https://api.github.com/users/ricklarsen/repos","events_url":"https://api.github.com/users/ricklarsen/events{/privacy}","received_events_url":"https://api.github.com/users/ricklarsen/received_events","type":"User","site_admin":false}],"requested_teams":[],"labels":[],"milestone":{"url":"https://api.github.com/repos/codice/ddf/milestones/24","html_url":"https://github.com/codice/ddf/milestone/24","labels_url":"https://api.github.com/repos/codice/ddf/milestones/24/labels","id":3673130,"node_id":"MDk6TWlsZXN0b25lMzY3MzEzMA==","number":24,"title":"2.13.3","description":"","creator":{"login":"clockard","id":5248090,"node_id":"MDQ6VXNlcjUyNDgwOTA=","avatar_url":"https://avatars1.githubusercontent.com/u/5248090?v=4","gravatar_id":"","url":"https://api.github.com/users/clockard","html_url":"https://github.com/clockard","followers_url":"https://api.github.com/users/clockard/followers","following_url":"https://api.github.com/users/clockard/following{/other_user}","gists_url":"https://api.github.com/users/clockard/gists{/gist_id}","starred_url":"https://api.github.com/users/clockard/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/clockard/subscriptions","organizations_url":"https://api.github.com/users/clockard/orgs","repos_url":"https://api.github.com/users/clockard/repos","events_url":"https://api.github.com/users/clockard/events{/privacy}","received_events_url":"https://api.github.com/users/clockard/received_events","type":"User","site_admin":false},"open_issues":6,"closed_issues":9,"state":"open","created_at":"2018-09-20T03:35:54Z","updated_at":"2018-10-08T15:13:27Z","due_on":null,"closed_at":null},"commits_url":"https://api.github.com/repos/codice/ddf/pulls/3858/commits","review_comments_url":"https://api.github.com/repos/codice/ddf/pulls/3858/comments","review_comment_url":"https://api.github.com/repos/codice/ddf/pulls/comments{/number}","comments_url":"https://api.github.com/repos/codice/ddf/issues/3858/comments","statuses_url":"https://api.github.com/repos/codice/ddf/statuses/3c47d628300c4b4662830b35f290fc5dced37dea","head":{"label":"emmberk:DDF-1366","ref":"DDF-1366","sha":"3c47d628300c4b4662830b35f290fc5dced37dea","user":{"login":"emmberk","id":8041246,"node_id":"MDQ6VXNlcjgwNDEyNDY=","avatar_url":"https://avatars3.githubusercontent.com/u/8041246?v=4","gravatar_id":"","url":"https://api.github.com/users/emmberk","html_url":"https://github.com/emmberk","followers_url":"https://api.github.com/users/emmberk/followers","following_url":"https://api.github.com/users/emmberk/following{/other_user}","gists_url":"https://api.github.com/users/emmberk/gists{/gist_id}","starred_url":"https://api.github.com/users/emmberk/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/emmberk/subscriptions","organizations_url":"https://api.github.com/users/emmberk/orgs","repos_url":"https://api.github.com/users/emmberk/repos","events_url":"https://api.github.com/users/emmberk/events{/privacy}","received_events_url":"https://api.github.com/users/emmberk/received_events","type":"User","site_admin":false},"repo":{"id":60542616,"node_id":"MDEwOlJlcG9zaXRvcnk2MDU0MjYxNg==","name":"ddf","full_name":"emmberk/ddf","private":false,"owner":{"login":"emmberk","id":8041246,"node_id":"MDQ6VXNlcjgwNDEyNDY=","avatar_url":"https://avatars3.githubusercontent.com/u/8041246?v=4","gravatar_id":"","url":"https://api.github.com/users/emmberk","html_url":"https://github.com/emmberk","followers_url":"https://api.github.com/users/emmberk/followers","following_url":"https://api.github.com/users/emmberk/following{/other_user}","gists_url":"https://api.github.com/users/emmberk/gists{/gist_id}","starred_url":"https://api.github.com/users/emmberk/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/emmberk/subscriptions","organizations_url":"https://api.github.com/users/emmberk/orgs","repos_url":"https://api.github.com/users/emmberk/repos","events_url":"https://api.github.com/users/emmberk/events{/privacy}","received_events_url":"https://api.github.com/users/emmberk/received_events","type":"User","site_admin":false},"html_url":"https://github.com/emmberk/ddf","description":"Distributed Data Framework - an open source, modular integration framework.","fork":true,"url":"https://api.github.com/repos/emmberk/ddf","forks_url":"https://api.github.com/repos/emmberk/ddf/forks","keys_url":"https://api.github.com/repos/emmberk/ddf/keys{/key_id}","collaborators_url":"https://api.github.com/repos/emmberk/ddf/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/emmberk/ddf/teams","hooks_url":"https://api.github.com/repos/emmberk/ddf/hooks","issue_events_url":"https://api.github.com/repos/emmberk/ddf/issues/events{/number}","events_url":"https://api.github.com/repos/emmberk/ddf/events","assignees_url":"https://api.github.com/repos/emmberk/ddf/assignees{/user}","branches_url":"https://api.github.com/repos/emmberk/ddf/branches{/branch}","tags_url":"https://api.github.com/repos/emmberk/ddf/tags","blobs_url":"https://api.github.com/repos/emmberk/ddf/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/emmberk/ddf/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/emmberk/ddf/git/refs{/sha}","trees_url":"https://api.github.com/repos/emmberk/ddf/git/trees{/sha}","statuses_url":"https://api.github.com/repos/emmberk/ddf/statuses/{sha}","languages_url":"https://api.github.com/repos/emmberk/ddf/languages","stargazers_url":"https://api.github.com/repos/emmberk/ddf/stargazers","contributors_url":"https://api.github.com/repos/emmberk/ddf/contributors","subscribers_url":"https://api.github.com/repos/emmberk/ddf/subscribers","subscription_url":"https://api.github.com/repos/emmberk/ddf/subscription","commits_url":"https://api.github.com/repos/emmberk/ddf/commits{/sha}","git_commits_url":"https://api.github.com/repos/emmberk/ddf/git/commits{/sha}","comments_url":"https://api.github.com/repos/emmberk/ddf/comments{/number}","issue_comment_url":"https://api.github.com/repos/emmberk/ddf/issues/comments{/number}","contents_url":"https://api.github.com/repos/emmberk/ddf/contents/{+path}","compare_url":"https://api.github.com/repos/emmberk/ddf/compare/{base}...{head}","merges_url":"https://api.github.com/repos/emmberk/ddf/merges","archive_url":"https://api.github.com/repos/emmberk/ddf/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/emmberk/ddf/downloads","issues_url":"https://api.github.com/repos/emmberk/ddf/issues{/number}","pulls_url":"https://api.github.com/repos/emmberk/ddf/pulls{/number}","milestones_url":"https://api.github.com/repos/emmberk/ddf/milestones{/number}","notifications_url":"https://api.github.com/repos/emmberk/ddf/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/emmberk/ddf/labels{/name}","releases_url":"https://api.github.com/repos/emmberk/ddf/releases{/id}","deployments_url":"https://api.github.com/repos/emmberk/ddf/deployments","created_at":"2016-06-06T16:18:42Z","updated_at":"2018-03-13T23:11:03Z","pushed_at":"2018-10-08T14:47:34Z","git_url":"git://github.com/emmberk/ddf.git","ssh_url":"git@github.com:emmberk/ddf.git","clone_url":"https://github.com/emmberk/ddf.git","svn_url":"https://github.com/emmberk/ddf","homepage":"http://ddf.codice.org","size":205056,"stargazers_count":0,"watchers_count":0,"language":"Java","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":0,"license":{"key":"other","name":"NOASSERTION","spdx_id":"NOASSERTION","url":null,"node_id":"MDc6TGljZW5zZTA="},"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"codice:2.13.x","ref":"2.13.x","sha":"60625ecf2a35857ab03e32da4fd2adc743473ffc","user":{"login":"codice","id":2386734,"node_id":"MDEyOk9yZ2FuaXphdGlvbjIzODY3MzQ=","avatar_url":"https://avatars2.githubusercontent.com/u/2386734?v=4","gravatar_id":"","url":"https://api.github.com/users/codice","html_url":"https://github.com/codice","followers_url":"https://api.github.com/users/codice/followers","following_url":"https://api.github.com/users/codice/following{/other_user}","gists_url":"https://api.github.com/users/codice/gists{/gist_id}","starred_url":"https://api.github.com/users/codice/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/codice/subscriptions","organizations_url":"https://api.github.com/users/codice/orgs","repos_url":"https://api.github.com/users/codice/repos","events_url":"https://api.github.com/users/codice/events{/privacy}","received_events_url":"https://api.github.com/users/codice/received_events","type":"Organization","site_admin":false},"repo":{"id":15173563,"node_id":"MDEwOlJlcG9zaXRvcnkxNTE3MzU2Mw==","name":"ddf","full_name":"codice/ddf","private":false,"owner":{"login":"codice","id":2386734,"node_id":"MDEyOk9yZ2FuaXphdGlvbjIzODY3MzQ=","avatar_url":"https://avatars2.githubusercontent.com/u/2386734?v=4","gravatar_id":"","url":"https://api.github.com/users/codice","html_url":"https://github.com/codice","followers_url":"https://api.github.com/users/codice/followers","following_url":"https://api.github.com/users/codice/following{/other_user}","gists_url":"https://api.github.com/users/codice/gists{/gist_id}","starred_url":"https://api.github.com/users/codice/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/codice/subscriptions","organizations_url":"https://api.github.com/users/codice/orgs","repos_url":"https://api.github.com/users/codice/repos","events_url":"https://api.github.com/users/codice/events{/privacy}","received_events_url":"https://api.github.com/users/codice/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/codice/ddf","description":"DDF Distributed Data Framework - an open source, modular integration framework.","fork":false,"url":"https://api.github.com/repos/codice/ddf","forks_url":"https://api.github.com/repos/codice/ddf/forks","keys_url":"https://api.github.com/repos/codice/ddf/keys{/key_id}","collaborators_url":"https://api.github.com/repos/codice/ddf/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/codice/ddf/teams","hooks_url":"https://api.github.com/repos/codice/ddf/hooks","issue_events_url":"https://api.github.com/repos/codice/ddf/issues/events{/number}","events_url":"https://api.github.com/repos/codice/ddf/events","assignees_url":"https://api.github.com/repos/codice/ddf/assignees{/user}","branches_url":"https://api.github.com/repos/codice/ddf/branches{/branch}","tags_url":"https://api.github.com/repos/codice/ddf/tags","blobs_url":"https://api.github.com/repos/codice/ddf/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/codice/ddf/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/codice/ddf/git/refs{/sha}","trees_url":"https://api.github.com/repos/codice/ddf/git/trees{/sha}","statuses_url":"https://api.github.com/repos/codice/ddf/statuses/{sha}","languages_url":"https://api.github.com/repos/codice/ddf/languages","stargazers_url":"https://api.github.com/repos/codice/ddf/stargazers","contributors_url":"https://api.github.com/repos/codice/ddf/contributors","subscribers_url":"https://api.github.com/repos/codice/ddf/subscribers","subscription_url":"https://api.github.com/repos/codice/ddf/subscription","commits_url":"https://api.github.com/repos/codice/ddf/commits{/sha}","git_commits_url":"https://api.github.com/repos/codice/ddf/git/commits{/sha}","comments_url":"https://api.github.com/repos/codice/ddf/comments{/number}","issue_comment_url":"https://api.github.com/repos/codice/ddf/issues/comments{/number}","contents_url":"https://api.github.com/repos/codice/ddf/contents/{+path}","compare_url":"https://api.github.com/repos/codice/ddf/compare/{base}...{head}","merges_url":"https://api.github.com/repos/codice/ddf/merges","archive_url":"https://api.github.com/repos/codice/ddf/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/codice/ddf/downloads","issues_url":"https://api.github.com/repos/codice/ddf/issues{/number}","pulls_url":"https://api.github.com/repos/codice/ddf/pulls{/number}","milestones_url":"https://api.github.com/repos/codice/ddf/milestones{/number}","notifications_url":"https://api.github.com/repos/codice/ddf/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/codice/ddf/labels{/name}","releases_url":"https://api.github.com/repos/codice/ddf/releases{/id}","deployments_url":"https://api.github.com/repos/codice/ddf/deployments","created_at":"2013-12-13T20:38:28Z","updated_at":"2018-10-07T16:15:51Z","pushed_at":"2018-10-08T15:59:40Z","git_url":"git://github.com/codice/ddf.git","ssh_url":"git@github.com:codice/ddf.git","clone_url":"https://github.com/codice/ddf.git","svn_url":"https://github.com/codice/ddf","homepage":"http://ddf.codice.org","size":411433,"stargazers_count":93,"watchers_count":93,"language":"Java","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":true,"forks_count":155,"mirror_url":null,"archived":false,"open_issues_count":39,"license":{"key":"other","name":"NOASSERTION","spdx_id":"NOASSERTION","url":null,"node_id":"MDc6TGljZW5zZTA="},"forks":155,"open_issues":39,"watchers":93,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/codice/ddf/pulls/3858"},"html":{"href":"https://github.com/codice/ddf/pull/3858"},"issue":{"href":"https://api.github.com/repos/codice/ddf/issues/3858"},"comments":{"href":"https://api.github.com/repos/codice/ddf/issues/3858/comments"},"review_comments":{"href":"https://api.github.com/repos/codice/ddf/pulls/3858/comments"},"review_comment":{"href":"https://api.github.com/repos/codice/ddf/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/codice/ddf/pulls/3858/commits"},"statuses":{"href":"https://api.github.com/repos/codice/ddf/statuses/3c47d628300c4b4662830b35f290fc5dced37dea"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"clockard"}}