<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
      version="3.0">
  <display-name>THREDDS Data Server</display-name>
  <description>THREDDS Data Server</description>

  <!-- Provide the context path at init time (otherwise, not available till a request is made). -->
  <!-- Servlet 2.5 spec provides ServletContext.getContextPath(). But we aren't requiring Servlet 2.5 yet. -->
  <context-param>
    <param-name>ContextPath</param-name>
    <param-value>thredds</param-value>
  </context-param>

  <!-- Turn on some more targeted debugging. -->
  <filter>
    <filter-name>RequestBracketingLogMessageFilter</filter-name>
    <filter-class>thredds.server.RequestBracketingLogMessageFilter</filter-class>
  </filter>

  <filter>
    <filter-name>RequestPathFilter</filter-name>
    <filter-class>thredds.servlet.filter.RequestPathFilter</filter-class>
  </filter>

  <filter>
    <filter-name>RequestQueryFilter</filter-name>
    <filter-class>thredds.servlet.filter.RequestQueryFilter</filter-class>
  </filter>

  <filter>
    <filter-name>RequestQueryFilterAllowAngleBrackets</filter-name>
    <filter-class>thredds.servlet.filter.RequestQueryFilter</filter-class>
    <init-param>
      <param-name>allowAngleBrackets</param-name>
      <param-value>true</param-value>
    </init-param>
  </filter>

  <!-- filter>
    <filter-name>CatalogServiceFilter</filter-name>
    <filter-class>thredds.servlet.filter.CatalogServiceFilter</filter-class>
  </filter -->

  <filter>
    <filter-name>CookieFilter</filter-name>
    <filter-class>thredds.servlet.filter.CookieFilter</filter-class>
  </filter>

  <filter>
    <filter-name>RequestCORSFilter</filter-name>
    <!--filter-class>thredds.servlet.filter.RequestCORSFilter</filter-class-->
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    <init-param>
	    <param-name>targetBeanName</param-name>
	    <param-value>corsFilter</param-value>
    </init-param>
  </filter>

  <filter-mapping>
    <filter-name>RequestBracketingLogMessageFilter</filter-name>
    <!-- servlet-name>metadata</servlet-name-->
    <url-pattern>/*</url-pattern>
  </filter-mapping>

  <!--
  Filter:
   - the request URL path
   - on all requests.
  -->
  <filter-mapping>
    <filter-name>RequestPathFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

  <!--
  Filter:
   - the request URL query string
   - on all requests except OPeNDAP requests.
  -->
  <filter-mapping>
    <filter-name>RequestQueryFilter</filter-name>
    <servlet-name>root</servlet-name>
  </filter-mapping>
   
  <!-- filter-mapping>
    <filter-name>RequestQueryFilter</filter-name>
    <servlet-name>catalogService</servlet-name>
  </filter-mapping -->
    
  <!--filter-mapping>
    <filter-name>RequestQueryFilter</filter-name>
    <servlet-name>FileServer</servlet-name>
  </filter-mapping-->
  <!-- filter-mapping>
    <filter-name>RequestQueryFilter</filter-name>
    <servlet-name>radarServer</servlet-name>
  </filter-mapping-->
  <filter-mapping>
    <filter-name>RequestQueryFilter</filter-name>
    <servlet-name>RestrictedDataset</servlet-name>
  </filter-mapping>
  <filter-mapping>
    <filter-name>RequestCORSFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
  <!-- filter-mapping>
    <filter-name>RequestQueryFilter</filter-name>
    <servlet-name>wcs</servlet-name>
  </filter-mapping -->
  <filter-mapping>
    <filter-name>RequestQueryFilter</filter-name>
    <servlet-name>wms</servlet-name>
  </filter-mapping>
  
  <!-- filter-mapping>
    <filter-name>RequestQueryFilter</filter-name>
    <servlet-name>DLwriter</servlet-name>
  </filter-mapping -->

  <!--
  Filter:
   - the request URL query string
   - on all OPeNDAP and DAP4 requests.
  -->
  <filter-mapping>
    <filter-name>RequestQueryFilterAllowAngleBrackets</filter-name>
    <servlet-name>Opendap</servlet-name>
  </filter-mapping>

  <!--
  Filter all requests that contain parameters used by CatalogServices
  -->
  <!-- filter-mapping>
    <filter-name>CatalogServiceFilter</filter-name>
    <servlet-name>catalogService</servlet-name>
  </filter-mapping -->
  
  <!--
  Filter opendap and dap4 cookies
  -->
  <filter-mapping>
    <filter-name>CookieFilter</filter-name>
    <servlet-name>Opendap</servlet-name>
  </filter-mapping>

  <!--
     Location of the Log4J config file (relative to the webapp root), for initialization.

  <context-param>
    <param-name>log4jConfigLocation</param-name>
    <param-value>/WEB-INF/log4j.xml</param-value>
  </context-param>
   -->
  <!--
     Don't expose the webapp root directory as the "webapp.root" system property.
     Multiple TDS will clash over this unless we change the name of the system property by defining it with a context-param named "webAppRootKey".
     It isn't needed because we determine the logging directory ourselves.

  <context-param>
    <param-name>log4jExposeWebAppRoot</param-name>
    <param-value>false</param-value>
  </context-param>
   -->

  <!--
     Spring listener to bootstrap Spring WebApplicationContext. Used to
     handle Spring bean configuration outside of SpringMVC configuration.
     Paths, by default, are relative to the application root.
  -->
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/applicationContext-tdsConfig.xml</param-value>
  </context-param>

  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>

  <listener>
    <listener-class>thredds.server.opendap.OpendapSessionAttributeListener</listener-class>
  </listener>



  <!-- Some possible ways to deal with error handling. -->
  <!--
  <error-page>
    <exception-type>java.lang.NullPointerException</exception-type>
    <location>/null.html</location>
  </error-page>
  -->
  <!-- The following goes into affect when 'res.sendError(100)' is called. -->
  <!--
  <error-page>
    <error-code>100</error-code>
    <location>/myPage.html</location>
  </error-page>
  -->

  <!-- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -->

  <!-- root servlet -->
  <servlet>
    <servlet-name>root</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>/WEB-INF/servlet-context.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>

  <!-- Setup for catalog services. (Catalog subsetting, validation, and translation into HTML.)
  <servlet>
    <servlet-name>catalogService</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet -->

  <!-- data services -->
  <!-- NON-SPRING  controllers ands servlets -->
  <!-- NetCDF/OPeNDAP server -->
  <servlet>
    <display-name>OPeNDAP Server</display-name>
    <servlet-name>Opendap</servlet-name>
    <servlet-class>thredds.server.opendap.OpendapServlet</servlet-class>
    <load-on-startup>2</load-on-startup>
  </servlet>

  <!-- HTTP File server -->
  <!-- servlet>
    <servlet-name>FileServer</servlet-name>
    <servlet-class>thredds.servlet.FileServerServlet</servlet-class>
    <load-on-startup>3</load-on-startup>
  </servlet -->

  <!-- Radar Server -->
  <!-- servlet>
    <servlet-name>radarServer</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet -->

  <!-- OGC Web Coverage server -->
  <!-- servlet>
    <servlet-name>wcs</servlet-name>
    <servlet-class>thredds.server.wcs.WCSServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet -->

  <servlet>
    <servlet-name>wms</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>4</load-on-startup>
  </servlet>

  <!-- Restricted Access (using container managed security, eg Tomcat, or CAMS) -->
  <servlet>
    <servlet-name>RestrictedDataset</servlet-name>
    <servlet-class>thredds.servlet.restrict.RestrictedDatasetServlet</servlet-class>

    <init-param>
      <param-name>Authorizer</param-name>
      <param-value>thredds.servlet.restrict.TomcatAuthorizer</param-value>
    </init-param>

    <init-param>
      <param-name>useSSL</param-name>
      <param-value>false</param-value>
    </init-param>

    <init-param>
      <param-name>portSSL</param-name>
      <param-value>8443</param-value>
    </init-param>

    <load-on-startup>2</load-on-startup>
  </servlet>

  <!-- Restricted Access (using CAS)
  <servlet>
    <servlet-name>RestrictedDataset</servlet-name>
    <servlet-class>thredds.servlet.restrict.RestrictedDatasetServlet</servlet-class>

    <init-param>
      <param-name>Authorizer</param-name>
      <param-value>thredds.servlet.restrict.CASAuthorizer</param-value>
    </init-param>

    <init-param>
      <param-name>RoleDatabase</param-name>
      <param-value>C:/Program Files (x86)/Apache Software Foundation/apache-tomcat-5.5.20/conf/tomcat-users.xml</param-value>
    </init-param>

    <init-param>
      <param-name>edu.yale.its.tp.cas.client.filter.loginUrl</param-name>
      <param-value>https://localhost:8443/cas/login</param-value>
    </init-param>
    <init-param>
      <param-name>edu.yale.its.tp.cas.client.filter.validateUrl</param-name>
      <param-value>https://localhost:8443/cas/proxyValidate</param-value>
    </init-param>
    <init-param>
      <param-name>edu.yale.its.tp.cas.client.filter.serverName</param-name>
      <param-value>localhost:8080</param-value>
    </init-param>

    <load-on-startup>2</load-on-startup>
  </servlet>  -->


  <!-- catalog services -->

  <!-- Setup for the CatalogAnnotate servlet. (Attach extra info to a catalog.
  <servlet>
    <servlet-name>CatalogAnnotate</servlet-name>
    <servlet-class>thredds.servlet.CatalogAnnotate</servlet-class>
  </servlet> -->

  <!-- Setup for the CatalogDL servlet. (Make Digital Library records from a catalog.  -->
  <!-- servlet>
    <servlet-name>DLwriter</servlet-name>
    <servlet-class>thredds.servlet.DLwriterServlet</servlet-class>
    <load-on-startup>10</load-on-startup>
  </servlet -->

  <!-- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -->

  <!-- default servlet -->
  <servlet-mapping>
    <servlet-name>root</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>root</servlet-name>
    <url-pattern>*.css</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>root</servlet-name>
    <url-pattern>*.gif</url-pattern>
  </servlet-mapping>

  <!-- servlet-mapping>
    <servlet-name>catalogService</servlet-name>
    <url-pattern>*.xml</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>catalogService</servlet-name>
    <url-pattern>*.html</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>catalogService</servlet-name>
    <url-pattern>/catalog/*</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>catalogService</servlet-name>
    <url-pattern>/remoteCatalogService</url-pattern>
  </servlet-mapping>
  <servlet-mapping>  For backwards compatibility
    <servlet-name>catalogService</servlet-name>
    <url-pattern>/catalogServices</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>catalogService</servlet-name>
    <url-pattern>/remoteCatalogValidation.html</url-pattern>
  </servlet-mapping -->

  <!-- data services -->
  <!--servlet-mapping>
    <servlet-name>radarServer</servlet-name>
    <url-pattern>/radarServer/*</url-pattern>
  </servlet-mapping -->

  <servlet-mapping>
    <servlet-name>Opendap</servlet-name>
    <url-pattern>/dodsC/*</url-pattern>
  </servlet-mapping>

  <!-- servlet-mapping>
    <servlet-name>FileServer</servlet-name>
    <url-pattern>/fileServer/*</url-pattern>
  </servlet-mapping -->

  <servlet-mapping>
    <servlet-name>RestrictedDataset</servlet-name>
    <url-pattern>/restrictedAccess/*</url-pattern>
  </servlet-mapping>

  <!-- servlet-mapping>
    <servlet-name>wcs</servlet-name>
    <url-pattern>/wcs/*</url-pattern>
  </servlet-mapping -->

  <servlet-mapping>
    <servlet-name>wms</servlet-name>
    <url-pattern>/wms/*</url-pattern>
  </servlet-mapping>

  <!-- catalog services -->
  <!--servlet-mapping>
    <servlet-name>DLwriter</servlet-name>
    <url-pattern>/DLwriter</url-pattern>
  </servlet-mapping -->

  <!-- servlet-mapping>
     <servlet-name>View</servlet-name>
     <url-pattern>/view/*</url-pattern>
   </servlet-mapping-->

  <welcome-file-list>
    <welcome-file>/</welcome-file>
  </welcome-file-list>

  <error-page>
    <error-code>404</error-code>
    <location>/WEB-INF/jsp/errorpages/404.jsp</location>
  </error-page>
  <error-page>
    <error-code>500</error-code>
    <location>/WEB-INF/jsp/errorpages/500.jsp</location>
  </error-page>

  <!-- ++++++++++ Setup security restrictions ++++++++++ -->
  <!-- Do not allow anything but GET  LOOK doesnt work
  <security-constraint>
      <display-name>Deny all HTTP methods except GET</display-name>
      <web-resource-collection>
          <url-pattern>/</url-pattern>
          <http-method-omission>GET</http-method-omission>
      </web-resource-collection>
      <auth-constraint/>
  </security-constraint -->

  <!-- tdsConfig with HTTPS needed for /admin access  -->
  <security-constraint>
    <web-resource-collection>
      <web-resource-name>sensitive read access</web-resource-name>
      <url-pattern>/admin/*</url-pattern>
    </web-resource-collection>
    <auth-constraint>
      <role-name>tdsConfig</role-name>
    </auth-constraint>
{% if thredds_force_ssl_for_user_data %}
     <user-data-constraint>
      <transport-guarantee>CONFIDENTIAL</transport-guarantee>
    </user-data-constraint>
{% endif %}
  </security-constraint>

  <!-- tdsTrigger with HTTPS needed for /admin/trigger  -->
  <security-constraint>
    <web-resource-collection>
      <web-resource-name>allow feature collection rescan to be triggered externally</web-resource-name>
      <url-pattern>/admin/collection/trigger</url-pattern>
      <url-pattern>/admin/trigger</url-pattern>
    </web-resource-collection>
    <auth-constraint>
      <role-name>tdsTrigger</role-name>
    </auth-constraint>
{% if thredds_force_ssl_for_user_data %}
     <user-data-constraint>
      <transport-guarantee>CONFIDENTIAL</transport-guarantee>
    </user-data-constraint>
{% endif %}
  </security-constraint>

  <!-- This allows "remote monitoring":
    /thredds/admin/log gives access to logs.
   -->

  <!-- tdsMonitor with HTTPS needed for access to logs  -->
  <security-constraint>
    <web-resource-collection>
      <web-resource-name>sensitive read access</web-resource-name>
      <url-pattern>/admin/log/*</url-pattern>
    </web-resource-collection>
    <auth-constraint>
      <role-name>tdsMonitor</role-name>
    </auth-constraint>
{% if thredds_force_ssl_for_user_data %}
     <user-data-constraint>
      <transport-guarantee>CONFIDENTIAL</transport-guarantee>
    </user-data-constraint>
{% endif %}
  </security-constraint>

  <!-- default restricted access dataset uses DIGEST, but not HTTPS -->
  <security-constraint>
    <web-resource-collection>
      <web-resource-name>restricted access datasets</web-resource-name>
      <url-pattern>/restrictedAccess/*</url-pattern>
    </web-resource-collection>
    <auth-constraint>
      <role-name>restrictedDatasetUser</role-name>
    </auth-constraint>
{% if thredds_force_ssl_for_user_data %}
     <user-data-constraint>
      <transport-guarantee>CONFIDENTIAL</transport-guarantee>
    </user-data-constraint>
{% endif %}
  </security-constraint>

  <!-- can only have one login-config for entire context. -->
  <login-config>
    <auth-method>BASIC</auth-method>
    <realm-name>THREDDS Data Server</realm-name>
  </login-config>

  <!-- Define security roles. -->
  <security-role>
    <description>The configuration role allows users to configure the THREDDS server.</description>
    <role-name>tdsConfig</role-name>
  </security-role>

  <security-role>
    <description>User who can download tds logs for monitoring purposes.</description>
    <role-name>tdsMonitor</role-name>
  </security-role>

  <security-role>
    <description>User is allowed to trigger featureCollection rereads</description>
    <role-name>tdsTrigger</role-name>
  </security-role>

  <security-role>
    <description>User who can access restricted datasets.</description>
    <role-name>restrictedDatasetUser</role-name>
  </security-role>

</web-app>