Sample code to create and start a FlashCopy mapping

This information demonstrates how CIMOM methods control the clustered system. The sample code includes a main method from a Java class, designed to create and start a FlashCopy mapping, and other methods called from the main method.

In this topic, the term method refers to a Java method. The term Method (initial capital) refers to a CIM Method.

Java main method

This example shows the Java main method for creating and starting a FlashCopy mapping. The assumption in this example is that the Java program is designed to control the same clustered system every time. It is a relatively simple process to make it more flexible, but that decision is left to the user.

/*
* FC Mapping states
*/
private static UnsignedInt16 INITIALIZED = new UnsignedInt16(2);
private static UnsignedInt16 PREPARING = new UnsignedInt16(3);
private static UnsignedInt16 PREPARED = new UnsignedInt16(4);

public static void main(String[] args) throws CIMException
{
   /*
    * First step is to connect to the CIMOM
   */
   UserPrincipal user = new UserPrincipal("superuser");
   PasswordCredential pwd = new PasswordCredential("itso13sj");
   CIMNameSpace ns = new CIMNameSpace("https://9.43.86.115:5989/root/ibm");

   CIMClient client = null;

   client = new CIMClient(ns,user,pwd);

   /*
    * Next, select the clustered system that we are interested in
   */
   CIMInstance chosenCluster = getCluster("ITSOCL1",client);

   /*
    * At this point, the relevant clustered system has been selected
    * and 'chosenCluster' is a CIMInstance of this clustered system
    *
    * Get the Config Service of this clustered system
    */
   CIMObjectPath cService = getConfigService(chosenCluster, client);

   /*
    * Now, get all of the Volumes in this clustered system
    */
   Map<Integer,CIMObjectPath> volumesById = getVolumes(chosenCluster,client);

   /*
    * Select the FlashCopy Source
    *
    * In this case, Volume 10 is our source
    * Volume 11 is our target
    */
   CIMObjectPath fcSrc = volumesById.get(new Integer(10));
   CIMObjectPath fcTgt = volumesById.get(new Integer(11));/*

   /*
    * Now create FC Mapping
    */
   CIMValue rc = makeFlashCopyMapping("CIMOMTestMap", fcSrc, fcTgt, cService,
      client,false);

   /*
    * Now that this has been created, we need to get an
    * Object Path to the newly created Association
    */
   List<CIMObjectPath> fcMaps = getFCMappings(fcSrc, client);
   CIMObjectPath fcMapping = fcMaps.get(0);

   /*
    * Now we prepare the FC Mapping
    */
   CIMArgument[] outArgs = new CIMArgument[2];
   rc = prepareFCMapping(cService, fcMapping, client, outArgs);
   System.out.println("Got value:"+
      Integer.toHexString(Integer.parseInt(rc.toString())));

   /*
    * Loop until it is prepared
    */
   CIMValue fcMapState = new CIMValue(PREPARING);
   while(fcMapState.equals(new CIMValue(PREPARING)))
   {
      CIMInstance fcMapInfo = client.getInstance(fcMapping);
      fcMapState = fcMapInfo.getProperty("SyncState").getValue();
   }

   /*
    * Now start the FC Mapping
    */
   rc = startFCMapping(cService, fcMapping, client, outArgs);
   System.out.println("Got value:"+
      Integer.toHexString(Integer.parseInt(rc.toString())));
}

getCluster method

The getCluster method returns the CIM instance corresponding to the clustered system with the supplied name. It does this by enumerating all of the instances of the class IBMTSSVC_Cluster and then checking the name of each instance. When an instance is found that matches the supplied name, an object path to that instance is returned.

static private CIMInstance getCluster(String clusterName, CIMClient client) throws
CIMException
{
   CIMInstance chosenCluster = null;
   Enumeration<CIMInstance> clusters =
      client.enumerateInstances(new CIMObjectPath("/root/ibm:IBMTSSVC_Cluster"));

   while(clusters.hasMoreElements())
   {
      CIMInstance possibleCluster = clusters.nextElement();
      String possibleName =
         possibleCluster.getProperty("ElementName").getValue().toString();

      if(possibleName.equals("\""+clusterName+"\""))
      {
         chosenCluster = possibleCluster;
      }
   }
   return chosenCluster;
}

getConfigService method

The CIM_StorageConfigurationService class has no direct equivalent in a SAN Volume Controller, but an instance of this class is required for invoking methods against the system.

In this method, all of the instances associated with the supplied clustered system are requested. The association connecting a clustered system to its configuration service is CIM_HostedService. Because a clustered systemhas only the configuration service associated with it, the first object path in the enumeration is selected.

