Automic Workload Automation

 View Only
  • 1.  How to use ITransportable to add a list of objects to the transport case

    Posted Mar 17, 2023 01:58 PM
    Edited by Michael A. Lowry Mar 31, 2025 03:57 AM

    Can anyone provide an example of how to use the ITransportable interface to add a list of objects to the transport case?

    Update 1, 2023.03.27 11:20 CET: I found out how to add objects from a folder or search to the transport case.

    Update 2, 2025.03.27 15:42 CET: I developed a solution for adding a user-provided list of objects to the transport case.



  • 2.  RE: How to use ITransportable to add a list of objects to the transport case

    Posted Mar 20, 2023 08:03 AM

    Not sure if this is what you are looking for as I am not a Java developer but we had someone write a program to place objects into the transport case. 

    	private void doTransport() {
    		if (deploymentList != null && !deploymentList.isEmpty()) {
    			try {
    				if (con == null) {
    					createConnection(client.getText(), user.getText(), pass.getText(), dept.getText());
    				}
    			} catch (IOException e) {
    				return;
    			}
    			try {
    				con.sendRequestAndWait(new ClearTransportCase());
    				con.sendRequestAndWait(new TransportObject(deploymentList.iterator()));
    				print("Transport complete");
    			} catch (Exception e) {
    				error(e.getMessage());
    				throw new RuntimeException(e);
    			} finally {
    				setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
    			}
    		} else {
    			print("Nothing to transport");
    		}
    	}
    	private void doMove() {
    		try {
    			if (con == null) {
    				createConnection(client.getText(), user.getText(), pass.getText(), dept.getText());
    			}
    		} catch (IOException e) {
    			return;
    		}
    		setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
    		if (moveResultList == null) {
    			moveResultList = new ArrayList<ITransportable>();
    		}
    		try {
    			BufferedReader reader = new BufferedReader(new StringReader(topText.getText()));
    			String line = null;
    			while ((line = reader.readLine()) != null) {
    				line = line.trim();
    				if (line.equals("")) {
    					continue;
    				}
    				SearchObject so = new SearchObject();
    				so.setName(line);
    				so.setTypeCALE(true);
    				so.setTypeCALL(true);
    				so.setTypeCODE(true);
    				so.setTypeCONN(true);
    				so.setTypeCPIT(true);
    				so.setTypeDOCU(true);
    				so.setTypeEVNT(true);
    				so.setTypeFILTER(true);
    				so.setTypeHOSTG(true);
    				so.setTypeJOBF(true);
    				so.setTypeJOBG(true);
    				so.setTypeJOBI(true);
    				so.setTypeJOBP(true);
    				so.setTypeJOBQ(true);
    				so.setTypeJOBS(true);
    				so.setTypeJSCH(true);
    				so.setTypeLOGIN(true);
    				so.setTypePRPT(true);
    				so.setTypeQUEUE(true);
    				so.setTypeSCRI(true);
    				so.setTypeSYNC(true);
    				so.setTypeVARA(true);
    				so.setTypeXSL(true);
    				so.setTypePERIOD(true); // Include "PERIOD" Object
    				con.sendRequestAndWait(so);
    				if (so.size() == 0) {
    					error("No match found for: " + line);
    				} else if (so.size() == 1) {
    					print("Found: " + line);
    					Iterator<SearchResultItem> it = so.resultIterator();
    					while (it.hasNext()) {
    						moveResultList.add(it.next());
    					}
    				} else {
    					error("Too many matches found for: " + line);
    				}
    			}
    			updateDeploymentList();
    		} catch (Exception e) {
    			error(e.getMessage());
    			throw new RuntimeException(e);
    		} finally {
    			setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
    		}
    	}
    
    	private void doTransport() {
    		if (deploymentList != null && !deploymentList.isEmpty()) {
    			try {
    				if (con == null) {
    					createConnection(client.getText(), user.getText(), pass.getText(), dept.getText());
    				}
    			} catch (IOException e) {
    				return;
    			}
    			try {
    				con.sendRequestAndWait(new ClearTransportCase());
    				con.sendRequestAndWait(new TransportObject(deploymentList.iterator()));
    				print("Transport complete");
    			} catch (Exception e) {
    				error(e.getMessage());
    				throw new RuntimeException(e);
    			} finally {
    				setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
    			}
    		} else {
    			print("Nothing to transport");
    		}
    	}
    
    	private boolean isTransportableInList(List<ITransportable> list, ITransportable transportable) {
    		for (ITransportable it : list) {
    			if (it.getName().equals(transportable.getName())) {
    				return true;
    			}
    		}
    		return false;
    	}



  • 3.  RE: How to use ITransportable to add a list of objects to the transport case

    Posted Mar 21, 2023 02:35 AM
    Edited by Michael A. Lowry Mar 21, 2023 02:35 AM

    Thanks, @Jared Kessans. That is helpful. Could you please also share the updateDeploymentList() method?



  • 4.  RE: How to use ITransportable to add a list of objects to the transport case

    Posted Mar 21, 2023 01:14 PM

    Hope this helps.  I believe the code provided (above and below) is from an older version of this tool, but I doubt it has been changed much.

    	private void updateDeploymentList() {
    		if (deploymentList == null) {
    			deploymentList = new ArrayList<ITransportable>();
    		}
    		int dups = 0;
    		if (searchResultList != null && !searchResultList.isEmpty()) {
    			for (ITransportable it : searchResultList) {
    				if (!isTransportableInList(deploymentList, it)) {
    					deploymentList.add(it);
    				} else {
    					++dups;
    				}
    			}
    			searchResultList.clear();
    			finalizeBtn.setEnabled(true);
    		}
    		if (moveResultList != null && !moveResultList.isEmpty()) {
    			for (ITransportable it : moveResultList) {
    				if (!isTransportableInList(deploymentList, it)) {
    					deploymentList.add(it);
    				} else {
    					++dups;
    				}
    			}
    			moveResultList.clear();
    			finalizeBtn.setEnabled(true);
    		}
    		if (dups > 0) {
    			error(dups + " duplicate(s) not added to list");
    		}
    		model.clear();
    		int listSize = 0;
    		for (ITransportable it : deploymentList) {
    			model.addElement(it.getName() + "\n");
    			++listSize;
    		}
    		labelMiddle.setText(labelTextPt1 + listSize + labelTextPt2);
    	}



  • 5.  RE: How to use ITransportable to add a list of objects to the transport case

    Posted Mar 27, 2023 04:39 AM
    Edited by Michael A. Lowry Mar 27, 2023 04:39 AM

    I figured out how it works. The 1st constructor of TransportObject is intended to cover most of the situations in which multiple objects must be added to the transport case at the same time.

    public TransportObject(java.util.Iterator<? extends ITransportable> it)

    This constructor takes a single argument: an Iterator over any class that implements ITransportable.

    Two classes implement ITransportable: FolderListItem and SearchResultItem. The APIs include two methods that return Iterators over these classes.

    ITransportable subclass
    Method that returns Iterator over this class
    FolderListItem FolderListItem.iterator()
    SearchResultItem SearchObject.resultIterator()

    When constructing TransportObject, you can pass either a folder listing or a set of search results as the argument. An example of each approach is shown below.

    Add folder listing to transport case

    public static void addFolderObjectsToTransportCase(Connection aeConnection, String folderPath) throws IOException {
        FolderTree folderTree = new FolderTree();
        aeConnection.sendRequestAndWait(folderTree);
        IFolder iFolder = folderTree.getFolder(folderPath);
        FolderList folderList = new FolderList(iFolder,false);
        Integer numSearchResults = folderList.size();
        System.out.println(String.format("Adding %s objects to transport case.",numSearchResults));
        TransportObject transportObject = new TransportObject(folderList.iterator());
        aeConnection.sendRequestAndWait(transportObject);
    }

    Add search results to transport case

    public static void addAllLoginObjectsToTransportCase(Connection aeConnection) throws IOException {
        SearchObject searchObject = new SearchObject();
        searchObject.setTypeLOGIN(true);
        searchObject.setSearchLocation("/", true);
        searchObject.setIncludeLinks(false);
        searchObject.setNoDateSelection();
        aeConnection.sendRequestAndWait(searchObject);
        Integer numSearchResults = searchObject.size();
        System.out.println(String.format("Adding %s objects to transport case.",numSearchResults));
        TransportObject transportObject = new TransportObject(searchObject.resultIterator());
        aeConnection.sendRequestAndWait(transportObject);
    }



  • 6.  RE: How to use ITransportable to add a list of objects to the transport case
    Best Answer

    Posted Mar 27, 2025 10:42 AM
    Edited by Michael A. Lowry Mar 31, 2025 04:16 AM

    Recently we ran into a problem impacting many of our REST jobs. The fix recommended by Tricise/Broadcom is to unload all of these objects to a transport case file and then load them back again. Because the AWI offers no way to search for objects by job sub-type, we are left with no straightforward way to quickly move the many hundreds of impacted objects to the transport case. We can generate a list using an SQL query, but there's no built-in way to tell the AE to add a list of objects to the transport case.

    I have an old tool that uses SearchObject to find and add objects one at a time, but it is very slow, taking 10–15 seconds per object.

    This brings me back to the ITransportable interface. Today I developed a class that implements ITransportable in a quick-and-dirty way to facilitate adding to the transport case a list of objects provided by the user.

    public class TransportableObject implements ITransportable {
    private final String objectName;
    private final String ObjectId;
    private final String ObjectType;
    private final String FolderId;

    // Constructor to initialize with object name
    public TransportableObject(Connection aeConnection, String objectName) throws IOException {
    this.objectName = objectName;
    UC4Object uc4Object = openObject(aeConnection, objectName, true);
    this.ObjectId = uc4Object.getIdnr();
    this.ObjectType = uc4Object.getType();
    this.FolderId = "0";
    }
    @Override
    public String getId() {
    return this.ObjectId;
    }
    @Override
    public String getName() {
    return objectName;
    }
    @Override
    public String getObjectType() {
    return this.ObjectType;
    }
    @Override
    public String getFolderID() {
    return this.FolderId;
    }
    }

    This relies on some other classes & methods I've developed, such as the openObject method to open a named object. It obviously also relies on an already-established Connection to the AE server.

    This class returns the folder ID 0 in all cases. This is to reduce overhead and save time. If there is a lightweight way to look up an object's folder ID using the Java APIs, I was not able to find it. The folder ID does not seem to be important for my use case.

    Here's the method I wrote to use the new TransportableObject class.

    public static void transportListOfObjects(Connection aeConnection, String inputFilePath) throws IOException {
    boolean aeError;
    Integer numObjects = 0;
    String pluralSuffix = "";
    TransportObject transportObject;
    try {
    System.out.println(String.format("Reading list of objects from file %s.", inputFilePath));
    List<String> objectNames = Files.readAllLines(Paths.get(inputFilePath));
    numObjects = objectNames.size();
    switch (numObjects) {
    case 0:
    System.out.println("No objects in list. Nothing to do. Exiting.");
    exit();
    break;
    case 1:
    pluralSuffix = "";
    break;
    default:
    pluralSuffix = "s";
    break;
    }
    System.out.println(String.format("%s object%s in list. Preparing to add objects.", numObjects, pluralSuffix));
    List<ITransportable> transportableObjectList = new ArrayList<>();
    for (String objectName : objectNames) {
    if (!objectName.equals("")) {
    // Use home-grown TransportableObject class
    transportableObjectList.add(new TransportableObject(aeConnection, objectName.toUpperCase()));
    }
    }
    transportObject = new TransportObject(transportableObjectList.iterator());
    System.out.println(String.format("Adding object%s to transport case.", pluralSuffix));
    aeConnection.sendRequestAndWait(transportObject);
    aeError = checkForAeErrors(transportObject);
    if (aeError) {
    System.out.println(String.format("Error encountered when adding object%s to transport case.", pluralSuffix));
    exit();
    }
    } catch (IOException ex) {
    throw new RuntimeException(ex);
    }
    }

    This approach seems to work OK, and is much quicker than using SearchObject to find each object. The faked folder IDs do not appear to cause a problem.

    Enjoy!