use of org.platformlayer.service.cloud.direct.model.DirectInstance in project platformlayer by platformlayer.
the class DirectPublicEndpointController method addChildren.
@Override
protected void addChildren() throws OpsException {
DirectPublicEndpoint model = OpsContext.get().getInstance(DirectPublicEndpoint.class);
DirectInstance directInstance = platformLayerClient.getItem(model.instance, DirectInstance.class);
{
DirectPublicPorts publicPorts = injected(DirectPublicPorts.class);
publicPorts.backendItem = directInstance;
publicPorts.tagItems.add(directInstance);
publicPorts.tagItems.add(model);
publicPorts.uuid = platformLayerClient.getOrCreateUuid(model).toString();
publicPorts.backendPort = model.backendPort;
publicPorts.publicPort = model.publicPort;
publicPorts.publicPortCluster = model.publicPortCluster;
if (model.transport != null) {
publicPorts.transport = EnumUtils.valueOfCaseInsensitive(Transport.class, model.transport);
}
addChild(publicPorts);
}
}
use of org.platformlayer.service.cloud.direct.model.DirectInstance in project platformlayer by platformlayer.
the class ScoreHostPolicy method choose.
@Override
public DirectCloudHost choose(List<DirectCloudHost> candidates) throws OpsException {
final String sameGroupId;
if (Strings.isNullOrEmpty(hostPolicy.groupId)) {
sameGroupId = DEFAULT_GROUP;
} else {
sameGroupId = hostPolicy.groupId;
}
final ItemType sameItemType;
if (hostPolicy.scoreSameItemType != 0) {
PlatformLayerKey owner = findOwner(newInstance);
if (owner == null) {
throw new OpsException();
}
sameItemType = owner.getItemType();
} else {
sameItemType = null;
}
List<HostRecord> records = Lists.newArrayList();
for (DirectCloudHost candidate : candidates) {
HostRecord record = new HostRecord();
record.candidate = candidate;
record.groups = Maps.newHashMap();
if (hostPolicy.scoreSameItemType != 0) {
record.owners = Maps.newHashMap();
}
records.add(record);
for (String assigned : candidate.getModel().getTags().findAll(Tag.ASSIGNED)) {
PlatformLayerKey instanceKey = PlatformLayerKey.parse(assigned);
// TODO: Avoid 1+N
DirectInstance instance = platformLayer.getItem(instanceKey);
if (instance == null) {
// TODO: Warn?
throw new IllegalStateException();
}
switch(instance.getState()) {
case DELETE_REQUESTED:
case DELETED:
continue;
}
HostPolicy instanceHostPolicy = instance.hostPolicy;
String instanceGroupId = instanceHostPolicy.groupId;
if (Strings.isNullOrEmpty(instanceGroupId)) {
instanceGroupId = DEFAULT_GROUP;
}
record.groups.put(instance, instanceGroupId);
if (sameItemType != null) {
PlatformLayerKey owner = findOwner(instance);
if (owner != null) {
record.owners.put(instance, owner);
}
}
record.all.add(instance);
}
}
Function<HostRecord, Float> score = new Function<HostRecord, Float>() {
@Override
public Float apply(HostRecord record) {
float score = 0;
for (DirectInstance instance : record.all) {
if (sameGroupId != null) {
String instanceGroupId = record.groups.get(instance);
if (Objects.equal(instanceGroupId, sameGroupId)) {
score += hostPolicy.scoreSameGroup;
}
}
if (sameItemType != null) {
PlatformLayerKey owner = record.owners.get(instance);
if (owner != null && owner.getItemType().equals(sameItemType)) {
score += hostPolicy.scoreSameItemType;
}
}
}
// Break ties using least-loaded
score -= record.all.size() / 1000.0f;
return score;
}
};
HostRecord bestRecord = ScoreChooser.chooseMax(score).choose(records);
return bestRecord.candidate;
}
use of org.platformlayer.service.cloud.direct.model.DirectInstance in project platformlayer by platformlayer.
the class DirectCloudController method buildInstanceTemplate.
@Override
public InstanceBase buildInstanceTemplate(MachineCreationRequest request) {
DirectInstance directMachine = new DirectInstance();
directMachine.minimumMemoryMb = request.minimumMemoryMB;
directMachine.hostname = request.hostname;
return directMachine;
}
use of org.platformlayer.service.cloud.direct.model.DirectInstance in project platformlayer by platformlayer.
the class DirectPublicPorts method addChildren.
@Override
protected void addChildren() throws OpsException {
final CloudInstanceMapper cloudHost;
{
cloudHost = injected(CloudInstanceMapper.class);
cloudHost.createInstance = false;
cloudHost.instance = backendItem;
addChild(cloudHost);
}
final SocketAddressPoolAssignment assignPublicAddress;
{
assignPublicAddress = cloudHost.addChild(SocketAddressPoolAssignment.class);
assignPublicAddress.holder = backendItem.getKey();
if (Objects.equal(transport, Transport.Ipv6)) {
assignPublicAddress.poolProvider = new OpsProvider<ResourcePool<InetSocketAddress>>() {
@Override
public ResourcePool<InetSocketAddress> get() throws OpsException {
final ResourcePool<AddressModel> pool = directCloudHelpers.getAddressPool6().get();
return new AssignPortToAddressPool(pool, publicPort);
}
};
} else {
List<Integer> publicPortCluster = this.publicPortCluster;
if (publicPortCluster == null) {
publicPortCluster = Lists.newArrayList();
publicPortCluster.add(publicPort);
}
if (!publicPortCluster.contains(publicPort)) {
throw new OpsException("Port set specified, but public port not in the set");
}
assignPublicAddress.poolProvider = directCloudHelpers.getPublicAddressPool4(publicPort, publicPortCluster);
}
}
if (Objects.equal(transport, Transport.Ipv6)) {
// TODO: Do we need separate frontend / backend ports really?
if (this.publicPort != this.backendPort) {
throw new UnsupportedOperationException();
}
} else {
for (Protocol protocol : Protocol.TcpAndUdp()) {
IptablesForwardPort forward = injected(IptablesForwardPort.class);
forward.publicAddress = assignPublicAddress;
forward.ruleKey = protocol.name() + "-" + uuid;
forward.protocol = protocol;
forward.privateAddress = new OpsProvider<String>() {
@Override
public String get() throws OpsException {
// Refresh item to pick up new tags
backendItem = platformLayerClient.getItem(backendItem.getKey(), DirectInstance.class);
PlatformLayerCloudMachine instanceMachine = (PlatformLayerCloudMachine) instanceHelpers.getMachine(backendItem);
DirectInstance instance = (DirectInstance) instanceMachine.getInstance();
List<InetAddress> addresses = Tag.NETWORK_ADDRESS.find(instance);
InetAddress address = InetAddressChooser.preferIpv4().choose(addresses);
if (address == null) {
throw new IllegalStateException();
}
if (InetAddressUtils.isIpv6(address)) {
// We can't NAT IPV4 -> IPV6 (I think)
throw new IllegalStateException();
}
return address.getHostAddress();
}
};
forward.privatePort = backendPort;
cloudHost.addChild(forward);
}
}
{
OpsProvider<TagChanges> tagChanges = new OpsProvider<TagChanges>() {
@Override
public TagChanges get() {
TagChanges tagChanges = new TagChanges();
InetSocketAddress socketAddress = assignPublicAddress.get();
if (socketAddress == null) {
return null;
}
if (socketAddress.getPort() != publicPort) {
throw new IllegalStateException();
}
EndpointInfo endpoint = new EndpointInfo(socketAddress);
tagChanges.addTags.add(endpoint.toTag());
return tagChanges;
}
};
for (ItemBase tagItem : tagItems) {
Tagger tagger = addChild(Tagger.class);
tagger.platformLayerKey = tagItem.getKey();
tagger.tagChangesProvider = tagChanges;
}
}
}
use of org.platformlayer.service.cloud.direct.model.DirectInstance in project platformlayer by platformlayer.
the class SpreadChooser method choose.
@Override
public DirectCloudHost choose(List<DirectCloudHost> candidates) throws OpsException {
List<HostRecord> records = Lists.newArrayList();
for (DirectCloudHost candidate : candidates) {
HostRecord record = new HostRecord();
record.candidate = candidate;
records.add(record);
for (String assigned : candidate.getModel().getTags().findAll(Tag.ASSIGNED)) {
PlatformLayerKey instanceKey = PlatformLayerKey.parse(assigned);
// TODO: Avoid 1+N
DirectInstance instance = platformLayer.getItem(instanceKey);
if (instance == null) {
// TODO: Warn?
throw new IllegalStateException();
}
switch(instance.getState()) {
case DELETE_REQUESTED:
case DELETED:
continue;
}
HostPolicy hostPolicy = instance.hostPolicy;
if (Objects.equal(groupId, hostPolicy.groupId)) {
record.matchingPolicy.add(instance);
}
record.all.add(instance);
}
}
Function<HostRecord, Float> score = new Function<HostRecord, Float>() {
@Override
public Float apply(HostRecord input) {
// Lower score is better
float score = input.matchingPolicy.size();
// For breaking ties
score += input.all.size() / 100000.0;
return score;
}
};
HostRecord bestRecord = ScoreChooser.chooseMin(score).choose(records);
return bestRecord.candidate;
}
Aggregations