All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.featurehub.client.ServerEvalFeatureContext Maven / Gradle / Ivy

package io.featurehub.client;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Future;

public class ServerEvalFeatureContext extends BaseClientContext {
  private static final Logger log = LoggerFactory.getLogger(ServerEvalFeatureContext.class);
  private final ObjectSupplier edgeService;
  private EdgeService currentEdgeService;
  private String xHeader;
  private boolean weOwnEdge;

  private final MessageDigest shaDigester;

  public ServerEvalFeatureContext(FeatureHubConfig config, FeatureRepositoryContext repository,
                                  ObjectSupplier edgeService) {
    super(repository, config);

    try {
      shaDigester = MessageDigest.getInstance("SHA-256");
    } catch (NoSuchAlgorithmException e) {
      throw new RuntimeException(e);
    }

    this.edgeService = edgeService;
    this.weOwnEdge = false;
  }

  @Override
  public Future build() {
    String newHeader = FeatureStateUtils.generateXFeatureHubHeaderFromMap(clientContext);

    if (newHeader != null || xHeader != null) {
      if ((newHeader != null && xHeader == null) || newHeader == null || !newHeader.equals(xHeader)) {
        xHeader = newHeader;

        repository.notReady();

        if (currentEdgeService != null && currentEdgeService.isRequiresReplacementOnHeaderChange()) {
          currentEdgeService.close();
          currentEdgeService = edgeService.get();
        }
      }
    }

    if (currentEdgeService == null) {
      currentEdgeService = edgeService.get();
      weOwnEdge = true;
    }

    Future change = currentEdgeService.contextChange(newHeader,
      newHeader == null ? null : bytesToHex(shaDigester.digest(newHeader.getBytes(StandardCharsets.UTF_8))));

    xHeader = newHeader;

    CompletableFuture future = new CompletableFuture<>();

    try {
      change.get();

      future.complete(this);
    } catch (Exception e) {
      log.error("Failed to update", e);
      future.completeExceptionally(e);
    }


    return future;
  }

  // from https://www.baeldung.com/sha-256-hashing-java as we don't have any libs consistently to do this for us
  private static String bytesToHex(byte[] hash) {
    StringBuilder hexString = new StringBuilder(2 * hash.length);
    for (int i = 0; i < hash.length; i++) {
      String hex = Integer.toHexString(0xff & hash[i]);
      if(hex.length() == 1) {
        hexString.append('0');
      }
      hexString.append(hex);
    }
    return hexString.toString();
  }

  @Override
  public EdgeService getEdgeService() {
    return currentEdgeService;
  }

  public ObjectSupplier getEdgeServiceSupplier() { return edgeService; }

  @Override
  public boolean exists(String key) {
    return false;
  }

  @Override
  public void close() {
    if (weOwnEdge && currentEdgeService != null) {
      currentEdgeService.close();
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy