summaryrefslogtreecommitdiffstats
path: root/src/bin/lfc/lfc_controller.h
blob: d58b418358d5481560714ab11d685ceb068bf6f3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
// Copyright (C) 2015-2018 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

#ifndef LFC_CONTROLLER_H
#define LFC_CONTROLLER_H

#include <exceptions/exceptions.h>
#include <string>

namespace isc {
namespace lfc {

/// @brief Exception thrown when the command line is invalid.
class InvalidUsage : public isc::Exception {
public:
    InvalidUsage(const char* file, size_t line, const char* what) :
        isc::Exception(file, line, what) { };
};

/// @brief Exceptions thrown when a method is unable to manipulate
/// (remove or rename) a file.
class RunTimeFail : public isc::Exception {
public:
    RunTimeFail(const char* file, size_t line, const char* what) :
        isc::Exception(file, line, what) { };
};

/// @brief Process controller for LFC process
///
/// This class provides the LFC process functions. These are used to:
/// manage the command line, check for already running instances,
/// invoke the code to process the lease files and finally to rename
/// the lease files as necessary.
class LFCController {
public:
    /// @brief Defines the application name, it may be used to locate
    /// configuration data and appears in log statements.
    static const char* lfc_app_name_;

    /// @brief Defines the executable name, by convention this should match
    /// the executable name.
    static const char* lfc_bin_name_;

    /// @brief Constructor
    LFCController();

    /// @brief Destructor
    ~LFCController();

    /// @brief Acts as the primary entry point to start execution
    /// of the process.
    ///
    /// Provides the control logic to combine two lease files and
    /// weed out duplicate and expired leases. A description of
    /// the design can be found at
    /// https://gitlab.isc.org/isc-projects/kea/wikis/designs/Lease-File-Cleanup-design
    ///
    /// -# parse command line arguments
    /// -# verify that it is the only instance
    /// -# create pid file
    /// -# read leases files
    /// -# write lease file
    /// -# move leases files
    /// -# cleanup artifacts
    /// -# remove pid file
    /// -# exit to the caller
    ///
    /// @param argc Number of strings in the @c argv array.
    /// @param argv Array of arguments passed in via the program's main function.
    /// @param test_mode is a bool value which indicates if @c launch
    /// should be run in the test mode (if true).  This parameter doesn't
    /// have a default value to force test implementers to enable test
    /// mode explicitly.
    ///
    /// @throw InvalidUsage if the command line parameters are invalid.
    void launch(int argc, char* argv[], const bool test_mode);

    /// @brief Process the command line arguments.
    ///
    /// It is the first step taken after the process has been launched.
    ///
    /// @param argc Number of strings in the @c argv array.
    /// @param argv Array of arguments passed in via the program's main function.
    ///
    /// @throw InvalidUsage if the command line parameters are invalid.
    void parseArgs(int argc, char* argv[]);

    /// @brief Rotate files.
    ///
    /// After we have a finish file, either from doing the cleanup or because
    /// a previous instance was interrupted, delete the work files (previous
    /// & copy) and move the finish file to be the new previous file.
    ///
    /// @throw RunTimeFail if we can't manipulate the files.
    void fileRotate() const;

    /// @name Accessor methods mainly used for testing purposes
    //@{

    /// @brief Gets the protocol version of the leases files
    ///
    /// @return Returns the value of the DHCP protocol version.
    /// This can be 4 or 6 while in use and 0 before parsing
    /// any arguments.
    int getProtocolVersion() const {
      return (protocol_version_);
    }

    /// @brief Gets the config file name
    ///
    /// @return Returns the path to the config file
    std::string getConfigFile() const {
        return (config_file_);
    }

    /// @brief Gets the previous file name
    ///
    /// @return Returns the path to the previous file
    std::string getPreviousFile() const {
        return (previous_file_);
    }

    /// @brief Gets the copy file name
    ///
    /// @return Returns the path to the copy file
    std::string getCopyFile() const {
        return (copy_file_);
    }

    /// @brief Gets the output file name
    ///
    /// @return Returns the path to the output file
    std::string getOutputFile() const {
        return (output_file_);
    }

    /// @brief Gets the finish file name
    ///
    /// @return Returns the path to the finish file
    std::string getFinishFile() const {
        return (finish_file_);
    }

    /// @brief Gets the pid file name
    ///
    /// @return Returns the path to the pid file
    std::string getPidFile() const {
        return (pid_file_);
    }
    //@}

private:
    /// Version of the DHCP protocol used, i.e. 4 or 6.
    int protocol_version_;
    /// When true output the result of parsing the command line
    bool verbose_;
    std::string config_file_;   ///< The path to the config file
    std::string previous_file_; ///< The path to the previous LFC file (if any)
    std::string copy_file_;     ///< The path to the copy of the lease file
    std::string output_file_;   ///< The path to the output file
    std::string finish_file_;   ///< The path to the finished output file
    std::string pid_file_;      ///< The path to the pid file

    /// @brief Prints the program usage text to std error.
    ///
    /// @param text is a string message which will preceded the usage text.
    /// This is intended to be used for specific usage violation messages.
    void usage(const std::string& text);

    /// @brief Gets the Kea version number for printing
    ///
    /// @param extended is a boolean indicating if the version string
    /// should be short (false) or extended (true)
    std::string getVersion(const bool extended) const;

    /// @brief Process files.
    ///
    /// Read in the leases from any previous & copy files we have and
    /// write the results out to the output file.  Upon completion of
    /// the write move the file to the finish file.
    ///
    /// @tparam LeaseObjectType A @c Lease4 or @c Lease6.
    /// @tparam LeaseFileType A @c CSVLeaseFile4 or @c CSVLeaseFile6.
    /// @tparam StorageType A @c Lease4Storage or @c Lease6Storage.
    ///
    /// @throw RunTimeFail if we can't move the file.
    template<typename LeaseObjectType, typename LeaseFileType, typename StorageType>
    void processLeases() const;

    ///@brief Start up the logging system
    ///
    /// @param test_mode indicates if we have have been started from the test
    /// system (true) or are running normally (false)
    void startLogger(const bool test_mode) const;
};

}; // namespace isc::lfc
}; // namespace isc

#endif // LFC_CONTROLLER_H