<commit_before>/* Copyright 2011, 2012 The Tor Project
 * See LICENSE for licensing information */
package org.torproject.onionoo;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;
import java.util.SortedMap;
import java.util.SortedSet;
import java.util.TimeZone;
import java.util.TreeMap;
import java.util.regex.Pattern;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ResourceServlet extends HttpServlet {

  private static final long serialVersionUID = 7236658979947465319L;

  private boolean maintenanceMode = false;

  private DocumentStore documentStore;

  public void init(ServletConfig config) throws ServletException {
    super.init(config);
    boolean maintenanceMode =
        config.getInitParameter("maintenance") != null
        && config.getInitParameter("maintenance").equals("1");
    File outDir = new File(config.getInitParameter("outDir"));
    this.init(maintenanceMode, outDir);
  }

  protected void init(boolean maintenanceMode, File outDir) {
    this.maintenanceMode = maintenanceMode;
    this.documentStore = new DocumentStore(outDir);
    if (!maintenanceMode) {
      this.readSummaryFile();
    }
  }

  long summaryFileLastModified = -1L;
  boolean readSummaryFile = false;
  private String relaysPublishedString, bridgesPublishedString;
  private List<String> relaysByConsensusWeight = null;
  private Map<String, String> relayFingerprintSummaryLines = null,
      bridgeFingerprintSummaryLines = null;
  private Map<String, Set<String>> relaysByCountryCode = null,
      relaysByASNumber = null, relaysByFlag = null,
      relaysByContact = null;
  private SortedMap<Integer, Set<String>> relaysByFirstSeenDays = null,
      bridgesByFirstSeenDays = null, relaysByLastSeenDays = null,
      bridgesByLastSeenDays = null;
  private void readSummaryFile() {
    long summaryFileLastModified = -1L;
    UpdateStatus updateStatus = this.documentStore.retrieve(
        UpdateStatus.class, false);
    if (updateStatus != null && updateStatus.documentString != null) {
      String updateString = updateStatus.documentString;
      try {
        summaryFileLastModified = Long.parseLong(updateString.trim());
      } catch (NumberFormatException e) {
        /* Handle below. */
      }
    }
    if (summaryFileLastModified < 0L) {
      // TODO Does this actually solve anything?  Should we instead
      // switch to a variant of the maintenance mode and re-check when
      // the next requests comes in that happens x seconds after this one?
      this.readSummaryFile = false;
      return;
    }
    if (summaryFileLastModified > this.summaryFileLastModified) {
      List<String> relaysByConsensusWeight = new ArrayList<String>();
      Map<String, String>
          relayFingerprintSummaryLines = new HashMap<String, String>(),
          bridgeFingerprintSummaryLines = new HashMap<String, String>();<commit_msg>Check that we don't serve stale data.<commit_after>/* Copyright 2011, 2012 The Tor Project
 * See LICENSE for licensing information */
package org.torproject.onionoo;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;
import java.util.SortedMap;
import java.util.SortedSet;
import java.util.TimeZone;
import java.util.TreeMap;
import java.util.regex.Pattern;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ResourceServlet extends HttpServlet {

  private static final long serialVersionUID = 7236658979947465319L;

  private boolean maintenanceMode = false;

  private DocumentStore documentStore;

  private boolean checkSummaryStale = false;

  public void init(ServletConfig config) throws ServletException {
    super.init(config);
    boolean maintenanceMode =
        config.getInitParameter("maintenance") != null
        && config.getInitParameter("maintenance").equals("1");
    File outDir = new File(config.getInitParameter("outDir"));
    this.checkSummaryStale = true;
    this.init(maintenanceMode, outDir);
  }

  protected void init(boolean maintenanceMode, File outDir) {
    this.maintenanceMode = maintenanceMode;
    this.documentStore = new DocumentStore(outDir);
    if (!maintenanceMode) {
      this.readSummaryFile();
    }
  }

  long summaryFileLastModified = -1L;
  boolean readSummaryFile = false;
  private String relaysPublishedString, bridgesPublishedString;
  private List<String> relaysByConsensusWeight = null;
  private Map<String, String> relayFingerprintSummaryLines = null,
      bridgeFingerprintSummaryLines = null;
  private Map<String, Set<String>> relaysByCountryCode = null,
      relaysByASNumber = null, relaysByFlag = null,
      relaysByContact = null;
  private SortedMap<Integer, Set<String>> relaysByFirstSeenDays = null,
      bridgesByFirstSeenDays = null, relaysByLastSeenDays = null,
      bridgesByLastSeenDays = null;
  private static final long SUMMARY_MAX_AGE = 6L * 60L * 60L * 1000L;
  private void readSummaryFile() {
    long summaryFileLastModified = -1L;
    UpdateStatus updateStatus = this.documentStore.retrieve(
        UpdateStatus.class, false);
    if (updateStatus != null && updateStatus.documentString != null) {
      String updateString = updateStatus.documentString;
      try {
        summaryFileLastModified = Long.parseLong(updateString.trim());
      } catch (NumberFormatException e) {
        /* Handle below. */
      }
    }
    if (summaryFileLastModified < 0L) {
      // TODO Does this actually solve anything?  Should we instead
      // switch to a variant of the maintenance mode and re-check when
      // the next requests comes in that happens x seconds after this one?
      this.readSummaryFile = false;
      return;
    }
    if (this.checkSummaryStale &&
        summaryFileLastModified + SUMMARY_MAX_AGE
        < System.currentTimeMillis()) {
      // TODO Does this actually solve anything?  Should we instead
      // switch to a variant of the maintenance mode and re-check when
      // the next requests comes in that happens x seconds after this one?
      this.readSummaryFile = false;
      return;
    }
    if (summaryFileLastModified > this.summaryFileLastModified) {
      List<String> relaysByConsensusWeight = new ArrayList<String>();
      Map<String, String>
          relayFingerprintSummaryLines = new HashMap<String, String>(),
          bridgeFingerprintSummaryLines = new HashMap<String, String>();
{'fraction_non_alphanumeric': 0.0869987512140974, 'fraction_numerical': 0.009851533231580408, 'mean_word_length': 4.037037037037037, 'pattern_counts': {'":': 0, '<': 28, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2133240', 'n_tokens_mistral': 2036, 'n_tokens_neox': 1960, 'n_words': 530}