\documentclass[11pt,a4paper]{ivoa}
\input tthdefs

\usepackage{listings}
\usepackage{courier}
\usepackage{appendix}

\lstset{
    basicstyle=\scriptsize\ttfamily,
    columns=fullflexible,
    keepspaces=true,
    breaklines=true,
    linewidth=14cm,
    frame=none
}

\hyphenation{Con-tai-ner-Node}

\title{VOSpace}

\ivoagroup{Grid and Web Services Working Group}

\author{Matthew Graham}
\author{Dave Morris}
\author{Guy Rixon}
\author{Pat Dowler}
\author{Andr\'e Schaaff}
\author{Doug Tody}
\author{Brian Major}

\editor{Matthew Graham}
\editor{Brian Major}

\previousversion[http://www.ivoa.net/documents/VOSpace/20180502/index.html]{PR-VOSpace-2.1-20180502}
\previousversion[http://www.ivoa.net/documents/VOSpace/20170924/index.html]{PR-VOSpace-2.1-20170924}
\previousversion[http://www.ivoa.net/documents/VOSpace/20170405/index.html]{PR-VOSpace-2.1-20170405}
\previousversion[http://www.ivoa.net/documents/VOSpace/20160420/index.html]{WD-VOSpace-2.1-20160405}
\previousversion[http://www.ivoa.net/documents/VOSpace/20150601/index.html]{WD-VOSpace-2.1-20150601}
\previousversion[http://www.ivoa.net/documents/VOSpace/20140805/index.html]{WD-VOSpace-2.1-20140805}
\previousversion[http://www.ivoa.net/documents/VOSpace/20130329/index.html]{REC-VOSpace-2.0-20130329}
\previousversion[http://www.ivoa.net/documents/VOSpace/20121221/index.html]{PR-VOSpace-2.0-20121221}
\previousversion[http://www.ivoa.net/documents/VOSpace/20120824/index.html]{PR-VOSpace-2.0-20120824}
\previousversion[http://www.ivoa.net/documents/VOSpace/20111202/index.html]{PR-VOSpace-2.0-20111202}
\previousversion[http://www.ivoa.net/documents/VOSpace/20110628/index.html]{WD-VOSpace-2.0-20110628}
\previousversion[http://www.ivoa.net/documents/VOSpace/20101112/index.html]{WD-VOSpace-2.0-20101112}
\previousversion[http://www.ivoa.net/documents/VOSpace/20100323/index.html]{WD-VOSpace-2.0-20100323}
\previousversion[http://www.ivoa.net/documents/VOSpace/20090513/index.html]{WD-VOSpace-2.0-20090513}
       
\begin{document}
\begin{abstract}
VOSpace is the IVOA interface to distributed storage. This specification presents the second RESTful version of the interface.  It specifies how VO agents and applications can use network attached data stores to persist and exchange data in a standard way.
\end{abstract}

\section*{Acknowledgments}
\label{sec:acknowledgments}
This document derives from discussions among the Grid and Web Services working group of the IVOA.

This document has been developed with support from the National Science Foundation's Information Technology Research Program under Cooperative Agreement AST0122449 with the John Hopkins University, from the UK Science and Technology Facilities Council (STFC), and from the European Commission's Sixth Framework Program via the Optical Infrared Coordination Network (OPTICON).

\section*{Conformance-related definitions}
\label{sec:conformance-related definitions}
The words ``MUST'', ``SHALL'', ``SHOULD'', ``MAY'', ``RECOMMENDED'', and
``OPTIONAL'' (in upper or lower case) used in this document are to be
interpreted as described in IETF standard, \citep{std:RFC2119}.

The \emph{Virtual Observatory (VO)} is
general term for a collection of federated resources that can be used
to conduct astronomical research, education, and outreach.
The \href{http://www.ivoa.net}{International
Virtual Observatory Alliance (IVOA)} is a global
collaboration of separately funded projects to develop standards and
infrastructure that enable VO applications.

\section{Introduction}
\label{sec:introduction}
VOSpace is the IVOA interface to distributed storage. It specifies how VO agents and applications can use network attached data stores to persist and exchange data in a standard way.

A VOSpace web service is an access point for a distributed storage network. Through this access point, a client can:

\begin{itemize}
    \item add or delete data objects in a tree data structure
    \item manipulate metadata for the data objects
    \item obtain URIs through which the content of the data objects can be accessed
\end{itemize}
VOSpace does not define how the data is stored or transferred, only the control messages to gain access. Thus, the VOSpace interface can readily be added to an existing storage system.

When we speak of ``a VOSpace'', we mean the arrangement of data accessible through one particular VOSpace service.

Each data object within a VOSpace service is represented as a node and has a description called a representation. A useful analogy to have in mind when reading this document is that a node is equivalent to a file or a directory.

Nodes in VOSpace have unique identifiers expressed as URIs in the `vos' scheme, as defined below.

\subsection{Previous Versions}
\label{subsec:previousversions}

This specification presents the second RESTful version of the interface. Except for minor additions to the 2.0 specification, it is functionally equivalent to the SOAP-based VOSpace 1.1 specification. Note that 1.x VOSpace clients will not work with this new version of the interface. VOSpace 2.0 and 2.1 clients will work with 2.1 services. VOSpace 2.1 clients, however, will not work with VOSpace 2.0 services.

VOSpace 2.0 did not introduce any new functionality to that already offered by prior (SOAP-based) versions of the interface (VOSpace 1.1) but defines a RESTful binding for the interface. VOSpace 2.1 introduces minor changes to VOSpace 2.0 mainly addressing access control and operation optimizations.

\subsection{Typical use of a VOSpace service}
\label{subsec:typical use of a vospace service}
A typical use case for VOSpace is uploading a local data file to a remote VOSpace service. This is a two-stage process: creating a description of the data file (representation) in the VOSpace including any metadata (its properties) that they want to associate with it (e.g., MIME type), and defining the transfer operation that will actually see the data file bytes uploaded to the VOSpace service.

Let's consider the first step: the user provides a XML description of the data file which they HTTP PUT to the appropriate VOSpace URI -- this will be the HTTP identifier for the data file in the VOSpace, e.g., http://server.example.com/vospace/nodes/mytable1. The description will resemble this:

\begin{lstlisting}
<vos:node xmlns:vos="http://www.ivoa.net/xml/VOSpace/v2.0"
    xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" 
    uri="vos://example.com!vospace/mytable1"
    xsi:type="vos:UnstructuredDataNode">  
    <vos:properties> 
        <vos:property uri="ivo://ivoa.net/vospace/core#mimetype">
            text/xml
        </vos:property>     
    </vos:properties> 
</vos:node> 
\end{lstlisting}
\noindent
Note that the node path is specified in two places on this request, and that they must match:
\begin{itemize}
   \item In the path of the URL in which the client performs the HTTP PUT
   \item In the node uri attribute of the XML description
\end{itemize}

The service will reply with an amended version of the representation containing service-specific details in addition to the information supplied by the user. These will include data formats that the service can handle for the type of node created in the VOSpace, third-party interfaces (capabilities) to the data that the service offers, and system metadata.

The user will then describe the data format (the view) they want to use in uploading the file, e.g., VOTable, and the transport protocol (the protocol) that they want to employ to upload the file, e.g., HTTP PUT. This will result in the HTTP POSTing of a XML description of the transfer request to the appropriate VOSpace transfer URL:  http://server.example.com/vospace/synctrans. The description will resemble this:

\begin{lstlisting}
<vos:transfer xmlns:vos="http://www.ivoa.net/xml/VOSpace/v2.0" version="2.1">
    <vos:target>vos://example.com!vospace/mytable1</vos:target>
    <vos:direction>pushToVoSpace</vos:direction> 
    <vos:view uri="ivo://ivoa.net/vospace/core#votable"/> 
    <vos:protocol uri="ivo://ivoa.net/vospace/core#httpput"/>  
</vos:transfer>
\end{lstlisting}

The service will reply with a redirect to a location with an amended version of the transfer representation that contains, for the protocols the service supports, URL endpoints that the user may HTTP PUT the data file to, e.g., http://storage1.example.com/vospace/mytable1.  The user will then use a regular HTTP client to transfer (PUT) the local file to one of the endpoints. This illustrates an important point about VOSpace -- it is only concerned with the server-side management of data storage and transfer. A client negotiates the details of a data transfer with a VOSpace service but the actual transfer of bytes across a network is handled by other tools.

Similarly, when users want to retrieve a data file from a VOSpace service, they will specify the data format (view) they want to use in downloading the file (e.g., VOTable), and the transport protocol (the protocol) that they want to employ to download the file (e.g., HTTP GET), and then HTTP POST a XML description of this transfer request to the VOSpace transfer URL (e.g., http://server.example.com/vospace/synctrans). The description will resemble this:

\begin{lstlisting}
<vos:transfer xmlns:vos="http://www.ivoa.net/xml/VOSpace/v2.0" version="2.1">
    <vos:target>vos://example.com!vospace/mytable1</vos:target>
    <vos:direction>pullFromVoSpace</vos:direction> 
    <vos:view uri="ivo://ivoa.net/vospace/core#votable"/> 
    <vos:protocol uri="ivo://ivoa.net/vospace/core#httpget"/>  
</vos:transfer>
\end{lstlisting}

The service will reply with a redirect to a location that contains an amended version of the transfer representation that contains, for the protocols the service supports, the URL endpoints that the user may HTTP GET the data from, e.g., http://storage1.example.com/vospace/myDataNode. The user can then download the data file by pointing an HTTP client (e.g., web browser) at the specified endpoint.

\subsection{Role within the VO Architecture}
\label{subsec:role within the vo architecture}

The IVOA Architecture \citep{note:VOARCH} provides a high-level view of how IVOA standards work together to connect users and applications with providers of data and services, as depicted in the diagram in Figure ~\ref{fig:archdiag}.

In this architecture, users employ a variety of tools (from the User Layer) to discover and access archives and services of interest (represented in the Resource Layer). VOSpace provides an interface to storage resources containing the results of using these archives and services and also to other storage solutions, e.g., local disks, where users might want to transfer these results for further work. Items in these resources are referenced by a VOSpace identifier which is related to the standard IVOA Resource Identifier. This version of VOSpace employs the UWS design pattern \citep{std:UWS} to manage data transfers (see section \ref{subsec:transfers}). VOSpace instances may also employ the IVOA Single-Sign-On standard \citep{std:SSOAUTH2} for authentication purposes (see section \ref{sec:access control}) and IVOA Credential Delegation Protocol \citep{std:CDP} to delegate data transfers.

\begin{figure}
\centering
% Get the architecture diagram from the TCG chair
% http://wiki.ivoa.net/twiki/bin/view/IVOA/IvoaTCG
% If they give you a PDF, for now dumb it down to a png by
% convert -antialias -density 72x72 archdiag.pdf archdiag.png
% Oh -- Notes don't need this; you'd have to remove archdiag.png
% from FIGURES in the Makefile, too.
\includegraphics[width=0.9\textwidth]{archdiag.png}
\caption{VOSpace in the IVOA Architecture. This provides an interface to distributed storage. It specifies how applications can use networked data stores to persist and exchange data in a standardized fashion.}
\label{fig:archdiag}
\end{figure}

% Note: add 'search' section to above paragraph when reinstated

\subsection{Document roadmap}
\label{subsec:document roadmap}
The rest of this document is structured as follows:

In Section \ref{sec:vospace identifiers}, we specify the URI syntax for identifying data objects (nodes) in VOSpace.

In Section \ref{sec:vospace data model}, we present the data model that underpins the VOSpace architecture. This consists of a number of data structures, which have XML representations that are used across the wire in message exchanges with a VOSpace service. These structures represent:

\begin{itemize}
    \item the data objects themselves (nodes)
    \item metadata that can be associated with a data object (properties)
    \item third-party interfaces to the data (capabilities)
    \item the data format used when transferring data objects across the wire (views)
    \item the transport protocol employed in a data transfer (protocols)
    \item the data transfer itself (transfers)
%    \item searches of data objects (searches)
\end{itemize}

We also describe the REST bindings between these representations and their URIs (HTTP identifiers).

In Section \ref{sec:access control}, we outline how security and access control policies are currently handled in VOSpace.

In Section \ref{sec:web service operations}, we detail the operations that the VOSpace interface supports. These handle access to service-level metadata, the creation and manipulation of nodes within the VOSpace, access to node metadata (properties) and data transfer to and from the VOSpace.

In Appendix \ref{sec:machine readable definitions}, we formally define the VOSpace interface with a machine readable description of its requests and responses and in Appendix \ref{sec:compliance matrix}, we present a compliance matrix listing the mandatory behaviour required of a valid VOSpace 2.1 service.

\section{VOSpace identifiers}
\label{sec:vospace identifiers}
The identifier for a node in VOSpace SHALL be a URI with the scheme vos.

Such a URI SHALL have the following parts with the meanings and encoding rules defined in RFC3986 \citep{std:RFC3986}.

\begin{itemize}
  \item scheme
  \item naming authority
  \item path
  \item (optional) query
  \item (optional) fragment identifier (with the expected semantics noted in URI fragments in IVOA specifications \citep{note:uriforms})
\end{itemize}

The naming authority for a VOSpace node SHALL be the VOSpace service through which the node was created. The authority part of the URI SHALL be constructed from the IVO registry identifier \citep{std:VOID2} for that service by deleting the ivo:// prefix and changing all forward-slash characters(`/') in the resource key to exclamation marks (`!') or tildes (`$\mathtt{\sim}$'). Note that a service SHALL be consistent in its use of separator characters (`!' or `$\mathtt{\sim}$') when referring to its own data but SHALL accept either as valid in URIs in service requests.

This is an example of a possible VOSpace identifier.

\begin{verbatim}
vos://example.com!vospace/myresults/siap-out-1.vot
\end{verbatim}

And is equivalent to this identifier that uses the tilde character instead of an exclamation mark:

\begin{verbatim}
vos://example.com~vospace/myresults/siap-out-1.vot
\end{verbatim}

The URI scheme is \emph{vos}

Using a separate URI scheme for VOSpace identifiers enables clients to distinguish between IVO registry identifiers and VOSpace identifiers.

\emph{example.com!vospace} is the authority part of the URI, corresponding to the IVO registry identifier \emph{ivo://example.com/vospace}.  This is the IVO registry identifier of the VOSpace service that contains the node.

\emph{/myresults/siap-out-1.vot} is the URI path

Slashes in the URI path imply a hierarchical arrangement of data: the data object identified by \emph{vos://example.com!vospace/myresults/siap-out-1.vot} is within the container identified by \emph{vos://example.com!vospace/myresults}.

Literal space characters are also not allowed in URIs.

All ancestors in the hierarchy SHALL be resolvable as containers (ContainerNodes), all the way up to the root node of the space (this precludes any system of implied hierarchy in the naming scheme for nodes with ancestors that are just logical entities and cannot be reified, e.g., the Amazon S3 system).

A VOSpace identifier is globally unique, and identifies one specific node in a specific VOSpace service.

A VOSpace 2.1 service in the VO Registry is identified by its standardID.  The standardID for this specification SHALL be:
\begin{verbatim}
ivo://ivoa.net/std/VOSpace/v2.1
\end{verbatim}

\begin{admonition}{Note}
The tilde (`$\mathtt{\sim}$') character was introduced in version 2.0 as an alternative to the exclamation (`!') character because it does not have to be URL encoded in HTTP requests making it more convenient for use.
\end{admonition}

\subsection{Identifier resolution}
\label{subsec:identifier resolution}
A VOSpace identifier can be resolved to a HTTP endpoint for accessing representations of the node associated with it. A client SHOULD use the following procedure to resolve access to a VOSpace node from a VOSpace identifier:

\begin{itemize}
    \item Resolve the HTTP endpoint of a VOSpace service with using the registry.  
    \item Append ``nodes/'' and the path following the naming authority part of the VOSpace identifier to the service endpoint
\end{itemize}

\noindent
Given the example identifier

\begin{verbatim}
    vos://example.com!vospace/container-6/siap-out-1.vot?foo=bar
\end{verbatim}

\noindent
Processing the URI to resolve the VOSpace service would involve:
\\* \\*
1.  Extract the IVO registry identifier of the VOSpace service by prepending an ivo scheme to the naming authority part:
\begin{verbatim}
ivo://example.com/vospace
\end{verbatim}
2.  Resolve the IVO identifier in a registry and retrieve the access URL of the service endpoint:
\begin{verbatim}
http://server.example.com/vospace
\end{verbatim}
3.  Append ``nodes/'' and the path part of the VOSpace identifier:
\begin{verbatim}
http://server.example.com/vospace/nodes/container-6/siap-out-1.vot?foo=bar
\end{verbatim}

Note that any fragment identifier in the identifier SHOULD be removed when resolving the identifier to a HTTP endpoint, consistent with the implied semantics of URI fragments \citep{note:uriforms}.

\section{VOSpace data model}
\label{sec:vospace data model}

\subsection{Nodes and node types}
\label{subsec:nodes and node types}

We refer to the arrangement of data accessible through one particular VOSpace service as ``a VOSpace''.

Each data object within a VOSpace SHALL be represented as a node that is identified by a URI.

There are different types of nodes and the type of a VOSpace node determines how the VOSpace service stores and interprets the node data.

In an XML representation of a Node, the type is specified by the \emph{xsi:type} attribute on the node.  For example, \emph{xsi:type="vos:ContainerNode"}.

The types are arranged in a hierarchy (see Figure ~\ref{fig:nodehierarchy}), with more detailed types inheriting the structure of more generic types.

\begin{figure}
\centering
\includegraphics[width=0.9\textwidth]{vospace-node-hierarchy.png}
\caption{Node hierarchy -- This shows the inheritance structure for the different types of nodes in VOSpace.}
\label{fig:nodehierarchy}
\end{figure}

The following types (and representations) are defined:

\begin{itemize}
    \item Node is the most basic type
    \item ContainerNode describes a data item that can contain other data items
    \item DataNode describes a data item stored in the VOSpace
    \item UnstructuredDataNode describes a data item for which the VOSpace does not understand the data format
    \item StructuredDataNode describes a data item for which the space understands the format and may make transformations that preserve the meaning of the data.
    \item LinkNode describes a node that points to another node.
\end{itemize}

When data is stored and retrieved from an \emph{UnstructuredDataNode}, the bit pattern read back SHALL be identical to that written.

When data is stored and retrieved from a \emph{StructuredDataNode}, the bit pattern returned MAY be different to the original. For example, storing tabular data from a VOTable file will preserve the tabular data, but any comments in the original XML file may be lost.

A Node representation SHALL have the following elements:

\begin{itemize}
    \item \emph{uri}: the vos:// identifier for the node, URI-encoded according to RFC3986 \citep{std:RFC3986}.
    \item \emph{properties}: a set of metadata properties for the node
    \item \emph{capabilities}: a third-party interface to a data object
\end{itemize}

In addition, a \emph{DataNode} representation SHALL have the following elements:

\begin{itemize}
    \item \emph{accepts}: a list of the views (data formats) that the node can accept
    \item \emph{provides}: a list of the views (data formats) that the node can provide
\end{itemize}

A \emph{DataNode} representation MAY have the following element:

\begin{itemize}
    \item \emph{busy}: a boolean flag to indicate that the data associated with the node cannot be accessed.
\end{itemize}

The \emph{busy} flag is used to indicate that an internal operation is in progress, and the node data is not available.

A \emph{ContainerNode} representation SHALL have the following elements, in addition to those it inherits from the \emph{Node} representation:

\begin{itemize}
    \item \emph{nodes}: a list of the direct children, if applicable, that the container has. Each child is represented as a node subelement containing its vos:// identifier, URI-encoded according to RFC3986 \citep{std:RFC3986}
\end{itemize}

A \emph{LinkNode} representation SHALL have the following elements, in addition to those it inherits from the Node representation:

\begin{itemize}
    \item \emph{target}: the target URI, URI-encoded according to RFC3986 \citep{std:RFC3986}
\end{itemize}

The link target can be a URI that points to any type of resource, including other VOSpace Nodes (within the same VOSpace service or in another service), or external resources outside VOSpace altogether.

The properties of a \emph{LinkNode} do not propagate to the target of the \emph{LinkNode}, i.e., a property attached to a LinkNode does not also get attached to the target node. One use case is to enable third-party annotations to be associated with a resource but without the resource itself getting cluttered with unnecessary metadata. In this case, the client creates a \emph{LinkNode} pointing to the resource in question and then adds the annotations as properties of the \emph{LinkNode}.

Both the \emph{ContainerNode} and the \emph{LinkNode} SHALL have no data bytes associated with them.

The set of node types defined by this standard is closed; new types may be introduced only via new versions of the standard.

To comply with the standard, a client or service SHALL be able to parse XML representations of all the node types defined in the current specification.

Note: This does not require all services to support all of the Node types, just that it can process an XML request containing any of the types. If the service receives a request for a type that it does not support, the service SHOULD return a \emph{TypeNotSupported} fault. The service SHALL NOT throw an XML parser error if it receives a request for a type that it does not support.

The following Nodes, appearing as part of a node-path, are reserved:

\begin{itemize}
    \item .auto indicates that the service should auto-generate an endpoint URI to replace this placeholder (Note: that this is an OPTIONAL feature of a service)
    \item .null indicates an endpoint that discards all data written to it and provides no data when read from, i.e., a bit bucket
\end{itemize}

\subsection{Properties}
\label{subsec:properties}
\emph{Properties} are simple string-based metadata properties associated with a node.

Individual \emph{Properties} should contain simple short string values, not large blocks of information. If a system needs to attach a large amount of metadata to a node, then it should either use multiple small \emph{Properties}, or a single \emph{Property} containing a URI to an internal or external resource that contains the additional metadata.

A \emph{Property} representation SHALL have the following elements:

\begin{itemize}
    \item \emph{uri}: the Property identifier
    \item \emph{value}: the string value of the Property
    \item \emph{readOnly}: a boolean flag to indicate that the Property cannot be changed by the client
\end{itemize}

Properties may be set by the client or the service.

\subsubsection{Property values}
\label{subsubsec:property values}
Unless they have special meaning to the service or client, Properties are treated as simple string values.

When a \emph{Property} can take multiple values, e.g., a list of groups which can access a particular resource, these SHOULD be comma-separated, unless the property description defines a specific delimiter.

Some \emph{Properties} may have meaning to the service; others may have meaning only to one specific type of client. A service implementation does not need to understand the meaning of all the \emph{Properties} of a node. Any Properties that it does not understand can simply be stored as text strings.

\subsubsection{Property identifiers}
\label{subsubsec:property identifiers}
Every new type of \emph{Property} SHALL require a unique URI to identify the \emph{Property} and its meaning.

The rules for the \emph{Property} identifiers are similar to the rules for namespace URIs in XML schema. The only restriction is that it SHALL be a valid (unique) URI.

\begin{itemize}
    \item An XML schema namespace identifier can be just a simple URN \citep{std:RFC2141}, e.g., urn:my-namespace
    \item Within the IVOA, the convention for namespace identifiers is to use a HTTP URL pointing to the namespace schema or a resource describing it
\end{itemize}

The current VOSpace schema defines \emph{Property} identifiers as anyURI. The only restriction is that it SHALL be a valid (unique) URI.

\begin{itemize}
    \item A \emph{Property} URI can be a simple URN, e.g., urn:my-property
\end{itemize}

This may be sufficient for testing and development on a private system, but it is not scalable for use on a public service.

For a production system, any new Properties SHOULD have unique URIs that can be resolved into to a description of the Property.

Ideally, these should be IVO registry URIs that point to a description registered in the IVO registry:

\begin{itemize}
    \item ivo://my-registry/vospace/properties\#my-property
\end{itemize}

Using an IVO registry URI to identify Properties has two main advantages:

\begin{itemize}
    \item IVO registry URIs are by their nature unique, which makes it easy to ensure that different teams do not accidentally use the same URI
    \item If the IVO registry URI points to a description registered in the IVO registry, this provides a mechanism to discover what the Property means
\end{itemize}

\subsubsection{Property descriptions}
\label{subsubsec:property descriptions}
If the URI for a particular Property is resolvable, i.e., an IVO registry identifier or a HTTP URL, then it SHOULD point to an XML resource that describes the Property.

A Property description SHOULD describe the data type and meaning of a Property.

A PropertyDescription SHOULD have the following members:

\begin{itemize}
    \item \emph{uri}: the formal URI of the Property
    \item \emph{DisplayName}: A display name for the Property
    \item \emph{Description}: A text block describing the meaning and validation rules of the Property
\end{itemize}

A PropertyDescription MAY have the following OPTIONAL members:

\begin{itemize}
    \item \emph{UCD}: the Universal Content Descriptor (in the UCD1 + scheme) for the Property
    \item \emph{Unit}: the unit of measurement of the Property
\end{itemize}

The information in a Property description can be used to generate a UI for displaying and modifying the different types of Properties.

\paragraph{UI Display name}
If a client is unable to resolve a Property identifier into a description, then it may just display the identifier as a text string:

\begin{itemize}
    \item urn:modifieddate
\end{itemize}

If the client can resolve the Property identifier into a description, then the client may use the information in the description to display a human readable name and description of the Property:

\begin{itemize}
    \item Last modification date of the node data
\end{itemize}

\paragraph{Property editors}
If the client is unable to resolve a Property identifier into a description, or does not understand the type information defined in the description, then the client MAY treat the Property value as a simple text string.

If the client can resolve the Property identifier into a description, then the client MAY use the information in the description to display an appropriate editing tool for the Property.

In the current version of the specification the rules for editing Properties are as follows:

\begin{itemize}
    \item A service MAY impose validation rules on the values of specific types of Properties
    \item If a client attempts to set a Property to an invalid value, then the service MAY reject the change
    \item Where possible, the validation rules for a type of Property SHOULD be defined in the Property description
\end{itemize}

Future versions of the VOSpace specification may extend the PropertyDescription to include more specific machine readable validation rules for a Property type.

\subsubsection{Standard properties}
\label{subsubsec:standard properties}
Property URIs and PropertyDescriptions for the core set of Properties are registered under a StandardKeyEnumeration resource \citep{std:STDREGEXT} in the IVOA registry with the resource identifier ivo://ivoa.net/vospace/core. The following URIs SHOULD be used to represent the service properties:

\begin{itemize}
    \item ivo://ivoa.net/vospace/core\#title SHALL be used as the property URI denoting a name given to the resource
    \item ivo://ivoa.net/vospace/core\#creator SHALL be used as the property URI denoting an entity primarily responsible for making the resource
    \item ivo://ivoa.net/vospace/core\#subject SHALL be used as the property URI denoting the topic of the resource
    \item ivo://ivoa.net/vospace/core\#description SHALL be used as the property URI denoting an account of the resource
    \item ivo://ivoa.net/vospace/core\#publisher SHALL be used as the property URI denoting an entity responsible for making the resource available
    \item ivo://ivoa.net/vospace/core\#contributor SHALL be used as the property URI denoting an entity responsible for making contributions to this resource
    \item ivo://ivoa.net/vospace/core\#date SHALL be used as the property URI denoting a point or period of time associated with an event in the lifecycle of the resource
    \item ivo://ivoa.net/vospace/core\#type SHALL be used as the property URI denoting the nature or genre of the resource
    \item ivo://ivoa.net/vospace/core\#format SHALL be used as the property URI denoting the file format, physical medium, or dimensions of the resource
    \item ivo://ivoa.net/vospace/core\#identifier SHALL be used as the property URI denoting an unambiguous reference to the resource within a given context
    \item ivo://ivoa.net/vospace/core\#source SHALL be used as the property URI denoting a related resource from which the described resource is derived
    \item ivo://ivoa.net/vospace/core\#language SHALL be used as the property URI denoting a language of the resource
    \item ivo://ivoa.net/vospace/core\#relation SHALL be used as the property URI denoting a related resource
    \item ivo://ivoa.net/vospace/core\#coverage SHALL be used as the property URI denoting the spatial or temporal topic of the resource, the spatial applicability of the resource, or the jurisdiction under which the resource is relevant
    \item ivo://ivoa.net/vospace/core\#rights SHALL be used as the property URI denoting information about rights held in and over the resource
    \item ivo://ivoa.net/vospace/core\#availableSpace SHALL be used as the property URI denoting the amount of space available within a container
    \item ivo://ivoa.net/vospace/core\#groupread SHALL be used as the property URI denoting the list of groups which can only read this resource (read-only)
    \item ivo://ivoa.net/vospace/core\#groupwrite SHALL be used as the property URI denoting the list of groups which can read and write to this resource (read-write)
    \item ivo://ivoa.net/vospace/core\#publicread SHALL be used as the property URI denoting whether this resource is world readable (anon-read-only)
    \item ivo://ivoa.net/vospace/core\#quota SHALL be used as the property URI denoting the value of a system quota on the resource
    \item ivo://ivoa.net/vospace/core\#length SHALL be used as the property URI denoting the length or size of a resource
    \item ivo://ivoa.net/vospace/core\#mtime SHALL be used as the property URI denoting the data modification time
    \item ivo://ivoa.net/vospace/core\#ctime SHALL be used as the property URI denoting status change (aka metadata modification) time
    \item ivo://ivoa.net/vospace/core\#btime SHALL be used as the property URI denoting initial creation time
\end{itemize}

However, this is not intended to be a closed list, different implementations are free to define and use their own Properties.

\subsection{Capabilities}
\label{subsec:capabilities}
A Capability describes a third-party interface to a node. One application of this would be to enable data access to a node or its contents using a 3rd party service interface.

A Capability representation SHALL have the following members:

\begin{itemize}
    \item \emph{uri}: the Capability identifier
    \item \emph{endpoint}: the endpoint URL to use for the third-party interface
    \item \emph{param}: a set of parameters for the capability
\end{itemize}

\subsubsection{Example capability use cases}
\label{subsubsec:example capability use cases}
A ContainerNode containing image files may offer a DAL SIAP capability so that the images in the container can be accessed using a SIAP service. In this way, a user could create a (DAL enabled) Container in VOSpace, transfer some images into it and then query the set of images using the SIAP interface.

Another example is a DataNode that provides a OpenStack Swift capability so that the OpenStack service API is exposed on that node.

\subsubsection{Capability identifiers}
\label{subsubsec:capability identifiers}
Every new type of Capability SHALL require a unique URI to identify the Capability. The rules for the Capability identifiers are similar to the rules for namespace URIs in XML schema. The only restriction is that it SHALL be a valid (unique) URI.

\begin{itemize}
    \item An XML schema namespace identifier can be just a simple URN, e.g., urn:my-namespace
    \item Within the IVOA, the convention for namespace identifiers is to use a HTTP URL pointing to the namespace schema, or a resource describing it.
\end{itemize}

The VOSpace schema defines Capability identifiers as anyURI. The only restriction is that it SHALL be a valid (unique) URI.

\begin{itemize}
    \item A Capability URI can be a simple URN, e.g., urn:my-capability
\end{itemize}

This may be sufficient for testing and development on a private system, but it is not suitable for use on a public service. For a production system, any new Capabilities SHOULD have unique URIs that can be resolved into a description of the Capability. Ideally, these SHOULD be IVO registry URIs that point to a description registered in the IVO registry:

\begin{itemize}
    \item ivo://my-registry/vospace/capabilities\#my-capability
\end{itemize}

Using an IVO registry URI to identify Capabilities has two main advantages:

\begin{itemize}
    \item IVO registry URIs are by their nature unique, which makes it easy to ensure that different teams do not accidentally use the same URI
    \item If the IVO registry URI points to a description registered in the IVO registry, this provides a mechanism to discover how to use the Capability.
\end{itemize}

\subsubsection{Capability descriptions}
\label{subsubsec:capability descriptions}
If the URI for a particular Capability is resolvable, i.e., an IVO registry identifier or a HTTP URL then it SHOULD point to an XML resource that describes the Capability.

A CapabilityDescription SHOULD describe the third-party interface and how it should be used in this context. A CapabilityDescription SHOULD have the following members:

\begin{itemize}
    \item \emph{uri}: the formal URI of the Capability
    \item \emph{DisplayName}: a simple display name of the Capability.
    \item \emph{Description}: a text block describing the third-party interface and how it should be used in this context.
\end{itemize}

\subsubsection{UI display name}
\label{subsubsection:ui display name}
If a client is unable to resolve a Capability identifier into a description then it may just display the identifier as a text string:

\begin{itemize}
    \item Access data using urn:openstack
\end{itemize}

If a client can resolve the Capability identifier into a description then the client may use the information in the description to display a human readable name and description of the Capability:

\begin{itemize}
    \item Access data using openstack
\end{itemize}

\subsubsection{Standard capabilities}
\label{subsubsec:standard capabilities}
Capability URIs and CapabilityDescriptions for the core set of Capabilities are registered under a StandardKeyEnumeration resource \citep{std:STDREGEXT} in the IVOA registry with the resource identifier ivo://ivoa.net/vospace/core.. The following URIs SHALL be used to represent the service capabilities:

\begin{itemize}
    \item ivo://ivoa.net/vospace/core\#vospace-1.0 SHALL be used as the capability URI for a VOSpace 1.0 service
    \item ivo://ivoa.net/vospace/core\#vospace-1.1 SHALL be used as the capability URI for a VOSpace 1.1 service
    \item ivo://ivoa.net/vospace/core\#vospace-2.0 SHALL be used as the capability URI for a VOSpace 2.0 service
    \item ivo://ivoa.net/vospace/core\#vospace-2.1 SHALL be used as the capability URI for a VOSpace 2.1 service
\end{itemize}
If a service implementation supports more than one version of the VOSpace interface then these capability URIs can be used with a VOSpace service to identify different VOSpace capabilities for a node.

\subsection{Views}
\label{subsec:views}
A View describes the data formats and contents available for importing or exporting data to or from a VOSpace node.

The metadata for a DataNode contains two lists of Views.

\begin{itemize}
    \item \emph{accepts}: is a list of Views that the service can accept for importing data into the Node
    \item \emph{provides}: is a list of Views that the service can provide for exporting data from Node
\end{itemize}

A View representation SHALL have the following members:

\begin{itemize}
    \item \emph{uri}: The view identifier
    \item \emph{original}: an optional boolean flag to indicate that the View preserves the original bit pattern of the data
    \item \emph{param}: a set of name-value pairs that can be used to specify additional arguments for the View
\end{itemize}

\subsubsection{Example view use cases}
\label{subsubsec:example view use cases}
A simple VOSpace system that stores data as binary files can just return the contents of the original file. The client supplies a View identifier when it imports the data, and the service uses this information to describe the data to other clients.

A file based system can use the special case identifier
\begin{verbatim}
        ivo://ivoa.net/vospace/core#anyview
\end{verbatim}
to indicate that it will accept any data format or View for a Node.

For example:

\begin{itemize}
    \item A client imports a file into the service, specifying a View to describe the file contents
    \item The service stores the data as a binary file and keeps a record of the View
    \item The service can then use the View supplied by the client to describe the data to other clients
\end{itemize}

This type of service is not required to understand the imported data, or to verify that it contents match the View, it treats all data as binary files.

\paragraph{Database store}
A VOSpace system that stores data in database tables would need to be able to understand the data format of an imported file in order to parse the data and store it correctly. This means that the service can only accept a specific set of Views, or data formats, for importing data into the Node.

In order to tell the client what input data formats it can accept, the service publishes a list of specific Views in the accepts list for each Node.

On the output side, a database system would not be able to provide access to the original input file. The contents of the file would have been transferred into the database table and then discarded. The system has to generate the output results from the contents of the database table.

In order to support this, the service needs to be able to tell the client what Views of the data are available.

A database system may offer access to the table contents as either VOTable or FITS files, it may also offer zip or tar.gz compressed versions of these. In which case the system needs to be able to express nested file formats such as ``zip containing VOTable'' and ``tar.gz containing FITS''.

A service may also offer subsets of the data. For example, a work flow system may only want to look at the table headers to decide what steps are required to process the data. If the table contains a large quantity of data, then downloading the whole contents just to look at the header information is inefficient. To make this easier, a database system may offer a 'metadata only' View of the table, returning a VOTable or FITS file containing just the metadata headers and no rows.

So our example service may want to offer the following Views of a database table:

\begin{itemize}
    \item Table contents as FITS
    \item Table contents as VOTable
    \item Table contents as zip containing FITS
    \item Table contents as zip containing VOTable
    \item Table contents as tar.gz containing FITS
    \item Table contents as tar.gz containing VOTable
    \item Table metadata as FITS
    \item Table metadata as VOTable
\end{itemize}

The service would publish this information as a list of Views in the provides section of the metadata for each Node.

The VOSpace specification does not mandate what Views a service must provide. The VOSpace specification is intended to provide a flexible mechanism enabling services to describe a variety of different Views of data. It is up to the service implementation to decide what Views of the data it can accept and provide.

\subsubsection{View identifiers}
\label{subsubsec:view identifiers}
Every new type of View SHALL require a unique URI to identify the View and its content.

The rules for the View identifiers are similar to the rules for namespace URIs in XML schema. The only restriction is that it SHALL be a valid (unique) URI.

\begin{itemize}
    \item An XML schema namespace identifier can be just a simple URN, e.g., urn:my-namespace
    \item Within the IVOA, the convention for namespace identifiers is to use a HTTP URL pointing to the namespace schema, or a resource describing it
\end{itemize}

The current VOSpace schema defines View identifiers as anyURI. The only restriction is that it SHALL be a valid (unique) URI.

\begin{itemize}
    \item A View URI can be a simple URN, e.g., urn:my-view
\end{itemize}

This may be sufficient for testing and development on a private system, but it is not scalable for use on a public service.

For a production system, any new Views SHOULD have unique URIs that can be resolved into to a description of the View.

Ideally, these should be IVO registry URIs that point to a description registered in the IVO registry:

\begin{itemize}
    \item ivo://my-registry/vospace/views\#my-view
\end{itemize}

Using an IVO registry URI to identify Views has two main advantages:

\begin{itemize}
    \item IVO registry URIs are by their nature unique, which makes it easy to ensure that different teams do not accidentally use the same URI
    \item If the IVO registry URI points to a description registered in the IVO registry, this provides a mechanism to discover what the View contains
\end{itemize}

\subsubsection{View descriptions}
\label{subsubsec:view descriptions}
If the URI for a particular View is resolvable, i.e., an IVO registry identifier or a HTTP URL, then it SHOULD point to an XML resource that describes the View.

A ViewDescription SHOULD describe the data format and/or content of the view.

A ViewDescription SHOULD have the following members:

\begin{itemize}
    \item \emph{uri}: the formal URI of the View
    \item \emph{DisplayName}: a simple display name of the View.
    \item \emph{Description}: a text block describing the data format and content of the View.
\end{itemize}

A ViewDescription MAY have the following optional members:

\begin{itemize}
    \item \emph{MimeType}: the standard MIME type of the View, if applicable
    \item \emph{Parameters}: a list of required and option parameters the view accepts, if applicable
\end{itemize}

\paragraph{UI Display name}
If a client is unable to resolve a View identifier into a description, then it MAY just display the identifier as a text string:

\begin{itemize}
    \item Download as urn:table.meta.fits
\end{itemize}

If the client can resolve the View identifier into a description, then the client MAY use the information in the description to display a human readable name and description of the View:

\begin{itemize}
    \item Download table metadata as FITS header
\end{itemize}

\paragraph{Mime Types}
If a VOSpace service provides HTTP access to the data contained in a Node, then if the ViewDescription contains a MimeType field, this SHOULD be included in the appropriate header field of the HTTP response.

\subsubsection{Default views}
\label{subsubsec:default views}
The following standard URIs are registered under a StandardKeyEnumeration resource \citep{std:STDREGEXT} in the IVOA registry with the resource identifier ivo://ivoa.net/vospace/core. They SHALL be used to refer to the default import and export views:

\begin{itemize}
    \item ivo://ivoa.net/vospace/core\#anyview SHALL be used as the view URI to indicate that a service will accept any view for an import operation
    \item ivo://ivoa.net/vospace/core\#binaryview SHALL be used as the view URI to import or export data as a binary file
    \item ivo://ivoa.net/vospace/core\#defaultview SHALL be used by a client to indicate that the service should choose the most appropriate view for a data export
\end{itemize}

\paragraph{Default import view}
If a client imports data using this view, the data SHALL be treated as a binary BLOB, and stored as is with no additional processing. This is equivalent to the application/octet-stream MIME type.

Note, this view is OPTIONAL, and the service may throw a ViewNotSupported exception if it does not accept this view. In particular, this view cannot be used to import data into a StructuredDataNode as the service needs to know about and understand the data format to be able to create the StructuredDataNode.

Note, this view is only valid for the data import operations, pullToVoSpace and pushToVoSpace. If this view is requested in an export operation, pullFromVoSpace and pushToVoSpace, then the service SHOULD throw a ViewNotSupported exception.

\paragraph{Default export view}
If a client requests data using this view, the server SHALL choose whichever of the available views the server thinks is the most appropriate, based on how the data is stored. In a simple file-based system, this will probably be the same format that the data was originally imported in. In a database table system, this will probably either be VOTable or CVS, depending on the level of metadata available.

Note, this view is OPTIONAL, and the server may throw a ViewNotSupported exception if it does not provide this view. However, in most cases, it is expected that a service would be able to select an appropriate 'default' format for data held within the service.

Note, this view is only valid for the data export operations, pullFromVoSpace and pushFromVoSpace. If this view is requested in an import operation, pullToVoSpace and pushFromVoSpace, then the service SHOULD throw a ViewNotSupported fault.

\subsubsection{Container views}
\label{subsubsec:container views}
In VOSpace 2.1, a view of a ContainerNode describes the data representation (format) of a file or data stream that represents the combined contents of the node and its children. If the view describes an archive format (tar, zip, etc.) then a service that accepts this view (format) for a ContainerNode SHALL provide access to the archive contents as children nodes of the container. Whether or not the service actually unpacks the archive is implementation dependent but the service SHALL behave as though it has done so. For example, a client may want to upload a tar file containing several images to a VOSpace service. If they associate it with (upload it to) a (Un)structuredDataNode then it will be treated as a blob and its contents will be not be available. However, if they upload it to a ContainerNode with an accepts view of \verb|"tar"| then the image files within the tar file will be represented as children nodes of the ContainerNode and accessible like any other data object within the space.

If a service provides an archive format (tar, zip, etc.) view of a ContainerNode then the service SHALL package the contents of the container and all its child nodes in the specified format.

\subsection{Protocols}
\label{subsec:protocols}
A Protocol describes the parameters required to perform a data transfer using a particular protocol.

A Protocol representation SHALL have the following members:

\begin{itemize}
    \item \emph{uri}: the Protocol identifier
    \item \emph{endpoint}: the endpoint URL to use for the data transfer additional arguments required for the transfer
\end{itemize}

A protocol representation MAY have the following members:

\begin{itemize}
    \item \emph{param}: A list of name-value pairs that specify any additional arguments required to support the protocol
    \item \emph{securityMethod}: The requested (and/or resulting) authentication type
\end{itemize}

Note: endpoint will only contain a value after the response from the service is received.

\subsubsection{Protocol identifiers}
\label{subsubsec:protocol identifiers}
Every new type of Protocol requires a unique URI to identify the Protocol and how to use it.

The rules for the Protocol identifiers are similar to the rules for namespace URIs in XML schema. The only restriction is that it SHALL be a valid (unique) URI

\begin{itemize}
    \item An XML schema namespace identifier can be just a simple URN, e.g., urn:my-namespace
    \item Within the IVOA, the convention for namespace identifiers is to use a HTTP URL pointing to the namespace schema, or a resource describing it
\end{itemize}

The current VOSpace schema defines Protocol identifiers as anyURI. The only restriction is that it SHALL be a valid (unique) URI.

\begin{itemize}
    \item A Protocol URI can be a simple URN, e.g., urn:my-protocol
\end{itemize}

This may be sufficient for testing and development on a private system, but it is not scalable for use on a public service.

For a production system, any new Protocols SHOULD have unique URIs that can be resolved into to a description of the Protocol.

Ideally, these should be IVO registry URIs that point to a description registered in the IVO registry:

\begin{itemize}
    \item \begin{verbatim}ivo://my-registry/vospace/protocols#my-protocol\end{verbatim}
\end{itemize}

Using an IVO registry URI to identify Protocols has two main advantages:

\begin{itemize}
    \item IVO registry URIs are by their nature unique, which makes it easy to ensure that different teams do not accidentally use the same URI
    \item If the IVO registry URI points to a description registered in the IVO registry, this provides a mechanism to discover how to use the Protocol
\end{itemize}

\subsubsection{Protocol descriptions}
\label{subsubsec:protocol descriptions}
If the URI for a particular Protocol is resolvable, i.e., an IVO registry identifier or a HTTP URL, then it SHOULD point to an XML resource that describes the Protocol.

A ProtocolDescription SHOULD describe the underlying transport protocol, and how it should be used in this context.

A ProtocolDescription SHOULD have the following members:

\begin{itemize}
    \item \emph{uri}: the formal URI of the Protocol
    \item \emph{DisplayName}: A simple display name of the Protocol
    \item \emph{Description}: Text block describing describing the underlying transport protocol, and how it should be used in this context
\end{itemize}

\paragraph{UI display name}

If a client is unable to resolve a Protocol identifier into a description, then it MAY just display the identifier as a text string:

\begin{itemize}
    \item Download using urn:my-protocol
\end{itemize}

If the client can resolve the Protocol identifier into a description, then the client MAY use the information in the description to display a human readable name and description of the Protocol:

\begin{itemize}
    \item Download using standard HTTP GET
\end{itemize}

\subsubsection{Standard protocols}
\label{subsubsec:standard protocols}
Protocol URIs and ProtocolDescriptions for the core set of standard protocols are registered under a StandardKeyEnumeration resource \citep{std:STDREGEXT} in the IVOA registry with the resource identifier ivo://ivoa.net/vospace/core. The following URIs SHALL be used to represent the standard transfer protocols:

\begin{itemize}
    \item \begin{verbatim}ivo://ivoa.net/vospace/core#httpget\end{verbatim} SHALL be used as the protocol URI for a HTTP GET transfer
    \item \begin{verbatim}ivo://ivoa.net/vospace/core#httpput\end{verbatim} SHALL be used as the protocol URI for a HTTP PUT transfer
    \item \begin{verbatim}ivo://ivoa.net/vospace/core#httpsget\end{verbatim} SHALL be used as the protocol URI for a HTTP GET transfer over a Secure Socket Layer (SSL)
    \item \begin{verbatim}ivo://ivoa.net/vospace/core#httpsput\end{verbatim} SHALL be used as the protocol URI for a HTTP PUT transfer over a Secure Socket Layer (SSL)
\end{itemize}

However, this is not intended to be a closed list, different implementations are free to define and use their own transfer Protocols and authentication types.

\subsubsection{External standard protocols}
\label{subsubsec:external standard protocols}

The following section lists protocols that are identified by an external URI and are documented at the location referenced by that URI.  If a service provides protocols with the following URIs, one should regard the information at the referenced location as if they were a part of this specification.  Incompatible changes to protocols listed here are forbidden by this specification.

Currently, there is only external standard protocol: the \emph{public share protocol}.

The \emph{public share protocol} provides a means of obtaining, through a transfer negotiation, a URL endpoint from a VOSpace service that can be shared with colleagues or published in a paper.  Implementation of this protocol is optional so services MAY provide support for the \emph{public share protocol} if they wish to generate URLs to data objects that can be shared with anonymous users.

The standard ID for the \emph{public share protocol} is:
\begin{verbatim}http://wiki.ivoa.net/twiki/bin/view/IVOA/VOSpacePublicShare\end{verbatim}

Note that, as mentioned above, the standard ID serves as both a URL to a document describing the protocol and as the URI identifying the protocol.  Thus, readers can find additional documentation on the public share protocol at the URL of the standard ID.

The curl command below gives an example of how to obtain a public share URL from VOSpace:

\begin{verbatim}
    curl "https://server.example.com/vospace/synctrans
        ?TARGET=vos://example.com~vospace/mydata1
        &DIRECTION=pullFromVoSpace
        &PROTOCOL=http://wiki.ivoa.net/twiki/bin/view/IVOA/VOSpacePublicShare
\end{verbatim}

If the VOSpace service supports the public share protocol, the resulting transfer document SHALL include an endpoint URLs for distribution and sharing.  For example:

\begin{verbatim}<vos:endpoint>http://public.example.com/001237995/mydata1</vos:endpoint>\end{verbatim}

The endpoint MUST be anonymously accessible, so the endpoint SHALL NOT contain a securityMethod for authentication.

If the VOSpace service does not support the public share protocol, the transfer Job phase SHALL be set to ERROR and the ErrorSummary SHALL be set to "ProtocolNotSupported".

Use of the public share protocol in transfer negotiations is only valid when the DIRECTION of the transfer request is pullFromVoSpace.	  If a DIRECTION other than pullFromVoSpace is used then the service SHALL set the Job phase to ERROR and set the ErrorSummary to "ProtocolNotSupported".

\subsubsection{Security Methods}
Each protocol may have an associated securityMethod element that describes the supported authentication method for that protocol.

For transfer requests, the securityMethod indicates that the client is capable of that authentication method for that protocol.  The protocols should be listed in preferred order.  It is recommended that the entire list of protocol securityMethod combinations that the client supports be provided.

The Protocol list in transfer responses represent the protocol and securityMethod combinations that are supported by the server.  The server must only list supported combinations.  The server may choose to consult the protocol and securityMethod combinations in the transfer request to generate the ordered list of protocols.

Please refer to the IVOA Single-Sign-On Profile: Authentication Mechanisms for more information: \citep{std:SSOAUTH2}

\subsection{Transfers}
\label{subsec:transfers}
A Transfer describes the details of a data transfer to or from a VOSpace.

\subsubsection{XML Document Transfers}
\label{subsubsec:xml document transfers}

Transfers can be represented as XML documents.  For example:

\begin{lstlisting}
<vos:transfer xmlns:vos="http://www.ivoa.net/xml/VOSpace/v2.0" version="2.1">
  <vos:target>vos://example.com!vospace/myspace/myfile</vos:target>
  <vos:direction>pushToVoSpace</vos:direction>
  <vos:protocol uri="ivo://ivoa.net/vospace/core#httpsput">
    <vos:securityMethod uri="ivo://ivoa.net/sso#tls-with-certificate"/>
  </vos:protocol>
  <vos:protocol uri="ivo://ivoa.net/vospace/core#httpput">
    <vos:securityMethod "uri="http://www.w3.org/Protocols/HTTP/1.0/spec/html#BasicAA"/>
  </vos:protocol>
</vos:transfer>
\end{lstlisting}

Clients send transfer XML documents to a VOSpace synchronous or asynchronous UWS transfer endpoint.  The VOSpace service SHALL put, in the UWS Job results, a resulting transfer XML document.

A client initiated UWS Job representation of a Transfer SHALL have the following parameters:

\begin{itemize}
    \item \emph{target}: denotes the VOSpace node to/from which data is to be transferred
    \item \emph{direction}: denotes the direction of a data transfer
        \begin{itemize}
            \item It can be a URI for internal data transfers (move and copy operations) or one of: pushToVoSpace, pullToVoSpace, pushFromVoSpace or pullFromVoSpace -- for external data transfer.
        \end{itemize}
    \item \emph{view}: denotes the requested View
        \begin{itemize}
            \item For the transfer to be valid, the specified View must match one of those listed in the accepts or provides list of the Node.
            \item For an internal data transfer, this parameter is not required.
        \end{itemize}
    \item \emph{protocol}: denotes the transfer protocol(s) to use
        \begin{itemize}
            \item A transfer may contain more than one protocol with different Protocol URIs.
            \item Each protocol may contain one or more security methods that can be applied to the protocol.  It is recommended that a protocol for each securityMethod be included in the transfer.
            \item For an internal data transfer, this parameter is not required.
        \end{itemize}
    \item \emph{keepBytes}: denotes whether the source object is to be kept in an internal data transfer, i.e., distinguishes between a move and a copy
        \begin{itemize}
            \item For an external data transfer, this parameter is not required.
        \end{itemize}
    \item \emph{param}: A list of zero or more parameters that specify any additional arguments for the transfer.
        \begin{itemize}
            \item Standard Property URIs should be used as the parameter key.
            \item e.g., Clients may tell the service the size of a file they intend to upload: 
            \begin{lstlisting}
            <vos:param uri="ivo://ivoa.net/vospace/core\#length">1024</vos:param>
            \end{lstlisting}
        \end{itemize}
\end{itemize}

This representation will be used as a child of the jobInfo element in a UWS Job representation.

The service representation of the results of a Transfer SHALL have the following members:

\begin{itemize}
    \item \emph{target}: denotes the VOSpace node to/from which data is to be transferred
    \item \emph{direction}: denotes the direction of a data transfer
        \begin{itemize}
            \item It can be a URI for internal data transfers (move and copy operations) or one of: pushToVoSpace, pullToVoSpace, pushFromVoSpace or pullFromVoSpace -- for an external data transfer.
        \end{itemize}
    \item \emph{view}: A View specifying the requested View
        \begin{itemize}
            \item For the transfer to be valid, the specified View must match one of those listed in the accepts or provides list of the Node.
            \item For an internal data transfer, this parameter is not required.
        \end{itemize}
    \item \emph{protocol}: denotes the transfer protocol(s) to use
        \begin{itemize}
            \item A transfer may contain more than one protocol with different Protocol URIs.
            \item A Transfer may contain more than one Protocol element with the same Protocol URI with different endpoints
            \item Each protocol on the result must contain an endpoint.
            \item Each protocol may contain one or more security methods that can be applied to the protocol.
            \item For an internal data transfer, this parameter is not required.
        \end{itemize}
    \item \emph{param}: parameters related to the transfer
        \begin{itemize}
            \item A transfer may contain zero or more transfer parameters.
        \end{itemize}
\end{itemize}

\subsubsection{URL Parameter Transfers}
\label{subsubsec:url parameter transfers}
A simplified and restricted method of transfer negotiation makes use of URL query string parameters rather than XML documents.  Parameter based transfer negotiation support is optional and is limited to the synchronous transfer endpoint.  The following is an example URL for a parameter transfer negotiation:

\begin{verbatim}
http://server.example.com/vospace/synctrans?
    TARGET=vos://example.com~vospace/mydata1&
    DIRECTION=pullFromVoSpace&
    PROTOCOL=ivo://ivoa.net/vospace/core#httpget
\end{verbatim}

The following parameters MUST be supplied by the client requesting a transfer:

\begin{itemize}
    \item \emph{TARGET}: denotes the VOSpace node to/from which data is to be transferred
    \item \emph{DIRECTION}: denotes the direction of a data transfer
        \begin{itemize}
            \item With parameter based negotiation, only pushToVoSpace and pullFromVoSpace are allowed as values for DIRECTION.
        \end{itemize}
    \item \emph{PROTOCOL}: denotes the transfer protocol(s) to use. 
        \begin{itemize}
            \item With parameter based negotiation, clients MUST provide exactly one PROTOCOL parameter.
        \end{itemize}
\end{itemize}

The following parameters MAY be supplied by the client requesting a transfer:

\begin{itemize}
    \item \emph{VIEW}: The standard URI of the view to use.  If no view is provided the service SHALL use the default view.
    \item \emph{SECURITYMETHOD}: The standard URI of the security method that can be used for the supplied PROTOCOL.
    \item \emph{REQUEST=redirect}: If supplied, the service SHALL respond with an HTTP redirect to an endpoint for the PROTOCOL.
    \begin{itemize}
        \item This parameter is only applicable when the value of the DIRECTION parameter is \emph{pullFromVoSpace}.
    \end{itemize}
\end{itemize}

Parameter values must be URL-encoded.

Upon receipt of a parameter based transfer negotiation request to the synchronous transfer endpoint, the service SHALL reply with a XML representation of the transfer results in the response body.  The only exception to this is when the DIRECTION is \emph{pullFromVoSpace} and the REQUEST=redirect parameter is provided and set to \emph{true}, in which case the service SHALL respond with an HTTP redirect to the endpoint of the supplied PROTOCOL.

\subsubsection{Service-initiated transfers}
\label{subsubsec:service-initiated transfers}
Two of the external data transfers (pullToVoSpace and pushFromVoSpace) rely on the server performing the data transfer itself.

The client constructs a Job request containing details of the View and one or more Protocol elements with valid endpoint addresses.

The service MAY ignore Protocols with URIs that it does not recognize.

If the server is unable to handle any of the requested Protocols in a Transfer request, then it SHALL respond with a fault.

The order of the Protocols in the request indicates the order of preference that the client would like the server to use. However, this is only a suggestion, and the server is free to use its own preferences to select which Protocol it uses first.

The service selects the first Protocol it wants to use from the list and attempts to transfer the data using the Protocol endpoint.

If the first attempt fails, the server may choose another Protocol from the list and re-try the transfer using that Protocol endpoint. The status flag will be updated to reflect this.

The server may attempt to transfer the data using any or all of the Protocols in the list until either, the data transfer succeeds, or there are no more Protocol options left.

The server SHALL be allowed to only use each Protocol option once. This allows a data source to issue one time URLs for a Transfer, and cancel each URL once it has been used.

Once one of the Protocol options succeeds the transfer SHALL be considered to have completed -- the status flag needs to be updated to reflect this -, and the server is not allowed to use any of the remaining Protocol options. This allows a data source to issue a set of one time URLs for a transfer, and to cancel any unused URLs once the transfer has been completed.

Some Protocols MAY require the service to call a callback address when a data transfer completes. This behavior is specific to the Protocol, and SHOULD be defined in the ProtocolDescription.

If none of the Protocol options succeed, then the transfer SHALL be considered to have failed, and the service SHALL return a fault containing details of the Protocol options it tried. The status flag will be updated to reflect this.

\subsubsection{Client-initiated transfers}
\label{subsubsec:client-initiated transfers}
Two of the VOSpace external transfer methods (pushToVoSpace and pullFromVoSpace) rely on an external actor performing the data transfer outside the scope of the service call.

In these methods, the client sends a Job request to the server which SHOULD contain details of the View and one or more protocol parameters.

In effect, the client is sending a list of Protocols that it (the client) wants to use for the transfer.

The service MAY ignore Protocols with URIs that it does not recognize.

The service selects the Protocols from the request that it is capable of handling, and builds a Transfer results response containing the selected Protocol elements filling in valid endpoint addresses for each of them.

If available, the service may choose to consult the securityMethod in the Protocols to construct correct endpoints.

The order of the Protocol elements (and their corresponding security methods) in the request indicates the order of preference that the client would like to use. However, this is only a suggestion, and the server is free to use its own preferences when generating the list of Protocols in the response.

In effect, the server is responding with the subset of the requested Protocols that it (the server) is prepared to offer.

If the server is unable to accept any of the requested Protocols, then it SHALL respond with a fault.

On receipt of the response, the client can use the list of Protocols itself, or pass them on to another agent to perform the data transfer on its behalf.

The agent MAY ignore Protocols URIs that it does not recognize.

The agent selects the first Protocol it wants to use from the list and attempts to transfer the data using the Protocol endpoint. The status flag will be updated to reflect this.

If the first attempt fails, the agent MAY choose another Protocol from the list and re-try the transfer using that Protocol endpoint.

The agent MAY attempt to transfer the data using any or all of the Protocols in the list until either, the data transfer succeeds, or there are no more Protocol options left.

The agent SHALL be allowed to only use each Protocol option once. This allows a data source to issue one time URLs for a Transfer, and cancel each URL once it has been used.

Once one of the Protocol options succeeds the transfer SHALL be considered to have completed and the status flag will be updated correspondingly. The agent is not allowed to use any of the remaining unused Protocol options. This allows a data source to issue a set of one time URLs for a transfer, and to cancel any unused URLs once the transfer has been completed.

Some Protocols MAY require the agent to call a callback address when a data transfer completes. This behavior is specific to the Protocol, and SHOULD be defined in the ProtocolDescription.

If none of the Protocol options succeed, then the transfer SHALL be considered to have failed and the status will be updated.

% Searches have been removed in version 2.1 due to no implementations
% \subsection{Searches}
% \label{subsec:searches}
% A Search describes the details of data objects in the space which meet specified search criteria, i.e. that are the results of a submitted search request.
% 
% A UWS Job representation of a Search SHALL have the following parameters:
% 
% \begin{itemize}
%     \item \emph{uri}: An OPTIONAL identifier indicating from which item to continue a search
%     \item \emph{limit}: An OPTIONAL limit indicating the maximum number of results in the response
%         \begin{itemize}
%             \item No limit indicates a request for an unpaged list. However the server MAY still impose its own limit on the size of an individual response, splitting the results into more than one page if required
%         \end{itemize}
%     \item \emph{detail}: The level of detail in the results
%         \begin{itemize}
%             \item min: The list contains the minimum detail for each Node with all optional parts removed - the node type should be returned
%                 \begin{itemize}
%                     \item e.g. \emph{<node uri="vos://service/name" xsi:type="Node"/>}
%                 \end{itemize}
%             \item max : The list contains the maximum detail for each Node, including any xsi:type specific extensions
%             \item properties : The list contains a basic node element with a list of properties for each Node with no xsi:type specific extensions.
%         \end{itemize}
%     \item \emph{matches}: An OPTIONAL search string consisting of properties and values to match against and joined in conjunction (and) or disjunction (or).
%         \begin{itemize}
%             \item Each property-value pair consists of the uri identifying a particular property and a regular expression against which the property values are to be matched: `uri' = `regex'
%             \item The match pairs can be combined in conjunction and/or disjunction using 'and' and 'or' respectively. For example: (property1 = `value1' and property2 = `value2') or property3 = `value3'.
%             \item The regex syntax SHALL comply with POSIX conventions.
%         \end{itemize}
%     \item \emph{node}: An OPTIONAL URI(s) identifying the starting node for a search, i.e., the matches constraints are applied to this node and its children
% \end{itemize}
% 
% This representation will be used as a child of the jobInfo element in a UWS Job representation. For example:
% 
% \begin{verbatim}
% <uws:jobInfo>
%   <vos:search>
%     <vos:detail>properties</vos:detail>
%     <vos:matches>
%         ivo://ivoa.net/vospace/core#description="galax"
%     </vos:matches>
%   <vos:search>
% <uws:jobInfo>
% \end{verbatim}
% 
% The representation of the results of a Search SHALL have the following members:
% 
% \begin{itemize}
%     \item \emph{nodes}: A list containing zero or more Nodes of appropriate detail identifying the target URIs meeting the search criteria
% \end{itemize}

\section{REST bindings}
\label{sec:rest bindings}
In a REST (Representational State Transfer) binding of VOSpace, each of the objects defined below is available as a web resource with its own URI.

The standard ID of a VOSpace is:

\begin{verbatim}ivo://ivoa.net/std/VOSpace\end{verbatim}

The 2.0 specification defined the standardID as:

\begin{verbatim}ivo://ivoa.net/std/VOSpace/v2.0\end{verbatim}

This form of standardID will also be recognized as a valid standardID for VOSpace in the 2.1 specification.

The syntax of the standard IDs for the REST bindings has changed in VOSpace 2.1 to be in accordance with the IVOA Recommendation IVOA Identifiers 2.0 \citep{2016ivoa.spec.0523D}.  Specifically, the question mark (?) symbol is to be used in place of the hash (\#) symbol for listing the particular resource.  Secondly, the resource is now versioned to align with the version of the standard, rather than having the version in the standardID of the specification.

Since only the /synctrans binding has changed in version 2.1, it is the only binding with a separate 2.1 resource identifier version.

The following is a list of the resourceIDs for the REST bindings for VOSpace 2.x implementations:

\begin{itemize}
    \item \begin{verbatim}ivo://ivoa.net/std/VOSpace/v2.0#properties\end{verbatim} The properties employed in the space.
    \item \begin{verbatim}ivo://ivoa.net/std/VOSpace/v2.0#views\end{verbatim} The protocols employed in the space.
    \item \begin{verbatim}ivo://ivoa.net/std/VOSpace/v2.0#protocols\end{verbatim} The views employed in the space.
    \item \begin{verbatim}ivo://ivoa.net/std/VOSpace/v2.0#nodes\end{verbatim} A Node under the nodes of the space.
    \item \begin{verbatim}ivo://ivoa.net/std/VOSpace/v2.0#transfers\end{verbatim} Asynchronous transfers for the space.
\end{itemize}

Transfer details can be discovered by appending \emph{/[job-id]/results/transferDetails} to the end of a service's transfer endpoint.

In version 2.0, the following is the resourceID for synchronous transfers in the space:

\begin{itemize}
    \item \begin{verbatim}ivo://ivoa.net/std/VOSpace/v2.0#sync\end{verbatim}
\end{itemize}

In version 2.1, the following resourceID has been introduced for the 2.1 version of synchronous transfers:

\begin{itemize}
    \item \begin{verbatim}ivo://ivoa.net/std/VOSpace#sync-2.1\end{verbatim}
\end{itemize}

For backwards compatibility support in the exchange of XML documents on transfers, VOSpace 2.1 employs the techniques described in the IVOA XML Schema Versioning note \citep{note:schemaversioning}.  This means that both 2.0 and 2.1 documents will use the single, major version in the namespace (v2.0), but 2.1 documents will also be tagged with the attribute \emph{version="2.1"}.

\section{Access Control}
\label{sec:access control}
VOSpace implementations may support a number of authentication methods including:

\begin{itemize}
    \item no authentication (anonymous clients)
    \item digital signatures with X.509 client certificates
    \item OAuth (http://oauth.net)
\end{itemize}

For a full list of authentication methods and the associated standardIDs please refer to the IVOA Single Sign-On document: \citep{std:SSOAUTH2}. 	

When a client is requesting a transfer from the service, the authentication type (securityMethod) may be supplied along side the list of transfer protocols. The \emph{securityMethod} is specified by standardID.  If the service supports the requested type, it may base the construction of the endpoint URL for data transfer from this information.  (Services may encounter situations when the URL for data transfer will depend on the authentication type the client wishes to use.)

For backwards compatibility support, services SHALL include the securityMethod element in the transfer response if and only if a securityMethod was provided by the client in the protocol.

The access control policy for a VOSpace is defined by the implementor of that space according to the use cases for which the implementation is intended.

A human-readable description of the implemented access policy must be declared in the registry metadata for the space.

These are the most probable access policies:

\begin{itemize}
    \item No authorization is required, but clients must authenticate an identity (for logging purposes) in each request to the space
    \item Clients may not create or change nodes (i.e., the contents of the space are fixed by the implementation or set by some interface other than VOSpace), but any client can read any node without authentication
    \item Nodes are considered to be owned by the user who created them. Only the owner can operate on a node
    \item Node authorization is similar to that of Linux file system permission handling with ownership and group membership.
\end{itemize}

No operations to modify the access policy (e.g., to set permissions on an individual node) are included in this standard. Later versions may add such operations.

Where the access policy requires authentication of callers, the VOSpace service SHALL support one of the authentication methods defined in the IVOA Single Sign On Profile.

\section{Web service operations}
\label{sec:web service operations}

A VOSpace 2.1 service SHALL be a RESTful service with the operations listed in this section.

\paragraph{Notes}
\begin{itemize}
    \item The URL http://(rest-endpoint)/nodes denotes the URL of the top node in the VOSpace. The URL http://(rest-endpoint)/nodes/(path) denotes a specific node within the VOSpace.
    \item When representing a Fault, the exact specified fault name SHALL be used. If this is followed by some details, the fault SHALL be separated from the subsequent characters by whitespace.
    \item If the service is able to detect an internal system failure (associated with an HTTP 500 status code) then it should indicate this as described below if possible.
    \item When clients POST or PUT XML documents (such as transfer documents), the Content-Type should be set to \emph{text/xml}
\end{itemize}

\subsection{Service metadata}
\label{subsec:service metadata}
These operations return comprehensive lists of service-level metadata, e.g., all protocols supported by the service. Individual nodes within a service, however, may not necessarily support all of these, i.e., only container nodes may support archive formats such as zip or tar.

\subsubsection{getProtocols}
\label{subsubsec:getprotocols}
Get a list of the transfer Protocols supported by the VOSpace service

\paragraph{Request}
A HTTP request to http://rest-endpoint/protocols

\paragraph{Response}
\subparagraph{Status code} A HTTP 200 status code
\subparagraph{Body}
A Protocols representation giving:
\begin{itemize}
    \item accepts: A list of Protocols that the service SHALL accept
    \begin{itemize}
        \item In this context `accepting a protocol' means that the service SHALL act as a client for the protocol
        \item e.g., `accepting httpget' means the service can read data from an external HTTP web server
    \end{itemize}
    \item provides: A list of Protocols that the service SHALL provide
    \begin{itemize}
        \item In this context `providing a protocol' means that the service SHALL act as a server for the protocol
        \item e.g., `providing httpget' means the service can act as a http web server
    \end{itemize}
\end{itemize}

\paragraph{Faults}
\begin{itemize}
    \item The service SHOULD throw a HTTP 500 status code including an InternalFault fault in the entity body if the operation fails
\end{itemize}

\paragraph{Example}
Get the VOSpace protocols
\\[5px]
\noindent
Request:
\begin{lstlisting}
> curl -v http://server.example.com/vospace/protocols
\end{lstlisting}
Response:
\begin{lstlisting}
> GET /vospace/protocols HTTP/1.1
>
< HTTP/1.1 200 OK
< Content-Type: text/xml
<
<vos:protocols xmlns:vos="http://www.ivoa.net/xml/VOSpace/v2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema-instance">
  <vos:accepts>
    <vos:protocol uri="ivo://ivoa.net/vospace/core#httpget"/>
    <vos:protocol uri="ivo://ivoa.net/vospace/core#httpput"/>
  </vos:accepts>
  <vos:provides>
    <vos:protocol uri="ivo://ivoa.net/vospace/core#httpget"/>
    <vos:protocol uri="ivo://ivoa.net/vospace/core#httpput"/>
  </vos:provides>
</vos:protocols>
\end{lstlisting}

\subsubsection{getViews}
\label{subsubsec:getviews}
Get a list of the Views and data formats supported by the VOSpace service

\paragraph{Request}
A HTTP GET to http://rest-endpoint/views

\paragraph{Response}
\subparagraph{Status code} A HTTP 200 status code
\subparagraph{Body}
A Views representation giving:
\begin{itemize}
    \item accepts: A list of Views that the service SHALL accept
    \begin{itemize}
        \item In this context `accepting a view' means that the service SHALL receive input data in this format
        \item A simple file based system may use the reserved View URI ivo://net.ivoa.vospace/views/any to indicate that it can accept data in any format
    \end{itemize}
    \item provides: A list of Views that the service SHALL provide
    \begin{itemize}
        \item In this context `providing a view' means that the service SHALL produce output data in this format
        \item A simple file based system may use the reserved View URI ivo://net.ivoa.vospace/views/any to indicate that it can provide data in any format
    \end{itemize}
\end{itemize}

\paragraph{Faults}
\begin{itemize}
    \item The service SHOULD throw a HTTP 500 status code including an InternalFault fault in the entity body if the operation fails
\end{itemize}

\paragraph{Example}
Get the VOSpace views
\\[5px]
\noindent
Request:
\begin{lstlisting}
> curl -v "http://server.example.com/vospace/views"
\end{lstlisting}
Response:
\begin{lstlisting}
> GET /vospace/views HTTP/1.1
>
< HTTP/1.1 200 OK
< Content-Type: text/xml
<
<vos:views xmlns:vos="http://www.ivoa.net/xml/VOSpace/v2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema-instance">
  <vos:accepts>
    <vos:view uri="ivo://ivoa.net/vospace/core#anyview"/>
  </vos:accepts>
  <vos:provides>
    <vos:view uri="ivo://ivoa.net/vospace/core#defaultview"/>
  </vos:provides>
</vos:views>
\end{lstlisting}

\subsubsection{getProperties}
\label{subsubsec:getproperties}

\paragraph{Request}
A HTTP request to http://rest-endpoint/properties

\paragraph{Response}
\subparagraph{Status code} A HTTP 200 status code
\subparagraph{Body}
A Properties representation including:
\begin{itemize}
    \item accepts: A list of identifiers for the Properties that the service SHALL accept and understand. This refers to metadata (Properties) that is implementation dependent but can be used by a client to control operational aspects of the service: for example, a VOSpace implementation might allow individual users to control the permissions on data objects via a Property called ``permissions''. If the VOSpace receives a data object with this Property then it `understands' what this property refers to and can deal with it accordingly.
    \item provides: A list of identifiers for the Properties that the service SHALL provide
    \item contains: A list of identifiers for all the Properties currently used by Nodes within the service
\end{itemize}

\paragraph{Faults}
\begin{itemize}
    \item The service SHOULD throw a HTTP 500 status code including an InternalFault fault in the entity body if the operation fails
\end{itemize}

\paragraph{Example}
Get the VOSpace properties
\\[5px]
\noindent
Request:
\begin{lstlisting}
> curl -v "http://server.example.com/vospace/properties"
\end{lstlisting}
Response:
\begin{lstlisting}
> GET /vospace/properties HTTP/1.1
>
< HTTP/1.1 200 OK
< Content-Type: text/xml
<
<vos:properties xmlns:vos="http://www.ivoa.net/xml/VOSpace/v2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema-instance">
  <vos:accepts>
    <vos:property uri="ivo://ivoa.net/vospace/core#title"/>
    <vos:property uri="ivo://ivoa.net/vospace/core#creator"/>
    <vos:property uri="ivo://ivoa.net/vospace/core#description"/>
  </vos:accepts>
  <vos:provides>
    <vos:property uri="ivo://ivoa.net/vospace/core#availableSpace"/>
    <vos:property uri="ivo://ivoa.net/vospace/core#httpput"/>
  </vos:provides>
  <vos:contains>
    <vos:property uri="ivo://ivoa.net/vospace/core#availableSpace"/>
    <vos:property uri="ivo://ivoa.net/vospace/core#title"/>
    <vos:property uri="ivo://ivoa.net/vospace/core#creator"/>
    <vos:property uri="ivo://ivoa.net/vospace/core#description"/>
  </vos:contains>
</vos:properties>
\end{lstlisting}

\subsection{Creating and manipulating data nodes}
\label{subsec:creating and manipulating data nodes}

\subsubsection{createNode}
\label{subsubsec:createnode}
Create a new node at a specified location

\paragraph{Request}
A HTTP PUT of a node representation to path of the node to be created on the /nodes resource:
\begin{verbatim}
http://server.example.com/vospace/nodes/<path to node>
\end{verbatim}
The node representation is template Node (as defined in section \ref{subsec:nodes and node types}) for the node to be created.

A valid uri attribute SHALL be required. The name .auto is a reserved URI to indicate an auto-generated URI for the destination, i.e., given the following URI vos://service/path/.auto a service SHOULD create a new unique URI for the node within vos://service/path.

If the node path of the URI in the node representation does not match the node path in the HTTP PUT URL the service SHALL return an error.

If the Node xsi:type is not specified then a generic node of type Node is implied.

The permitted values of xsi:type are:

\begin{itemize}
    \item vos:Node
    \item vos:DataNode
    \item vos:UnstructuredDataNode
    \item vos:StructuredDataNode
    \item vos:ContainerNode
    \item vos:LinkNode
\end{itemize}

When creating a new Node the service MAY substitute a valid subtype, i.e., If xsi:type is set to vos:DataNode then this may be implemented as a DataNode, StructuredDataNode or an UnstructuredDataNode.

The properties of the new Node can be set by adding Properties to the template. Attempting to set a Property that the service considers to be 'readOnly' SHALL cause a PermissionDenied fault. The accepts and provides lists of Views for the Node cannot be set using this method.

The capabilities list for the Node cannot be set using this method.

\paragraph{Response}
\subparagraph{Status code} A HTTP 201 status code
\subparagraph{Body}
A node representation including:
\begin{itemize}
    \item \emph{node}: details of the new Node
\end{itemize}

The \emph{accepts} list of Views for the Node SHALL be filled in by the service based on service capabilities.

The \emph{provides} list of Views for the Node MAY not be filled in until some data has been imported into the Node.

The \emph{capabilities} list for the Node MAY not be filled in until some data has been imported into the Node.

\paragraph{Faults}
\begin{itemize}
    \item The service SHOULD throw a HTTP 500 status code including an InternalFault fault in the entity body if the operation fails
    \item The service SHALL throw a HTTP 409 status code including a DuplicateNode fault in the entity body if a Node already exists with the same URI
    \item The service SHALL throw a HTTP 400 status code including an InvalidURI fault in the entity body if the requested URI is invalid
    \item If the URI node path does not match the node path of the HTTP PUT request the service must throw a HTTP 400 status including an InvalidURI fault in the entity body.
    \item The service SHALL throw a HTTP 400 status code including a TypeNotSupported fault in the entity body if the type specified in xsi:type is not supported
    \item The service SHALL throw a HTTP 403 status code including PermissionDenied fault in the entity body if the user does not have permissions to perform the operation
    \item If a parent node in the URI path does not exist then the service SHALL throw a HTTP 404 status code including a ContainerNotFound fault in the entity body.
    \begin{itemize}
        \item For example, given the URI path /a/b/c, the service must throw a HTTP 404 status code including a ContainerNotFound fault in the entity body if either /a or /a/b do not exist.
    \end{itemize}
    \item If a parent node in the URI path is a LinkNode, the service SHALL throw a HTTP 400 status code including a LinkFound fault in the entity body.
        \begin{itemize}
        \item For example, given the URI path /a/b/c, the service must throw a HTTP 400 status code including a LinkFound fault in the entity body if either /a or /a/b are LinkNodes.
    \end{itemize}
\end{itemize}

\paragraph{Example}
Create a node
\\[5px]
\noindent
The node to be created (newNode.xml):
\begin{lstlisting}
<vos:node xmlns:xs="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:vos="http://www.ivoa.net/xml/VOSpace/v2.0" xsi:type="vos:UnstructuredDataNode" uri="vos://example.com!vospace/mydata1">
  <vos:properties>
    <vos:property uri="ivo://ivoa.net/vospace/core#description">My important results</vos:property>
  </vos:properties>
  <vos:accepts/>
  <vos:provides/>
  <vos:capabilities/>
</vos:node>
\end{lstlisting}
Request:
\begin{lstlisting}
> curl -v -X PUT -d @newNode.xml -H "Content-type: text/xml" "http://server.example.com/vospace/nodes/mydata1"
\end{lstlisting}
Response:
\begin{lstlisting}
> PUT /vospace/nodes/mydata1 HTTP/1.1
> Content-Type: text/xml
>
< HTTP/1.1 200 OK
< Content-Type: text/xml
<
<vos:node xmlns:xi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns:vos="http://www.ivoa.net/xml/VOSpace/v2.0"
      xsi:type="vos:UnstructuredDataNode" 
      uri="vos://example.com!vospace/mydata1">
  <vos:properties>
    <vos:property uri="ivo://ivoa.net/vospace/core#description">My important results</vos:property>
    <vos:property uri="ivo://ivoa.net/vospace/core#date" readOnly="true">2015-05-22T23:06:32.966</vos:property>
  </vos:properties>
  <vos:accepts>
    <vos:view uri="ivo://ivoa.net/vospace/core#anyview"/>
  </vos:accepts>
  <vos:provides/>
  <vos:capabilities/>
</vos:node>
\end{lstlisting}

\subsubsection{moveNode}
\label{subsubsec:movenode}
Move a node within a VOSpace service.

Note that this does not cover moving data between two separate VOSpace services.

Moving nodes between separate VOSpace services SHOULD be handled by the client, using the import, export and delete methods.

When the source is a ContainerNode, all its children (the contents of the container) SHALL also be moved to the new destination.

When the destination is an existing ContainerNode, the source SHALL be placed under it (i.e., within the container).

The Node type cannot be changed using this method.

\paragraph{Request}
\begin{itemize}
    \item A HTTP POST of a Job representation for the transfer to http://rest-endpoint/transfers.
\end{itemize}

.auto is a reserved URI to indicate an autogenerated URI for the destination, i.e., vos://service/path/.auto SHOULD cause a new unique URI for the node within vos://service/path to be generated.

\paragraph{Response}
\subparagraph{Status code} The initial response is a HTTP 303 status code with the Location header keyword assigned to the created job.
\subparagraph{Body}
If an autogenerated URI for the destination was specified in the request then its value SHALL be specified as a result in the Results List for the completed transfer with the id of ``destination'':
\begin{lstlisting}
<uws:job>
  ...
  <uws:jobInfo>
    <vos:direction>vos://example.com!vospace/mjg/.auto</vos:direction>
  ...
  <uws:results>
    <uws:result id="destination">vos://example.com!vospace/mjg/abc123</uws:result>
  </uws:results>
  ...
</uws:job>
\end{lstlisting}

\paragraph{Faults}

For all faults, the service shall set the PHASE to ``ERROR'' in the Job representation. The \verb|<errorSummary>| element in the Job representation shall be set to the appropriate value for the fault type and the appropriate fault representation provided at the error URI: http://rest-endpoint/transfers/(jobid)/error.

\vspace{3mm}
\begin{tabular}{ p{5cm} l p{4cm} }
\textbf{Fault description} & \textbf{errorSummary} & \textbf{Fault representation} \\
\hline
Operation fails & Internal Fault & InternalFault \\
\hline
User does not have permissions to perform the operation &Permission Denied & PermissionDenied \\
\hline
Source node does not exist & Node Not Found & NodeNotFound \\
\hline
Destination node already exists and it is not a ContainerNode & Duplicate Node & DuplicateNode \\
\hline
A specified URI is invalid & Invalid URI & InvalidURI \\
\hline
\end{tabular}
\vspace{3mm}

\paragraph{Example}
Move a node
\\[5px]
\noindent
The Job to be submitted (moveJob.xml):
\begin{lstlisting}
<vos:transfer xmlns:xs="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:vos="http://www.ivoa.net/xml/VOSpace/v2.0" version="2.1">
  <vos:target>vos://example.com!vospace/mydata1</vos:target>
  <vos:direction>vos://example.com!vospace/mydata2</vos:direction>
  <vos:keepBytes>false</vos:keepBytes>
</vos:transfer>
\end{lstlisting}
Request:
\begin{lstlisting}
> curl -v -X POST -d @moveJob.xml -H "Content-type: text/xml" "http://server.example.com/vospace/transfers"
\end{lstlisting}
Response:
\begin{lstlisting}
> POST /vospace/transfers HTTP/1.1
> Content-Type: text/xml
>
< HTTP/1.1 303 See Other
< Location: http://server.example.com/vospace/transfers/glmldqf591feljub
< Content-Type: text/plain
<
\end{lstlisting}
Job information can be seen by following the redirect to:
\begin{lstlisting}
> curl -v "http://server.example.com/vospace/transfers/glmldqf591feljub"
\end{lstlisting}
Response:
\begin{lstlisting}
> GET /vospace/transfers/glmldqf591feljub HTTP/1.1
>
< HTTP/1.1 200 OK
< Content-Type: text/xml
<
<?xml version="1.0" encoding="UTF-8"?>
<uws:job xmlns:uws="http://www.ivoa.net/xml/UWS/v1.0" xmlns:xlink="http://www.w3.org/1999/xlink">
  <uws:jobId>glmldqf591feljub</uws:jobId>
  <uws:ownerId xs:nill="true" />
  <uws:phase>PENDING</uws:phase>
  <uws:quote>2015-05-23T11:44:03.993</uws:quote>
  <uws:startTime xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" xs:nil="true" />
  <uws:endTime xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" xs:nil="true" />
  <uws:executionDuration>43200</uws:executionDuration>
  <uws:destruction>2015-05-29T23:44:03.993</uws:destruction>
  <uws:parameters />
  <uws:results />
  <uws:jobInfo>
    <vos:transfer xmlns:vos="http://www.ivoa.net/xml/VOSpace/v2.0" version="2.1">
      <vos:target>vos://example.com!vospace/mydata1</vos:target>
      <vos:direction>vos://example.com!vospace/mydata2</vos:direction>
      <vos:keepBytes>false</vos:keepBytes>
    </vos:transfer>
  </uws:jobInfo>
</uws:job>
\end{lstlisting}
Now start the UWS job:
\begin{lstlisting}
> curl -v -d "PHASE=RUN" "http://server.example.com/vospace/transfers/glmldqf591feljub/phase"
\end{lstlisting}
Response:
\begin{lstlisting}
> POST /vospace/transfers/glmldqf591feljub/phase HTTP/1.1
> Content-Type: text/xml
>
< HTTP/1.1 303 See Other
< Location: http://server.example.com/vospace/transfers/glmldqf591feljub
< Content-Type: text/plain
<
\end{lstlisting}
Follow the redirect to see the phase.  The job will be either RUNNING, COMPLETED or ERROR.
\begin{lstlisting}
> curl -v http://server.example.com/vospace/transfers/glmldqf591feljub/phase
\end{lstlisting}
Response:
\begin{lstlisting}
> GET /vospace/transfers/glmldqf591feljub/phase HTTP/1.1
>
< HTTP/1.1 200 OK
< Content-Type: text/plain
<
COMPLETED
\end{lstlisting}
If the job is in phase RUNNING, the phase can be polled intermittently until it is COMPLETED or ERROR.
Error and result details can be seen by performing an HTTP GET to the job URL:
\begin{lstlisting}
> curl -v "http://server.example.com/vospace/transfers/glmldqf591feljub"
\end{lstlisting}

\subsubsection{copyNode}
\label{subsubsec:copynode}
Copy a node within a VOSpace service.
Note that this does not cover copying data between two separate VOSpace services.
Copying nodes between separate VOSpace services SHOULD be handled by the client, using the import and export methods.
When the source is a ContainerNode, all its children (the full contents of the container) SHALL get copied, i.e., this is a deep recursive copy.
When the destination is an existing ContainerNode, the copy SHALL be placed under it (i.e., within the container).
The Node type cannot be changed using this method.

\paragraph{Request}
A HTTP POST of a Job representation for the transfer (see section \ref{subsec:transfers}) to http://rest-endpoint/transfers.
.auto is the reserved URI to indicate an auto-generated URI for the destination, i.e., vos://service/path/.auto SHOULD cause a new unique URI for the node within vos://service/path to be generated.

\paragraph{Response}
The initial response is a HTTP 303 status code with the Location header keyword assigned to the created job.
If an autogenerated URI for the destination was specified in the request then its value SHALL be specified as a result in the Results List for the completed transfer with the id of "destination":

\begin{lstlisting}
<uws:job>
  ...
  <uws:jobInfo>
    <vos:direction>vos://nvo.caltech!vospace/mjg/.auto</vos:direction>
  ...
  <uws:results>
    <uws:result id="destination">vos://nvo.caltech!vospace/mjg/abc123</uws:result>
  </uws:results>
  ...
</uws:job>
\end{lstlisting}

\paragraph{Faults}
For all faults, the service shall set the PHASE to ``ERROR'' in the Job representation. The \verb|<errorSummary>| element in the Job representation shall be set to the appropriate value for the fault type and the appropriate fault representation (see section \ref{subsec:fault arguments}) provided at the error URI: http://rest-endpoint/transfers/(jobid)/error.

\vspace{3mm}
\begin{tabular}{ p{5cm} l p{4cm} }
\textbf{Fault description} & \textbf{errorSummary} & \textbf{Fault representation} \\
\hline
Operation fails & Internal Fault & InternalFault \\
\hline
User does not have permissions to perform the operation & Permission Denied & PermissionDenied \\
\hline
Source node does not exist & Node Not Found & NodeNotFound \\
\hline
Destination node already exists and it is not a ContainerNode & Duplicate Node & DuplicateNode \\
\hline
A specified URI is invalid & Invalid URI & InvalidURI \\
\hline
\end{tabular}
\vspace{3mm}

\paragraph{Example}
Copy a VOSpace node
\\[5px]
\noindent
The Job to be submitted (copyJob.xml):
\begin{lstlisting}
<vos:transfer xmlns:xs="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:vos="http://www.ivoa.net/xml/VOSpace/v2.0" version="2.1">
  <vos:target>vos://example.com!vospace/mydata1</vos:target>
  <vos:direction>vos://example.com!vospace/mydir/.auto</vos:direction>
  <vos:keepBytes>true</vos:keepBytes>
</vos:transfer>
\end{lstlisting}
Request:
\begin{lstlisting}
> curl -v -X POST -d @copyJob.xml -H "Content-type: text/xml" "http://server.example.come/vospace/transfers"
\end{lstlisting}
Response:
\begin{lstlisting}
> POST /vospace/transfers HTTP/1.1
> Content-Type: text/xml
>
< HTTP/1.1 303 See Other
< Location: http://server.example.com/vospace/transfers/usil5s8mdbgjwzvq
< Content-Type: text/plain
<
* Closing connection #0
\end{lstlisting}
Job information can be seen by following the redirect to:
\begin{lstlisting}
> curl -v "http://server.example.com/vospace/transfers/usil5s8mdbgjwzvq"
\end{lstlisting}
Response:
\begin{lstlisting}
> GET /vospace/transfers/usil5s8mdbgjwzvq HTTP/1.1
>
< HTTP/1.1 200 OK
< Content-Type: text/xml
<
<?xml version="1.0" encoding="UTF-8"?>
<uws:job xmlns:uws="http://www.ivoa.net/xml/UWS/v1.0" xmlns:xlink="http://www.w3.org/1999/xlink">
  <uws:jobId>usil5s8mdbgjwzvq</uws:jobId>
  <uws:ownerId xs:nill="true" />
  <uws:phase>PENDING</uws:phase>
  <uws:quote>2015-05-23T11:44:03.993</uws:quote>
  <uws:startTime xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" xs:nil="true" />
  <uws:endTime xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" xs:nil="true" />
  <uws:executionDuration>43200</uws:executionDuration>
  <uws:destruction>2015-05-29T23:44:03.993</uws:destruction>
  <uws:parameters />
  <uws:results>
    <uws:result id="destination" xlink:href="vos://example.com!vospace/mydir/ef9ce281f5bd4bff92c8991580cddff4"/>
  </uws:results>
  <uws:jobInfo>
    <vos:transfer xmlns:vos="http://www.ivoa.net/xml/VOSpace/v2.0" version="2.1">
      <vos:target>vos://example.com!vospace/mydata1</vos:target>
      <vos:direction>vos://example.com!vospace/mydir/.auto</vos:direction>
      <vos:keepBytes>true</vos:keepBytes>
    </vos:transfer>
  </uws:jobInfo>
</uws:job>
\end{lstlisting}
Now start the UWS job:
\begin{lstlisting}
> curl -v -d "PHASE=RUN" "http://server.example.com/vospace/transfers/usil5s8mdbgjwzvq/phase"
\end{lstlisting}
Response:
\begin{lstlisting}
> POST /vospace/transfers/usil5s8mdbgjwzvq/phase HTTP/1.1
> Content-Type: text/xml
>
< HTTP/1.1 303 See Other
< Location: http://server.example.com/vospace/transfers/usil5s8mdbgjwzvq
< Content-Type: text/plain
<
\end{lstlisting}
Follow the redirect to see the phase.  The job will be either RUNNING, COMPLETED or ERROR.
\begin{lstlisting}
> curl -v http://server.example.com/vospace/transfers/usil5s8mdbgjwzvq/phase
\end{lstlisting}
Response:
\begin{lstlisting}
> GET /vospace/transfers/usil5s8mdbgjwzvq/phase HTTP/1.1
>
< HTTP/1.1 200 OK
< Content-Type: text/plain
<
COMPLETED
\end{lstlisting}
If the job is in phase RUNNING, the phase can be polled intermittently until it is COMPLETED or ERROR.
Error and result details can be seen by performing an HTTP GET to the job URL:
\begin{lstlisting}
> curl -v "http://server.example.com/vospace/transfers/usil5s8mdbgjwzvq"
\end{lstlisting}

\subsubsection{deleteNode}
\label{subsubsec:deletenode}
Delete a node.
When the target is a ContainerNode, all its children (the contents of the container) SHALL also be deleted.
Note that the same operation can also be achieved with a moveNode (see \ref{subsubsec:movenode}) with a .null node as the direction (destination node).

\paragraph{Request}
A HTTP DELETE to the URL of an existing node

\paragraph{Response}
A HTTP 204 status code

\paragraph{Faults}
\begin{itemize}
    \item The service SHOULD throw a HTTP 500 status code including an InternalFault fault in the entity-body if the operation fails
    \item The service SHALL throw a HTTP 403 status code including a PermissionDenied fault in the entity-body if the user does not have permissions to perform the operation
    \item The service SHALL throw a HTTP 404 status code including a NodeNotFound fault in the entity-body if the target node does not exist
    \item If a parent node in the URI path does not exist then the service SHALL throw a HTTP 404 status code including a ContainerNotFound fault in the entity-body
    \begin{itemize}
        \item For example, given the URI path /a/b/c, the service must throw a HTTP 404 status code including a ContainerNotFound fault in the entity-body if either /a or /a/b do not exist.
    \end{itemize}
    \item If a parent node in the URI path is a LinkNode, the service SHALL throw a HTTP 400 status code including a LinkFound fault in the entity-body.
    \begin{itemize}
        \item For example, given the URI path /a/b/c, the service must throw a HTTP 400 status code including a LinkFound fault in the entity-body if either /a or /a/b are LinkNodes.
    \end{itemize}
    \item If the target node in the URI path does not exist, the service SHALL throw a HTTP 404 status code including a NodeNotFound fault in the entity-body.
    \begin{itemize}
        \item For example, given the URI path /a/b/c, the service must throw a HTTP 404 status code including a NodeNotFound fault in the entity-body if /a/b/c does not exist.
    \end{itemize}
\end{itemize}

\paragraph{Example}
Delete a VOSpace node
\\[5px]
\noindent
Request:
\begin{lstlisting}
> curl -v -X DELETE "http://server.example.com/vospace/nodes/mydata1"
\end{lstlisting}
Response:
\begin{lstlisting}
> DELETE /vospace/nodes/mydata1 HTTP/1.1
>
< HTTP/1.1 200 OK
< Content-Type: text/plain
<
\end{lstlisting}

\subsection{Accessing metadata}
\label{subsec:accessing metadata}

\subsubsection{getNode}
\label{subsubsec:getnode}
Get the details for a specific Node.

\paragraph{Request}
A HTTP GET to the URL of an existing node http://rest-endpoint/nodes/path
This can take the optional parameters to control the size of the response:

\begin{itemize}
    \item \emph{detail} with values of:
    \begin{itemize}
        \item \emph{min}: the returned record for the node contains minimum detail with all optional parts removed -- the node type should be returned
        \begin{itemize}
            \item e.g., \verb|<Node uri="vos://service/name" xsi:type="Node"/>|
        \end{itemize}
        \item \emph{max}: the returned record for the node contains the maximum detail, including any xsi:type specific extensions
        \item \emph{properties}: the returned record for the node contains the basic node element with a list of properties but no xsi:type specific extensions
    \end{itemize}
    \item \emph{uri} with a value of a VOSpace identifier, URI-encoded according to RFC2396
    \item \emph{limit} with an integer value indicating the maximum number of results in the response.
    \begin{itemize}
        \item No limit indicates a request for an unpaged list. However the server MAY still impose its own limit on the size of an individual response, splitting the results into more than one page if required
     \end{itemize}
\end{itemize}
The list of supported protocols for a node can be retrieved with:

\begin{itemize}
    \item A HTTP POST of an empty protocol representation to the URL of an existing node http://rest-endpoint/nodes/path
\end{itemize}
    
\paragraph{Response}
A HTTP 200 status code and a Node representation in the entity-body.
When no parameters are present in the request, the full expanded record for the node SHALL be returned, including any xsi:type specific extensions; otherwise the appropriate form for the specified value of the ``detail'' parameter SHALL be returned.

When the node is a container, the returned record will also contain a list of direct children nodes in the container (as \verb|<node>| subelements under the \verb|<nodes>| element).

If a ``uri'' and ``offset'' are specified in the request then the returned list will consist of the subset of children which begins at the node matching the specified value of the ``uri'' parameter and with cardinality matching the specified value of the ``offset'' parameter drawn from an ordered sequence of all children. The ordering is determined by the server but results must always be drawn from the same ordered sequence.

For the target node and for any children returned for a container node, the attribute \emph{xsi:type} SHALL be included in the resulting Node document.  

\paragraph{Faults}
\begin{itemize}
    \item The service SHOULD throw a HTTP 500 status code including an InternalFault fault in the entity-body if the operation fails
    \item The service SHALL throw a HTTP 403 status code including a PermissionDenied fault in the entity-body if the user does not have permissions to perform the operation
    \item The service SHALL throw a HTTP 404 status code including a NodeNotFound fault in the entity-body if the target Node does not exist
\end{itemize}

\paragraph{Example}
Get a VOSpace node
\\[5px]
\noindent
Request:
\begin{lstlisting}
> curl -v "http://server.example.com/vospace/nodes/mydir?detail=min&uri=vos://example.com!vospace/mydir/file3401"
\end{lstlisting}
Response:
\begin{lstlisting}
> GET /vospace/nodes/mydir?detail=min&uri=vos://example.com!vospace/mydir/file3401 HTTP/1.1
>
< HTTP/1.1 200 OK
< Content-Type: text/xml
<
<?xml version="1.0" encoding="UTF-8"?>
<vos:node xmlns:vos="http://www.ivoa.net/xml/VOSpace/v2.0" version="2.1" xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" uri="vos://example.com!vospace/mydir" xsi:type="vos:ContainerNode">
  <vos:properties>
    <vos:property uri="ivo://ivoa.net/vospace/core#description">My award winning images</property>
  </vos:properties>
  <vos:accepts>
    <vos:view uri="ivo://ivoa.net/vospace/core#anyview"/>
  </vos:accepts>
  <vos:provides>
    <vos:view uri="ivo://ivoa/net/vospace/core#defaultview"/>
  </vos:provides>
  <vos:capabilities/>
  <vos:nodes>
    <vos:node uri="vos://example.com!vospace/mydir/file3401" xsi:type="vos:DataNode"/>
    <vos:node uri="vos://example.com!vospace/mydir/file3406" xsi:type="vos:DataNode"/>
    <vos:node uri="vos://example.com!vospace/mydir/file3532" xsi:type="vos:DataNode"/>
  </vos:nodes>
\end{lstlisting}

\subsubsection{setNode}
\label{subsubsec:setnode}
Set the property values for a specific Node

\paragraph{Request}
A HTTP POST of a Node representation to the URL of an existing node http://rest-endpoint/nodes/path including:
\begin{itemize}
    \item \emph{node}: A Node containing the Node URI and a list of the Properties to set (as defined in section 3.1)
\end{itemize}
This will add or update the node properties including any xsi:type specific elements.

The operation is the union of existing values and new ones.  An empty value sets the value to blank.  To delete a Property, set the xs:nil attribute to true

This method cannot be used to modify the Node type.

This method cannot be used to modify the accepts or provides list of Views for the Node.

This method cannot be used to create children of a container Node.

\paragraph{Response}
A HTTP 200 status code and a Node representation in the entity-body
The full expanded record for the node SHALL be returned, including any xsi:type specific extensions.

\paragraph{Faults}
\begin{itemize}
    \item The service SHOULD throw a HTTP 500 status code including an InternalFault fault in the entity-body if the operation fails
    \item The service SHALL throw a HTTP 403 status code including a PermissionDenied fault in the entity-body if the request attempts to modify a read-only Property
    \item The service SHALL throw a HTTP 403 status code including a PermissionDenied fault in the entity-body if the user does not have permissions to perform the operation
    \item The service SHALL throw a HTTP 404 status code including a NodeNotFound fault in the entity-body if the target Node does not exist
    \item If a parent node in the URI path does not exist then the service SHALL throw a HTTP 404 status code including a ContainerNotFound fault in the entity-body
    \begin{itemize}
        \item For example, given the URI path /a/b/c, the service must throw a HTTP 404 status code including a ContainerNotFound fault in the entity-body if either /a or /a/b do not exist.
    \end{itemize}
    \item The service SHALL throw a HTTP 400 status code including an InvalidArgument fault in the entity-body if a specified property value is invalid
\end{itemize}

\paragraph{Example}
Set node metadata
\\[5px]
\noindent
The updated node (setNode.xml) is:
\begin{lstlisting}
<node xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" xsi:type="vos:UnstructuredDataNode" xmlns:vos="http://www.ivoa.net/xml/VOSpace/v2.0" version="2.1" uri="vos://nvo.caltech!vospace/mydata1">
  <properties>
    <property uri="ivo://ivoa.net/vospace/core#title" readOnly="false">Title for my data</property>
  </properties>
  <accepts/>
  <provides/>
  <capabilities/>
</node>
\end{lstlisting}
Request:
\begin{lstlisting}
> curl -v -X POST -d @setNode.xml -H "Content-type: text/xml" "http://server.example.com/vospace/nodes/mydata1"
\end{lstlisting}
Response:
\begin{lstlisting}0)
> POST /vospace/nodes/mydata1 HTTP/1.1
> Content-type: text/xml
>
< HTTP/1.1 200 OK
< Content-Type: text/xml
<
<?xml version="1.0" encoding="UTF-8"?>
<vos:node xmlns:vos="http://www.ivoa.net/xml/VOSpace/v2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" version="2.1" uri="vos://cadc.nrc.ca!vospace/mydata1" xsi:type="vos:DataNode" busy="false">
  <vos:properties>
    <vos:property uri="ivo://ivoa.net/vospace/core#length" readOnly="true">44</vos:property>
    <vos:property uri="ivo://ivoa.net/vospace/core#MD5" readOnly="true">12c13e49f2fd37e2c91bcca6acb78a08</vos:property>
    <vos:property uri="ivo://ivoa.net/vospace/core#date" readOnly="true">2015-05-24T23:02:10.397</vos:property>
    <vos:property uri="ivo://ivoa.net/vospace/core#title" readOnly="false">Title for my data</vos:property>
  </vos:properties>
  <vos:accepts>
    <vos:view uri="ivo://ivoa.net/vospace/core#anyview"/>
  </vos:accepts>
  <vos:provides />
</vos:node>
\end{lstlisting}

% \subsubsection{findNodes}
% \label{subsubsec:findnodes}
% Find nodes whose properties match the specified values.
% 
% This operation is OPTIONAL.
% 
% \paragraph{Request}
% A HTTP POST of a Job representation of a Search (see section 3.7) to http://rest-endpoint/searches
% A null value of the "matches" parameter implies a full listing of the space.
% 
% \paragraph{Response}
% The initial response is a HTTP 303 status code with the Location header keyword assigned to the created job.
% 
% The search results representation can be retrieved directly from the link reported in the Results List, available from the results endpoint -- http://rest-endpoint/searches/(jobid)/results -, the standard UWS location under the results endpoint -- http://rest-endpoint/searches/(jobid)/results/searchDetails -- (which may well just be a redirect to the former link), or as part of the full Job representation from http://rest-endpoint/searches/(jobid). The result element in the Results List SHALL have an id of ``searchDetails'':
% 
% \begin{lstlisting}
% <uws:job>
% ...
%   <uws:results>
%    <uws:result id="searchDetails" xlink:href="http://rest-endpoint/searches/(jobid)/results/listing1"/>
%   </uws:results>
% ...
% </uws:job>
% \end{lstlisting}
% 
% \paragraph{Faults}
% For all faults, the service shall set the PHASE to ``ERROR'' in the Job representation. The <errorSummary> element in the Job representation shall be set to the appropriate value for the fault type and the appropriate fault representation (see section 5.5) provided at the error URI: http://rest-endpoint/transfers/(jobid)/error.
% 
% \vspace{3mm}
% \begin{tabular}{ p{5cm} l p{4cm} }
% \textbf{Fault description} & \textbf{errorSummary} & \textbf{Fault representation} \\
% \hline
% Operation not supported & Operation Not Supported & OperationNotSupported \\
% \hline
% Operation fails & Internal Fault & InternalFault \\
% \hline
% User does not have permissions to perform the operation	 & Permission Denied & PermissionDenied \\
% \hline
% A particular property is specified and does not exist in the space & Property Not Found & PropertyNotFound \\
% \hline
% \end{tabular}
% \vspace{3mm}
% 
% \paragraph{Example}
% 
% 
% Find VOSpace nodes
% \\[5px]
% \noindent
% The Job to be submitted (searchJob.xml) is:
% \begin{lstlisting}
% <vos:search xmlns:vos="http://www.ivoa.net/xml/VOSpace/v2.0">
%   <vos:detail>properties</vos:detail>
%   <vos:matches>ivo://ivoa.net/vospace/core#description='galax'</vos:matches>
% <vos:search>
% \end{lstlisting}
% Request:
% \begin{lstlisting}
% > curl -v -X POST -d @searchJob.xml -H "Content-type: text/xml" "http://localhost:8000/searches"
% \end{lstlisting}
% Response:
% \begin{lstlisting}
% > POST /searches HTTP/1.1
% > Content-Type: text/xml
% > 
% < HTTP/1.1 303 See Other
% < Location: http://localhost:8080/searches/8c5b0f78cd5a44af8694f10da1b92060
% < Content-Type: text/html
% < 
% \end{lstlisting}
% This resource can be found at:
% \begin{lstlisting}
% http://localhost:8080/searches/8c5b0f78cd5a44af8694f10da1b92060
% \end{lstlisting}
% The status of the job can now be polled at the job location:
% \begin{lstlisting}
% > curl -v "http://localhost:8000/searches/8c6e7bc53ee848638cda35817e47da65"
% \end{lstlisting}
% Response:
% \begin{lstlisting}
% > GET /searches/8c6e7bc53ee848638cda35817e47da65 HTTP/1.1
% > 
% < HTTP/1.1 200 OK
% < Content-Type: text/xml
% < 
% <uws:job xmlns:uws="http://www.ivoa.net/xml/UWS/v1.0" xmlns:xlink="http://www.w3.org/1999/xlink"
%   xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" xs:schemaLocation="http://www.ivoa.net/xml/UWS/v1.0 UWS.xsd ">
%   <uws:jobId>8c6e7bc53ee848638cda35817e47da65<
%   <uws:ownerId xs:nil="true"/>
%   <uws:phase>COMPLETED</uws:phase>
%   <uws:startTime>2010-03-12T19:50:56.552278</uws:startTime>
%   <uws:endTime>2010-03-12T19:50:56.562416</uws:endTime>
%   <uws:executionDuration>0</uws:executionDuration>
%   <uws:destruction xs:nil="true"/>
%   <uws:jobInfo>
%     <vos:search>
%       <vos:detail>properties</vos:detail>
%       <vos:matches>ivo://ivoa.net/vospace/core#description='galax'</vos:matches>
%     <vos:search>
%   <uws:jobInfo>
%   <uws:results>
%     <uws:result id="searchDetails" xlink:href="http://localhost:8000/searches/d55814f88d974c21afe5ad50e4e875c8/results/listing1"/>
%   </uws:results>
% </uws:job>
% \end{lstlisting}
% Once the Job has completed, the result can be obtained from the URL reported in the result element:
% \begin{lstlisting}
% > curl -v "http://localhost:8000/searches/d55814f88d974c21afe5ad50e4e875c8/results/listing1"
% \end{lstlisting}
% Response:
% \begin{lstlisting}
% > GET /searches/d55814f88d974c21afe5ad50e4e875c8/results/listing1 HTTP/1.1
% > 
% < HTTP/1.1 200 OK
% < Content-Type: text/html
% < 
% <nodes xmlns:vos="http://www.ivoa.net/xml/VOSpace/v2.0"
% xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
%   <node uri="vos://nvo.caltech!vospace/mydir/img1" xsi:type="vos:UnstructuredDataNode">
%     <properties>
%       <property uri="ivo://ivoa.net/vospace/core#description">This is an R-band image of the galaxy NGC 3276</property>
%     </properties>
%   </node>
%   <node uri="vos://nvo.caltech!vospace/mydir/img5" xsi:type="vos:StructuredDataNode">
%     <properties>
%       <property uri="ivo://ivoa.net/vospace/core#description">This is a Chandra mosaic of the Fornax cluster of galaxies</property>
%     </properties>
%   </node>
% </nodes>
% \end{lstlisting}

\subsection{Transferring data}
\label{subsec:transferringdata}
Two modes are supported for external data transfers: a simple HTTP GET to retrieve data from a service (pullFromVoSpace) and a more general mechanism which employs a UWS-based approach \citep{std:UWS} for submitting general data transfer requests (see section \ref{subsec:transfers}). In the latter, four directions are specified in which external data transfers can happen:
\begin{itemize}
    \item \begin{verbatim}pushToVoSpace\end{verbatim} For sending data to a service (upload from a client to a VOSpace)
    \item \begin{verbatim}pullFromVoSpace\end{verbatim} For reading data from a service (download from a VOSpace to a client)
    \item \begin{verbatim}pullToVoSpace\end{verbatim} For importing data into a service (download from one VOSpace to another VOSpace)
    \item \begin{verbatim}pushFromVoSpace\end{verbatim} For sending data from a service (upload from one VOSpace to another VOSpace)
\end{itemize}

A transfer job is created by a HTTP POST of an appropriate Job representation to the transfers endpoint of the service: http://rest-endpoint/transfers.  The following example shows a transfer document for a pushToVoSpace operation:

\begin{lstlisting}
<vos:transfer xmlns:vos="http://www.ivoa.net/xml/VOSpace/v2.0" version="2.1">   
  <vos:target>vos://server.example.com!vospace/mydata1</vos:target>
  <vos:direction>pushToVoSpace</vos:direction>
  <vos:view uri="ivo://net.ivoa/vospace/core#fits"/>
  <vos:protocol uri="ivo://net.ivoa/vospace/core#httpsput">
       <vos:securityMethod uri="ivo://ivoa.net/sso#tls-with-certificate"/>
  </vos:protocol>
</vos:transfer>
\end{lstlisting}

This example transfer job is making a request for an TLS endpoint that supports client certificates that is to be used for performing an HTTP PUT of a file.  

The service returns a 303 redirect with the Location set to the URL of the UWS jobid of the transfer.  It can then be initiated with a HTTP POST of the single parameter ``PHASE=RUN'' to the appropriate job endpoint: http://rest-endpoint/transfers/(jobid)/phase. Alternatively the transfer can also be run immediately on creation by adding the parameter ``PHASE=RUN'' to the initial Job creation URL.

If the job creation POST is sent the synchronous transfer endpoint instead (http://rest-endpoint/synctrans), then the Job is started immediately.

The status of any transfer can be obtained by polling the phase endpoint for a particular transfer, i.e., a HTTP GET to http://rest-endpoint/transfers/(jobid)/phase.

Once a transfer has completed, any results can be obtained by following the link in the Results List available from the results endpoint for that transfer, i.e., with a HTTP GET to http://rest-endpoint/transfers/(jobid)/results. This pertains particularly to the transfer methods in which data is sent to or read from a service-negotiated URL (pushToVoSpace and pullFromVoSpace).

A transfer can also be aborted at any stage with a HTTP POST of the parameter ``PHASE=ABORT'' to the endpoint:\\ http://rest-endpoint/transfers/(jobid)/phase

The two write operations, pushToVoSpace and pullToVoSpace, should set the busy flag on the Node to true while the operation is in progress.  This would have the consequence that the two read operations, pullFromVoSpace and pushFromVoSpace, may fail on requests to that Node.

It is up to each specific transfer protocol or view to define how they behave when invoked on a busy node.

During the negotiation of a transfer, a Node should only offer transfer protocols that are valid at the point when the negotiation is taking place.

More specific details for each of the four directions are given in the sections following.

\subsubsection{pushToVoSpace}
\label{subsubsec:pushtovospace}
Request a list of URLs to send data to a VOSpace node.

This method asks the server for a list of one or more URLs that the client can use to send data to.

The data transfer is initiated by the client, after it has received the response from the VOSpace service.

The primary use case for this method is client that wants to send some data directly to a VOSpace service.

This operation is OPTIONAL.

\paragraph{Request}
An HTTP POST of a Job representation for the transfer to http://rest-endpoint/transfers or http://rest-endpoint/synctrans

If a Node already exists at the target URI, then the data SHALL be imported into the existing Node and the Node properties SHALL be cleared unless the node is a ContainerNode.

If there is no Node at the target URI, then the service SHALL create a new Node using the URI and the default xsi:type for the space.

The transfer representation contains details of the View and a list of the Protocols (and, optionally, the preferred security method(s) per protocol) that the client wants to use.

The list of Protocols SHOULD not contain endpoint addresses, the service will supply the endpoint addresses in the response.

The service SHALL ignore any of the requested protocols and security methods that it does not understand or is unable to support.

.auto is the reserved URI to indicate an auto-generated URI for the destination, i.e., vos://service/path/.auto SHOULD cause a new unique URI for the node within vos://service/path to be generated.  If supported, this URI SHALL be specified as a result in the Results list for the completed transfer with the id of \verb|"target"|.

A pushToVoSpace transfer may be initiated with an HTTP POST of a Job representation of the transfer to http://rest-endpoint/transfers. The service SHALL respond with a redirect to the newly created job.  (See Example 1)

A pushToVoSpace transfer may be initiated with an HTTP POST of a Job representation of the transfer to http://rest-endpoint/synctrans. The service SHALL respond with a redirect to the transfer details of the job.  (See Example 2)

A pushToVoSpace transfer may be initiated with an HTTP POST or GET to http://rest-endpoint/synctrans with the following required URL query parameters:
\begin{itemize}
    \item \emph{TARGET}: The value is the URI of the target node
        \begin{itemize}
           \item Example:  vos://example.com$\mathtt{\sim}$vospace/mydata1
        \end{itemize}
    \item \emph{DIRECTION}: pushToVoSpace
    \item \emph{PROTOCOL}: The standard URI of the protocol to use (see section ~\ref{subsubsec:standard protocols})
        \begin{itemize}
           \item Example: ivo://ivoa.net/vospace/core\#httpput
        \end{itemize}
\end{itemize}

The following optional parameters may also be included:
\begin{itemize}
    \item \emph{VIEW}: The standard URI of the view to use
        \begin{itemize}
           \item Example:  ivo://ivoa.net/vospace/core\#fits
        \end{itemize}
    \item \emph{SECURITYMETHOD}: The standard URI of the security method to use
        \begin{itemize}
           \item Example:  ivo://ivoa.net/sso\#tls-with-certificate
        \end{itemize}
\end{itemize}

The service SHALL respond with the job containing the transfer results in the response body.  (See Example 3)

\paragraph{Response}
Redirect responses are a HTTP 303 status code with the Location header keyword assigned to the created job.
The service SHALL select which of the requested Protocols it is willing to provide and fill in the operational details for each one in the transfer result representation -- this SHOULD normally include specifying the destination URL of the transfer protocol endpoint.

The transfer result SHOULD not include any Protocols or security methods that it is unable to support.

During the byte transfer for the pushToVoSpace operation, the service SHOULD set the busy flag of the Node to true.

If the busy flag of the Node is already set to true, the service SHOULD respond with a NodeBusy fault.

The transfer results representation can be retrieved directly from the link reported in the Results List, available either from the results endpoint -- http://rest-endpoint/transfers/(jobid)/results -- or as part of the full Job representation for the completed transfer available from http://rest-endpoint/transfers/(jobid). The result element in the Results List SHALL have an id of ``transferDetails'':
\begin{lstlisting}
<uws:job>
...
  <uws:results>
   <uws:result id="transferDetails" xlink:href="http://rest-endpoint/transfers/(jobid)/results/transferDetails"/>
  </uws:results>
...
</uws:job>
\end{lstlisting}
For synchronous job postings:
\begin{itemize}
    \item A HTTP 303 status code with the Location header keyword assigned to the endpoint: http://rest-endpoint/transfers/(jobid)/results/transferDetails.
\end{itemize}
The HTTP 303 redirect points to a transfer representation with the required transfer details and endpoints.

For parameter based transfers, the transfer representation with the required transfer details and endpoints is returned directly in the response--no redirect is issued.

\paragraph{Faults}
For all faults using the UWS mode, the service shall set the PHASE to ``ERROR'' in the Job representation. The \verb|<errorSummary>| element in the Job representation shall be set to the appropriate value for the fault type and the appropriate fault representation provided at the error URI: http://rest-endpoint/transfers/(jobid)/error.

\vspace{3mm}
\begin{tabular}{ p{5cm} l p{4cm} }
\textbf{Fault description} & \textbf{errorSummary} & \textbf{Fault representation} \\
\hline
Operation not supported & Operation Not Supported & OperationNotSupported \\
\hline
Operation fails & Internal Fault & InternalFault \\
\hline
User does not have permissions to perform the operation & Permission Denied & PermissionDenied \\
\hline
Service does not support the requested View & View Not Supported & ViewNotSupported \\
\hline
Service supports none of the requested Protocols & Protocol Not Supported &ProtocolNotSupported \\
\hline
A View parameter is invalid & Invalid Argument & InvalidArgument \\
\hline
A Protocol parameter is invalid & Invalid Argument & InvalidArgument \\
\hline
The busy flag of the Node is true & Node Busy & NodeBusy \\
\hline
\end{tabular}
\vspace{3mm}

If an error occurs with the synchronous convenience mode, the resulting transfers document SHOULD have no protocols. The client can then retrieve the Job representation for error information as with asynchronous transfers.

\paragraph{Example 1}
pushToVoSpace over the asynchronous endpoint
\\[5px]
\noindent
The Job to be submitted (pushToVoSpace.xml):
\begin{lstlisting}
<vos:transfer xmlns:vos="http://www.ivoa.net/xml/VOSpace/v2.0" version="2.1">
  <vos:target>vos://example.com!vospace/mydata1</vos:target>
  <vos:direction>pushToVoSpace</vos:direction>
  <vos:view uri="ivo://ivoa.net/vospace/core#fits"/>
  <vos:protocol uri="ivo://ivoa.net/vospace/core#httpput" />
  <vos:param uri="ivo://ivoa.net/vospace/core#length">388943</vos:param>
</vos:transfer>
\end{lstlisting}
Request:
\begin{lstlisting}
> curl -v -X POST -d @pushToVoSpace.xml -H "Content-type: text/xml" "http://server.example.com/vospace/transfers"
\end{lstlisting}
Response:
\begin{lstlisting}
> POST /vospace/transfers HTTP/1.1
> Content-type: text/xml
>
< HTTP/1.1 303 See Other
< Location: http://server.example.com/vospace/transfers/zkqzpftmufdi8luh
< Content-Type: text/plain
<
\end{lstlisting}
The PENDING job can be seen by following the redirect to:
\begin{lstlisting}
> curl -v http://server.example.com/vospace/transfers/zkqzpftmufdi8luh
\end{lstlisting}
Response:
\begin{lstlisting}
> GET /vospace/transfers/zkqzpftmufdi8luh HTTP/1.1
>
< HTTP/1.1 200 OK
< Content-Type: text/xml
<
<?xml version="1.0" encoding="UTF-8"?>
<uws:job xmlns:uws="http://www.ivoa.net/xml/UWS/v1.0" xmlns:xlink="http://www.w3.org/1999/xlink">
  <uws:jobId>zkqzpftmufdi8luh</uws:jobId>
  <uws:phase>PENDING</uws:phase>
  <uws:quote>2015-05-26T11:06:45.713</uws:quote>
  <uws:startTime xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xs:nil="true" />
  <uws:endTime xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xs:nil="true" />
  <uws:executionDuration>43200</uws:executionDuration>
  <uws:destruction>2015-06-01T23:06:45.713</uws:destruction>
  <uws:parameters />
  <uws:results />
  <uws:jobInfo>
    <vos:transfer xmlns:vos="http://www.ivoa.net/xml/VOSpace/v2.0" version="2.1">
      <vos:target>vos://example.com!vospace/mydata1</vos:target>
      <vos:direction>pushToVoSpace</vos:direction>
      <vos:view uri="ivo://ivoa.net/vospace/core#fits" />
      <vos:protocol uri="ivo://ivoa.net/vospace/core#httpput" />
    </vos:transfer>
  </uws:jobInfo>
</uws:job>
\end{lstlisting}
The job can now be started by posting PHASE=RUN:
\begin{lstlisting}
curl -v -X POST -d "PHASE=RUN" http://server.example.com/vospace/transfers/zkqzpftmufdi8luh/phase
\end{lstlisting}
Response:
\begin{lstlisting}
> POST /vospace/transfers/zkqzpftmufdi8luh/phase HTTP/1.1
> Content-Type: text/xml
>
< HTTP/1.1 303 See Other
< Location: http://server.examle.com/vospace/transfers/zkqzpftmufdi8luh
< Content-Type: text/plain
<
\end{lstlisting}
The EXECUTING job can be seen by following the redirect to:
\begin{lstlisting}
http://server.examle.com/vospace/transfers/zkqzpftmufdi8luh
\end{lstlisting}
Response:
\begin{lstlisting}
> GET /vospace/transfers/zkqzpftmufdi8luh HTTP/1.1
>
< HTTP/1.1 200 OK
< Content-Type: text/xml
<
<?xml version="1.0" encoding="UTF-8"?>
<uws:job xmlns:uws="http://www.ivoa.net/xml/UWS/v1.0" xmlns:xlink="http://www.w3.org/1999/xlink">
  <uws:jobId>zkqzpftmufdi8luh</uws:jobId>
  <uws:phase>EXECUTING</uws:phase>
  <uws:quote>2015-05-26T11:06:45.713</uws:quote>
  <uws:startTime>2015-05-25T23:17:41.217</uws:startTime>
  <uws:endTime xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xs:nil="true" />
  <uws:executionDuration>43200</uws:executionDuration>
  <uws:destruction>2015-06-01T23:06:45.713</uws:destruction>
  <uws:parameters />
  <uws:results>
    <uws:result id="transferDetails" xlink:href="http://server.example.com/vospace/transfers/zkqzpftmufdi8luh/results/transferDetails" />
    <uws:result id="dataNode" xlink:href="vos://example.com!vospace/mydata1" />
  </uws:results>
  <uws:jobInfo>
    <vos:transfer xmlns:vos="http://www.ivoa.net/xml/VOSpace/v2.0" version="2.1">
      <vos:target>vos://example.com!vospace/mydata1</vos:target>
      <vos:direction>pushToVoSpace</vos:direction>
      <vos:view uri="ivo://ivoa.net/vospace/core#fits" />
      <vos:protocol uri="ivo://ivoa.net/vospace/core#httpput" />
    </vos:transfer>
  </uws:jobInfo>
</uws:job>
\end{lstlisting}
The details of the transfer negotiation can be see by following the \emph{transferDetails} result:
\begin{lstlisting}
> curl -v http://server.example.com/vospace/transfers/zkqzpftmufdi8luh/results/transferDetails
\end{lstlisting}
Response:
\begin{lstlisting}
> GET /vospace/transfers/zkqzpftmufdi8luh/results/transferDetails HTTP/1.1
>
< HTTP/1.1 200 OK
< Content-Type: text/xml
<
<?xml version="1.0" encoding="UTF-8"?>
<vos:transfer xmlns:vos="http://www.ivoa.net/xml/VOSpace/v2.0" version="2.1">
  <vos:target>vos://example.com!vospace/mydata1</vos:target>
  <vos:direction>pushToVoSpace</vos:direction>
  <vos:protocol uri="ivo://ivoa.net/vospace/core#httpput">
    <vos:endpoint>http://storage1.example.com/trans/mydata1</vos:endpoint>
  </vos:protocol>
  <vos:protocol uri="ivo://ivoa.net/vospace/core#httpput">
    <vos:endpoint>http://storage2.example.com/mydata1</vos:endpoint>
  </vos:protocol>
</vos:transfer>
\end{lstlisting}
The FITS file can now be pushed over HTTP PUT to one of the endpoints listed in the transfer details.
\begin{lstlisting}
> curl -v -T mydata1 "http://storage1.example.com/mydata1"
\end{lstlisting}
Response:
\begin{lstlisting}
> PUT /trans/mydata1 HTTP/1.1
>
< HTTP/1.1 100 Continue
< HTTP/1.1 200 OK
< Content-Type: text/plain
<
\end{lstlisting}
On successful file transfer completion the job will be COMPLETED:
\begin{lstlisting}
curl -v http://server.examle.com/vospace/transfers/zkqzpftmufdi8luh/phase
\end{lstlisting}
Response:
\begin{lstlisting}
> GET /vospace/transfers/zkqzpftmufdi8luh/phase HTTP/1.1
>
< HTTP/1.1 200 OK
< Content-Type: text/plain
<
COMPLETED
\end{lstlisting}

\paragraph{Example 2}
pushToVoSpace over the synchronous endpoint
\\[5px]
\noindent
The Job to be submitted (pushToVoSpace.xml):
\begin{lstlisting}
<vos:transfer xmlns:vos="http://www.ivoa.net/xml/VOSpace/v2.0" version="2.1">
  <vos:target>vos://example.com!vospace/mydata1</vos:target>
  <vos:direction>pushToVoSpace</vos:direction>
  <vos:view uri="ivo://ivoa.net/vospace/core#fits"/>
  <vos:protocol uri="ivo://ivoa.net/vospace/core#httpput" />
</vos:transfer>
\end{lstlisting}
Request:
\begin{lstlisting}
> curl -v -X POST -d @pushToVoSpace.xml -H "Content-type: text/xml" "http://server.example.com/vospace/synctrans"
\end{lstlisting}
Response:
\begin{lstlisting}
> POST /vospace/synctrans HTTP/1.1
> Content-Type: text/xml
>
< HTTP/1.1 303 See Other
< Location: http://server.example.com/vospace/transfers/zkqzpftmufdi8luh/results/transferDetails
< Content-Type: text/plain
<
\end{lstlisting}
The negotiated transfer details can be seen by following the redirect to:
\begin{lstlisting}
http://server.examlpe.com/vospace/transfers/zkqzpftmufdi8luh/results/transferDetails
\end{lstlisting}
Request:
\begin{lstlisting}
> curl -v http://server.example.com/vospace/transfers/zkqzpftmufdi8luh/results/transferDetails
\end{lstlisting}
Response:
\begin{lstlisting}
> GET /vospace/transfers/zkqzpftmufdi8luh/results/transferDetails HTTP/1.1
>
< HTTP/1.1 200 OK
< Content-Type: text/xml;UTF-8
<
<?xml version="1.0" encoding="UTF-8"?>
<vos:transfer xmlns:vos="http://www.ivoa.net/xml/VOSpace/v2.0" version="2.1">
  <vos:target>vos://example.com!vospace/mydata1</vos:target>
  <vos:direction>pushToVoSpace</vos:direction>
  <vos:protocol uri="ivo://ivoa.net/vospace/core#httpput">
    <vos:endpoint>http://storage1.example.com/trans/mydata1</vos:endpoint>
  </vos:protocol>
  <vos:protocol uri="ivo://ivoa.net/vospace/core#httpput">
    <vos:endpoint>http://storage2.example.com/mydata1</vos:endpoint>
  </vos:protocol>
</vos:transfer>
\end{lstlisting}

\paragraph{Example 3}
pushToVoSpace over the synchronous endpoint with securityMethod
\\[5px]
\noindent
A transfer request for endpoints supporting basic authentication over HTTP or TLS with a client certificate over SSL.\\
The Job to be submitted (pushToVoSpace.xml):
\begin{lstlisting}
<vos:transfer xmlns:vos="http://www.ivoa.net/xml/VOSpace/v2.0" version="2.1">
  <vos:target>vos://example.com!vospace/mydata1</vos:target>
  <vos:direction>pushToVoSpace</vos:direction>
  <vos:view uri="ivo://ivoa.net/vospace/core#fits"/>
  <vos:protocol uri="ivo://ivoa.net/vospace/core#httpsput">
      <vos:securityMethod uri="ivo://ivoa.net/sso#tls-with-certificate"/>
  </vos:protocol>
  <vos:protocol uri="ivo://ivoa.net/vospace/core#httpput">
      <vos:securityMethod uri="uri="http://www.w3.org/Protocols/HTTP/1.0/spec/html#BasicAA"/>
  </vos:protocol>
</vos:transfer>
\end{lstlisting}
Request:
\begin{lstlisting}
> curl -v -X POST -d @pushToVoSpace.xml -H "Content-type: text/xml" "http://server.example.com/vospace/synctrans"
\end{lstlisting}
Response:
\begin{lstlisting}
> POST /vospace/synctrans HTTP/1.1
> Content-Type: text/xml
>
< HTTP/1.1 303 See Other
< Location: http://server.example.com/vospace/transfers/zkqzpftmufdi8luh/results/transferDetails
< Content-Type: text/plain
<
\end{lstlisting}
The negotiated transfer details can be seen by following the redirect to:
\begin{lstlisting}
http://server.example.com/vospace/transfers/zkqzpftmufdi8luh/results/transferDetails
\end{lstlisting}
Request:
\begin{lstlisting}
> curl -v http://server.example.come/vospace/transfers/zkqzpftmufdi8luh/results/transferDetails
\end{lstlisting}
Response:
\begin{lstlisting}
> GET /vospace/transfers/zkqzpftmufdi8luh/results/transferDetails HTTP/1.1
>
< HTTP/1.1 200 OK
< Content-Type: text/xml
<
<?xml version="1.0" encoding="UTF-8"?>
<vos:transfer xmlns:vos="http://www.ivoa.net/xml/VOSpace/v2.0" version="2.1">
  <vos:target>vos://example.com!vospace/mydata1</vos:target>
  <vos:direction>pushToVoSpace</vos:direction>
  <vos:protocol uri="ivo://ivoa.net/vospace/core#httpsput">
    <vos:endpoint>https://storage1.example.com/trans/mydata1</vos:endpoint>
    <vos:securityMethod uri="ivo://ivoa.net/sso#tls-with-certificate"/>
  </vos:protocol>
</vos:transfer>
\end{lstlisting}
The service has replied with a single HTTPS endpoint that support TLS with client certificates.

\paragraph{Example 4}
pushToVoSpace over the synchronous endpoint with URL parameters
\\[5px]
\noindent
Request:
\begin{lstlisting}
curl -v -X POST "http://server.example.com/vospace/synctrans?TARGET=vos://example.com~vospace/mydata1&DIRECTION=pushToVoSpace&PROTOCOL=ivo://ivoa.net/vospace/core%23httpput"
\end{lstlisting}
(Note that the \# sign in PROTOCOL is URL encoded as \%23 and that the alternate separator `$\mathtt{\sim}$' is used instead of `!' in the TARGET) \\
\\
Response:
\begin{lstlisting}
> POST /vospace/synctrans?TARGET=vos://example.com~vospace/mydata1&DIRECTION=pushToVoSpace&PROTOCOL=ivo://ivoa.net/vospace/core\%23httpput HTTP/1.1
>
< HTTP/1.1 200 OK
< Content-Type: text/xml
<
<?xml version="1.0" encoding="UTF-8"?>
<vos:transfer xmlns:vos="http://www.ivoa.net/xml/VOSpace/v2.0" version="2.1">
  <vos:target>vos://example.com!vospace/mydata1</vos:target>
  <vos:direction>pushToVoSpace</vos:direction>
  <vos:protocol uri="ivo://ivoa.net/vospace/core#httpput">
    <vos:endpoint>http://storage1.example.com/trans/mydata1</vos:endpoint>
  </vos:protocol>
  <vos:protocol uri="ivo://ivoa.net/vospace/core#httpput">
    <vos:endpoint>http://storage2.example.com/mydata1</vos:endpoint>
  </vos:protocol>
</vos:transfer>
\end{lstlisting}

\subsubsection{pullToVoSpace}
\label{subsubsec:pulltovospace}
Import data into a VOSpace node.

This method asks the server to fetch data from a remote location.

The data transfer is initiated by the VOSpace service and transferred direct into the target Node.

The data source can be another VOSpace service, or a standard HTTP or FTP server.

The primary use case for this method is transferring data from one server or service to another.

This operation is OPTIONAL.

\paragraph{Request}
A HTTP POST of a Job representation for the transfer to http://rest-endpoint/transfers

If a Node already exists at the target URI, then the data SHALL be imported into the existing Node and the Node properties SHALL be cleared unless the node is a ContainerNode.

If there is no Node at the target URI, then the service SHALL create a new Node using the URI, and the default xsi:type for the space.

\paragraph{Response}
The initial response is a HTTP 303 status code with the Location header keyword assigned to the created job.

During the byte transfer for the pullToVoSpace operation, the service SHOULD set the busy flag of the Node to true.

If the busy flag of the Node is already set to true, the service SHOULD respond with a NodeBusy fault.

\paragraph{Faults}\
For all faults, the service shall set the PHASE to ``ERROR'' in the Job representation. The \verb|<errorSummary>| element in the Job representation shall be set to the appropriate value for the fault type and the appropriate fault representation provided at the error URI: http://rest-endpoint/transfers/(jobid)/error.

\vspace{3mm}
\begin{tabular}{ p{5cm} l p{4cm} }
\textbf{Fault description} & \textbf{errorSummary} & \textbf{Fault representation} \\
\hline
Operation not supported & Operation Not Supported & OperationNotSupported \\
\hline
Operation fails & Internal Fault & InternalFault \\
\hline
User does not have permissions to perform the operation & Permission Denied & PermissionDenied \\
\hline
Service does not support the requested View & View Not Supported & ViewNotSupported \\
\hline
Service supports none of the requested Protocols & Protocol Not Supported &ProtocolNotSupported \\
\hline
Destination URI is invalid & Invalid URI & InvalidURI \\
\hline
A View parameter is invalid & Invalid Argument & InvalidArgument \\
\hline
A Protocol parameter is invalid & Invalid Argument & InvalidArgument \\
\hline
Data format does not match the requested View & Invalid Data & InvalidData \\
\hline
The busy flag of the Node is true & Node Busy & NodeBusy \\
\hline
\end{tabular}
\vspace{3mm}

\paragraph{Notes}
If the Job request contains more than one protocol parameter, then the service MAY fail over to use one or more of the options if the first one fails. The service SHOULD try each protocol option in turn until one succeeds or all have been tried.

\paragraph{Example}
pullToVoSpace
\\[5px]
\noindent
The Job to be submitted (pullToVoSpace.xml):
\begin{lstlisting}
<vos:transfer xmlns:vos="http://www.ivoa.net/xml/VOSpace/v2.0" version="2.1">
  <vos:target>vos://example.com!vospace/mydata1</vos:target>
  <vos:direction>pullToVoSpace</vos:direction>
  <vos:protocol uri="ivo://ivoa.net/vospace/core#httpput">
    <vos:endpoint>http://anotherserver.example.com/here/is/the/data</vos:endpoint>
  </vos:protocol>
</vos:transfer>
\end{lstlisting}
Request:
\begin{lstlisting}
> curl -v -X POST -d @pullToVoSpace.xml -H "Content-type: text/xml" "http://server.example.com/vospace/transfers"
\end{lstlisting}
Response:
\begin{lstlisting}
> POST /vospace/transfers HTTP/1.1
> Content-type: text/xml
>
< HTTP/1.1 303 See Other
< Location: http://server.example.com/vospace/transfers/m4ipu36gairz0dnl
< Content-Type: text/plain
<
* Closing connection #0
\end{lstlisting}
The PENDING job can be seen by following the redirect to:
\begin{lstlisting}
> curl -v http://server.example.com/vospace/transfers/m4ipu36gairz0dnl
\end{lstlisting}
Response:
\begin{lstlisting}
> GET /vospace/transfers/m4ipu36gairz0dnl HTTP/1.1
>
< HTTP/1.1 200 OK
< Content-Type: text/xml
<
<?xml version="1.0" encoding="UTF-8"?>
<uws:job xmlns:uws="http://www.ivoa.net/xml/UWS/v1.0" xmlns:xlink="http://www.w3.org/1999/xlink">
  <uws:jobId>m4ipu36gairz0dnl</uws:jobId>
  <uws:phase>PENDING</uws:phase>
  <uws:quote>2015-05-26T11:06:45.713</uws:quote>
  <uws:startTime xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xs:nil="true" />
  <uws:endTime xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xs:nil="true" />
  <uws:executionDuration>43200</uws:executionDuration>
  <uws:destruction>2015-06-01T23:06:45.713</uws:destruction>
  <uws:parameters />
  <uws:results />
  <uws:jobInfo>
    <vos:transfer xmlns:vos="http://www.ivoa.net/xml/VOSpace/v2.0" version="2.1">
      <vos:target>vos://example.com!vospace/mydata1</vos:target>
      <vos:direction>pullToVoSpace</vos:direction>
      <vos:protocol uri="ivo://ivoa.net/vospace/core#httpput">
        <vos:endpoint>http://anotherserver.example.com/here/is/the/data</vos:endpoint>
      </vos:protocol>
    </vos:transfer>
  </uws:jobInfo>
</uws:job>
\end{lstlisting}
The job can now be started by posting PHASE=RUN:
\begin{lstlisting}
curl -v -X POST -d "PHASE=RUN" http://server.example.com/vospace/transfers/m4ipu36gairz0dnl/phase
\end{lstlisting}
Response:
\begin{lstlisting}
> POST /vospace/transfers/m4ipu36gairz0dnl/phase HTTP/1.1
> Content-Type: text/xml
>
< HTTP/1.1 303 See Other
< Location: http://server.examle.com/vospace/transfers/m4ipu36gairz0dnl
< Content-Type: text/plain
<
\end{lstlisting}
The EXECUTING job can be seen by following the redirect to:
\begin{lstlisting}
http://server.examle.com/vospace/transfers/m4ipu36gairz0dnl
\end{lstlisting}
Response:
\begin{lstlisting}
> GET /vospace/transfers/m4ipu36gairz0dnl HTTP/1.1
>
< HTTP/1.1 200 OK
< Content-Type: text/xml
<
<?xml version="1.0" encoding="UTF-8"?>
<uws:job xmlns:uws="http://www.ivoa.net/xml/UWS/v1.0" xmlns:xlink="http://www.w3.org/1999/xlink">
  <uws:jobId>m4ipu36gairz0dnl</uws:jobId>
  <uws:phase>EXECUTING</uws:phase>
  <uws:quote>2015-05-26T11:06:45.713</uws:quote>
  <uws:startTime>2015-05-25T23:17:41.217</uws:startTime>
  <uws:endTime xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xs:nil="true" />
  <uws:executionDuration>43200</uws:executionDuration>
  <uws:destruction>2015-06-01T23:06:45.713</uws:destruction>
  <uws:parameters />
  <uws:results>
    <uws:result id="transferDetails" xlink:href="http://server.example.com/vospace/transfers/m4ipu36gairz0dnl/results/transferDetails" />
    <uws:result id="dataNode" xlink:href="vos://example.com!vospace/mydata1" />
  </uws:results>
  <uws:jobInfo>
    <vos:transfer xmlns:vos="http://www.ivoa.net/xml/VOSpace/v2.0" version="2.1">
      <vos:target>vos://example.com!vospace/mydata1</vos:target>
      <vos:direction>pullToVoSpace</vos:direction>
      <vos:protocol uri="ivo://ivoa.net/vospace/core#httpput">
        <vos:endpoint>http://anotherserver.example.com/here/is/the/data</vos:endpoint>
      </vos:protocol>
    </vos:transfer>
  </uws:jobInfo>
</uws:job>
\end{lstlisting}

\subsubsection{pullFromVoSpace}
\label{subsubsec:pullfromvospace}
Request a set of URLs that the client can read data from.

The client requests access to the data in a Node, and the server SHALL respond with a set of URLs that the client can read the data from.

\paragraph{Request}
A HTTP POST of a Job representation for the transfer to http://rest-endpoint/transfers or http://rest-endpoint/synctrans.
The transfer representation SHOULD contain details of the View and a list of the Protocols that the client would like to use.

The list of Protocols SHOULD not contain endpoint addresses; the service SHALL supply the endpoint addresses in the response.

The service SHALL ignore any of the requested protocols and security methods that it does not understand or is unable to support.

A pullFromVoSpace transfer may be initiated with an HTTP POST of a Job representation of the transfer to http://rest-endpoint/transfers. The service SHALL respond with a redirect to the newly created job.  (See Example 1)

A pullFromVoSpace transfer may be initiated with an HTTP POST of a Job representation of the transfer to http://rest-endpoint/synctrans. The service SHALL respond with a redirect to the transfer details of the job.  (See Example 2)

A pullFromVoSpace transfer may be initiated with an HTTP POST or GET to http://rest-endpoint/synctrans with the following URL query parameters:
\begin{itemize}
    \item \emph{TARGET}: The value is the URI of the target node
        \begin{itemize}
           \item Example:  vos://example.com$\mathtt{\sim}$vospace/mydata1
        \end{itemize}
    \item \emph{DIRECTION}: pullFromVoSpace
    \item \emph{PROTOCOL}: The standard URI of the protocol to use (see section ~\ref{subsubsec:standard protocols})
        \begin{itemize}
           \item Example: ivo://ivoa.net/vospace/core\#httpget
        \end{itemize}
\end{itemize}

The following optional parameters may also be included:
\begin{itemize}
    \item \emph{VIEW}: The standard URI of the view to use
        \begin{itemize}
           \item Example:  ivo://ivoa.net/vospace/core\#cutoutview
        \end{itemize}
    \item \emph{SECURITYMETHOD}: The standard URI of the security method to use
        \begin{itemize}
           \item Example:  ivo://ivoa.net/sso\#tls-with-certificate
        \end{itemize}
    \item \emph{REQUEST=redirect}: If supplied, the service will issue an immediate redirect to the preferred endpoint matching the transfer request.     
\end{itemize}

The service SHALL respond with the job containing the transfer results in the response body.  (See Example 3)
If the parameter key value REQUEST=redirect is included with the other transfer parameters, the service SHALL respond with an immediate redirect to the preferred protocol endpoint for data download.  (See Example 4)

There is also an alternate convenience mode of for full data download using view=data on the http://rest-endpoint/nodes resource (This alternative is now deprecated and will be removed in v3.0.  This convenience mode has been replaced with the REQUEST=redirect functionality)
\begin{itemize}
    \item A HTTP GET to the node URL that wants to be read with a parameter of "view = data": \\*
        http://rest-endpoint/nodes/path?view=data
\end{itemize}

Clients may also use the "view" parameter on the getNode operation. Services may support different types of views for particular purposes. e.g., "view=rss" to identify a RSS feed on the resource.

\paragraph{Response}
The initial response for the UWS mode is a HTTP 303 status code with the Location header keyword assigned to the created job
The service SHALL select which of the requested Protocols it is willing to provide and fill in the operational details for each one in the transfer result representation -- this SHOULD normally include specifying the source URL of the transfer protocol endpoint.

The service response SHOULD not include any Protocols that it is unable to support.

If the busy flag of the Node is set to true, the service MAY respond with a NodeBusy fault.

The transfer results representation can be retrieved directly from the link reported in the Results List, available either from the results endpoint -- http://rest-endpoint/transfers/(jobid)/results -- or as part of the full Job representation for the completed transfer available from http://rest-endpoint/transfers/(jobid). In the latter case, the result element in the Results List SHALL have an id of ``transferDetails'':
\begin{lstlisting}
<uws:job>
...
  <uws:results>
   <uws:result id="transferDetails" xlink:href="http://rest-endpoint/transfers/(jobid)/results/transferDetails"/>
  </uws:results>
...
< /uws:job>
\end{lstlisting}
If the transfer was initiated with a HTTP POST to http://rest-endpoint/sync then the response is:
\begin{itemize}
    \item A HTTP 303 status code with the Location header keyword assigned to the endpoint: http://rest-endpoint/transfers/(jobid)/results/transferDetails.
\end{itemize}
The HTTP 303 redirect points to a transfer representation with the required transfer details and endpoints.
If the transfer was initiated with a HTTP POST to http://rest-endpoint/sync with transfer information TARGET, DIRECTION, and PROTOCOL supplied as query string parameters, the service may respond with the transfer details directly. If the parameter REQUEST=redirect is also provided in this POST, then the service may respond with a redirect to a preferred endpoint (example below).

\paragraph{Faults}
For all faults using the UWS mode, the service shall set the PHASE to ``ERROR'' in the Job representation. The \verb|<errorSummary>| element in the Job representation shall be set to the appropriate value for the fault type and the appropriate fault representation provided at the error URI: http://rest-endpoint/transfers/(jobid)/error.

\vspace{3mm}
\begin{tabular}{ p{5cm} l p{4cm} }
\textbf{Fault description} & \textbf{errorSummary} & \textbf{Fault representation} \\
\hline
Operation fails & Internal Fault & InternalFault \\
\hline
User does not have permissions to perform the operation	 & Permission Denied & PermissionDenied \\
\hline
Source Node does not exist & Node Not Found & NodeNotFound \\
\hline
Service does not support the requested View & View Not Supported & ViewNotSupported \\
\hline
Service supports none of the requested Protocols & Protocol Not Supported &ProtocolNotSupported \\
\hline
Destination URI is invalid & Invalid URI & InvalidURI \\
\hline
A View parameter is invalid & Invalid Argument & InvalidArgument \\
\hline
A Protocol parameter is invalid & Invalid Argument & InvalidArgument \\
\hline
The busy flag of the Node is true & Node Busy & NodeBusy \\
\hline
\end{tabular}
\vspace{3mm}

If an error occurs with the synchronous convenience mode, the resulting transfers document SHOULD have no protocols. The client can then retrieve the Job representation for error information as with asynchronous transfers.

If an error occurs with the synchronous convenience mode where the preferred endpoint is immediately returned as a redirect, the error information is returned directly in the response body with the associated HTTP status code.

\paragraph{Notes}
The endpoint URLs supplied in the UWS response SHOULD be considered as 'one shot' URLs. A VOSpace service connected to a standard web server MAY return the public URL for the data. However, a different implementation MAY create a unique single use URL specifically for this transfer.

\paragraph{Example 1}
pullFromVoSpace over the asynchronous endpoint
\\[5px]
\noindent
The Job to be submitted (pullFromVoSpace.xml):
\begin{lstlisting}
<vos:transfer xmlns:vos="http://www.ivoa.net/xml/VOSpace/v2.0" version="2.1">
  <vos:target>vos://example.com!vospace/mydata1</vos:target>
  <vos:direction>pullFromVoSpace</vos:direction>
  <vos:protocol uri="ivo://ivoa.net/vospace/core#httpget" />
</vos:transfer>
\end{lstlisting}
Request:
\begin{lstlisting}
> curl -v -X POST -d @pullFromVoSpace.xml -H "Content-type: text/xml" "http://server.example.com/vospace/transfers"
\end{lstlisting}
Response:
\begin{lstlisting}
> POST /vospace/transfers HTTP/1.1
> Content-type: text/xml
>
< HTTP/1.1 303 See Other
< Location: http://server.example.com/vospace/transfers/m4ipu36gairz0dnl
< Content-Type: text/plain
<
* Closing connection #0
\end{lstlisting}
The PENDING job can be seen by following the redirect to:
\begin{lstlisting}
> curl -v http://server.example.com/vospace/transfers/m4ipu36gairz0dnl
\end{lstlisting}
Response:
\begin{lstlisting}
> GET /vospace/transfers/m4ipu36gairz0dnl HTTP/1.1
>
< HTTP/1.1 200 OK
< Content-Type: text/xml
<
<?xml version="1.0" encoding="UTF-8"?>
<uws:job xmlns:uws="http://www.ivoa.net/xml/UWS/v1.0" xmlns:xlink="http://www.w3.org/1999/xlink">
  <uws:jobId>m4ipu36gairz0dnl</uws:jobId>
  <uws:phase>PENDING</uws:phase>
  <uws:quote>2015-05-26T11:06:45.713</uws:quote>
  <uws:startTime xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xs:nil="true" />
  <uws:endTime xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xs:nil="true" />
  <uws:executionDuration>43200</uws:executionDuration>
  <uws:destruction>2015-06-01T23:06:45.713</uws:destruction>
  <uws:parameters />
  <uws:results />
  <uws:jobInfo>
    <vos:transfer xmlns:vos="http://www.ivoa.net/xml/VOSpace/v2.0" version="2.1">
      <vos:target>vos://example.com!vospace/mydata1</vos:target>
      <vos:direction>pullFromVoSpace</vos:direction>
      <vos:protocol uri="ivo://ivoa.net/vospace/core#httpget" />
    </vos:transfer>
  </uws:jobInfo>
</uws:job>
\end{lstlisting}
The job can now be started by posting PHASE=RUN:
\begin{lstlisting}
curl -v -X POST -d "PHASE=RUN" http://server.example.com/vospace/transfers/m4ipu36gairz0dnl/phase
\end{lstlisting}
Response:
\begin{lstlisting}
> POST /vospace/transfers/m4ipu36gairz0dnl/phase HTTP/1.1
> Content-Type: text/xml
>
< HTTP/1.1 303 See Other
< Location: http://server.examle.com/vospace/transfers/m4ipu36gairz0dnl
< Content-Type: text/plain
<
\end{lstlisting}
The EXECUTING job can be seen by following the redirect to:
\begin{lstlisting}
http://server.examle.com/vospace/transfers/m4ipu36gairz0dnl
\end{lstlisting}
Response:
\begin{lstlisting}
> GET /vospace/transfers/m4ipu36gairz0dnl HTTP/1.1
>
< HTTP/1.1 200 OK
< Content-Type: text/xml
<
<?xml version="1.0" encoding="UTF-8"?>
<uws:job xmlns:uws="http://www.ivoa.net/xml/UWS/v1.0" xmlns:xlink="http://www.w3.org/1999/xlink">
  <uws:jobId>m4ipu36gairz0dnl</uws:jobId>
  <uws:phase>EXECUTING</uws:phase>
  <uws:quote>2015-05-26T11:06:45.713</uws:quote>
  <uws:startTime>2015-05-25T23:17:41.217</uws:startTime>
  <uws:endTime xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xs:nil="true" />
  <uws:executionDuration>43200</uws:executionDuration>
  <uws:destruction>2015-06-01T23:06:45.713</uws:destruction>
  <uws:parameters />
  <uws:results>
    <uws:result id="transferDetails" xlink:href="http://server.example.com/vospace/transfers/m4ipu36gairz0dnl/results/transferDetails" />
    <uws:result id="dataNode" xlink:href="vos://example.com!vospace/mydata1" />
  </uws:results>
  <uws:jobInfo>
    <vos:transfer xmlns:vos="http://www.ivoa.net/xml/VOSpace/v2.0" version="2.1">
      <vos:target>vos://example.com!vospace/mydata1</vos:target>
      <vos:direction>pullFromVoSpace</vos:direction>
      <vos:protocol uri="ivo://ivoa.net/vospace/core#httpget" />
    </vos:transfer>
  </uws:jobInfo>
</uws:job>
\end{lstlisting}
The details of the transfer negotiation can be see by following the \emph{transferDetails} result:
\begin{lstlisting}
> curl -v http://server.example.com/vospace/transfers/m4ipu36gairz0dnl/results/transferDetails
\end{lstlisting}
Response:
\begin{lstlisting}
> GET /vospace/transfers/m4ipu36gairz0dnl/results/transferDetails HTTP/1.1
>
< HTTP/1.1 200 OK
< Content-Type: text/xml
<
<?xml version="1.0" encoding="UTF-8"?>
<vos:transfer xmlns:vos="http://www.ivoa.net/xml/VOSpace/v2.0" version="2.1">
  <vos:target>vos://example.com!vospace/mydata1</vos:target>
  <vos:direction>pullFromVoSpace</vos:direction>
  <vos:protocol uri="ivo://ivoa.net/vospace/core#httpget">
    <vos:endpoint>http://storage1.example.com/trans/mydata1</vos:endpoint>
  </vos:protocol>
  <vos:protocol uri="ivo://ivoa.net/vospace/core#httpget">
    <vos:endpoint>http://storage2.example.com/mydata1</vos:endpoint>
  </vos:protocol>
</vos:transfer>
\end{lstlisting}
The file can now be retrieved over HTTP GET from one of the endpoints listed in the transfer details.
\begin{lstlisting}
> curl -v -o mydata1 "http://storage1.example.com/mydata1"
\end{lstlisting}
Response:
\begin{lstlisting}
> GET /mydata1 HTTP/1.1
>
< HTTP/1.1 200 OK
< Content-Type: text/plain
<
[data not shown]
\end{lstlisting}
On successful file transfer completion the job will be COMPLETED:
\begin{lstlisting}
curl -v http://server.examle.com/vospace/transfers/m4ipu36gairz0dnl/phase
\end{lstlisting}
Response:
\begin{lstlisting}
> GET /vospace/transfers/m4ipu36gairz0dnl/phase HTTP/1.1
>
< HTTP/1.1 200 OK
< Content-Type: text/plain
<
COMPLETED
\end{lstlisting}
\paragraph{Example 2}
pullFromVoSpace over the synchronous endpoint
\\[5px]
\noindent
The Job to be submitted (pullFromVoSpace.xml):
\begin{lstlisting}
<vos:transfer xmlns:vos="http://www.ivoa.net/xml/VOSpace/v2.0" version="2.1">
  <vos:target>vos://example.com!vospace/mydata1</vos:target>
  <vos:direction>pullFromVoSpace</vos:direction>
  <vos:protocol uri="ivo://ivoa.net/vospace/core#httpget" />
</vos:transfer>
\end{lstlisting}
Request:
\begin{lstlisting}
> curl -v -X POST -d @pullFromVoSpace.xml -H "Content-type: text/xml" "http://server.example.com/vospace/synctrans"
\end{lstlisting}
Response:
\begin{lstlisting}
> POST /vospace/synctrans HTTP/1.1
> Content-Type: text/xml
>
< HTTP/1.1 303 See Other
< Location: http://server.example.com/vospace/transfers/m4ipu36gairz0dnl/results/transferDetails
< Content-Type: text/plain
<
\end{lstlisting}
The negotiated transfer details can be seen by following the redirect to:
\begin{lstlisting}
http://server.examlpe.com/vospace/transfers/m4ipu36gairz0dnl/results/transferDetails
\end{lstlisting}
Request:
\begin{lstlisting}
> curl -v http://server.example.com/vospace/transfers/m4ipu36gairz0dnl/results/transferDetails
\end{lstlisting}
Response:
\begin{lstlisting}
> GET /vospace/transfers/m4ipu36gairz0dnl/results/transferDetails HTTP/1.1
>
< HTTP/1.1 200 OK
< Content-Type: text/xml
<
<?xml version="1.0" encoding="UTF-8"?>
<vos:transfer xmlns:vos="http://www.ivoa.net/xml/VOSpace/v2.0" version="2.1">
  <vos:target>vos://example.com!vospace/mydata1</vos:target>
  <vos:direction>pullFromVoSpace</vos:direction>
  <vos:protocol uri="ivo://ivoa.net/vospace/core#httpget">
    <vos:endpoint>http://storage1.example.com/trans/mydata1</vos:endpoint>
  </vos:protocol>
  <vos:protocol uri="ivo://ivoa.net/vospace/core#httpget">
    <vos:endpoint>http://storage2.example.com/mydata1</vos:endpoint>
  </vos:protocol>
</vos:transfer>
\end{lstlisting}
The file can be retrieved with an HTTP GET to one of the endpoints:
\begin{lstlisting}
curl -v -o mydata1 http://storage1.example.com/mydata1
\end{lstlisting}
Response:
\begin{lstlisting}
> GET /mydata1 HTTP/1.1
>
< HTTP/1.1 200 OK
< Content-Type: text/plain
<
 [data not shown]
\end{lstlisting}

\paragraph{Example 3}
pullFromVoSpace over the synchronous endpoint with securityMethod
\\[5px]
\noindent
A transfer request for endpoints supporting basic authentication over HTTP or TLS with a client certificate over SSL.\\
The Job to be submitted (pullFromVoSpace.xml):
\begin{lstlisting}
<vos:transfer xmlns:vos="http://www.ivoa.net/xml/VOSpace/v2.0" version="2.1">
  <vos:target>vos://example.com!vospace/mydata1</vos:target>
  <vos:direction>pullFromVoSpace</vos:direction>
  <vos:protocol uri="ivo://ivoa.net/vospace/core#httpsget">
      <vos:securityMethod uri="ivo://ivoa.net/sso#tls-with-certificate"/>
  </vos:protocol>
  <vos:protocol uri="ivo://ivoa.net/vospace/core#httpget">
      <vos:securityMethod uri="uri="http://www.w3.org/Protocols/HTTP/1.0/spec/html#BasicAA"/>
  </vos:protocol>
</vos:transfer>
\end{lstlisting}
Request:
\begin{lstlisting}
> curl -v -X POST -d @pullFromVoSpace.xml -H "Content-type: text/xml" "http://server.example.com/vospace/synctrans"
\end{lstlisting}
Response:
\begin{lstlisting}
> POST /vospace/synctrans HTTP/1.1
> Content-Type: text/xml
>
< HTTP/1.1 303 See Other
< Location: http://server.example.com/vospace/transfers/zkqzpftmufdi8luh/results/transferDetails
< Content-Type: text/plain
<
\end{lstlisting}
The negotiated transfer details can be seen by following the redirect to:
\begin{lstlisting}
http://server.examlpe.com/vospace/transfers/zkqzpftmufdi8luh/results/transferDetails
\end{lstlisting}
Request:
\begin{lstlisting}
> curl -v http://server.example.com/vospace/transfers/zkqzpftmufdi8luh/results/transferDetails
\end{lstlisting}
Response:
\begin{lstlisting}
> GET /vospace/transfers/zkqzpftmufdi8luh/results/transferDetails HTTP/1.1
>
< HTTP/1.1 200 OK
< Content-Type: text/xml
<
<?xml version="1.0" encoding="UTF-8"?>
<vos:transfer xmlns:vos="http://www.ivoa.net/xml/VOSpace/v2.0" version="2.1">
  <vos:target>vos://example.com!vospace/mydata1</vos:target>
  <vos:direction>pullFromVoSpace</vos:direction>
  <vos:protocol uri="ivo://ivoa.net/vospace/core#httpsget">
    <vos:endpoint>https://storage1.example.com/trans/mydata1</vos:endpoint>
    <vos:securityMethod uri="ivo://ivoa.net/sso#tls-with-certificate"/>
  </vos:protocol>
</vos:transfer>
\end{lstlisting}
The service has replied with a single HTTPS endpoint that support TLS with client certificates.\\
The file can be retrieved with an HTTPS GET to the endpoint:
\begin{lstlisting}
curl -v -o mydata1 -E mycert.pem https://storage1.example.com/mydata1
\end{lstlisting}
Response:
\begin{lstlisting}
> GET /mydata1 HTTP/1.1
>
< HTTP/1.1 200 OK
< Content-Type: text/plain
<
 [data not shown]
\end{lstlisting}

\paragraph{Example 4}
pullFromVoSpace over the synchronous endpoint with URL parameters
\\[5px]
\noindent
Request:
\begin{lstlisting}
curl -v -X POST "http://server.example.com/vospace/synctrans?TARGET=vos://example.com~vospace/mydata1&DIRECTION=pullFromVoSpace&PROTOCOL=ivo://ivoa.net/vospace/core%23httpget"
\end{lstlisting}
(Note that the \# sign in PROTOCOL is URL encoded as \%23 and that the alternate separator `$\mathtt{\sim}$' is used instead of `!' in the TARGET) \\
\\
Response:
\begin{lstlisting}
> POST /vospace/synctrans?TARGET=vos://example.com~vospace/mydata1&DIRECTION=pullFromVoSpace&PROTOCOL=ivo://ivoa.net/vospace/core\%23httpget HTTP/1.1
>
< HTTP/1.1 200 OK
< Content-Type: text/xml
<
<?xml version="1.0" encoding="UTF-8"?>
<vos:transfer xmlns:vos="http://www.ivoa.net/xml/VOSpace/v2.0" version="2.1">
  <vos:target>vos://example.com!vospace/mydata1</vos:target>
  <vos:direction>pullFromVoSpace</vos:direction>
  <vos:protocol uri="ivo://ivoa.net/vospace/core#httpget">
    <vos:endpoint>http://storage1.example.com/trans/mydata1</vos:endpoint>
  </vos:protocol>
  <vos:protocol uri="ivo://ivoa.net/vospace/core#httpget">
    <vos:endpoint>http://storage2.example.com/mydata1</vos:endpoint>
  </vos:protocol>
</vos:transfer>
\end{lstlisting}
The file can be retrieved with an HTTP GET to one of the endpoints:
\begin{lstlisting}
curl -v -o mydata1 http://storage1.example.com/mydata1
\end{lstlisting}
Response:
\begin{lstlisting}
> GET /mydata1 HTTP/1.1
>
< HTTP/1.1 200 OK
< Content-Type: text/plain
<
 [data not shown]
 \end{lstlisting}

\paragraph{Example 5}
pullFromVoSpace over the synchronous endpoint with URL parameters and REQUEST=redirect
\\[5px]
\noindent
Request:
\begin{lstlisting}
curl -v -X POST "http://server.example.com/vospace/synctrans?TARGET=vos://example.com~vospace/mydata1&DIRECTION=pullFromVoSpace&PROTOCOL=ivo://ivoa.net/vospace/core%23httpget&REQUEST=redirect"
\end{lstlisting}
(Note that the \# sign in PROTOCOL is URL encoded as \%23 and the alternate separator `$\mathtt{\sim}$' is used instead of `!' in the TARGET) \\
\\
Response:
\begin{lstlisting}
> POST /vospace/synctrans?TARGET=vos://example.com~vospace/mydata1&DIRECTION=pullFromVoSpace&PROTOCOL=ivo://ivoa.net/vospace/core\%23httpget&REQUEST=redirect HTTP/1.1
<
< HTTP/1.1 303 See Other
< Location: http://storage1.example.com/mydata1
< Content-Type: text/plain
<
\end{lstlisting}
The file can be retrieved by following the redirect:
\begin{lstlisting}
curl -v -o mydata1 http://storage1.example.com/mydata1
\end{lstlisting}
Response:
\begin{lstlisting}
> GET /mydata1 HTTP/1.1
>
< HTTP/1.1 200 OK
< Content-Type: text/plain
<
 [data not shown]
\end{lstlisting}

\paragraph{Example 6}
pullFromVoSpace over the synchronous endpoint with URL parameters, REQUEST=redirect and securityMethod
\\[5px]
\noindent
Request:
\begin{lstlisting}
curl -v -X POST -E mycert.pem "https://server.example.com/vospace/synctrans?TARGET=vos://example.com~vospace/mydata1&DIRECTION=pullFromVoSpace&PROTOCOL=ivo://ivoa.net/vospace/core%23httpsget&REQUEST=redirect&SECURITYMETHOD=ivo://ivoa.net/sso%23tls-with-certificate"
\end{lstlisting}
Since the expected response is a redirect, the initial protocol on the post is HTTPS and the certificate is supplied.\\*
(Note that the \# sign in PROTOCOL is URL encoded as \%23 and that the alternate separator `$\mathtt{\sim}$' is used instead of `!' in the TARGET) \\
\\
Response:
\begin{lstlisting}
> POST /vospace/synctrans?TARGET=vos://example.com~vospace/mydata1&DIRECTION=pullFromVoSpace&PROTOCOL=ivo://ivoa.net/vospace/core\%23httpget&REQUEST=redirect&SECURITYMETHOD=ivo://ivoa.net/sso%23tls-with-certificate HTTP/1.1
>
< HTTP/1.1 303 See Other
< Location: https://storage1.example.com/mydata1
< Content-Type: text/plain
<
\end{lstlisting}
The file can be retrieved by following the redirect:
\begin{lstlisting}
curl -v -o mydata1 -E mycert.pem https://storage1.example.com/mydata1
\end{lstlisting}
Response:
\begin{lstlisting}
> GET /mydata1 HTTP/1.1
>
< HTTP/1.1 200 OK
< Content-Type: text/plain
<
 [data not shown]
\end{lstlisting}

\subsubsection{pushFromVoSpace}
\label{subsubsec:pushfromvospace}
Ask the server to send data to a remote location.

The client supplies a list of URLs and asks the server to send the data to the remote location.

The transfer is initiated by the server, and the data transferred direct from the server to the remote location.

This operation is OPTIONAL.

\paragraph{Request}
A HTTP POST of a Job representation for the transfer to http://rest-endpoint/transfers

\paragraph{Response}
The initial response is a HTTP 303 status code with the Location header keyword assigned to the created job.

If the busy flag of the target Node is set to true, the service MAY respond with a NodeBusy fault.

5.4.4.3 Faults

\vspace{3mm}
\begin{tabular}{ p{5cm} l p{4cm} }
\textbf{Fault description} & \textbf{errorSummary} & \textbf{Fault representation} \\
\hline
Operation not supported & Operation Not Supported & OperationNotSupported \\
\hline
Operation fails & Internal Fault & InternalFault \\
\hline
User does not have permissions to perform the operation	 & Permission Denied & PermissionDenied \\
\hline
Source Node does not exist & Node Not Found & NodeNotFound \\
\hline
Service does not support the requested View & View Not Supported & ViewNotSupported \\
\hline
Service supports none of the requested Protocols & Protocol Not Supported &ProtocolNotSupported \\
\hline
Destination URI is invalid & Invalid URI & InvalidURI \\
\hline
A View parameter is invalid & Invalid Argument & InvalidArgument \\
\hline
A Protocol parameter is invalid & Invalid Argument & InvalidArgument \\
\hline
Data transfer does not complete & Transfer Failed & TransferFailed \\
\hline
The busy flag of the Node is true & Node Busy & NodeBusy \\
\hline
\end{tabular}
\vspace{3mm}

\paragraph{Notes}
If the Job request contains more than one protocol parameter then the service MAY fail over to use one or more of the options if the first one fails. The service SHOULD try each protocol option in turn until one succeeds or all have been tried.

\paragraph{Example}
pushFromVoSpace
\\[5px]
\noindent
The Job to be submitted (pushFromVoSpace.xml):
\begin{lstlisting}
<vos:transfer xmlns:vos="http://www.ivoa.net/xml/VOSpace/v2.0" version="2.1">
  <vos:target>vos://example.com!vospace/mydata1</vos:target>
  <vos:direction>pushFromVoSpace</vos:direction>
  <vos:protocol uri="ivo://ivoa.net/vospace/core#httpput">
    <vos:endpoint>http://anotherserver1.example.com/put/the/data/here</vos:endpoint>
  </vos:protocol>
  <vos:protocol uri="ivo://ivoa.net/vospace/core#httpput">
    <vos:endpoint>http://anotherserver2.example.com/put/the/data/here</vos:endpoint>
  </vos:protocol>
</vos:transfer>
\end{lstlisting}
Request:
\begin{lstlisting}
> curl -v -X POST -d @pushFromVoSpace.xml -H "Content-type: text/xml" "http://server.example.com/vospace/transfers"
\end{lstlisting}
Response:
\begin{lstlisting}
> POST /vospace/transfers HTTP/1.1
> Content-type: text/xml
>
< HTTP/1.1 303 See Other
< Location: http://server.example.com/vospace/transfers/m4ipu36gairz0dnl
< Content-Type: text/plain
<
* Closing connection #0
\end{lstlisting}
The PENDING job can be seen by following the redirect to:
\begin{lstlisting}
> curl -v http://server.example.com/vospace/transfers/m4ipu36gairz0dnl
\end{lstlisting}
Response:
\begin{lstlisting}
> GET /vospace/transfers/m4ipu36gairz0dnl HTTP/1.1
>
< HTTP/1.1 200 OK
< Content-Type: text/xml
<
<?xml version="1.0" encoding="UTF-8"?>
<uws:job xmlns:uws="http://www.ivoa.net/xml/UWS/v1.0" xmlns:xlink="http://www.w3.org/1999/xlink">
  <uws:jobId>m4ipu36gairz0dnl</uws:jobId>
  <uws:phase>PENDING</uws:phase>
  <uws:quote>2015-05-26T11:06:45.713</uws:quote>
  <uws:startTime xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xs:nil="true" />
  <uws:endTime xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xs:nil="true" />
  <uws:executionDuration>43200</uws:executionDuration>
  <uws:destruction>2015-06-01T23:06:45.713</uws:destruction>
  <uws:parameters />
  <uws:results />
  <uws:jobInfo>
    <vos:transfer xmlns:vos="http://www.ivoa.net/xml/VOSpace/v2.0" version="2.1">
      <vos:target>vos://example.com!vospace/mydata1</vos:target>
      <vos:direction>pushFromVoSpace</vos:direction>
      <vos:protocol uri="ivo://ivoa.net/vospace/core#httpput">
        <vos:endpoint>http://anotherserver1.example.com/put/the/data/here</vos:endpoint>
      </vos:protocol>
      <vos:protocol uri="ivo://ivoa.net/vospace/core#httpput">
        <vos:endpoint>http://anotherserver2.example.com/put/the/data/here</vos:endpoint>
      </vos:protocol>
    </vos:transfer>
  </uws:jobInfo>
</uws:job>
\end{lstlisting}
The job can now be started by posting PHASE=RUN:
\begin{lstlisting}
curl -v -X POST -d "PHASE=RUN" http://server.example.com/vospace/transfers/m4ipu36gairz0dnl/phase
\end{lstlisting}
Response:
\begin{lstlisting}
> POST /vospace/transfers/m4ipu36gairz0dnl/phase HTTP/1.1
> Content-Type: text/xml
>
< HTTP/1.1 303 See Other
< Location: http://server.examle.com/vospace/transfers/m4ipu36gairz0dnl
< Content-Type: text/plain
<
\end{lstlisting}
The EXECUTING job can be seen by following the redirect to:
\begin{lstlisting}
http://server.examle.com/vospace/transfers/m4ipu36gairz0dnl
\end{lstlisting}
Response:
\begin{lstlisting}
> GET /vospace/transfers/m4ipu36gairz0dnl HTTP/1.1
>
< HTTP/1.1 200 OK
< Content-Type: text/xml
<
<?xml version="1.0" encoding="UTF-8"?>
<uws:job xmlns:uws="http://www.ivoa.net/xml/UWS/v1.0" xmlns:xlink="http://www.w3.org/1999/xlink">
  <uws:jobId>m4ipu36gairz0dnl</uws:jobId>
  <uws:phase>EXECUTING</uws:phase>
  <uws:quote>2015-05-26T11:06:45.713</uws:quote>
  <uws:startTime>2015-05-25T23:17:41.217</uws:startTime>
  <uws:endTime xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xs:nil="true" />
  <uws:executionDuration>43200</uws:executionDuration>
  <uws:destruction>2015-06-01T23:06:45.713</uws:destruction>
  <uws:parameters />
  <uws:results>
    <uws:result id="transferDetails" xlink:href="http://server.example.com/vospace/transfers/m4ipu36gairz0dnl/results/transferDetails" />
    <uws:result id="dataNode" xlink:href="vos://example.com!vospace/mydata1" />
  </uws:results>
  <uws:jobInfo>
    <vos:transfer xmlns:vos="http://www.ivoa.net/xml/VOSpace/v2.0" version="2.1">
      <vos:target>vos://example.com!vospace/mydata1</vos:target>
      <vos:direction>pushFromVoSpace</vos:direction>
      <vos:protocol uri="ivo://ivoa.net/vospace/core#httpput">
        <vos:endpoint>http://anotherserver1.example.com/put/the/data/here</vos:endpoint>
      </vos:protocol>
      <vos:protocol uri="ivo://ivoa.net/vospace/core#httpput">
        <vos:endpoint>http://anotherserver2.example.com/put/the/data/here</vos:endpoint>
      </vos:protocol>
    </vos:transfer>
  </uws:jobInfo>
</uws:job>
\end{lstlisting}

\subsection{Fault arguments}
\label{subsec:fault arguments}
Faults reported by a VOSpace service SHALL contain the following information:

\paragraph{InternalFault}
This is thrown with a description of the cause of the fault.

\paragraph{PermissionDenied}
This is thrown with a description of why the credentials (if any were provided) were rejected.

\paragraph{InvalidURI}
This is thrown with details of the invalid URI.

\paragraph{NodeNotFound}
This is thrown with the URI of the missing Node.

\paragraph{DuplicateNode}
This is thrown with the URI of the duplicate Node.

\paragraph{InvalidToken}
This is thrown with the invalid token.

\paragraph{InvalidArgument}
This is thrown with a description of the invalid argument, including the View or Protocol URI and the name and value of the parameter that caused the fault.

\paragraph{TypeNotSupported}
This is thrown with the QName of the unsupported type.

\paragraph{ViewNotSupported}
This is thrown with the URI of the View.

\paragraph{InvalidData}
This is thrown with any error message that the data parser produced.

\paragraph{LinkFoundFault}
The fault details must contain the full details of the LinkNode.

\paragraph{NodeBusy}
This is thrown when a node is not in a state to perform the requested operation.

\appendix

\section{Machine readable definitions}
\label{sec:machine readable definitions}
\subsection{Message schema}
\label{subsec:message schema}
The requests and responses of a VOSpace 2.1 service shall adhere to the following XML Schema:

\lstinputlisting{VOSpace-2.1.xsd}

\section{Compliance matrix}
\label{sec:compliance matrix}
This table summarizes the mandatory behaviour required of a fully compliant VOSpace 2.1 service, i.e., those operations denoted as SHALL and MUST occurring. Note that for faults the general condition is specified but specific details should be checked in the relevant sections. Those associated with optional features are marked with an asterisk in the appropriate section reference -- if the service implements an optional feature then it must show this mandatory behaviour.

\hskip-2.0cm\begin{tabular}{ | p {1cm} | p {11cm} | p {4cm} | }
\hline
\textbf{Item} & \textbf{Description} & \textbf{Occurs in section(s)} \\ \hline
1 & VOSpace node identifiers are a URI with the scheme vos:// & ~\ref{sec:vospace identifiers} \\ \hline
2 & The naming authority for a VOSpace node URI is the VOSpace service through which the node was created & ~\ref{sec:vospace identifiers} \\ \hline
3 & "!" or "$\mathtt{\sim}$" are used consistently in VOSpace node URIs & ~\ref{sec:vospace identifiers} \\ \hline
4 & "!" or "$\mathtt{\sim}$" are valid separator characters in service requests & ~\ref{sec:vospace identifiers} \\ \hline
5 & All ancestors in a node hierarchy are resolvable as containers & ~\ref{sec:vospace identifiers} \\ \hline
6 & The bit pattern for data stored in an UnstructuredDataNode is identical for read/write operations & ~\ref{subsec:nodes and node types}* \\ \hline
7 & A Node has elements: uri, properties and capabilities & ~\ref{subsec:nodes and node types} \\ \hline
8 & A DataNode has elements: uri, properties, capabilities, accepts, provides & ~\ref{subsec:nodes and node types} \\ \hline
9 & A LinkNode has elements: uri, properties, capabilities and target & ~\ref{subsec:nodes and node types}* \\ \hline
10 & A ContainerNode and a LinkNode have no data bytes associated with them & ~\ref{subsec:nodes and node types}* \\ \hline
11 & A VOSpace service parses XML representations of all node types & ~\ref{subsec:nodes and node types} \\ \hline
12 & A VOSpace services does not throw a XML parser error in response to requests about unsupported node types & ~\ref{subsec:nodes and node types} \\ \hline
13 & A Property has elements:uri, endpoint and optional readonly flag & ~\ref{subsec:properties} \\ \hline
14 & URIs must be valid (and unique) & ~\ref{subsubsec:property identifiers}, ~\ref{subsubsec:capability identifiers}, ~\ref{subsubsec:view identifiers}, ~\ref{subsubsec:protocol identifiers}, ~\ref{subsubsec:createnode}, ~\ref{subsubsec:pushtovospace}, ~\ref{subsubsec:pulltovospace} \\ \hline
15 & A Capability has elements: uri, endpoint and param & ~\ref{subsec:capabilities} \\ \hline
16 & Standard capabilities are represented by the specified URIs & ~\ref{subsubsec:standard capabilities} \\ \hline
17 & Each Property is identified by a unique URI & ~\ref{subsubsec:property identifiers} \\ \hline
18 & Each Capability is identified by a unique URI & ~\ref{subsubsec:capability identifiers} \\ \hline
19 & Each View is identified by a unique URI & ~\ref{subsubsec:view identifiers} \\ \hline
20 & Each Protocol is identified by a unique URI & ~\ref{subsubsec:protocol identifiers} \\ \hline
21 & Standard views are represented by the specified URIs & ~\ref{subsubsec:default views} \\ \hline
23 & Standard properties are represented by the specified URIs & ~\ref{subsubsec:standard properties} \\ \hline
23 & Data imported with the default View is treated as a binary BLOB & ~\ref{subsubsec:default views} \\ \hline
24 & Data exported with the default export View is returned in the most appropriate format & ~\ref{subsubsec:default views} \\ \hline
25 & An archive format View on a ContainerNode provides access to the archive contents as children nodes of the container & ~\ref{subsubsec:container views}* \\ \hline
26 & An archive format View specified in a data export operation on a ContainerNode will package the contents of the container and all its child nodes & ~\ref{subsubsec:container views}* \\ \hline
\end{tabular}

\hskip-2.0cm\begin{tabular}{ | p {1cm} | p {11cm} | p {4cm} | }
\hline
\textbf{Item} & \textbf{Description} & \textbf{Occurs in section(s)} \\ \hline
27 & A Protocol has elements: uri and and endpoint & ~\ref{subsec:protocols} \\ \hline
28 & Standard Protocols are represented by the specified URIs & ~\ref{subsubsec:standard protocols} \\ \hline	
29 & A Transfer UWS Job representation has elements: target, direction, view, protocol and keepBytes & ~\ref{subsec:transfers} \\ \hline
30 & A Transfer results representation has elements: target, direction, view, and protocol & ~\ref{subsec:transfers} \\ \hline
31 & A server responds with a fault if it is unable to handle any of the requested protocols in a data transfer & ~\ref{subsubsec:service-initiated transfers}, ~\ref{subsubsec:client-initiated transfers} \\ \hline
32 & A server uses each requested protocol only once in a data transfer & ~\ref{subsubsec:service-initiated transfers}, ~\ref{subsubsec:client-initiated transfers} \\ \hline
33 & A data transfer is complete once a specified protocol is successful & ~\ref{subsubsec:service-initiated transfers}, ~\ref{subsubsec:client-initiated transfers} \\ \hline
34 & A data transfer has failed if none of the specified protocols has been successful & ~\ref{subsubsec:service-initiated transfers}, ~\ref{subsubsec:client-initiated transfers} \\ \hline
35 & A server updates the status flag in the UWS Job representation as appropriate & ~\ref{subsubsec:service-initiated transfers}, ~\ref{subsubsec:client-initiated transfers} \\ \hline
36 & A VOSpace service has the REST bindings: properties, views, protocols, nodes, and transfers & ~\ref{sec:rest bindings} \\ \hline
37 & Access policies on a VOSpace service are declared in the registered metadata for the service & ~\ref{sec:access control} \\ \hline
38 & VOSpace authentication employs IVOA SSO supported methods & ~\ref{sec:access control} \\ \hline
39 & A VOSpace service supports the operations: getProtocols, getViews, getProperties, createNode, deleteNode, moveNode, copyNode, getNode, setNode, pullFromVoSpace. The following are optional operations: pushToVoSpace, pullToVoSpace, pushFromVoSpace & ~\ref{subsubsec:getprotocols}, ~\ref{subsubsec:getviews}, ~\ref{subsubsec:getproperties}, ~\ref{subsubsec:createnode}, ~\ref{subsubsec:movenode}, ~\ref{subsubsec:copynode}, ~\ref{subsubsec:deletenode}, ~\ref{subsubsec:getnode}, ~\ref{subsubsec:setnode}, ~\ref{subsubsec:pushtovospace}*, ~\ref{subsubsec:pushtovospace}*, ~\ref{subsubsec:pullfromvospace}, ~\ref{subsubsec:pushfromvospace}* \\ \hline
40 & accepts and provides specify entities that the service supports & ~\ref{subsubsec:getprotocols}, ~\ref{subsubsec:getviews}, ~\ref{subsubsec:getproperties} \\ \hline
41 & An autogenerated URI is specified as a result in the Results List & ~\ref{subsubsec:createnode}*, ~\ref{subsubsec:movenode}*, ~\ref{subsubsec:copynode}*, ~\ref{subsubsec:pushtovospace}* \\ \hline
42 & Any data written to the reserved URI .null is discarded & ~\ref{sec:rest bindings} \\ \hline
43 & accepts is filled in based on service capabilities & ~\ref{subsubsec:createnode} \\ \hline
44 & If a container is deleted then so are its children & ~\ref{subsubsec:deletenode} \\ \hline
45 & If a container is listed, only direct children are listed & ~\ref{subsubsec:getnode} \\ \hline
46 & Results are drawn from the same ordered sequence in any ordering imposed by the server & ~\ref{subsubsec:getnode} \\ \hline
% 47 & Regex expressions comply with POSIX conventions & ~\ref{subsec:searches} \\ \hline
47 & Moving a container moves its children as well & ~\ref{subsubsec:movenode} \\ \hline
\end{tabular}

\hskip-2.0cm\begin{tabular}{ | p {1cm} | p {11cm} | p {4cm} | }
\hline
\textbf{Item} & \textbf{Description} & \textbf{Occurs in section(s)} \\ \hline
48 & Importing data into an existing container puts the new data within the container & ~\ref{subsubsec:pushtovospace} \\ \hline
49 & Node types are not changed when a node is moved or copied & ~\ref{subsubsec:movenode}, ~\ref{subsubsec:copynode} \\ \hline
50 & Copying a container copies its children as well & ~\ref{subsubsec:copynode} \\ \hline
51 & Importing data into an existing node overwrites any preexisting data (unless it is a container) & ~\ref{subsubsec:pushtovospace}*, ~\ref{subsubsec:pulltovospace}* \\ \hline
52 & A HTTP 200 status code is returned if the operation completes successfully & ~\ref{subsubsec:getprotocols}, ~\ref{subsubsec:getviews}, ~\ref{subsubsec:getproperties}, ~\ref{subsubsec:createnode}, ~\ref{subsubsec:deletenode}, ~\ref{subsubsec:getnode}, ~\ref{subsubsec:setnode} \\ \hline
53 & A HTTP 303 status code is returned if the operation completes successfully & ~\ref{subsubsec:movenode}, ~\ref{subsubsec:copynode}, ~\ref{subsubsec:findnodes}*, ~\ref{subsubsec:pushtovospace}*, ~\ref{subsubsec:pulltovospace}*, ~\ref{subsubsec:pullfromvospace}, ~\ref{subsubsec:pushfromvospace}* \\ \hline
54 & A HTTP 500 status code with an InternalFault fault in the body is thrown if the operation fails & ~\ref{subsubsec:getprotocols}, ~\ref{subsubsec:getviews}, ~\ref{subsubsec:getproperties}, ~\ref{subsubsec:createnode}, ~\ref{subsubsec:deletenode}, ~\ref{subsubsec:getnode}, ~\ref{subsubsec:setnode}, ~\ref{subsubsec:pullfromvospace} \\ \hline
55 & A HTTP 400 status code with an InvalidArgument fault in the body is thrown if a specified value is invalid & ~\ref{subsubsec:setnode} \\ \hline
56 & A HTTP 400 status code with an InvalidURI fault in the body is thrown if the specified URI is invalid & ~\ref{subsubsec:createnode} \\ \hline
57 & A HTTP 400 status code with a TypeNotSupported fault in the body is thrown if the specified type is not supported & ~\ref{subsubsec:createnode} \\ \hline
58 & A HTTP 403 status code with a PermissionDenied fault in the body is thrown if the user does not have permission to perform the operation & ~\ref{subsubsec:createnode}, ~\ref{subsubsec:deletenode}, ~\ref{subsubsec:getnode}, ~\ref{subsubsec:setnode}, ~\ref{subsubsec:pullfromvospace} \\ \hline
59 & A HTTP 404 status code with a NodeNotFound fault in the body is thrown if... & ~\ref{subsubsec:movenode}, ~\ref{subsubsec:getnode}, ~\ref{subsubsec:copynode}, ~\ref{subsubsec:pullfromvospace} \\ \hline
60 & A HTTP 409 status code with a DuplicateFault fault in the body is thrown if the specified node already exists & ~\ref{subsubsec:createnode} \\ \hline
61 & A HTTP 404 status code with a ContainerNotFound fault in the body is thrown if a container is not found & ~\ref{subsubsec:createnode}, ~\ref{subsubsec:deletenode} \\ \hline
62 & A HTTP 400 status code with a LinkFound fault in the body is thrown if a LinkNode is found & ~\ref{subsubsec:createnode}, ~\ref{subsubsec:deletenode} \\ \hline
63 & The PHASE in the UWS Job representation is set to ``ERROR'' in case of a fault occurring & ~\ref{subsubsec:movenode}, ~\ref{subsubsec:findnodes}*, ~\ref{subsubsec:pushtovospace}*, ~\ref{subsubsec:pulltovospace}*, ~\ref{subsubsec:pullfromvospace}, ~\ref{subsubsec:pushfromvospace}* \\ \hline
64 & The errorSummary element in the UWS Job representation is set to the appropriate value for the type of fault occurring & ~\ref{subsubsec:movenode}, ~\ref{subsubsec:findnodes}*, ~\ref{subsubsec:pushtovospace}*, ~\ref{subsubsec:pulltovospace}*, ~\ref{subsubsec:pullfromvospace}, ~\ref{subsubsec:pushfromvospace}* \\ \hline
65 & The appropriate fault representation is provided at the error URI for the job & ~\ref{subsubsec:movenode}, ~\ref{subsubsec:findnodes}*, ~\ref{subsubsec:pushtovospace}*, ~\ref{subsubsec:pulltovospace}*, ~\ref{subsubsec:pullfromvospace}, ~\ref{subsubsec:pushfromvospace}* \\ \hline
\end{tabular}

\section{Standard properties}
\label{sec:standard properties}
This table summarizes the standard properties that SHALL be recognized by a VOSpace service and are registered in the IVOA Registry of Registries.

\hskip-4.0cm\begin{tabular}{ | p {8cm} | p {8cm} | p {2cm} | }
\hline
\textbf{Property} & \textbf{Description} & \textbf{Data type} \\ \hline
ivo://ivoa.net/vospace/core\#availableSpace & the amount of space available within a container & string \\ \hline
ivo://ivoa.net/vospace/core\#btime & the initial creation time & string \\ \hline
ivo://ivoa.net/vospace/core\#contributor & an entity responsible for making contributions to this resource & URI \\ \hline
ivo://ivoa.net/vospace/core\#coverage & a spatial or temporal topic of the resource, the spatial applicability of the resource, or the jurisdiction under which the resource is relevant & string \\ \hline
ivo://ivoa.net/vospace/core\#creator & an entity primarily responsible for making the resource & URI \\ \hline
ivo://ivoa.net/vospace/core\#ctime & the status change (aka metadata modification) time & datetime \\ \hline
ivo://ivoa.net/vospace/core\#date & a point or period of time associated with an event in the lifecycle of the resource & datetime \\ \hline
ivo://ivoa.net/vospace/core\#description & an account of the resource & string \\ \hline
ivo://ivoa.net/vospace/core\#format & the file format, physical medium or dimensions of the resource & string \\ \hline
ivo://ivoa.net/vospace/core\#groupread & the list of groups which can only read this resource & delimiter-separated list \\ \hline
ivo://ivoa.net/vospace/core\#groupwrite & the list of groups which can read and write to this resource & delimiter-separated list \\ \hline
ivo://ivoa.net/vospace/core\#identifier & an unambiguous reference to the resource within a given context & string/URI \\ \hline
ivo://ivoa.net/vospace/core\#language & a language of the resource & string \\ \hline
ivo://ivoa.net/vospace/core\#length & the length or size of a resource & float \\ \hline
ivo://ivoa.net/vospace/core\#mtime & the data modification time & datetime \\ \hline
ivo://ivoa.net/vospace/core\#publicread & whether this resource is world readable & boolean \\ \hline
ivo://ivoa.net/vospace/core\#publisher & an entity responsible for making the resource available & URI \\ \hline
ivo://ivoa.net/vospace/core\#quota & the value of a system quota on the resource & string \\ \hline
ivo://ivoa.net/vospace/core\#relation & a related resource & URI \\ \hline
ivo://ivoa.net/vospace/core\#rights & information about rights held in and over the resource & string \\ \hline
ivo://ivoa.net/vospace/core\#source & a related resource from which the described resource is derived & string \\ \hline
ivo://ivoa.net/vospace/core\#subject & the topic of the resource & string \\ \hline
ivo://ivoa.net/vospace/core\#title & a name given to the resource & string \\ \hline
ivo://ivoa.net/vospace/core\#type & the nature or genre of the resource & string \\ \hline
\end{tabular}

\section{Changes from Previous Versions}
\label{sec:changes from previous versions}

\paragraph{From version 2.1-20170405:}
\begin{itemize}
    \item Replaced the dated Custom Protocols section with a new Public Share Protocol section
    \item Updates from working group feedback
\end{itemize}

\paragraph{From version 2.1-20150601:}
\begin{itemize}
    \item Added REQUEST=redirect for further optimized pullFromVoSpace
    \item Removed ``search'' and ``find nodes'' until use cases and implementations are presented
    \item Changed pullToVoSpace, pushFromVoSpace to be client orchestrated.
    \item Changed Transfer in XSD to accept parameters.
    \item Recreated and expanded all webservice operation examples
    \item Changed XSD element authType to SecurityMethod to match IVOA standard.
    \item Fixed text inconsistencies
    \item Clarified role of the node busy flag
    \item Ported source to ivoatex format
\end{itemize}

\paragraph{From version 2.1-20140805:}
\begin{itemize}
    \item Addition of optimized HTTP GET method of data transfer for pushToVoSpace, pullFromVoSpace
    \item Addition of authType to Protocol in XML schema for transfer negotiation.
    \item Added preliminary list of standard authType URIs
    \item Deprecated view=data convenience method of data transfer
    \item Corrections to minor XML format errors in the examples throughout the document.
\end{itemize}

\paragraph{From version 2.00-20120824:}
\begin{itemize}
    \item Use of Resource Idenfifier and CDP in Architecture diagram clarified.
    \item StandardID defined for this version.
    \item Various formatting issues.
    \item Use of HTTP 500 status code clarified.
    \item HTTP response codes made consistent with RFC 2616.
\end{itemize}

\paragraph{From version 2.00-20111202:}
\begin{itemize}
    \item Clarified use of URI fragments
    \item Added appendix of standard properties
    \item Clarified multi-value properties
    \item Added 404 error codes to getNode and setNode for no parent container ensuring consistent behaviour
    \item Adjusted pushToVoSpace and pullFromVoSpace convenience methods for self consistency and closer matching to UWS Fault formatting.
\end{itemize}

\paragraph{From version 2.00-20110628:}
\begin{itemize}
    \item Corrected REST binding for synchronous transfer details
    \item Added endpoint for synchronous job POSTs
    \item Added properties mtime, ctime, btime
    \item Changed text to describe use of StandardsRegExt for standard properties, views, capabilities, tranfer protocols
    \item Changed error code on ContainerNotFound and LinkFound faults
    \item Added correct failure response for unsupported operations
\end{itemize}

\paragraph{From version 2.00-20101112:}
\begin{itemize}
    \item Examples amended with correct namespaces and root elements
    \item "$\mathtt{\sim}$" listed as a valid URI separator character along with "!"
    \item Core property list added to
    \item Properties with multiple values clarified
    \item Optional operations clarified and indicated in conformance matrix
    \item getNode and findNode operation arguments made consistent
    \item Synchronous HTTP PUT method added
    \item createNode response changed to HTTP 200 from HTTP 201
    \item /{transferDetails} endpoint added
    \item Support for .auto made optional
\end{itemize}

\paragraph{From version 2.00-20100323:}
\begin{itemize}
    \item Updated UWS details: use uws:jobInfo instead of uws:parameters
    \item Added IVOA architecture text
    \item Removed text about WSDL/WADL
\end{itemize}

\bibliography{ivoatex/ivoabib,ivoatex/docrepo}


\end{document}
