{"action":"created","comment":{"url":"https://api.github.com/repos/codice/ddf/pulls/comments/57547124","id":57547124,"diff_hunk":"@@ -0,0 +1,305 @@\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 ddf.catalog.registry.federationadmin.service.impl;\n+\n+import java.io.ByteArrayInputStream;\n+import java.io.ByteArrayOutputStream;\n+import java.io.IOException;\n+import java.io.InputStream;\n+import java.time.OffsetDateTime;\n+import java.time.ZoneId;\n+import java.time.ZoneOffset;\n+import java.util.ArrayList;\n+import java.util.Arrays;\n+import java.util.Collections;\n+import java.util.List;\n+import java.util.UUID;\n+\n+import javax.xml.bind.JAXBElement;\n+import javax.xml.bind.Marshaller;\n+import javax.xml.datatype.DatatypeConstants;\n+\n+import org.apache.commons.lang.StringUtils;\n+import org.codice.ddf.configuration.SystemInfo;\n+import org.codice.ddf.parser.Parser;\n+import org.codice.ddf.parser.ParserConfigurator;\n+import org.codice.ddf.parser.ParserException;\n+import org.codice.ddf.security.common.Security;\n+import org.geotools.filter.FilterFactoryImpl;\n+import org.opengis.filter.Filter;\n+import org.opengis.filter.FilterFactory;\n+import org.opengis.filter.sort.SortBy;\n+import org.opengis.filter.sort.SortOrder;\n+import org.slf4j.LoggerFactory;\n+import org.slf4j.ext.XLogger;\n+\n+import ddf.catalog.CatalogFramework;\n+import ddf.catalog.data.Attribute;\n+import ddf.catalog.data.Metacard;\n+import ddf.catalog.data.Result;\n+import ddf.catalog.data.impl.AttributeImpl;\n+import ddf.catalog.federation.FederationException;\n+import ddf.catalog.operation.CreateRequest;\n+import ddf.catalog.operation.Query;\n+import ddf.catalog.operation.QueryRequest;\n+import ddf.catalog.operation.QueryResponse;\n+import ddf.catalog.operation.impl.CreateRequestImpl;\n+import ddf.catalog.operation.impl.QueryImpl;\n+import ddf.catalog.operation.impl.QueryRequestImpl;\n+import ddf.catalog.registry.api.metacard.RegistryObjectMetacardType;\n+import ddf.catalog.registry.common.RegistryConstants;\n+import ddf.catalog.registry.federationadmin.service.FederationAdminService;\n+import ddf.catalog.source.IngestException;\n+import ddf.catalog.source.SourceUnavailableException;\n+import ddf.catalog.source.UnsupportedQueryException;\n+import ddf.catalog.transform.CatalogTransformerException;\n+import ddf.catalog.transform.InputTransformer;\n+import ddf.security.SecurityConstants;\n+import ddf.security.Subject;\n+import oasis.names.tc.ebxml_regrep.xsd.rim._3.ExtrinsicObjectType;\n+import oasis.names.tc.ebxml_regrep.xsd.rim._3.InternationalStringType;\n+import oasis.names.tc.ebxml_regrep.xsd.rim._3.LocalizedStringType;\n+import oasis.names.tc.ebxml_regrep.xsd.rim._3.ObjectFactory;\n+import oasis.names.tc.ebxml_regrep.xsd.rim._3.RegistryObjectType;\n+import oasis.names.tc.ebxml_regrep.xsd.rim._3.RegistryPackageType;\n+import oasis.names.tc.ebxml_regrep.xsd.rim._3.SlotType1;\n+import oasis.names.tc.ebxml_regrep.xsd.rim._3.ValueListType;\n+import oasis.names.tc.ebxml_regrep.xsd.rim._3.VersionInfoType;\n+\n+public class FederationAdminServiceImpl implements FederationAdminService {\n+\n+    private static final XLogger LOGGER = new XLogger(LoggerFactory.getLogger(\n+            FederationAdminServiceImpl.class));\n+\n+    private static final FilterFactory FILTER_FACTORY = new FilterFactoryImpl();\n+\n+    private static final ObjectFactory RIM_FACTORY = new ObjectFactory();\n+\n+    private static final String REGISTRY_CONTENT_TYPE = \"registry.service\";\n+\n+    private static final String REGISTRY_NODE_PRIMARY = \"PRIMARY\";\n+\n+    private CatalogFramework catalogFramework;\n+\n+    private InputTransformer registryTransformer;\n+\n+    private Parser parser;\n+\n+    private ParserConfigurator configurator;\n+\n+    private final Security security;\n+\n+    public FederationAdminServiceImpl() {\n+        this(Security.getInstance());\n+    }\n+\n+    FederationAdminServiceImpl(Security security) {\n+        this.security = security;\n+    }\n+\n+    @Override\n+    public void addLocalEntry(Metacard metacard)\n+            throws SourceUnavailableException, IngestException {\n+        Subject systemSubject = security.getSystemSubject();\n+        final CreateRequest createRequest = new CreateRequestImpl(metacard);\n+        createRequest.getProperties()\n+                .put(SecurityConstants.SECURITY_SUBJECT, systemSubject);\n+\n+        catalogFramework.create(createRequest);\n+    }\n+\n+    public List<Metacard> getRegistryMetacards()\n+            throws UnsupportedQueryException, SourceUnavailableException, FederationException {\n+        List<Metacard> registryMetacards = new ArrayList<>();\n+\n+        Filter filter =\n+                FILTER_FACTORY.and(FILTER_FACTORY.like(FILTER_FACTORY.property(Metacard.CONTENT_TYPE),\n+                        REGISTRY_CONTENT_TYPE),\n+                        FILTER_FACTORY.like(FILTER_FACTORY.property(Metacard.TAGS),\n+                                RegistryConstants.REGISTRY_TAG));\n+        SortBy sortBy = FILTER_FACTORY.sort(Metacard.CREATED, SortOrder.ASCENDING);\n+\n+        Query query = new QueryImpl(filter);\n+        ((QueryImpl) query).setSortBy(sortBy);\n+\n+        Subject systemSubject = security.getSystemSubject();\n+        final QueryRequest queryRequest = new QueryRequestImpl(query);\n+        queryRequest.getProperties()\n+                .put(SecurityConstants.SECURITY_SUBJECT, systemSubject);\n+\n+        QueryResponse queryResponse = catalogFramework.query(queryRequest);\n+\n+        if (queryResponse != null) {\n+            List<Result> results = queryResponse.getResults();\n+\n+            for (Result result : results) {\n+                Metacard metacard = result.getMetacard();\n+                if (metacard != null) {\n+                    registryMetacards.add(metacard);\n+                }\n+            }\n+        }\n+\n+        return registryMetacards;\n+    }\n+\n+    public void init() {\n+        try {\n+            List<Metacard> registryMetacards = getRegistryMetacards();\n+            boolean hasIdentityNode = false;\n+\n+            for (Metacard metacard : registryMetacards) {\n+                Attribute regNodeStatus =\n+                        metacard.getAttribute(RegistryObjectMetacardType.REGISTRY_NODE_STATUS);\n+\n+                if (regNodeStatus != null && regNodeStatus.getValue()\n+                        .equals(\"PRIMARY\")) {\n+                    hasIdentityNode = true;\n+                    LOGGER.debug(\"Identity Node found. ID: {}\", metacard.getId());\n+                }\n+            }\n+\n+            if (!hasIdentityNode) {\n+                createIdentityNode();\n+            }\n+        } catch (SourceUnavailableException | UnsupportedQueryException | FederationException e) {\n+            LOGGER.error(\"There was an error executing a query. Failed to come up properly.\");\n+        } catch (IngestException e) {\n+            LOGGER.error(\n+                    \"There was an error creating the identity node. Failed to come up properly.\");\n+        }\n+    }\n+\n+    private void createIdentityNode() throws SourceUnavailableException, IngestException {\n+\n+        String registryPackageId = UUID.randomUUID()\n+                .toString()\n+                .replaceAll(\"-\", \"\");\n+        RegistryPackageType registryPackage = RIM_FACTORY.createRegistryPackageType();\n+        registryPackage.setId(registryPackageId);\n+\n+        ExtrinsicObjectType extrinsicObject = RIM_FACTORY.createExtrinsicObjectType();\n+        extrinsicObject.setObjectType(RegistryConstants.REGISTRY_NODE_OBJECT_TYPE);\n+\n+        String extrinsicObjectId = UUID.randomUUID()\n+                .toString()\n+                .replaceAll(\"-\", \"\");\n+        extrinsicObject.setId(extrinsicObjectId);\n+\n+        String siteName = SystemInfo.getSiteName();\n+        if (StringUtils.isNotBlank(siteName)) {\n+            extrinsicObject.setName(getInternationalStringTypeFromString(siteName));\n+        }\n+\n+        String version = SystemInfo.getVersion();\n+        if (StringUtils.isNotBlank(version)) {\n+            VersionInfoType versionInfo = RIM_FACTORY.createVersionInfoType();\n+            versionInfo.setVersionName(version);\n+\n+            extrinsicObject.setVersionInfo(versionInfo);\n+        }\n+\n+        OffsetDateTime now = OffsetDateTime.now(ZoneId.of(ZoneOffset.UTC.toString()));\n+        String rightNow = now.toString();\n+        ValueListType valueList = RIM_FACTORY.createValueListType();\n+        valueList.getValue()\n+                .add(rightNow);\n+\n+        SlotType1 lastUpdated = RIM_FACTORY.createSlotType1();\n+        lastUpdated.setValueList(RIM_FACTORY.createValueList(valueList));\n+        lastUpdated.setSlotType(DatatypeConstants.DATETIME.toString());\n+        lastUpdated.setName(RegistryConstants.XML_LAST_UPDATED_NAME);\n+        extrinsicObject.getSlot()\n+                .add(lastUpdated);\n+\n+        SlotType1 liveDate = RIM_FACTORY.createSlotType1();\n+        liveDate.setValueList(RIM_FACTORY.createValueList(valueList));\n+        liveDate.setSlotType(DatatypeConstants.DATETIME.toString());\n+        liveDate.setName(RegistryConstants.XML_LIVE_DATE_NAME);\n+        extrinsicObject.getSlot()\n+                .add(liveDate);\n+\n+        if (registryPackage.getRegistryObjectList() == null) {\n+            registryPackage.setRegistryObjectList(RIM_FACTORY.createRegistryObjectListType());\n+        }\n+\n+        registryPackage.getRegistryObjectList()\n+                .getIdentifiable()\n+                .add(RIM_FACTORY.createIdentifiable(extrinsicObject));\n+\n+        Metacard identityMetacard = jaxbToMetacard(registryPackage);\n+        if (identityMetacard != null) {\n+            Attribute registryNodeAttribute =\n+                    new AttributeImpl(RegistryObjectMetacardType.REGISTRY_NODE_STATUS,\n+                            REGISTRY_NODE_PRIMARY);\n+            identityMetacard.setAttribute(registryNodeAttribute);\n+\n+            Attribute registryContentType = new AttributeImpl(Metacard.CONTENT_TYPE,\n+                    REGISTRY_CONTENT_TYPE);\n+            identityMetacard.setAttribute(registryContentType);\n+\n+            addLocalEntry(identityMetacard);\n+        }\n+    }\n+\n+    private Metacard jaxbToMetacard(RegistryPackageType registryPackage) {\n+        Metacard metacard;\n+\n+        try {\n+            JAXBElement<RegistryPackageType> jaxbRegistryObjectType =\n+                    RIM_FACTORY.createRegistryPackage(registryPackage);\n+\n+            ByteArrayOutputStream baos = new ByteArrayOutputStream();\n+            parser.marshal(configurator, jaxbRegistryObjectType, baos);\n+            InputStream xmlInputStream = new ByteArrayInputStream(baos.toByteArray());\n+            metacard = registryTransformer.transform(xmlInputStream);\n+\n+        } catch (IOException | CatalogTransformerException | ParserException e) {\n+            LOGGER.error(\"Error creating metacard from registry package.\", e);\n+            metacard = null;\n+        }\n+\n+        return metacard;\n+    }\n+\n+    private InternationalStringType getInternationalStringTypeFromString(\n+            String internationalizeThis) {\n+        InternationalStringType ist = RIM_FACTORY.createInternationalStringType();\n+        LocalizedStringType lst = RIM_FACTORY.createLocalizedStringType();\n+        lst.setValue(internationalizeThis);\n+        ist.setLocalizedString(Collections.singletonList(lst));\n+\n+        return ist;\n+    }\n+\n+    public void setCatalogFramework(CatalogFramework catalogFramework) {\n+        this.catalogFramework = catalogFramework;\n+    }\n+\n+    public void setParser(Parser parser) {\n+        this.configurator =\n+                parser.configureParser(Arrays.asList(RegistryObjectType.class.getPackage()\n+                                .getName(),\n+                        net.opengis.ogc.ObjectFactory.class.getPackage()\n+                                .getName(),\n+                        net.opengis.gml.v_3_1_1.ObjectFactory.class.getPackage()\n+                                .getName()), FederationAdminServiceImpl.class.getClassLoader());\n+        this.configurator.addProperty(Marshaller.JAXB_FRAGMENT, true);\n+        this.parser = parser;\n+    }\n+\n+    public void setRegistryTransformer(InputTransformer inputTransformer) {","path":"catalog/registry/catalog-registry-federationadminserviceimpl/src/main/java/ddf/catalog/registry/federationadmin/service/impl/FederationAdminServiceImpl.java","position":302,"original_position":302,"commit_id":"33b18cfc067029d28a86d482996e08d4661728c2","original_commit_id":"33b18cfc067029d28a86d482996e08d4661728c2","user":{"login":"gordocanchola","id":14877145,"avatar_url":"https://avatars.githubusercontent.com/u/14877145?v=3","gravatar_id":"","url":"https://api.github.com/users/gordocanchola","html_url":"https://github.com/gordocanchola","followers_url":"https://api.github.com/users/gordocanchola/followers","following_url":"https://api.github.com/users/gordocanchola/following{/other_user}","gists_url":"https://api.github.com/users/gordocanchola/gists{/gist_id}","starred_url":"https://api.github.com/users/gordocanchola/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gordocanchola/subscriptions","organizations_url":"https://api.github.com/users/gordocanchola/orgs","repos_url":"https://api.github.com/users/gordocanchola/repos","events_url":"https://api.github.com/users/gordocanchola/events{/privacy}","received_events_url":"https://api.github.com/users/gordocanchola/received_events","type":"User","site_admin":false},"body":"No, this is accessed by blueprint so must be public","created_at":"2016-03-28T06:02:18Z","updated_at":"2016-03-28T06:02:18Z","html_url":"https://github.com/codice/ddf/pull/644#discussion_r57547124","pull_request_url":"https://api.github.com/repos/codice/ddf/pulls/644","_links":{"self":{"href":"https://api.github.com/repos/codice/ddf/pulls/comments/57547124"},"html":{"href":"https://github.com/codice/ddf/pull/644#discussion_r57547124"},"pull_request":{"href":"https://api.github.com/repos/codice/ddf/pulls/644"}}},"pull_request":{"url":"https://api.github.com/repos/codice/ddf/pulls/644","id":63963980,"html_url":"https://github.com/codice/ddf/pull/644","diff_url":"https://github.com/codice/ddf/pull/644.diff","patch_url":"https://github.com/codice/ddf/pull/644.patch","issue_url":"https://api.github.com/repos/codice/ddf/issues/644","number":644,"state":"open","locked":false,"title":"DDF-1771 Implement FederationAdmin bean for storing/editing federation configurations","user":{"login":"gordocanchola","id":14877145,"avatar_url":"https://avatars.githubusercontent.com/u/14877145?v=3","gravatar_id":"","url":"https://api.github.com/users/gordocanchola","html_url":"https://github.com/gordocanchola","followers_url":"https://api.github.com/users/gordocanchola/followers","following_url":"https://api.github.com/users/gordocanchola/following{/other_user}","gists_url":"https://api.github.com/users/gordocanchola/gists{/gist_id}","starred_url":"https://api.github.com/users/gordocanchola/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gordocanchola/subscriptions","organizations_url":"https://api.github.com/users/gordocanchola/orgs","repos_url":"https://api.github.com/users/gordocanchola/repos","events_url":"https://api.github.com/users/gordocanchola/events{/privacy}","received_events_url":"https://api.github.com/users/gordocanchola/received_events","type":"User","site_admin":false},"body":"#### What does this PR do?\r\nThis introduces the registry's Federation Admin Service. \r\nFederationAdminServiceImpl will come up on init and check existing registry entries for the identity node. If one doesn't exist, it will create itself\r\nThere was also some minor refactoring in the registry.\r\n#### Who is reviewing it?\r\n@clockard @vinamartin @brianfelix @oscaritoro @mcalcote @ricklarsen @stustison \r\n#### How should this be tested?\r\nInstall catalog-registry feature\r\nUsing solr query the catalog and verify an entry is displayed with the registry-node-status set to \"PRIMARY\"\r\n#### Any background context you want to provide?\r\n#### What are the relevant tickets?\r\nDDF-1771\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  Adding the following bundles to the catalog-registry feature:\r\n    catalog-registry-api\r\n    catalog-registry-schema-bindings\r\n    catalog-registry-federationadminservice\r\n    catalog-registry-federationadminserviceimpl\r\n\r\nMoving RegistryObjectMetacardType to catalog-registry-api\r\nUpdating RegistryPackageConverter and RegistryTransformer for the refactor\r\nUpdating IdentificationPluging for the refactor\r\nUpdating RegistryPolicyPlugin for the refactor\r\n\r\nBundle-izing catalog-registry-schema-bindings\r\nUpdating poms that were embedding it\r\n\r\nAdding catalog-registry-api and supporting files\r\nAdding catalog-registry-federationadminservice & impl and supporting files\r\nFederationAdminServiceImpl will come up on init and check existing registry entries for the identity node. If one doesn't exist, it will create itself.","created_at":"2016-03-23T22:34:27Z","updated_at":"2016-03-28T06:02:19Z","closed_at":null,"merged_at":null,"merge_commit_sha":"31eed5917614f518e0be914c9be9c3173d03f752","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/codice/ddf/pulls/644/commits","review_comments_url":"https://api.github.com/repos/codice/ddf/pulls/644/comments","review_comment_url":"https://api.github.com/repos/codice/ddf/pulls/comments{/number}","comments_url":"https://api.github.com/repos/codice/ddf/issues/644/comments","statuses_url":"https://api.github.com/repos/codice/ddf/statuses/33b18cfc067029d28a86d482996e08d4661728c2","head":{"label":"gordocanchola:DDF-1771","ref":"DDF-1771","sha":"33b18cfc067029d28a86d482996e08d4661728c2","user":{"login":"gordocanchola","id":14877145,"avatar_url":"https://avatars.githubusercontent.com/u/14877145?v=3","gravatar_id":"","url":"https://api.github.com/users/gordocanchola","html_url":"https://github.com/gordocanchola","followers_url":"https://api.github.com/users/gordocanchola/followers","following_url":"https://api.github.com/users/gordocanchola/following{/other_user}","gists_url":"https://api.github.com/users/gordocanchola/gists{/gist_id}","starred_url":"https://api.github.com/users/gordocanchola/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gordocanchola/subscriptions","organizations_url":"https://api.github.com/users/gordocanchola/orgs","repos_url":"https://api.github.com/users/gordocanchola/repos","events_url":"https://api.github.com/users/gordocanchola/events{/privacy}","received_events_url":"https://api.github.com/users/gordocanchola/received_events","type":"User","site_admin":false},"repo":{"id":43379971,"name":"ddf","full_name":"gordocanchola/ddf","owner":{"login":"gordocanchola","id":14877145,"avatar_url":"https://avatars.githubusercontent.com/u/14877145?v=3","gravatar_id":"","url":"https://api.github.com/users/gordocanchola","html_url":"https://github.com/gordocanchola","followers_url":"https://api.github.com/users/gordocanchola/followers","following_url":"https://api.github.com/users/gordocanchola/following{/other_user}","gists_url":"https://api.github.com/users/gordocanchola/gists{/gist_id}","starred_url":"https://api.github.com/users/gordocanchola/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gordocanchola/subscriptions","organizations_url":"https://api.github.com/users/gordocanchola/orgs","repos_url":"https://api.github.com/users/gordocanchola/repos","events_url":"https://api.github.com/users/gordocanchola/events{/privacy}","received_events_url":"https://api.github.com/users/gordocanchola/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/gordocanchola/ddf","description":"The Distributed Data Framework - Distribution, SDK, and Test","fork":true,"url":"https://api.github.com/repos/gordocanchola/ddf","forks_url":"https://api.github.com/repos/gordocanchola/ddf/forks","keys_url":"https://api.github.com/repos/gordocanchola/ddf/keys{/key_id}","collaborators_url":"https://api.github.com/repos/gordocanchola/ddf/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/gordocanchola/ddf/teams","hooks_url":"https://api.github.com/repos/gordocanchola/ddf/hooks","issue_events_url":"https://api.github.com/repos/gordocanchola/ddf/issues/events{/number}","events_url":"https://api.github.com/repos/gordocanchola/ddf/events","assignees_url":"https://api.github.com/repos/gordocanchola/ddf/assignees{/user}","branches_url":"https://api.github.com/repos/gordocanchola/ddf/branches{/branch}","tags_url":"https://api.github.com/repos/gordocanchola/ddf/tags","blobs_url":"https://api.github.com/repos/gordocanchola/ddf/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/gordocanchola/ddf/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/gordocanchola/ddf/git/refs{/sha}","trees_url":"https://api.github.com/repos/gordocanchola/ddf/git/trees{/sha}","statuses_url":"https://api.github.com/repos/gordocanchola/ddf/statuses/{sha}","languages_url":"https://api.github.com/repos/gordocanchola/ddf/languages","stargazers_url":"https://api.github.com/repos/gordocanchola/ddf/stargazers","contributors_url":"https://api.github.com/repos/gordocanchola/ddf/contributors","subscribers_url":"https://api.github.com/repos/gordocanchola/ddf/subscribers","subscription_url":"https://api.github.com/repos/gordocanchola/ddf/subscription","commits_url":"https://api.github.com/repos/gordocanchola/ddf/commits{/sha}","git_commits_url":"https://api.github.com/repos/gordocanchola/ddf/git/commits{/sha}","comments_url":"https://api.github.com/repos/gordocanchola/ddf/comments{/number}","issue_comment_url":"https://api.github.com/repos/gordocanchola/ddf/issues/comments{/number}","contents_url":"https://api.github.com/repos/gordocanchola/ddf/contents/{+path}","compare_url":"https://api.github.com/repos/gordocanchola/ddf/compare/{base}...{head}","merges_url":"https://api.github.com/repos/gordocanchola/ddf/merges","archive_url":"https://api.github.com/repos/gordocanchola/ddf/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/gordocanchola/ddf/downloads","issues_url":"https://api.github.com/repos/gordocanchola/ddf/issues{/number}","pulls_url":"https://api.github.com/repos/gordocanchola/ddf/pulls{/number}","milestones_url":"https://api.github.com/repos/gordocanchola/ddf/milestones{/number}","notifications_url":"https://api.github.com/repos/gordocanchola/ddf/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/gordocanchola/ddf/labels{/name}","releases_url":"https://api.github.com/repos/gordocanchola/ddf/releases{/id}","deployments_url":"https://api.github.com/repos/gordocanchola/ddf/deployments","created_at":"2015-09-29T16:34:02Z","updated_at":"2015-09-29T16:34:17Z","pushed_at":"2016-03-23T22:23:31Z","git_url":"git://github.com/gordocanchola/ddf.git","ssh_url":"git@github.com:gordocanchola/ddf.git","clone_url":"https://github.com/gordocanchola/ddf.git","svn_url":"https://github.com/gordocanchola/ddf","homepage":"","size":137663,"stargazers_count":0,"watchers_count":0,"language":"Java","has_issues":false,"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":"060ff4c416c82b4a3d59dcccec0fd7b0e39a8f22","user":{"login":"codice","id":2386734,"avatar_url":"https://avatars.githubusercontent.com/u/2386734?v=3","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://avatars.githubusercontent.com/u/2386734?v=3","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":"The Distributed Data Framework - Federated Open Geospatial Consortium (OGC) filter powered metadata catalog with SAML Web SSO secured container","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":"2016-03-17T15:01:17Z","pushed_at":"2016-03-28T00:41:54Z","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":"","size":164156,"stargazers_count":35,"watchers_count":35,"language":"Java","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":true,"forks_count":73,"mirror_url":null,"open_issues_count":15,"forks":73,"open_issues":15,"watchers":35,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/codice/ddf/pulls/644"},"html":{"href":"https://github.com/codice/ddf/pull/644"},"issue":{"href":"https://api.github.com/repos/codice/ddf/issues/644"},"comments":{"href":"https://api.github.com/repos/codice/ddf/issues/644/comments"},"review_comments":{"href":"https://api.github.com/repos/codice/ddf/pulls/644/comments"},"review_comment":{"href":"https://api.github.com/repos/codice/ddf/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/codice/ddf/pulls/644/commits"},"statuses":{"href":"https://api.github.com/repos/codice/ddf/statuses/33b18cfc067029d28a86d482996e08d4661728c2"}}}}