WCS Service Prototype

From OPeNDAP Documentation
⧼opendap2-jumptonavigation⧽

Introduction

The WCS service prototype is written as a DispatchHandler implementation for the OLFS (essentially a plug-in).

One of the challenges encountered when implementing a WCS service for Hyrax is catalog generation: How do we generate a list of coverages from existing holdings in Hyrax?

The initial plan was to use semantic web technology to crosswalk from existing (Climate Forecast, aka cf) metadata into the WCS metadata space. This effort is ongoing but the software technology involved has proved to be bleeding edge and somewhat difficult to make progress with. In order to move forward with the other aspects of WCS, we have implemented a configuration based catalog. In this catalog every wcs:CoverageDescription is hand written and placed in a file in a designated directory. The directory is identified in the DispatchHandler's configuration object and at system start-up each file in the Coverages directory is ingested (with the assumption that the file contains a single wcs:CoverageDescription) and added to the catalog.

Although there are many drawbacks to this approach it is something that has a few positive qualities:

  • It works.
  • Although it's possible for a data provider to have large numbers of wcs:Coverages in their holdings, it is not practical since large numbers of wcs:Coverages will cause the wcs:Capabilities document to grow to such a size as to be indigestible by clients. Thus it seems that although it appears that this method is limited in it's scalability, if a software process is developed to generate the wcs:CoverageDescriptions it would seem that long before the file system became clogged with wcs:CoverageDescription files the service itself would be come to cumbersome for most clients.
  • Many data centers with large numbers of small coverages may find that these coverages would be appropriately aggregated into a singe larger coverage. Which in fact is the case for many the the data sets served by the THREDDS Data Server (TDS). Aggregation for Hyrax is currently under development and will be a useful addition to the WCS service when it becomes operational.

WCS Configuration

WCS is made up of three commands:

  1. wcs:GetCapabilities
  2. wcs:DescribeCoverage
  3. wcs;GetCoverage

The responses for both the wcs:DescribeCoverage and wcs:GetCoverage requests can be generated directly from the WCS "catalog". The response for a wcs:GetCapaibilities request requires localization information that can only be determined by the individual(s) that are installing the service.

The wcs:Capabilites document contains 4 sections:

  • Service Identification (ows:ServiceIdentification)
  • Service Provider (ows:ServiceProvider)
  • Operations Metadata (ows:OperationsMetadata)
  • Contents (wcs:Contents)

For any given installation of a WCS service the first three sections must be carefully localized. Their contents cannot realistically be ascertained by an automation. Thus, they are really part of the WCS configuration activity that must be performed by the service installer. The last section, Contents, can be automatically generated from the catalog of Coverages.

In this WCS implementation the ows:ServiceIdentification, ows:ServiceProvider and ows:OperationsMetadata sections are each stored as a separate XML file that is loaded by the server at startup.


Service Identification

The Service Identification metadata as described in section 7.4.4 of OGC document OGC 06-121r3.

Localization should include (but may not be limited to) updating the ows:Keytwords, ows:Fees and ows:AccessConstraints

Example Document

<?xml version="1.0" encoding="UTF-8"?>
<!-- ************************************************************ -->
<!-- * SERVICE IDENTIFICATION SECTION                           * -->
<!-- ************************************************************ -->
<ows:ServiceIdentification xmlns="http://www.opengis.net/wcs/1.1"
xmlns:ows="http://www.opengis.net/ows/1.1"
xmlns:xlink="http://www.w3.org/1999/xlink" >
  <ows:Title>OPeNDAP Hyrax Prototype WCS Service</ows:Title>
  <ows:Abstract>A prototype WCS server intended to provide WCS 1.1 (1.1.2) access to DAP datasets</ows:Abstract>
  <ows:Keywords>
     <ows:Keyword>Web Coverage Service</ows:Keyword>
     <ows:Keyword>OPeNDAP</ows:Keyword>
     <ows:Keyword>nectcdf</ows:Keyword>
     <ows:Keyword>DAP</ows:Keyword>
  </ows:Keywords>
  <ows:ServiceType>WCS</ows:ServiceType>
  <ows:ServiceTypeVersion>1.1.2</ows:ServiceTypeVersion>
  <ows:Fees>NONE</ows:Fees>
  <ows:AccessConstraints>NONE</ows:AccessConstraints>
