# Best practices

## Always close iterators

Enumeration and association traversal operations return a CloseableIterator. Make sure that this iterator always gets closed. In current implementations the iterator is closed automatically when you iterate beyond the last element. However there's no guarantee whatsoever that this behavior is kept for future releases. Moreover you have to ensure that the iterator is closed when you stop iterating before the end is reached either normally or caused by an exception.

If you fail to close the iterator the client will leak a network socket.

      final CloseableIterator<CIMObjectPath> iterator = client.enumerateInstanceNames(new CIMObjectPath(
        "CIM_RegisteredProfile", "root/cimv2"));
      try {
        while (iterator.hasNext()) {
          final CIMObjectPath path = iterator.next();
          System.out.println(path.toString());
        }
      } finally {
        iterator.close();
      }

## Sharing vs pooling of WBEMClients

The WBEMClient class is designed for thread-safety. It contains an HTTP client pool that allows the reuse of network connections used for previous operations. You are able to set configuration properties that apply to the current thread only.

Bottom line: we did a lot of work to ensure that sharing a WBEMClient between threads is safe and convenient to use. Therefore create just one WBEMClient per CIMOM and share it. There isn't a compelling reason for having a pool of multiple clients per CIMOM - this is a pattern used with other client libraries that had not been thread-safe.

## Choose the right parser

The SBLIM CIM Client for Java offers three different XML parsers: DOM, SAX and PULL. All three produce identical results out of a CIM-XML response. What is different is the way they are producing these results.

- The DOM parser produces a DOM structure out of the CIM-XML. This is quite convenient to debug, but consumes by far the most memory and is also the slowest approach.

- The SAX parser creates Java CIM objects (javax.cim.*) directly without building a DOM structure first. That saves memory and is much faster. The SAX parser is also the default parser.

- The PULL parser is based on the SAX code. But instead of parsing the whole CIM-XML response in one step, it just parses as much XML as needed to create the next Java CIM object. With every call to Iterator.next() by the application another chunk of the response is parsed.

  The SBLIM CIM Client for Java throttles the HTTP stream so that the CIMOM does not send us parts of the response we do not need yet. This throttling has caused problems with a view CIMOMs in the past and because of this the client does not use the PULL parser as default. However the PULL parser has the least memory consumption and what's more important the memory footprint is independent of the size of the response. It is overall a bit slower than the SAX parser, but returns the first object much faster.

  NOTE:Because pulled enumeration operations include required information at the very end of the CIMOM's CIM-XML response, the whole CIM-XML response in parsed in one step even if the PULL parser is in effect.

Bottom line: when you are dealing with large numbers of objects and your CIMOM works with the PULL parser ... choose the PULL parser. For all other cases SAX is the first choice. DOM shouldn't be used in a production environment.

## Restrain tracing for problem determination

The SBLIM CIM Client for Java can produce a lot of trace data. That's nice during your application development or when you have to analyze a problem at a customer site. It's wasting performance and capacity if tracing runs in a healthy production system.

Traces are much bigger than logs. This data has to be written, and that comes at a cost of performance. The trace code analyzes the stack trace on every message that is written. That eats up performance too.

Bottom line: tracing is convenient for problem determination, but nothing suitable for a healthy production environment. So do not ship your product with tracing configured by default.

## Have a look at the configuration options

The SBLIM CIM Client for Java has a good number of configuration options. Probably you can live with the chosen defaults most of the time. But have a look first. There are some options you cannot find a good default for, e.g. the HTTP timeout - zero is the default, which means that the client will never timeout while waiting on a CIMOM response. That might not be what you want.

## OpenPegasus local authentication

The SBLIM CIM Client for Java supports the local authentication mechanism of OpenPegasus. In order to use it you have to set a configuration property:

    ...
    final Subject subject = new Subject();
    subject.getPrincipals().add(new UserPrincipal("root"));
    WBEMClientSBLIM client = (WBEMClientSBLIM) WBEMClientFactory.getClient(WBEMClientConstants.PROTOCOL_CIMXML);
    client.setProperty(WBEMConfigurationProperties.HTTP_AUTHENTICATION_MODULE, PegasusLocalAuthInfo.class.getName());
    client.initialize(path, subject, new Locale[] { Locale.US });
    ...

With this property you specify the authentication module to be used. The client ships two modules:

- `org.sblim.cimclient.internal.http.WwwAuthInfo`: Usual basic and digest HTTP authentication. User & password or certificate required.
- `org.sblim.cimclient.internal.http.PegasusLocalAuthInfo`: OpenPegasus local authentication. Only username required.

You might also create your own module by subclassing `org.sblim.cimclient.internal.http.AuthInfo`. Keep in mind this is "internal" API, so it might be subject to change.

## Object Paths

An object path has the general form of `[scheme:host:port//]namespace:[classname[.key=value]*]`. The client distinguishes three types of object paths:

- Namespace paths which do not contain classname or keys.
- Class paths which do not contain keys.
- Instance paths which contain all elements.

So far, so good. The `scheme:host:port` part is optional, so you may not rely on it. Therefore the SBLIM CIM Client for Java ignores the host information when calling `CIMObjectPath.equals()`.

Unfortunately the CIM-XML protocol specification defines quite strange behavior regarding object paths, e.g. an instance retrieved via EnumerateInstances contains one, but when retrieved via GetInstance contains none at all. The SBLIM CIM Client for Java hides this as best as possible from the application. Therefore you can expect a full object path any time, but the host information is still optional. See the table below:

| SBLIM CIM Client for Java | CIM-XML
--- | --- | ---
Operation | host | namespace | classname/keys | host | namespace | classname/keys
EnumerateClassNames | no | yes | yes | no | no | yes
EnumerateClasses | no | yes | yes | no | no | yes
GetClass | no | yes | yes | no | no | yes
EnumerateInstanceNames | no | yes | yes | no | no | yes
EnumerateInstances | no | yes | yes | no | no | yes
GetInstance | no | yes | yes | no | no | no
AssociatorNames | maybe | yes | yes | maybe | maybe | yes
Associators | yes | yes | yes | yes | yes | yes
ReferenceNames | maybe | yes | yes | maybe | maybe | yes
References | yes | yes | yes | yes | yes | yes