// Path: fiat-roles/src/main/java/com/netflix/spinnaker/fiat/providers/ProviderHealthTracker.java
// public class ProviderHealthTracker {
// 
//   /** Maximum age of stale data before this instance goes unhealthy. */
//   private final long maximumStalenessTimeMs;
// 
//   private AtomicLong lastSuccessfulUpdateTimeMs = new AtomicLong(-1);
// 
//   public ProviderHealthTracker(long maximumStalenessTimeMs) {
//     this.maximumStalenessTimeMs = maximumStalenessTimeMs;
//   }
// 
//   public void success() {
//     lastSuccessfulUpdateTimeMs.set(System.currentTimeMillis());
//   }
// 
//   public boolean isProviderHealthy() {
//     return lastSuccessfulUpdateTimeMs.get() != -1 && getStaleness() < maximumStalenessTimeMs;
//   }
// 
//   private long getStaleness() {
//     if (lastSuccessfulUpdateTimeMs.get() == -1) {
//       return -1;
//     }
//     return System.currentTimeMillis() - lastSuccessfulUpdateTimeMs.get();
//   }
// 
//   public HealthView getHealthView() {
//     return new HealthView();
//   }
// 
//   @Data
//   public class HealthView {
//     boolean providerHealthy = ProviderHealthTracker.this.isProviderHealthy();
//     long msSinceLastSuccess = ProviderHealthTracker.this.getStaleness();
//     long lastSuccessfulUpdateTime = ProviderHealthTracker.this.lastSuccessfulUpdateTimeMs.get();
//     long maximumStalenessTimeMs = ProviderHealthTracker.this.maximumStalenessTimeMs;
//   }
// }


import com.fasterxml.jackson.databind.ObjectMapper;
import com.jakewharton.retrofit.Ok3Client;
import com.netflix.spinnaker.config.DefaultServiceEndpoint;
import com.netflix.spinnaker.config.okhttp3.OkHttpClientProvider;
import com.netflix.spinnaker.fiat.providers.ProviderHealthTracker;
import com.netflix.spinnaker.fiat.providers.internal.*;
import com.netflix.spinnaker.retrofit.Slf4jRetrofitLogger;
import lombok.Setter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.annotation.Scope;
import retrofit.Endpoints;
import retrofit.RestAdapter;
import retrofit.converter.JacksonConverter;
  @Autowired @Setter private OkHttpClientProvider clientProvider;

  @Value("${services.front50.base-url}")
  @Setter
  private String front50Endpoint;

  @Value("${services.clouddriver.base-url}")
  @Setter
  private String clouddriverEndpoint;

  @Value("${services.igor.base-url}")
  @Setter
  private String igorEndpoint;

  @Bean
  Front50Api front50Api() {
    return new RestAdapter.Builder()
        .setEndpoint(Endpoints.newFixedEndpoint(front50Endpoint))
        .setClient(
            new Ok3Client(
                clientProvider.getClient(new DefaultServiceEndpoint("front50", front50Endpoint))))
        .setConverter(new JacksonConverter(objectMapper))
        .setLogLevel(retrofitLogLevel)
        .setLog(new Slf4jRetrofitLogger(Front50Api.class))
        .build()
        .create(Front50Api.class);
  }

  @Bean
  Front50ApplicationLoader front50ApplicationLoader(
// Path: fiat-roles/src/main/java/com/netflix/spinnaker/fiat/providers/ProviderHealthTracker.java
// public class ProviderHealthTracker {
// 
//   /** Maximum age of stale data before this instance goes unhealthy. */
//   private final long maximumStalenessTimeMs;
// 
//   private AtomicLong lastSuccessfulUpdateTimeMs = new AtomicLong(-1);
// 
//   public ProviderHealthTracker(long maximumStalenessTimeMs) {
//     this.maximumStalenessTimeMs = maximumStalenessTimeMs;
//   }
// 
//   public void success() {
//     lastSuccessfulUpdateTimeMs.set(System.currentTimeMillis());
//   }
// 
//   public boolean isProviderHealthy() {
//     return lastSuccessfulUpdateTimeMs.get() != -1 && getStaleness() < maximumStalenessTimeMs;
//   }
// 
//   private long getStaleness() {
//     if (lastSuccessfulUpdateTimeMs.get() == -1) {
//       return -1;
//     }
//     return System.currentTimeMillis() - lastSuccessfulUpdateTimeMs.get();
//   }
// 
//   public HealthView getHealthView() {
//     return new HealthView();
//   }
// 
//   @Data
//   public class HealthView {
//     boolean providerHealthy = ProviderHealthTracker.this.isProviderHealthy();
//     long msSinceLastSuccess = ProviderHealthTracker.this.getStaleness();
//     long lastSuccessfulUpdateTime = ProviderHealthTracker.this.lastSuccessfulUpdateTimeMs.get();
//     long maximumStalenessTimeMs = ProviderHealthTracker.this.maximumStalenessTimeMs;
//   }
// }


// Path: fiat-web/src/main/java/com/netflix/spinnaker/fiat/config/ResourcesConfig.java
import com.fasterxml.jackson.databind.ObjectMapper;
import com.jakewharton.retrofit.Ok3Client;
import com.netflix.spinnaker.config.DefaultServiceEndpoint;
import com.netflix.spinnaker.config.okhttp3.OkHttpClientProvider;
import com.netflix.spinnaker.fiat.providers.ProviderHealthTracker;
import com.netflix.spinnaker.fiat.providers.internal.*;
import com.netflix.spinnaker.retrofit.Slf4jRetrofitLogger;
import lombok.Setter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.annotation.Scope;
import retrofit.Endpoints;
import retrofit.RestAdapter;
import retrofit.converter.JacksonConverter;

  @Autowired @Setter private OkHttpClientProvider clientProvider;

  @Value("${services.front50.base-url}")
  @Setter
  private String front50Endpoint;

  @Value("${services.clouddriver.base-url}")
  @Setter
  private String clouddriverEndpoint;

  @Value("${services.igor.base-url}")
  @Setter
  private String igorEndpoint;

  @Bean
  Front50Api front50Api() {
    return new RestAdapter.Builder()
        .setEndpoint(Endpoints.newFixedEndpoint(front50Endpoint))
        .setClient(
            new Ok3Client(
                clientProvider.getClient(new DefaultServiceEndpoint("front50", front50Endpoint))))
        .setConverter(new JacksonConverter(objectMapper))
        .setLogLevel(retrofitLogLevel)
        .setLog(new Slf4jRetrofitLogger(Front50Api.class))
        .build()
        .create(Front50Api.class);
  }

  @Bean
  Front50ApplicationLoader front50ApplicationLoader(
      ProviderHealthTracker tracker, Front50Api front50Api) {