Workspace Design

Introduction

Workspaces are a special type of DDF metacard that can be used to share queries and saved items between users.


To distinguish workspaces from other metacards, be sure to specify metacard-tags with a value of "workspace".

metcard-tags
<string name="metacard-tags">
    <value>workspace</value>
</string>


Moreover, every workspace must have an owner specified by the metacard.owner attribute. An owner can be specified at creation time or it will resolve to the security subject (normally the currently logged in user) if none is provided.

NOTE: emails are used to identify owners, so if no owner is provided, and the current security subject doesn't have an email, workspace creation will fail.

To specify an owner, add the following:

metacard.owner
<string name="metacard.owner">
    <value>user@domain.com</value>
</string>

Sharing Workspaces

A workspace can be shared with others using the DDF Security Attributes.


Sharing a workspace with a group can be accomplished adding the following attribute to a workspace:

security.access-groups
<string name="security.access-groups">
    <value>group1</value>
	...
    <value>groupn</value>
</string>


Sharing a workspace with a specific user can be accomplished by adding the following attribute to a workspace:

security.access-individuals
<string name="security.access-individuals">
    <value>user1@domain.com</value>
    ...
    <value>usern@domain.com</value>
</string>


Programmatic Usage: API

DDF has many API's for interacting with metacards and the the Catalog Framework. Below, is a demonstration of how to work with workspaces using the DDF's CSW endpoint. If you choose to use another API, the usage should be similar.

Note: all the request are being made as the admin user.


To query DDF for all workspace metacards, make the following HTTP request:

Query For All Workspaces - Request
POST /services/csw HTTP/1.1
Authorization: Basic YWRtaW46YWRtaW4=
Content-Type: application/xml

<csw:GetRecords resultType="results"
                outputFormat="application/xml"
                outputSchema="urn:catalog:metacard"
                startPosition="1"
                maxRecords="10"
                service="CSW"
                version="2.0.2"
                xmlns:ogc="http://www.opengis.net/ogc"
                xmlns:csw="http://www.opengis.net/cat/csw/2.0.2">

  <csw:Query>
    <csw:ElementSetName>full</csw:ElementSetName>
    <csw:Constraint version="2.0.0">
      <ogc:Filter>

        <ogc:PropertyIsEqualTo>
          <ogc:PropertyName>metacard-tags</ogc:PropertyName>
          <ogc:Literal>workspace</ogc:Literal>
        </ogc:PropertyIsEqualTo>

      </ogc:Filter>
    </csw:Constraint>
  </csw:Query>

</csw:GetRecords>
Query For All Workspaces - Response
HTTP/1.1 200 OK
content-type: application/octet-stream

<?xml version='1.0' encoding='UTF-8'?>
<csw:GetRecordsResponse 
  xmlns:dct="http://purl.org/dc/terms/" 
  xmlns:xml="http://www.w3.org/XML/1998/namespace" 
  xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" 
  xmlns:ows="http://www.opengis.net/ows" 
  xmlns:xs="http://www.w3.org/2001/XMLSchema" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0.2">
  <csw:SearchStatus timestamp="2016-06-29T08:09:52.705-07:00"/>
  <csw:SearchResults numberOfRecordsMatched="1" numberOfRecordsReturned="1" nextRecord="0" recordSchema="urn:catalog:metacard" elementSet="full">
    <metacard 
      xmlns="urn:catalog:metacard" 
      xmlns:gml="http://www.opengis.net/gml" 
      xmlns:xlink="http://www.w3.org/1999/xlink" 
      xmlns:smil="http://www.w3.org/2001/SMIL20/" 
      xmlns:smillang="http://www.w3.org/2001/SMIL20/Language" gml:id="8d0482abda4a4bff9dd493e622f4d8c6">
      <type>workspace</type>
      <source>ddf.distribution</source>
      <string name="title">
        <value>Admin Workspace</value>
      </string>
      <string name="owner">
        <value>admin@localhost.local</value>
      </string>
      <string name="metacard-tags">
        <value>workspace</value>
      </string>
    </metacard>
  </csw:SearchResults>
</csw:GetRecordsResponse>


To query for a specific workspace by id, make the following HTTP request:

Query For Workspace by ID - Request
POST /services/csw HTTP/1.1
Authorization: Basic YWRtaW46YWRtaW4=
Content-Type: application/xml

