Saturday, February 18, 2012

NetApp SDK for Java Basics

I've been working with the NetApp Manageability SDK for a while now and I think I have the basics down. While there are samples in the SDK, I thought I make some notes here in case someone else is looking or I just plain forget. First, there are only a handful of objects to deal with. I actually find this a bit annoying as I'm constantly looking to the API documentation to find out how to create a meaningful query which then requires me to type error prone (for me) strings rather than static variables or methods. For the most part this is pretty easy but can get rough in a couple of spots.

As an example lets create a snapshot. The API documentation is located in the download pack under doc/ontap/ontapapi_1.15/7-Mode/snapshot/index.html and looks like this:

snapshot-create
Input Name Range Type Description
async boolean
optional
If true, the snapshot is to be created asynchronously. The default value is false.
is-valid-lun-clone-snapshot boolean
optional
If true, the snapshot create has been requested by snapvault hence all backing snapshots for all the lun clones in this snapshot will be locked. This ensures the consistency of this snapshot. The default value is false.
snapshot string
nonempty
Name of the snapshot to be created. The maximum string length is 256 characters.
volume string
Name of the volume on which the snapshot is to be created. The volume name can contain letters, numbers, and the underscore character (_), but the first character must be a letter or an underscore.
I need two objects to get the job done, an NaServer to talk to the array, and an NaElement to do the work as an XML document. According to the documentation, the NaElement I need to create is called "snapshot-create" and has two mandatory fields, "snapshot" and "volume". Since both of these are strings and the options are boolean, it looks something like this.
String arrayName = "netapp1.domain.com";
String userName = "administrator";
String password = "password";
String volumeName = "volume";
String snapName = "snapname.0";
NaServer netappServer = null;
NaElement request, response;
try {
   netappServer = new NaServer(arrayName);
   netappServer.setTransportType(NaServer.TRANSPORT_TYPE_HTTPS);
   netappServer.setPort(443);
   netappServer.setStyle(NaServer.STYLE_LOGIN_PASSWORD);
   netappServer.setAdminUser(userName, password);
} catch (UnknownHostException e) {
   e.printStackTrace();
}
request = new NaElement("snapshot-create");
request.addNewChild("volume", volumeName);
request.addNewChild("snapshot", snapName);
try {
   response = netappServer.invokeElem(request);
} catch (Exception e) {
   e.printStackTrace();
}
The request portion is the interesting part. It's telling the array I want to create a snapshot for volume /vol/volume called snapname.0. I'm not using any of the options but if you do, remember that everything is added as a string. I really want to add request.addNewChild("async", true); but that won't work. You'll have to use true as a string value and end up with request.addNewChild("async", "true");

There are of course a number of things that can go wrong. Errors caused by your request will generally throw an NaAPIFailedException. You can grab the error number with e.getErrno() and then compare it against static references in the NaErrno class. Something like this
try {
    response = netappServer.invokeElem(request);
} catch (NaAPIFailedException e) {
switch (e.getErrno()) {
    case NaErrno.ESNAPSHOTEXISTS:
        System.out.println("snap already exists");
}

4 comments:

  1. Hi,

    Im trying to do a similar thing myself, but could you post what imports you have in your code, if i can get this example working im halfway there. Thanks!

    ReplyDelete
  2. I suspect this has to do with your project setup rather than just the imports. I've included these for my application:
    nmsdk-runtime-5.0.jar
    ontap-api-8.1.jar
    commons-codec-1.5.jar (netapp comes with 1.4)
    manageontap-4.1.jar

    You should know, I'm still using 5.0R1 rather than 5.1 so your version will probably be different. You'll need to download both the netapp manageability sdk "all platforms" and the "java API bindings" in order to get everything.

    Once that's done, Eclipse should automatically import the required classes but for reference, here are mine:

    import netapp.manage.NaAPIFailedException;
    import netapp.manage.NaAuthenticationException;
    import netapp.manage.NaElement;
    import netapp.manage.NaErrno;
    import netapp.manage.NaProtocolException;
    import netapp.manage.NaServer;

    ReplyDelete
  3. Hi ,

    Just curious where to download the jars needed? I'm searching from NetApp web site but could not find them.

    Thanks.

    ReplyDelete
  4. The latest SDK is part of netapp's support site (support.netapp.com). Under downloads > software and then under "NetApp Manageability SDK". I'm not sure how long term this information is, but for now it should be there. Here's a link. If the SDK doesn't show up on your list I'm guessing you'll need to email NetApp to get a copy.

    ReplyDelete