</ows:ServiceIdentification>

Service Provider

The Service Provider metadata as described in section 7.4.5 of OGC document OGC 06-121r3.

The ows:ServiceProvider section should be localized to identify the local operator of the system. Typically this would be the name and contact information of the individual or group responsible for installing and maintaing the WCS service.

Example Document

<?xml version="1.0" encoding="UTF-8"?>
<!-- ************************************************************ -->
<!-- * SERVICE PROVIDER SECTION                                 * -->
<!-- ************************************************************ -->
<ows:ServiceProvider  xmlns="http://www.opengis.net/wcs/1.1"
xmlns:ows="http://www.opengis.net/ows/1.1"
xmlns:xlink="http://www.w3.org/1999/xlink">
  <ows:ProviderName>OPeNDAP Inc.</ows:ProviderName>
  <ows:ProviderSite xlink:href="http://www.opendap.org"/>
  <ows:ServiceContact>
     <ows:IndividualName>Nathan D. Potter</ows:IndividualName>
     <ows:PositionName>Senior Software Engineer</ows:PositionName>
     <ows:ContactInfo>
        <ows:Phone>
           <ows:Voice>123-456-7890</ows:Voice>
           <ows:Facsimile>234-567-8901</ows:Facsimile>
        </ows:Phone>
        <ows:Address>
           <ows:DeliveryPoint>165 Dean Knauss Dr</ows:DeliveryPoint>
           <ows:City>Narragansett</ows:City>
           <ows:AdministrativeArea>Rhode Island</ows:AdministrativeArea>
           <ows:PostalCode>02882</ows:PostalCode>
           <ows:Country>USA</ows:Country>
           <ows:ElectronicMailAddress>support[a.t]opendap[d.o.t]org</ows:ElectronicMailAddress>
        </ows:Address>
        <ows:OnlineResource xlink:href="http://ndp.opendap.org:8080/opendap/"/>
        <ows:HoursOfService>24x7x365</ows:HoursOfService>
        <ows:ContactInstructions>email</ows:ContactInstructions>
     </ows:ContactInfo>
     <ows:Role>Developer</ows:Role>
  </ows:ServiceContact>
</ows:ServiceProvider>

Operations Metadata

The Operations Metadata as described in section 7.4.6 of OGC document OGC 06-121r3.

Careful localization of this information is crucial to the correct function of the WCS service. Many clients will use this section of the wcs:Capabilities document to ascertain where and how they can interact with the service. It is required that the Get and Post URL's for each WCS operation point to the correct terminus on your server. If the server is behind a firewall which is port-forwarding the incoming requests the URL's may have little to do with the local network configuration.


Looking at this again I am wondering if this could be either configured or determined?

The base URL for their system could be added to the DispatchHandler configuration and the service URL's generated from that.

OR

It is the case that the servlet request contains the URL to be dereferenced. I think it might work to dynamically determine the URL that brought the GetCapabilities request to the service and to pluck it from the request and build the service URLs from it.

Either one of these would diminish the configuration burden presented to the Hyrax user.

Comments?

ndp 19:57, 14 April 2009 (PDT)

Example Document

