Package org.platformlayer.federation

Source Code of org.platformlayer.federation.FederationMap

package org.platformlayer.federation;

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

import org.platformlayer.HttpPlatformLayerClient;
import org.platformlayer.PlatformLayerClient;
import org.platformlayer.TypedItemMapper;
import org.platformlayer.TypedPlatformLayerClient;
import org.platformlayer.core.model.PlatformLayerKey;
import org.platformlayer.federation.model.FederationConfiguration;
import org.platformlayer.federation.model.FederationRule;
import org.platformlayer.federation.model.PlatformLayerConnectionConfiguration;
import org.platformlayer.http.HttpStrategy;
import org.platformlayer.ids.FederationKey;
import org.platformlayer.ids.ProjectId;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.Joiner;
import com.google.common.base.Objects;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

/**
* Maps platform layer keys to one or more children.
*/
public class FederationMap {
  private static final Logger log = LoggerFactory.getLogger(FederationMap.class);

  private final Map<FederationMapping, MappedTarget> targetMap;
  private final TypedItemMapper mapper;

  final List<Rule> rules;

  final HttpStrategy httpStrategy;

  static class MappedTarget {
    PlatformLayerConnectionConfiguration configuration;
    TypedPlatformLayerClient client;
  }

  public static class Rule {
    public FederationMapping targetKey;
    public PlatformLayerKey mappedItems;
  }

  public FederationMap(HttpStrategy httpStrategy, TypedItemMapper mapper, FederationConfiguration config) {
    this.httpStrategy = httpStrategy;
    this.mapper = mapper;

    this.rules = Lists.newArrayList();

    this.targetMap = Maps.newHashMap();

    buildTargetMap(config);
    buildRules(config);
  }

  public void addDefault(TypedPlatformLayerClient defaultClient) {
    FederationKey host = FederationKey.LOCAL;
    ProjectId project = defaultClient.getProject();
    FederationMapping mapKey = new FederationMapping(host, project);

    MappedTarget target = new MappedTarget();
    target.client = defaultClient;

    addMapping(mapKey, target);
  }

  public void addMapping(FederationMapping mapKey, TypedPlatformLayerClient localClient) {
    MappedTarget target = new MappedTarget();
    target.client = localClient;

    addMapping(mapKey, target);
  }

  private void addMapping(FederationMapping mapKey, MappedTarget target) {
    if (targetMap.containsKey(mapKey)) {
      throw new IllegalArgumentException("Duplicate key: " + mapKey);
    }

    targetMap.put(mapKey, target);
  }

  private void buildTargetMap(FederationConfiguration config) {
    for (PlatformLayerConnectionConfiguration child : config.systems) {
      FederationKey host = FederationKey.build(child.authenticationEndpoint);
      ProjectId project = new ProjectId(child.tenant);
      FederationMapping key = new FederationMapping(host, project);

      MappedTarget target = new MappedTarget();
      target.configuration = child;

      addMapping(key, target);
    }
  }

  private void buildRules(FederationConfiguration config) {
    for (FederationRule federationRule : config.rules) {
      Rule rule = new Rule();

      rule.mappedItems = PlatformLayerKey.fromServiceAndItem(federationRule.serviceType, null);

      for (PlatformLayerConnectionConfiguration system : config.systems) {
        if (Objects.equal(system.key, federationRule.target)) {
          if (rule.targetKey != null) {
            throw new IllegalStateException();
          }

          FederationKey host = FederationKey.build(system.authenticationEndpoint);
          ProjectId project = new ProjectId(system.tenant);
          rule.targetKey = new FederationMapping(host, project);
        }
      }

      if (rule.targetKey == null) {
        throw new IllegalStateException();
      }

      addRule(rule);
    }
  }

  private FederationMapping toKey(PlatformLayerKey original, Rule rule) {
    FederationKey targetHost = original.getHost();
    ProjectId targetProject = original.getProject();

    if (rule.targetKey != null) {
      MappedTarget target = targetMap.get(rule.targetKey);
      if (target == null) {
        throw new IllegalStateException("Cannot find target: " + rule.targetKey);
      }

      targetHost = rule.targetKey.host;
      targetProject = rule.targetKey.project;
    }

    return new FederationMapping(targetHost, targetProject);
  }

  private FederationMapping buildDefault(PlatformLayerKey original) {
    FederationKey targetHost = original.getHost();
    if (targetHost == null) {
      targetHost = FederationKey.LOCAL;
    }

    ProjectId targetProject = original.getProject();

    return new FederationMapping(targetHost, targetProject);
  }

  public Iterable<FederationMapping> getAllTargetKeys() {
    return targetMap.keySet();
  }

  public TypedPlatformLayerClient buildClient(FederationMapping key) {
    MappedTarget target = targetMap.get(key);
    if (target == null) {
      throw new IllegalArgumentException("Unknown key: " + key);
    }

    if (target.client == null) {
      PlatformLayerClient client = HttpPlatformLayerClient.buildUsingConfiguration(httpStrategy,
          target.configuration);

      TypedPlatformLayerClient typedClient = new TypedPlatformLayerClient(client, mapper);
      // TODO: Save client??
      return typedClient;
    } else {
      return target.client;
    }
  }

  public List<FederationMapping> getClients(PlatformLayerKey path) {
    if (path.getHost() != null) {
      throw new IllegalStateException();
    }

    List<FederationMapping> keys = Lists.newArrayList();

    for (Rule rule : rules) {
      if (isMatch(rule, path)) {
        keys.add(toKey(path, rule));
      }
    }

    keys.add(buildDefault(path));

    if (keys.size() > 1) {
      log.debug("Multiple clients for " + path + ": " + Joiner.on(",").join(keys));
    }

    return keys;
  }

  public FederationMapping getClientForCreate(PlatformLayerKey path) {
    if (path.getHost() != null) {
      throw new IllegalStateException();
    }

    List<FederationMapping> keys = Lists.newArrayList();

    for (Rule rule : rules) {
      if (isMatch(rule, path)) {
        keys.add(toKey(path, rule));
      }
    }

    if (keys.isEmpty()) {
      keys.add(buildDefault(path));
    }

    if (keys.size() == 0) {
      return null;
    }

    if (keys.size() != 1) {
      throw new IllegalArgumentException();
    }

    return keys.get(0);
  }

  private boolean isMatch(Rule rule, PlatformLayerKey path) {
    if (rule.mappedItems == null) {
      throw new IllegalStateException();
      // (Used to return true)
    }

    if (rule.mappedItems.getHost() != null) {
      throw new IllegalStateException();
    }

    if (rule.mappedItems.getServiceType() != null) {
      if (!Objects.equal(rule.mappedItems.getServiceType(), path.getServiceType())) {
        return false;
      }
    }

    if (rule.mappedItems.getItemType() != null) {
      if (!Objects.equal(rule.mappedItems.getItemType(), path.getItemType())) {
        return false;
      }
    }

    if (rule.mappedItems.getItemId() != null) {
      throw new IllegalStateException();
    }

    return true;
  }

  public void addRule(Rule rule) {
    rules.add(rule);
  }

  public boolean isEmpty() {
    return rules.isEmpty() && targetMap.isEmpty();
  }

}
TOP

Related Classes of org.platformlayer.federation.FederationMap

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.