<csw:GetRecords resultType="results"
                outputFormat="application/xml"
                outputSchema="urn:catalog:metacard"
                startPosition="1"
                maxRecords="10"
                service="CSW"
                version="2.0.2"
                xmlns:ogc="http://www.opengis.net/ogc"
                xmlns:csw="http://www.opengis.net/cat/csw/2.0.2">

  <csw:Query>
    <csw:ElementSetName>full</csw:ElementSetName>
    <csw:Constraint version="2.0.0">
      <ogc:Filter>
        <ogc:And>

        <ogc:PropertyIsEqualTo>
          <ogc:PropertyName>id</ogc:PropertyName>
          <ogc:Literal>8d0482abda4a4bff9dd493e622f4d8c6</ogc:Literal>
        </ogc:PropertyIsEqualTo>

        <ogc:PropertyIsEqualTo>
          <ogc:PropertyName>metacard-tags</ogc:PropertyName>
          <ogc:Literal>workspace</ogc:Literal>
        </ogc:PropertyIsEqualTo>

        </ogc:And>
      </ogc:Filter>
    </csw:Constraint>
  </csw:Query>

</csw:GetRecords>
Query For Workspace by ID - Response
HTTP/1.1 200 OK
content-type: application/octet-stream

<?xml version='1.0' encoding='UTF-8'?>
<csw:GetRecordsResponse 
  xmlns:dct="http://purl.org/dc/terms/" 
  xmlns:xml="http://www.w3.org/XML/1998/namespace" 
  xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" 
  xmlns:ows="http://www.opengis.net/ows" 
  xmlns:xs="http://www.w3.org/2001/XMLSchema" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0.2">
  <csw:SearchStatus timestamp="2016-06-29T08:11:41.508-07:00"/>
  <csw:SearchResults numberOfRecordsMatched="1" numberOfRecordsReturned="1" nextRecord="0" recordSchema="urn:catalog:metacard" elementSet="full">
    <metacard 
      xmlns="urn:catalog:metacard" 
      xmlns:gml="http://www.opengis.net/gml" 
      xmlns:xlink="http://www.w3.org/1999/xlink" 
      xmlns:smil="http://www.w3.org/2001/SMIL20/" 
      xmlns:smillang="http://www.w3.org/2001/SMIL20/Language" gml:id="8d0482abda4a4bff9dd493e622f4d8c6">
      <type>workspace</type>
      <source>ddf.distribution</source>
      <string name="title">
        <value>Admin Workspace</value>
      </string>
      <string name="owner">
        <value>admin@localhost.local</value>
      </string>
      <string name="metacard-tags">
        <value>workspace</value>
      </string>
    </metacard>
  </csw:SearchResults>
</csw:GetRecordsResponse>


To create a new workspace, make the following HTTP request:

Insert a New Workspace - Request
POST /services/csw HTTP/1.1
Authorization: Basic YWRtaW46YWRtaW4=
Content-Type: application/xml

<csw:Transaction service="CSW"
                 version="2.0.2"
                 verboseResponse="true"
                 xmlns:csw="http://www.opengis.net/cat/csw/2.0.2">
  <csw:Insert typeName="xml">

    <metacard 
      xmlns="urn:catalog:metacard" 
      xmlns:gml="http://www.opengis.net/gml" 
      xmlns:xlink="http://www.w3.org/1999/xlink" 
      xmlns:smil="http://www.w3.org/2001/SMIL20/" 
      xmlns:smillang="http://www.w3.org/2001/SMIL20/Language">

      <type>workspace</type>

      <string name="title">
        <value>Created From CSW</value>
      </string>
      <string name="metacard-tags">
        <value>workspace</value>
      </string>

    </metacard>

  </csw:Insert>
</csw:Transaction>
Insert a New Workspace - Response
HTTP/1.1 200 OK
content-type: text/xml

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<csw:TransactionResponse
  xmlns:ows="http://www.opengis.net/ows"
  xmlns:ns2="http://www.w3.org/1999/xlink"
  xmlns:ogc="http://www.opengis.net/ogc"
  xmlns:gml="http://www.opengis.net/gml"
  xmlns:csw="http://www.opengis.net/cat/csw/2.0.2"
  xmlns:ns6="http://www.w3.org/2001/SMIL20/"
  xmlns:dc="http://purl.org/dc/elements/1.1/"
  xmlns:dct="http://purl.org/dc/terms/"
  xmlns:ns9="http://www.w3.org/2001/SMIL20/Language"
  xmlns:ns10="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" ns10:schemaLocation="http://www.opengis.net/csw /ogc/csw/2.0.2/CSW-publication.xsd">
  <csw:TransactionSummary>
    <csw:totalInserted>1</csw:totalInserted>
    <csw:totalUpdated>0</csw:totalUpdated>
    <csw:totalDeleted>0</csw:totalDeleted>
  </csw:TransactionSummary>
  <csw:InsertResult>
    <csw:BriefRecord>
      <dc:identifier>15ea4767c17c4bfeabdc27598ee14a74</dc:identifier>
      <dc:title>Created From CSW</dc:title>
      <dc:type/>
    </csw:BriefRecord>
  </csw:InsertResult>