<?xml version="1.0" encoding="UTF-8"?>
<!-- ************************************************************ -->
<!-- * OPERATIONS METADATA                                      * -->
<!-- ************************************************************ -->
<ows:OperationsMetadata xmlns="http://www.opengis.net/wcs/1.1"
                        xmlns:ows="http://www.opengis.net/ows/1.1"
                        xmlns:xlink="http://www.w3.org/1999/xlink">
    <ows:Operation name="GetCapabilities">
        <ows:DCP>
            <ows:HTTP>
                <ows:Get xlink:href="http://ndp.opendap.org:8080/opendap/WCS?"/>
                <ows:Post xlink:href="http://ndp.opendap.org:8080/opendap/WCS/post">
                    <ows:Constraint name="PostEncoding">
                        <ows:AllowedValues>
                            <ows:Value>XML</ows:Value>
                        </ows:AllowedValues>
                    </ows:Constraint>
                </ows:Post>
                <ows:Post xlink:href="http://ndp.opendap.org:8080/opendap/WCS/soap">
                    <ows:Constraint name="PostEncoding">
                        <ows:AllowedValues>
                            <ows:Value>SOAP</ows:Value>
                        </ows:AllowedValues>
                    </ows:Constraint>
                </ows:Post>
            </ows:HTTP>
        </ows:DCP>
    </ows:Operation>
    <ows:Operation name="GetCoverage">
        <ows:DCP>
            <ows:HTTP>
                <ows:Get xlink:href="http://ndp.opendap.org:8080/opendap/WCS?"/>
                <ows:Post xlink:href="http://ndp.opendap.org:8080/opendap/WCS/post">
                    <ows:Constraint name="PostEncoding">
                        <ows:AllowedValues>
                            <ows:Value>XML</ows:Value>
                        </ows:AllowedValues>
                    </ows:Constraint>
                </ows:Post>
                <ows:Post xlink:href="http://ndp.opendap.org:8080/opendap/WCS/soap">
                    <ows:Constraint name="PostEncoding">
                        <ows:AllowedValues>
                            <ows:Value>SOAP</ows:Value>
                        </ows:AllowedValues>
                    </ows:Constraint>
                </ows:Post>
            </ows:HTTP>
        </ows:DCP>
        <ows:Parameter name="Format">
            <ows:AllowedValues>
                <ows:Value>application/x-netcdf-cf1.0</ows:Value>
                <ows:Value>application/x-dap2.0</ows:Value>
            </ows:AllowedValues>
        </ows:Parameter>
    </ows:Operation>
    <ows:Operation name="DescribeCoverage">
        <ows:DCP>
            <ows:HTTP>
                <ows:Get xlink:href="http://ndp.opendap.org:8080/opendap/WCS?"/>
                <ows:Post xlink:href="http://ndp.opendap.org:8080/opendap/WCS/post">
                    <ows:Constraint name="PostEncoding">
                        <ows:AllowedValues>
                            <ows:Value>XML</ows:Value>
                        </ows:AllowedValues>
                    </ows:Constraint>
                </ows:Post>
                <ows:Post xlink:href="http://ndp.opendap.org:8080/opendap/WCS/soap">
                    <ows:Constraint name="PostEncoding">
                        <ows:AllowedValues>
                            <ows:Value>SOAP</ows:Value>
                        </ows:AllowedValues>
                    </ows:Constraint>
                </ows:Post>
            </ows:HTTP>
        </ows:DCP>
        <ows:Parameter name="Format">
            <ows:AllowedValues>
                <ows:Value>text/xml</ows:Value>
            </ows:AllowedValues>
        </ows:Parameter>
    </ows:Operation>
</ows:OperationsMetadata>

WCS Coverages Catalog

The WCS service must maintain a catalog of Coverages. In the Hyrax WCS service the implementation of this catalog is identified at server start-up from the DispatchHandler's configuration element in the olfs.xml file. As stated in the introduction the original intent (on the goal for the future) is to provide a catalog implementation that utilizes semantic web technologies to generate the WCS catalog content from existing (and probably supplemented) metadata from within the existing OPeNDAP data framework. However in there are many more fish to fry with respect to WCS than just the catalog issue, so in an effort to move that part of the process forward we have implemented a simple catalog that reads wcs:CoverageDescription elements local files. The name of this catalog implementation class is opendap.wcs.v1_1_2.LocalFileCatalog.

Currently the LocalFileCatalog is implemented to use a directory in the local file system. It assumes that every file in the directory is an XML document that contains a single wcs:CoverageDescription element. The files are ingested and QC'd at start up.

