Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright 2015 Netflix, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.netflix.fenzo;
import com.netflix.fenzo.functions.Func1;
import org.apache.mesos.Protos;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;
class VMCollection {
private static final String defaultGroupName = "DEFAULT";
private static final Logger logger = LoggerFactory.getLogger(VMCollection.class);
private final ConcurrentMap> vms;
private final Func1 newVmCreator;
private final String groupingAttrName;
VMCollection(Func1 func1, String groupingAttrName) {
vms = new ConcurrentHashMap<>();
this.newVmCreator = func1;
this.groupingAttrName = groupingAttrName;
}
Collection getAllVMs() {
List result = new LinkedList<>();
vms.values().forEach(m -> result.addAll(m.values()));
return result;
}
Collection getGroups() {
return Collections.unmodifiableCollection(vms.keySet());
}
/**
* Create n pseudo VMs for each group by cloning a VM in each group.
* @param groupCounts Map with keys contain group names and values containing number of agents to clone
* @param ruleGetter Getter function for autoscale rules
* @return Collection of pseudo host names added.
*/
Map> clonePseudoVMsForGroups(Map groupCounts,
Func1 ruleGetter,
Predicate vmFilter
) {
if (groupCounts == null || groupCounts.isEmpty())
return Collections.emptyMap();
InternalVMCloner vmCloner = new InternalVMCloner();
Map> result = new HashMap<>();
long now = System.currentTimeMillis();
for (String g: groupCounts.keySet()) {
List hostnames = new LinkedList<>();
result.put(g, hostnames);
final ConcurrentMap avmsMap = vms.get(g);
if (avmsMap != null) {
final List vmsList = avmsMap.values()
.stream()
.filter(avm -> vmFilter.test(avm.getCurrTotalLease()))
.collect(Collectors.toList());
if (vmsList != null && !vmsList.isEmpty()) {
// NOTE: a shortcoming here is that the attributes of VMs across a group may not be homogeneous.
// By creating one lease object and cloning from it, we pick one combination of the attributes
// and replicate across all the newly created pseudo VMs. It may be possible to capture the
// unique set of attributes across all existing VMs in the group and replicate that mix within
// the new pseudo VMs. However, we will not do that at this time. So, it is possible that some
// task constraints that depend on the variety of such attributes may fail the task placement.
// We will live with that limitation at this time.
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 attributeMap = lease.getAttributeMap();
if (attributeMap == null || attributeMap.isEmpty())
logger.debug("Cloned maxRes lease has empty attributeMap");
else
for (Map.Entry 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);
// update total lease on the newly added VMs so they are available for use
getVmByName(hostname).ifPresent(AssignableVirtualMachine::updateCurrTotalLease);
}
}
}
}
return result;
}
private String createHostname(String g, int i) {
return AssignableVirtualMachine.PseuoHostNamePrefix + g + "-" + i;
}
/**
* Remove VM of given name from the given group. This is generally unsafe and intended only to be used by whoever
* uses {@link VMCollection#clonePseudoVMsForGroups(Map, Func1, Predicate)}.
* @param name
* @param group
*/
/* package */ AssignableVirtualMachine unsafeRemoveVm(String name, String group) {
final ConcurrentMap vmsMap = vms.get(group);
if (vmsMap != null) {
return vmsMap.remove(name);
}
return null;
}
Optional getVmByName(String name) {
return vms.values().stream()
.flatMap(
(Function, Stream>) m
-> m.values().stream()
)
.filter(avm -> name.equals(avm.getHostname()))
.findFirst();
}
AssignableVirtualMachine create(String host) {
return create(host, defaultGroupName);
}
AssignableVirtualMachine create(String host, String group) {
vms.putIfAbsent(group, new ConcurrentHashMap<>());
AssignableVirtualMachine prev = null;
if (!defaultGroupName.equals(group)) {
if (vms.get(defaultGroupName) != null)
prev = vms.get(defaultGroupName).remove(host);
}
vms.get(group).putIfAbsent(host, prev == null? newVmCreator.call(host) : prev);
return vms.get(group).get(host);
}
AssignableVirtualMachine getOrCreate(String host) {
final Optional vmByName = getVmByName(host);
if (vmByName.isPresent())
return vmByName.get();
return create(host, defaultGroupName);
}
private AssignableVirtualMachine getOrCreate(String host, String group) {
vms.putIfAbsent(group, new ConcurrentHashMap<>());
final AssignableVirtualMachine avm = vms.get(group).get(host);
if (avm != null)
return avm;
if (logger.isDebugEnabled())
logger.debug("Creating new host " + host);
return create(host, group);
}
boolean addLease(VirtualMachineLease l) {
String group = l.getAttributeMap() == null? null :
l.getAttributeMap().get(groupingAttrName) == null?
null :
l.getAttributeMap().get(groupingAttrName).getText().getValue();
if (group == null)
group = defaultGroupName;
final AssignableVirtualMachine avm = getOrCreate(l.hostname(), group);
return avm.addLease(l);
}
public int size() {
final Optional size = vms.values().stream().map(Map::size).reduce((i1, i2) -> i1 + i2);
return size.orElse(0);
}
public int size(String group) {
final ConcurrentMap m = vms.get(group);
return m == null? 0 : m.size();
}
public AssignableVirtualMachine remove(AssignableVirtualMachine avm) {
final String group = avm.getAttrValue(groupingAttrName);
AssignableVirtualMachine removed = null;
if (group != null) {
final ConcurrentMap m = vms.get(group);
if (m != null) {
removed = m.remove(avm.getHostname());
}
}
if (removed != null)
return removed;
final ConcurrentMap m = vms.get(defaultGroupName);
if (m != null)
m.remove(avm.getHostname());
return null;
}
}