{"action":"created","comment":{"url":"https://api.github.com/repos/codice/ddf/pulls/comments/135964854","pull_request_review_id":59439513,"id":135964854,"diff_hunk":"@@ -0,0 +1,174 @@\n+/**\n+ * Copyright (c) Codice Foundation\n+ * <p>\n+ * This is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser\n+ * General Public License as published by the Free Software Foundation, either version 3 of the\n+ * License, or any later version.\n+ * <p>\n+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without\n+ * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n+ * Lesser General Public License for more details. A copy of the GNU Lesser General Public License\n+ * is distributed along with this program and can be found at\n+ * <http://www.gnu.org/licenses/lgpl.html>.\n+ */\n+package org.codice.ddf.configuration.admin;\n+\n+import java.io.File;\n+import java.net.MalformedURLException;\n+import java.net.URI;\n+import java.net.URISyntaxException;\n+import java.net.URL;\n+import java.nio.file.Path;\n+import java.nio.file.PathMatcher;\n+import java.nio.file.Paths;\n+import java.util.HashSet;\n+import java.util.Map;\n+import java.util.Set;\n+import java.util.UUID;\n+import java.util.function.Function;\n+import java.util.stream.Collectors;\n+import java.util.stream.Stream;\n+\n+import org.apache.commons.io.FilenameUtils;\n+import org.apache.commons.lang.Validate;\n+import org.apache.felix.fileinstall.internal.DirectoryWatcher;\n+import org.codice.ddf.configuration.persistence.PersistenceStrategy;\n+import org.codice.ddf.migration.ExportMigrationContext;\n+import org.codice.ddf.migration.ExportMigrationContextProxy;\n+import org.codice.ddf.migration.ExportMigrationEntry;\n+import org.codice.ddf.migration.MigrationEntry;\n+import org.codice.ddf.migration.MigrationWarning;\n+import org.osgi.service.cm.Configuration;\n+import org.slf4j.Logger;\n+import org.slf4j.LoggerFactory;\n+\n+/**\n+ * This class extends on the {@link ExportMigrationContext} interface to pre-create entries for\n+ * all configuration objects.\n+ */\n+public class ExportMigrationConfigurationAdminContext extends ExportMigrationContextProxy {\n+    private static final Logger LOGGER = LoggerFactory.getLogger(\n+            ExportMigrationConfigurationAdminContext.class);\n+\n+    private final ConfigurationAdminMigratable admin;\n+\n+    private final Set<String> warnedExtensions = new HashSet<>(8);\n+\n+    private final Map<Path, ExportMigrationEntry> entries;\n+\n+    public ExportMigrationConfigurationAdminContext(ExportMigrationContext context,\n+            ConfigurationAdminMigratable admin, Configuration[] configs) {\n+        super(context);\n+        Validate.notNull(admin, \"invalid null configuration admin migratable\");\n+        Validate.notNull(configs, \"invalid null configurations\");\n+        this.admin = admin;\n+        this.entries = Stream.of(configs)\n+                .map(this::getEntry)\n+                .collect(Collectors.toMap(MigrationEntry::getPath, Function.identity()));\n+    }\n+\n+    public Stream<ExportMigrationEntry> entries() {\n+        return entries.values()\n+                .stream();\n+    }\n+\n+    @Override\n+    public ExportMigrationEntry getEntry(Path path) {\n+        throw new IllegalStateException(\"should not be called\");\n+    }\n+\n+    @Override\n+    public Stream<ExportMigrationEntry> entries(Path path) {\n+        throw new IllegalStateException(\"should not be called\");\n+    }\n+\n+    @Override\n+    public Stream<ExportMigrationEntry> entries(Path path, PathMatcher filter) {\n+        throw new IllegalStateException(\"should not be called\");\n+    }\n+\n+    private ExportMigrationEntry getEntry(Configuration configuration) {\n+        Path path = getPathFromConfiguration(configuration);\n+        final String extn = FilenameUtils.getExtension(path.toString());\n+        PersistenceStrategy ps = admin.getPersister(extn);\n+\n+        if (ps == null) {\n+            ps = admin.getDefaultPersister();\n+            if (warnedExtensions.add(extn)) {\n+                getReport().record(new MigrationWarning(String.format(\n+                        \"Persistence strategy [%s] is not defined; defaulting to [%s]\",\n+                        extn,\n+                        ps.getExtension())));\n+            }\n+            path = Paths.get(\n+                    path.toString() + FilenameUtils.EXTENSION_SEPARATOR + ps.getExtension());\n+        }\n+        return new ExportMigrationConfigurationAdminEntry(super.getEntry(path), configuration, ps);\n+    }\n+\n+    private Path getPathFromConfiguration(Configuration configuration) {\n+        final Object o = configuration.getProperties()\n+                .get(DirectoryWatcher.FILENAME);\n+        Path path = null;\n+\n+        if (o != null) {\n+            try {\n+                if (o instanceof URL) {\n+                    path = new File(((URL) o).toURI()).toPath();\n+                } else if (o instanceof URI) {\n+                    path = new File((URI) o).toPath();\n+                } else if (o instanceof String) {\n+                    path = new File(new URL((String) o).toURI()).toPath();\n+                } else if (o instanceof File) {\n+                    path = ((File) o).toPath();\n+                } else if (o instanceof Path) {\n+                    path = (Path) o;\n+                } else {\n+                    path = constructPath(configuration);\n+                    LOGGER.debug(\"unsupported {} property from '{}'\", DirectoryWatcher.FILENAME, o);\n+                    getReport().record(new MigrationWarning(\n+                            \"Path [%s] from %s property for configuration [%s] is of an unsupported format; exporting as [%s].\",\n+                            o,\n+                            DirectoryWatcher.FILENAME,\n+                            configuration.getPid(),\n+                            path));\n+                }\n+            } catch (MalformedURLException | URISyntaxException e) {\n+                path = constructPath(configuration);\n+                LOGGER.debug(String.format(\"failed to parse %s property from '%s'; \",\n+                        DirectoryWatcher.FILENAME,\n+                        o), e);\n+                getReport().record(new MigrationWarning(\n+                        \"Path [%s] from %s property for configuration [%s] cannot be parsed; exporting as [%s].\",\n+                        o,\n+                        DirectoryWatcher.FILENAME,\n+                        configuration.getPid(),\n+                        path));\n+            }\n+        } else {\n+            path = constructPath(configuration);\n+        }\n+        // ignore the whole path if any (there shouldn't be any other than etc) and force it to be under etc\n+        return Paths.get(\"etc\")\n+                .resolve(path.getFileName());\n+    }\n+\n+    private Path constructPath(Configuration configuration) {","path":"platform/migration/platform-migration/src/main/java/org/codice/ddf/configuration/admin/ExportMigrationConfigurationAdminContext.java","position":156,"original_position":156,"commit_id":"23132fce7d06e2a22a3f794ef807168c93b17b4d","original_commit_id":"23132fce7d06e2a22a3f794ef807168c93b17b4d","user":{"login":"paouelle","id":10549555,"avatar_url":"https://avatars0.githubusercontent.com/u/10549555?v=4","gravatar_id":"","url":"https://api.github.com/users/paouelle","html_url":"https://github.com/paouelle","followers_url":"https://api.github.com/users/paouelle/followers","following_url":"https://api.github.com/users/paouelle/following{/other_user}","gists_url":"https://api.github.com/users/paouelle/gists{/gist_id}","starred_url":"https://api.github.com/users/paouelle/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/paouelle/subscriptions","organizations_url":"https://api.github.com/users/paouelle/orgs","repos_url":"https://api.github.com/users/paouelle/repos","events_url":"https://api.github.com/users/paouelle/events{/privacy}","received_events_url":"https://api.github.com/users/paouelle/received_events","type":"User","site_admin":false},"body":"... and you didn't change it when you built the test cases 😛 \r\nI renamed it.","created_at":"2017-08-30T03:56:21Z","updated_at":"2017-08-30T03:56:21Z","html_url":"https://github.com/codice/ddf/pull/2174#discussion_r135964854","pull_request_url":"https://api.github.com/repos/codice/ddf/pulls/2174","author_association":"CONTRIBUTOR","_links":{"self":{"href":"https://api.github.com/repos/codice/ddf/pulls/comments/135964854"},"html":{"href":"https://github.com/codice/ddf/pull/2174#discussion_r135964854"},"pull_request":{"href":"https://api.github.com/repos/codice/ddf/pulls/2174"}},"in_reply_to_id":135868785},"pull_request":{"url":"https://api.github.com/repos/codice/ddf/pulls/2174","id":133361200,"html_url":"https://github.com/codice/ddf/pull/2174","diff_url":"https://github.com/codice/ddf/pull/2174.diff","patch_url":"https://github.com/codice/ddf/pull/2174.patch","issue_url":"https://api.github.com/repos/codice/ddf/issues/2174","number":2174,"state":"open","locked":false,"title":"DDF-3142 - New migration API","user":{"login":"paouelle","id":10549555,"avatar_url":"https://avatars0.githubusercontent.com/u/10549555?v=4","gravatar_id":"","url":"https://api.github.com/users/paouelle","html_url":"https://github.com/paouelle","followers_url":"https://api.github.com/users/paouelle/followers","following_url":"https://api.github.com/users/paouelle/following{/other_user}","gists_url":"https://api.github.com/users/paouelle/gists{/gist_id}","starred_url":"https://api.github.com/users/paouelle/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/paouelle/subscriptions","organizations_url":"https://api.github.com/users/paouelle/orgs","repos_url":"https://api.github.com/users/paouelle/repos","events_url":"https://api.github.com/users/paouelle/events{/privacy}","received_events_url":"https://api.github.com/users/paouelle/received_events","type":"User","site_admin":false},"body":"#### What does this PR do?\r\nThis is the first PR related to migration export/import.\r\n\r\n#### Who is reviewing it? \r\n@brjeter @Lambeaux @figliold \r\n\r\n(please choose AT LEAST two reviewers that need to approve the PR before it can get merged)\r\n#### Select relevant component teams: \r\nhttps://github.com/orgs/codice/teams\r\n\r\n#### Choose 2 committers to review/merge the PR. \r\n(please choose ONLY two committers from below, delete the rest)\r\n@coyotesqrl\r\n@pklinef\r\n@lessarderic\r\n\r\n#### How should this be tested? (List steps with links to updated documentation)\r\nThis should be tested on both Linux/Mac and Windows. Unzip DDF, install and configure it then perform migration:export. Copy the export file out. Delete DDF completely. Re-unzip DDF and install then perform migration:import.\r\n\r\n#### Any background context you want to provide?\r\nThe migration API is changed to handle the import side. It will also abstract the format of the export so it becomes unknown to the various migratable. In our case, we will start exporting in a zip file. It will also be used in subsequent tickets where we will encrypt, sign, and checksum the generated zip file and where auditing will be done.\r\n\r\nTo simplify the review process, it is suggested to subdivide it as follow:\r\n1- API - everything under platform/migration/platform-migratable-api\r\n2- Framework implementation - everything under platform/migration/platform-migration minus the admin package\r\n3- Config Admin Migratable - the admin package under platform/migration/platform-migration\r\n4- Platform Migratable - everything under platform/platform-migratable\r\n5- Security Migratable - everything under platform/security/security-migratable\r\n6- Admin Commands - everything under platform/admin/core/admin-core-migration-commands\r\n\r\n#### What are the relevant tickets?\r\n[DDF-3142](https://codice.atlassian.net/browse/DDF-3142)\r\n\r\n#### Screenshots (if appropriate)\r\n#### Checklist:\r\n- [ ] Documentation Updated\r\n- [ ] Update / Add Unit Tests\r\n- [ ] Update / Add Integration Tests\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":"2017-07-31T23:47:12Z","updated_at":"2017-08-30T03:56:21Z","closed_at":null,"merged_at":null,"merge_commit_sha":"58fd80808b4358997d3e718e10f6f98f8931a826","assignee":{"login":"pklinef","id":700518,"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,"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,"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":"lessarderic","id":11377558,"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":[],"milestone":null,"commits_url":"https://api.github.com/repos/codice/ddf/pulls/2174/commits","review_comments_url":"https://api.github.com/repos/codice/ddf/pulls/2174/comments","review_comment_url":"https://api.github.com/repos/codice/ddf/pulls/comments{/number}","comments_url":"https://api.github.com/repos/codice/ddf/issues/2174/comments","statuses_url":"https://api.github.com/repos/codice/ddf/statuses/23132fce7d06e2a22a3f794ef807168c93b17b4d","head":{"label":"paouelle:DDF-3142","ref":"DDF-3142","sha":"23132fce7d06e2a22a3f794ef807168c93b17b4d","user":{"login":"paouelle","id":10549555,"avatar_url":"https://avatars0.githubusercontent.com/u/10549555?v=4","gravatar_id":"","url":"https://api.github.com/users/paouelle","html_url":"https://github.com/paouelle","followers_url":"https://api.github.com/users/paouelle/followers","following_url":"https://api.github.com/users/paouelle/following{/other_user}","gists_url":"https://api.github.com/users/paouelle/gists{/gist_id}","starred_url":"https://api.github.com/users/paouelle/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/paouelle/subscriptions","organizations_url":"https://api.github.com/users/paouelle/orgs","repos_url":"https://api.github.com/users/paouelle/repos","events_url":"https://api.github.com/users/paouelle/events{/privacy}","received_events_url":"https://api.github.com/users/paouelle/received_events","type":"User","site_admin":false},"repo":{"id":85875261,"name":"ddf","full_name":"paouelle/ddf","owner":{"login":"paouelle","id":10549555,"avatar_url":"https://avatars0.githubusercontent.com/u/10549555?v=4","gravatar_id":"","url":"https://api.github.com/users/paouelle","html_url":"https://github.com/paouelle","followers_url":"https://api.github.com/users/paouelle/followers","following_url":"https://api.github.com/users/paouelle/following{/other_user}","gists_url":"https://api.github.com/users/paouelle/gists{/gist_id}","starred_url":"https://api.github.com/users/paouelle/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/paouelle/subscriptions","organizations_url":"https://api.github.com/users/paouelle/orgs","repos_url":"https://api.github.com/users/paouelle/repos","events_url":"https://api.github.com/users/paouelle/events{/privacy}","received_events_url":"https://api.github.com/users/paouelle/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/paouelle/ddf","description":"Distributed Data Framework - an open source, modular integration framework.","fork":true,"url":"https://api.github.com/repos/paouelle/ddf","forks_url":"https://api.github.com/repos/paouelle/ddf/forks","keys_url":"https://api.github.com/repos/paouelle/ddf/keys{/key_id}","collaborators_url":"https://api.github.com/repos/paouelle/ddf/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/paouelle/ddf/teams","hooks_url":"https://api.github.com/repos/paouelle/ddf/hooks","issue_events_url":"https://api.github.com/repos/paouelle/ddf/issues/events{/number}","events_url":"https://api.github.com/repos/paouelle/ddf/events","assignees_url":"https://api.github.com/repos/paouelle/ddf/assignees{/user}","branches_url":"https://api.github.com/repos/paouelle/ddf/branches{/branch}","tags_url":"https://api.github.com/repos/paouelle/ddf/tags","blobs_url":"https://api.github.com/repos/paouelle/ddf/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/paouelle/ddf/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/paouelle/ddf/git/refs{/sha}","trees_url":"https://api.github.com/repos/paouelle/ddf/git/trees{/sha}","statuses_url":"https://api.github.com/repos/paouelle/ddf/statuses/{sha}","languages_url":"https://api.github.com/repos/paouelle/ddf/languages","stargazers_url":"https://api.github.com/repos/paouelle/ddf/stargazers","contributors_url":"https://api.github.com/repos/paouelle/ddf/contributors","subscribers_url":"https://api.github.com/repos/paouelle/ddf/subscribers","subscription_url":"https://api.github.com/repos/paouelle/ddf/subscription","commits_url":"https://api.github.com/repos/paouelle/ddf/commits{/sha}","git_commits_url":"https://api.github.com/repos/paouelle/ddf/git/commits{/sha}","comments_url":"https://api.github.com/repos/paouelle/ddf/comments{/number}","issue_comment_url":"https://api.github.com/repos/paouelle/ddf/issues/comments{/number}","contents_url":"https://api.github.com/repos/paouelle/ddf/contents/{+path}","compare_url":"https://api.github.com/repos/paouelle/ddf/compare/{base}...{head}","merges_url":"https://api.github.com/repos/paouelle/ddf/merges","archive_url":"https://api.github.com/repos/paouelle/ddf/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/paouelle/ddf/downloads","issues_url":"https://api.github.com/repos/paouelle/ddf/issues{/number}","pulls_url":"https://api.github.com/repos/paouelle/ddf/pulls{/number}","milestones_url":"https://api.github.com/repos/paouelle/ddf/milestones{/number}","notifications_url":"https://api.github.com/repos/paouelle/ddf/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/paouelle/ddf/labels{/name}","releases_url":"https://api.github.com/repos/paouelle/ddf/releases{/id}","deployments_url":"https://api.github.com/repos/paouelle/ddf/deployments","created_at":"2017-03-22T20:55:51Z","updated_at":"2017-03-22T20:56:09Z","pushed_at":"2017-08-29T06:00:29Z","git_url":"git://github.com/paouelle/ddf.git","ssh_url":"git@github.com:paouelle/ddf.git","clone_url":"https://github.com/paouelle/ddf.git","svn_url":"https://github.com/paouelle/ddf","homepage":"http://ddf.codice.org","size":319008,"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,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"codice:master","ref":"master","sha":"4f358bc9df9dbf0933e50ef164ddec8c7e5ab0c2","user":{"login":"codice","id":2386734,"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,"name":"ddf","full_name":"codice/ddf","owner":{"login":"codice","id":2386734,"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},"private":false,"html_url":"https://github.com/codice/ddf","description":"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":"2017-08-23T20:37:37Z","pushed_at":"2017-08-29T22:41: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":328402,"stargazers_count":62,"watchers_count":62,"language":"Java","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":true,"forks_count":118,"mirror_url":null,"open_issues_count":30,"forks":118,"open_issues":30,"watchers":62,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/codice/ddf/pulls/2174"},"html":{"href":"https://github.com/codice/ddf/pull/2174"},"issue":{"href":"https://api.github.com/repos/codice/ddf/issues/2174"},"comments":{"href":"https://api.github.com/repos/codice/ddf/issues/2174/comments"},"review_comments":{"href":"https://api.github.com/repos/codice/ddf/pulls/2174/comments"},"review_comment":{"href":"https://api.github.com/repos/codice/ddf/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/codice/ddf/pulls/2174/commits"},"statuses":{"href":"https://api.github.com/repos/codice/ddf/statuses/23132fce7d06e2a22a3f794ef807168c93b17b4d"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"paouelle"}}