Package org.platformlayer.service.cloud.direct.ops.cloud

Source Code of org.platformlayer.service.cloud.direct.ops.cloud.ScoreHostPolicy$HostRecord

package org.platformlayer.service.cloud.direct.ops.cloud;

import java.util.List;
import java.util.Map;

import javax.inject.Inject;

import org.platformlayer.choice.Chooser;
import org.platformlayer.choice.ScoreChooser;
import org.platformlayer.core.model.HostPolicy;
import org.platformlayer.core.model.ItemBase;
import org.platformlayer.core.model.PlatformLayerKey;
import org.platformlayer.core.model.Tag;
import org.platformlayer.ids.ItemType;
import org.platformlayer.ops.Injection;
import org.platformlayer.ops.OpsException;
import org.platformlayer.ops.machines.PlatformLayerHelpers;
import org.platformlayer.service.cloud.direct.model.DirectInstance;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.Function;
import com.google.common.base.Objects;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

public class ScoreHostPolicy implements Chooser<DirectCloudHost> {

  private static final Logger log = LoggerFactory.getLogger(ScoreHostPolicy.class);

  @Inject
  PlatformLayerHelpers platformLayer;

  HostPolicy hostPolicy;
  DirectInstance newInstance;

  public static final String DEFAULT_GROUP = "default";

  class HostRecord {
    List<DirectInstance> all = Lists.newArrayList();
    Map<DirectInstance, PlatformLayerKey> owners;
    Map<DirectInstance, String> groups;

    DirectCloudHost candidate;
  }

  PlatformLayerKey findOwner(DirectInstance instance) throws OpsException {
    PlatformLayerKey parentKey = Tag.PARENT.findUnique(instance);
    if (parentKey != null) {
      ItemBase persistentInstance = platformLayer.getItem(parentKey);

      if (persistentInstance != null) {
        PlatformLayerKey grandparentKey = Tag.PARENT.findUnique(instance);
        return grandparentKey;
      }
    }
    return null;
  }

  @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;
  }

  public static ScoreHostPolicy build(HostPolicy hostPolicy, DirectInstance newInstance) {
    if (hostPolicy == null) {
      hostPolicy = new HostPolicy();
    }

    ScoreHostPolicy chooser = Injection.getInstance(ScoreHostPolicy.class);
    chooser.hostPolicy = hostPolicy;
    chooser.newInstance = newInstance;

    return chooser;
  }
}
TOP

Related Classes of org.platformlayer.service.cloud.direct.ops.cloud.ScoreHostPolicy$HostRecord

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.