Core

 

Application Program Interface

 

Version 1.3.1a1

(Addendum 1)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

15 November 2010


 

 

 

 

 

 

 

 

 

 

 

 

This document was produced by Energistics in conjunction with the

 WITSML Technical Review Team members.

 

 

 

www.energistics.org

 

Copyright (c) 2005, 2010 Petrotechnical Energistics. All rights reserved.

POSC® and the POSC logo® are registered trademarks and WITSML™ and the WITSML logo™ are trademarks of Energistics.

 

This file is distributed under the Energistics License Agreement at http://www.energistics.org
Use of this file constitutes agreement with the Energistics License Agreement.

 


 

Table of Contents

 

 

1      Introduction. 6

2      Document Revisions. 7

3      Terminology and Basic Concepts. 9

3.1       [WITSML] Object or Data Object 9

3.2       Unique Identifiers (UIDs) 10

3.3       Representation versus Transport 11

3.4       Transport versus Storage. 12

3.5       [WITSML] Document 12

3.6       Subscribe/Publish Application Program Interface (API) 12

3.7       Client/Server Application Program Interface (API) 13

3.8       Versioning. 13

3.8.1        Versioning - Data Objects. 13

3.8.2        Versioning - API Signature. 14

3.8.3        Versioning - API Capabilities. 14

3.8.4        Versioning - Executable Programs. 15

3.8.5        Incrementing Version Numbers. 15

4      API Objectives and Constraints. 16

5      Use Cases. 17

5.1       Sensor Data over WITSML.. 17

5.2       Rig Site Repository/Aggregator 21

6      The Interfaces. 23

6.1       STORE and PUBLISH.. 23

6.2       Choosing an Interface. 24

6.3       Common Behavior 25

6.3.1        Case Sensitivity. 25

6.3.2        Query and Subscription Templates. 26

7      STORE Interface. 28

7.1       Introduction. 28

7.2       Query Templates. 30

7.2.1        Introduction. 30

7.2.2        Data Item Selection. 32

7.2.3        Object Selection. 33

7.2.4        Combining Data Item and Object Selection. 35

7.2.5        Selection using Recurring Data Items. 37

7.2.6        Minimum Query Template. 40

7.3       Authentication and Encryption. 41

7.4       Capabilities Objects. 42

7.4.1        Client Capabilities (capClient) Object 42

7.4.2        Server Capabilities (capServer) Object 42

7.4.3        Capabilities by Object 43

7.5       STORE Functions. 47

7.5.1        WMLS_AddToStore. 48

7.5.2        WMLS_DeleteFromStore. 51

7.5.3        WMLS_GetBaseMsg. 54

7.5.4        WMLS_GetCap. 55

7.5.5        WMLS_GetFromStore. 56

7.5.6        WMLS_GetVersion. 60

7.5.7        WMLS_UpdateInStore. 61

7.6       STORE Interface - WSDL File. 64

7.6.1        File Listing. 65

7.6.2        Narrative. 72

8      PUBLISH Interface. 74

8.1       Introduction. 74

8.2       Subscription Requests. 77

8.2.1        action attribute - the action being requested. 79

8.2.1.1     action=”add” - add a new subscription. 79

8.2.1.2     action=”modify” - modify an existing subscription. 80

8.2.1.3     action=”cancel” - cancel one or all existing subscriptions. 81

8.2.1.4     action=”verify” - verify an existing Subscription. 82

8.2.1.5     action=”retransmit” - retransmit the realtime headers. 83

8.2.2        retCode attribute - the return code. 84

8.2.3        idSub attribute - the subscription identifier 84

8.2.4        test attribute - test network connectivity. 85

8.2.5        host, process, port and encrypt attributes - specify the subscriber’s URL.. 86

8.2.6        idPub attribute - identify the Publisher 87

8.2.7        retry attribute - the error retry count 88

8.2.8        updateInterval attribute - limit the publication rate. 89

8.2.9        Subscription Object Attribute Summary. 90

8.3       Subscription Templates. 91

8.3.1        Realtime Example. 94

8.4       Publishing and Maintaining Subscriptions. 98

8.5       POST Request 99

8.5.1        Syntax. 99

8.5.2        Notes: 100

8.5.3        Example: 100

8.6       Authentication and Encryption. 101

8.7       Capabilities Objects. 102

8.7.1        Subscriber Capabilities (capSubscriber) Object 102

8.7.2        Publisher Capabilities (capPublisher) Object 102

8.7.3        Capabilities by Object 103

8.8       PUBLISH Functions. 107

8.8.1        WMLP_GetBaseMsg. 107

8.8.2        WMLP_GetCap. 108

8.8.3        WMLP_GetVersion. 109

8.8.4        WMLP_Subscribe. 110

8.9       PUBLISH Interface - WSDL File. 113

8.9.1        File Listing. 114

8.9.2        Narrative. 118

9      APPENDIX A - Example Data Object Schema. 120

10        APPENDIX B - Unit of Measure. 126

10.1     Overview.. 126

10.2     Basics. 126

10.3     Process interaction with ‘uom’ 127

10.4     Responsibilities. 128

10.5     Updating. 128

11        APPENDIX C - Defined Values. 129

11.1     Return Values. 129

12        APPENDIX D – Special Handling. 131

12.1     Randomly growing objects. 133

12.2     Systematically Growing Objects. 134

12.3     STORE and PUBLISH behavior 136

12.4     STORE Interface Examples. 139

12.4.1      trajectory Data Object Example. 141

12.4.2      mudLog Data Object Example. 144

12.4.3      log Data Object Example. 147

12.4.3.1       Querying for Rows in a Systematically Growing Object 151

12.4.3.2       Updating Rows in a Systematically Growing Object 158

12.4.3.3       Deleting Rows in a Systematically Growing Object 160

12.4.3.4       Adding Columns in a Systematically Growing Object 162

12.4.3.5       Deleting Columns in a Systematically Growing Object 163

12.5     PUBLISH Interface Example. 164

13        APPENDIX E - Service Agreement 166

14        APPENDIX F - Custom Data. 168

14.1     Namespace. 168


1          Introduction

This document describes the core components of the WITSML Version 1.3.1 API. The core components consist of the Client/Server and Subscribe/Publish interfaces.

 

 


2          Document Revisions

2.1         Clarifications of the v1.3.1 release

This represents clarifications to the v1.3.1 specification as agreed to by the WITSML Special Interest Group (SIG). There is no intentional broadening of the underlying behavior of the v1.3.1 API specification. The section names are hotlinked.

These are changes are from W-RFC-017:

·         In sections 7.5.2 "WMLS_DeleteFromStore", 7.5.5 "WMLS_GetFromStore" and 7.5.7 "WMLS_UpdateInStore", added a note to clarify that a server shall use a caseless compare against uid values (as it does for all other values).
In section 6.3.1 "Case Sensitivity", clarified that a server may alter a stored parentage pointer (e.g., uidWell) in order to make the case match the related uid (enables support for alternative/future case sensitive interfaces).
In section 7.5.1 "WMLS_AddToStore", added a note that a best practice for clients is to always use pointers whose value exactly matches the related uid value because:

1.      Some servers may reject an added object if the case of a parentage uid pointer does not match the parent uid.

2.      Some servers may accept an added object if the case of a parentage uid pointer does not match the parent uid and may change the pointer to match the uid.

3.      Some servers may enforce referential integrity of pointers using a case sensitive constraint.

·         In section 7.5.7 "WMLS_UpdateInStore", added note to clarify that after the update, a retrieval of everything must be schema compliant.

·         In section 7.5.7 "WMLS_UpdateInStore", modified note to clarify that an element without a uid refers to no uid in the schema (as opposed to no uid in the XML).

·         In section STORE and PUBLISH behavior, modified item 2.a to clarify that only the specified columns will be cleared as part of the replacement.

·         In sections 7.5.1 "WMLS_AddToStore" and 7.5.7 "WMLS_UpdateInStore", added note for client best practice of using the index unit and datum from the header of a growing object.

These are changes are from W-RFC-001:

·         Clarified that OptionsIn is encoded utilizing a subset of the encoding rules for HTML form content type application/x-www-form-urlencoded. The allowed encoding is constrained by only allowing semicolons for separators and by not allowing whitespace. For example, “param1=value1;param2=value2”. This modified the documentation of section WMLS_GetCap, WMLS_GetFromStore and WMLP_GetCap and WMLP_Subscribe but it is intended to affect all usages of OptionsIn.

·         Added recommendation for a client to always return dataVersion in section WMLS_GetCap. Also added clarification of the interaction of the different kinds of versions. Added paragraph to section Versioning.

·         In section 7.5.1 WMLS_UpdateInStore, added notes from v1.4.0 to clarify update behavior. Added note that the client should always specify the relevant unit of measure information. In section 9 "APPENDIX A - Example Data Object Schema" added element nameFormation to the mudLog schema so that it can be used in the example for updating an element with no uid.

·         Modified section Unique Identifiers to copy the v1.4.1 clarification that the globally unique uid is only needed on the independent objects.

·         In section WMLS_GetFromStore, added note that the suggested mechanism for detecting active wellbores is to look for changes in mdCurrent or in object's dTimLastChange. Servers should attempt to keep mdCurrent reasonably up to date and should modify dTimLastChange when data within an object is modified.

·         In section Combining Data Item and Object Selection, added v1.4.0 clarification to the "Limitation" box that some "date and time" elements will have "greater than" comparisons instead of "equal". In section WMLS_GetFromStore, added note to clairify that the commonData elements dTimCreation and dTimLastChange shall be treated by the server as a request for comparisons of "greater than" rather than "equal" (as documented in the v1.4.0 data schema).

·         In section WMLS_GetFromStore, added note to document that a client should expect systematically growing object (i.e, log and wellLog) data to be returned in chunks. A recommended practice is to first retrieve the header of the object and then retrieve the data components. After each call, compare the returned structural range values to those defined in the header to see if all data has been returned. If not then execute a new call requesting data from the end of the previous return. If the object is growing, then element dTimLastChange should be monitored to determine when new data has been registered.

·         In sections WMLS_AddToStore and WMLS_UpdateInStore, added note to document that the time zone information is very important in any dateTime value.

·         In section WMLS_UpdateInStore, added note that a client best practice is to utilize the server units defined in the log header of a WMLS_GetFromStore result. However, a server must honor whatever units (e.g., startIndex/@uom) the client specifies in a WMLS_UpdateInStore request. This does not mean that the server will internally store the data in the client units. It only means that the server must convert the client values to the server internal units.

·         In section STORE and PUBLISH behavior, modified item 2.a to add the v1.4.0 clarification that for the purpose of this section, “append” means to add new data whose index is greater than the current maximum index. Modified item 2.b to add the v1.4.0 clarification that replace is logically an “insert” if no data exists within the specified range. Also clarified that the structural range value should match the index range in the new data because some servers delete the structural range and some servers delete the range in the data before adding the new data.

·         In section WMLS_UpdateInStore, modified note 3 to add an example with and without a uid.

·         Schema Variants:

o   In section WMLS_AddToStore, added the v1.4.0 documentation that for XMLin, the XML should conform to the derived “write” schema where child and parentage uids are mandatory.

o   In section WMLS_DeleteFromStore, added (variation of the v1.4.0) documentation that for QueryIn, the XML should conform to a derived “delete” schema where all elements and attributes are optional except that all object and parentage uids are mandatory.

o   In section WMLS_GetFromStore, added the v1.4.0 documentation that because QueryIn can contain empty elements, it cannot be schema validated but otherwise the XML should conform to a derived “read” schema where all elements and attributes are optional. Added the v1.4.0 documentation for XMLout that the XML should conform to a derived “read” schema where all elements and attributes are optional. Added the v1.4.0 note that the OptionsIn keyword returnElements with a value of “all” can be used to construct a query without empty values.

o   In section WMLS_UpdateInStore, added the v1.4.0 documentation that for XMLin, the XML should conform to a derived “update” schema where all elements and attributes are optional except for all uid and uom attributes which are mandatory.

·         In section WMLS_DeleteFromStore, added v1.4.0 example of deleting an object. Added v1.4.0 note to see section “STORE and PUBLISH behavior” for additional behavior related to growing objects.

·         In section WMLS_UpdateInStore, added v1.4.0 "delete" note that an empty non-container element (i.e., cannot have child elements) will delete its value and any attributes.

·         In section WMLS_GetFromStore, added note that if structural range client values are requested in a randomly growing object (i.e., mudLog startMd/mdTop, trajectory mdMn/mdMx) then the returned values should represent the minimum and maximum values of the data within that range whether returned (i.e., data requested) or in-store (i.e., only header requested). Minimum means the nearest to the surface measured along the borehole. This is in contrast to the returned values in a systematically growing object (i.e., log start/end, wellLog start/end) where the values represent the first and last values. The difference is because systematically growing objects are ordered while the randomly growing objects are not necessarily sorted (i.e., the actual order is server dependent). See section STORE and PUBLISH behavior, items 1.b through 1.e for detailed behavior.

·         In section WMLS_GetFromStore, updated note 9 to emphasize that nothing is sorted but the data rows in systematically growing objects.

2.2         Since Revision 0 (the v1.3.0 specification)

Changed all version references from “1.3.0” to “1.3.1”. Changed all namespace designations from “130” to “131”. This excludes the WSDL namespaces which changed from "130" back to "120". Changed the data schema namespace in all XML examples from "130" to "131ex" to reflect the example schema in Appendix A.

Deleted attribute "apiVers" from element "function" in examples (the attribute was deleted in 1.3.0).

Consistently italicized all WMLS_ references.

Deleted all references to the Supplemental API specification.

The following changes are for the indicated issues:

Issue 1.3-14 "WSDL namespace not backward compatible"

1)      Clarified that data schema version values must match the version attribute in the plural container object.

2)      Changed WMLS_GetVersion to return a comma delimited list of data schema versions (without spaces) instead of returning the software version.

3)      Documented the "dataVersion" OptionsIn parameter in WMLS_GetCap and WMLP_GetCap so the client can tell the server the data schema version for which capability information is desired.

4)      Changed the ReturnAllElements OptionsIn parameter in WMLS_GetFromStore and WMLP_Subscribe to have a keyword and value format with the keyword being "returnElements" and the values being "all" or "requested" (default).

5)      Documented that the OptionsIn parameter string is encoded utilizing the encoding rules for HTML form content type application/x-www-form-urlencoded as specified at http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.13.3.3.

Issue 1.2-139 " Retrieving the server-specific UID-prefix info"
Modified WMLS_AddToStore to document that if a uid is not specified for the object, then the server will assign a uid value to the object and return the value in 'SuppMsgOut' (if there is no error). Child uids must be populated by the client.

Issue 1.3-24 " Suggested clarification for query templates"
Clarify that Object Selectors will be returned in addition to Data Item Selectors.

Issue 1.3-27 " Side effects of updates to growing objects"
Documented in section 12.3 STORE and PUBLISH behavior that in growing objects, any request to update a server query element will be ignored without issuing an error.

 


3          Terminology and Basic Concepts

3.1         [WITSML] Object or Data Object

A WITSML data object is a logical organization and grouping of the data items associated with the major components and operations involved in drilling a well. For example, a group known as the rig “data object” would contain the data items related to the rig, such as its owner, type and manufacturer.

► A WITSML data object is not, however, a formal programming object
 (with methods, properties, events, etc).

These data objects can be organized into a single hierarchical “tree”, with the well object at the top of the tree. The well object is the parent of one or more wellbore objects, a wellbore object has one or more children, and so on.

 

 

 

 

 

 


► When being exchanged between systems, each of the logical objects
is represented as a physical XML document.

 

That is, all the data items in one wellbore object are transported as one XML document, which is simply a text file. In order to transport the complete tree shown above, five XML documents are required. The objects can be logically thought of as being in one tree, but they are physically represented as five separate documents.

 

Since each object carries with it its own identifier and the identifier(s) of its’ parent, grand-parent, etc, the tree can be reconstructed from the individual documents.


3.2         Unique Identifiers (UIDs)

Every WITSML data object has within it an identifier, and the identifier(s) of its ancestry. For instance, a Mud Log (mudLog) object has an identifier of itself, and the identifiers of its parent (wellbore) object and its grandparent (well) object.

These identifiers are known as "unique identifiers" or UIDs. The Mud Log’s own identifier is its uid attribute, its parent wellbore is its uidWellbore attribute and its grandparent is its uidWell attribute.