static private CIMObjectPath getConfigService(CIMInstance cluster, CIMClient
client) throws CIMException
{
   Enumeration<CIMObjectPath> configServices = null;
   configServices = client.associatorNames(
         cluster.getObjectPath(),
         "CIM_HostedService",
         "CIM_StorageConfigurationService",
         null,
         null);
   return configServices.nextElement();
}

getVolumes method

This method returns a map relating Volume IDs (as integers) to IBMTSSVC_StorageVolume object paths. The method requests all of the IBMTSSVC_StorageVolume instances associated with the provided clustered system instance.

static private Map<Integer,CIMObjectPath> getVolumes(CIMInstance cluster, CIMClient
client) throws CIMException
{
   Enumeration<CIMObjectPath> volumes = client.associatorNames(
         cluster.getObjectPath(),
         null,
         "IBMTSSVC_StorageVolume",
         null,
         null);

   Map<Integer,CIMObjectPath> volumesById = new HashMap<Integer, CIMObjectPath>();

   while(volumes.hasMoreElements())
   {
      CIMObjectPath volumeOP = volumes.nextElement();
      CIMValue volumesId = volumeOP.getKey("DeviceID").getValue();
      String idAsString = volumeId.toString();
      String idNoQuotes = idAsString.substring(1, idAsString.length()-1);
      volumesById.put(Integer.parseInt(idNoQuotes), volumeOP);
   }
   return volumesById;
}

makeFlashCopyMapping method

This example invokes the AttachReplica against the clustered system configuration service. CIM Methods take typed parameters; this method makes use of the argRef, argString, and argUint16 methods. These methods act as shortcuts to generating the required arguments for the CIM Method. The AttachReplica method is used for FlashCopy, Metro Mirror and Global Mirror. The CopyType argument indicates which type is required.

static private CIMValue makeFlashCopyMapping(
           String name,
           CIMObjectPath source,
           CIMObjectPath target,
           CIMObjectPath configService,
           CIMClient client,
           boolean autodelete) throws CIMException
{
   CIMArgument src = argRef("SourceElement", source, "IBMTSSVC_StorageVolume");
   CIMArgument tgt = argRef("TargetElement", target, "IBMTSSVC_StorageVolume");
   CIMArgument fcName = argString("ElementName",name);
   CIMArgument type = argUint16("CopyType",autodelete?5:4);
   CIMArgument[] inArgs = {src,tgt,fcName,type};
   CIMArgument[] outArgs = new CIMArgument[1];

   CIMValue rc = client.invokeMethod(configService,
      "AttachReplica",
      inArgs,
      outArgs);
   return rc;
}

getFCMappings method

The getFCMappings method returns a list of all the FCMappings associated with the provided volume. This method requests a list of all of the associations that reference the provided IBMTSSVC_StorageVolume. Currently, all of the Java WBEM Services methods of this type return enumerations; this method converts this to a list for ease of use.

static private List<CIMObjectPath> getFCMappings(CIMObjectPath volume, CIMClient
client) throws CIMException
{
   Enumeration<CIMObjectPath> assocs = client.referenceNames(
              volume,
              "IBMTSSVC_LocalStorageSynchronized",
              null);
   return Collections.list(assocs);
}

prepareFCMapping method

The prepareFCMapping method prepares a FlashCopy mapping. Much like the AttachReplica Method, the ModifySynchronization Method controls FlashCopy, Metro Mirror and Global Mirror. The operation parameter indicates what is actually to be done.

private static CIMValue prepareFCMapping(
           CIMObjectPath configService,
           CIMObjectPath fcMapping,
           CIMClient client,
           CIMArgument[] outArgs) throws CIMException
{
   CIMArgument operation = argUint16("Operation", 6);
   CIMArgument synch = argRef("Synchronization",
fcMapping,"IBMTSSVC_FlashCopyStorageSynchronized");

   CIMArgument[] inArgs = new CIMArgument[]{operation,synch};
   outArgs = new CIMArgument[2];

   return client.invokeMethod(configService,
         "ModifySynchronization",
         inArgs,
         outArgs);

startFCMapping method

The startFCMapping method starts a FlashCopy mapping. This method invokes the ModifySynchronization Method as in prepareFCMapping method but uses a different operation parameter.

private static CIMValue startFCMapping(
      CIMObjectPath configService,
      CIMObjectPath fcMapping,
      CIMClient client,
      CIMArgument[] outArgs) throws CIMException
{
   CIMArgument operation = argUint16("Operation", 4);
   CIMArgument synch = argRef("Synchronization",
fcMapping,"IBMTSSVC_FlashCopyStorageSynchronized");

   CIMArgument[] inArgs = new CIMArgument[]{operation,synch};
   outArgs = new CIMArgument[2];
   
   return client.invokeMethod(configService,
         "ModifySynchronization",
         inArgs,
         outArgs);
}

Argument generators class

This class uses the following argument generators: