<?xml version="1.0" encoding="UTF-8"?>
<!--
  _=_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_=
  Repose
  _-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
  Copyright (C) 2010 - 2015 Rackspace US, Inc.
  _-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at
  
       http://www.apache.org/licenses/LICENSE-2.0
  
  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
  =_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_=_
  -->


<xs:schema xmlns:dds="http://docs.openrepose.org/repose/distributed-datastore/v1.0"
           xmlns:html="http://www.w3.org/1999/xhtml"
           xmlns:xs="http://www.w3.org/2001/XMLSchema"
           xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning"
           xmlns:xerces="http://xerces.apache.org"
           xmlns:saxon="http://saxon.sf.net/"
           elementFormDefault="qualified"
           attributeFormDefault="unqualified"
           targetNamespace="http://docs.openrepose.org/repose/distributed-datastore/v1.0">

    <!-- Configuration Schema Definitions -->
    <xs:element name="distributed-datastore" type="dds:DistributedDatastoreConfiguration"/>

    <xs:complexType name="DistributedDatastoreConfiguration">
        <xs:annotation>
            <xs:documentation>
                <html:p>
                    Defines a collection of configuration options for the distributed
                    datastore component.
                </html:p>
            </xs:documentation>
        </xs:annotation>

        <xs:sequence>
            <xs:element name="allowed-hosts" type="dds:HostAccessControlList" minOccurs="1" maxOccurs="1"/>
            <xs:element name="port-config" type="dds:PortConfiguration" minOccurs="1" maxOccurs="1"/>
        </xs:sequence>

        <xs:attribute name="connection-pool-id" type="xs:string" use="optional">
            <xs:annotation>
                <xs:documentation>
                    <html:p>
                        HTTP Connection pool (ID) to use when communicating with other members of the distributed
                        datastore.
                    </html:p>
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>

        <xs:attribute name="keystore-filename" type="xs:anyURI" use="optional">
            <xs:annotation>
                <xs:documentation>
                    <html:p>
                        IF this attribute is configured,
                        THEN it is assumed that it points to the Java keystore containing the client certificate to
                        present for client authentication (e.g keystore.jks)
                        AND the keystore-password and key-password attributes are no longer optional.
                    </html:p>
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>

        <xs:attribute name="keystore-password" type="xs:string" use="optional">
            <xs:annotation>
                <xs:documentation>
                    <html:p>The password for the client authentication keystore.</html:p>
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>

        <xs:attribute name="key-password" type="xs:string" use="optional">
            <xs:annotation>
                <xs:documentation>
                    <html:p>The password for the particular client authentication key in the keystore.</html:p>
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>

        <xs:attribute name="truststore-filename" type="xs:anyURI" use="optional">
            <xs:annotation>
                <xs:documentation>
                    <html:p>
                        The truststore used for validating the server this pool is connecting to.
                        This is typically set to the same path as the client authentication keystore.
                    </html:p>
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>

        <xs:attribute name="truststore-password" type="xs:string" use="optional">
            <xs:annotation>
                <xs:documentation>
                    <html:p>
                        The password for the client authentication truststore.
                        NOTE: This attribute is only used if the truststore-filename attribute is present.
                    </html:p>
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>

        <xs:assert vc:minVersion="1.1"
                   test="if (@keystore-filename or @keystore-password or @key-password) then (@keystore-filename and @keystore-password and @key-password) else true()"
                   xerces:message="IF a keystore filename, password, or key password is provided, THEN all must be provided"
                   saxon:message="IF a keystore filename, password, or key password is provided, THEN all must be provided"/>
    </xs:complexType>

    <xs:complexType name="HostAccessControlList">
        <xs:annotation>
            <xs:documentation>
                <html:p>
                    Defines a list of hosts who has access to the distributed datastore
                    API calls. This does not add the host to the participating data
                    storage nodes.
                </html:p>
            </xs:documentation>
        </xs:annotation>

        <xs:sequence>
            <xs:element name="allow" type="dds:HostAccessControl" minOccurs="0" maxOccurs="unbounded"/>
        </xs:sequence>

        <xs:attribute name="allow-all" type="xs:boolean" use="optional" default="false">
            <xs:annotation>
                <xs:documentation>
                    <html:p>
                        Setting allow-all to true will turn off host ACL checking.
                    </html:p>
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>

        <xs:assert vc:minVersion="1.1" test="if (xs:boolean(@allow-all)) then count(dds:allow) = 0 else true()"
                   xerces:message="If allow-all is true then allow elements not allowed."
                   saxon:message="If allow-all is true then allow elements not allowed."/>

    </xs:complexType>

    <xs:complexType name="HostAccessControl">
        <xs:annotation>
            <xs:documentation>
                <html:p>
                    An allow access control defines a set of parameters that must be
                    met for an API request to be allowed.
                </html:p>
            </xs:documentation>
        </xs:annotation>

        <xs:attribute name="host" type="xs:string" use="required">
            <xs:annotation>
                <xs:documentation>
                    <html:p>
                        Defines a host who has access to the distributed datastore API.
                    </html:p>
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>
    </xs:complexType>


    <xs:complexType name="PortConfiguration">
        <xs:annotation>
            <xs:documentation>
                <html:p>
                    Defines a list of hosts who has access to the distributed datastore
                    API calls. This does not add the host to the participating data
                    storage nodes.
                </html:p>
            </xs:documentation>
        </xs:annotation>

        <xs:sequence>
            <xs:element name="port" type="dds:Port" minOccurs="1" maxOccurs="unbounded"/>
        </xs:sequence>
    </xs:complexType>

    <xs:complexType name="Port">
        <xs:annotation>
            <xs:documentation>
                <html:p>
                    An allow access control defines a set of parameters that must be
                    met for an API request to be allowed.
                </html:p>
            </xs:documentation>
        </xs:annotation>

        <xs:attribute name="cluster" type="xs:string" use="required">
            <xs:annotation>
                <xs:documentation>
                    <html:p>
                        Defines the cluster which this datastore is tied.
                    </html:p>
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>

        <xs:attribute name="node" type="xs:string" use="optional" default="-1">
            <xs:annotation>
                <xs:documentation>
                    <html:p>
                        Defines the node which this datastore is tied.
                    </html:p>
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>

        <xs:attribute name="port" type="xs:int" use="required">
            <xs:annotation>
                <xs:documentation>
                    <html:p>
                        Defines the port on which this datastore will listen
                    </html:p>
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>
    </xs:complexType>
</xs:schema>