It is recommended that the uid of each singular independent object be made globally unique by generating uids according to uuid algorightm of rfc 4122 (http://www.faqs.org/rfcs/rfc4122.html). An independent object is one which is not identified within the context of another object (e.g., well is an independent object). The unique identifier of all dependent objects (e.g., wellbore) are only required to be unique within the context of its nearest parent object. For example, the unique identifier in trajectory is only required to be unique within the context of its parent wellbore.

Because these system oriented-unique identifiers might contain internal keys or other not-easily-readable values, elements have been defined to carry more "human readable" names of an object and its parentage, such as nameWell, nameWellbore, name, etc.

Each repeatable element (i.e., has maxOccurs greater than 1) that needs to be individually queried by the server (e.g., update a single node) must have a uid attribute. If an element has a uid attribute then all repeatable parent elements must also have a uid attribute. A non-repeatable element should not have a uid attribute. For the purposes of this discussion, a foreign key to a non-parent node is not considered to be a uid value. The only purpose of uid values is to insure uniqueness of nodes in a server. Best practice should not assume any semantic content of a uid value.

Each individual child uid value is only required to be unique within the context of its nearest repeatable parent node. The unique key for any node is the combination of all uid values in the hierarchy down to and including that node. Each uid value may actually be unique within a broader context but best practice should not assume a broader context.

Some WITSML objects that utilize the plural convention may combine to represent one hierarchical tree (e.g., well/wellbore/...). For objects that represent a common hierarchy, the repeatable parent node may exist in another object that is referenced using a parent key. For example, the wellbore object would reference a well uid. Since the unique key for a node must necessarily include the unique key for its nearest repeatable parent node, the unique key of a child object of a wellbore object would include the wellbore key (i.e., a well uid value and a wellbore uid value) in addition to its own uid value.

Similarly, any "natural" human recognizable identifiers (e.g., name, index) for a node should be populated with values that identify the node within the context of the nearest repeatable parent node. For objects that represent a common hierarchy, the name pointer to parent another object is part of the uniqueness of that object. The possibly-unique natural key for a node is the combination of all natural identifiers in the hierarchy down to and including that node. While natural keys are not required to be unique within the context of a server, every effort should be made to insure their uniqueness in order to eliminate ambiguity. Where the natural keys are not unique then human inspection is required to determine if the nodes represent the same thing (and they should be combined) or if they represent different things (and their identity should be changed).

3.3         Representation versus Transport

WITSML data objects being exchanged between systems are always represented as XML documents. The WITSML XML Schemas define the format of these objects when they are represented as XML documents.

Since XML documents are simply text files, they can be transported by various means, such as email or other file transfer method. A WITSML data object could even be in the form of a printed or Faxed document.

The WITSML API described in this document specifies a standardized way of electronically transporting WITSML data objects between systems using the HTTP/S-based protocols. However, it is acceptable for companies to agree to send and receive WITSML data streams without the use of the WITSML API.

We will use the term "HTTP" in this document to specify "Hypertext Transport Protocol  (un-encrypted)".

We will use the term "HTTPS" to specify "Hypertext Transport Protocol over Secure Sockets Layer (encrypted)"

We will use the term "HTTP/S" when generically referring to both HTTP and HTTPS.

 
 

 

 

 

 

 



3.4         Transport versus Storage

WITSML data objects being transported between systems must be represented as XML documents.

The specification does not dictate, however, how the WITSML data objects are to be stored within those systems. The data objects might be stored as text files or in a database system.

WITSML defines an interoperability specification concerning how the data must be represented and a standard way of exchanging the data electronically. It does not define the storage mechanism.

3.5         [WITSML] Document

One or more complete WITSML data objects - such as well, wellbore or log - when they are represented as an XML text string. Consistent with the way the XML literature uses the word "document", the term does not necessarily mean a physical file. A text string of XML being sent via an HTTP/S POST is also an XML document. If that XML represents one or more WITSML objects, it is then a WITSML document. Also see WITSML Object/Data Object.

3.6         Subscribe/Publish Application Program Interface (API)

Using the Subscribe/Publish API, WITSML data objects are periodically “pushed” from a Publisher to a Subscriber. The Subscriber defines what data objects it wishes to have sent to it by sending a subscription to the Publisher. The Subscriber then waits to receive the requested data objects.  When new or changed data objects are available which match the subscription - either immediately or at some time in the future - the Publisher sends them to the Subscriber.  Subscribe/Publish uses the SOAP protocol to transport the subscription/acknowledgment between the Subscriber and Publisher, and uses the HTTP/S POST protocol to push the data objects from the Publisher to the Subscriber.

► The Subscribe/Publish API is also known as the PUBLISH interface, or by the prefix of its functions: “WMLP” (a contraction of “WITSML Publish”).


3.7         Client/Server Application Program Interface (API)

In Client/Server mode, WITSML data objects are “pulled” on-demand by a Client from a Server. The Client makes a request of the Server, and the Server immediately responds with an acknowledgement or an error code. The Client can add, update, delete and retrieve WITSML data objects on the Server. Client/Server uses the SOAP protocol to transport the requests/responses between Client and Server.

► The Client/Server API is also known as the STORE interface, or by the prefix of its functions: “WMLS” (a contraction of “WITSML Store”).

3.8         Versioning

There are four major entities in the WITSML specification that can be "versioned":

the data objects

the API signature

the API capabilities

the executable programs

Basically,

·         The signature defines the structure of the serialized XML stream of the web service.

·         The data objects define structure of the data packets which can be "contained" within the serialized XML stream.

·         The capabilities define the behavior related to the serialized XML stream.

·         The executable programs represent a particular implementation of all of the above.

Each of these four entities use versioning in slightly different contexts:

3.8.1        Versioning - Data Objects

For a data object, the version number specifies the version of the XML Data Schema against which the object can be validated. The number is conveyed in the version attribute of the data object's plural container element:

       <wells version="1.3.1.0"   …  >

              <well … />

       </wells>

The example indicates that the well object is compliant with the WITSML 1.3.1.0 XML Data Schemas.

A client or subscriber can also determine the version of WITSML data supported by the server via WMLS_GetVersion.

 
 

 

 



3.8.2        Versioning - API Signature

The API signature is a contract between the provider system (server or publisher)
and the consumer system (client or subscriber) that specifies how the Web Service will interact in terms of what function calls are available, their parameters, the protocols they run over and where the service is located.

The contract is defined in a Web Services Description Language (WSDL) file, described in this document. Once defined, it should not change, else consumer applications that were written to an earlier specification might "break".

When new functionality needs to be added, the contract - the WSDL file - can be updated (but hopefully in a way that extends but does not break the existing functionality!). Or if the changes are such that it is not possible to provide backward compatibility to existing clients, a completely new WSDL file (with a different Web Service name) could be published.

A new or updated WSDL file constitutes a new version of the API signature. The version of the WSDL file is specified by the URI of the targetNamespace attribute of its <definitions> element:

<definitions name='WMLS' targetNamespace='http://www.witsml.org/wsdl/120' …

There is also a <documentation> element in the WSDL file that specifies the version in a more easily-readable form:

<documentation>WITSML Version 1.2.0 STORE interface WSDL file </documentation>

Client programs should use the targetNamespace URI rather than the <documentation> element to determine the version of the WSDL file.

The presently published WSDL file is version 1.2.0.

3.8.3        Versioning - API Capabilities

The API capabilities describe the "details" about how the client/server and subscriber/publisher interfaces operate. An API's capabilities further define and clarify the basic functionality which the API signature advertises (think of the capabilities as being the "fine print" on the contract). For example, while the API signature says that a client can issue a "Get From Store" function call to retrieve WITSML data objects from a server, it is the API's capabilities that determine which data objects are available on a particular server.

An API's capabilities - or more precisely, the capabilities of a particular implementation of the API - are conveyed in Capabilities Objects, which are a special kind of WITSML API object. There is a Capabilities Object for a Server, a Client, a Publisher and a Subscriber. The version of the capabilities implemented by a WITSML component, such as a Server, is conveyed in the apiVers attribute of the Capabilities Object.

Here is an example of a Server's capabilities (capServer) object showing the version:

       <capServers … >

              <capServer apiVers="1.3.1">

                     …

              </capServer>

       </capServers>

The Capabilities Objects are exchanged using the WMLx_GetCap functions of the API or by passing the objects as parameters to the function calls.

3.8.4        Versioning - Executable Programs

The version or "build" number of an executable program is provided as additional information, and can be used to assist in troubleshooting, for example. The program's version/build number is chosen solely by the particular implementer, and does not necessarily correlate to the version numbering scheme used by the other WITSML entities.

Here is an example of a Server's capabilities (capServer) object showing theexecuitable  version:

       <capServers ...>

              <capServer>

                     <version>1.3.1.1463</ version >

              </capServer>

       </capServers>

3.8.5        Incrementing Version Numbers

Note that the version numbering of the various WITSML entities is mostly independent of one another. The version numbers may increment at different rates and times for different parts of the WITSML specification.

In the future, it is expected that the API signature will almost "never" change, while the data objects will likely experience the greatest rate of change, with the API implementation's rate of change somewhere in the middle. And, of course, changes to program version/build numbers will vary by implementation.

 


 

4          API Objectives and Constraints

The WITSML API is intended to be platform independent. It should be useable by any programming language that can invoke a function-call interface. An object-oriented language is not required, although object-oriented wrappers over the WITSML API could be developed.

The API is specified in function-call syntax, and specifies simple data types (integers, strings, etc) for parameters and return values. Pointers and structures are not used.

Unless noted otherwise, function calls are synchronous (blocking).

The concurrent use of API functions by multiple client applications is dependent on the particular API implementation.

This specification describes only the external interfaces exposed by the API, not any particular implementation. The internal implementation of the API can and will vary. All references in this document to implementation scenarios are for the purpose of example only.

 

 


5          Use Cases

The following use cases are intended to illustrate how the two core API interfaces - Client/Server and Subscribe/Publish - might be used. The use cases do not necessarily illustrate recommended solutions to specific business requirements.

5.1         Sensor Data over WITSML

This example illustrates how WITSML realtime data objects could be transferred using the Subscribe/Publish mode from a sensor aggregator application on a rig to an application in the operating company’s offices.

The sensor aggregator system is the Publisher and the office system is the Subscriber. The realtime data objects are “pushed” from the Publisher to the Subscriber.

The first phase in the process involves “subscribing” to one or more of the Publisher’s available realtime data channels. To do this, the potential Subscriber sends a subscription request to the Publisher. The subscription request will specify, among other things, that the Subscriber wishes to receive the WITSML realtime data object and which channels of the realtime object.

In order to know what data object types and realtime channels it can request, the Subscriber can first ask the Publisher for that information.

The Subscriber can determine what data object types are available by using SOAP to invoke the Publisher’s WMLP_GetCap (Get Capabilities) function, denoted by (1) in the diagram below.

The Publisher's WMLP_GetCap function returns the Publisher’s Capabilities object (2) to the Subscriber, which lists the data object types the Publisher can provide. In this example, the Publisher would list only the realtime data object type in the returned Capabilities object, as that is the only data object type it can publish.

The Subscriber then needs to know what channels are available for the realtime object. This information is not conveyed in the Publisher's Capabilities object, since it can vary by well, wellbore or time. Instead, the Subscriber can query the Publisher for this information (3), using the WMLS_GetFromStore function. For example, the following query would return the channel mnemonics and well/wellbore identifiers for all realtime objects on the Publisher (4).

       <realtimes xmlns="http://www.witsml.org/schemas/131ex">

              <realtime uidWell="" uidWellbore="">

                     <channel mnemonic="">

              </realtime>

       </realtimes>

If the Subscriber already knew the well/wellbore identifiers, it could have specified them in the query:

       <realtimes xmlns="http://www.witsml.org/schemas/131ex">

              <realtime uidWell="w1" uidWellbore="w1b">

                     <channel mnemonic="">

              </realtime>

       </realtimes>

This could result in a smaller result set and a quicker, more efficient query.

 

 

 

 

 

 

 

 

 

 


Once the Subscriber has determined which channels on which wells and wellbores are available to be published, it then invokes the Publisher’s WMLP_Subscribe function (5) and subscribes to one or more realtime channels. Included in the Subscription request (which is itself passed as a WITSML data object) are the Subscriber’s host name and various other information that the Publisher will need when it has data to send to the Subscriber. The Subscriber also passes its own Capabilities object to the Publisher. [1] Thus, both the Publisher and Subscriber now know each other’s capabilities.

So that subscriptions are not lost across restarts of the Publisher system, the Publisher then records the subscription in a non-volatile store (7) and returns a unique subscription identifier to the Subscriber (6). The Subscriber can later use this subscription identifier to cancel, modify or verify the subscription.

Once the subscription has been accepted, we are then ready for the second phase of the process: publishing the data.

Whenever new or changed data for the specified channels become available – perhaps immediately after the subscription was received or at some time later - the sensor aggregator application will create a WITSML realtime data object and send it to all Subscribers who are subscribed to that channel of the realtime data object.

The sensor aggregator application is responsible for parsing the data coming in from the sensors, associating that data to the appropriate data items defined for the WITSML realtime data object, supplying any missing data items and creating the WITSML realtime data objects.

 

The sensor aggregator application then uses HTTP/S POST to send the WITSML data objects to the Subscriber, as denoted by (2) in the diagram on the next page.

On the Subscriber system, a process running under a Web server receives the WITSML data objects (3), [2] extracts the data items from the data object and then persists them to its own internal data store (4).

NOTE

 

While this use case illustrated using the Subscribe/Publish API to transport the WITSML realtime data (notification) object, it’s important to note that the Subscribe/Publish API be used to issue notifications of changes to any of the WITSML data object types. For example, a Subscriber can request that a Publisher send it notifications of any new or changed well objects. Although suited for use in situations where new transient data is periodically available - such as with the realtime object - the Subscribe/Publish API is not restricted to use for only the realtime data object.

 
 

 

 

 

 

 

 



5.2         Rig Site Repository/Aggregator

This example illustrates how a server located at a rig site could act as a central repository for data related to its well(s).

Some of the data stored in such a repository would be collected by other front-end applications used on the rig, such as drilling management systems. These applications would act as clients, and use the rig server as a persistent store, to either augment or replace their own internal proprietary databases. These applications could provide the user interface for initially defining the well, accepting manual input and for producing and distributing periodic reports.

Other applications on the rig would use the server as a realtime data Subscriber, in a similar manner to what was illustrated in the first use case. Sensor aggregator applications would collect realtime data and publish it to a Subscriber process running on the rig server.

Backend applications located either at the rig or at the office could then act as Clients and retrieve data from the server on-request. A data analysis application, for example, could populate its own well definition based on the well object it retrieves from the server, and then retrieve the stored log curves for analysis.

In this example, the rig server performs as both a Subscriber and Server. When being used as a persistent store by the drilling management or data analysis applications, it is acting as a Server. When receiving data from the sensor aggregator application, it is operating as a Subscriber.

Most of the internal processes involved in receiving the realtime data and persisting it are the same as for the Subscribe/Publish use case described earlier, and we have omitted some of that detail here (the process of requesting the subscription has been omitted, for example, although it is still applicable).

However, we have made one change of note to the Subscriber processing: in the first use case, we showed the Subscriber process writing directly to its own proprietary data store.

But in this case, we show the Subscriber process invoking the STORE interface instead. Since the STORE interface must be implemented on this server anyway (to provide access for clients), it makes sense to use this same implementation to store the realtime data received by the Subscriber process. This would assume that log data is being stored – not realtime data.

There are typically different implementation considerations for storing large volumes of data – particularly if received in “realtime” mode - versus supporting relatively lower volume transactional updates or queries. In order to maintain good performance in both modes, the fairly static and low volume data objects such as well, rig and wellbore might be stored by the STORE implementation in one database while the realtime data objects received from the sensor application might be stored as logs in a different database, using a different storage mechanism. But client applications are not aware of this; they merely request STORE to access a particular object, regardless of how it is stored.


6          The Interfaces

6.1         STORE and PUBLISH

The WITSML Core API defines two interfaces:

            STORE (aka, Client/Server or WMLS)
            PUBLISH
(aka, Subscribe/Publish or WMLP)

The STORE interface provides Client applications access to WITSML data objects stored on a Server.

The PUBLISH interface provides Subscriber applications the ability to query a Publisher for what WITSML data object types are available for publication, to subscribe to changes to data objects to be published at some time in the future and to maintain the subscription requests held by the Publisher.

Both the STORE and PUBLISH interfaces are exposed to client applications via SOAP (Remote Procedure Call-style).


6.2         Choosing an Interface

In addition to their functional differences, the STORE and PUBLISH interfaces also differ in their underlying goals and philosophies.

The STORE interface is an immediate-response, synchronous client-server mechanism. Its reliability is subject only to the limitations of the underlying transport protocols.

On the other hand, the PUBLISH interface - or more precisely, the actual push or publication of the requested data - is a best-effort, delayed-action delivery mechanism.

While features have been included in the PUBLISH interface to reduce the likelihood of data loss, it’s still possible for the PUBLISH interface to fail to deliver requested data objects to a subscriber, such as when a subscriber is not ready to receive the data objects when they are published. The publisher does not, for example, “queue” undeliverable data for later delivery, once the error retry count has been exhausted. Every reasonable attempt will be made by the publisher to deliver the data objects, but if connectivity is lost for any reason the specification does not require or imply that undelivered data objects will be retained for resending once connectivity is re-established.

The PUBLISH interface employs the concept of "changed" data content. A Publisher sends only changed data objects to its Subscribers. The publication of the data object is triggered by a change in the contents of the data object.

The STORE interface does not support the concept of “changed” data content. Using the STORE interface, there is no way to determine if the contents of a data object has changed, other than for the client application to periodically retrieve the data object and perform a comparison against the old versus new data content. If the client application wishes to receive notifications of changes to a data object (and thus shift the processing load of determining whether the data content has changed to the sender), the PUBLISH interface should be used.

The system designer should take into account these design differences between the STORE and PUBLISH interfaces when choosing which is applicable for a particular application. For situations where 100% data reliability is required, the “pull” model of the STORE interface is available. For situations in which periodic polling of a server for new/changed data objects isn’t possible (i.e., the data source has no persistent store) or isn’t desirable (i.e., due to load on the network or client), the PUBLISH model provides the ability to publish changes to data objects in an efficient, but not guaranteed, manner.


6.3         Common Behavior

6.3.1        Case Sensitivity

All functions exposed by the STORE and PUBLISH interfaces preserve upper and lower case characters present in all data items that have an underlying data type of “String”. An exception is that a server may alter a stored parentage pointer (e.g., uidWell) in order to make the case match the related uid (enables support for alternative/future case sensitive interfaces).

The “country” data item of the well object, for example, has a WITSML-defined data type which is derived from the W3C-data type of “String”.

Therefore, if the country data item contains “Norway” when stored to a server, it will contain exactly the same case - “Norway” - when later retrieved by a Client application, or when published to a Subscriber.

However, when performing a query against a stored data item, the WITSML interfaces perform case-insensitive comparisons. If a client application wishes to retrieve (or have published to it) all well objects where “country is equal to Norway”, it could simply specify “norway” and have returned to it objects containing:

       <country>Norway</country>

       <country>norway</country>

       <country>NORWAY</country>

 

       … or any other combination of character case.

► WITSML servers preserve case in persisted string data items, but are not case sensitive when servicing STORE or PUBLISH interface queries against those persisted data items.

Stated another way: string data values which differ only in character case are treated as being “equal”. It therefore follows that the “unique identifier” (UID) data items in the various WITSML data objects - such as “uidWell” - would usually be treated as equal values if they differ only in case.

 

 

 

 

 

 


6.3.2        Query and Subscription Templates

Both the STORE and PUBLISH interfaces utilize the concept of a “Template” to specify which data objects and data items within those objects are to be accessed.

A Template is a well-formed XML document that specifies “by example” what WITSML data objects - and data items within those objects - are to be acted-upon.

The STORE interface uses Query Templates to specify the objects being accessed by the Client application, and the PUBLISH interface uses Subscription Templates to specify the objects to be published to the Subscriber.

Both Query and Subscription Templates are based on the idea of "you get only what you ask for". For example, if you want a list of well objects with the <name> and <country> XML data elements, you would specify:

<wells xmlns="http://www.witsml.org/schemas/131ex">

    <well uid="">

        <name/>

        <country/>

    </well>

</wells>

The returned well data objects might contain:

<wells xmlns="http://www.witsml.org/schemas/131ex">

    <well uid="W-1">

        <name>6507/7-1</name>

        <country>Norway</country>

    </well>

    <well uid="W-2">

        <name>6507/7-2</name>

        <country>Norway</country>

    </well>

    <well uid="W-3">

        <name>EI128/10-2</name>

        <country>United States</country>

    </well>

</wells>

 


 

 

 

 

 

 

 

 

 


Although the Query and Subscription Templates are almost identical in concept, they have minor differences in their usage, and so we’ll discuss them individually in the STORE  and PUBLISH interfaces.

 


7          STORE Interface

7.1         Introduction

The STORE interface provides Client applications the ability to:

§  add a WITSML data object to a Server

§  update an existing WITSML data object on a Server

§  delete an existing WITSML data object on a Server

§  query (retrieve) one or more existing WITSML data objects from a Server

When using the STORE interface, the transfer of WITSML data objects between client and server is initiated by the client. The client application issues the request to access the stored objects - or to a add new one - and the server immediately (synchronously) responds to the request.

The WITSML data objects are exchanged between client and server as XML documents.

The functions (methods) exposed by the STORE interface are prefixed with “WMLS_”.

The WMLS_ functions are exposed to client applications via SOAP (Remote Procedure Call-style). A standardized Web Services Description Language (WSDL) file is used to define the STORE interface exposed via SOAP.

 

 

 

 

 

 

 

 

 



To retrieve a WITSML data object stored on a server, the client application passes the type of WITSML object and a Query Template as parameters to the WMLS_GetFromStore function:

RetVal = WMLS_GetFromStore(‘well‘,                                               ç data object type

                  ‘ <wells><well uid=“123”><name/></well></wells>‘,  ç Query Template

                 OptionsIn,

                 CapabilitiesIn,

                 XMLout,                                                                                ç returned objects

                 SuppMsgOut)

The server’s STORE implementation returns an XML document containing the WITSML object(s) which satisfy the Query Template, and a return value (RetVal) indicating the success or failure of the function.

► Query Templates are described in the next topic.

The client application can also add a single WITSML data object to a server by passing an XML document containing the object to the WMLS_AddToStore function:

RetVal = WMLS_AddToStore("well", StringContainingXML)

And likewise, the client application can update or delete a single WITSML data object stored on the server using the WMLS_UpdateInStore and WMLS_DeleteFromStore functions.

 

 

 

 

 

 

 

 


 


7.2         Query Templates

The following describes the standard behavior of the Query Template. There are some data objects - log, mudLog and trajectory - that have special handling defined which extends this standard behavior (see Appendix D - Special Handling).

 
 

 

 

 


7.2.1        Introduction

The various STORE functions accept a Query Template as an input parameter.

In the example in the previous section, the second parameter is the Query Template. Here we have restructured that example Query Template parameter so that the nesting of the XML elements is more apparent: [3]

<wells xmlns="http://www.witsml.org/schemas/131ex">

the query

 

the Query Template

 
<well uid=”123”>

<nameLegal/>

</well>

</wells>

This Query Template contains only one query, which requests the legal name of the well object that has an ID of “123”.

All Query Templates must contain a plural container element; in this case, “<wells>”.

Within the plural container element can be one or more singular elements of the same data object type; in this case, “<well>”.

The Query Template could have included more than one query:

                 <wells xmlns="http://www.witsml.org/schemas/131ex">

1st query

 
<well uid=”123”>                  

<nameLegal/>

</well>

2nd query

 
<well uid=”456”>                  

<nameLegal/>

</well>

</wells>

Each <well> element in this Query Template is a separate query. Multiple queries can only be specified when retrieving data.

The ability to submit multiple queries for the same data object type is provided merely for efficiency – there is otherwise no relationship between the queries. Each is a separate, standalone query that will result in zero or more well data objects being selected for each.

The data object(s) selected by multiple queries will be returned as separate data objects in one plural container. The data object(s) resulting from query 1 (if any) will be first, followed by the data object(s) resulting from query 2, and so on.

The returned data objects will not be explicitly identified with the query that requested them. When using multiple queries, it is the responsibility of the client to determine which data object(s) were returned as a result of which query, if such a correlation is necessary.


7.2.2        Data Item Selection

The data items – either attributes or elements - to be returned by a query are specified by including the XML attribute(s) or element(s) in the Query Template without an associated value.

For those more comfortable with SQL syntax, this is equivalent to the “column” selection criteria of the SQL Select statement:

SELECT column1, column2, … , columnN

 

 
 

 

 

 

 

 

 


For XML attributes, this is done by specifying:

           

attribute=””

 

For XML elements, this is done by specifying:

 

            <element></element>  or simply  <element/>

 

For example, the following query includes the nameLegal element without a value…

 

            <wells xmlns="http://www.witsml.org/schemas/131ex">

                        <well>

                                    <nameLegal/>

                        </well>

            </wells>

 

…and will return:

 

            <wells xmlns="http://www.witsml.org/schemas/131ex">

                        <well>

                                    <nameLegal>HLH 4 Walker Survey</nameLegal>

                        </well>

                        <well>

                                    <nameLegal>WAThom 6 Sewell Survey</nameLegal>

                        </well>

 

                                    … and so on for all well objects on the server

            </wells>

 

There is no syntax for returning all data items, other than specifying all the attributes/elements individually. However, the query parameter returnElements achieves the same result and is equivalent to the SQL SELECT * statement.


7.2.3        Object Selection

The data objects to be returned by a query are specified by including the attribute(s) or element(s) in the query template with an associated value. The object selectors will be returned by the query in addition to the data item selectors.

 

Or in SQL syntax, this is equivalent to a “where" clause of the SQL Select statement:

     SELECT column1, column2, … , columnN  WHERE column1 = value1, …

 

 
 

 

 

 

 

 

 


For XML attributes, this is done by specifying:

           

attribute=”value”

 

For XML elements, this is done by specifying:

 

             <element>value</element>

 

For example, the following query includes a value of “Mexico” for the country element…

 

            <wells xmlns="http://www.witsml.org/schemas/131ex">

                        <well>

                                    <country>Mexico</country>

                        </well>

            </wells>

 

…and will return only the well objects with a value of “Mexico” in the country element:

 

            <wells xmlns="http://www.witsml.org/schemas/131ex">

                        <well>

                                    <country>Mexico</country>

                        </well>

                        <well>

                                    <country>mexico</country>

                        </well>

                        <well>

                                    <country>MEXICO</country>

                        </well>

            </wells>

 

► See the topic on Case Sensitivity to see why the above results are possible.


7.2.4        Combining Data Item and Object Selection

Object Selection can also be combined with Data Item Selection to return more useful data objects. For example, to retrieve all the Mexico wells, their legal names and their unique identifiers, you can specify:

 

            <wells xmlns="http://www.witsml.org/schemas/131ex">

                        <well uid=””>

                                    <country>Mexico</country>

                                    <nameLegal/>

                        </well>

            </wells>

 

In this example <country> is an Object Selection criteria - because it has a value - and <nameLegal>, and uid are Item Selection criteria, because they have no value.

 

Well data objects will be returned for all Mexico wells on the server and the nameLegal data item and the well’s unique identifiers (UIDs) will also be returned.

 

You can also specify multiple Object Selection criteria in the same query. If instead of returning all the Mexico wells and their legal names, you wished to return all the Mexico wells with the legal name of BossWell, you can specify two Object Selection criteria:

 

            <wells xmlns="http://www.witsml.org/schemas/131ex">

                        <well…>

                                    <country>Mexico</country>

                                    <nameLegal>BossWell</nameLegal>

                                                …

                        </well>

            </wells>

 

► When multiple Object Selection criteria are included in one query, they are AND’ed together. The returned result set will contain only the objects where all the Object Selection criteria are true.

 


► Remember that when multiple queries are included in one Query Template, they are treated as completely separate queries. So, instead of combining the country and nameLegal Object Selection criteria in one query as we did in the example on the previous page, we had instead specified two separate queries:

 

            <wells xmlns=“http://www.witsml.org/schemas/131ex”>

                        <well>

                                    <country>Mexico</country>

                                                …

                        </well>

                        <well>

                                    <nameLegal>BossWell</nameLegal>

                                                …

                        </well>

            </wells>

 

…the results are likely to be quite different from the previous example!  In this case, all the Mexico wells will be returned and all the wells named BossWell, not just the Mexico wells named BossWell.

 

 

 

 

 

 

 

 

 

 

 

 


7.2.5        Selection using Recurring Data Items

When recurring data is included in a query they are OR’ed together.

For example, the following query will return all channels where (uidWell=w1  AND  uidWellbore=w1b  AND  (mnemonic=BPOS  OR  mnemonic=ROP)).

            <realtimes xmlns="http://www.witsml.org/schemas/131ex">
                        <realtime uidWell="w1" uidWellbore="w1b">
                                    <channel>
                                                <mnemonic>BPOS<mnemonic>
                                     </channel>
                                    <channel>
                                                <mnemonic>ROP</mnemonic>
                                     </channel>
                        </realtime>
            </realtimes>

When multiple selection criteria is included in the recurring element, then the criteria are AND’ed together.

For example, the following query will return all channels where (uidWell=w1  AND  uidWellbore=w1b  AND  ((mnemonic=BPOS  AND  qualData=good)  OR  (mnemonic=ROP  AND  qualData=fair))).

            <realtimes xmlns="http://www.witsml.org/schemas/131ex">
                        <realtime uidWell="w1" uidWellbore="w1b">
                                    <channel>
                                                <mnemonic>BPOS<mnemonic>
                                                <qualData>good<qualData>
                                     </channel>
                                    <channel>
                                                <mnemonic>ROP</mnemonic>
                                                <qualData>fair<qualData>
                                     </channel>
                        </realtime>
            </realtimes>

The same selection items must exist in each recurring element.

For example, the following template requests mnemonic in one channel item and md in another. The results of this query are server dependent..

            <realtimes xmlns="http://www.witsml.org/schemas/131ex">
                        <realtime uidWell="w1" uidWellbore="w1b">
                                    <channel>
                                                <mnemonic>BPOS<mnemonic>
                                     </channel>
                                    <channel>
                                                <md uom=”ft”>1000</md>
                                     </channel>
                        </realtime>
            </realtimes>

The selection criteria containing multiple recurring items should be kept simple and unambiguous.

For example, the following template requests mnemonic BPOS both explicity (using <mnemonic>BPOS<mnemonic>) and implicitly (using <mnemonic/>). Some servers may return BPOS two times and some servers may only return it once while other sesrvers may return an error.

            <realtimes xmlns="http://www.witsml.org/schemas/131ex">
                        <realtime uidWell="w1" uidWellbore="w1b">
                                    <channel>
                                                <mnemonic>BPOS<mnemonic>
                                     </channel>
                                    <channel>
                                                <mnemonic/>
                                     </channel>
                        </realtime>
            </realtimes>

The results of the following query with nested recurring selection is also server dependent.

            <mudLogs xmlns="http://www.witsml.org/schemas/131ex">
                        <mudLog uidWell="w1" uidWellbore="w1b" uid=”ml3>
                                    <geologyInterval>
                                                <typeLithology>interpreted< typeLithology >
                                                <lithology>
                                                            <type>Limestone< type >
                                                 </lithology>
                                     </geologyInterval>
                                    <geologyInterval>
                                                <typeLithology>cuttings< typeLithology >
                                                <lithology>
                                                            <type>Salt< type >
                                                 </lithology>
                                     </geologyInterval>
                        </mudLog>
            </mudLogs>

 


7.2.6        Minimum Query Template

A Query Template must be a well-formed XML document which includes only attributes and elements defined by WITSML for the particular data object type.

 

It must include a default namespace declaration for the WITSML namespace (see below), and any other necessary namespace declarations.

 

It need not be a valid document, however, as it can omit attributes/elements that are specified as mandatory in the WITSML XML Schemas.

 

The examples in this specification will utilize the following namespace from the example schema defined in Appendix A:

 

xmlns=”http://www.witsml.org/schemas/131ex”

 

Therefore, the minimum valid Query Template to return all the wells on a server is:

 

<wells xmlns="http://www.witsml.org/schemas/131ex">

<well/>

</wells>

 

For real queries against a server, the namespace of the actual data schema must be substituted for the example data schema namespace.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 



7.3         Authentication and Encryption

The STORE interface uses HTTP/S Basic Authentication, as described in IETF RFC’s 2616 (HTTP 1.1) and 2617 (Authentication).

 

The userid and password transported via the HTTP/S Basic Authentication mechanism can be used by the STORE implementation to perform authorization checking and control of client access.

 

The capabilities and implementation of authorization checking, if any, are not specified by WITSML. It is up to participating companies to agree if authentication is required to access a WITSML server. If it is required, the authentication data should be sent with each WITSML message.

 

Secure Sockets Layer (SSL) for HTTP (HTTPS) can be used to encrypt the HTTP traffic.


7.4         Capabilities Objects

The STORE interface uses two special objects to exchange information about the “capabilities” of the Client and the Server. These special objects are called the Capabilities objects.

 

 

 

 

 

 

 

 

 

 


7.4.1        Client Capabilities (capClient) Object

The Client Capabilities or “capClient” object is used to inform the Server of the Client’s functional capabilities. The capClient object is conveyed as the CapabilitiesIn parameter of various STORE interface functions. It must be passed on each call; the value is not maintained across calls.

 

The CapabilitiesIn parameter may be set to a null string to indicate that no capClient object is being provided. When a capClient object is not provided, default values for the various capabilities are used by the Server.

7.4.2        Server Capabilities (capServer) Object

The Server Capabilities or “capServer” object is used to inform the Client of the Server’s functional capabilities. The capServer object is conveyed as the CapabilitiesOut parameter of the STORE interface’s WMLS_GetCap (Get Capabilities) function.

 


7.4.3        Capabilities by Object

These are the presently defined capabilities that can be exchanged using the capClient and/or the capServer objects:

 

 

Capability:       version of the API which the Client or Server supports

Applies to:       capClient and capServer objects

Conveyed as:  apiVers attribute of the capServer or capClient element

Syntax:            apiVers=”n.n.n”

Default:           1.3.1

Example:         <capServer apiVers=”1.3.1”>

                        </capServer>

Notes:              this is the value to be used if it is necessary to dynamically adapt to
                        differing implementation levels (do not use the version element below)

 

 

Capability:       contact information for the Client or Server

Applies to:       capClient and capServer objects

Conveyed as:  contact child element of the capServer or capClient element

Syntax:            <contact>

                                    <name>xxx…xxx</name>

                                    <email>xxx…xxx</email>

                                    <phone>nnn…nnn</phone>

</contact>

Default:           none

Example:         <contact>

                                    <name>Bob Junior</name>

                                    <email>bobj@aol.com</email>

                                    <phone>1-800-555-1212</phone>

</contact>

Notes:              any descriptive text

 

 

Capability:       description of the Client or Server

Applies to:       capClient and capServer objects

Conveyed as:  description child element of the capServer or capClient element

Syntax:            <description>xxxx…xxxx</description>

Default:           none

Example:         <capServer>

                                    <description>Equip Rm A - Rack 12 - Slot 2</description>

                        </capServer>

Notes:              any descriptive text



 

Capability:       name of the Client or Server

Applies to:       capClient and capServer objects

Conveyed as:  name child element of the capServer or capClient element

Syntax:            <name>xxxx…xxxx</name>

Default:           none

Example:         <capServer>

                                    <name>Server #1</name>

                        </capServer>

Notes:              any descriptive text

 

 

Capability:       vendor (producer) of the software

Applies to:       capClient and capServer objects

Conveyed as:  vendor child element of the capServer or capClient element

Syntax:            <vendor>xxxx…xxxx</vendor>

Default:           none

Example:         <capServer>

                                    <vendor>Acme Downhole Software</vendor>

                        </capServer>

Notes:             

 

 

Capability:       version (build) of the executable program

Applies to:       capClient and capServer objects

Conveyed as:  version child element of the capServer or capClient element

Syntax:            <version>n.n.n.n</version>

Default:           none

Example:         <capServer>

                                    <version>1.3.1.1451</version>

                        </capServer>

Notes:             

 

 

Capability:       schema version(s) that are supported

Applies to:       capClient and capServer objects

Conveyed as:  schemaVersion child element of the capServer or capClient element

Syntax:            <schemaVersion>n.n.n.n,m.m.m.m</ schemaVersion >

Default:           none

Example:         <capClient>

                                    < schemaVersion >1.1.0,1.2.0,1.3.1.0</ schemaVersion >

                        </capClient>

                        <capServer>

                                    < schemaVersion >1.3.1.0</ schemaVersion >

                        </capServer>

Notes:              The values must match the version attribute in the plural object.

                        For capClient, the value is a comma separated list of values without
                        spaces. The oldest version should be listed first.
                        For Servers, the value must match a value that is returned
                        by the WMLS_GetVersion function.

 

 

Capability:       the STORE functions, versions and data objects that the Server
                        supports for each function

Applies to:       capServer object only

Conveyed as:  function child element of the capServer element

                        dataObject child element of the function element

Syntax:            <function name=”xxx” >

                                    <dataObject>xxx</dataObject>

                        </function>

Default:           none (Client should not assume capability exists if not explicitly listed)

Example:         <capServer apiVers=”1.3.1”>

                                    <function name=”WMLS_GetFromStore”>

                                                <dataObject>well</dataObject>

                                                <dataObject>wellbore</dataObject>

                                                <dataObject>log</dataObject>

                                    </function>

                                    <function name=”WMLS_AddToStore” >

                                                <dataObject>log</dataObject>

                                    </function>

                                    <function name=”WMLS_GetVersion”>

                                    </function>

                        </capServer>

Notes:              the example shows supports for only the three specified data object types
                        for WMLS_GetFromStore and only the log object for WMLS_AddToStore.

The function calls are from version 1.3.1 of theAPI. It also supports the WMLS_GetVersion function. The capServer object does not need to specify the WMLS_GetCap function, as this is implied if the capServer object is returned to the Client.


7.5         STORE Functions

This section describes the STORE interface functions.

 

The following functions are defined:

WMLS_AddToStore - add one new object to the server

 

WMLS_DeleteFromStore - delete one existing object from the server

 

WMLS_GetBaseMsg - get the fixed "base" description of a return value

 

WMLS_GetCap - get the server’s Capabilities object

 

WMLS_GetFromStore – gets one or more objects from the server

 

WMLS_GetVersion - retrieves the data version(s) that are supported

 

WMLS_UpdateInStore - update one existing object on the server

 

These functions are documented on the following pages.

 

The realtime object has been designed as a temporary envelope for real-time data. Therefore, the behavior of the WMLS_AddToStore, WMLS_UpdateInStore and WMLS_DeleteFromStore functions for the realtime object is not defined in the WITSML specifications. WMLS_GetFromStore may be used to retrieve the current snapshot of realtime data including the currently available channels. However, the specifications do not prohibit the implementation of the STORE interface functions for the realtime object. Contact each provider for information on his implemented behavior.

 

 

 

 

 


7.5.1        WMLS_AddToStore

Adds one WITSML object to the server. The object is passed in a single XML document, containing a root plural object element (e.g., <wells>) enclosing one singular object element (e.g., <well>). The object is added using the object type specified by WMLtypeIn plus the unique identifier(s) present in the WITSML objects. An object with the same type and unique identifier(s) must not already exist in the persistent store (use WMLS_UpdateInStore if updating an existing object). If a uid value is not defined for the object in the XMLin file, the server will create one and return the created uid value in SuppMsgOut (if there are no errors). All other lower level (child) uid values must be defined in the XMLin file.

integer = WMLS_AddToStore(
                                                      [in] string WMLtypeIn,
                                                      [in] string XMLin,

                                                      [in] string OptionsIn,

                                                      [in] string CapabilitiesIn,

                                                      [out] string SuppMsgOut
                                                       );

 

Parameters (all required):

 

WMLtypeIn   - input string - not case sensitive

                        - one WITSML object type

  (see the specific WITSML data schema)


XMLin           - input string - case sensitive (an XML document - see Notes)

- the WITSML object(s) to be added (see Notes)

- the XML should conform to the derived “write” schema where child and parentage uids are mandatory.

           

            OptionsIn       - input string

                                    - for future use

            CapabilitiesIn - input string - case sensitive (an XML document)

                                     - the client’s capabilities object (capClient) to be sent to the
                                       Server; may be a null string if no capabilities object is to
                                       be provided to the Server

            SuppMsgOut    - output string

                                       - Supplemental message text. If a uid is created for
                                         the object, the created uid value will be returned in this string.
                                         The uid value will not be returned if there are any errors.

Return Value:
short                (see Appendix C)


WMLS_AddToStore (continued)

 

Notes:

            1) the object is added to the server using the passed type (WMLtypeIn) plus
                the unique identifier(s) present in the object (XMLin); unique identifiers are
                not passed as separate parameters. The following XMLin will add a new well
                object with the UID of “new1”:

 

                        <wells xmlns=“http://www.witsml.org/schemas/131ex”>

                                    <well uid=”new1”>

                                                …

                                    </well>

                        </wells>

 

 

            2) the XML document must contain the plural container object as its root XML
                element, even though it encloses only one WITSML object:

 

                        <wells …>      [required even though there is only one <well> element]

                                    <well uid=”new4”>

                                                …

                                    </well>

                        </wells>

