Chapter 2 Programming Issues and Considerations

2.1 General Programming Considerations

There are a number of considerations that programmers should take into account when developing against the Web Services API. This section provides a breakdown of common obstacles that users of the API encounter, and how they should be handled.

2.1.1 Object Modification

When you read an object into your client application, the object should be considered as a copy of the object actually contained within Oracle VM Manager. Changes to the client side representation of an object don't affect anything until you call an object modify method and pass it the updated copy of the object that you have modified locally within your client application. If you populate a local object with the data returned from a get object method, the local object is only a copy of the actual object. If you make changes to the local object, the server-side object remains unchanged. It is only when you call an object modify method that the object on the server-side is actually affected.

Since Oracle VM Manager can be accessed by multiple users or clients at any moment in time, it is always possible that two users are attempting to modify an object at the same time. The API handles race conditions, but if the object that you are modifying has already been modified by another operation and your object is out of date the API will generate an exception. Therefore, when performing an object modification, you should always ensure that your object is up to date before you call an object modify method.

This behavior prevents random changes being made that you didn't intend. For example, if you have an object that you change the description for, but the content of your object is old, someone else may have made all kinds of changes to that object. If an exception wasn't thrown, the object would revert to the previous state for all of those other attributes even though that wasn't the callers intention.

Object IDs can't be modified, even if there are methods that seem like they might achieve this for you. See Section 2.1.3, “Read-only Methods and Object Properties” for more information on why these methods exist. Object IDs are generated within Oracle VM Manager and are used to maintain consistency across object relationships and must remain unique. Therefore, it is not possible for a client application to directly modify an object ID.

2.1.2 Object Associations

Associations aren't modified by calling setters on the object and then calling modify. Associations are changed with explicit API calls. Examples include, serverPoolAddServer, networkAddEthernetPort, etc.

Associations are changed in one direction only - typically from the "parent". Using the above cases, you add servers to a server pool, you don't set the serverPoolId on a server, even though it appears as a property of the server object. See Section 2.1.3, “Read-only Methods and Object Properties” for more information on these properties and why they exist for any object.

As mentioned previously in Section 2.1.1, “Object Modification”, the IDs of objects that have an association with a "parent" object cannot be modified even if there are methods that seem like they might achieve this for you. These associated object IDs that appear as properties of a "parent" object are not modifiable directly and are automatically associated when an association method is called from the API.

2.1.3 Read-only Methods and Object Properties

There are methods documented as "read-only" on the model objects. For example, if you look at the API documentation for Server.setServerPoolId, it explicitly states that the serverPoolId is read only. If you attempt to call these methods or modify these properties for an object, the value that you attempt to set is simply ignored by the API when the modify call is submitted to the API. No exception is thrown if you call one of these methods, or even if you attempt to modify the value of such a property using an object modify API call. This means that while you can call read-only setter methods on the client side and the values on the client side object may reflect the change, the changes are ignored when the object is submitted to Oracle VM Manager and subsequent retrievals of the object do not reflect the changes.

The reason that these methods exist is to allow particular web services frameworks (such as the Jackson and Jersey libraries) to de-serialize these objects. Therefore, these methods and properties need to be available on the client side, but they do not affect the manager's representation of the object.

2.1.4 Working with Jobs

Jobs can have child jobs. For an operation to have fully completed, the child jobs must be complete as well. However, there are certain operations in which the child jobs can take a very long time to complete or which never complete. This can happen when a child job is spawned to deal with each server. However, if the server is offline, that child job remains active until the server comes back online.

Jobs have properties indicating firstly whether the parent job has completed, and secondly whether all child jobs spawned by the parent job have also completed. The done property relates to the parent job, while the summaryDone property relates to the parent job as well as all spawned child jobs. In some cases, the parent job may appear to be complete if you check the done property, but the summaryDone property indicates that some child jobs are still running. Therefore, it is usually better practice to check the value of the summaryDone property when waiting for job completion.

To see the updates to an object after a job completes (including a modify), you must refresh the client's view of the object.

2.1.5 Dealing with Exceptions

Oracle VM Manager is a multi-layered application. As such, checks on the legitimacy of operations are performed at various levels within the Oracle VM Manager Core. Some errors may be caught within the Web Services layer itself, while others may only be triggered by the Core rule evaluations. This should not make any difference within your application itself. An exception should be treated as such, regardless of where it originates from.

For instance, the following exception returned as a Job error for a web services request, is as much of an exception as a rule exception returned by Core:

ovm.mgr.ws.model.WsException: NETWORK_000008: Cannot perform operation Modify Role
List on a Server local Network: Modify Role List

Equally, a rule exception from within the core, is as important as an error generated at the Web Services layer:

