// Path: fiat-roles/src/main/java/com/netflix/spinnaker/fiat/providers/HealthTrackable.java
// public interface HealthTrackable {
// 
//   ProviderHealthTracker getHealthTracker();
// }
// 
// 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 static com.netflix.spinnaker.security.AuthenticatedRequest.allowAnonymous;
import com.netflix.spinnaker.fiat.providers.HealthTrackable;
import com.netflix.spinnaker.fiat.providers.ProviderHealthTracker;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Supplier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
/*
 * Copyright 2020 Netflix, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.netflix.spinnaker.fiat.providers.internal;



public class DataLoader<T> implements HealthTrackable, ApplicationListener<ContextRefreshedEvent> {

  private final Logger log = LoggerFactory.getLogger(getClass());

  private final Supplier<List<T>> loadingFunction;
  private final ProviderHealthTracker healthTracker;

  private AtomicReference<List<T>> cache = new AtomicReference<>();

// Path: fiat-roles/src/main/java/com/netflix/spinnaker/fiat/providers/HealthTrackable.java
// public interface HealthTrackable {
// 
//   ProviderHealthTracker getHealthTracker();
// }
// 
// 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-roles/src/main/java/com/netflix/spinnaker/fiat/providers/internal/DataLoader.java
import static com.netflix.spinnaker.security.AuthenticatedRequest.allowAnonymous;
import com.netflix.spinnaker.fiat.providers.HealthTrackable;
import com.netflix.spinnaker.fiat.providers.ProviderHealthTracker;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Supplier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;

/*
 * Copyright 2020 Netflix, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.netflix.spinnaker.fiat.providers.internal;



public class DataLoader<T> implements HealthTrackable, ApplicationListener<ContextRefreshedEvent> {

  private final Logger log = LoggerFactory.getLogger(getClass());

  private final Supplier<List<T>> loadingFunction;
  private final ProviderHealthTracker healthTracker;

  private AtomicReference<List<T>> cache = new AtomicReference<>();

  public DataLoader(ProviderHealthTracker healthTracker, Supplier<List<T>> loadingFunction) {