3) upper/lowercase string data values present in the XMLin string will be stored exactly as supplied: “preserving their case”. Subsequent WMLS_GetFromStore invocations will return the string data values in their originally supplied case.

4) All values with an underlying type of xsd:dateTime should have time zone information specified. This is very important because, otherwise, software toolsets such as .NET will commonly "assume" a time zone such as the client local, server local or Zulu (Greenwich). Once an assumption has been made, it is not possible to distinguish whether the information was known or was assumed. The proper XML Schema format for dateTime must be followed (see http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/#dateTime).

5) A best practice for clients is to always use pointers (e.g., uidWell, uidRef) whose value exactly matches the related uid value because:

1.      Some servers may reject an added object if the case of a parentage uid pointer does not match the parent uid.

2.      Some servers may accept an added object if the case of a parentage uid pointer does not match the parent uid but may change the pointer to match the uid.

3.      Some servers may enforce referential integrity of all pointers using a case sensitive constraint.

6) A best practice with all growing objects is for clients to always use the index (e.g., measured depth) unit of measure from the header for all index values (including an index curve) in an object. Note that by extension, this implies using the datum values from the header for elevation, measured depth and vertical depth indices. This unit and datum should be used when adding (appending) data to a growing object.An easy way to determine the server unit and datum for indices is to look at the minimum index from the object header.

7)A best practice with all systematically objects is for clients to always use the curve unit of measure from the header when adding (appending) data to a growing object.

 

 


7.5.2        WMLS_DeleteFromStore

Permanently deletes one WITSML object from the server. The object to be deleted is specified by the WMLTypeIn and QueryIn parameters.

 

integer = WMLS_DeleteFromStore(

                                                              [in] string WMLtypeIn,

                                                              [in] string QueryIn,

                                                              [in] string OptionsIn,

                                                              [in] string CapabilitiesIn,

                                                              [out] string SuppMsgOut

                                                              );

 

Parameters (all required):

 

WMLtypeIn   - input string - not case sensitive

- one WITSML object type

  (see the specific WITSML data schema)


            QueryIn          - input string - case sensitive (an XML document)

- a Query Template that specifies the unique identifiers

  of the objects to be deleted
- The XML should conform to a derived “delete” schema where all elements and attributes are optional except that all object and parentage uids are mandatory.

 

            OptionsIn       - input string

                                    - for future use

            CapabilitiesIn - input string - case sensitive (an XML document)
                                     - the client’s capabilities object (capClient) to be sent to the
                                       Server; may be a null string if no capabilities object is to
                                       be provided to the Server

            SuppMsgOut - output string

                                    - supplemental message text

 

 

Return Value:

short                (see Appendix C - Defined Values)

 


WMLS_DeleteFromStore (continued)

 

Notes:

 

1) The client application specifies the object to be deleted using a Query Template, passed via the QueryIn parameter. The uid for the object and its parents must be specified. For example, the following will delete a specific wellbore object as identified by the uidWell and uid attributes

       <wellbores xmlns=“http://www.witsml.org/schemas/140ex”>

              <wellbore uidWell=”12345” uid=”01” />

            </wellbores>

 

2) Cascading deletes are not supported. Only bottom level objects should be deleted and all child objects should be deleted before the parent is deleted. For example, a child wellbore should be deleted before the parent well is deleted. That is, a server is not required to support referential integrity.

3) To eliminate the likelihood of accidental deletion of multiple objects, WMLS_DeleteFromStore requires that the object present in the Query Template must contain the unique identifier(s) (UIDs) of one object to be deleted.

 

You cannot, for example, request WMLS_DeleteFromStore – in one step - to delete all the wells where <country> is Mexico [4]

            <wells xmlns=“http://www.witsml.org/schemas/131ex”>     

                        <well> [this will fail because there is no uid specified]

                                    <country>Mexico</country>

                        </well>

            </wells>

 



 

 


 

WMLS_DeleteFromStore (continued)

 

4) If the client application needs to delete multiple objects based on selection criteria other than the UID, it can first use WMLS_GetFromStore to retrieve the UIDs of the objects based on the necessary criteria, then repetitively pass each returned object containing the UIDs to WMLS_DeleteFromStore.

For example, to delete all the planned well objects from a server:

a) use WMLS_GetFromStore to query for the UID of all the planned well objects. The QueryIn parameter of WMLS_GetFromStore would contain:

                        <wells xmlns=“http://www.witsml.org/schemas/131ex”>

                                    <well uid=““>

                                                <itemState>Planned</itemState>

                                    </well>

</wells>

b) pass the returned well object(s) in multiple calls to WMLS_DeleteFromStore. The QueryIn parameter of the first WMLS_DeleteFromStore might contain:

<wells xmlns=“http://www.witsml.org/schemas/131ex”>

            <well uid=“123”/>

</wells>

While the next one might contain:

<wells xmlns=“http://www.witsml.org/schemas/131ex”>

            <well uid=“456”/>

</wells>

5) A server shall use a caseless compare against uid values (as it does for all other values).

6) See section “STORE and PUBLISH behavior” for additional behavior related to growing objects.

 

7.5.3        WMLS_GetBaseMsg

Returns a string containing the fixed ("base") message text associated with a return value.

 

string = WMLS_GetBaseMsg(
                                                    [in] integer ReturnValueIn
                                                     );

 

Parameters (all required):

 

ReturnValueIn - input integer

                                       - a valid Return Value (see Appendix C - Defined Values)

 

Return Value:

string               - the fixed descriptive message text associated with the Return
                                      Value (a null string is returned if ReturnValueIn is invalid)

 

Notes:

 

1) this function returns only the fixed description of the specified Return Value.

2) Variable, context-specific "supplemental" message text and diagnostic
    information, if any, is returned in the SuppMsgOut parameter of the various
    STORE functions.


7.5.4        WMLS_GetCap

Returns the capServer object that describes the capabilities of the Server for one data schema. The capServer object is returned in the form of an XML document. Multiple calls to WMLS_GetCap are required in order to determine the capabilities of the server for all data schemas that it supports.

 

integer = WMLS_GetCap(

                                             [in] string OptionsIn,

                                             [out] string CapabilitiesOut,

                                             [out] string SuppMsgOut

                                             );

 

Parameters (all required):

 

            OptionsIn       - input string

- The keyword "dataVersion" with a value of a data schema version specifies that capabilities information is desired for that particular data version. The returned capabilities object will utilize the namespace that is appropriate for the data version. For example:
            dataVersion=1.3.1.0
requests information about data version 1.3.1.0 utilizing a 1.3.1 capabilities object. The data schemas that are supported by the server can be determined using WMLS_GetVerson. The version string must match the value of attribute "version" on the plural object container. The default is for the server to return information about the oldest data version that is supported by the server.

 

CapabilitiesOut - output string - case sensitive (an XML document)

 

SuppMsgOut             - output string

                        - supplemental message text

 

 

 

Return Value:

short                (see Appendix C - Defined Values)

 

Notes:

1)      The OptionsIn parameter string is encoded utilizing a subset of the encoding rules for HTML form content type application/x-www-form-urlencoded as specified at http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.13.3.3
The encoding is constrained by only allowing semicolons for separators and by not allowing whitespace. For example, “param1=value1;param2=value2”.

2)      Clients based on this specification should always pass the dataVersion OptionsIn parameter to the server because the server may support multiple versions and the client needs to specify which version it understands. For example, WMLS_GetVersion may return “1.2.0,1.3.1.0” so the v1.3.1 client needs to specify “dataVersion=1.3.1” or the server will return the older v1.2 capabilities object. The resultant CapabilitiesOut would contain something like the following:

<capServers … version=”1.3.1”> <!— API schema version ->

   <capServer apiVers="1.3.1"> <!— API behavior version ->

      <contact>

         <name>Server contact name</name>

         <email>serverAdministrator@serverCompany.com</email>

         <phone>281-135-7924</phone>

      </contact>

      <description>Server description</description>

      <name>John Smith</name>

      <vendor>INSITE Server #1</vendor>

      <version>1.1.0.120</version> <!— Executable build ->

      <schemaVersion>1.3.1</schemaVersion> <!— API schema version ->

      <function name="GetCap">

         <dataObject>capServer</dataObject> <!— Supported API object ->

         <dataObject>capPublisher</dataObject>

      </function>

   <capServer>

   <capServer apiVers="1.3.1">

      <contact>

         <name>Server contact name</name>

         <email>serverAdministrator@serverCompany.com</email>

         <phone>281-135-7924</phone>

      </contact>

      <description>Server description</description>

      <name>John Smith</name>

      <vendor>INSITE Server #1</vendor>

      <version>1.1.0.120</version> <!— Executable build ->

      <schemaVersion>1.3.1.1</schemaVersion> <!— Data schema version ->

      <function name="GetFromStore">

         <dataObject>well</dataObject> <!— Supported Data object ->

         <dataObject>wellbore</dataObject>

      </function>

   <capServer>

</capServers>

The apiVersion of “1.3.1” will be returned because that is the API version which is associated with the requested v1.3.1.1 Data Schema. Each Data Schema is assumed to be used with only one API version (i.e., the active API at the time of the schema release). This is because the current interface requires that a Data Schema only be used with one version of the API (including any corrigendums). Correspondingly, the API requires a specific version of the API Schemas. The API Schemas associated with this API version are v1.3.1.

 

7.5.5        WMLS_GetFromStore

Returns one or more WITSML objects from the Server. The objects are returned in the form of an XML document containing a root plural object element (e.g., <wells>) enclosing one or more singular object elements (e.g., <well>). The objects to be retrieved are identified by the object type and Query Template passed to the function.

 

integer = WMLS_GetFromStore(

 [in] string WMLtypeIn,

 [in] string QueryIn,

                                                             [in] string OptionsIn,

                                                             [in] string CapabilitiesIn,

 [out] string XMLout,

                                                             [out] string SuppMsgOut
                                                          );

 

Parameters (all required):

 

WMLtypeIn   - input string - not case sensitive

                        - one WITSML object type

 (see the specific WITSML data schema)

            QueryIn          - input string - case sensitive (an XML document)

- a Query Template that specifies the objects to be returned
- because QueryIn can contain empty elements, it cannot be schema validated but otherwise the XML should conform to a derived “read” schema where all elements and attributes are optional.

 

OptionsIn       - input string

- The keyword of ‘returnElements’ with a value of "all" requests that all elements and attributes be returned. The template should be treated as if all elements and attributes had explicitly been specified in the template. A value of "requested" requests the mode of "you only get what you ask for". For example:
            returnElements=all

The default is "requested".

 

            CapabilitiesIn - input string - case sensitive (an XML document)

- the client’s capabilities object (capClient) to be sent to the
  Server; may be a null string if no capabilities object is to
  be provided to the Server

XMLout         - output string - case sensitive

- the returned WITSML object(s) as an XML document

- the XML should conform to a derived “read” schema where all elements and attributes are optional.

 

            SuppMsgOut - output string

                                    - supplemental message text

 

WMLS_GetFromStore (continued)

 

Return Value:

short                (see Appendix C - Defined Values)

 

Notes:

1) output parameters are valid only if Return Value = 1

 

2) no locking of the object is performed on the server

 

3) the returned document will contain a plural container object as its root XML element, enclosing zero or more singular object elements:

 

                        <wells xmlns=“http://www.witsml.org/schemas/131ex”>

                                    <well…>

                                                …

                                    </well>

                                    <well…>

                                                …

                                    </well>

                        </wells>

 

4) if the Query Template does not result in any objects being returned, the returned document will contain only the plural container element:

 

                        <wells/>

 

5) when multiple queries are present in the Query Template, the sets of objects returned by the queries are returned in the order in which the queries were specified.

 

If the Query Template specified:

 

            <wells xmlns=“http://www.witsml.org/schemas/131ex”>

                        <well…>

                                    <country>UK</country>

                        </well>

                        <well…>

                                    <country>Norway</country>

                        </well>

            </wells>

 

The set of well objects in the UK (if any) would be returned before the set of well objects in Norway (if any).

 

► The individual well objects within each set would be unordered, however.

6) The inclusion of a uom value in a query is to be regarded as a request for unit conversion, not a query filter. See section “Process interaction with ‘uom’”.

7) If no value is available for an element or attribute then nothing will be returned. That is, empty values will not be returned,

8) The elements will be returned in the order defined by the schema.

9) The order of the recurring data within an object is server dependent. The order that a client added components will not necessarily be retained unless the schema documents some significance of the order. In the resulting XML, nothing has a predefined sort order except for the data rows in systematically growing objects. The order in all cases but systematically growing objects is server dependent (sometimes based on the order defined by clients). This includes the sub-components of randomly growing objects (i.e., trajectory and mudLog). If a client wants nodes in a particular order then it will need to sort the nodes itself.

10) If multiple queries are contained in the template and one query fails then all of the queries will fail.

11) The Extended Query Syntax that was in version 1.0 was eliminated from the standard in version 1.2.

12) For various reasons, some servers may impose restrictions on retrievals. For example, because the log data section can be so voluminous, a server may impose constraints when retrieving curve data (as opposed to only retrieving header data):

a)      A server may require that a specific log be identified

b)      A server may not allow a request for all logs from one well.

c)      A server may not allow a request for all logs from all wells.

 

13) The normal behavior for a server is to return only “what you ask for”. That is, in order for an element to be returned it has to exist in the query template. This includes uom attributes (see “Appendix B - Unit of Measure”).

a)      For the special case of <customData> (see “Appendix F - Custom Data”), all sub-nodes will be returned if only the customData element is specified. Querying sub-nodes of customData is server dependent.

b)      For the special category called growing objects, special behavior has been defined. See “Appendix D – Special Handling” for a discussion of growing objects and their special behavior.

c)      For various reasons, some servers may return more than was requested, such as all mandatory items. Servers will always return what was requested if it exists – subject to restrictions as noted in a previous note.

14) For realtime, if the client pulls more frequently than the server has fresh data then the same realtime will be repetitively returned until new data is available. It is the clients responsibility to inspect for duplicates based on the indices (e.g., dTim and md).

15) The OptionsIn parameter string is encoded utilizing a subset of the encoding rules for HTML form content type application/x-www-form-urlencoded as specified at http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.13.3.3. The encoding is constrained by only allowing semicolons for separators and by not allowing whitespace. For example, “param1=value1;param2=value2”.

16) The QueryIn template will not be schema compliant if it contains empty values. If it does not contain empty values, it should be schema compliant against a derived “read” schema where all elements and attributes are optional. The OptionsIn keyword returnElements with a value of “all” can be used to construct a query without empty values.

17) The commonData elements dTimCreation and dTimLastChange shall be treated by the server as a request for comparisons of "greater than" rather than "equal". This is an exception to the normal behavior of "equal" comparisons.

18) The suggested mechanism for detecting active wellbores is to look for changes in mdCurrent or in object's dTimLastChange. Servers should attempt to keep mdCurrent reasonably up to date and should modify dTimLastChange when data within an object is modified.

19) If structural range client values are requested in a randomly growing object (i.e., mudLog startMd/mdTop, trajectory mdMn/mdMx) then the returned values should represent the minimum and maximum values within that range whether returned (i.e., data requested) or in-store (i.e., only header requested). Minimum means the nearest to the surface measured along the borehole. This is in contrast to the returned values in a systematically growing object (i.e., log, wellLog) where the values represent the first and last values. The difference is because systematically growing objects are ordered while the randomly growing objects are not necessarily sorted (i.e., the actual order is server dependent). See section STORE and PUBLISH behavior, items 1.b through 1.e for detailed behavior.

20) A client should expect systematically growing object (i.e, log and wellLog) data to be returned in chunks. A recommended practice is to first retrieve the header of the object and then retrieve the data components. After each call, compare the returned structural range values to those defined in the header to see if all data has been returned. If not then execute a new call requesting data from the end of the previous return. If the object is growing, then element dTimLastChange should be monitored to determine when new data has been registered.

21) A server shall use a caseless compare against uid values (as it does for all other values).

7.5.6        WMLS_GetVersion

Returns a string containing the version(s) of data schemas that are supported by the server. A particular data version can be passed to WMLS_GetCap via its OptionsIn parameter to request information about the server capabilities with respect to that data version.

 

string = WMLS_GetVersion();

 

Parameters:

 

none

 

Return Value:

string               - A comma separated list of schema versions (without spaces) that
                                       are supported by the server. The oldest version should be listed
                                       first, followed by the next oldest, etc.

                       

                        Example: 1.2.0,1.3.1.0

 

Notes:

 

Each version number must match the contents of the version attribute on the plural container element for each object.

 

For more information, see the topic on Versioning in the Terminology and Basic Concepts section of this document.


7.5.7        WMLS_UpdateInStore

Updates one existing WITSML object on the Server. The WITSML object with the updated/added values is passed in a single XML document, containing a root plural object element (e.g., <wells>) enclosing one singular object element (e.g., <well>). The object to be updated is identified using the object type specified by WMLtypeIn plus the unique identifier(s) present in the object. An object with the same type and unique identifier(s) must already exist in the persistent store (use WMLS_AddToStore if adding a new object).

 

 

integer = WMLS_UpdateInStore(
                                                          [in] string WMLtypeIn,

                                                          [in] string XMLin,

                                                          [in] string OptionsIn,

                                                          [in] string CapabilitiesIn,

                                                          [out] string SuppMsgOut
                                                           );

Parameters (all required):

 

WMLtypeIn   - input string - not case sensitive

                        - one WITSML object type

              (see the specific WITSML data schema)


XMLin           - input string - case sensitive (an XML document)

- the updated WITSML object(s)

- the XML should conform to a derived “update” schema where all elements and attributes are optional except for all uid and uom attributes which are mandatory.

 

            OptionsIn       - input string

- for future use

 

CapabilitiesIn  - input string - case sensitive (an XML document)
                                      - the client’s capabilities object (capClient) to be sent to the
                                        Server; may be a null string if no capabilities object is to
                                        be provided to the Server

            SuppMsgOut - output string

                                    - supplemental message text

 

 

Return Value:

short                (see Appendix C - Defined Values)


WMLS_UpdateInStore (continued)

 

Notes:

 

1) the document must contain the required plural container item as its root XML element

2) The XMLin document must uniquely identify one object to be updated by including the unique identifier of the object.

 

3) Recurring nodes within an object can be updated if they have a uid value. A recurring element cannot be specified without a uid. If a recurring element does not have a uid (in the schema) then all nodes of that element will be replaced when that element is updated. For example, within a specific geologyInterval of a specific mudLog, the following will replace all existing nameFormation data.

<mudLogs xmlns=“http://www.witsml.org/schemas/131ex”>

      <mudLog uidWell="W-12" uidWellbore="B-01" uid="h45a">
            <geologyInterval uid="312">

                  <nameFormation>Entrada Sandstone</nameFormation>

            </geologyInterval>

      </mudLog>

</mudLogs>

4) An element (container or not) in an existing container occurrence (recurring or not) can be altered without changing anything else in the container (a container element contains other elements). In the example above, nameFormation within the geologyInterval is changed without changing any other elements or attributes within that geologyInterval.

5) An attribute can be altered without changing anything else in the element. That is, similar to an element, an attribute can be changed without changing any other content of the attribute's parent element.

6) Specifying a value for an existing non-container element (i.e., cannot contain other elements) will replace the value for that element. There is no check to see if the value is actually different. For example, the following will update the itemState of well “123”.

<wells xmlns=“http://www.witsml.org/schemas/131ex”>

      <well uid=“123“>

            <itemState>Planned</itemState>

      </well>

      </wells>

7) Specifying a value for an existing attribute will replace the value for that attribute. There is no check to see if the value is actually different.

8) Any new element or attribute will be inserted. A recurring container with a new unique identifier value is a new element. New elements or attributes cannot be empty. For example, the following will insert a new trajectoryStation, assuming that it did not already exist: If it already existed, it would change the value of name, etc

<trajectorys xmlns=“http://www.witsml.org/schemas/131ex”>

      <trajectory uidWell="W-12" uidWellbore="B-01" uid="pe84e">

            <trajectoryStation  uid=”456”>

                  <name>new station</name>

            </trajectoryStation>

      </trajectory>

      </trajectorys>

9) After applying the update, a retrieval of everything must be schema compliant with the “write” schema. For example, mandatory items cannot be totally eliminated because they are constrained by minOccurs.

10) A uom attribute cannot be specified unless its corresponding value is specified. This prevents any assumption that a client can influence the default unit of measure. For example in the following, the md in the first station is not allowed but the md in the second station is OK.

<trajectorys xmlns=“http://www.witsml.org/schemas/131ex”>

      <trajectory uidWell="W-12" uidWellbore="B-01" uid="pe84e">

Invalid because the md value not specified.

 

 
            <trajectoryStation  uid=”123”>

                  <md uom=”ft” />

            </trajectoryStation>

OK because the md value is specified.

 
            <trajectoryStation  uid=”123”>

                  <md uom=”ft”>667.4</md>

            </trajectoryStation>

      </trajectory>

</trajectorys>

11) The client should always specify the relevant unit of measure information or the server may reject the update. That is, a measure value should not be specified without its uom attribute and log curve data should not be specified without specifying the curve unit element.

12) A client best practice is to use the same index (e.g., measured depth) units for all index values (including an index curve) in an object. Note that by extension, this means that all datum values should be the same when the index is measured depth. This constraint is desirable because the indices are frequently compared by everyone. An easy way to determine the server unit and datum for indices is to look at the minimum index from the object header.

13) A client best practice is to utilize the server units defined in the log header of a WMLS_GetFromStore result. However, a server shall honor whatever units (e.g., startIndex/@uom) the client specifies in a WMLS_UpdateInStore request. This does not mean that the server will internally store the data in the client units. It only means that the server must convert the client values to the server internal units.

14) All values with an underlying type of xsd:dateTime should have time zone information specified. This is very important because, otherwise, software toolsets such as .NET will commonly "assume" a time zone such as the client local, server local or Zulu (Greenwich). Once an assumption has been made, it is not possible to distinguish whether the information was known or was assumed. The proper XML Schema format for dateTime must be followed (see http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/#dateTime).

15) An empty non-container element (i.e., cannot have child elements) will delete its value and any attributes. For example, the following will delete the country element in the specified well object.

<wells xmlns=“http://www.witsml.org/schemas/140ex”>  

            <well uid=”12345”>

                  <country />

            </well>

      </wells>

16) A server shall use a caseless compare against uid values (as it does for all other values). If more than one node is matched, an error shall be issued.