com.oracle.ovm.mgr.api.exception.RuleException: OVMRU_002043E Cannot release
ownership of Repository: MyRepo. Virtual Disks/CDroms:
[0004fb0000120000eb8cd3defdc71ba5.img on 0004fb0000060000e3ea97cd6b8d45bd,
0004fb0000120000f2ba448c46f4fc12.img on 0004fb0000060000e3ea97cd6b8d45bd],
are still assigned to VMs/Templates that have configuration files in another
repository.

It is also worth noting that exceptions that are returned from the API may vary in terms of the error message or exception code that is returned depending on whether you are using the SOAP API or the REST API. If you are coding an application that can use either API, you need to ensure that your code is consistent in handling these exceptions regardless of the API used.

2.1.6 XML Tags in Object Names and Descriptions

There are no restrictions on the content that can be used in an object name or description within Oracle VM Manager, however if XML tags are present in a name or description field for any object within Oracle VM Manager and your WS-API client is using the REST API with an XML media type, errors are likely to occur.

In general, you should avoid inserting XML into the name and description fields within Oracle VM Manager. However, if this problem already exists, you may see an error similar to the following:

javax.xml.stream.XMLStreamException: ParseError at [row,col]:[1,432983]
Message: The character sequence "]]>" must not appear in content unless used
to mark the end of a CDATA section.]

Either remove any XML tags from the names and descriptions of all objects within Oracle VM Manager, or use the REST API with a JSON media type.

The default behavior defined in the SDK Java client is to use JSON as the media type when using the RestClient. Furthermore the default settings in the sample WsDevClient.properties file has been set to REST with JSON.

2.2 Notable Issues for Suds Users

This section describes issues that Python users may have if using the Suds SOAP library. Note that the SOAP API is deprecated in Oracle VM Manager 3.4 and if you are using the Suds library, you should consider changing your code to use the REST API in the future.

2.2.1 Dealing with an Externally Hosted XSD

The SOAP API references an externally hosted XSD:

<xs:import namespace="http://www.w3.org/2005/08/addressing"
schemaLocation="http://www.w3.org/2006/03/addressing/ws-addr.xsd"/>

In environments where your client application is unable to directly access the Internet, this could pose a problem for the Suds library. In this case, you should host a localized copy of this XSD and bind the new schema location for the namespace, as described at https://fedorahosted.org/suds/wiki/Documentation#BindingSchemaLocationsURLtoNamespaces. An example function follows to show how to bind the namespace to an XSD hosted locally in a temporary directory:

from suds.xsd.sxbasic import Import

def bind_schema_locations():
    Import.bind(
        'http://www.w3.org/2005/08/addressing',
        'file:///tmp/xsd/www.w3.org/2006/03/addressing/ws-addr.xsd')

2.2.2 Null Properties and Empty Lists

When an instance has a null property or an empty list, the instance in Suds removes the property. For example, when instance has no name:

instance.name = None

the Suds instance removes the name property. Therefore, in order to check the name property, you must first check that the instance actually contains the property:

if 'name' in instance and instance.name == 'foo':
      # do something

Equally, empty lists result in a similar behavior, where Suds removes the property. In order to iterate on a property that contains a list, you must first check that the property exists:

if 'ethernetPortIds' in server:
      for ethernet_port_id in server.ethernetPortIds:
      # do something

Attempting to iterate through a property containing an empty list results in an exception, as the property is removed from the instance. As a result, it is not a good idea to simply attempt to iterate on a property expecting it to be available:

for ethernet_port_id in server.ethernetPortIds:
      # do something

In the example above, if the ethernetPortIds property is an empty list, Suds does not attach it as a property of the server instance. The result is an exception similar to the following:

AttributeError: server instance has no attribute ‘ethernetPortIds’ exception.

2.2.3 Unable to Access the OvmWsUtilities Endpoint

While it is possible to load the WSDL for the OvmWsUtilities endpoint in Suds, it is not possible to authenticate for this endpoint. This is because authentication is handled using the login method exposed by the OvmWsApi endpoint.

Technically, access to the Utilities endpoint is designed to be achieved by calling the getOvmWsUtilitiesEndpoint method from the OvmWsApi endpoint, however this method returns an Endpoint Reference which the client is meant to follow. The Suds library does not appear to easily cater for this functionality.

Therefore, in the case that you decide to use the methods exposed by the OvmWsUtilities endpoint, it is recommended that you resort to using the REST interface to the API.

2.3 Notable Issues for Jackson and Jersey Library Users

2.3.1 Null Properties and Empty Lists

When empty lists are serialized or deserialized through web services, they can be converted into nulls by the Jackson and Jersey libraries. Therefore, your code must be able to handle getting back a null property instead of an empty list. Also, an empty list passed into the web services api can be converted into a null. Therefore, the api treats them as equivalent.

Examples illustrating checks for null properties are included in the WsDevClient class in the sample client provided with the SDK.