VMCollection { Map<String, List<String>> clonePseudoVMsForGroups(Map<String, Integer> groupCounts, Func1<String, AutoScaleRule> ruleGetter, Predicate<VirtualMachineLease> vmFilter ) { if (groupCounts == null || groupCounts.isEmpty()) return Collections.emptyMap(); InternalVMCloner vmCloner = new InternalVMCloner(); Map<String, List<String>> result = new HashMap<>(); long now = System.currentTimeMillis(); for (String g: groupCounts.keySet()) { List<String> hostnames = new LinkedList<>(); result.put(g, hostnames); final ConcurrentMap<String, AssignableVirtualMachine> avmsMap = vms.get(g); if (avmsMap != null) { final List<AssignableVirtualMachine> vmsList = avmsMap.values() .stream() .filter(avm -> vmFilter.test(avm.getCurrTotalLease())) .collect(Collectors.toList()); if (vmsList != null && !vmsList.isEmpty()) { VirtualMachineLease lease = vmCloner.getClonedMaxResourcesLease(vmsList); if(logger.isDebugEnabled()) { logger.debug("Cloned lease cpu={}, mem={}, disk={}, network={}", lease.cpuCores(), lease.memoryMB(), lease.diskMB(), lease.networkMbps()); final Map<String, Protos.Attribute> attributeMap = lease.getAttributeMap(); if (attributeMap == null || attributeMap.isEmpty()) logger.debug("Cloned maxRes lease has empty attributeMap"); else for (Map.Entry<String, Protos.Attribute> entry : attributeMap.entrySet()) logger.debug("Cloned maxRes lease attribute: " + entry.getKey() + ": " + (entry.getValue() == null ? "null" : entry.getValue().getText().getValue()) ); } int n = groupCounts.get(g); final AutoScaleRule rule = ruleGetter.call(g); if (rule != null) { int max = rule.getMaxSize(); if (max < Integer.MAX_VALUE && n > (max - vmsList.size())) n = max - vmsList.size(); } for (int i = 0; i < n; i++) { final String hostname = createHostname(g, i); addLease(vmCloner.cloneLease(lease, hostname, now)); if(logger.isDebugEnabled()) logger.debug("Added cloned lease for " + hostname); hostnames.add(hostname); getVmByName(hostname).ifPresent(AssignableVirtualMachine::updateCurrTotalLease); } } } } return result; } VMCollection(Func1<String, AssignableVirtualMachine> func1, String groupingAttrName); int size(); int size(String group); AssignableVirtualMachine remove(AssignableVirtualMachine avm);  }
@Test public void clonePseudoVMsForGroups() throws Exception { AutoScaleRule rule = getAutoScaleRule(attributeVal1, 4); Action1<VirtualMachineLease> leaseRejectAction = l -> {}; final ConcurrentMap<String, String> vmIdTohostNames = new ConcurrentHashMap<>(); final ConcurrentMap<String, String> leasesToHostnames = new ConcurrentHashMap<>(); final Map<String, AssignableVirtualMachine> avms = new HashMap<>(); final TaskTracker taskTracker = new TaskTracker(); VMCollection vms = createVmCollection(vmIdTohostNames, leasesToHostnames, taskTracker, avms); for (int i=0; i < rule.getMaxSize()-1; i++) { vms.addLease(LeaseProvider.getLeaseOffer("host"+i, 4, 4000, 0, 0, ports, attributes1, Collections.singletonMap("GPU", 1.0))); } for (AssignableVirtualMachine avm: avms.values()) avm.updateCurrTotalLease(); final Map<String, List<String>> map = vms.clonePseudoVMsForGroups( Collections.singletonMap(rule.getRuleName(), 6), s -> rule, lease -> true ); Assert.assertNotNull(map); Assert.assertEquals(1, map.size()); Assert.assertEquals(rule.getRuleName(), map.keySet().iterator().next()); Assert.assertEquals(1, map.values().iterator().next().size()); }