17) You cannot include Object Selection criteria in the XML document passed in XMLin. For example, you cannot change all the legal names of all the wells in Scotland by merely specifying:

 

            <wells xmlns=“http://www.witsml.org/schemas/131ex”>

                        <well>

                                    <nameLegal>changed Legal Name</nameLegal>

            <country>Scotland</country>

                        </well>                       

            </wells>

 

WMLS_UpdateInStore would not be able to determine which values were selection criteria and which were merely new values to be updated (and the update would fail nevertheless, since there is no UID specified for the well…see Note #2).


WMLS_UpdateInStore (continued)

 


You can accomplish the same task in three steps, however:

 

a) use WMLS_GetFromStore to select the UIDs of all the wells in Scotland. The QueryIn parameter passed to WMLS_GetFromStore would be:

            <wells xmlns=“http://www.witsml.org/schemas/131ex”>

                        <well uid=””>

                                    <nameLegal/>

            <country>Scotland</country>

                        </well>                       

            </wells>

 

This might return:

 

            <wells xmlns=“http://www.witsml.org/schemas/131ex”>

                        <well uid=”123”>

                                    <nameLegal>existing legal name of 123</nameLegal>

                                    <country>Scotland</country>

                        </well>

                        <well uid=”456”>

                                    <nameLegal>existing legal name of 456</nameLegal>

                                    <country>Scotland</country>

                        </well>                       

            </wells>

 

b) programmatically update the legal names in the returned document to their new values and split into multiple documents:


            <wells xmlns=“http://www.witsml.org/schemas/131ex”>

                        <well uid=”123”>

                                    <nameLegal>changed legal name of 123</nameLegal>

                        </well>

            </wells>

and
            <wells xmlns=“http://www.witsml.org/schemas/131ex”>

                        <well uid=”456”>

                                    <nameLegal>changed legal name of 456</nameLegal>

                        </well>

            </wells>

 

c) pass the updated documents to WMLS_UpdateInStore in multiple calls. Each <well> element will then update its persisted object with the new legal name


7.6         STORE Interface - WSDL File

The Web Service Description Language (WSDL) file used to expose the STORE interface to SOAP clients is listed below. A narrative describing several key points follows the file listing.

 

 

 

 

 

 

 

 

 

 

 

 



7.6.1        File Listing

<?xml version='1.0' encoding='UTF-8' ?>

 

<definitions name='WMLS' targetNamespace='http://www.witsml.org/wsdl/120'

     xmlns:wsdlns='http://www.witsml.org/wsdl/120'

     xmlns:soap='http://schemas.xmlsoap.org/wsdl/soap/'

     xmlns:xsd='http://www.w3.org/2001/XMLSchema'

     xmlns='http://schemas.xmlsoap.org/wsdl/'>

 

<documentation>WITSML Version 1.2.0 STORE interface WSDL file

</documentation>

 

<!-- Abstract Definitions Section - <types>, <message> and <portType> elements -->

 

<!-- <types> element declares user-defined machine and language independent data types, and is not needed for the WITSML STORE interface, which uses only W3C-defined data types -->

 

<!-- <message> elements define request/response messages and their parameters-->

 

<message name='Store.WMLS_AddToStore'>

     <part name='WMLtypeIn' type='xsd:string'/>

     <part name='XMLin' type='xsd:string'/>

     <part name='OptionsIn' type='xsd:string'/>

     <part name='CapabilitiesIn' type='xsd:string'/>

</message>

 

<message name='Store.WMLS_AddToStoreResponse'>

     <part name='Result' type='xsd:short'/>

     <part name='SuppMsgOut' type='xsd:string'/>

</message>

 


 

<message name='Store.WMLS_DeleteFromStore'>

     <part name='WMLtypeIn' type='xsd:string'/>

     <part name='QueryIn' type='xsd:string'/>

     <part name='OptionsIn' type='xsd:string'/>

     <part name='CapabilitiesIn' type='xsd:string'/>

</message>

 

<message name='Store.WMLS_DeleteFromStoreResponse'>

     <part name='Result' type='xsd:short'/>

     <part name='SuppMsgOut' type='xsd:string'/>

</message>

 

 

<message name='Store.WMLS_GetBaseMsg'>

     <part name='ReturnValueIn' type='xsd:short'/>

</message>

             

<message name='Store.WMLS_GetBaseMsgResponse'>

     <part name='Result' type='xsd:string'/>

</message>

 

 

<message name='Store.WMLS_GetCap'>

     <part name='OptionsIn' type='xsd:string'/>

</message>

             

<message name='Store.WMLS_GetCapResponse'>

     <part name='Result' type='xsd:short'/>

     <part name='CapabilitiesOut' type='xsd:string'/>
     <part name='SuppMsgOut' type='xsd:string'/>

</message>

 

 

<message name='Store.WMLS_GetFromStore'>

     <part name='WMLtypeIn' type='xsd:string'/>

     <part name='QueryIn' type='xsd:string'/>

     <part name='OptionsIn' type='xsd:string'/>

     <part name='CapabilitiesIn' type='xsd:string'/>

</message>

   

<message name='Store.WMLS_GetFromStoreResponse'>

     <part name='Result' type='xsd:short'/>

     <part name='XMLout' type='xsd:string'/>

     <part name='SuppMsgOut' type='xsd:string'/>

</message>

 

 

<message name='Store.WMLS_GetVersion'>

</message>

   

<message name='Store.WMLS_GetVersionResponse'>

     <part name='Result' type='xsd:string'/>

</message>

 

 

<message name='Store.WMLS_UpdateInStore'>

     <part name='WMLtypeIn' type='xsd:string'/>

     <part name='XMLin' type='xsd:string'/>

     <part name='OptionsIn' type='xsd:string'/>

     <part name='CapabilitiesIn' type='xsd:string'/>

</message>

 

<message name='Store.WMLS_UpdateInStoreResponse'>

     <part name='Result' type='xsd:short'/>

     <part name='SuppMsgOut' type='xsd:string'/>

</message>

 

 

<!-- <portType> element groups the functions (operations) into an interface -->

 

<portType name='StoreSoapPort'>

 

<!-- <operation> elements define the function signatures (operation name and parameters) and associate the input and output messages -->

<!-- parameterOrder attribute values must be separated by a single space -->

     <operation name='WMLS_AddToStore' parameterOrder='WMLtypeIn XMLin           OptionsIn CapabilitiesIn SuppMsgOut'>

          <input message='wsdlns:Store.WMLS_AddToStore' />

          <output message='wsdlns:Store.WMLS_AddToStoreResponse' />

     </operation>

   

     <operation name='WMLS_DeleteFromStore' parameterOrder='WMLtypeIn QueryIn        OptionsIn CapabilitiesIn SuppMsgOut'>

          <input message='wsdlns:Store.WMLS_DeleteFromStore' />

          <output message='wsdlns:Store.WMLS_DeleteFromStoreResponse' />

     </operation>

   


 

     <operation name='WMLS_GetBaseMsg' parameterOrder='ReturnValueIn'>

           <input message='wsdlns:Store.WMLS_GetBaseMsg' />

           <output message='wsdlns:Store.WMLS_GetBaseMsgResponse' />

     </operation>

   

     <operation name='WMLS_GetCap' parameterOrder='OptionsIn CapabilitiesOut             SuppMsgOut'>

          <input message='wsdlns:Store.WMLS_GetCap' />

          <output message='wsdlns:Store.WMLS_GetCapResponse' />

     </operation>

           

     <operation name='WMLS_GetFromStore' parameterOrder='WMLtypeIn QueryIn OptionsIn CapabilitiesIn XMLout SuppMsgOut'>

          <input message='wsdlns:Store.WMLS_GetFromStore' />

          <output message='wsdlns:Store.WMLS_GetFromStoreResponse' />

     </operation>

           

     <operation name='WMLS_GetVersion'>

          <input message='wsdlns:Store.WMLS_GetVersion' />

          <output message='wsdlns:Store.WMLS_GetVersionResponse' />

     </operation>

         

      <operation name='WMLS_UpdateInStore' parameterOrder='WMLtypeIn XMLin OptionsIn CapabilitiesIn SuppMsgOut'>

          <input message='wsdlns:Store.WMLS_UpdateInStore' />

          <output message='wsdlns:Store.WMLS_UpdateInStoreResponse' />

     </operation>

 

</portType>

 

<!-- Concrete Definitions Section - <binding> and <service> elements -->

 

<!-- <binding> specifies the protocol binding for each operation in the <portType> section -->

 

<binding name='StoreSoapBinding' type='wsdlns:StoreSoapPort' >

 

     <soap:binding style='rpc' transport='http://schemas.xmlsoap.org/soap/http' />

 

     <operation name='WMLS_AddToStore' >

          <soap:operation

             soapAction='http://www.witsml.org/action/120/Store.WMLS_AddToStore' />

          <input>

               <soap:body use='encoded' namespace='http://www.witsml.org/message/120'

                       encodingStyle='http://schemas.xmlsoap.org/soap/encoding/' />

           </input>

           <output>

                <soap:body use='encoded' namespace='http://www.witsml.org/message/120'

                       encodingStyle='http://schemas.xmlsoap.org/soap/encoding/' />

           </output>

     </operation>

   

     <operation name='WMLS_DeleteFromStore' >

          <soap:operation

           soapAction='http://www.witsml.org/action/120/Store.WMLS_DeleteFromStore' />

          <input>

                <soap:body use='encoded' namespace='http://www.witsml.org/message/120'

                       encodingStyle='http://schemas.xmlsoap.org/soap/encoding/' />

          </input>

          <output>

               <soap:body use='encoded' namespace='http://www.witsml.org/message/120'

                      encodingStyle='http://schemas.xmlsoap.org/soap/encoding/' />

           </output>

     </operation>

 

     <operation name='WMLS_GetBaseMsg' >

          <soap:operation

             soapAction='http://www.witsml.org/action/120/Store.WMLS_GetBaseMsg' />

          <input>

              <soap:body use='encoded' namespace='http://www.witsml.org/message/120'

                     encodingStyle='http://schemas.xmlsoap.org/soap/encoding/' />

          </input>

          <output>

               <soap:body use='encoded' namespace='http://www.witsml.org/message/120'

                    encodingStyle='http://schemas.xmlsoap.org/soap/encoding/' />

           </output>

     </operation>

 

     <operation name='WMLS_GetCap' >

          <soap:operation

             soapAction='http://www.witsml.org/action/120/Store.WMLS_GetCap' />

          <input>

              <soap:body use='encoded' namespace='http://www.witsml.org/message/120'

                     encodingStyle='http://schemas.xmlsoap.org/soap/encoding/' />

         </input>

         <output>

              <soap:body use='encoded' namespace='http://www.witsml.org/message/120'

                 encodingStyle='http://schemas.xmlsoap.org/soap/encoding/' />

         </output>

     </operation>

 

     <operation name='WMLS_GetFromStore' >

          <soap:operation soapAction='http://www.witsml.org/action/120/Store.WMLS_GetFromStore' />

          <input>

              <soap:body use='encoded' namespace='http://www.witsml.org/message/120'

                  encodingStyle='http://schemas.xmlsoap.org/soap/encoding/' />

         </input>

         <output>

            <soap:body use='encoded' namespace='http://www.witsml.org/message/120'

                encodingStyle='http://schemas.xmlsoap.org/soap/encoding/' />

         </output>

     </operation>

   

     <operation name='WMLS_GetVersion' >

          <soap:operation soapAction='http://www.witsml.org/action/120/Store.WMLS_GetVersion' />

         <input>

             <soap:body use='encoded' namespace='http://www.witsml.org/message/120'

                  encodingStyle='http://schemas.xmlsoap.org/soap/encoding/' />

         </input>

         <output>

             <soap:body use='encoded' namespace='http://www.witsml.org/message/120'

                  encodingStyle='http://schemas.xmlsoap.org/soap/encoding/' />

         </output>

      </operation>

 

     <operation name='WMLS_UpdateInStore' >

           <soap:operation

             soapAction='http://www.witsml.org/action/120/Store.WMLS_UpdateInStore' />

           <input>

                 <soap:body use='encoded' namespace='http://www.witsml.org/message/120'

                    encodingStyle='http://schemas.xmlsoap.org/soap/encoding/' />

           </input>

           <output>

                 <soap:body use='encoded' namespace='http://www.witsml.org/message/120'

                          encodingStyle='http://schemas.xmlsoap.org/soap/encoding/' />

           </output>

    </operation>

 

  </binding>


 

<!-- <service> specifies the portType for each binding and the URL of the service -->

 

<service name='WMLS' >

 

     <port name='StoreSoapPort' binding='wsdlns:StoreSoapBinding' >

          <soap:address location='http://yourorg.com/yourwebservice' />

      </port>

 

</service>

 

</definitions>

 


7.6.2        Narrative

§  The only part of the WSDL file that should normally be modified is the location attribute of the SOAP address element. This should be set to the URL of the Web Service (see implementation specifics below):

 

  <service name='WMLS' >

 

    <port name='StoreSoapPort' binding='wsdlns:StoreSoapBinding' >

      <soap:address location='http://yourorg.com/yourwebservice' />

    </port>

 

  </service>

 

§  The WSDL file complies with Version 1.1 of the Web Services Description Language (www.w3.org/TR/wsdl)

 

§  The target namespace and wsdlns prefix used in the WSDL file are both declared as:

 

  'http://www.witsml.org/wsdl/120'

 

<definitions name='WMLS'

targetNamespace='http://www.witsml.org/wsdl/120'

                        xmlns:wsdlns='http://www.witsml.org/wsdl/120'

 

§  A default namespace declaration is used to make the document more readable:

 

<definitions name='WMLS' targetNamespace='http://www.witsml.org/wsdl/120'

             xmlns:wsdlns='http://www.witsml.org/wsdl/120'

             xmlns:soap='http://schemas.xmlsoap.org/wsdl/soap/'

             xmlns:xsd='http://www.w3.org/2001/XMLSchema'

             xmlns='http://schemas.xmlsoap.org/wsdl/'>


 

 

§  The soapAction attribute of the SOAP operation elements specify a WITSML-related URI:  http://www.witsml.org/action/120/Store.WMLS_xxxx

The soapAction attribute is used by the HTTP transport as the value of the SOAPAction HTTP header. Its use is not clear as of this writing; SOAP 1.1 states that it can be used to identify the “intent” of messages.

 

    <operation name='WMLS_AddToStore' >

      <soap:operation

           soapAction='http://www.witsml.org/action/120/Store.WMLS_AddToStore' />

      <input>
          …

 

§  The namespace attribute of the SOAP body elements also specify a WITSML-related URI:  http://www.witsml.org/message/120

    <operation name='WMLS_AddToStore' >

      <soap:operation

          soapAction='http://www.witsml.org/action/120/Store.WMLS_AddToStore' />

      <input>

         <soap:body use='encoded' namespace='http://www.witsml.org/message/120'

                          encodingStyle='http://schemas.xmlsoap.org/soap/encoding/' />

      </input>

    </operation>

            …

§  Although XML generally ignores white-space, the values of certain XML attributes and elements may be sensitive to the amount of white-space. For example, the parameterOrder attribute of the <operation> element must have only a single space between parameters:

     <operation name='WMLS_AddToStore' parameterOrder='WMLtypeIn XMLin OptionsIn CapabilitiesIn SuppMsgOut'>

 


For an easy-to-read, understandable introduction to WSDL files, see the article titled “Web Services Description Language (WSDL) Explained” by Carlos C. Tapang - Infotects (in the Microsoft MSDN Library and elsewhere).


8          PUBLISH Interface

8.1         Introduction

The PUBLISH interface provides Subscriber applications the ability to:

 

§  query a Publisher for what data object types are available for publication

 

§  subscribe to changed WITSML data objects to be published at some time in the future

 

§  maintain its subscription requests held by a Publisher.

 

When using the PUBLISH interface, the actual transfer of the requested WITSML data objects between Publisher and Subscriber is performed by the Publisher when changed data objects matching the Subscription become available (see CONCEPT box on next page).  Although the Subscriber initiates the process by sending a Subscription request to the Publisher that specifies the objects it wishes to have sent to it, it’s still a “push” model in the sense that the requested data objects are eventually pushed from Publisher to Subscriber.

 

Both the WITSML Subscription request and published data objects are XML documents.

 

The functions exposed by the PUBLISH interface are prefixed with “WMLP_”.

 

The WMLP_ functions are exposed to client applications as SOAP methods (Remote Procedure Call-style). A standardized Web Services Description Language (WSDL) file is used to define the PUBLISH interface exposed via SOAP.

The PUBLISH interface defines only the SOAP-exposed functions needed by a Subscriber to determine what is available for subscription, and for the Subscriber to manipulate its subscriptions. It does not expose an interface for invoking the publication (push) operation. Publication is performed internally by the PUBLISH implementation when data is available for publication, based on the subscriptions the Publisher has accepted.

 

The PUBLISH implementation uses HTTP/S POST to publish (push) the requested data objects to the Subscriber. SOAP is used only for the Subscriber to access the Publisher during the subscription process, not for the publication of the data objects

 

 

 

 

 


 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


Here is an example of a subscriber requesting two subscriptions. The subscriber application uses SOAP to invoke the WMLP_Subscribe function on the Publisher . It passes the two Subscription Requests in the SubscriptionIn parameter:

 

 

RetVal = WMLP_Subscribe(SubscriptionIn,

                        OptionsIn,

                        SubscriptionOut,

                        SuppMsgOut)

 

 

The SubscriptionIn parameter might contain:

 

            <subscriptions xmlns="http://www.witsml.org/api/131">

                        <subscription action=”add ”… >

                                    <realtimes namespace="http://www.witsml.org/schemas/131ex">

                                                <realtime … />

                                    </realtimes>

                                    <mudLogs namespace="http://www.witsml.org/schemas/131ex">

                                                <mudLog … />

                                    </mudLogs>  

                        </subscription>

 

                                    (parameter continued on next page)

 

                        <subscription action=”add” … >

                                    <wells namespace="http://www.witsml.org/schemas/131ex">         

                                                <well … />

                                    </wells>

                                    <wellbores namespace="http://www.witsml.org/schemas/131ex">

                                                <wellbore … />

                                    </wellbores>

                                    <trajectorys namespace="http://www.witsml.org/schemas/131ex">

                                                <trajectory … />

                                    </trajectorys>             

                        </subscription>

            </subscriptions>

 

 

The Publisher inserts a return code (retCode attribute) into each Subscription Request (the <subscription> element) and - if the subscription was accepted - the subscription identifier (idSub attribute). It then returns the modified Subscription Requests to the Subscriber in the SubscriptionOut parameter.

 

The Publisher also returns a value (RetVal) indicating the overall success or failure of the function.

 

►  Subscription Requests and their child elements - known as Subscription Templates - are described in subsequent topics.

 

If RetVal = “1” (meaning OK) then SubscriptionOut might contain:

 

            <subscriptions xmlns="http://www.witsml.org/api/131">

                <subscription retCode=”1”  idSub=”12345”  … > ß subscription accepted

                                    …

                </subscription>

                <subscription retCode=”-101” … >  ß error, so no idSub was returned

                        …

                </subscription>

            </subscriptions>

 

The first subscription was accepted (retCode=”1”) and was assigned a subscription ID of 12345. The Subscriber can later use that ID to verify, modify or cancel the subscription or retransmit realtime headers, by again invoking the WMLP_Subscribe function but passing a subscription object with action=”verify”, “modify”, “cancel” or “retransmit” and the subscription ID.

 

The second subscription was rejected (retCode is a negative value). No subscription ID was returned.


8.2         Subscription Requests

A Subscription Request is used both to request a new subscription and to modify an existing subscription. A Subscription Request carries with it various information that identifies the Subscriber.

Here is an example of one Subscription Request:

 

            <subscriptions xmlns="http://www.witsml.org/api/131">

                        <subscription  … />                ç the Subscription Request

            </subscriptions>         

 

The plural <subscriptions> element is required even when there is only one Subscription Request. There can be one or more Subscription Requests contained within the plural <subscriptions> element:

 

            <subscriptions xmlns="http://www.witsml.org/api/131">

                        <subscription …/>

                        <subscription …/>

            </subscriptions>

 

Each Subscription Request must specify one or more WITSML data object types [5] to be published. Here is an example of a Subscription Request for the well and wellbore data objects, and a second Subscription Request for just the mudLog data object:

 

            <subscriptions xmlns="http://www.witsml.org/api/131">

                        <subscription … >                              ç Subscription Request #1

                                    <wells … />                            ß Subscription Template #1a

                        <wellbores … />                     ß Subscription Template #1b

                        </subscription>                                  

<subscription … >                              ç Subscription Request #2

                                    < mudLogs … />                    ß Subscription Template #2

                        </subscription>

</subscriptions>


► The plural wells, wellbores and mudLogs child elements are known as Subscription Templates, and will be described later. Subscription Templates specify which data objects and which data items within each data object are to be published, much like the Query Templates used by the STORE interface. We will discuss them in detail later on, but for now, let us continue describing the Subscription Request (<subscription>) element.


 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


The Subscription Request (<subscription>) element accepts the following XML attributes:


8.2.1         action attribute - the action being requested

Each Subscription Request must contain an action attribute, specifying:

 

            add                  - a new subscription is being added

            modify            - an existing subscription is being modified

            cancel              - one (or all) existing subscriptions are to be cancelled (deleted)

            verify              - one (or all) subscriptions are to be verified (and listed)

            retransmit      - retransmit the realtime headers.

 

8.2.1.1  action=”add” - add a new subscription

Here is an example of requesting a new subscription:

 

                        <subscriptions xmlns="http://www.witsml.org/api/131">

                                    <subscription  action=”add” … >

                                                <wells namespace="http://www.witsml.org/schemas/131ex">

<well><country/></well>

</wells>

                                    </subscription>

</subscriptions>

 

After processing by the Publisher, each add request is returned to the Subscriber as-submitted with a return code inserted (see retCode later in this section):

 

<subscriptions xmlns="http://www.witsml.org/api/131">

                                    <subscription  action=”add” retCode="1" … >

                                                <wells namespace="http://www.witsml.org/schemas/131ex">

<well><country/></well>

</wells>

                                    </subscription>                                  

</subscriptions>

 

Note that the Subscription Template is made up of one or more plural container elements, such as <wells>. This is done to allow multiple instances of the same object type to be specified in the same Template.


8.2.1.2   action=”modify” - modify an existing subscription

If you need to modify an existing subscription, you specify action=”modify” and provide the existing subscription ID using the idSub attribute:

 

                        <subscriptions xmlns="http://www.witsml.org/api/131">

                                    <subscription  action=”modify”  idSub=”12345” … >

                                                <wells namespace="http://www.witsml.org/schemas/131ex">

<well><country/></well>

</wells>

                                    </subscription>                                  

</subscriptions>

 

After processing by the Publisher, each modify request is returned to the Subscriber as-submitted with a return code inserted (see retCode later in this section):

 

                        <subscriptions xmlns="http://www.witsml.org/api/131">

                                    <subscription  action=”modify”  idSub=”12345” retCode="1"…>

                                                <wells namespace="http://www.witsml.org/schemas/131ex">

<well><country/></well>
</wells>

                                    </subscription>                                  

</subscriptions>

 

► When modifying an existing subscription, all attributes and elements must be respecified on the Subscription Request, and all Subscription Templates (such as the <wells> container in the example above) must be respecified; there is no “merging” of information from the existing subscription to the updated one; action="modify" is a complete replacement.


8.2.1.3  action=”cancel” - cancel one or all existing subscriptions

If you need to cancel (delete) one existing subscription, you specify action="cancel" and provide the existing subscription ID using the idSub attribute:

 

                        <subscriptions xmlns="http://www.witsml.org/api/131">

                                    <subscription  action=”cancel” idSub=”12345” >

                                    </subscription>                                  

</subscriptions>

 

When canceling a subscription, you do not need to specify a Subscription Template (i.e., child elements of the <subscription> element).

 

After processing by the Publisher, each cancel request is returned to the Subscriber as-submitted with a return code inserted (see retCode later in this section):

 

                        <subscriptions xmlns="http://www.witsml.org/api/131">

                                    <subscription  action=”cancel” idSub=”12345” retCode="1" >

                                    </subscription>                                  

</subscriptions>

 

If you need to cancel (delete) all the subscriptions for a given host you can specify action="cancel", idSub="" and include the host attribute:

 

      <subscriptions xmlns="http://www.witsml.org/api/131">

              <subscription  action=”cancel”  idSub=""  host="myhost.myorg.com">

              </subscription>

       </subscriptions>

 

The Publisher will delete all subscriptions associated with the host URL (see host attribute, described later in this section).

 

After processing by the Publisher, each deleted subscription will be returned to the Subscriber with a return code inserted (see retCode later in this section):

 

       <subscriptions xmlns="http://www.witsml.org/api/131">

               <subscription  action=”cancel” idSub=”12345” host="myhost.myorg.com"
                               retCode="1" >

               </subscription>

               <subscription  action=”cancel” idSub=”67890" host="myhost.myorg.com"
                               retCode="1" >

               </subscription>

       </subscriptions>


8.2.1.4   action=”verify” - verify an existing Subscription

You may verify an existing subscription and retrieve its present contents by specifying action=”verify” and providing the existing subscription ID using the idSub attribute:

 

                        <subscriptions xmlns="http://www.witsml.org/api/131">

                                    <subscription  action=”verify” idSub=”12345”  … >

                                    </subscription>                                  

</subscriptions>

 

Verify does not modify the subscription, and you do not have to specify a Subscription Template when requesting action=”verify”.

 

After processing by the Publisher, the entire contents of the existing Subscription - including its Subscription Template(s) - are returned to the Subscriber with a return code inserted (see retCode later in this section):

 

                        <subscriptions xmlns="http://www.witsml.org/api/131">

                                    <subscription  action=”verify” idSub=”12345” retCode="1" … >

                                                … Subscription Template(s)

                                    </subscription>                                  

</subscriptions>

 

If you need to verify all your existing subscriptions, you can specify action="verify", idSub="" and include your host attribute:

 

      <subscriptions xmlns="http://www.witsml.org/api/131">

              <subscription  action=”verify”  idSub=""  host="myhost.myorg.com">

              </subscription>

       </subscriptions>

 

The Publisher will verify all subscriptions associated with your host URL (see host attribute, described later in this section).


 

After processing by the Publisher, the entire contents of all existing Subscriptions matching the host - including their Subscription Template(s) - are returned to the Subscriber with return codes inserted (see retCode later in this section):

 

                        <subscriptions xmlns="http://www.witsml.org/api/131">

                                    <subscription  action=”verify” idSub=”12345” retCode="1" … >

                                                … Subscription Template(s)

                                    </subscription>

                                    <subscription  action=”verify” idSub=”67890” retCode="1" … >

                                                … Subscription Template(s)

                                    </subscription>                                  

                        </subscriptions>

 

 

 

 

 

 

 

 

 

 

 

 

 


