1c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved.
2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// found in the LICENSE file.
4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#ifndef COMPONENTS_POLICY_CORE_COMMON_CLOUD_EXTERNAL_POLICY_DATA_UPDATER_H_
6a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#define COMPONENTS_POLICY_CORE_COMMON_CLOUD_EXTERNAL_POLICY_DATA_UPDATER_H_
7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <map>
9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <queue>
10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <string>
11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/basictypes.h"
13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/callback_forward.h"
14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/memory/ref_counted.h"
1558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/memory/scoped_ptr.h"
16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/memory/weak_ptr.h"
17a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/policy_export.h"
18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace base {
20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class SequencedTaskRunner;
21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace policy {
24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)class ExternalPolicyDataFetcher;
2658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// This class downloads external policy data. Given a |Request|, data is fetched
28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// from the |url|, verified to not exceed |max_size| and to match the expected
29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// |hash| and then handed to a callback that can do further verification before
30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// finally deciding whether the fetched data is valid.
31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// If a fetch is not successful or retrieves invalid data, retries are scheduled
32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// with exponential backoff.
3358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// The actual fetching is handled by an ExternalPolicyDataFetcher, allowing this
3458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// class to run on a background thread where network I/O is not possible.
35a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)class POLICY_EXPORT ExternalPolicyDataUpdater {
36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public:
37a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  struct POLICY_EXPORT Request {
38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   public:
39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    Request();
40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    Request(const std::string& url, const std::string& hash, int64 max_size);
41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    bool operator==(const Request& other) const;
43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    std::string url;
45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    std::string hash;
46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    int64 max_size;
47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  };
48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // This callback is invoked when a fetch has successfully retrieved |data|
50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // that does not exceed |max_size| and matches the expected |hash|. The
51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // callback can do further verification to decide whether the fetched data is
52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // valid.
53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // If the callback returns |true|, the data is accepted and the |Request| is
54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // finished. If the callback returns |false|, the data is rejected and the
55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // fetch is retried after a long backoff. Note that in this case, the callback
56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // may be invoked multiple times as the fetch is repeated. Make sure to not
57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // bind base::Passed() scoped_ptrs to the callback in such cases as these
58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // become invalid after a callback has been run once. base::Owned() can be
59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // used in all cases.
60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  typedef base::Callback<bool(const std::string&)> FetchSuccessCallback;
61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
6258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // This class runs on the background thread represented by |task_runner|,
6358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // which must support file I/O. All network I/O is forwarded to a different
6458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // thread by the |external_policy_data_fetcher|.
65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ExternalPolicyDataUpdater(
66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      scoped_refptr<base::SequencedTaskRunner> task_runner,
6758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      scoped_ptr<ExternalPolicyDataFetcher> external_policy_data_fetcher,
68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      size_t max_parallel_fetches);
69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ~ExternalPolicyDataUpdater();
70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Fetches the external data specified in the |request|. The |key| is an
72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // opaque identifier. If another request for the same |key| is still pending,
73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // it will be canceled and replaced with the new |request|. The callback will
74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // be invoked after a successful fetch. See the documentation of
75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // |FetchSuccessCallback| for more details.
76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void FetchExternalData(const std::string key,
77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         const Request& request,
78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         const FetchSuccessCallback& callback);
79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Cancels the pending request identified by |key|. If no such request is
81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // pending, does nothing.
82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void CancelExternalDataFetch(const std::string& key);
83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private:
85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  class FetchJob;
86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Starts jobs from the |job_queue_| until |max_parallel_jobs_| are running or
88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // the queue is depleted.
89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void StartNextJobs();
90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Appends |job| to the |job_queue_| and starts it immediately if less than
92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // |max_parallel_jobs_| are running.
93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void ScheduleJob(FetchJob* job);
94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Callback for jobs that succeeded.
96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void OnJobSucceeded(FetchJob* job);
97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Callback for jobs that failed.
99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void OnJobFailed(FetchJob* job);
100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<base::SequencedTaskRunner> task_runner_;
10258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  scoped_ptr<ExternalPolicyDataFetcher> external_policy_data_fetcher_;
103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The maximum number of jobs to run in parallel.
105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  size_t max_parallel_jobs_;
106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The number of jobs currently running.
108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  size_t running_jobs_;
109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Queue of jobs waiting to be run. Jobs are taken off the queue and started
111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // by StartNextJobs().
112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::queue<base::WeakPtr<FetchJob> > job_queue_;
113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Map that owns all existing jobs, regardless of whether they are currently
115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // queued, running or waiting for a retry.
116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::map<std::string, FetchJob*> job_map_;
117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // |True| once the destructor starts. Prevents jobs from being started during
119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // shutdown.
120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool shutting_down_;
121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ExternalPolicyDataUpdater);
123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}  // namespace policy
126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
127a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#endif  // COMPONENTS_POLICY_CORE_COMMON_CLOUD_EXTERNAL_POLICY_DATA_UPDATER_H_
128