I have a program, running outside vCenter, that creates a ServiceConnection, then a PropertyCollector. I use the waitForUpdatesEx() with a timeout of 2 minutes. The method wakes up after 2 minutes, prints debug output then loops and waits again. After 30 minutes, the connection seems to timeout. So, to get around that problem, when the method wakes up after the 2 minute timeout, I performed a serviceConnection.currentTime() (or a getAboutInfo()) to communicate with the vCenter in an attempt to prevent the timeout.
Unfortunately, I still lose contact (session lost?) after a little over an hour. No exception is thrown, the thread just seems to hang. What do I need to do to keep the session live?
@Override publicvoid run() { try { ViewManager viewManager = serviceInstance.getViewManager(); ContainerView containerView = viewManager.createContainerView(serviceInstance.getRootFolder(), new String[] { "Folder", "VirtualMachine" }, true); ObjectSpec objectSpec = new ObjectSpec(); objectSpec.setObj(containerView.getMOR()); TraversalSpec traversalSpec = new TraversalSpec(); traversalSpec.setPath("view"); traversalSpec.setType("ContainerView"); objectSpec.setSelectSet(new SelectionSpec[] { traversalSpec }); PropertySpec propertySpec = new PropertySpec(); propertySpec.setType("VirtualMachine"); propertySpec.setPathSet(new String[] { "runtime.powerState", "runtime.host" }); PropertyFilterSpec propertyFilterSpec = new PropertyFilterSpec(); propertyFilterSpec.setObjectSet(new ObjectSpec[] { objectSpec }); propertyFilterSpec.setPropSet(new PropertySpec[] { propertySpec }); PropertyCollector propertyCollector = serviceInstance.getPropertyCollector(); propertyCollector.createFilter(propertyFilterSpec, true); WaitOptions waitOptions = new WaitOptions(); waitOptions.setMaxWaitSeconds(120); // What, only 2 minutes? Change for production maybe waitOptions.setMaxObjectUpdates(1000); // An arbitrary, but manageable number // Calculate initial stuff before waiting on new events InventoryNavigator inventoryNavigator = new InventoryNavigator(serviceInstance.getRootFolder()); ManagedEntity[] initialDatastores = (ManagedEntity[]) inventoryNavigator .searchManagedEntities("Datastore"); for (ManagedEntity entity : initialDatastores) { Datastore datastore = (Datastore) entity; log.debug(Thread.currentThread().getName() + " Do stuff with datastore " + datastore.getName()); doStuff(datastore); } booleaninitial = true; // Skip the initial flood of old data while (true) { // Monitor changes forever booleantruncated = true; while (truncated) { // Get all the updates for this version UpdateSet updateSet = propertyCollector.waitForUpdatesEx(version, waitOptions); if (updateSet == null) { // Woke up because of a wait timeout log.debug(" timeout"); serviceInstance.getAboutInfo(); continue; } version = updateSet.getVersion(); // Save version for next time through the loop if (!initial) { for (PropertyFilterUpdate propertyFilterUpdate : updateSet.getFilterSet()) { for (ObjectUpdate objectUpdate : propertyFilterUpdate.getObjectSet()) { for (Datastore datastore : getDatastores(serviceInstance, objectUpdate)) { log.debug(" Adding datastore " + datastore.getName() + " to set of datastores"); // Build a set of datastores so they only get processed once // Note: Use name (String) set because datastores aren't hashable if (!datastoreNameSet.contains(datastore.getName())) { datastoreNameSet.add(datastore.getName()); datastoreSet.add(datastore); } } } } } truncated = (updateSet.getTruncated() == null ? false : updateSet.getTruncated()); } initial = false; // Initial flood of old data has been skipped log.debug(" Version " + version); // Only process the datastore once for (Datastore datastore : datastoreSet) { log.debug(" Calculating Stuff for datastore " + datastore.getName()); doStuff(datastore); } datastoreNameSet.clear(); datastoreSet.clear(); } } catch (Exception e) { log.warn("Lost communications with the vCenter", e); } } }