8.2.1.5  action=”retransmit” - retransmit the realtime headers

The realtime header is included with the first realtime that is returned for each wellbore. The header is also returned if it is updated. If the realtimeHeaders are desired at any other time then a subscription specifying action=”retransmit” and providing the existing subscription ID using the idSub attribute should be submitted:

 

                        <subscriptions xmlns="http://www.witsml.org/api/131">

                                    <subscription  action=”retransmit” idSub=”12345”  … >

                                    </subscription>

                        </subscriptions>

 

The header will be sent with the next available new data.


8.2.2        retCode attribute - the return code

After processing by the Publisher, the Subscription Request(s) are returned to the Subscriber, but with return codes (retCode attributes) inserted:

 

                        <subscriptions xmlns="http://www.witsml.org/api/131">

                                    <subscription  action=”add” retCode=”1” … >

                                                <wells namespace="http://www.witsml.org/schemas/131ex">

<well><country/></well>
</wells>

</subscription>                                  

</subscriptions>

 

The retCode value indicates the disposition of the subscription request. A value of “1” means the Subscription Request was processed without error.

 

Although the above example shows the returned Subscription Request for an “add” request, a retCode attribute will be inserted into the returned Subscription Request regardless of what action was requested.

8.2.3        idSub attribute - the subscription identifier

If the retCode value is “1” (meaning OK), the subscription ID (idSub attribute) will also have been inserted into the returned Subscription Request:

 

                        <subscriptions xmlns="http://www.witsml.org/api/131">

                                    <subscription  action=”add” retCode=”1”
                                                            idSub=”XYZ123:12345”
… >

                                                <wells namespace="http://www.witsml.org/schemas/131ex">

<well><country/></well>

</wells>

                                    </subscription>                                  

</subscriptions>

 

The Subscription Identifier uniquely identifies the accepted Subscription Request within a global context. This identifier must be used exactly as returned by the Publisher in subsequent requests to modify, verify or cancel the Subscription. The Subscriber must not manipulate the returned Subscription Identifier.

 

 

 

 


8.2.4        test attribute - test network connectivity

Unless you request otherwise, whenever you request a new subscription or modify or verify an existing one, a network test will first be performed by the Publisher to make sure it can contact the Subscriber. The test will consist of an empty data object sent via HTTP/S POST from Publisher to Subscriber, using the host, process, port, encrypt and idPub values specified in the new/existing subscription.

 

► If the network test fails, no further processing will be done on the request and a error code will be returned.

 

You may suppress the default network test by specifying the test attribute with a value of “false” in your subscription object:

 

                        <subscriptions xmlns="http://www.witsml.org/api/131">

                                    <subscription  action=”add” test=”false”  … >

                                                …

                                    </subscription>                                  

</subscriptions>

 

 

 

 

 

 

 

 

 

 

 

 



8.2.5         host, process, port and encrypt attributes - specify the subscriber’s URL

In addition to an action and sometimes a subscription ID, each Subscription object must also contain the following attribute:

 

            host                 - the DNS host name or IP address of the system that will
                                      receive the published data objects as HTTP/S POSTs.        

 

Optionally, the Subscription object can specify:

 

encrypt                        - whether HTTP (encrypt=”false”) or HTTPS (encrypt=”true”) is

                                      to be used to POST the data to the listening process. If omitted,
                                      the default is “false” (use HTTP)

 

            process                        - the name of the HTTP/S listener process on the “host” system,
                                      including the directory/path name if needed. A leading delimiter
                                      is not required.

 

            port                  - the TCP port number on which the HTTP/S listener “process”
                                      is listening. If omitted, the default is 80 (if encrypt="false" or
                                      encrypt is omitted) or 443 (if encrypt="true")

 

The host, process, port and encrypt attributes are combined to create the URL of the system to which the published data will be sent. A URL consists of:

 

                        protocol://host:port/process

 

The encrypt attribute determines whether http or https will be used as the protocol.

 

The host attribute specifies the host portion of the URL.

 

The port value - if explicitly supplied - is used to specify the port portion of the URL. If the port attribute is supplied, it is separated from the host by a colon (":") character. If the port attribute is not supplied, the colon character will not be present in the URL.

 

The process attribute specifies the process portion of the URL. If specified, a forward slash character ("/") is used to delineate it.

 

Example:

            <subscriptions xmlns="http://www.witsml.org/api/131">

                        <subscription  host=”myhost.myorg.com”
                                                process=”WMLR_Publish.aspx?id=Sense-898”
…>

                        </subscription>

            </subscriptions>

… will result in the URL:  http://myhost.myorg.com/WMLR_Publish.aspx?id=Sense-898

In this example, the parameter after the question mark is being used to pass a client assigned publisher identifier back to the client. When using this technique, the client name should be part of the identifier.

8.2.6         idPub attribute - identify the Publisher

If the system that is to receive the published data (the system identified by the host attribute) requires a userid/password in order to accept POSTs from the Publisher, that userid/password must be specified in the optional idPub attribute of the Subscription object:

 

                        <subscriptions xmlns="http://www.witsml.org/api/131">

                                    <subscription  idPub=”userid:password” …>

                                    </subscription>                                  

</subscriptions>

 

The value of the idPub attribute must be a valid userid, optionally followed by a valid password. If a password is present, the userid and password must be separated by a single colon (":") character (e.g., userid:password).

 

The userid and password (if present) must be specified as clear, un-encoded text in the subscription request. The Publisher implementation or its HTTP/S stack will perform the necessary base64 encoding to comply with the BASIC authentication requirement (see ‘Authentication and Encryption’ section of this document).




8.2.7        retry attribute - the error retry count

A Subscription object can also include the retry attribute to specify the number of retries the Publisher is to perform before considering a data object to be “undeliverable”:

 

                        <subscriptions xmlns="http://www.witsml.org/api/131">

                                    <subscription  retry=”3” …>

                                    </subscription>                                  

</subscriptions>

This example would cause the Publisher to retry a failed HTTP/S POST three times before treating the data object as undeliverable.

 

If omitted, the default value of retry is zero (0), meaning that the Publisher does not retry failed POSTs.

 

 

 

 

 

 

 

 

 

 

 



8.2.8         updateInterval attribute - limit the publication rate

The default frequency for publication of changes to an object matching the Subscription Template is “as frequently as it is changed”. That is, the Publisher will, by default, publish a data object matching the Subscription Template each time the object is changed, regardless of how frequently that might be.

 

The subscription request can specify an update interval to limit the frequency of the publications by including the optional updateInterval attribute of the Subscription object. The updateInterval value specifies the minimum period (in seconds) between publications of a given object. Regardless of how frequently the object changes, the Publisher will send the changed object to the Subscriber no more frequently than the specified updateInterval.

 

                        <subscriptions xmlns="http://www.witsml.org/api/131">

                                    <subscription  updateInterval=”60” …>

                                    </subscription>                                  

</subscriptions>

 

 

 

 

 

 




 

 

 

The updateInterval does not specify a maximum period. If there have been no changes to the data objects, no publication will occur (e.g., there is no maximum period).

 

The updateInterval specified in the subscription request also specifies the default interval for the realtime object, unless over-ridden by the realtime object’s <interval> element.

 


8.2.9        Subscription Object Attribute Summary

Here is a summary of all the XML attributes that can be specified on the Subscription Request (<subscription>) element.

 

attribute                     required         values                                      default

 

action                          yes                   add, modify, cancel, verify,
                                                            retransmit                                (none)

 

retCode                       yes (1)             WITSML-defined codes        (none)

 

idSub                           yes (2)             defined by Publisher               (none)

 

test                              no                    true, false                                true

 

host                             yes (6)             valid hostname or IP addr      (none) 

 

process                                    no                    name of process on host          null string

 

port                              no                    TCP port number                    80 or 443 (3)

 

encrypt                                    no                    true, false                                false

 

idPub                           no                    userid:password (4)                 (none)

 

retry                             no                    0-n                                           0

 

updateInterval             no                    n (seconds)                              (none) (5)

 

Notes:

 

1) required in all Subscription Requests returned from Publisher to Subscriber.

 

2) except in an initial Subscription request when action=”add” or when action="cancel (or "verify") and user wishes to delete (or verify) all subscriptions for associated host.

 

3) port 80 is default if encrypt=”false” (or defaulted); port 443 is default if encrypt="true"

 

4) or just userid (without the ":" character) if no password is needed.

 

5) Publisher can send data objects as frequently as they become available.

           

6) required when adding a new subscription or when canceling or verifying all subscriptions (i.e., when idSub="")


8.3         Subscription Templates

The following describes the standard behavior of the Subscription Template. For data objects that conform to special requirements, special handling has been defined that extends this standard behavior (see Appendix D - Special Handling).

 
 

 

 

 

 


Now that we’ve described the Subscription Request element and its attributes, let’s now look at Subscription Templates. A Subscription Template specifies the data object types and data items within those objects that are to be published for a particular Subscription, much like the Query Templates used by the STORE interface.

 

Here is our earlier example showing two Subscription Requests, each with their own Subscription Templates:

 

            <subscriptions xmlns="http://www.witsml.org/api/131">

                        <subscription … >                              ç Subscription Request #1

                                    <wells … />                            ß Subscription Template #1a

                        <wellbores … />                     ß Subscription Template #1b

                        </subscription>                                  

<subscription … >                              ç Subscription Request #2

                                    <trajectorys … />                    ß Subscription Template #2

                        </subscription>

</subscriptions>

Each Subscription Template specifies both:

 

§  the contents of the published data objects, by including those XML elements/attributes that are to be sent by the Publisher, but without specifying a value for the elements/attributes. The following example requests that a well object be published whenever any well object on the Publisher is changed, and that the published well objects are to contain only the country data item (and its parent items):

 

                        <subscriptions xmlns="http://www.witsml.org/api/131">

                                    <subscription … >

                                                <wells namespace="http://www.witsml.org/schemas/131ex">

<well><country/></well>

</wells>  

                                    </subscription>                                  

</subscriptions>


 

The published well object might contain:

 

<wells>

            <well>

                        <country>UK</country>

            </well>

                        …

</wells>

§  the selection of which data objects are to be published, by including a value with the XML elements and/or attributes. The following example requests that a well object be published whenever a well object containing a country data item of “Norway” is changed:

                        <subscriptions xmlns="http://www.witsml.org/api/131">

                                    <subscription … >

                                                <wells namespace="http://www.witsml.org/schemas/131ex">

<well>

<country>Norway</country>

</well>

</wells>

                                    </subscription>

</subscriptions>

 

The structural content of the published well object(s) would be the same as in the first example above. The difference is that in the first example, a change to any well object will result in a publication, while in the second example only a change to a well with a country data item of “Norway” will result in a publication.

 

► The plural data object container provides for more than one Subscription Template for a given WITSML data object type within one Subscription Request.

            <subscriptions xmlns="http://www.witsml.org/api/131">

                        <subscription … >

                                    <wells namespace="http://www.witsml.org/schemas/131ex">

                                                <well uid="1"/>

                                                <well uid="2"/>

                        </wells>

                        </subscription>

</subscriptions>

The plural container is required even if only one instance of a data object type is specified in the Subscription Template.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


8.3.1        Realtime Example

The realtime object is designed to permit transmittal of data as it is being acquired (similar to a demultiplexed log). It has behavior similar to a systematically growing object (See APPENDIX D – Special Handling) but the data is defined at the individual cell level rather than at the row level and it does not have a structural range capability. The realtime header describes a table structure with each column representing a sensor channel. The channel element represents one value from one sensor at one index value. Realtime data is commonly converted to a log in order to make it persistent. The realtime header will exist until the realtime stream is finished and then the header will normally be deleted. Each individual channel value is intendded to be transient and will normally exist for only a short time.

A common scenario for accessing realtime is to use WMLS_GetFromStore to access the realtimeHeaders for a particular wellbore in order to determine what channels are available. The results of the STORE query is then used to create a template for WMLP_Subscribe.

For example, the following WMLS_GetFromStore template requests the mnemonics for each channel of a particular wellbore.

            <realtimes xmlns="http://www.witsml.org/schemas/131ex">
                        <realtime uidWell="w1" uidWellbore="w1b">
                                    <realtimeHeader>
                                                <channelDefinition>
                                                            <mnemonic/>
                                                </ channelDefinition>
                                     </realtimeHeader>
                        </realtime>
            </realtimes>

This might return the following message. Note that realtime does not contain an index channel.

            <realtimes xmlns="http://www.witsml.org/schemas/131ex">
                        <realtime uidWell="w1" uidWellbore="w1b">
                                    <realtimeHeader>
                                                <channelDefinition>
                                                            <mnemonic> WOB </mnemonic>
                                                </ channelDefinition>
                                                <channelDefinition>
                                                            <mnemonic> SPM </mnemonic>
                                                </ channelDefinition>
                                     </realtimeHeader>
                        </realtime>
            </realtimes>

Based on this result a subscription can be submitted using the following template.

            <realtimes xmlns="http://www.witsml.org/schemas/131ex">
                        <realtime uidWell="w1" uidWellbore="w1b">
                                    <md uom=””/>
                                    <realtimeHeader>
                                                <channelDefinition>
                                                            <mnemonic> WOB </mnemonic>
                                                </ channelDefinition>
                                                <channelDefinition>
                                                            <mnemonic> SPM </mnemonic>
                                                </ channelDefinition>
                                     </realtimeHeader>
                                    <channel>
                                                <mnemonic/>
                                                <value uom=/>
                                     </channel>
                        </realtime>
            </realtimes>

The realtimeHeader data will be returned with the first data that is published but not with subsequent data. Thus the following sequence of messages might be published as a result of the above subscription.

            <realtimes xmlns="http://www.witsml.org/schemas/131ex">
                        <realtime uidWell="w1" uidWellbore="w1b" idSub=”12345”>
                                    <md uom=”m”> 3598.346</md>
                                    <realtimeHeader>
                                                <channelDefinition>
                                                            <mnemonic> WOB </mnemonic>
                                                </ channelDefinition>
                                                <channelDefinition>
                                                            <mnemonic> SPM </mnemonic>
                                                </ channelDefinition>
                                     </realtimeHeader>
                                    <channel>
                                                <mnemonic> SPM </mnemonic>
                                                <value uom=”rpm”> 78.160 <value>
                                     </channel>
                                    <channel>
                                                <mnemonic> WOB </mnemonic>
                                                <value uom=”t”>5.979<value>
                                     </channel>
                        </realtime>
            </realtimes>

            <realtimes xmlns="http://www.witsml.org/schemas/131ex">
                        <realtime uidWell="w1" uidWellbore="w1b" idSub=”12345”>
                                    <md uom=”m”>3578.14</md>                                  <channel>
                                                <mnemonic> SPM </mnemonic>
                                                <value uom=”rpm”> 78.160 <value>
                                     </channel>
                                    <channel>
                                                <mnemonic> WOB </mnemonic>
                                                <value uom=”t”>5.979<value>
                                     </channel>
                        </realtime>
            </realtimes>

            <realtimes xmlns="http://www.witsml.org/schemas/131ex">
                        <realtime uidWell="w1" uidWellbore="w1b" idSub=”12345”>
                                    <md uom=”m”>3598.346</md>
                                    <channel>
                                                <mnemonic> SPM </mnemonic>
                                                <value uom=”rpm”> 78.172 <value>
                                     </channel>
                        </realtime>
            </realtimes>

            <realtimes xmlns="http://www.witsml.org/schemas/131ex">
                        <realtime uidWell="w1" uidWellbore="w1b" idSub=”12345”>
                                    <md uom=”m”>3601.285</md>
                                    <channel>
                                                <mnemonic> WOB </mnemonic>
                                                <value uom=”t”>5.967<value>
                                     </channel>
                        </realtime>
            </realtimes>

And so on. The md element defines the node index and the mnemonic element identifies the column identifier for each data value.

 

8.4         Publishing and Maintaining Subscriptions

The Publisher does not specify the nature of the “change” to the object. The object could have been added, modified or deleted.

 

When an object is deleted the Publisher should send only the unique identifiers (UID’s) of the deleted object, regardless of the Subscription Template contents.

 

Because this manner of indicating a deleted object can be somewhat ambiguous, it is strongly recommended that a subscriber perform a STORE interface query to the originating system to verify that the object has in fact been deleted.

 

 
 

 

 

 

 

 

 

 

 


Subscriptions are maintained indefinitely - until cancelled by the Subscriber or by the administrator of the Publisher system. There is no mechanism in WITSML that notifies the subscriber about a cancellation so the verify action should be periodically utilized to insure that the subscription is still active. The Subscriber can always modify or cancel a subscription but the Publisher may allow others to modify or cancel a subscription depending on the user rights in that system.

 

A subscription is retained by the Publisher in a non-volatile store, such that no action is required by the Subscriber upon restart of the Publisher system; the subscription will still be present and active.

 

If connectivity is lost for any reason, there is no requirement for the Publisher to retain data objects for resending; it is expected that Publishers will simply discard documents that cannot be published.

 

Failure to publish a document to a Subscriber does not affect the subscription. The subscription will remain active, and the Publisher will continue publishing when the next document is available for that Subscriber.


8.5         POST Request

The Publisher sends data objects to Subscribers using an HTTP/S POST Request.

8.5.1        Syntax

The general syntax is: [6]

 

POST request-uri  HTTP/1.1 crlf

Host:  host [ ":" port ]

Content-Type: application/xml; charset=utf-8 crlf

Content-Length:  length crlf

Authorization: BASIC credentials crlf

crlf

message-body

 

Where the text shown in italics indicates variable content as follows:

 

crlf is a US-ASCII CR, carriage return (13)
              immediately followed by a
          US-ASCII LF, linefeed (10)

 

request-uri specifies the resource upon which to apply the request

 

host and port specify the Internet host and optional port number of the
                        resource being requested:

Host: www.witsml.org

Host: www.other.org:1234

 

length specifies the length of the message-body, in decimal octets

 

credentials is the userid and password, separated by a single colon (":")

                        character as a base64 encoded string

 

message-body is one or more WITSML data objects within a plural container
                          element, preceded by an <?xml …> element

 

 

► Text not in italics should be specified as-shown.


8.5.2        Notes:

§  The Publisher places one or more WITSML data objects - in the form of a single XML document - in the message body of the HTTP/S POST request.

 

§  Multiple WITSML data objects of the same type may be sent in one request.

 

§  The root element of the XML document must be a plural container element of the same type as the data object(s), such as:

 

<wells>

<well … />

<well … />

</wells>

 

§  The plural root element must be included even if there is only one data object.

 

§  The Authorization field may be omitted if no authorization is required by the subscriber.

§  Other HTTP Request fields may be included as needed.

8.5.3        Example:

POST /witsml/listener HTTP/1.1

Host: www.witsml.org

Content-Type: application/xml

Content-Length: 182

Authorization: BASIC QWxhZGRpbjpvcGVuIHNlc2FtZQ==

 

<?xml version=“1.0” encoding=“UTF-8”?>

<wells xmlns=“http://www.witsml.org/schemas/131ex”>

    <well uid=“W-1”>

        <name>6507/7-1</name>

        <country>Norway</country>

    </well>

</wells>

8.6         Authentication and Encryption

The PUBLISH interface uses HTTP/S Basic Authentication, as described in IETF RFC’s 2616 (HTTP 1.1) and 2617 (Authentication).

 

The userid and password transported via the HTTP/S Basic Authentication mechanism can be used by the Publisher and/or Subscriber implementations to perform authorization checking and control.

 

The capabilities and implementation of authorization checking, if any, are not specified by WITSML.

 

Secure Sockets Layer (SSL) for HTTP (HTTPS) can be used to encrypt the HTTP traffic.

 


8.7         Capabilities Objects

The PUBLISH interface uses two special objects to exchange information about the “capabilities” of the Subscriber and the Publisher. These special objects are called the Capabilities objects.

 

 

 

 

 

 

 

 

 


8.7.1        Subscriber Capabilities (capSubscriber) Object

The Subscriber Capabilities or “capSubscriber” object is used to inform the Publisher of the Subscriber’s functional capabilities. The capSubscriber object is conveyed as the CapabilitiesIn parameter of the PUBLISH interface's WMLP_Subscribe function. It must be passed on each call; the value is not maintained across calls.

 

The CapabilitiesIn parameter may be set to a null string to indicate that no capSubscriber object is being provided. When a capSubscriber object is not provided, default values for the various Subscriber capabilities are assumed by the Publisher.

8.7.2        Publisher Capabilities (capPublisher) Object

The Publisher Capabilities or “capPublisher” object is used to inform the Subscriber of the Publisher’s functional capabilities. The capPublisher object is returned in the CapabilitiesOut parameter of the PUBLISH interface’s WMLP_GetCap (Get Capabilities) function.

 


8.7.3        Capabilities by Object

These are the presently-defined capabilities that can be exchanged using the capSubscriber and/or the capPublisher objects:

 

 

Capability:       version of the API which the Subscriber or Publisher supports

Applies to:       capSubscriber and capPublisher objects

Conveyed as:  apiVers attribute of the capSubscriber or capPublisher element

Syntax:            apiVers=”n.n.n”

Default:           1.3.1

Example:         <capSubscriber apiVers=”1.3.1”>

                        </capSubscriber>

Notes:              this is the value to be used if it is necessary to dynamically adapt to
                        differing implementation levels (do not use the version element below)

 

 

Capability:       contact information for the Subscriber or Publisher

Applies to:       capSubscriber and capPublisher objects

Conveyed as:  contact child element of the capPublisher or capSubscriber element

Syntax:            <contact>

                                    <name>xxx…xxx</name>

                                    <email>xxx…xxx</email>

                                    <phone>nnn…nnn</phone>

                        </contact>

Default:           none

Example:         <contact>

                                    <name>Bob Junior</name>

                                    <email>bobj@aol.com</email>

                                    <phone>1-800-555-1302</phone>

                        </contact>

Notes:              any descriptive text

 

 

Capability:       description of the Subscriber or Publisher

Applies to:       capSubscriber and capPublisher objects

Conveyed as:  description child element of the capPublisher or capSubscriber element

Syntax:            <description>xxxx…xxxx</description>

Default:           none

Example:         <capPublisher>

                                    <description>Equip Rm A - Rack 12 - Slot 2</description>

                        </capPublisher>

Notes:              any descriptive text



Capability:       name of the Subscriber or Publisher

Applies to:       capSubscriber and capPublisher objects

Conveyed as:  name child element of the capPublisher or capSubscriber element

Syntax:            <name>xxxx…xxxx</name>

Default:           none

Example:         <capPublisher>

                                    <name>Publisher #1</name>

                        </capPublisher>

Notes:              any descriptive text

 

 

Capability:       vendor (producer) of the software

Applies to:       capSubscriber and capPublisher objects

Conveyed as:  vendor child element of the capPublisher or capSubscriber element

Syntax:            <vendor>xxxx…xxxx</vendor>

Default:           none

Example:         <capPublisher>

                                    <vendor>Acme Downhole Software</vendor>

                        </capPublisher>

Notes:             

 

 

Capability:       version (build) of the executable program

Applies to:       capSubscriber and capPublisher objects

Conveyed as:  version child element of the capPublisher or capSubscriber element

Syntax:            <version>n.n.n.n</version>

Default:           none

Example:         <capPublisher>

                                    <version>1.3.1.1451</version>

                        </capPublisher>

Notes:             

 

 

Capability:       schema version(s) that are supported

Applies to:       capSubscriber and capPublisher objects

Conveyed as:  schemaVersion child element of the capPublisher or capSubscriber
                        element

Syntax:            <schemaVersion>n.n.n.n,m.m.m.m</ schemaVersion >

Default:           none

Example:         <capClient>

                                    < schemaVersion >1.1.0,1.2.0,1.3.1.0</ schemaVersion >

                        </capClient>

                        <capServer>

                                    < schemaVersion >1.3.1.0</ schemaVersion >

                        </capServer>

Notes:              The values must match the version attribute in the plural object.

                        For capClient, the value is a comma separated list of values without
                        spaces. The oldest version should be listed first.
                        For Publishers, the value must match a value that is returned
                        by the WMLP_GetVersion function.

 

 

Capability:       the PUBLISH functions, versions and data objects that the Publisher
                        supports for each function

Conveyed as:  function element of the capPublisher element

                        apiVers attribute of the function element

                        dataObject element of the function element

Syntax:            <function name=”xxx” apiVers=”n.n.n”>

                                    <dataObject>xxx</dataObject>

                        </function>

Default:           none (Subscriber should not assume capability exists if not explicitly
                                    listed)

Example:         <capPublisher apiVers=”1.3.1”>

                                    <function name=”WMLP_Subscribe”>

                                                <dataObject>well</dataObject>

                                                <dataObject>wellbore</dataObject>

                                                <dataObject>realtime</dataObject>

                                    </function>

                                    <function name=”WMLP_GetVersion”>

                                    </function>

                        </capPublisher>

Notes:              the example shows supports for only the three specified data object types
                        for WMLP_Subscribe. It supports version 1.3.1 for all functions. It also
                        supports the WMLP_GetVersion function. The capPublisher object does
                        not need to specify the WMLP_GetCap function, as this is implied if the
                        capPublisher object is returned to the Subscriber.

 

8.8         PUBLISH Functions

This section describes the PUBLISH interface functions.

 

The following functions are defined:

 

WMLP_GetBaseMsg - get the fixed "base" description of a return value

 

WMLP_GetCap - get the Publisher’s Capabilities object

 

WMLP_GetVersion - retrieves the data version(s) that are supported

 

WMLP_Subscribe - to request subscriptions to data objects

 

These functions are documented on the following pages.

8.8.1        WMLP_GetBaseMsg

Returns a string containing the fixed ("base") message text associated with a return value.

 

string = WMLP_GetBaseMsg(
                                                    [in] integer ReturnValueIn,
                                                     );

 

Parameters (all required):

 

ReturnValueIn - input integer

                                       - a valid Return Value (see Appendix C - Defined Values)

 

Return Value:

string               - the fixed descriptive message text associated with the Return
                                      Value (a null string is returned if ReturnValueIn is invalid)

 

Notes:

 

1) this function returns only the fixed description of the specified Return Value.

2) Variable, context-specific "supplemental" message text and diagnostic
    information, if any, is returned in the SuppMsgOut parameter of the various
    PUBLISH functions.

 


8.8.2        WMLP_GetCap

Returns the capPublisher object which represents the capabilities of the Publisher for one data schema. The capPublisher object is returned in the form of an XML document. Multiple calls to WMLP_GetCap are required in order to determine the capabilities of the server for all data schemas that it supports.

 

integer = WMLP_GetCap(

                                             [in] string OptionsIn,   

                                             [out] string CapabilitiesOut,

                                             [out] string SuppMsgOut        

                                             );

 