</csw:TransactionResponse>


To update an existing workspace by id, make the following HTTP request:

Update an Existing Workspace - Request
POST /services/csw HTTP/1.1
Authorization: Basic YWRtaW46YWRtaW4=
Content-Type: application/xml

<csw:Transaction service="CSW"
                 version="2.0.2"
                 verboseResponse="true"
                 xmlns:csw="http://www.opengis.net/cat/csw/2.0.2">
  <csw:Update typeName="xml">

     <metacard xmlns="urn:catalog:metacard"
               xmlns:gml="http://www.opengis.net/gml"
               gml:id="f7dad53993ca44798a62c5de95053e0d">

      <type>workspace</type>
      <string name="metacard-tags">
        <value>workspace</value>
      </string>

      <string name="title">
        <value>my updated workspace title</value>
      </string>

    </metacard>

  </csw:Update>
</csw:Transaction>
Update an Existing Workspace - Reponse
HTTP/1.1 200 OK
content-type: text/xml

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<csw:TransactionResponse 
  xmlns:ows="http://www.opengis.net/ows" 
  xmlns:ns2="http://www.w3.org/1999/xlink" 
  xmlns:ogc="http://www.opengis.net/ogc" 
  xmlns:gml="http://www.opengis.net/gml" 
  xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" 
  xmlns:ns6="http://www.w3.org/2001/SMIL20/" 
  xmlns:dc="http://purl.org/dc/elements/1.1/" 
  xmlns:dct="http://purl.org/dc/terms/" 
  xmlns:ns9="http://www.w3.org/2001/SMIL20/Language" 
  xmlns:ns10="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" ns10:schemaLocation="http://www.opengis.net/csw /ogc/csw/2.0.2/CSW-publication.xsd">
  <csw:TransactionSummary>
    <csw:totalInserted>0</csw:totalInserted>
    <csw:totalUpdated>1</csw:totalUpdated>
    <csw:totalDeleted>0</csw:totalDeleted>
  </csw:TransactionSummary>
</csw:TransactionResponse>


To remove a workspace by id, make the following HTTP request:

Delete Workspace by ID - Request
POST /services/csw HTTP/1.1
Authorization: Basic YWRtaW46YWRtaW4=
Content-Type: application/xml

<csw:Transaction service="CSW"
                 version="2.0.2"
                 xmlns:csw="http://www.opengis.net/cat/csw/2.0.2"
                 xmlns:ogc="http://www.opengis.net/ogc">

  <csw:Delete typeName="csw:Record">
    <csw:Constraint version="2.0.0">
      <ogc:Filter>
        <ogc:And>

        <ogc:PropertyIsEqualTo>
          <ogc:PropertyName>id</ogc:PropertyName>
          <ogc:Literal>{put workspace id here}</ogc:Literal>
        </ogc:PropertyIsEqualTo>

        <ogc:PropertyIsEqualTo>
          <ogc:PropertyName>metacard-tags</ogc:PropertyName>
          <ogc:Literal>workspace</ogc:Literal>
        </ogc:PropertyIsEqualTo>

        </ogc:And>
      </ogc:Filter>
    </csw:Constraint>
  </csw:Delete>

</csw:Transaction>
Delete Workspace by ID - Response
HTTP/1.1 200 OK
content-type: text/xml

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<csw:TransactionResponse 
  xmlns:ows="http://www.opengis.net/ows" 
  xmlns:ns2="http://www.w3.org/1999/xlink" 
  xmlns:ogc="http://www.opengis.net/ogc" 
  xmlns:gml="http://www.opengis.net/gml" 
  xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" 
  xmlns:ns6="http://www.w3.org/2001/SMIL20/" 
  xmlns:dc="http://purl.org/dc/elements/1.1/" 
  xmlns:dct="http://purl.org/dc/terms/" 
  xmlns:ns9="http://www.w3.org/2001/SMIL20/Language" 
  xmlns:ns10="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" ns10:schemaLocation="http://www.opengis.net/csw /ogc/csw/2.0.2/CSW-publication.xsd">
  <csw:TransactionSummary>
    <csw:totalInserted>0</csw:totalInserted>
    <csw:totalUpdated>0</csw:totalUpdated>
    <csw:totalDeleted>1</csw:totalDeleted>
  </csw:TransactionSummary>
</csw:TransactionResponse>