If you haven't noticed by now, this implementation requires that for each Coverage it's wcs:CoverageDescription must be written by another entity - quite probably a human.

WCS DispatchHandler Configuration

The Hyrax WCS service is made of a collection 4 implementations of the opendap.coreServlet.DispatchHandler interface.

  • HTTP GET: opendap.wcs.v1_1_2.DispatchHandler
  • HTTP POST (For posting unadorned XML WCS requests): opendap.wcs.v1_1_2.PostHandler
  • HTTP POST (For posting SOAP envelopes containg WCS requests): opendap.wcs.v1_1_2.SoapHandler
  • HTTP POST (For handling WCS requests posted from an HTML form): opendap.wcs.v1_1_2.FormHandler

The service is enabled by creating an entry for each service component in the olfs.xml file.

The primary DispatchHandler is opendap.wcs.v1_1_2.DispatchHandler. It is required for the WCS service and it's Handler declaration contains the configuration information for the service. In it's Handler declaration the location of the ServiceIdentification, ServiceProvider, and OperationsMetadata documents are identified, along with a WCS catalog implementation to be used by the service.


To "turn on" the service Handler declarations must appear in the olfs.xml opendap.wcs.v1_1_2.DispatchHandler Configuration


Example Configuration

 <?xml version="1.0" encoding="UTF-8"?>
 <OLFSConfig>
   <DispatchHandlers>
       <HttpGetHandlers>
           <Handler className="opendap.bes.BESManager">
               <BES>
                   <prefix>/</prefix>
                   <host>localhost</host>
                   <port>10002</port>
                   <ClientPool maximum="10" />
               </BES>
           </Handler>

           <Handler className="opendap.coreServlet.BotBlocker">
              <IpMatch>65\.55\.[012]?\d?\d\.[012]?\d?\d</IpMatch>
            </Handler>  
                       

           <Handler className="opendap.wcs.v1_1_2.DispatchHandler">
               <prefix>WCS</prefix>
               <ServiceIdentification>/absolute/path/to/the/document/ServiceIdentification.xml</ServiceIdentification>
               <ServiceProvider>/absolute/path/to/the/document/ServiceProvider.xml</ServiceProvider>
               <OperationsMetadata>/absolute/path/to/the/document/OperationsMetadata.xml</OperationsMetadata>
               <WcsCatalog className="opendap.wcs.v1_1_2.LocalFileCatalog">
                   <CoveragesDirectory>/absolute/path/to/the/directory/containing/the/wcs:CoverageDescription/documents/coverages/dir</CoveragesDirectory>
               </WcsCatalog>
           </Handler>


           <Handler className="opendap.threddsHandler.StaticCatalogDispatch">
               <prefix>thredds</prefix>
               <useMemoryCache>true</useMemoryCache>
           </Handler>
           <Handler className="opendap.bes.DapDispatchHandler" />
           <Handler className="opendap.bes.DirectoryDispatchHandler" />
           <Handler className="opendap.coreServlet.SpecialRequestDispatchHandler" />
           <Handler className="opendap.bes.VersionDispatchHandler" />
           <Handler className="opendap.bes.FileDispatchHandler" >
               <AllowDirectDataSourceAccess />
           </Handler>
           <Handler className="opendap.bes.BESThreddsDispatchHandler" />
       </HttpGetHandlers>


       <HttpPostHandlers>

           <Handler className="opendap.wcs.v1_1_2.PostHandler" >
               <prefix>WCS/post</prefix>
           </Handler>
           <Handler className="opendap.wcs.v1_1_2.SoapHandler" >
               <prefix>WCS/soap</prefix>
           </Handler>
           <Handler className="opendap.wcs.v1_1_2.FormHandler" >
               <prefix>WCS/form</prefix>
           </Handler>
 

           <Handler className="opendap.coreServlet.SOAPRequestDispatcher" >
               <OpendapSoapDispatchHandler>opendap.bes.SoapDispatchHandler</OpendapSoapDispatchHandler>
           </Handler>
       </HttpPostHandlers>
   </DispatchHandlers>
</OLFSConfig>