Parameters (all required):

 

            OptionsIn       - input string

- The keyword "dataVersion" with a value of a data schema version specifies that capabilities information is desired for that particular data version. The returned capabilities object will utilize the namespace that is appropriate for the data version. For example:
            dataVersion=1.3.1.0
requests information about data version 1.3.1.0 utilizing a 1.3.1 capabilities object. The data schemas that are supported by the server can be determined using WMLP_GetVerson. The version string must match the value of attribute "version" on the plural object container. The default is for the server to return information about the oldest data version that is supported by the server

 

CapabilitiesOut - output string - case sensitive (an XML document)

 

            SuppMsgOut - output string

                                    - supplemental message text

 

Return Value:

short                (see Appendix C - Defined Values)

 

Notes:

 

1)      The OptionsIn parameter string is encoded utilizing a subset of the encoding rules for HTML form content type application/x-www-form-urlencoded as specified at http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.13.3.3.  The encoding is constrained by only allowing semicolons for separators and by not allowing whitespace. For example, “param1=value1;param2=value2”.

 

 


8.8.3        WMLP_GetVersion

Returns a string containing the data version(s) that are supported by the Publisher. A particular data version can be passed to WMLP_GetCap via its OptionsIn parameter to request information about the server capabilities with respect to that data version.

 

string = WMLP_GetVersion();

 

Parameters:

 

none

 

Return Value:

string               - A comma separated list of schema versions (without spaces) that
                                       are supported by the server. The oldest version should be listed
                                       first, followed by the next oldest, etc

 

                        Example: 1.2.0,1.3.1.0

 

Notes:

 

Each version number must match the contents of the version attribute on the plural container element for each object.

 

For more information, see the topic on Versioning in the Terminology and Basic Concepts section of this document.

 


8.8.4        WMLP_Subscribe

Receives and processes Subscription Requests from Subscribers.

 

integer = WMLP_Subscribe(

                                                   [in] string SubscriptionIn,

                                                   [in] string OptionsIn,

                                       [in] string CapabilitiesIn,

                                                   [out] string SubscriptionOut,

                                                   [out] string SuppMsgOut

                                                 );

 

Parameters (all required):

 

            SubscriptionIn – input string – case sensitive (an XML document)

                                     - one or more WITSML Subscription Requests containing the
                                       object types names to which a subscription is to be created, the
                                       subscriber’s host and receiving process name and other
                                       properties of the subscription.

 

OptionsIn       -  input string
- The keyword of ‘returnElements’ with a value of "all" requests that all elements and attributes be returned. The template should be treated as if all elements and attributes had explicitly been specified in the template. A value of "requested" requests the mode of "you only get what you ask for". The default is "requested". For example:
            returnElements=all

 

 

            CapabilitiesIn  - input string - case sensitive (an XML document)
                                      - the Subscriber’s capabilities object (capSubscriber) to be sent to
                                        the Publisher;  may be a null string if no capabilities object is to
                                        be provided to the Publisher.

            SubscriptionOut – output string – case sensitive (an XML document)

                                     - the WITSML Subscription Requests returned by the Publisher
                                       with return codes inserted for each subscription request.

            SuppMsgOut - output string

                                     - supplemental message text

 

Return Value:


short                (see Appendix C- Defined Values)

 

Notes:

 

1) output parameters are valid only if Return Value = 1

 

2) For various reasons, some servers may impose restrictions on subscriptions. For example:

a)      A publisher may not allow more than one subscription (total).

b)      A publisher may not allow more than one subscription per subscriber.

c)      A publisher may not allow more than one subscription per object per subscriber.

d)     When subscribing to realtime, a publisher may require that the subscriber specify a specific well and/or wellbore and/or mnemonic.

e)      A publisher may not allow multiple templates per subscription request.

3)                       The OptionsIn parameter string is encoded utilizing a subset of the encoding rules for HTML form content type application/x-www-form-urlencoded as specified at http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.13.3.3.  The encoding is constrained by only allowing semicolons for separators and by not allowing whitespace. For example, “param1=value1;param2=value2”.

 


8.9         PUBLISH Interface - WSDL File

The Web Service Description Language (WSDL) file used to expose the PUBLISH interface to SOAP clients is listed below. A narrative describing several key points follows the file listing.

 

 

 

 

 

 

 

 

 

 

 

 

 



8.9.1        File Listing

<?xml version='1.0' encoding='UTF-8' ?>

 

<definitions name='WMLP' targetNamespace='http://www.witsml.org/wsdl/120'

             xmlns:wsdlns='http://www.witsml.org/wsdl/120'

             xmlns:soap='http://schemas.xmlsoap.org/wsdl/soap/'

             xmlns:xsd='http://www.w3.org/2001/XMLSchema'

             xmlns='http://schemas.xmlsoap.org/wsdl/'>

           

<documentation>WITSML Version 1.2.0 PUBLISH interface WSDL file

</documentation>

 

<!-- Abstract Definitions Section - <types>, <message> and <portType> elements -->

 

<!-- <types> element declares user-defined machine and language independent data types, and is not needed for the WITSML PUBLISH interface, which uses only W3C-defined data types  -->

 

<!-- <message> elements define request/response messages and their parameters-->

 

<message name='Publish.WMLP_GetBaseMsg'>

     <part name='ReturnValueIn' type='xsd:short'/>

</message>

 

<message name='Publish.WMLP_GetBaseMsgResponse'>

     <part name='Result' type='xsd:string'/>

</message>

 

 

<message name='Publish.WMLP_GetCap'>

     <part name='OptionsIn' type='xsd:string'/>

</message>

 


 

<message name='Publish.WMLP_GetCapResponse'>

     <part name='CapabilitiesOut' type='xsd:string'/>

     <part name='SuppMsgOut' type='xsd:string'/>

     <part name='Result' type='xsd:short'/>

</message>

 

 

<message name='Publish.WMLP_GetVersion'>

</message>

 

<message name='Publish.WMLP_GetVersionResponse'>

     <part name='Result' type='xsd:string'/>

</message>

 

 

<message name='Publish.WMLP_Subscribe'>

     <part name='SubscriptionIn' type='xsd:string'/>

     <part name='OptionsIn' type='xsd:string'/>

     <part name='CapabilitiesIn' type='xsd:string'/>

</message>

 

<message name='Publish.WMLP_SubscribeResponse'>

     <part name='Result' type='xsd:short'/>

     <part name='SubscriptionOut' type='xsd:string'/>

     <part name='SuppMsgOut' type='xsd:string'/>

</message>

 

<!-- <portType> element groups the functions (operations) into an interface  -->

 

<portType name='PublishSoapPort'>

 

<!-- <operation> elements define the function signatures (operation name and parameters) and associate the input and output messages  -->

<!-- parameterOrder attribute values must be separated by a single space  -->

     <operation name='WMLP_GetBaseMsg' parameterOrder='ReturnValueIn'>

          <input message='wsdlns:Publish.WMLP_GetBaseMsg' />

          <output message='wsdlns:Publish.WMLP_GetBaseMsgResponse' />

     </operation>

 


 

     <operation name='WMLP_GetCap' parameterOrder='OptionsIn CapabilitiesOut SuppMsgOut'>

          <input message='wsdlns:Publish.WMLP_GetCap' />

          <output message='wsdlns:Publish.WMLP_GetCapResponse' />

     </operation>

 

     <operation name='WMLP_GetVersion'>

          <input message='wsdlns:Publish.WMLP_GetVersion' />

          <output message='wsdlns:Publish.WMLP_GetVersionResponse' />

     </operation>

 

     <operation name='WMLP_Subscribe' parameterOrder='SubscriptionIn OptionsIn CapabilitiesIn SubscriptionOut SuppMsgOut'>

           <input message='wsdlns:Publish.WMLP_Subscribe' />

           <output message='wsdlns:Publish.WMLP_SubscribeResponse' />

     </operation>

 

</portType>

 

<!-- Concrete Definitions Section - <binding> and <service> elements -->

 

<!-- <binding> specifies the protocol binding for each operation in the <portType> section -->

 

<binding name='PublishSoapBinding' type='wsdlns:PublishSoapPort' >

 

     <soap:binding style='rpc' transport='http://schemas.xmlsoap.org/soap/http' />

 

     <operation name='WMLP_GetBaseMsg' >

          <soap:operation soapAction='http://www.witsml.org/action/120/Publish.WMLP_GetBaseMsg' />

          <input>

               <soap:body use='encoded' namespace='http://www.witsml.org/message/120'

                   encodingStyle='http://schemas.xmlsoap.org/soap/encoding/' />

          </input>

          <output>

               <soap:body use='encoded' namespace='http://www.witsml.org/message/120'

                  encodingStyle='http://schemas.xmlsoap.org/soap/encoding/' />

          </output>

     </operation>

 

     <operation name='WMLP_GetCap' >

          <soap:operation soapAction='http://www.witsml.org/action/120/Publish.WMLP_GetCap' />

          <input>

               <soap:body use='encoded' namespace='http://www.witsml.org/message/120'

                   encodingStyle='http://schemas.xmlsoap.org/soap/encoding/' />

          </input>

          <output>

               <soap:body use='encoded' namespace='http://www.witsml.org/message/120'

                   encodingStyle='http://schemas.xmlsoap.org/soap/encoding/' />

          </output>

     </operation>

 

     <operation name='WMLP_GetVersion' >

          <soap:operation soapAction='http://www.witsml.org/action/120/Publish.WMLP_GetVersion' />

          <input>

               <soap:body use='encoded' namespace='http://www.witsml.org/message/120'

                   encodingStyle='http://schemas.xmlsoap.org/soap/encoding/' />

          </input>

          <output>

               <soap:body use='encoded' namespace='http://www.witsml.org/message/120'

                  encodingStyle='http://schemas.xmlsoap.org/soap/encoding/' />

          </output>

     </operation>

 

     <operation name='WMLP_Subscribe' >

          <soap:operation soapAction='http://www.witsml.org/action/120/Publish.WMLP_Subscribe' />

          <input>

               <soap:body use='encoded' namespace='http://www.witsml.org/message/120'

                   encodingStyle='http://schemas.xmlsoap.org/soap/encoding/' />

          </input>

          <output>

               <soap:body use='encoded' namespace='http://www.witsml.org/message/120'

                   encodingStyle='http://schemas.xmlsoap.org/soap/encoding/' />

          </output>

     </operation>

 

</binding>

 

<!-- <service> specifies the portType for each binding and the URL of the service -->

 

<service name='WMLP' >

     <port name='PublishSoapPort' binding='wsdlns:PublishSoapBinding' >

          <soap:address location='http://yourorg.com/yourwebservice' />

      </port>

  </service>

 

</definitions>

8.9.2        Narrative

§  The only part of the WSDL file that should normally be modified is the location attribute of the SOAP address element. This should be set to the URL of the Web Service (see implementation specifics below):

 

  <service name='WMLP' >

 

    <port name='PublishSoapPort' binding='wsdlns:PublishSoapBinding' >

      <soap:address location='http://yourorg.com/yourwebservice' />

    </port>

 

  </service>

 

§  The WSDL file complies with Version 1.1 of the Web Services Description Language (www.w3.org/TR/wsdl)

 

§  The target namespace and wsdlns prefix used in the WSDL file are both declared as:

 

'http://www.witsml.org/wsdl/120'

 

<definitions name='WMLP'

targetNamespace='http://www.witsml.org/wsdl/120'

                        xmlns:wsdlns='http://www.witsml.org/wsdl/120'

 

§  A default namespace declaration is used to make the document more readable:

 

<definitions name='WMLP' targetNamespace='http://www.witsml.org/wsdl/120'

             xmlns:wsdlns='http://www.witsml.org/wsdl/120'

             xmlns:soap='http://schemas.xmlsoap.org/wsdl/soap/'

             xmlns:xsd='http://www.w3.org/2001/XMLSchema'

             xmlns='http://schemas.xmlsoap.org/wsdl/'>


 

§  The soapAction attribute of the SOAP operation elements specify a WITSML-related URI:  http://www.witsml.org/action/120/Publish.WMLP_xxxx

The soapAction attribute is used by the HTTP transport as the value of the SOAPAction HTTP header. Its use is not clear as of this writing; SOAP 1.1 states that it can be used to identify the “intent” of messages.

 

    <operation name='WMLP_Subscribe' >

      <soap:operation

           soapAction='http://www.witsml.org/action/120/Publish.WMLP_Subscribe' />

      <input>
          …

 

§  The namespace attribute of the SOAP body elements also specify a WITSML-related URI:  http://www.witsml.org/message/120

    <operation name='WMLP_Subscribe' >

      <soap:operation

          soapAction='http://www.witsml.org/action/120/Publish.WMLP_Subscribe' />

      <input>

         <soap:body use='encoded' namespace='http://www.witsml.org/message/120'

                          encodingStyle='http://schemas.xmlsoap.org/soap/encoding/' />

      </input>

    </operation>

            …

§  Although XML generally ignores white-space, the values of certain XML attributes and elements may be sensitive to the amount of white-space. For example, the parameterOrder attribute of the <operation> element must have only a single space between parameters:

    <operation name='WMLP_Subscribe' parameterOrder='SubscriptionIn OptionsIn CapabilitiesIn SubscriptionOut SuppMsgOut'>

 


For an easy-to-read, understandable introduction to WSDL files, see the article titled “Web Services Description Language (WSDL) Explained” by Carlos C. Tapang - Infotects (in the Microsoft MSDN Library and elsewhere).


9          APPENDIX A - Example Data Object Schema

The schema in this section is a non-normative example that is used to demonstrate server behavior. The portions of the schema that conform to normative requirements are:

1)      The root elements are a plural form of the first child element that is formed by adding an “s” to the singular child element. The singular child will be called an “object” within the context of this specification.

2)      The object has mandatory uid attributes. In this example, they are named “uid”.

3)      An object may have foreign uid keys to a “parent” object. In this example, the attributes are named by suffixing “uid” with the parent object name. For example, the parent object of welbore is well. The foreign key from wellbore to well is uidWell. A server may or may not take advantage of this for something like referential integrity.

4)      Recurring nodes that are intended to be updatable via WMLS_UpdateInStore must have a uid attribute. An update of a recurring element that does not have a uid attribute will result in all existing instances of the element being replaced.

Objects well and wellbore are general objects that demonstrate a parent object – child object relationship.

The mudLog object represents a randomly growing object. It has two recurring child elements that both contain “index” values (i.e., mdTop and mdBot). The mudLog contains corresponding “index” values (i.e., startMd and endMd) that represent the range of the child index values in that mudLog.

The trajectory object is similar to the mudLog object except that its recurring child element represents a point rather than an interval. The relevant indexes are mdMx, mdMn and md.

The log object represents a systematically growing “table” where the data is added as “the next row”. The table has an index column and index range values (i.e., startIndex, endIndex, startDateTimeIndex and endDateTimeIndex) for the overall table (in logHeader) and for individual columns of the table (in logCurveInfo).

The realtime object represents a transient stream of data. There will be one header for each wellbore.

The actual form of these objects in a data model is not critical to the behavior described in this specification. It is the servers responsibility to adjust to variations in the schemas and to support the relevant behavior. Inherent to this behavior is that the server must understand underlying concepts such as units of measure, data types, index columns, etc.

<?xml version="1.0" encoding="UTF-8"?>

<xsd:schema

   elementFormDefault="qualified"

   attributeFormDefault="unqualified"

   targetNamespace="http://www.witsml.org/schemas/131ex"

   xmlns=          "http://www.witsml.org/schemas/131ex"

   xmlns:xsd="http://www.w3.org/2001/XMLSchema">

   <!--                                                         -->

   <!-- POSC License Agreement

   This file is distributed under the POSC License Agreement at

   http://www.posc.org/about/license.shtml.

   Use of this file constitutes agreement with the POSC License Agreement.

   -->

   <!--                                                         -->

   <xsd:annotation>

      <xsd:documentation>Example non-normative schemas to describe API behavior. </xsd:documentation>

   </xsd:annotation>

   <!--                                                         -->

   <!--                                                         -->

   <xsd:element name="wells">

      <xsd:complexType>

         <xsd:sequence>

            <xsd:element name="well" maxOccurs="unbounded">  <!—well object à

               <xsd:complexType>

                  <xsd:sequence>

                     <xsd:element name="name" type="xsd:string"/>

                     <xsd:element name="nameLegal" type="xsd:string" minOccurs="0"/>

                     <xsd:element name="country" type="xsd:string" minOccurs="0"/>

                     <xsd:element name="itemState" type="xsd:string" minOccurs="0"/>

                  </xsd:sequence>

               </xsd:complexType>

            </xsd:element>

         </xsd:sequence>

         <xsd:attribute name="uid" type="xsd:string" use="required"/>

      </xsd:complexType>

   </xsd:element>

   <!--                                                         -->

   <xsd:element name="wellbores">

      <xsd:complexType>

         <xsd:sequence>

            <xsd:element name="wellbore" maxOccurs="unbounded">  <!—wellbore object à

               <xsd:complexType>

                  <xsd:sequence>

                     <xsd:element name="nameWell" type="xsd:string"/>

                     <xsd:element name="name" type="xsd:string"/>

                     <xsd:element name="numGovt" type="xsd:string" minOccurs="0"/>

                  </xsd:sequence>

               </xsd:complexType>

            </xsd:element>

         </xsd:sequence>

         <xsd:attribute name="uidWell" type="xsd:string" use="required"/>

         <xsd:attribute name="uid" type="xsd:string" use="required"/>

      </xsd:complexType>

   </xsd:element>

   <!--                                                         -->

   <xsd:element name="mudLogs">

      <xsd:complexType>

         <xsd:sequence>

            <xsd:element name="mudLog" maxOccurs="unbounded">  <!—mudLog object à

               <xsd:complexType>

                  <xsd:sequence>

                     <xsd:element name="nameWell" type="xsd:string"/>

                     <xsd:element name="nameWellbore" type="xsd:string"/>

                     <xsd:element name="name" type="xsd:string"/>

                     <xsd:element name="startMd" type="measure" minOccurs="0"/>

                     <xsd:element name="endMd" type="measure" minOccurs="0"/>

                     <xsd:element name="parameter" minOccurs="0" maxOccurs="unbounded">

                        <xsd:complexType>

                           <xsd:sequence>

                              <xsd:element name="mdTop" type="measure" minOccurs="0"/>

                              <xsd:element name="mdBottom" type="measure" minOccurs="0"/>

                           </xsd:sequence>

                           <xsd:attribute name="uid" type="xsd:string" use="required"/>

                        </xsd:complexType>

                     </xsd:element>

                     <xsd:element name="geologyInterval" minOccurs="0"
                                                     maxOccurs="unbounded">

                        <xsd:complexType>

                           <xsd:sequence>

                              <xsd:element name="typeLithology" type="xsd:string”/>

                              <xsd:element name="mdTop" type="measure>

                              <xsd:element name="mdBottom" type="measure" minOccurs="0"/>

                              <xsd:element name="lithology" minOccurs="0"
                                                        maxOccurs="unbounded">

                                 <xsd:complexType>

                                    <xsd:sequence>

                                       <xsd:element name="type" type="xsd:string”/>

                                    </xsd:sequence>

                                 </xsd:complexType>

                              </xsd:element>

                           </xsd:sequence>

                           <xsd:attribute name="uid" type="xsd:string" use="required"/>

                        </xsd:complexType>

                     </xsd:element>

                     <xsd:element name="nameFormation" type="xsd:string" minOccurs="0"
                                                   maxOccurs="unbounded"/>

                  </xsd:sequence>

               </xsd:complexType>

            </xsd:element>

         </xsd:sequence>

         <xsd:attribute name="uidWell" type="xsd:string" use="required"/>

         <xsd:attribute name="uidWellbore" type="xsd:string" use="required"/>

         <xsd:attribute name="uid" type="xsd:string" use="required"/>

      </xsd:complexType>

   </xsd:element>

   <!--                                                         -->

   <xsd:element name="trajectorys">

      <xsd:complexType>

         <xsd:sequence>

            <xsd:element name="trajectory" maxOccurs="unbounded">  <!—trajectory object à

               <xsd:complexType>

                  <xsd:sequence>

                     <xsd:element name="nameWell" type="xsd:string"/>

                     <xsd:element name="nameWellbore" type="xsd:string"/>

                     <xsd:element name="name"  type="xsd:string"/>

                     <xsd:element name="mdMn"  type="measure" minOccurs="0"/>

                     <xsd:element name="mdMx"  type="measure" minOccurs="0"/>

                     <xsd:element name="trajectoryStation" minOccurs="0">

                        <xsd:complexType>

                           <xsd:sequence>

                              <xsd:element name="md" type="measure" minOccurs="0"/>

                              <xsd:element name="mdDelta" type="measure" minOccurs="0"/>

                           </xsd:sequence>

                        </xsd:complexType>

                     </xsd:element>

                  </xsd:sequence>

                  <xsd:attribute name="uid" type="xsd:string" use="required"/>

               </xsd:complexType>

            </xsd:element>

         </xsd:sequence>

         <xsd:attribute name="uidWell" type="xsd:string" use="required"/>

         <xsd:attribute name="uidWellbore" type="xsd:string" use="required"/>

         <xsd:attribute name="uid"  type="xsd:string" use="required"/>

      </xsd:complexType>

   </xsd:element>

   <!--                                                         -->

   <xsd:element name="logs">

      <xsd:complexType>

         <xsd:sequence>

            <xsd:element name="log" maxOccurs="unbounded">  <!—log object à

               <xsd:complexType>

                  <xsd:sequence>

                     <xsd:element name="nameWell" type="xsd:string"/>

                     <xsd:element name="nameWellbore" type="xsd:string"/>

                     <xsd:element name="name"  type="xsd:string"/>

                     <xsd:element name="logHeader" minOccurs="0">

                        <xsd:complexType>

                           <xsd:sequence>

                              <xsd:element name="dataRowCount" type="xsd:double"
                                  minOccurs="0"/>

                              <xsd:element name="indexType"  type="xsd:string"
                                  minOccurs="0"/>

                              <xsd:element name="startIndex"  type="xsd:double"
                                  minOccurs="0"/>

                              <xsd:element name="endIndex"  type="xsd:double"
                                  minOccurs="0"/>

                              <xsd:element name="indexUnits"  type="xsd:string"
                                  minOccurs="0"/>

                              <xsd:element name="startDateTimeIndex" type="xsd:dateTime"
                                  minOccurs="0"/>

                              <xsd:element name="endDateTimeIndex" type="xsd:dateTime"
                                  minOccurs="0"/>

                              <xsd:element name="direction"  type="xsd:string"
                                  minOccurs="0"/>

                              <xsd:element name="indexCurve"  type="xsd:string"
                                  minOccurs="0"/>

                              <xsd:element name="logCurveInfo" minOccurs="0"
                                  maxOccurs="unbounded">

                                 <xsd:complexType>

                                    <xsd:sequence>

                                       <xsd:element name="mnemonic"  type="xsd:string"
                                         minOccurs="0"/>

                                       <xsd:element name="nullValue"  type="xsd:string"
                                         minOccurs="0"/>

                                       <xsd:element name="startIndex"  type="xsd:double"
                                         minOccurs="0"/>

                                       <xsd:element name="endIndex"  type="xsd:double"
                                         minOccurs="0"/>

                                       <xsd:element name="startDateTimeIndex"
                                         type="xsd:dateTime" minOccurs="0"/>

                                       <xsd:element name="endDateTimeIndex"
                                         type="xsd:dateTime" minOccurs="0"/>

                                       <xsd:element name="columnIndex" type="xsd:integer"
                                         minOccurs="0"/>

                                    </xsd:sequence>

                                 </xsd:complexType>

                              </xsd:element>

                           </xsd:sequence>

                        </xsd:complexType>

                     </xsd:element>

                     <xsd:element name="logData" minOccurs="0">

                        <xsd:complexType>

                           <xsd:sequence>

                              <xsd:element name="data" type="xsd:string" minOccurs="0"
                                  maxOccurs="unbounded"/>

                           </xsd:sequence>

                        </xsd:complexType>

                     </xsd:element>

                  </xsd:sequence>

               </xsd:complexType>

            </xsd:element>

         </xsd:sequence>

         <xsd:attribute name="uidWell" type="xsd:string" use="required"/>

         <xsd:attribute name="uidWellbore" type="xsd:string" use="required"/>

         <xsd:attribute name="uid"  type="xsd:string" use="required"/>

      </xsd:complexType>

   </xsd:element>

   <!--                                                         -->

   <xsd:element name="realtimes">

      <xsd:complexType>

         <xsd:sequence>

            <xsd:element name="realtime" maxOccurs="unbounded">

               <xsd:complexType>

                  <xsd:sequence>

                     <xsd:element name="dTim" type="xsd:dateTime" minOccurs="0"/>

                     <xsd:element name="md" type="measure"/>

                     <xsd:element name="realtimeHeader" minOccurs="0">

                        <xsd:complexType>

                           <xsd:sequence>

                              <xsd:element name="nameWell" type="xsd:string"/>

                              <xsd:element name="nameWellbore" type="xsd:string"/>

                              <xsd:element name="channelDefinition" minOccurs="0">

                                 <xsd:complexType>

                                    <xsd:sequence>

                                       <xsd:element name="mnemonic" type="xsd:string"/>

                                    </xsd:sequence>

                                 </xsd:complexType>

                              </xsd:element>

                           </xsd:sequence>

                        </xsd:complexType>

                     </xsd:element>

                     <xsd:element name="channel" minOccurs="0">

                        <xsd:complexType>

                           <xsd:sequence>

                              <xsd:element name="mnemonic" type="xsd:string"
                                  minOccurs="0"/>

                              <xsd:element name="md" type="measure" minOccurs="0"/>

                              <xsd:element name="dTim" type="xsd:dateTime"
                                  minOccurs="0"/>

                              <xsd:element name="value" type="measure"/>

                              <xsd:element name="qualData" type="xsd:string"/>

                           </xsd:sequence>

                        </xsd:complexType>

                     </xsd:element>

                  </xsd:sequence>

                  <xsd:attribute name="uidWell" type="xsd:string" use="required"/>

                  <xsd:attribute name="uidWellbore" type="xsd:string" use="required"/>

                  <xsd:attribute name="idSub"  type="xsd:string" use="required"/>

               </xsd:complexType>

            </xsd:element>

         </xsd:sequence>

      </xsd:complexType>

   </xsd:element>

   <!--                                                         -->

   <xsd:complexType name="measure">

      <xsd:simpleContent>

         <xsd:extension base="xsd:double">

            <xsd:attribute name="uom" type="xsd:string" use="required"/>

         </xsd:extension>

      </xsd:simpleContent>

   </xsd:complexType>

   <!--                                                         -->

</xsd:schema>

 


10      APPENDIX B - Unit of Measure

10.1     Overview

