Before we begin, we need to take a closer look at how resource properties are represented and handled internally in our service. First of all, let's recall how our resource properties are declared in all the examples we've seen so far:
<types>
<xsd:schema targetNamespace="http://www.globus.org/namespaces/examples/core/MathService_instance"
xmlns:tns="http://www.globus.org/namespaces/examples/core/MathService_instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<!-- REQUESTS AND RESPONSES -->
<!-- ... -->
<!-- RESOURCE PROPERTIES -->
<xsd:element name="Value" type="xsd:int"/>
<xsd:element name="LastOp" type="xsd:string"/>
<xsd:element name="MathResourceProperties">
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="tns:Value" minOccurs="1" maxOccurs="1"/>
<xsd:element ref="tns:LastOp" minOccurs="1" maxOccurs="1"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
</types>
Notice how we're using XML Schema to declare an element named MathResourceProperties
that must contain a Value
element and a LastOp
element. The Value
element, in turn, is declared to contain an integer (xsd:int
) and the LastOp
element, a string (xsd:string
).
In the previous examples, we have simply interpreted this as meaning "Our service has two resource properties, Value
of type integer and LastOp
of type string". In our Java implementation of the resource, this simply meant that our resource class had attributes representing each of the resource properties, and that we used special Globus classes (ReflectionResourceProperty
and ResourcePropertySet
) to manage those resource properties.
However, the reason why our resource properties are declared in XML Schema, and in that particular way, is because even though they can be implemented internally different ways (not only in GT4, but in other WSRF implementations), they must be exchanged with other entities (clients, other services, etc.) as an XML document. This XML representation is called the resource property document. For example, the following is an example of how our service's RP document might look like at a given point:
<MathResourceProperties xmlns:tns="http://www.globus.org/namespaces/examples/core/MathService_instance"> <tns:Value>50</tns:Value> <tns:LastOp>ADDITION</tns:LastOp> </MathResourceProperties>
It is important to be familiar with this representation because many operations related with resource properties are better explained in terms of how that operation modifies the RP document. For example, let's suppose our resource properties are declared the following way:
<!-- RESOURCE PROPERTIES --> <xsd:element name="Value" type="xsd:int"/> <xsd:element name="LastOp" type="xsd:string"/> <xsd:element name="MathResourceProperties"> <xsd:complexType> <xsd:sequence> <xsd:element ref="tns:Value" minOccurs="1" maxOccurs="unbounded"/> <xsd:element ref="tns:LastOp" minOccurs="1" maxOccurs="unbounded"/> </xsd:sequence> </xsd:complexType> </xsd:element>
Notice how we are allowing Value
and LastOp
to occur at least one time, with no other limit (unbounded
). Although internally this will be implemented as an array of integers and an array of strings, the RP document could look like this at a given point:
<MathResourceProperties xmlns:tns="http://www.globus.org/namespaces/examples/core/MathService_instance"> <tns:Value>10</tns:Value> <tns:Value>30</tns:Value> <tns:Value>50</tns:Value> <tns:Value>40</tns:Value> <tns:LastOp>ADDITION</tns:LastOp> <tns:LastOp>ADDITION</tns:LastOp> <tns:LastOp>ADDITION</tns:LastOp> <tns:LastOp>SUBTRACTION</tns:LastOp> </MathResourceProperties>
Later on, for example, we will talk about "inserting a new resource property LastOp
with value ADDITION
". This doesn't mean that we are declaring a new RP but, rather, that we are inserting a new element LastOp
inside our resource property document. Again, it is useful to be aware of how resource properties are represented in XML.
An entire WSRF specification, WS-ResourceProperties, is devoted to RPs, RP documents, and to a set of standard portTypes we can use to interact with a service's RPs. Each of these four portTypes exposes a single operation, with the same name as the portType. In this chapter's example we will use all of these portTypes.
This portType allows us to access the value of any resource property given its QName. This portType provides a general way of accessing RPs without the need of an individual get
operation for each RP (recall that, in previous chapters, we used the GetValueRP
operation to access the Value
resource property).
This portType allows us to access the value of several resource properties at once, given each of their QNames.
This portType allows us to request one or several modifications on a service's RPs. In particular we can perform the following operations:
Update: Change the value of a RP with a new value.
Insert: Add a new RP with a given value.
Delete: Eliminate all occurrences of a certain RP.
Again, note that the SetResourceProperties
portType has a single operation (not three separate ones). We will use the parameters of the SetResourceProperties
to specify what action (update, insert, or delete) we want to carry out.