Numeric measure values exchanged using WITSML have an associated "uom" attribute that describes the Unit of Measure for that value. This is a flexible approach that allows data to be exchanged with the minimum of constraints or assumptions.

10.2     Basics

The "uom" attribute is mandatory for all numeric values that need to be qualified with a unit of measure indicator to provide the full context of an element value. The value of the uom attribute is expected to match an ‘annotation’ attribute from the WITSML Units Dictionary XML file that is included with the Data Schema.

 

For example, a WITSML document may contain the fragment:

 

<ropAv uom="ft/h">80.00</ropAv>

 

This specifies that the value for ropAv is measured in feet per hour ("ft/h").

 

The "uom" value of "ft/h" is the annotation for a UnitOfMeasure in the WITSML Units Dictionary reference file as:

 

<UnitOfMeasure id="ftPh" annotation="ft/h">

      <Name>feet/hour</Name>

      <CatalogName>POSC</CatalogName>

      <CatalogSymbol isExplicit="true">ft/h</CatalogSymbol>

      <ConversionToBaseUnit baseUnit="m/s">

            <Fraction>

                  <Numerator>0.3048</Numerator>

                  <Denominator>3600</Denominator>

            </Fraction>

      </ConversionToBaseUnit>

</UnitOfMeasure>

 

This gives a link to the base SI unit of meters per second and a suggested conversion to this base unit.

 

In this way, any WITSML compliant document can be decoded by any application that can work with SI units.


10.3     Process interaction with ‘uom’

A provider and consumer of WITSML documents can work with units in a number of ways:

  1. No preference of units expressed by the consumer (i.e. ‘uom’ in a query template is empty or absent, or the document has been generated as a result of a non-SOAP request).

The provider will provide the data in a mutually agreed or default set of units of measure.

E.g. A request for <ropAv uom=““/> gives

<ropAv uom=“ft/h”>80.00</ropAv>

 

  1. The consumer requests an element in a particular unit of measure, that is recognized by the provider as compliant with WITSML.

The provider will supply the element converted to the requested unit of measure and with the ‘uom’ attribute populated appropriately.

E.g. A request for <ropAv uom=“ft/min”/> gives

<ropAv uom=“ft/min”>1.3333</ropAv>

 

  1. The consumer requests an element in a particular unit of measure, that is NOT recognized by the provider as compliant with WITSML.

The provider will supply the element converted to the server default unit of measure and with the ‘uom’ attribute populated appropriately.

E.g. <ropAv uom=“furlong/fortnight”/> gives

<ropAv uom=“ft/h”>80.00</ropAv>

  1. The provider does not support requests for units of measure other than the server default.

E.g. A request for <ropAv uom=“ft/min”/> gives

<ropAv uom=“ft/h”>80.00</ropAv>

Notes:

1) It is server dependent as to which options are supported.

10.4     Responsibilities

If a unit is requested, a server / publisher will always populate the ‘uom’ attribute of an element with an entry that describes the units of the element value. The ‘uom’ will align with the WITSML units dictionary.

The source of the data should use consistent units within an object. For example, all length measures in the same unit and all coordinates of the same type (e.g., measured depth) in the same unit. The unit system should also be consistent (e.g., metric). The source might be a server or it might be a client that adds data to a server.

A uom attribute is not part of the selection criteria. Specifying a particular uom value in a query template is a request for the element value to be returned in those units But, the client / subscriber should verify that the ‘uom’ in the returned document matches that requested and if not, handle any mismatch as it sees fit.

If an empty uom attribute is specified in a query then a default unit will be returned.

10.5      Updating

The WITSML Units Dictionary file) is included in the WITSML distribution media for each WITML Data Schema version.

 

Updates to the Units Dictionary are made as part of the WITSML Data Schema revision process.

 


11      APPENDIX C - Defined Values

11.1     Return Values

The values returned in intReturn by the WITSML Core API functions are shown below, along with the string returned by the WMLx_GetBaseMsg function.

 

The WITSML-defined Return Values are in the range of -999 thru -1 (to indicate exception conditions) and 1 (to indicate no exception occurred).

 

Implementers are encouraged to use values from this list whenever possible.

 

It is recognized that this list is incomplete, however, and additional values will need to be defined over time.

 

If no Return Value is presently defined for an error condition, implementers are free to assign their own proprietary Return Values less than -1000 (i.e., -1001, -1002, etc).

 

It is hoped that proprietary Return Values will be contributed to the WITSML community for possible inclusion in this standard list.

 

 

Value  String returned by WMLx_GetBaseMsg

 

1          Function completed successfully

 

 -1nn:   Parameter errors

 

-101     Parameter error: Invalid/missing WITSML object type

-102     Parameter error: Invalid/missing XML

-103     Parameter error: Invalid/missing selection criteria

-104     Parameter error: Invalid/missing server name

-105     Parameter error: Invalid/missing publisher name

-106     Parameter error: Invalid/missing subscriber name

-107     Parameter error: Invalid/missing real-time data type name

-108     Parameter error: Invalid/missing real-time data

-109     Parameter error: Invalid/missing XML Schema (XSD) path/filename

-110     Parameter error: Invalid option

-111     Parameter error: Invalid/missing subscriber process location

-112     Parameter error: Invalid/missing subscriber secure indicator

-199     Parameter error: unknown cause


 

 -2nn:   Persistent Store errors

 

-201     Persistent Store error: Duplicate key

-202     Persistent Store error: Could not parse XML

-203     Persistent Store error: Could not map XML

-204     Persistent Store error: No data matched selection criteria

-205     Persistent Store error: The query results are too large

-299     Persistent Store error: unknown cause

 

 

 -3nn:   XML Schema errors

 

-301     XML Schema error: Error while parsing the specified XML Schema (XSD) file

-302     XML Schema error: specified XML Schema (XSD) has invalid content

-303     XML Schema error: no base attribute present below data type definition element

-304     XML Schema error: nesting of data types exceeds maximum - check for circular

              reference in definitions

-305     XML Schema error: unrecognized XML Schema data type

-306     XML Schema error: circular reference (loop) in included schemas

-399     XML Schema error: unknown cause

 

 

 -9nn:   program logic/exception errors

 

-901     Program Error: problem loading internal program or component

-902     Program Error: XML Schema data type is not presently supported by the
              WITSML API

-999     Program Error: unknown cause

 

 

 

 


12      APPENDIX D – Special Handling

Several WITSML data objects contain recurring groups of data items organized into structures.

 

For example, the mudLog object can contain multiple occurrences of the group of data items related to a geologyInterval:

 

            <mudLog uidWell="W-12" uidWellbore="B-01" uid="h45a">

                        …

                        <geologyInterval>

                                    <mdTop uom="ft">5000</mdTop>

mudLog data object with multiple geologyInterval structures

 
                                    <mdBottom uom="ft">5030</mdBottom>

                                    …

                        </geologyInterval>

                        <geologyInterval>

                                    <mdTop uom="ft">5030</mdTop>

                                    <mdBottom uom="ft">5060</mdBottom>

                                    …

                        </geologyInterval>

                        …

            </mudLog>

 

 

Using the standard behavior of the Query and Subscription templates, the above mudLog object could be retrieved or subscribed by specifying:

 

            <mudLog uidWell="W-12" uidWellbore="B-01" uid="h45a">

template requesting all geologyIntervals

 
                        <geologyInterval>

                                    …

                        </geologyInterval>

            </mudLog>

 

 

This template will retrieve - or cause to be published - all occurrences of the geologyInterval structure within the mudLog object.

 

If, however, one wished to retrieve only a particular range of geologyIntervals, then special handling - above and beyond the standard behavior - is required by the Server and Publisher.

 


To accommodate the need to selectively retrieve or have published only a range of occurrences of a structure, special handling rules have been defined for some types of data objects.

 

Generally, the data objects with special handling rules are those that:

1) have a relatively large number of occurrences of recurring data that is indexed in depth or time

 

            and

 

2) have additional occurrences of recurring data that are inserted (or updated) over time
    (e.g., the object grows)

There are two types of these growing objects that are supported with special behavior: randomly growing and systematically growing. For randomly growing object the indexes in the substructures are unrelated and they may overlap or coexist in the index space. These substructures must be assigned a uid attribute. For systematically growing objects, the equivalent of a “table” is described and data is added one “row” at a time. It is assumed that the data does not overlap in index space. These “row” structures are not assigned a uid attribute.

 

 

When this specification was issued, the following WITSML data objects were categorized as growing objects

 

§     trajectory       (random)

§     mudLog          (random

§     log                   (systematic)

§     wellLog           (systematic)

 

The special handling rules modify the standard behavior of Query and Subscription templates, as well as the rules which determine what portions of these objects are eligible for publication.

 
 

 

 

 

 

 

 

 

 

 

 

 

 


12.1     Randomly growing objects

In order for an object to qualify for special server behavior as a randomly growing object the object must have the following characteristics.

1)      In a non-recurring portion of the object (e.g., in a header) there must be one or more pairs of elements that each represent a range of index values. Each pair must represent a measure, a coordinate or a date-time value. These elements must represent the range (i.e., minimum and maximum) of index values that exist in the substructures. That is, they represent a structural range. Each individual element may represent concepts such as start, end, minimum, maximum, top or bottom but the content of the pair must be able to represent a minimum and maximum. For example, startMd and mdTop in mudlogs, mdMn and mdMx in trajectory represent structural range elements.

2)      Each  recurring substructure(s) must contain element(s) representing a particular index point or index interval that locates the each node in the index space. These index(es) represent the node index More that one index space may be represented but, if so, corresponding structural range elements must exist in the non-recurring area. This substructure represents the data nodes. Example node indexes are, mdTop and mdBottom in the mudLog’s parameter and geologyInterval, md in trajectoryStation, and the index curve in log data. Example data nodes are (mudLog) parameter, geologyInterval, trajectoryStation and (log) data.

3)      The recurring substructure(s) must have a uid attribute to uniquely identify each node.

4)      The schema must categorize the object as a randomly growing object and document the above elements accordingly.

If an object conforms to the above characteristics, the behavior listed in the following subsections must be supported by the server. It is the servers responsibility to under stand how a particular schema fits the above characteristics.

12.2     Systematically Growing Objects

In order for an object to qualify for special server behavior as a systematically growing object the object must have the following characteristics.

1)      The object must represent a table or a set of tables.

2)      In a non-recurring portion of the object (e.g., in a header) there must be one or more pairs of elements that each represent a range of index values. Each pair must represent a measure, a coordinate or a date-time value. These elements must represent the range (i.e., minimum and maximum) of index values that exist in a single table. That is, they represent a structural range. Each individual element may represent concepts such as start, end, minimum, maximum, top or bottom but the content of the pair must be able to represent a minimum and maximum. For example, startIndex and endIndex in logHeader represent structual range elements.

3)      If the object represents a set of (i.e., multiple) tables:

a.       The above structural range elements must exist in the recurring structure that describes each individual table. The recurring table definition structure must have a uid attribute to uniquely identify each table.

b.      In a non-recurring portion of the object (e.g., in a header) there may be one or more pairs of elements that each represent an overall range of index values for all tables. The overall range values represent the range of rows that actually exist in the tables.

4)      Each table must be assigned a recurring structure that represents a row in that table. This structure represents the data nodes (i.e., rows). This recurring structure should not have a uid attribute. The recurring row structure must contain a point value (i.e., not to a pair representing an interval) in each indexing space. This value represents the node index. Note that this value may be implicitly defined (e.g., via start and increment) or be explicitly defined as a column. An example node index is the data value representing the index curve in log data. An example data node is data in logData.

5)      Each table definition structure must be assigned a recurring structure to describe each column in the table. Each column should have a contextual column identifier (not a uid). For example, mnemonic in logCurveInfo represents a column identifier. Each column may have one or more pairs of elements that each represent an informative range of index values for that column. The range values represent the range where values of that column actually exist in the table. Null or empty values would be excluded from this range. For example, startIndex and endIndex in logCurveInfo represents informative range elements.

6)      Each table may have an element to define the row count (number of rows) in the persistent store. For example, dataRowCount in logHeader represents a row count element.

7)      The schema must categorize the object as a systematically growing object and document the above elements accordingly.

If an object conforms to the above characteristics, the behavior listed in the following subsections must be supported by the server. It is the servers responsibility to understand how a particular schema fits the above characteristics.

12.3     STORE and PUBLISH behavior

The following STORE and PUBLISH behavior is available to qualified growing objects:

1)      In a WMLS_GetFromStore template or a WMLP_Subscribe template:

a.       For PUBLISH, information in the non-recurring header portion of a growing object is eligible for publication if anything in the object has changed. Data nodes that are new or have changed are eligible for publication but data nodes that have not changed are not eligible for publication. The subscription template is only applied to data that is eligible for publication.

b.      If a structural range value is specified and data nodes are requested, the range values are interpreted as meaning to include in the returned object all data nodes where the node index values are at or within the index range.

                                                              i.      For a point index, the data node will be included if the node index is greater than or equal to the minimum range value and less than or equal to the maximum range value.

                                                            ii.      For an interval index, the data node will be included if the minimum node index value is greater than or equal to the minimum range value and the maximum node index value is less than or equal to the maximum range value.

                                                          iii.      If a minimum range value is specified and not a maximum range value, all data nodes with a minimum or point node index value greater than or equal to that minimum range value will be returned.

                                                          iv.      If a maximum range value is specified and not a minimum range value, all data nodes with a maximum or point node index value less than or equal to that maximum range value will be returned.

                                                            v.      The returned range values will match the range of the node index values in the returned data nodes.

                                                          vi.      If there are no data nodes within the specified index range, then nothing will be returned for those nodes. An empty node will not be returned.

                                                        vii.      As is true for all queries, if a node index value is to be returned then it must be explicitly specified in the query. The selection of which data nodes are to be returned is performed against the persisted index values whether the index is specified in the query or not.

                                                      viii.      For a randomly growing object, if a value is specified for a node index element and a structural range value is also specified, the node index value will be ignored. The node index element will be interpreted as a normal query request for a value of that element.

                                                          ix.      The structural range and column identifiers represent Cellular selection criteria (i.e., which cells from a table) and they are AND’ed together. Any other Cellular selection criteria (e.g., a specific data value or header value) will also be AND’ed. The returned result set will contain only the cells where all the Cellular Selection criteria are true. A row will not be returned with all null values. If there are no non-null values for a column within the specified range then nothing about that column will be returned. The Cellular selection criteria are AND’ed with any Object selection criteria.

c.       If a structural range value is specified and data nodes are not requested, the range values are interpreted as meaning to include in the returned object only information about those columns which have non-null data within that range. That is, no (header) information will be returned about columns which do not have non-null data in that range. The result will be the same as when data nodes are requested except that data nodes will not be returned.

d.      If a structural range element is specified and data nodes are not returned (whether data nodes are requested or not), the range values that are returned will reflect the values in the persistent store.

e.       If no structural range value is specified, standard query rules apply and all nodes – regardless of index – will be returned assuming that they match any other specified selection criteria.

f.       For a systematically growing object, if an informative range element is specified:

                                                              i.      If a value is specified, then it will be ignored.

                                                            ii.      If no data nodes are returned then the server will return a value that reflects the persistent data in the server.

                                                          iii.      If data nodes are returned then the server will return a value that reflects the returned nodes.

g.      For a systematically growing object, if a value for the row count is specified then the server will limit the resultant number of data nodes to a maximum of that value. The returned value for the row count will be the number of rows in the persistent store.

h.      For a systematically growing object, if no column identifier is specified then the server will interpret it as a request for all columns.

2)      In a WMLS_UpdateInStore template for a systematically growing object:

a.       If a structural range value is not specified the server will interpret it as a request to append the data nodes. For the purpose of this section, “append” means to add new data whose index is greater than the current maximum index.

b.      If a structural range value is specified, the server will interpret it as a request to replace the specified data nodes or to insert new data nodes as appropriate. This is logically an “insert” if no data exists within the specified range. The structural range value should match the index range in the new data because some servers will delete the structural range and some servers will delete the range in the data before adding the new data. However, only the specified columns will be cleared as part of the replacement.

c.       If a new column identifier and data nodes with values are specified then the values will be added to existing data nodes and new data nodes will be added if required. The only other column identifier that can be specified is the index column. A structural range must not be specified with this option but its absence does not imply append.

d.      If informative range values are specified, they will be ignored.

3)      In a WMLS_DeleteFromStore template,

a.       For a randomly growing object, specifying the uid of data node will delete that node. This extends the normal behavior that only an object can be deleted.

b.      For a systematically growing object , if a structural range value is specified

                                                              i.      The server will interpret it as a request to delete all data nodes with a node index that is greater than or equal to the minimum range value and less than or equal to the maximum range value.

                                                            ii.      Specifying only the minimum range value will delete all data nodes with a node index value that is greater than or equal to the range value.

                                                          iii.      Specifying only the maximum range value will delete all data nodes with a data index value that is less than or equal to the range value.

c.       For a systematically growing object , if a column identifier is specified then all information associated with that column will be deleted. A structural range can be specified with this option in order to delete a subset of a column.

4)      The structural range, overall range, informative range and row count elements are considered to be read-only elements and any request to update them will be ignored by the server without an error being issued.

For all other functions the normal STORE rules apply. For example, use WMLS_UpdateInStore to add a data node in a randomly growing object by specifying a node with a new uid value.

 


12.4     STORE Interface Examples

The special handling in the STORE interface for the trajectory, mudLog and log objects allows a Query template to specify a range of recurring structures to be returned.

 

For all three objects, the range of recurring structures to be returned is indicated by specifying values for specific, pre-determined index range data element(s) in the non-recurring ("header") portion of the object. These values are then compared against specific, pre-determined index data element(s) in the recurring portion of the object. If the data element(s) in the recurring portion fall within the specified index range, that occurrence of the recurring structure is included in the returned data object.

 

 

 

Object             Range Specified By           Recurring             Compared To Field

                      Element(s) in Header           Structure           in Recurring Structure     

 

example (see below)  begin/end                         xxx                                index

 

mudLog               startMd/endMd               geologyInterval         mdTop/mdBottom

 

log                      startIndex/endIndex (1)          data (2)             data value of the index

 

trajectory             mdMn/mdMx                 trajectoryStation                   md

 

Notes:

 

1) startIndex/endIndex elements are in the logHeader. The elements startDateTimeIndex and endDateTimeIndex are alternative indexes which are treated similarly to startIndex and endIndex but have a different underlying type.

 

2) data structure is in the logData container

 


Example:

 

Persisted Data Object                  Query Template               Returned Data Object                    

<example…>                                    <example…>                     <example…>

      <header_elements>                       <begin>950</begin>          <begin>1000</begin>    

             …                                            <end>4000</end>             <end>3000</end>

      <xxx>                                             <xxx>                                <xxx>

           <index>500</index>                     <index/>                           <index>1000</index>

               …                                          </xxx>                               </xxx>

      </xxx>                                       </example>                            <xxx>     

      <xxx>                                                                                           <index>3000</index>

           <index>1000</index>                                                         </xxx> 

              …                                                                                   </example>

      </xxx>

      <xxx>

            <index>3000</index>

                    …

      </xxx>

</example>


12.4.1    trajectory Data Object Example

The trajectory data object contains recurring trajectoryStation structures:

 

<trajectory uidWell="W-12" uidWellbore="B-01" uid="pe84e">

                        …

trajectory data object with multiple trajectoryStation structures

 
            <trajectoryStation …              uid="34ht5">

                        …

            </trajectoryStation>

            <trajectoryStation …  uid="34ht6">

                        …

            </trajectoryStation>

                        …

</trajectory>

 

A Query can retrieve a range of trajectoryStations by specifying values for the minimum and maximum measured-depth elements (mdMn and mdMx) of the trajectory object and by specifying a single trajectoryStation element in the Query template, such as:

 

<trajectory uidWell="W-12" uidWellbore="B-01" uid="pe84e">

            <mdMn>3000</mdMn>

query template specifying a depth range and a single trajectoryStation structure

 
            <mdMx>4000</mdMx>

                        …

            <trajectoryStation … >

                        …

            </trajectoryStation>

</trajectory>

 

 

 

 

 

 


 


If no value is specified for both the mdMn or mdMx elements, "standard" Query template handling rules will apply, and all trajectory stations - regardless of depth - will be returned (assuming they match any other specified selection criteria).

 

If a value is specified for mdMn and not for mdMx, all trajectoryStation occurrences with an md value greater than or equal to mdMn will be returned. Likewise, if a value is specified for mdMx and not for mdMn, all trajectoryStation occurrences with an md value less than or equal to mdMx will be returned.

 

If there are no trajectoryStations with md values within the specified range of value(s) for mdMn/mdMx, any requested header elements will be returned but no trajectoryStations will be returned (i.e., an empty element will not be returned).

 

► As is true for Query templates in general, if the md element of the trajectoryStation structure is to be returned, it must be explicitly specified in the Query:

 

<trajectory uidWell="W-12" uidWellbore="B-01" uid="pe84e">

            <mdMn>3000</mdMn>

query template requesting that the md data item be returned in the trajectoryStation structure(s)

 
            <mdMx>4000</mdMx>

                        …

            <trajectoryStation …

                        <md/>

            </trajectoryStation>

                        …

</trajectory>

 

The selection of which trajectoryStation(s) are to be returned is performed against the persisted md value(s), whether the md item is specified in the Query template or not.

 

If a value is specified in the trajectory for mdMn or mdMx, and a value is also specified in the trajectoryStation for md, the value of md in the trajectoryStation will be ignored:

 

<trajectory uidWell="W-12" uidWellbore="B-01" uid="pe84e">

            <mdMn>3000</mdMn>

            <mdMx>4000</mdMx>

                        …

this value will be ignored

 
            <trajectoryStation  …

                        <md>5000</md>

            </trajectoryStation>

                        …

</trajectory>

 

The above query would return all trajectoryStation instances between 3000 and 4000 (inclusive). The md element of the returned trajectoryStations will contain the persisted value for each.

Any values specified for an attribute or element of the trajectoryStation structure - other than the md child element - are combined with the selection criteria specified by mdMn and mdMx. The following example would return all trajectoryStations with mdDelta value of 10 within the 3000-4000 depth range:

 

<trajectory uidWell="W-12" uidWellbore="B-01" uid="pe84e">

            <mdMn>3000</mdMn>

criteria are combined

 
            <mdMx>4000</mdMx>

                        …

            <trajectoryStation>

<mdDelta>10</mdDelta>    

</trajectoryStation>

                        …

</trajectory>

 


12.4.2    mudLog Data Object Example

The mudLog data object contains recurring geologyInterval structures:

 

<mudLog uidWell="W-12" uidWellbore="B-01" uid="h45a">

                        …

<parameter>

                        …

            </ parameter >

mudLog data object with multiple parameter and geologyInterval structures

 
<parameter>

                        …

            </ parameter >

<geologyInterval>

                        …

            </geologyInterval>

<geologyInterval>

                        …

            </geologyInterval>

            …

</mudLog>

 

A Query template can retrieve a range of parameters and/or geologyIntervals by specifying values for the start and end measured-depth elements (startMd and endMd) of the mudLog object:

 

<mudLog uidWell="W-12" uidWellbore="B-01" uid="h45a">

                        <startMd>5010</startMd>

query template specifying a depth range and a single geologyInterval structure

 
                        <endMd>5020</endMd>

                                    …

                        <geologyInterval>

                                    …

                        </geologyInterval>

 

</mudLog>

 

 

 

 

 

 

 

 

 



If no value is specified for both the startMd or endMd elements, "standard" Query template handling rules will apply, and all parameter or geologyIntervals - regardless of depth - will be returned (assuming they match any other specified selection criteria).

 

If a value is specified for startMd and not for endMd, all parameter or geologyInterval occurrences with an mdTop value greater than or equal to startMd will be returned. Likewise, if a value is specified for endMd and not for startMd, all parameter or geologyInterval occurrences with a mdBottom value less than or equal to endMd will be returned.

 

If there are no parameter or geologyIntervals with mdTop/Bottom values within the specified range of value(s) for startMd/endMd, any requested header elements will be returned but no geologyIntervals will be returned (i.e., an empty element will not be returned)

 

► As is true for Query templates in general, if the mdTop and/or mdBottom elements of the parameter or geologyInterval structure are to be returned, they must be specified:

 

<mudLog uidWell="W-12" uidWellbore="B-01" uid="h45a">

                        <startMd>5010</startMd>

                        <endMd>5020</endMd>

query template requesting that the mdTop and mdBottom data items are to be returned in the geologyInterval structure(s)

 
                                    …

                        <geologyInterval>

                                    <mdTop/>

                                    <mdBottom/>

                        </geologyInterval>

</mudLog>

 

The selection of which parameter(s) or geologyInterval(s) are to be returned is performed against the persisted mdTop/mdBottom value(s), whether the mdTop/mdBottom item is specified in the Query template or not.

 

If a value is specified in the mudLog for startMd or endMd, and a value is also specified in the parameter or geologyInterval for mdTop/mdBottom, the value of mdTop/mdBottom in the geologyInterval will be ignored:

 

<mudLog uidWell="W-12" uidWellbore="B-01" uid="h45a">

                        <startMd>5010</startMd>

                        <endMd>5520</endMd>

                                    …

this value will be ignored

 
                        < parameter >

                                    <mdTop>4000</mdTop>

                        </ parameter >

</mudLog>

 

The above query will return all the parameters between 5010 and 5520 (inclusive). The mdTop element of the returned parameters will contain the persisted value for each.

 

Any values specified for an attribute or element of the parameter or geologyInterval structure - other than the mdTop/mdBottom element described above - are combined with the selection criteria specified by startMd and endMd. The following query would return the geologyIntervals between 5010 and 5510 which have a dolomite value of 1:

 

            <mudLog uidWell="W-12" uidWellbore="B-01" uid="h45a">

                        <startMd>5010</startMd>

criteria are combined

 
                        <endMd>5510</endMd>

                                    …

                        <geologyInterval>

                                    <dolomite>1</dolomite>

                        </geologyInterval>

 

</mudLog>

 


12.4.3    log Data Object Example

Because the special handling required by the log object is somewhat more complex than the other objects, we should first review the structure of the log object.

 

The log object can be logically divided into two sections: metadata about the log (logHeader section) and the data for the curves (logData section).

 

                  XML Element                                      Description

     <log   …>

 

          <logHeader   …>

metadata section

                 <dataRowCount …>

The number of data rows in the persistent log.

                 <indexType …>

type of log (depth, datetime, elapsed time or other)

                 <startIndex …>

starting time/depth index for entire log

                 <endIndex …>

ending time/depth index for entire log

                 <indexCurve …>

name of curve which serves as index value

                          … 

additional child elements of logHeader

                <logCurveInfo   …>

metadata about a curve

                         <startIndex …>

starting time/depth index for this curve

                         <endIndex …>

ending time/depth index for this curve

                              …               

additional child elements of logCurveInfo

                </logCurveInfo>

 

                           …

additional occurrences  of logCurveInfo structure

          </logHeader>

 

          <logData   …>

data section

                   <data>

data for all curves at this time/depth index

                            …

additional occurrences  of data element

          </logData>

 

    </log>

 

 

The logHeader section defines:

 

The logData section of the log object contains one or more <data> elements, each containing a comma-delimited string value that contains the data points at a particular depth or time for all the curves in the log.


Here is an example of a simplified log object containing four log curves: Mdepth, ROP, Bit RPM and ECD.

           

<log uidWell="W-12" uidWellbore="B-01" uid="L001">

                        <logHeader>

                                    <dataRowCount>5</ dataRowCount>

Metadata about the entire log

       (table)

 
                                    <indexType>MeasuredDepth</indexType>

                                    <startIndex>4050</startIndex>

                                    <endIndex>4090</endIndex>

                                    <indexCurve>Mdepth</indexCurve>

                                    <logCurveInfo>

                                                <mnemonic>Mdepth</mnemonic>

                                                <startIndex>4050</startIndex>

                                                <endIndex>4090</endIndex>

                                                <columnIndex>1</columnIndex>

                                    </logCurveInfo>

                                    <logCurveInfo>

                                                <mnemonic>ROP</mnemonic>

                                                <startIndex>4050</startIndex>

                                                <endIndex>4090</endIndex>

Metadata about individual curves

(column heading)

 
                                                <columnIndex>2</columnIndex>

                                    </logCurveInfo>

                                    <logCurveInfo>

                                                <mnemonic>Bit RPM</mnemonic>

                                                <nullValue>-99999</nullValue>

                                                <startIndex>4050</startIndex>

                                                <endIndex>4070</endIndex>

                                                <columnIndex>3</columnIndex>

                                    </logCurveInfo>

                                    <logCurveInfo>

                                                <mnemonic>ECD</mnemonic>

                                                <startIndex>4060</startIndex>

                                                <endIndex>4090</endIndex>

                                                <columnIndex>4</columnIndex>

                                    </logCurveInfo>

                        </logHeader>

                        <logData>

<data>4050,   37.11,    93.74,         </data>

Intervals

  (rows)

 
                                    <data>4060,     9.85,         95,   1.33</data>

                                    <data>4070,   32.44,    89.19,   1.31</data>

                                    <data>4080,   29.03,  -99999,   1.32</data>

                                    <data>4090,   13.09,  -99999,   1.34</data>

                        </logData>

Curves

(columns)

 
            </log>


 

From dataRowCount we learn that the log has 5 data intervals. From the startIndex and endIndex elements of the logHeader we can see that the entire log covers the range of 4050 thru 4090. From the startIndex/endIndex elements of the four logCurveInfo elements, we see that the Mdepth and ROP curves cover this same range. The Bit RPM curve, however, contains non-null data only for 4050-4070 and the ECD curve contains non-null data only for 4060-4090.

 

The values for the four curves are stored in the log as four data points within each <data> element - one data point for each curve. [7]

 

            …

<logData>

<data>4050,   37.11,    93.74,         </data>

Intervals

 
                                    <data>4060,     9.85,         95,   1.33</data>

                                    <data>4070,   32.44,    89.19,   1.31</data>

                                    <data>4080,   29.03,  -99999,   1.32</data>

                                    <data>4090,   13.09,  -99999,   1.34</data>

                        </logData>

Curves

 
            </log>

 

 

Our four curves happen to have ascending <columnIndex> values (Mdepth =1, ROP = 2, etc), and so the first “column” in the <data> element contains the Mdepth values (4050, 4060, etc) followed by the ROP values in column 2 (37.11, 9.85, etc), the Bit RPM values in column 3 and the ECD values in column 4.

 

If a log curve has no value at a particular depth or time, the value for that column in that <data> element will be the value of the nullValue element specified for that curve or - if no nullValue is specified, a null string.

 

For example, the Bit RPM curve specifies a value of -99999 for its nullValue element. Therefore, the Bit RPM (3rd) column of the <data> element uses a value of -99999 for the fourth and fifth intervals to indicate null values. However, since the nullValue element was not specified for the other log curves, a null string (consecutive commas) will be used to indicate null values for all other curves. This is the case with the ECD (4th) column, in which a null string is used to indicate a null value for the first interval.

 


Viewed another way, the five example <data> elements convey the following data points for our four curves:

                                                  Interval

                                  #1       #2          #3       #4        #5

        MDepth         4050    4060     4070    4080    4090

        ROP              37.11    9.85    32.44   29.03   13.09

        Bit RPM        93.74       95    89.19  -99999  -99999

        ECD        null string   1.33      1.31     1.32     1.34

 

One of the curves in a log must be designated as the “Index Curve”. If the log is depth-based, the Index Curve will be the curve containing the depth at which the values were taken. If it is a time-based log, the Index Curve will be the curve containing the time of the measurement.

Our example is a depth-based log, and Mdepth (curve/column #1) is the Index Curve, in feet. Therefore, the data points represent values taken every ten feet from 4050 through 4090 feet.

 

12.4.3.1                      Querying for Rows in a Systematically Growing Object

 

Now let us look at the special handling that allows a range of one or more rows to be queried in a systematically growing object.

 

First, the column(s) to be returned are specified by including one or more column identifiers. For the log object, this is the logCurveInfo elements, along with its child element <mnemonic>.

 

Second, at least one data node must be included. For the log object, this is the logData element with its child element <data>. Specifying an empty data node will return all data nodes within the structural range.

 

Third, the rows to be returned is specified by including a structural range. For the log object, this is the elements startIndex and endIndex. If a row count value is specified then the server will limit the resultant interval count to a maximum of that value. For the log object, the row count is represented by the dataRowCount element.

 

► The structural range applies to all the columns specified in the query.

 

If there are no rows with node index values within the specified range of values for start index and end index, an empty object will be returned.

 

 

 

 

 

 

 

 

 

 

 


To query the ROP and the Bit RPM curves in our example log object for data in the range of 4050 thru 4080 one would specify:

 

            <log uidWell="W-12" uidWellbore="B-01" uid="L001">

                        <logHeader>

query template requesting the ROP and Bit RPM curves from 4050 through 4080

 
                                    <startIndex>4050</startIndex>

                                    <endIndex>4080</endIndex> [8]

                                    <logCurveInfo>

                                                <mnemonic>ROP</mnemonic>

                                    </logCurveInfo>

                                    <logCurveInfo>

                                                <mnemonic>Bit RPM</mnemonic>

                                    </logCurveInfo>

                        </logHeader>

                        <logData>                  

                                    <data/>

                        </logData>

</log>

 

If a query specifies values for the start/endIndex elements in the logCurveInfo element, those values will be ignored:

query template specifying extraneous start/endIndex values under logCurveInfo

 
 


            <logHeader>

                        <startIndex>4050</startIndex>

                        <endIndex>4080</endIndex>

                        <logCurveInfo>

                                    <mnemonic>ROP</mnemonic>

            <startIndex>4060</startIndex> [ignored]

                                    <endIndex>4070</endIndex>     [ignored]

                        </logCurveInfo>  

 

The above query will be interpreted as if it had specified:

 

            <logHeader>

                        <startIndex>4050</startIndex>

                        <endIndex>4080</endIndex>

                        <logCurveInfo>

                                    <mnemonic>ROP</mnemonic>

            <startIndex></startIndex>

                                    <endIndex></endIndex>

                        </logCurveInfo>  

 

Therefore, the server will return its persisted start/endIndex values for the ROP curve.

Here is another example query requesting the data for our example ROP and Bit RPM curves for the interval range 4060-4100 (inclusive):

 

            <log>

                        <logHeader>

                                    <dataRowCount>3</ dataRowCount>

                                    <startIndex>4060</startIndex>

                                    <endIndex>4100</endIndex>

                                    <logCurveInfo>

                                                <mnemonic> Mdepth </mnemonic>

                                                <startIndex></startIndex>

                                                <endIndex></endIndex>

                                                <columnIndex></columnIndex>

                                                <nullValue></nullValue>

                                    </logCurveInfo>

                                    <logCurveInfo>

                                                <mnemonic>Bit RPM</mnemonic>

                                                <startIndex></startIndex>

                                                <endIndex></endIndex>

                                                <columnIndex></columnIndex>

                                                <nullValue></nullValue>

                                    </logCurveInfo>

                                    </logCurveInfo>

                                                <mnemonic>ECD</mnemonic>

                                                <startIndex></startIndex>

                                                <endIndex></endIndex>

                                                <columnIndex></columnIndex>

                                                <nullValue></nullValue>

                                    </logCurveInfo>

                        </logHeader>

                        <logData>

                                    <data>

                        </logData>

            </log>

 

Let us now look at what would be returned by this query.

 

Recalling that our stored log object contains:

 

                        Mdepth             Bit

 RPM    ECD

                            ¯                      ¯          ¯     

<data>4050,   37.11,    93.74,         </data>

            <data>4060,     9.85,         95,   1.33</data>

            <data>4070,   32.44,    89.19,   1.31</data>

            <data>4080,   29.03,  -99999,   1.32</data>

            <data>4090,   13.09,  -99999,   1.34</data>

 

And we specified the range 4060 through 4100 for these three curves:

 

            Mdepth RPM  (curve/column #1 in the stored data)

 

            Bit RPM  (curve/column #3 in the stored data)

 

ECD        (curve/column #4 in the stored data)



The returned document will contain:

 

     <log>

            <logHeader>

Left Arrow: A                        <dataRowCount>5</ dataRowCount>

                        <startIndex>4060</startIndex>

                        <endIndex>4080</endIndex> 

                        <logCurveInfo>

                              <mnemonic>Mdepth</mnemonic>

                              <nullValue/>

                              <startIndex>4060</startIndex>

                              <endIndex>4090</endIndex> Left Arrow: B

                              <columnIndex>1</columnIndex>

                        </logCurveInfo>

                        <logCurveInfo>

                              <mnemonic>Bit RPM</mnemonic>

                              <nullValue>-99999</nullValue>

                              <startIndex>4060</startIndex>

Left Arrow: B                              <endIndex>4070</endIndex>

                              <columnIndex>2</columnIndex>

                        </logCurveInfo>

                        <logCurveInfo>

                              <mnemonic>ECD</mnemonic>

                              <nullValue/>

Left Arrow: B                              <startIndex>4060</startIndex>

                              <endIndex>4090</endIndex>

                              <columnIndex>3</columnIndex>

                        </logCurveInfo>

            </logHeader>

<logData>

                        <data>4060,        95,   1.33 </data>

Left Arrow: A                        <data>4070,   89.19,   1.31 </data>

                        <data>4080, -99999,   1.32 </data>

</logData>
      </log>

 

 

(the letters refer to the narrative on the next page)

 


 

 

Here is a discussion that explains why the query returned the results it did…

 

 

 

A - The start/endIndex values returned in the logHeader will encompass the range of values in the returned curves (not necessarily the entire range of values in the persisted log, nor the range of values that was requested in the query). In our example, we requested the range of 4060-4100. However, none of the requested non-index curves contained data greater than interval 4090. Therefore, the values returned in the logHeader were adjusted to reflect the range actually returned in the curves, in order to maintain the internal consistency of the returned log object. Note also that the interval for index 4090 was not returned because a maximum of three intervals was requested.

 

queried for:           <logHeader>

                                    <startIndex>4060</startIndex>

                                     <endIndex>4100</endIndex> 

 

returned:                <logHeader>

                                     <startIndex>4060</startIndex>

                                     <endIndex>4080</endIndex>   [adjusted]

 

 

B - While the Bit RPM curve data was persisted by the server as curve #3, and ECD data as curve #4, these index values are only relative to the other curves stored with the log. They are not absolute, unchanging values. For example, when the Bit RPM and ECD curves’ data values are returned to the client, the curves will have been assigned new index numbers relative to the other curves returned by that particular query. In our example, while the Bit RPM curve data was originally stored as curve #3, it is returned as curve #2. Likewise, the ECD data was stored as curve #4, but is returned as curve #3. The server adjusts the index values (<columnIndex> element in the logCurveInfo headers) of the returned objects to reflect the column index within the returned <data> elements. The client must use the returned columnIndex value in the logCurveInfo from that particular query in order to properly interpret the returned <data> elements.


The logCurveInfo section of the returned log object will also have been adjusted by the server to reflect the actual position of the Index Curve in the returned <data> elements. Although shown as columnIndex 1 in our examples, the Index Curve does not necessarily occupy columnIndex 1 in the stored log or in the returned <data> elements.

 

We could request all curves by using an empty mnemonic. The following query would return the entire contents of the log.

           

<log uidWell="W-12" uidWellbore="B-01" uid="L001">

                        <logHeader>

                                    <dataRowCount></ dataRowCount>

                                    <indexType></indexType>

                                    <startIndex></startIndex>

                                    <endIndex></endIndex>

                                    <indexCurve></indexCurve>

                                    <logCurveInfo>

                                                <mnemonic> </mnemonic>

                                                <startIndex></startIndex>

                                                <endIndex></endIndex>

                                                <columnIndex></columnIndex>

                                    </logCurveInfo>

                        </logHeader>

                        <logData>

                                    <data></data>

                        </logData>

            </log>

 

 


12.4.3.2                      Updating Rows in a Systematically Growing Object

The general behavior for updating recurring elements that do not have a uid attribute is to replace all occurrences with the elements in the query. However, an exception is made when updating systematically growing components (e.g., logData). The behavior for updating rows in a systematically g rowing object is to append the rows when start and end indexes are not specified and to replace the rows when start or end index values are specified.

Thus, the following template:

 

    <log uidWell="W-12" uidWellbore="B-01" uid="L001">

                        <logHeader

Update adding one row in a particular log.

 
                                    <logCurveInfo>

                                                <mnemonic>Mdepth</mnemonic>

                                                <columnIndex>1</columnIndex>

                                    </logCurveInfo>

                                    <logCurveInfo>

                                                <mnemonic>ROP</mnemonic>

                                                <columnIndex>2</columnIndex>

                                    </logCurveInfo>

                                    <logCurveInfo>

                                                <mnemonic>ECD</mnemonic>

                                                <columnIndex>3</columnIndex>

                                    </logCurveInfo>

                        </logHeader>

            <logData>

                        <data>5000,   22.59,   1.36</data>

                        </ logData >

                </log>

 

would result in the following data in the server: Note that mnemonic ‘Bit RPM’ was not specified in the above template which resulted in an empty value being defined in the third column on the server. An empty value is equivalent to a null value.

 

<data>4050,   37.11,    93.74,          </data>

            <data>4060,     9.85,         95,   1.33</data>

            <data>4070,   32.44,    89.19,   1.31</data>

            <data>4080,   29.03,  -99999,   1.32</data>

            <data>4090,   13.09,  -99999,   1.34</data>

            <data>5000,   22.59,             ,   1.36</data>

While, the following template:

 

                <log uidWell="W-12" uidWellbore="B-01" uid="L001">

Update replacing one row in a particular log.

 
                        <logHeader>

                                    <startIndex>4075<startIndex>

                                    <endIndex>4080<endIndex>

                                    <logCurveInfo>

                                                <mnemonic>Mdepth</mnemonic>

                                                <columnIndex>1</columnIndex>

                                    </logCurveInfo>

                                    <logCurveInfo>

                                                <mnemonic>ROP</mnemonic>

                                                <columnIndex>2</columnIndex>

                                    </logCurveInfo>

                                    <logCurveInfo>

                                                <mnemonic>Bit RPM</mnemonic>

                                                <columnIndex>3</columnIndex>

                                    </logCurveInfo>

                                    <logCurveInfo>

                                                <mnemonic>ECD</mnemonic>

                                                <columnIndex>4</columnIndex>

                                    </logCurveInfo>

            <logData>

                        <data>4080,29.03,87.4,1.32</data>

                        </logData >

                </log>

 

will replace the row with an index of 4080 to result in the following data in the server:

 

<data>4050,   37.11,    93.74,          </data>

            <data>4060,     9.85,         95,   1.33</data>

            <data>4070,   32.44,    89.19,   1.31</data>

            <data>4080,   29.03,      87.4,   1.32</data>

            <data>4090,   13.09,  -99999,   1.34</data>

 

 

 

 

 

 

 

 

 


12.4.3.3                      Deleting Rows in a Systematically Growing Object

The general behavior is that only a whole object can be deleted. For a systematically growing object, special handling is allowed. Specifying a start index or an end index in the header will result in the corresponding rows being deleted.

For example, the following template will delete all rows where the indexCurve value is greater than or equal to 4060 and the indexCurve value is less than or equal to 4080.

 

<logs xmlns="http://www.witsml.org/schemas/120">
    <log uidWell="W-12" uidWellbore="B-01" uid="f34a">
        <logHeader>
            <startIndex>4060</startIndex>
            <endIndex>4080</endIndex>
        </logHeader>
    </log>
</logs>
 

And would result in the following being left on the server.

 

<data>4050,   37.11,    93.74,          </data>

<data>4090,   13.09,  -99999,   1.34</data>

 
 
 
The above example could be modified to only delete data for specific mnemonics. Thus,

 

            <logs xmlns="http://www.witsml.org/schemas/120">
                        <log uidWell="W-12" uidWellbore="B-01" uid="f34a">
                                    <logHeader>
                                                <startIndex>4060</startIndex>
                                                <endIndex>4080</endIndex>

                                                <logCurveInfo>

                                                            <mnemonic>ROP</mnemonic>

                                                </logCurveInfo>

                                                <logCurveInfo>

                                                            <mnemonic>Bit RPM</mnemonic>

                                                </logCurveInfo>
                                    </logHeader>
                        </log>
            </logs>

 

Would result in the following being left on the server.

 

            <data>4050,   37.11,    93.74,         </data>

            <data>4060,            ,             ,   1.33</data>

            <data>4070,            ,             ,   1.31</data>

            <data>4080,            ,             ,   1.32</data>

            <data>4090,   13.09,  -99999,   1.34</data>

 

The index curve cannot be deleted unless the whole row is deleted. As shown in the first example, if specific mnemonics had not been specified then the whole row would have been deleted.

 

Specifying only startIndex will delete from (and including) that point to the end of the log. Specifying only endIndex will delete from the beginning of the log to (and including) endIndex. The startIndex and endIndex will be updated after the delete for all affected curves.

 

 

 

 

 

 

 

 

 

 

 



12.4.3.4                      Adding Columns in a Systematically Growing Object

The general behavior for updating an object with data that does not yet exist is to add the data. Updating a systematically growing object with a new column also results in the data being added. That is, there is no special behavior except that the row index must also be specified.

Thus, the following template:

 

    <log uidWell="W-12" uidWellbore="B-01" uid="L001">

            <logHeader>

                        <logCurveInfo>

                                    <mnemonic> Mdepth </mnemonic>

                                    <columnIndex>1</columnIndex>

Update adding one column to a particular log.

 
                        </logCurveInfo>

                        <logCurveInfo>

                                    <mnemonic>HKLD</mnemonic>

                                    <columnIndex>2</columnIndex>

                        </logCurveInfo>

            </logHeader>

<logData>

            <data>4050,187.66</data>

            <data>4060,185.74</data>

            <data>4070,184.23</data>

            <data>4080,185.49</data>

            <data>4090,185.55</data>

            </ logData >

    </log>

 

would result in the following data in the server

 

<data>4050,   37.11,    93.74,          ,187.66</data>

            <data>4060,     9.85,         95,   1.33,185.74</data>

            <data>4070,   32.44,    89.19,   1.31,184.23</data>

            <data>4080,   29.03,  -99999,   1.32,185.49</data>

            <data>4090,   13.09,  -99999,   1.34,185.55</data>

 

 

 

 

 

 

 

 

 

 



12.4.3.5                      Deleting Columns in a Systematically Growing Object

The general behavior is that only a whole object can be deleted. For a systematically growing object, special handling is allowed. Specifying a column identifier in the header will result in the corresponding column being deleted.

Thus, the following template:

 

    <log uidWell="W-12" uidWellbore="B-01" uid="L001">

                        <logHeader>

                                    <logCurveInfo>

                                                <mnemonic> ECD </mnemonic>

                                    </logCurveInfo>

                        </logHeader>

    </log>

 

would result in the following data in the server:

 

<data>4050,   37.11,    93.74</data>

            <data>4060,     9.85,         95</data>

            <data>4070,   32.44,    89.19</data>

            <data>4080,   29.03,  -99999</data>

            <data>4090,   13.09,  -99999</data>

 

 

 

 

 

 

 

 

 

 



12.5     PUBLISH Interface Example

Just as the STORE interface has special handling of Query Templates for the growing objects, the PUBLISH interface also has special handling of Subscription Templates for these objects.

 

That is, a Subscription Template can - like a Query Template - specify a range of values that determine which occurrences of a recurring structure are to be returned. A Subscription Template for the log object, for example, can specify a begin and end depth and only the log data points falling within that range will be published.

 

Both Query and Subscription Templates specify the type of object to be returned (well, wellbore,  etc), the data items to be returned (elements and attributes), which objects are to be returned (by specifying a value of one or more data items) and  -  for those objects having special handling -  the range of recurring structure occurrences to be returned.

 

For the STORE interface, that is the extent of the "selection" process; the Query Template fully specifies the object types, instances and contents to be returned.

 

And, for most data objects, the Subscription Template also fully specifies the object types and contents to be sent to a Subscriber by the Publisher.

 

► However, for the growing objects, the PUBLISH interface also performs additional "eligibility" processing prior to applying the Subscription Template.

 

As described in the section on Publishing, a Publisher considers an object to be "eligible" to be sent to a Subscriber only when that object has changed (or been newly-added).

 

But some objects "grow" over time as additional occurrences of their recurring structures are added (as additional trajectoryStations are added to a trajectory object, for instance), and thus the Publisher might publish the entire object each time a new recurring structure was inserted!

 

To prevent this needless retransmission of data, the Publisher always considers the non-recurring ("header") data items of the log, mudLog and trajectory objects to be eligible for publication, but only considers those instances of the recurring structure that are new or have been changed to be eligible for publication.

 


 

Here's a summary of the parts of growing objects that are eligible to be published, based on the type of change:

                        

Type of Change                                 Eligible for Publication                                

 

new object                                           all non-recurring data

    and

all instances of recurring structure  

 

update of non-recurring data              all non-recurring data                          

 

add of new recurring data                  all non-recurring data

    and

new instance(s) of recurring structure

 

update of existing recurring data        all non-recurring data

                                                               and

updated instance(s) of recurring structure

 

Once the Publisher has determined which part of these objects are eligible for publication, it then applies the Subscription Template to determine whether the Subscriber has requested this particular object (and which portions of the object).

 

 

 

 

 

 

 

 

 

 

 

 

 

 


►  The Subscription Template is applied to the parts of the object that are eligible to be published in the same way as a Query Template - including special handling.


13      APPENDIX E - Service Agreement

Whenever a WITSML service is setup between a WITSML service provider (provider) and a WITSML service consumer (consumer) there are several aspects of the service that needs to be further specified and agreed upon.

 

The WITSML standard only contains specifications about the data transport media, format, protocol, data objects and their elements, and so the issues below are not part of the standard itself.

 

In order for a WITSML service to be successfully setup, the provider and consumer also needs to agree on these subjects:

 

-          What WITSML interfaces should the provider supply?

-          What WITSML API version is the server supporting?

-          What version of the provider’s WITSML server should be provided?

-          What character sets and encodings is the WITSML server able to handle in the incoming WITSML requests (XML documents), and what kind of characters sets and encodings will the server use in it’s answers to the WITSML clients?

-          What data objects and data elements should the provider supply (not all WITSML data elements are mandatory)?

-          How should the mapping between provider and consumer names on curves etc be done?

-          What default unit of measures should be used for the various data elements?

-          What unit of measure conversions should be available for the various data elements?

-          Security

o   Should authentication be used?

o   What protocol should be used, HTTP or HTTPS?

o   Over what network should the service be run: Internet, VPN, or some other closed network?

o   If firewalls need to be opened for the service to run the IP addresses and ports of the participating machines as well as the direction of connection initiation between them should be specified.

-          For how long should the service run?

-          Quality of service

o   For what period is the service available? 24/7?

o   Is the service supported in that same period?

o   E-mail and phone number of the provider support personnel or contact person.

o   Is the service kept under surveillance? At what times?

-          What is the IP address and URL to the WITSML server?


14      APPENDIX F - Custom Data

All the WITSML data objects include a container element named <customData> which can be used to extend the WITSML data object definitions. While this is a useful feature, it can lead to the very interoperability problems that WITSML was intended to prevent.

For the special case of <customData>, all sub-nodes will be returned if only the customData element is specified. Querying sub-nodes of customData is server dependent.

The following recommendations are made in order to minimize problems across different implementations of custom data.

14.1     Namespace

Custom data definitions should use a namespace URI different from the one used by WITSML (http://www.witsml.org/schemas/nnn).

 

Here is a WITSML well object that uses the xmlns attribute to declare a custom namespace prefix of "cns" associated with the URI http://www.my.org/schemas/100.

 

The object includes two custom data elements (cd1 and cd2) defined in that custom data namespace.

 

<?xml version="1.0" encoding="UTF-8"?>

<wells xmlns="http://www.witsml.org/schemas/131ex"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns:cns="http://www.my.org/schemas/100">    ç custom ns declaration

            <well uid="W-1">

                        … WITSML-defined elements and attributes …

                        <customData>

                                    <cns:cd1>value of cd1</cns:cd1>

                                    <cns:cd2>value of cd2</cns:cd2>

                        </customData>

            </well>

</wells>

 

Note that in this example the WITSML-defined elements and attributes do not require a namespace prefix, since they use the default namespace declaration.

 



[1] for example, the Subscriber will convey in its capabilities object the version of the API that it implements. This will allow new versions of the API  to be implemented without disrupting existing systems.

[2] because HTTP/S is used to transport the published data, this use case shows the Subscriber process running under a generic HTTP/S Server (aka, “web server”). A Subscriber is free to implement its own dedicated, embedded HTTP/S processing if it wishes.

[3] XML is not sensitive to “white space” characters such as line feeds, so reformatting it this way doesn’t affect its meaning.

[4] but this can be accomplished in two steps – see the next page.

[5] the Subscription object cannot specify the Subscription or Capabilities object types, however. Those object types cannot be published.

 

[6] for a more rigorous definition of HTTP syntax, see http://www.w3.org/Protocols/rfc2616/rfc2616.html

[7] additional spaces have been inserted into the example <data> elements to make the example more easily readable. Spaces would not be present between numeric values in actual <data> elements.

 

[8] Since the Bit RPM curve in the example contains data only up to interval 4070, this query will result in null values being returned for the Bit RPM curve in the intervals above 4070.